<commit_before>/*
 * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "CreatureAI.h"
#include "InstanceScript.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "uldaman.h"

enum Spells
{
    SPELL_ARCHAEDAS_AWAKEN      = 10347,
    SPELL_AWAKEN_VAULT_WALKER   = 10258,
};

enum Events
{
    EVENT_SUB_BOSS_AGGRO        = 2228
};

class instance_uldaman : public InstanceMapScript
{
public:
    instance_uldaman() : InstanceMapScript("instance_uldaman", 70) { }

    struct instance_uldaman_InstanceMapScript : public InstanceScript
    {
        instance_uldaman_InstanceMapScript(Map* map) : InstanceScript(map) { }

        void Initialize() override
        {
            memset(&_encounters, 0, sizeof(_encounters));
        }

        void OnGameObjectCreate(GameObject* gameobject) override
        {
            switch (gameobject->GetEntry())
            {
                case GO_IRONAYA_SEAL_DOOR:
                case GO_KEYSTONE:
                    if (_encounters[DATA_IRONAYA_DOORS] == DONE)
                    {
                        HandleGameObject(ObjectGuid::Empty, true, gameobject);
                        gameobject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
                    }
                    break;
                case GO_TEMPLE_DOOR:
                    if (_encounters[DATA_STONE_KEEPERS] == DONE)
                        HandleGameObject(ObjectGuid::Empty, true, gameobject);
                    break;
                case GO_ANCIENT_VAULT_DOOR:
                    ancientVaultDoorGUID = gameobject->GetGUID();
                    if (_encounters[DATA_ARCHAEDAS] == DONE)
                        HandleGameObject(ObjectGuid::Empty, true, gameobject);
                    break;
                case GO_ARCHAEDAS_TEMPLE_DOOR:
                    archaedasTempleDoorGUID = gameobject->GetGUID();
                    break;
            }
        }

        void SetData(uint32 type, uint32 data) override
        {
            switch (type)
            {
                case DATA_IRONAYA_DOORS:
                case DATA_STONE_KEEPERS:
                    _encounters[type] = data;
                    break;
                case DATA_ARCHAEDAS:
                    _encounters[type] = data;
                    HandleGameObject(ancientVaultDoorGUID, data == DONE, nullptr);
                    HandleGameObject(archaedasTempleDoorGUID, data != IN_PROGRESS, nullptr);
                    break;
            }

            if (data == DONE)
                SaveToDB();
        }

        std::string GetSaveData() override
        {
            std::ostringstream saveStream;
            saveStream << "U D " << _encounters[DATA_IRONAYA_DOORS] << ' ' << _encounters[DATA_STONE_KEEPERS] << ' ' << _encounters[DATA_ARCHAEDAS];
            return saveStream.str();
        }

        void Load(const char* in) override
        {
            if (!in)
                return;

            char dataHead1, dataHead2;
            std::istringstream loadStream(in);
            loadStream >> dataHead1 >> dataHead2;

            if (dataHead1 == 'U' && dataHead2 == 'D')
            {
                for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
                {
                    loadStream >> _encounters[i];
                    if (_encounters[i] == IN_PROGRESS)
                        _encounters[i] = NOT_STARTED;
                }
            }
        }

        void OnCreatureCreate(Creature* creature) override
        {
            switch (creature->GetEntry())
            {
                case NPC_STONE_KEEPER:
                    if (_encounters[DATA_STONE_KEEPERS] != DONE && !creature->IsAlive())
                        creature->Respawn();
                    break;
            }
        }

    private:
        uint32 _encounters[MAX_ENCOUNTERS];
        ObjectGuid archaedasTempleDoorGUID;
        ObjectGuid ancientVaultDoorGUID;
    };

    InstanceScript* GetInstanceScript(InstanceMap* map) const override
    {
        return new instance_uldaman_InstanceMapScript(map);
    }
};

class spell_uldaman_sub_boss_agro_keepers : public SpellScriptLoader
{
public:
    spell_uldaman_sub_boss_agro_keepers() : SpellScriptLoader("spell_uldaman_sub_boss_agro_keepers") { }

    class spell_uldaman_sub_boss_agro_keepers_SpellScript : public SpellScript
    {
        PrepareSpellScript(spell_uldaman_sub_boss_agro_keepers_SpellScript);

        void HandleSendEvent(SpellEffIndex  /*effIndex*/)
        {
            if (Creature* keeper = GetCaster()->FindNearestCreature(NPC_STONE_KEEPER, 100.0f, true))
                keeper->AI()->SetData(1, 1);
        }

        void Register() override
        {
            OnEffectLaunch += SpellEffectFn(spell_uldaman_sub_boss_agro_keepers_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
        }
    };

    SpellScript* GetSpellScript() const override
    {
        return new spell_uldaman_sub_boss_agro_keepers_SpellScript();
    }
};

enum UldamanStonedEnum
{
    MAP_ULDAMAN = 70
};

class spell_uldaman_stoned : public SpellScriptLoader
{
public:
    spell_uldaman_stoned() : SpellScriptLoader("spell_uldaman_stoned") { }

    class spell_uldaman_stoned_AuraScript : public AuraScript
    {
        PrepareAuraScript(spell_uldaman_stoned_AuraScript);

        bool Load() override
        {
            return GetUnitOwner()->GetTypeId() == TYPEID_UNIT && GetUnitOwner()->GetMapId() == MAP_ULDAMAN;
        }

        void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
        {
            Creature* target = GetUnitOwner()->ToCreature();
            target->SetReactState(REACT_PASSIVE);
            target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
        }

        void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
        {
            Creature* target = GetUnitOwner()->ToCreature();
            target->SetReactState(REACT_AGGRESSIVE);
            target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
        }

        void Register() override
        {
            OnEffectApply += AuraEffectApplyFn(spell_uldaman_stoned_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
            OnEffectRemove += AuraEffectRemoveFn(spell_uldaman_stoned_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
        }
    };

    AuraScript* GetAuraScript() const override
    {
        return new spell_uldaman_stoned_AuraScript();
    }
};

class spell_uldaman_boss_agro_archaedas : public SpellScriptLoader
{
public:
    spell_uldaman_boss_agro_archaedas() : SpellScriptLoader("spell_uldaman_boss_agro_archaedas") { }

    class spell_uldaman_boss_agro_archaedas_SpellScript : public SpellScript
    {
        PrepareSpellScript(spell_uldaman_boss_agro_archaedas_SpellScript);

        void HandleSendEvent(SpellEffIndex  /*effIndex*/)
        {
            InstanceScript* instance = GetCaster()->GetInstanceScript();
            if (!instance || instance->GetData(DATA_ARCHAEDAS) == IN_PROGRESS)
                return;

            instance->SetData(DATA_ARCHAEDAS, IN_PROGRESS);
            if (Creature* archaedas = GetCaster()->FindNearestCreature(NPC_ARCHAEDAS, 100.0f, true))
                archaedas->AI()->SetData(1, 1);
        }

        void Register() override
        {
            OnEffectLaunch += SpellEffectFn(spell_uldaman_boss_agro_archaedas_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
        }
    };

    SpellScript* GetSpellScript() const override
    {
        return new spell_uldaman_boss_agro_archaedas_SpellScript();
    }
};

void AddSC_instance_uldaman()
{
    new instance_uldaman();
    new spell_uldaman_sub_boss_agro_keepers();
    new spell_uldaman_stoned();
    new spell_uldaman_boss_agro_archaedas();
}
<commit_msg>Fix(Core/Uldaman): Door behind Archaedas can close after event. (#8024)<commit_after>/*
 * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by the
 * Free Software Foundation; either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "CreatureAI.h"
#include "InstanceScript.h"
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "uldaman.h"

enum Spells
{
    SPELL_ARCHAEDAS_AWAKEN      = 10347,
    SPELL_AWAKEN_VAULT_WALKER   = 10258,
};

enum Events
{
    EVENT_SUB_BOSS_AGGRO        = 2228
};

class instance_uldaman : public InstanceMapScript
{
public:
    instance_uldaman() : InstanceMapScript("instance_uldaman", 70) { }

    struct instance_uldaman_InstanceMapScript : public InstanceScript
    {
        instance_uldaman_InstanceMapScript(Map* map) : InstanceScript(map) { }

        void Initialize() override
        {
            memset(&_encounters, 0, sizeof(_encounters));
        }

        void OnGameObjectCreate(GameObject* gameobject) override
        {
            switch (gameobject->GetEntry())
            {
                case GO_IRONAYA_SEAL_DOOR:
                case GO_KEYSTONE:
                    if (_encounters[DATA_IRONAYA_DOORS] == DONE)
                    {
                        HandleGameObject(ObjectGuid::Empty, true, gameobject);
                        gameobject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
                    }
                    break;
                case GO_TEMPLE_DOOR:
                    if (_encounters[DATA_STONE_KEEPERS] == DONE)
                        HandleGameObject(ObjectGuid::Empty, true, gameobject);
                    break;
                case GO_ANCIENT_VAULT_DOOR:
                    ancientVaultDoorGUID = gameobject->GetGUID();
                    if (_encounters[DATA_ARCHAEDAS] == DONE)
                        HandleGameObject(ObjectGuid::Empty, true, gameobject);
                    break;
                case GO_ARCHAEDAS_TEMPLE_DOOR:
                    archaedasTempleDoorGUID = gameobject->GetGUID();
                    break;
            }
        }

        void SetData(uint32 type, uint32 data) override
        {
            switch (type)
            {
                case DATA_IRONAYA_DOORS:
                case DATA_STONE_KEEPERS:
                    _encounters[type] = data;
                    break;
                case DATA_ARCHAEDAS:
                    _encounters[type] = data;
                    HandleGameObject(ancientVaultDoorGUID, data == DONE, nullptr);
                    HandleGameObject(archaedasTempleDoorGUID, data != IN_PROGRESS, nullptr);
                    break;
            }

            if (data == DONE)
                SaveToDB();
        }

        uint32 GetData(uint32 data) const override
        {
            if (data < MAX_ENCOUNTERS)
            {
                return _encounters[data];
            }
            return 0;
        }

        std::string GetSaveData() override
        {
            std::ostringstream saveStream;
            saveStream << "U D " << _encounters[DATA_IRONAYA_DOORS] << ' ' << _encounters[DATA_STONE_KEEPERS] << ' ' << _encounters[DATA_ARCHAEDAS];
            return saveStream.str();
        }

        void Load(const char* in) override
        {
            if (!in)
                return;

            char dataHead1, dataHead2;
            std::istringstream loadStream(in);
            loadStream >> dataHead1 >> dataHead2;

            if (dataHead1 == 'U' && dataHead2 == 'D')
            {
                for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
                {
                    loadStream >> _encounters[i];
                    if (_encounters[i] == IN_PROGRESS)
                        _encounters[i] = NOT_STARTED;
                }
            }
        }

        void OnCreatureCreate(Creature* creature) override
        {
            switch (creature->GetEntry())
            {
                case NPC_STONE_KEEPER:
                    if (_encounters[DATA_STONE_KEEPERS] != DONE && !creature->IsAlive())
                        creature->Respawn();
                    break;
            }
        }

    private:
        uint32 _encounters[MAX_ENCOUNTERS];
        ObjectGuid archaedasTempleDoorGUID;
        ObjectGuid ancientVaultDoorGUID;
    };

    InstanceScript* GetInstanceScript(InstanceMap* map) const override
    {
        return new instance_uldaman_InstanceMapScript(map);
    }
};

class spell_uldaman_sub_boss_agro_keepers : public SpellScriptLoader
{
public:
    spell_uldaman_sub_boss_agro_keepers() : SpellScriptLoader("spell_uldaman_sub_boss_agro_keepers") { }

    class spell_uldaman_sub_boss_agro_keepers_SpellScript : public SpellScript
    {
        PrepareSpellScript(spell_uldaman_sub_boss_agro_keepers_SpellScript);

        void HandleSendEvent(SpellEffIndex  /*effIndex*/)
        {
            if (Creature* keeper = GetCaster()->FindNearestCreature(NPC_STONE_KEEPER, 100.0f, true))
                keeper->AI()->SetData(1, 1);
        }

        void Register() override
        {
            OnEffectLaunch += SpellEffectFn(spell_uldaman_sub_boss_agro_keepers_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
        }
    };

    SpellScript* GetSpellScript() const override
    {
        return new spell_uldaman_sub_boss_agro_keepers_SpellScript();
    }
};

enum UldamanStonedEnum
{
    MAP_ULDAMAN = 70
};

class spell_uldaman_stoned : public SpellScriptLoader
{
public:
    spell_uldaman_stoned() : SpellScriptLoader("spell_uldaman_stoned") { }

    class spell_uldaman_stoned_AuraScript : public AuraScript
    {
        PrepareAuraScript(spell_uldaman_stoned_AuraScript);

        bool Load() override
        {
            return GetUnitOwner()->GetTypeId() == TYPEID_UNIT && GetUnitOwner()->GetMapId() == MAP_ULDAMAN;
        }

        void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
        {
            Creature* target = GetUnitOwner()->ToCreature();
            target->SetReactState(REACT_PASSIVE);
            target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
        }

        void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
        {
            Creature* target = GetUnitOwner()->ToCreature();
            target->SetReactState(REACT_AGGRESSIVE);
            target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
        }

        void Register() override
        {
            OnEffectApply += AuraEffectApplyFn(spell_uldaman_stoned_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
            OnEffectRemove += AuraEffectRemoveFn(spell_uldaman_stoned_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
        }
    };

    AuraScript* GetAuraScript() const override
    {
        return new spell_uldaman_stoned_AuraScript();
    }
};

class spell_uldaman_boss_agro_archaedas : public SpellScriptLoader
{
public:
    spell_uldaman_boss_agro_archaedas() : SpellScriptLoader("spell_uldaman_boss_agro_archaedas") { }

    class spell_uldaman_boss_agro_archaedas_SpellScript : public SpellScript
    {
        PrepareSpellScript(spell_uldaman_boss_agro_archaedas_SpellScript);

        void HandleSendEvent(SpellEffIndex  /*effIndex*/)
        {
            InstanceScript* instance = GetCaster()->GetInstanceScript();

            if (!instance || instance->GetData(DATA_ARCHAEDAS) == IN_PROGRESS || instance->GetData(DATA_ARCHAEDAS) == DONE)
                return;

            instance->SetData(DATA_ARCHAEDAS, IN_PROGRESS);
            if (Creature* archaedas = GetCaster()->FindNearestCreature(NPC_ARCHAEDAS, 100.0f, true))
                archaedas->AI()->SetData(1, 1);
        }

        void Register() override
        {
            OnEffectLaunch += SpellEffectFn(spell_uldaman_boss_agro_archaedas_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
        }
    };

    SpellScript* GetSpellScript() const override
    {
        return new spell_uldaman_boss_agro_archaedas_SpellScript();
    }
};

void AddSC_instance_uldaman()
{
    new instance_uldaman();
    new spell_uldaman_sub_boss_agro_keepers();
    new spell_uldaman_stoned();
    new spell_uldaman_boss_agro_archaedas();
}
<|endoftext|>


<commit_before>
// DungeonRoomsFinisher.cpp

// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms

#include "Globals.h"
#include "DungeonRoomsFinisher.h"
#include "../FastRandom.h"

/** Height, in blocks, of the internal dungeon room open space. This many air blocks Y-wise. */
static const int ROOM_HEIGHT = 4;

////////////////////////////////////////////////////////////////////////////////
// cDungeonRoom:

class cDungeonRoom :
	public cGridStructGen::cStructure
{
	typedef cGridStructGen::cStructure super;

public:

	cDungeonRoom(
		int a_GridX, int a_GridZ,
		int a_OriginX, int a_OriginZ,
		int a_HalfSizeX, int a_HalfSizeZ,
		int a_FloorHeight,
		cNoise & a_Noise
	) :
		super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
		m_StartX(a_OriginX - a_HalfSizeX),
		m_EndX(a_OriginX + a_HalfSizeX),
		m_StartZ(a_OriginZ - a_HalfSizeZ),
		m_EndZ(a_OriginZ + a_HalfSizeZ),
		m_FloorHeight(a_FloorHeight)
	{
		/*
		Pick coords next to the wall for the chests.
		This is done by indexing the possible coords, picking any one for the first chest
		and then picking another position for the second chest that is not adjacent to the first pos
		*/
		int rnd = a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
		int SizeX = m_EndX - m_StartX - 1;
		int SizeZ = m_EndZ - m_StartZ - 1;
		int NumPositions = 2 * SizeX + 2 * SizeZ;
		int FirstChestPos = rnd % NumPositions;  // The corner positions are a bit more likely, but we don't mind
		rnd = rnd / 512;
		int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions;
		m_Chest1 = DecodeChestCoords(FirstChestPos,  SizeX, SizeZ);
		m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ);
	}

protected:

	// The X range of the room, start inclusive, end exclusive:
	int m_StartX, m_EndX;

	// The Z range of the room, start inclusive, end exclusive:
	int m_StartZ, m_EndZ;

	/** The Y coord of the floor of the room */
	int m_FloorHeight;

	/** The (absolute) coords of the first chest. The Y coord represents the chest's Meta value (facing). */
	Vector3i m_Chest1;

	/** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */
	Vector3i m_Chest2;

	/** Decodes the position index along the room walls into a proper 2D position for a chest. */
	Vector3i DecodeChestCoords(int a_PosIdx, int a_SizeX, int a_SizeZ)
	{
		if (a_PosIdx < a_SizeX)
		{
			// Return a coord on the ZM side of the room:
			return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZP, m_StartZ + 1);
		}
		a_PosIdx -= a_SizeX;
		if (a_PosIdx < a_SizeZ)
		{
			// Return a coord on the XP side of the room:
			return Vector3i(m_EndX - 1, E_META_CHEST_FACING_XM, m_StartZ + a_PosIdx + 1);
		}
		a_PosIdx -= a_SizeZ;
		if (a_PosIdx < a_SizeX)
		{
			// Return a coord on the ZP side of the room:
			return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZM, m_StartZ + 1);
		}
		a_PosIdx -= a_SizeX;
		// Return a coord on the XM side of the room:
		return Vector3i(m_StartX + 1, E_META_CHEST_FACING_XP, m_StartZ + a_PosIdx + 1);
	}

	/** Fills the specified area of blocks in the chunk with the specified blocktype if they are one of the overwritten block types.
	The coords are absolute, start coords are inclusive, end coords are exclusive. */
	void ReplaceCuboid(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType)
	{
		int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
		int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
		int RelEndX   = Clamp(a_EndX - BlockX,   0, cChunkDef::Width);
		int RelEndZ   = Clamp(a_EndZ - BlockZ,   0, cChunkDef::Width);
		for (int y = a_StartY; y < a_EndY; y++)
		{
			for (int z = RelStartZ; z < RelEndZ; z++)
			{
				for (int x = RelStartX; x < RelEndX; x++)
				{
					if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
					{
						a_ChunkDesc.SetBlockType(x, y, z, a_DstBlockType);
					}
				}  // for x
			}  // for z
		}  // for z
	}

	/** Fills the specified area of blocks in the chunk with a random pattern of the specified blocktypes, if they are one of the overwritten block types.
	The coords are absolute, start coords are inclusive, end coords are exclusive. The first blocktype uses 75% chance, the second 25% chance. */
	void ReplaceCuboidRandom(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType1, BLOCKTYPE a_DstBlockType2)
	{
		int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
		int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
		int RelEndX   = Clamp(a_EndX - BlockX,   0, cChunkDef::Width);
		int RelEndZ   = Clamp(a_EndZ - BlockZ,   0, cChunkDef::Width);
		cFastRandom rnd;
		for (int y = a_StartY; y < a_EndY; y++)
		{
			for (int z = RelStartZ; z < RelEndZ; z++)
			{
				for (int x = RelStartX; x < RelEndX; x++)
				{
					if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
					{
						BLOCKTYPE BlockType = (rnd.NextInt(101) < 75) ? a_DstBlockType1 : a_DstBlockType2;
						a_ChunkDesc.SetBlockType(x, y, z, BlockType);
					}
				}  // for x
			}  // for z
		}  // for z
	}

	/** Tries to place a chest at the specified (absolute) coords.
	Does nothing if the coords are outside the chunk. */
	void TryPlaceChest(cChunkDesc & a_ChunkDesc, const Vector3i & a_Chest)
	{
		int RelX = a_Chest.x - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int RelZ = a_Chest.z - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		if (
			(RelX < 0) || (RelX >= cChunkDef::Width) ||  // The X coord is not in this chunk
			(RelZ < 0) || (RelZ >= cChunkDef::Width)     // The Z coord is not in this chunk
		)
		{
			return;
		}
		a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y);

		// TODO: Fill the chest with random loot
	}

	// cGridStructGen::cStructure override:
	virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override
	{
		if (
			(m_EndX <= a_ChunkDesc.GetChunkX() * cChunkDef::Width) ||
			(m_StartX >= a_ChunkDesc.GetChunkX() * cChunkDef::Width + cChunkDef::Width) ||
			(m_EndZ <= a_ChunkDesc.GetChunkZ() * cChunkDef::Width) ||
			(m_StartZ >= a_ChunkDesc.GetChunkZ() * cChunkDef::Width + cChunkDef::Width)
		)
		{
			// The chunk is not intersecting the room at all, bail out
			return;
		}
		int b = m_FloorHeight + 1;  // Bottom
		int t = m_FloorHeight + 1 + ROOM_HEIGHT;  // Top
		ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE);  // Floor
		ReplaceCuboid(a_ChunkDesc, m_StartX + 1, b, m_StartZ + 1, m_EndX, t, m_EndZ, E_BLOCK_AIR);  // Insides

		// Walls:
		ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_StartX + 1, t, m_EndZ,       E_BLOCK_COBBLESTONE);  // XM wall
		ReplaceCuboid(a_ChunkDesc, m_EndX,   b, m_StartZ, m_EndX + 1,   t, m_EndZ,       E_BLOCK_COBBLESTONE);  // XP wall
		ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_EndX + 1,   t, m_StartZ + 1, E_BLOCK_COBBLESTONE);  // ZM wall
		ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_EndZ,   m_EndX + 1,   t, m_EndZ + 1,   E_BLOCK_COBBLESTONE);  // ZP wall

		// Place chests:
		TryPlaceChest(a_ChunkDesc, m_Chest1);
		TryPlaceChest(a_ChunkDesc, m_Chest2);

		// Place the spawner:
		int CenterX = (m_StartX + m_EndX) / 2 - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int CenterZ = (m_StartZ + m_EndZ) / 2 - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		if (
			(CenterX >= 0) && (CenterX < cChunkDef::Width) &&
			(CenterZ >= 0) && (CenterZ < cChunkDef::Width)
		)
		{
			a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0);
			// TODO: Set the spawned mob
		}
	}
} ;

////////////////////////////////////////////////////////////////////////////////
// cDungeonRoomsFinisher:

cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) :
	super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024),
	m_HeightGen(a_HeightGen),
	m_MaxHalfSize((a_MaxSize + 1) / 2),
	m_MinHalfSize((a_MinSize + 1) / 2),
	m_HeightProbability(cChunkDef::Height)
{
	// Initialize the height probability distribution:
	m_HeightProbability.SetDefString(a_HeightDistrib);

	// Normalize the min and max size:
	if (m_MinHalfSize > m_MaxHalfSize)
	{
		std::swap(m_MinHalfSize, m_MaxHalfSize);
	}
}

cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
	// Select a random room size in each direction:
	int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
	int HalfSizeX = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
	rnd = rnd / 32;
	int HalfSizeZ = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
	rnd = rnd / 32;

	// Select a random floor height for the room, based on the height generator:
	int ChunkX, ChunkZ;
	int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ;
	cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
	cChunkDef::HeightMap HeightMap;
	m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap);
	int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ);  // Max room height at {a_OriginX, a_OriginZ}
	Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5);

	// Create the dungeon room descriptor:
	return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise));
}

<commit_msg>DungeonRooms: Fixed an off-by-one error.<commit_after>
// DungeonRoomsFinisher.cpp

// Declares the cDungeonRoomsFinisher class representing the finisher that generates dungeon rooms

#include "Globals.h"
#include "DungeonRoomsFinisher.h"
#include "../FastRandom.h"

/** Height, in blocks, of the internal dungeon room open space. This many air blocks Y-wise. */
static const int ROOM_HEIGHT = 4;

////////////////////////////////////////////////////////////////////////////////
// cDungeonRoom:

class cDungeonRoom :
	public cGridStructGen::cStructure
{
	typedef cGridStructGen::cStructure super;

public:

	cDungeonRoom(
		int a_GridX, int a_GridZ,
		int a_OriginX, int a_OriginZ,
		int a_HalfSizeX, int a_HalfSizeZ,
		int a_FloorHeight,
		cNoise & a_Noise
	) :
		super(a_GridX, a_GridZ, a_OriginX, a_OriginZ),
		m_StartX(a_OriginX - a_HalfSizeX),
		m_EndX(a_OriginX + a_HalfSizeX),
		m_StartZ(a_OriginZ - a_HalfSizeZ),
		m_EndZ(a_OriginZ + a_HalfSizeZ),
		m_FloorHeight(a_FloorHeight)
	{
		/*
		Pick coords next to the wall for the chests.
		This is done by indexing the possible coords, picking any one for the first chest
		and then picking another position for the second chest that is not adjacent to the first pos
		*/
		int rnd = a_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
		int SizeX = m_EndX - m_StartX - 1;
		int SizeZ = m_EndZ - m_StartZ - 1;
		int NumPositions = 2 * SizeX + 2 * SizeZ;
		int FirstChestPos = rnd % NumPositions;  // The corner positions are a bit more likely, but we don't mind
		rnd = rnd / 512;
		int SecondChestPos = (FirstChestPos + 2 + (rnd % (NumPositions - 3))) % NumPositions;
		m_Chest1 = DecodeChestCoords(FirstChestPos,  SizeX, SizeZ);
		m_Chest2 = DecodeChestCoords(SecondChestPos, SizeX, SizeZ);
	}

protected:

	// The X range of the room, start inclusive, end exclusive:
	int m_StartX, m_EndX;

	// The Z range of the room, start inclusive, end exclusive:
	int m_StartZ, m_EndZ;

	/** The Y coord of the floor of the room */
	int m_FloorHeight;

	/** The (absolute) coords of the first chest. The Y coord represents the chest's Meta value (facing). */
	Vector3i m_Chest1;

	/** The (absolute) coords of the second chest. The Y coord represents the chest's Meta value (facing). */
	Vector3i m_Chest2;

	/** Decodes the position index along the room walls into a proper 2D position for a chest. */
	Vector3i DecodeChestCoords(int a_PosIdx, int a_SizeX, int a_SizeZ)
	{
		if (a_PosIdx < a_SizeX)
		{
			// Return a coord on the ZM side of the room:
			return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZP, m_StartZ + 1);
		}
		a_PosIdx -= a_SizeX;
		if (a_PosIdx < a_SizeZ)
		{
			// Return a coord on the XP side of the room:
			return Vector3i(m_EndX - 1, E_META_CHEST_FACING_XM, m_StartZ + a_PosIdx + 1);
		}
		a_PosIdx -= a_SizeZ;
		if (a_PosIdx < a_SizeX)
		{
			// Return a coord on the ZP side of the room:
			return Vector3i(m_StartX + a_PosIdx + 1, E_META_CHEST_FACING_ZM, m_StartZ + 1);
		}
		a_PosIdx -= a_SizeX;
		// Return a coord on the XM side of the room:
		return Vector3i(m_StartX + 1, E_META_CHEST_FACING_XP, m_StartZ + a_PosIdx + 1);
	}

	/** Fills the specified area of blocks in the chunk with the specified blocktype if they are one of the overwritten block types.
	The coords are absolute, start coords are inclusive, end coords are exclusive. */
	void ReplaceCuboid(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType)
	{
		int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
		int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
		int RelEndX   = Clamp(a_EndX - BlockX,   0, cChunkDef::Width);
		int RelEndZ   = Clamp(a_EndZ - BlockZ,   0, cChunkDef::Width);
		for (int y = a_StartY; y < a_EndY; y++)
		{
			for (int z = RelStartZ; z < RelEndZ; z++)
			{
				for (int x = RelStartX; x < RelEndX; x++)
				{
					if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
					{
						a_ChunkDesc.SetBlockType(x, y, z, a_DstBlockType);
					}
				}  // for x
			}  // for z
		}  // for z
	}

	/** Fills the specified area of blocks in the chunk with a random pattern of the specified blocktypes, if they are one of the overwritten block types.
	The coords are absolute, start coords are inclusive, end coords are exclusive. The first blocktype uses 75% chance, the second 25% chance. */
	void ReplaceCuboidRandom(cChunkDesc & a_ChunkDesc, int a_StartX, int a_StartY, int a_StartZ, int a_EndX, int a_EndY, int a_EndZ, BLOCKTYPE a_DstBlockType1, BLOCKTYPE a_DstBlockType2)
	{
		int BlockX = a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int BlockZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		int RelStartX = Clamp(a_StartX - BlockX, 0, cChunkDef::Width - 1);
		int RelStartZ = Clamp(a_StartZ - BlockZ, 0, cChunkDef::Width - 1);
		int RelEndX   = Clamp(a_EndX - BlockX,   0, cChunkDef::Width);
		int RelEndZ   = Clamp(a_EndZ - BlockZ,   0, cChunkDef::Width);
		cFastRandom rnd;
		for (int y = a_StartY; y < a_EndY; y++)
		{
			for (int z = RelStartZ; z < RelEndZ; z++)
			{
				for (int x = RelStartX; x < RelEndX; x++)
				{
					if (cBlockInfo::CanBeTerraformed(a_ChunkDesc.GetBlockType(x, y, z)))
					{
						BLOCKTYPE BlockType = (rnd.NextInt(101) < 75) ? a_DstBlockType1 : a_DstBlockType2;
						a_ChunkDesc.SetBlockType(x, y, z, BlockType);
					}
				}  // for x
			}  // for z
		}  // for z
	}

	/** Tries to place a chest at the specified (absolute) coords.
	Does nothing if the coords are outside the chunk. */
	void TryPlaceChest(cChunkDesc & a_ChunkDesc, const Vector3i & a_Chest)
	{
		int RelX = a_Chest.x - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int RelZ = a_Chest.z - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		if (
			(RelX < 0) || (RelX >= cChunkDef::Width) ||  // The X coord is not in this chunk
			(RelZ < 0) || (RelZ >= cChunkDef::Width)     // The Z coord is not in this chunk
		)
		{
			return;
		}
		a_ChunkDesc.SetBlockTypeMeta(RelX, m_FloorHeight + 1, RelZ, E_BLOCK_CHEST, (NIBBLETYPE)a_Chest.y);

		// TODO: Fill the chest with random loot
	}

	// cGridStructGen::cStructure override:
	virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override
	{
		if (
			(m_EndX   <  a_ChunkDesc.GetChunkX() * cChunkDef::Width) ||
			(m_StartX >= a_ChunkDesc.GetChunkX() * cChunkDef::Width + cChunkDef::Width) ||
			(m_EndZ   <  a_ChunkDesc.GetChunkZ() * cChunkDef::Width) ||
			(m_StartZ >= a_ChunkDesc.GetChunkZ() * cChunkDef::Width + cChunkDef::Width)
		)
		{
			// The chunk is not intersecting the room at all, bail out
			return;
		}
		int b = m_FloorHeight + 1;  // Bottom
		int t = m_FloorHeight + 1 + ROOM_HEIGHT;  // Top
		ReplaceCuboidRandom(a_ChunkDesc, m_StartX, m_FloorHeight, m_StartZ, m_EndX + 1, b, m_EndZ + 1, E_BLOCK_MOSSY_COBBLESTONE, E_BLOCK_COBBLESTONE);  // Floor
		ReplaceCuboid(a_ChunkDesc, m_StartX + 1, b, m_StartZ + 1, m_EndX, t, m_EndZ, E_BLOCK_AIR);  // Insides

		// Walls:
		ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_StartX + 1, t, m_EndZ,       E_BLOCK_COBBLESTONE);  // XM wall
		ReplaceCuboid(a_ChunkDesc, m_EndX,   b, m_StartZ, m_EndX + 1,   t, m_EndZ,       E_BLOCK_COBBLESTONE);  // XP wall
		ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_StartZ, m_EndX + 1,   t, m_StartZ + 1, E_BLOCK_COBBLESTONE);  // ZM wall
		ReplaceCuboid(a_ChunkDesc, m_StartX, b, m_EndZ,   m_EndX + 1,   t, m_EndZ + 1,   E_BLOCK_COBBLESTONE);  // ZP wall

		// Place chests:
		TryPlaceChest(a_ChunkDesc, m_Chest1);
		TryPlaceChest(a_ChunkDesc, m_Chest2);

		// Place the spawner:
		int CenterX = (m_StartX + m_EndX) / 2 - a_ChunkDesc.GetChunkX() * cChunkDef::Width;
		int CenterZ = (m_StartZ + m_EndZ) / 2 - a_ChunkDesc.GetChunkZ() * cChunkDef::Width;
		if (
			(CenterX >= 0) && (CenterX < cChunkDef::Width) &&
			(CenterZ >= 0) && (CenterZ < cChunkDef::Width)
		)
		{
			a_ChunkDesc.SetBlockTypeMeta(CenterX, b, CenterZ, E_BLOCK_MOB_SPAWNER, 0);
			// TODO: Set the spawned mob
		}
	}
} ;

////////////////////////////////////////////////////////////////////////////////
// cDungeonRoomsFinisher:

cDungeonRoomsFinisher::cDungeonRoomsFinisher(cTerrainHeightGen & a_HeightGen, int a_Seed, int a_GridSize, int a_MaxSize, int a_MinSize, const AString & a_HeightDistrib) :
	super(a_Seed + 100, a_GridSize, a_GridSize, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 1024),
	m_HeightGen(a_HeightGen),
	m_MaxHalfSize((a_MaxSize + 1) / 2),
	m_MinHalfSize((a_MinSize + 1) / 2),
	m_HeightProbability(cChunkDef::Height)
{
	// Initialize the height probability distribution:
	m_HeightProbability.SetDefString(a_HeightDistrib);

	// Normalize the min and max size:
	if (m_MinHalfSize > m_MaxHalfSize)
	{
		std::swap(m_MinHalfSize, m_MaxHalfSize);
	}
}

cDungeonRoomsFinisher::cStructurePtr cDungeonRoomsFinisher::CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ)
{
	// Select a random room size in each direction:
	int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 7;
	int HalfSizeX = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
	rnd = rnd / 32;
	int HalfSizeZ = m_MinHalfSize + (rnd % (m_MaxHalfSize - m_MinHalfSize + 1));
	rnd = rnd / 32;

	// Select a random floor height for the room, based on the height generator:
	int ChunkX, ChunkZ;
	int RelX = a_OriginX, RelY = 0, RelZ = a_OriginZ;
	cChunkDef::AbsoluteToRelative(RelX, RelY, RelZ, ChunkX, ChunkZ);
	cChunkDef::HeightMap HeightMap;
	m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap);
	int Height = cChunkDef::GetHeight(HeightMap, RelX, RelZ);  // Max room height at {a_OriginX, a_OriginZ}
	Height = Clamp(m_HeightProbability.MapValue(rnd % m_HeightProbability.GetSum()), 10, Height - 5);

	// Create the dungeon room descriptor:
	return cStructurePtr(new cDungeonRoom(a_GridX, a_GridZ, a_OriginX, a_OriginZ, HalfSizeX, HalfSizeZ, Height, m_Noise));
}

<|endoftext|>


<commit_before>/**
* Released under the same permissive MIT-license as Urho3D.
* https://raw.githubusercontent.com/urho3d/Urho3D/master/License.txt
*/

#include <string>
#include <memory>

#include <Urho3D/Urho3D.h>
#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Graphics/RenderPath.h>
#include <Urho3D/Engine/Application.h>
#include <Urho3D/Engine/Engine.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/Input/InputEvents.h>
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Resource/XMLFile.h>
#include <Urho3D/IO/Log.h>
#include <Urho3D/UI/UI.h>
#include <Urho3D/UI/Text.h>
#include <Urho3D/UI/Font.h>
#include <Urho3D/UI/Button.h>
#include <Urho3D/UI/UIEvents.h>
#include <Urho3D/Scene/Scene.h>
#include <Urho3D/Scene/SceneEvents.h>
#include <Urho3D/Graphics/Graphics.h>
#include <Urho3D/Graphics/Camera.h>
#include <Urho3D/Graphics/Geometry.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/Graphics/DebugRenderer.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/Light.h>
#include <Urho3D/Graphics/Model.h>
#include <Urho3D/Graphics/StaticModel.h>
#include <Urho3D/Graphics/Material.h>
#include <Urho3D/Graphics/Skybox.h>
#include <Urho3D/Graphics/Zone.h>
#include <Urho3D/Audio/Sound.h>
#include <Urho3D/Audio/SoundSource3D.h>
#include <Urho3D/Audio/SoundListener.h>
#include <Urho3D/Audio/Audio.h>

#include "gs_main_menu.h"
#include "gs_playing.h"

using namespace Urho3D;

class MyApp : public Application
{
public:
    SharedPtr<Scene> scene_;
    Node* cameraNode_;

    MyApp(Context * context) : Application(context)
    {
    }

    virtual void Setup()
    {
        engineParameters_["FullScreen"]=false;
        engineParameters_["WindowWidth"]=1280;
        engineParameters_["WindowHeight"]=720;
        engineParameters_["WindowResizable"]=true;
        engineParameters_["Multisample"]=4;
    }

    virtual void Start()
    {
        ResourceCache* cache=GetSubsystem<ResourceCache>();
        GetSubsystem<UI>()->GetRoot()->SetDefaultStyle(cache->GetResource<XMLFile>("UI/DefaultStyle.xml"));

        scene_=new Scene(context_);
        scene_->CreateComponent<Octree>();
        scene_->CreateComponent<DebugRenderer>();

        // until we get a better sky system
        Node* skyNode=scene_->CreateChild("Sky");
        skyNode->SetScale(500.0f);
        Skybox* skybox=skyNode->CreateComponent<Skybox>();
        skybox->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        skybox->SetMaterial(cache->GetResource<Material>("Materials/Skybox.xml"));

        cameraNode_=scene_->CreateChild("Camera");
        Camera* camera=cameraNode_->CreateComponent<Camera>();
        camera->SetFarClip(10000);
        SoundListener* listener=cameraNode_->CreateComponent<SoundListener>();
        GetSubsystem<Audio>()->SetListener(listener);

        Renderer* renderer=GetSubsystem<Renderer>();
        SharedPtr<Viewport> viewport(new Viewport(context_,scene_,cameraNode_->GetComponent<Camera>()));
        renderer->SetViewport(0,viewport);
        renderer->SetShadowMapSize(4096);
        renderer->SetHDRRendering(true);

        RenderPath* effectRenderPath=viewport->GetRenderPath();
        effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/AutoExposure.xml"));
        effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/BloomHDR.xml"));
        effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/FXAA2.xml"));
        //effectRenderPath.SetEnabled("GammaCorrection",false);
        viewport->SetRenderPath(effectRenderPath);

        Node* zoneNode=scene_->CreateChild("Zone");
        Zone* zone=zoneNode->CreateComponent<Zone>();
        zone->SetBoundingBox(BoundingBox(-20000.0f,20000.0f));
        zone->SetFogStart(100.0f);
        zone->SetFogEnd(5000.0f);
        zone->SetAmbientColor(Color(0.1,0.1,0.1));

        SubscribeToEvent(E_KEYDOWN,HANDLER(MyApp,HandleKeyDown));
        SubscribeToEvent(E_UPDATE,HANDLER(MyApp,HandleUpdate));

        // fill our game state shared variables
        globals::instance()->cache=cache;
        globals::instance()->camera=camera;
        globals::instance()->scene=scene_;
        globals::instance()->context=context_;
        globals::instance()->ui_root=GetSubsystem<UI>()->GetRoot();
        globals::instance()->engine=engine_;
        globals::instance()->game_states.emplace_back(new gs_main_menu);
    }
    virtual void Stop()
    {
        globals::instance()->game_states.resize(0);
    }

    void HandleKeyDown(StringHash eventType,VariantMap& eventData)
    {
        using namespace KeyDown;
        int key=eventData[P_KEY].GetInt();

        if(key==KEY_TAB)
        {
            GetSubsystem<Input>()->SetMouseVisible(!GetSubsystem<Input>()->IsMouseVisible());
            GetSubsystem<Input>()->SetMouseGrabbed(!GetSubsystem<Input>()->IsMouseGrabbed());
        }
    }

    void HandleUpdate(StringHash eventType,VariantMap& eventData)
    {

    }
};

DEFINE_APPLICATION_MAIN(MyApp)
<commit_msg>Reduced shadow map size from 4096 to 1024 to improve the framerate. This would be a nice game setting.<commit_after>/**
* Released under the same permissive MIT-license as Urho3D.
* https://raw.githubusercontent.com/urho3d/Urho3D/master/License.txt
*/

#include <string>
#include <memory>

#include <Urho3D/Urho3D.h>
#include <Urho3D/Core/CoreEvents.h>
#include <Urho3D/Graphics/RenderPath.h>
#include <Urho3D/Engine/Application.h>
#include <Urho3D/Engine/Engine.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/Input/InputEvents.h>
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Resource/XMLFile.h>
#include <Urho3D/IO/Log.h>
#include <Urho3D/UI/UI.h>
#include <Urho3D/UI/Text.h>
#include <Urho3D/UI/Font.h>
#include <Urho3D/UI/Button.h>
#include <Urho3D/UI/UIEvents.h>
#include <Urho3D/Scene/Scene.h>
#include <Urho3D/Scene/SceneEvents.h>
#include <Urho3D/Graphics/Graphics.h>
#include <Urho3D/Graphics/Camera.h>
#include <Urho3D/Graphics/Geometry.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/Graphics/DebugRenderer.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/Light.h>
#include <Urho3D/Graphics/Model.h>
#include <Urho3D/Graphics/StaticModel.h>
#include <Urho3D/Graphics/Material.h>
#include <Urho3D/Graphics/Skybox.h>
#include <Urho3D/Graphics/Zone.h>
#include <Urho3D/Audio/Sound.h>
#include <Urho3D/Audio/SoundSource3D.h>
#include <Urho3D/Audio/SoundListener.h>
#include <Urho3D/Audio/Audio.h>

#include "gs_main_menu.h"
#include "gs_playing.h"

using namespace Urho3D;

class MyApp : public Application
{
public:
    SharedPtr<Scene> scene_;
    Node* cameraNode_;

    MyApp(Context * context) : Application(context)
    {
    }

    virtual void Setup()
    {
        engineParameters_["FullScreen"]=false;
        engineParameters_["WindowWidth"]=1280;
        engineParameters_["WindowHeight"]=720;
        engineParameters_["WindowResizable"]=true;
        engineParameters_["Multisample"]=4;
    }

    virtual void Start()
    {
        ResourceCache* cache=GetSubsystem<ResourceCache>();
        GetSubsystem<UI>()->GetRoot()->SetDefaultStyle(cache->GetResource<XMLFile>("UI/DefaultStyle.xml"));

        scene_=new Scene(context_);
        scene_->CreateComponent<Octree>();
        scene_->CreateComponent<DebugRenderer>();

        // until we get a better sky system
        Node* skyNode=scene_->CreateChild("Sky");
        skyNode->SetScale(500.0f);
        Skybox* skybox=skyNode->CreateComponent<Skybox>();
        skybox->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        skybox->SetMaterial(cache->GetResource<Material>("Materials/Skybox.xml"));

        cameraNode_=scene_->CreateChild("Camera");
        Camera* camera=cameraNode_->CreateComponent<Camera>();
        camera->SetFarClip(10000);
        SoundListener* listener=cameraNode_->CreateComponent<SoundListener>();
        GetSubsystem<Audio>()->SetListener(listener);

        Renderer* renderer=GetSubsystem<Renderer>();
        SharedPtr<Viewport> viewport(new Viewport(context_,scene_,cameraNode_->GetComponent<Camera>()));
        renderer->SetViewport(0,viewport);
        renderer->SetShadowMapSize(1024);
        renderer->SetHDRRendering(true);

        RenderPath* effectRenderPath=viewport->GetRenderPath();
        effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/AutoExposure.xml"));
        effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/BloomHDR.xml"));
        effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/FXAA2.xml"));
        //effectRenderPath.SetEnabled("GammaCorrection",false);
        viewport->SetRenderPath(effectRenderPath);

        Node* zoneNode=scene_->CreateChild("Zone");
        Zone* zone=zoneNode->CreateComponent<Zone>();
        zone->SetBoundingBox(BoundingBox(-20000.0f,20000.0f));
        zone->SetFogStart(100.0f);
        zone->SetFogEnd(5000.0f);
        zone->SetAmbientColor(Color(0.1,0.1,0.1));

        SubscribeToEvent(E_KEYDOWN,HANDLER(MyApp,HandleKeyDown));
        SubscribeToEvent(E_UPDATE,HANDLER(MyApp,HandleUpdate));

        // fill our game state shared variables
        globals::instance()->cache=cache;
        globals::instance()->camera=camera;
        globals::instance()->scene=scene_;
        globals::instance()->context=context_;
        globals::instance()->ui_root=GetSubsystem<UI>()->GetRoot();
        globals::instance()->engine=engine_;
        globals::instance()->game_states.emplace_back(new gs_main_menu);
    }
    virtual void Stop()
    {
        globals::instance()->game_states.resize(0);
    }

    void HandleKeyDown(StringHash eventType,VariantMap& eventData)
    {
        using namespace KeyDown;
        int key=eventData[P_KEY].GetInt();

        if(key==KEY_TAB)
        {
            GetSubsystem<Input>()->SetMouseVisible(!GetSubsystem<Input>()->IsMouseVisible());
            GetSubsystem<Input>()->SetMouseGrabbed(!GetSubsystem<Input>()->IsMouseGrabbed());
        }
    }

    void HandleUpdate(StringHash eventType,VariantMap& eventData)
    {

    }
};

DEFINE_APPLICATION_MAIN(MyApp)
<|endoftext|>


<commit_before>/* Please refer to license.txt */

#include "interface.hpp"

#include <iostream>

#include "../graphic/2d/2d.hpp"
#include "../graphic/window/window.hpp"

#include "../file/file.hpp"

namespace GEngine
{

namespace mui
{

Interface::Interface()
{
	//d2d = nullptr;
	cegui_system = nullptr;

	cegui_configfile_path = CEGUI_CONFIGFILE_PATH;
	cegui_logfile_path = CEGUI_LOGFILE_PATH;
	cegui_schemes_path = CEGUI_SCHEMES_PATH;
	cegui_imagesets_path = CEGUI_IMAGESETS_PATH;
	cegui_fonts_path = CEGUI_FONTS_PATH;
	cegui_layouts_path = CEGUI_LAYOUTS_PATH;
	cegui_looknfeels_path = CEGUI_LOOKNFEELS_PATH;
	cegui_luascripts_path = CEGUI_LUASCRIPTS_PATH;

	cegui_resourceprovider = nullptr;
	//cegui_root_window = nullptr;
	//cegui_windowmanager = nullptr;
}

Interface::~Interface()
{
	/*if (d2d)
	{
		d2d = nullptr;
	}

	if (cegui_root_window)
	{
		delete cegui_root_window;
	}*/

	cegui_system = nullptr;
	cegui_resourceprovider = nullptr;
}

bool Interface::initialize(mgfx::d2d::D2D &d2d, std::vector<std::string> cegui_schemes)
{
	//d2d = &_d2d;
	//d2d->window->showMouseCursor(false); //CEGUI's default schemes are fugly with the mouse or don't have one at all. Using default sfml mouse. //TODO: Handle mouse.

	try
	{
		CEGUI::OpenGLRenderer& myRenderer = CEGUI::OpenGLRenderer::create();

		std::string log_directory("");
		mfile::FileManager::separatePathFromFilename(cegui_logfile_path, log_directory);
		//Check if the directory the cegui logfile is going to be kept in exists. It not, create it.
		if (!mfile::FileManager::directoryExists(log_directory))
		{
			mfile::FileManager::mkDir(log_directory);
		}

		CEGUI::System::create(myRenderer, nullptr, nullptr, nullptr, nullptr, cegui_configfile_path, cegui_logfile_path);

		//Initialise the required dirs for the CEGUI DefaultResourceProvider.
		cegui_resourceprovider = static_cast<CEGUI::DefaultResourceProvider*>(CEGUI::System::getSingleton().getResourceProvider());
		cegui_resourceprovider->setResourceGroupDirectory("imagesets", cegui_imagesets_path);
		cegui_resourceprovider->setResourceGroupDirectory("fonts", cegui_fonts_path);
		cegui_resourceprovider->setResourceGroupDirectory("layouts", cegui_layouts_path);
		cegui_resourceprovider->setResourceGroupDirectory("looknfeels", cegui_looknfeels_path);
		cegui_resourceprovider->setResourceGroupDirectory("lua_scripts", cegui_luascripts_path);
		cegui_resourceprovider->setResourceGroupDirectory("schemes", cegui_schemes_path);
		//According to the documentation, this is only really needed if you are using Xerces and need to specify the schemas location.
		//cegui_resourceprovider->setResourceGroupDirectory("schemas", "datafiles/xml_schemas/");

		//Set the default resource groups to be used
		CEGUI::ImageManager::setImagesetDefaultResourceGroup("imagesets");
		CEGUI::Font::setDefaultResourceGroup("fonts");
		CEGUI::Scheme::setDefaultResourceGroup("schemes");
		CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
		CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
		CEGUI::WindowManager::setDefaultResourceGroup("layouts");
		//This is only needed if the resourceprovider's schemas is set.
		//Setup default group for validation schemas.
		//CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
		//if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
		//{
		//	parser->setProperty("SchemaDefaultResourceGroup", "schemas");
		//}

		//Load the schemes specified in cegui_schemes.
		for (std::vector<std::string>::iterator i = cegui_schemes.begin(); i != cegui_schemes.end(); ++i) //TODO: Vector iterator.
		{
			CEGUI::SchemeManager::getSingleton().createFromFile(*i + ".scheme");
			loaded_schemes.push_back(*i); //Save it so we know how to access it later, if needed.
		}

		//TODO: Handle the mouse.
		/*CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("GlossySerpent/MouseArrow");
		CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().show();*/

		//CEGUI::System::getSingleton().getDefaultGUIContext().setDefaultTooltipType("GlossySerpent/Tooltip"); //TODO: Set in XML, if possible.

		sf::Vector2i coords = sf::Mouse::getPosition(*d2d.window->window2d);
		CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(coords.x, coords.y);

		//Map SFML Key and Mouse stuff to CEGUI stuff for injecting input into CEGUI.
		mapSFMLKeysToCEGUI();
		mapSFMLMouseToCEGUI();

		d2d.cegui_gui_context = &CEGUI::System::getSingleton().getDefaultGUIContext(); //Point this accordingly.
		d2d.cegui_renderer = &myRenderer;
		d2d.default_d2d = true;
	}
	catch(CEGUI::Exception& e)
	{
		std::cout << "CEGUI Exception:" << e.getMessage().c_str() << "\n";
		return false;
	}

	addD2D(d2d); //Add the D2D to the list of D2Ds.

	return true; //Success.
}

bool Interface::loadFont(std::string filepath)
{
	font.loadFromFile(filepath);

	return true;
}

void Interface::update()
{
	std::vector<mgfx::d2d::D2D* >::iterator iter = windows.begin();
	for (iter = windows.begin(); iter != windows.end(); ++iter)
	//for (int i = 0; i < windows.size(); ++i)
	{
		mgfx::d2d::D2D *d2d = *iter; //First point to this so I don't have to type crazy things every time.
		//mgfx::d2d::D2D *d2d = windows[i]; //First point to this so I don't have to type crazy things every time.
		CEGUI::GUIContext& context = *d2d->cegui_gui_context; //Next, point to this so that I don't have to type out the full thing every time.

		context.getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.

		//Now, handle injecting events into CEGUI.
		for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
		{
			switch (d2d->window->events[i].type)
			{
			case sf::Event::KeyPressed:
				context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::KeyReleased:
				context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::TextEntered:
				context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
				break;
			case sf::Event::MouseMoved:
				{
					sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
					context.injectMousePosition(coords.x, coords.y);
				}
				break;
			case sf::Event::MouseButtonPressed:
				if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
				{
					context.injectMouseButtonDown(CEGUI::LeftButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
				{
					context.injectMouseButtonDown(CEGUI::MiddleButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
				{
					context.injectMouseButtonDown(CEGUI::RightButton);
				}
				break;
			case sf::Event::MouseButtonReleased:
				switch (d2d->window->events[i].mouseButton.button)
				{
				case sf::Mouse::Left:
					context.injectMouseButtonUp(CEGUI::LeftButton);
					break;
				case sf::Mouse::Middle:
					context.injectMouseButtonUp(CEGUI::MiddleButton);
					break;
				case sf::Mouse::Right:
					context.injectMouseButtonUp(CEGUI::RightButton);
					break;
				}
				break;
			case sf::Event::MouseWheelMoved:
				context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
				break;
			default:
				break;
			}
		}
	}

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs.

	/*CEGUI::GUIContext& context = CEGUI::System::getSingleton().getDefaultGUIContext();
	//First, handle injecting events into CEGUI.
	for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
	{
		switch (d2d->window->events[i].type)
		{
		case sf::Event::KeyPressed:
			context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::KeyReleased:
			context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::TextEntered:
			context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
			break;
		case sf::Event::MouseMoved:
			{
				sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
				context.injectMousePosition(coords.x, coords.y);
			}
			break;
		case sf::Event::MouseButtonPressed:
			if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
			{
				context.injectMouseButtonDown(CEGUI::LeftButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
			{
				context.injectMouseButtonDown(CEGUI::MiddleButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
			{
				context.injectMouseButtonDown(CEGUI::RightButton);
			}
			break;
		case sf::Event::MouseButtonReleased:
			switch (d2d->window->events[i].mouseButton.button)
			{
			case sf::Mouse::Left:
				context.injectMouseButtonUp(CEGUI::LeftButton);
				break;
			case sf::Mouse::Middle:
				context.injectMouseButtonUp(CEGUI::MiddleButton);
				break;
			case sf::Mouse::Right:
				context.injectMouseButtonUp(CEGUI::RightButton);
				break;
			}
			break;
		case sf::Event::MouseWheelMoved:
			context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
			break;
		default:
			break;
		}
	}

	//onMouseButtonUp //Use this to check if the frame window's button was pressed.

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs. //TODO: Make this work properly later.
	//CEGUI::System::getSingleton().getDefaultGUIContext().draw();
	//CEGUI::System::getSingleton().getDefaultGUIContext().getRenderTarget().draw();
	CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.*/
}

CEGUI::Window* Interface::getRootWindow(mgfx::d2d::D2D &d2d)
{
	//return cegui_root_window;
	return d2d.getRootWindow();
}

void Interface::setRootWindow(CEGUI::Window *window, mgfx::d2d::D2D &d2d) //Sets the root window.
{
	/*cegui_root_window = window;
	CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(cegui_root_window);*/
	d2d.cegui_root_window = window;
	d2d.cegui_gui_context->setRootWindow(d2d.cegui_root_window);
}

CEGUI::Window* Interface::createVirtualWindowFromLayout(std::string layout/*, bool root*/)
{
	CEGUI::Window *window = CEGUI::WindowManager::getSingleton().loadLayoutFromFile(layout);
	/*if (root) //If it's supposed to be the root window...
	{
		setRootWindow(window); //Set it.
	}*/

	return window;
}

void Interface::addD2D(mgfx::d2d::D2D &d2d)
{
	if (!d2d.cegui_renderer)
	{
		d2d.cegui_renderer = &CEGUI::OpenGLRenderer::create();
	}

	if (!d2d.cegui_gui_context)
	{
		d2d.cegui_gui_context = &CEGUI::System::getSingleton().createGUIContext(d2d.cegui_renderer->getDefaultRenderTarget());
	}

	windows.push_back(&d2d);
}

} //namespace mui

} //namespace GEngine
<commit_msg>Stuff<commit_after>/* Please refer to license.txt */

#include "interface.hpp"

#include <iostream>

#include "../graphic/2d/2d.hpp"
#include "../graphic/window/window.hpp"

#include "../file/file.hpp"

namespace GEngine
{

namespace mui
{

Interface::Interface()
{
	//d2d = nullptr;
	cegui_system = nullptr;

	cegui_configfile_path = CEGUI_CONFIGFILE_PATH;
	cegui_logfile_path = CEGUI_LOGFILE_PATH;
	cegui_schemes_path = CEGUI_SCHEMES_PATH;
	cegui_imagesets_path = CEGUI_IMAGESETS_PATH;
	cegui_fonts_path = CEGUI_FONTS_PATH;
	cegui_layouts_path = CEGUI_LAYOUTS_PATH;
	cegui_looknfeels_path = CEGUI_LOOKNFEELS_PATH;
	cegui_luascripts_path = CEGUI_LUASCRIPTS_PATH;

	cegui_resourceprovider = nullptr;
	//cegui_root_window = nullptr;
	//cegui_windowmanager = nullptr;
}

Interface::~Interface()
{
	/*if (d2d)
	{
		d2d = nullptr;
	}

	if (cegui_root_window)
	{
		delete cegui_root_window;
	}*/

	cegui_system = nullptr;
	cegui_resourceprovider = nullptr;
}

bool Interface::initialize(mgfx::d2d::D2D &d2d, std::vector<std::string> cegui_schemes)
{
	//d2d = &_d2d;
	//d2d->window->showMouseCursor(false); //CEGUI's default schemes are fugly with the mouse or don't have one at all. Using default sfml mouse. //TODO: Handle mouse.

	try
	{
		CEGUI::OpenGLRenderer& myRenderer = CEGUI::OpenGLRenderer::create();

		std::string log_directory("");
		mfile::FileManager::separatePathFromFilename(cegui_logfile_path, log_directory);
		//Check if the directory the cegui logfile is going to be kept in exists. It not, create it.
		if (!mfile::FileManager::directoryExists(log_directory))
		{
			mfile::FileManager::mkDir(log_directory);
		}

		CEGUI::System::create(myRenderer, nullptr, nullptr, nullptr, nullptr, cegui_configfile_path, cegui_logfile_path);

		//Initialise the required dirs for the CEGUI DefaultResourceProvider.
		cegui_resourceprovider = static_cast<CEGUI::DefaultResourceProvider*>(CEGUI::System::getSingleton().getResourceProvider());
		cegui_resourceprovider->setResourceGroupDirectory("imagesets", cegui_imagesets_path);
		cegui_resourceprovider->setResourceGroupDirectory("fonts", cegui_fonts_path);
		cegui_resourceprovider->setResourceGroupDirectory("layouts", cegui_layouts_path);
		cegui_resourceprovider->setResourceGroupDirectory("looknfeels", cegui_looknfeels_path);
		cegui_resourceprovider->setResourceGroupDirectory("lua_scripts", cegui_luascripts_path);
		cegui_resourceprovider->setResourceGroupDirectory("schemes", cegui_schemes_path);
		//According to the documentation, this is only really needed if you are using Xerces and need to specify the schemas location.
		//cegui_resourceprovider->setResourceGroupDirectory("schemas", "datafiles/xml_schemas/");

		//Set the default resource groups to be used
		CEGUI::ImageManager::setImagesetDefaultResourceGroup("imagesets");
		CEGUI::Font::setDefaultResourceGroup("fonts");
		CEGUI::Scheme::setDefaultResourceGroup("schemes");
		CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
		CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
		CEGUI::WindowManager::setDefaultResourceGroup("layouts");
		//This is only needed if the resourceprovider's schemas is set.
		//Setup default group for validation schemas.
		//CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
		//if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
		//{
		//	parser->setProperty("SchemaDefaultResourceGroup", "schemas");
		//}

		//Load the schemes specified in cegui_schemes.
		for (std::vector<std::string>::iterator i = cegui_schemes.begin(); i != cegui_schemes.end(); ++i) //TODO: Vector iterator.
		{
			CEGUI::SchemeManager::getSingleton().createFromFile(*i + ".scheme");
			loaded_schemes.push_back(*i); //Save it so we know how to access it later, if needed.
		}

		//TODO: Handle the mouse.
		/*CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("GlossySerpent/MouseArrow");
		CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().show();*/

		//CEGUI::System::getSingleton().getDefaultGUIContext().setDefaultTooltipType("GlossySerpent/Tooltip"); //TODO: Set in XML, if possible.

		sf::Vector2i coords = sf::Mouse::getPosition(*d2d.window->window2d);
		CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(coords.x, coords.y);

		//Map SFML Key and Mouse stuff to CEGUI stuff for injecting input into CEGUI.
		mapSFMLKeysToCEGUI();
		mapSFMLMouseToCEGUI();

		d2d.cegui_gui_context = &CEGUI::System::getSingleton().getDefaultGUIContext(); //Point this accordingly.
		d2d.cegui_renderer = &myRenderer;
		d2d.default_d2d = true;
	}
	catch(CEGUI::Exception& e)
	{
		std::cout << "CEGUI Exception:" << e.getMessage().c_str() << "\n";
		return false;
	}

	addD2D(d2d); //Add the D2D to the list of D2Ds.

	return true; //Success.
}

bool Interface::loadFont(std::string filepath)
{
	font.loadFromFile(filepath);

	return true;
}

void Interface::update()
{
	std::vector<mgfx::d2d::D2D* >::iterator iter;
	for (iter = windows.begin(); iter != windows.end(); ++iter)
	//for (int i = 0; i < windows.size(); ++i)
	{
		mgfx::d2d::D2D *d2d = *iter; //First point to this so I don't have to type crazy things every time.
		//mgfx::d2d::D2D *d2d = windows[i]; //First point to this so I don't have to type crazy things every time.
		CEGUI::GUIContext& context = *d2d->cegui_gui_context; //Next, point to this so that I don't have to type out the full thing every time.

		context.getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.

		//Now, handle injecting events into CEGUI.
		for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
		{
			switch (d2d->window->events[i].type)
			{
			case sf::Event::KeyPressed:
				context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::KeyReleased:
				context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::TextEntered:
				context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
				break;
			case sf::Event::MouseMoved:
				{
					sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
					context.injectMousePosition(coords.x, coords.y);
				}
				break;
			case sf::Event::MouseButtonPressed:
				if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
				{
					context.injectMouseButtonDown(CEGUI::LeftButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
				{
					context.injectMouseButtonDown(CEGUI::MiddleButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
				{
					context.injectMouseButtonDown(CEGUI::RightButton);
				}
				break;
			case sf::Event::MouseButtonReleased:
				switch (d2d->window->events[i].mouseButton.button)
				{
				case sf::Mouse::Left:
					context.injectMouseButtonUp(CEGUI::LeftButton);
					break;
				case sf::Mouse::Middle:
					context.injectMouseButtonUp(CEGUI::MiddleButton);
					break;
				case sf::Mouse::Right:
					context.injectMouseButtonUp(CEGUI::RightButton);
					break;
				}
				break;
			case sf::Event::MouseWheelMoved:
				context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
				break;
			default:
				break;
			}
		}
	}

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs.

	/*CEGUI::GUIContext& context = CEGUI::System::getSingleton().getDefaultGUIContext();
	//First, handle injecting events into CEGUI.
	for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
	{
		switch (d2d->window->events[i].type)
		{
		case sf::Event::KeyPressed:
			context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::KeyReleased:
			context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::TextEntered:
			context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
			break;
		case sf::Event::MouseMoved:
			{
				sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
				context.injectMousePosition(coords.x, coords.y);
			}
			break;
		case sf::Event::MouseButtonPressed:
			if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
			{
				context.injectMouseButtonDown(CEGUI::LeftButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
			{
				context.injectMouseButtonDown(CEGUI::MiddleButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
			{
				context.injectMouseButtonDown(CEGUI::RightButton);
			}
			break;
		case sf::Event::MouseButtonReleased:
			switch (d2d->window->events[i].mouseButton.button)
			{
			case sf::Mouse::Left:
				context.injectMouseButtonUp(CEGUI::LeftButton);
				break;
			case sf::Mouse::Middle:
				context.injectMouseButtonUp(CEGUI::MiddleButton);
				break;
			case sf::Mouse::Right:
				context.injectMouseButtonUp(CEGUI::RightButton);
				break;
			}
			break;
		case sf::Event::MouseWheelMoved:
			context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
			break;
		default:
			break;
		}
	}

	//onMouseButtonUp //Use this to check if the frame window's button was pressed.

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs. //TODO: Make this work properly later.
	//CEGUI::System::getSingleton().getDefaultGUIContext().draw();
	//CEGUI::System::getSingleton().getDefaultGUIContext().getRenderTarget().draw();
	CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.*/
}

CEGUI::Window* Interface::getRootWindow(mgfx::d2d::D2D &d2d)
{
	//return cegui_root_window;
	return d2d.getRootWindow();
}

void Interface::setRootWindow(CEGUI::Window *window, mgfx::d2d::D2D &d2d) //Sets the root window.
{
	/*cegui_root_window = window;
	CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(cegui_root_window);*/
	d2d.cegui_root_window = window;
	d2d.cegui_gui_context->setRootWindow(d2d.cegui_root_window);
}

CEGUI::Window* Interface::createVirtualWindowFromLayout(std::string layout/*, bool root*/)
{
	CEGUI::Window *window = CEGUI::WindowManager::getSingleton().loadLayoutFromFile(layout);
	/*if (root) //If it's supposed to be the root window...
	{
		setRootWindow(window); //Set it.
	}*/

	return window;
}

void Interface::addD2D(mgfx::d2d::D2D &d2d)
{
	if (!d2d.cegui_renderer)
	{
		d2d.cegui_renderer = &CEGUI::OpenGLRenderer::create();
	}

	if (!d2d.cegui_gui_context)
	{
		d2d.cegui_gui_context = &CEGUI::System::getSingleton().createGUIContext(d2d.cegui_renderer->getDefaultRenderTarget());
	}

	windows.push_back(&d2d);
}

} //namespace mui

} //namespace GEngine
<|endoftext|>


<commit_before>/* Please refer to license.txt */

#include "interface.hpp"

#include <iostream>

#include "../graphic/2d/2d.hpp"
#include "../graphic/window/window.hpp"

#include "../file/file.hpp"

namespace GEngine
{

namespace mui
{

Interface::Interface()
{
	//d2d = nullptr;
	cegui_system = nullptr;

	cegui_configfile_path = CEGUI_CONFIGFILE_PATH;
	cegui_logfile_path = CEGUI_LOGFILE_PATH;
	cegui_schemes_path = CEGUI_SCHEMES_PATH;
	cegui_imagesets_path = CEGUI_IMAGESETS_PATH;
	cegui_fonts_path = CEGUI_FONTS_PATH;
	cegui_layouts_path = CEGUI_LAYOUTS_PATH;
	cegui_looknfeels_path = CEGUI_LOOKNFEELS_PATH;
	cegui_luascripts_path = CEGUI_LUASCRIPTS_PATH;

	cegui_resourceprovider = nullptr;
	//cegui_root_window = nullptr;
	//cegui_windowmanager = nullptr;
}

Interface::~Interface()
{
	/*if (d2d)
	{
		d2d = nullptr;
	}

	if (cegui_root_window)
	{
		delete cegui_root_window;
	}*/

	cegui_system = nullptr;
	cegui_resourceprovider = nullptr;
}

bool Interface::initialize(mgfx::d2d::D2D &d2d, std::vector<std::string> cegui_schemes)
{
	//d2d = &_d2d;
	//d2d->window->showMouseCursor(false); //CEGUI's default schemes are fugly with the mouse or don't have one at all. Using default sfml mouse. //TODO: Handle mouse.

	try
	{
		CEGUI::OpenGLRenderer& myRenderer = CEGUI::OpenGLRenderer::create();

		std::string log_directory("");
		mfile::FileManager::separatePathFromFilename(cegui_logfile_path, log_directory);
		//Check if the directory the cegui logfile is going to be kept in exists. It not, create it.
		if (!mfile::FileManager::directoryExists(log_directory))
		{
			mfile::FileManager::mkDir(log_directory);
		}

		CEGUI::System::create(myRenderer, nullptr, nullptr, nullptr, nullptr, cegui_configfile_path, cegui_logfile_path);

		//Initialise the required dirs for the CEGUI DefaultResourceProvider.
		cegui_resourceprovider = static_cast<CEGUI::DefaultResourceProvider*>(CEGUI::System::getSingleton().getResourceProvider());
		cegui_resourceprovider->setResourceGroupDirectory("imagesets", cegui_imagesets_path);
		cegui_resourceprovider->setResourceGroupDirectory("fonts", cegui_fonts_path);
		cegui_resourceprovider->setResourceGroupDirectory("layouts", cegui_layouts_path);
		cegui_resourceprovider->setResourceGroupDirectory("looknfeels", cegui_looknfeels_path);
		cegui_resourceprovider->setResourceGroupDirectory("lua_scripts", cegui_luascripts_path);
		cegui_resourceprovider->setResourceGroupDirectory("schemes", cegui_schemes_path);
		//According to the documentation, this is only really needed if you are using Xerces and need to specify the schemas location.
		//cegui_resourceprovider->setResourceGroupDirectory("schemas", "datafiles/xml_schemas/");

		//Set the default resource groups to be used
		CEGUI::ImageManager::setImagesetDefaultResourceGroup("imagesets");
		CEGUI::Font::setDefaultResourceGroup("fonts");
		CEGUI::Scheme::setDefaultResourceGroup("schemes");
		CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
		CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
		CEGUI::WindowManager::setDefaultResourceGroup("layouts");
		//This is only needed if the resourceprovider's schemas is set.
		//Setup default group for validation schemas.
		//CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
		//if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
		//{
		//	parser->setProperty("SchemaDefaultResourceGroup", "schemas");
		//}

		//Load the schemes specified in cegui_schemes.
		for (std::vector<std::string>::iterator i = cegui_schemes.begin(); i != cegui_schemes.end(); ++i) //TODO: Vector iterator.
		{
			CEGUI::SchemeManager::getSingleton().createFromFile(*i + ".scheme");
			loaded_schemes.push_back(*i); //Save it so we know how to access it later, if needed.
		}

		//TODO: Handle the mouse.
		/*CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("GlossySerpent/MouseArrow");
		CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().show();*/

		//CEGUI::System::getSingleton().getDefaultGUIContext().setDefaultTooltipType("GlossySerpent/Tooltip"); //TODO: Set in XML, if possible.

		sf::Vector2i coords = sf::Mouse::getPosition(*d2d.window->window2d);
		CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(coords.x, coords.y);

		//Map SFML Key and Mouse stuff to CEGUI stuff for injecting input into CEGUI.
		mapSFMLKeysToCEGUI();
		mapSFMLMouseToCEGUI();

		d2d.cegui_gui_context = &CEGUI::System::getSingleton().getDefaultGUIContext(); //Point this accordingly.
		d2d.cegui_renderer = &myRenderer;
		d2d.default_d2d = true;
	}
	catch(CEGUI::Exception& e)
	{
		std::cout << "CEGUI Exception:" << e.getMessage().c_str() << "\n";
		return false;
	}

	addD2D(d2d); //Add the D2D to the list of D2Ds.

	return true; //Success.
}

bool Interface::loadFont(std::string filepath)
{
	font.loadFromFile(filepath);

	return true;
}

void Interface::update()
{
	for (std::vector<mgfx::d2d::D2D* >::iterator iter = windows.begin(); iter != windows.end(); ++iter)
	//for (int i = 0; i < windows.size(); ++i)
	{
		if (windows.size() > 1)
		{
			//std::cout << "More than one & i = " << i << "\n";
			//std::cout << "More than 1.\n";
		}
		mgfx::d2d::D2D *d2d = *iter; //First point to this so I don't have to type crazy things every time.
		//mgfx::d2d::D2D *d2d = windows[i]; //First point to this so I don't have to type crazy things every time.
		CEGUI::GUIContext& context = *d2d->cegui_gui_context; //Next, point to this so that I don't have to type out the full thing every time.

		context.getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.

		//Now, handle injecting events into CEGUI.
		for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
		{
			switch (d2d->window->events[i].type)
			{
			case sf::Event::KeyPressed:
				context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::KeyReleased:
				context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::TextEntered:
				context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
				break;
			case sf::Event::MouseMoved:
				{
					sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
					context.injectMousePosition(coords.x, coords.y);
				}
				break;
			case sf::Event::MouseButtonPressed:
				if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
				{
					context.injectMouseButtonDown(CEGUI::LeftButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
				{
					context.injectMouseButtonDown(CEGUI::MiddleButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
				{
					context.injectMouseButtonDown(CEGUI::RightButton);
				}
				break;
			case sf::Event::MouseButtonReleased:
				switch (d2d->window->events[i].mouseButton.button)
				{
				case sf::Mouse::Left:
					context.injectMouseButtonUp(CEGUI::LeftButton);
					break;
				case sf::Mouse::Middle:
					context.injectMouseButtonUp(CEGUI::MiddleButton);
					break;
				case sf::Mouse::Right:
					context.injectMouseButtonUp(CEGUI::RightButton);
					break;
				}
				break;
			case sf::Event::MouseWheelMoved:
				context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
				break;
			default:
				break;
			}
		}
	}

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs.

	/*CEGUI::GUIContext& context = CEGUI::System::getSingleton().getDefaultGUIContext();
	//First, handle injecting events into CEGUI.
	for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
	{
		switch (d2d->window->events[i].type)
		{
		case sf::Event::KeyPressed:
			context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::KeyReleased:
			context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::TextEntered:
			context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
			break;
		case sf::Event::MouseMoved:
			{
				sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
				context.injectMousePosition(coords.x, coords.y);
			}
			break;
		case sf::Event::MouseButtonPressed:
			if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
			{
				context.injectMouseButtonDown(CEGUI::LeftButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
			{
				context.injectMouseButtonDown(CEGUI::MiddleButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
			{
				context.injectMouseButtonDown(CEGUI::RightButton);
			}
			break;
		case sf::Event::MouseButtonReleased:
			switch (d2d->window->events[i].mouseButton.button)
			{
			case sf::Mouse::Left:
				context.injectMouseButtonUp(CEGUI::LeftButton);
				break;
			case sf::Mouse::Middle:
				context.injectMouseButtonUp(CEGUI::MiddleButton);
				break;
			case sf::Mouse::Right:
				context.injectMouseButtonUp(CEGUI::RightButton);
				break;
			}
			break;
		case sf::Event::MouseWheelMoved:
			context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
			break;
		default:
			break;
		}
	}

	//onMouseButtonUp //Use this to check if the frame window's button was pressed.

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs. //TODO: Make this work properly later.
	//CEGUI::System::getSingleton().getDefaultGUIContext().draw();
	//CEGUI::System::getSingleton().getDefaultGUIContext().getRenderTarget().draw();
	CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.*/
}

CEGUI::Window* Interface::getRootWindow(mgfx::d2d::D2D &d2d)
{
	//return cegui_root_window;
	return d2d.getRootWindow();
}

void Interface::setRootWindow(CEGUI::Window *window, mgfx::d2d::D2D &d2d) //Sets the root window.
{
	/*cegui_root_window = window;
	CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(cegui_root_window);*/
	d2d.cegui_root_window = window;
	d2d.cegui_gui_context->setRootWindow(d2d.cegui_root_window);
}

CEGUI::Window* Interface::createVirtualWindowFromLayout(std::string layout/*, bool root*/)
{
	CEGUI::Window *window = CEGUI::WindowManager::getSingleton().loadLayoutFromFile(layout);
	/*if (root) //If it's supposed to be the root window...
	{
		setRootWindow(window); //Set it.
	}*/

	return window;
}

void Interface::addD2D(mgfx::d2d::D2D &d2d)
{
	if (!d2d.cegui_renderer)
	{
		//When creating a renderer, perhaps force SFML to set the viewport to the d2d's window?
		d2d.cegui_renderer = &CEGUI::OpenGLRenderer::create();
	}

	if (!d2d.cegui_gui_context)
	{
		d2d.cegui_gui_context = &CEGUI::System::getSingleton().createGUIContext(d2d.cegui_renderer->getDefaultRenderTarget());
	}

	windows.push_back(&d2d);
}

} //namespace mui

} //namespace GEngine
<commit_msg>Testing if this contexts thing is working...<commit_after>/* Please refer to license.txt */

#include "interface.hpp"

#include <iostream>

#include "../graphic/2d/2d.hpp"
#include "../graphic/window/window.hpp"

#include "../file/file.hpp"

namespace GEngine
{

namespace mui
{

Interface::Interface()
{
	//d2d = nullptr;
	cegui_system = nullptr;

	cegui_configfile_path = CEGUI_CONFIGFILE_PATH;
	cegui_logfile_path = CEGUI_LOGFILE_PATH;
	cegui_schemes_path = CEGUI_SCHEMES_PATH;
	cegui_imagesets_path = CEGUI_IMAGESETS_PATH;
	cegui_fonts_path = CEGUI_FONTS_PATH;
	cegui_layouts_path = CEGUI_LAYOUTS_PATH;
	cegui_looknfeels_path = CEGUI_LOOKNFEELS_PATH;
	cegui_luascripts_path = CEGUI_LUASCRIPTS_PATH;

	cegui_resourceprovider = nullptr;
	//cegui_root_window = nullptr;
	//cegui_windowmanager = nullptr;
}

Interface::~Interface()
{
	/*if (d2d)
	{
		d2d = nullptr;
	}

	if (cegui_root_window)
	{
		delete cegui_root_window;
	}*/

	cegui_system = nullptr;
	cegui_resourceprovider = nullptr;
}

bool Interface::initialize(mgfx::d2d::D2D &d2d, std::vector<std::string> cegui_schemes)
{
	//d2d = &_d2d;
	//d2d->window->showMouseCursor(false); //CEGUI's default schemes are fugly with the mouse or don't have one at all. Using default sfml mouse. //TODO: Handle mouse.

	try
	{
		CEGUI::OpenGLRenderer& myRenderer = CEGUI::OpenGLRenderer::create();

		std::string log_directory("");
		mfile::FileManager::separatePathFromFilename(cegui_logfile_path, log_directory);
		//Check if the directory the cegui logfile is going to be kept in exists. It not, create it.
		if (!mfile::FileManager::directoryExists(log_directory))
		{
			mfile::FileManager::mkDir(log_directory);
		}

		CEGUI::System::create(myRenderer, nullptr, nullptr, nullptr, nullptr, cegui_configfile_path, cegui_logfile_path);

		//Initialise the required dirs for the CEGUI DefaultResourceProvider.
		cegui_resourceprovider = static_cast<CEGUI::DefaultResourceProvider*>(CEGUI::System::getSingleton().getResourceProvider());
		cegui_resourceprovider->setResourceGroupDirectory("imagesets", cegui_imagesets_path);
		cegui_resourceprovider->setResourceGroupDirectory("fonts", cegui_fonts_path);
		cegui_resourceprovider->setResourceGroupDirectory("layouts", cegui_layouts_path);
		cegui_resourceprovider->setResourceGroupDirectory("looknfeels", cegui_looknfeels_path);
		cegui_resourceprovider->setResourceGroupDirectory("lua_scripts", cegui_luascripts_path);
		cegui_resourceprovider->setResourceGroupDirectory("schemes", cegui_schemes_path);
		//According to the documentation, this is only really needed if you are using Xerces and need to specify the schemas location.
		//cegui_resourceprovider->setResourceGroupDirectory("schemas", "datafiles/xml_schemas/");

		//Set the default resource groups to be used
		CEGUI::ImageManager::setImagesetDefaultResourceGroup("imagesets");
		CEGUI::Font::setDefaultResourceGroup("fonts");
		CEGUI::Scheme::setDefaultResourceGroup("schemes");
		CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
		CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
		CEGUI::WindowManager::setDefaultResourceGroup("layouts");
		//This is only needed if the resourceprovider's schemas is set.
		//Setup default group for validation schemas.
		//CEGUI::XMLParser* parser = CEGUI::System::getSingleton().getXMLParser();
		//if (parser->isPropertyPresent("SchemaDefaultResourceGroup"))
		//{
		//	parser->setProperty("SchemaDefaultResourceGroup", "schemas");
		//}

		//Load the schemes specified in cegui_schemes.
		for (std::vector<std::string>::iterator i = cegui_schemes.begin(); i != cegui_schemes.end(); ++i) //TODO: Vector iterator.
		{
			CEGUI::SchemeManager::getSingleton().createFromFile(*i + ".scheme");
			loaded_schemes.push_back(*i); //Save it so we know how to access it later, if needed.
		}

		//TODO: Handle the mouse.
		/*CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("GlossySerpent/MouseArrow");
		CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().show();*/

		//CEGUI::System::getSingleton().getDefaultGUIContext().setDefaultTooltipType("GlossySerpent/Tooltip"); //TODO: Set in XML, if possible.

		sf::Vector2i coords = sf::Mouse::getPosition(*d2d.window->window2d);
		CEGUI::System::getSingleton().getDefaultGUIContext().injectMousePosition(coords.x, coords.y);

		//Map SFML Key and Mouse stuff to CEGUI stuff for injecting input into CEGUI.
		mapSFMLKeysToCEGUI();
		mapSFMLMouseToCEGUI();

		d2d.cegui_gui_context = &CEGUI::System::getSingleton().getDefaultGUIContext(); //Point this accordingly.
		d2d.cegui_renderer = &myRenderer;
		d2d.default_d2d = true;
	}
	catch(CEGUI::Exception& e)
	{
		std::cout << "CEGUI Exception:" << e.getMessage().c_str() << "\n";
		return false;
	}

	addD2D(d2d); //Add the D2D to the list of D2Ds.

	return true; //Success.
}

bool Interface::loadFont(std::string filepath)
{
	font.loadFromFile(filepath);

	return true;
}

void Interface::update()
{
	for (std::vector<mgfx::d2d::D2D* >::iterator iter = windows.begin(); iter != windows.end(); ++iter)
	//for (int i = 0; i < windows.size(); ++i)
	{
		if (windows.size() > 1)
		{
			//std::cout << "More than one & i = " << i << "\n";
			//std::cout << "More than 1.\n";
		}
		mgfx::d2d::D2D *d2d = *iter; //First point to this so I don't have to type crazy things every time.
		//mgfx::d2d::D2D *d2d = windows[i]; //First point to this so I don't have to type crazy things every time.
		CEGUI::GUIContext& context = *d2d->cegui_gui_context; //Next, point to this so that I don't have to type out the full thing every time.

		context.getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.

		//Now, handle injecting events into CEGUI.
		for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
		{
			switch (d2d->window->events[i].type)
			{
			case sf::Event::KeyPressed:
				context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::KeyReleased:
				context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
				break;
			case sf::Event::TextEntered:
				context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
				break;
			case sf::Event::MouseMoved:
				{
					sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
					context.injectMousePosition(coords.x, coords.y);
				}
				break;
			case sf::Event::MouseButtonPressed:
				if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
				{
					context.injectMouseButtonDown(CEGUI::LeftButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
				{
					context.injectMouseButtonDown(CEGUI::MiddleButton);
				}
				else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
				{
					context.injectMouseButtonDown(CEGUI::RightButton);
				}
				break;
			case sf::Event::MouseButtonReleased:
				switch (d2d->window->events[i].mouseButton.button)
				{
				case sf::Mouse::Left:
					context.injectMouseButtonUp(CEGUI::LeftButton);
					break;
				case sf::Mouse::Middle:
					context.injectMouseButtonUp(CEGUI::MiddleButton);
					break;
				case sf::Mouse::Right:
					context.injectMouseButtonUp(CEGUI::RightButton);
					break;
				}
				break;
			case sf::Event::MouseWheelMoved:
				context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
				break;
			default:
				break;
			}
		}

		glBegin(GL_TRIANGLES);
			glVertex3f(  0.0f,  1.0f, 0.0f );
			glVertex3f( -1.0f, -1.0f, 0.0f );
			glVertex3f(  1.0f, -1.0f, 0.0f );
		glEnd( );
	}

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs.

	/*CEGUI::GUIContext& context = CEGUI::System::getSingleton().getDefaultGUIContext();
	//First, handle injecting events into CEGUI.
	for (unsigned int i = 0; i < d2d->window->events.size(); ++i)
	{
		switch (d2d->window->events[i].type)
		{
		case sf::Event::KeyPressed:
			context.injectKeyDown(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::KeyReleased:
			context.injectKeyUp(sfml_cegui_keymap[d2d->window->events[i].key.code]);
			break;
		case sf::Event::TextEntered:
			context.injectChar(static_cast<char>(d2d->window->events[i].text.unicode));
			break;
		case sf::Event::MouseMoved:
			{
				sf::Vector2i coords = sf::Mouse::getPosition(*d2d->window->window2d);
				context.injectMousePosition(coords.x, coords.y);
			}
			break;
		case sf::Event::MouseButtonPressed:
			if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
			{
				context.injectMouseButtonDown(CEGUI::LeftButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Middle))
			{
				context.injectMouseButtonDown(CEGUI::MiddleButton);
			}
			else if (sf::Mouse::isButtonPressed(sf::Mouse::Right))
			{
				context.injectMouseButtonDown(CEGUI::RightButton);
			}
			break;
		case sf::Event::MouseButtonReleased:
			switch (d2d->window->events[i].mouseButton.button)
			{
			case sf::Mouse::Left:
				context.injectMouseButtonUp(CEGUI::LeftButton);
				break;
			case sf::Mouse::Middle:
				context.injectMouseButtonUp(CEGUI::MiddleButton);
				break;
			case sf::Mouse::Right:
				context.injectMouseButtonUp(CEGUI::RightButton);
				break;
			}
			break;
		case sf::Event::MouseWheelMoved:
			context.injectMouseWheelChange(d2d->window->events[i].mouseWheel.delta);
			break;
		default:
			break;
		}
	}

	//onMouseButtonUp //Use this to check if the frame window's button was pressed.

	CEGUI::System::getSingleton().renderAllGUIContexts(); //Render all of CEGUI's stuffs. //TODO: Make this work properly later.
	//CEGUI::System::getSingleton().getDefaultGUIContext().draw();
	//CEGUI::System::getSingleton().getDefaultGUIContext().getRenderTarget().draw();
	CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().draw(); //Force draw it because it doesn't seem to want to work otherwise.*/
}

CEGUI::Window* Interface::getRootWindow(mgfx::d2d::D2D &d2d)
{
	//return cegui_root_window;
	return d2d.getRootWindow();
}

void Interface::setRootWindow(CEGUI::Window *window, mgfx::d2d::D2D &d2d) //Sets the root window.
{
	/*cegui_root_window = window;
	CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(cegui_root_window);*/
	d2d.cegui_root_window = window;
	d2d.cegui_gui_context->setRootWindow(d2d.cegui_root_window);
}

CEGUI::Window* Interface::createVirtualWindowFromLayout(std::string layout/*, bool root*/)
{
	CEGUI::Window *window = CEGUI::WindowManager::getSingleton().loadLayoutFromFile(layout);
	/*if (root) //If it's supposed to be the root window...
	{
		setRootWindow(window); //Set it.
	}*/

	return window;
}

void Interface::addD2D(mgfx::d2d::D2D &d2d)
{
	if (!d2d.cegui_renderer)
	{
		//When creating a renderer, perhaps force SFML to set the viewport to the d2d's window?
		d2d.cegui_renderer = &CEGUI::OpenGLRenderer::create();
	}

	if (!d2d.cegui_gui_context)
	{
		d2d.cegui_gui_context = &CEGUI::System::getSingleton().createGUIContext(d2d.cegui_renderer->getDefaultRenderTarget());
	}

	windows.push_back(&d2d);
}

} //namespace mui

} //namespace GEngine
<|endoftext|>


<commit_before>/************************************************************
 *
 * uEcho for C
 *
 * Copyright (C) Satoshi Konno 2015
 *
 * This is licensed under BSD-style license, see file COPYING.
 *
 ************************************************************/

#include "TestDevice.h"

#undef UECHO_TEST_VERBOSE

void uecho_test_printrequest(uEchoMessage* msg)
{
  uEchoProperty* prop;
  size_t opc, n;

  opc = uecho_message_getopc(msg);
  printf("%s %2X %2X %04X %06X %06X %02X %ld ",
      uecho_message_getsourceaddress(msg),
      uecho_message_getehd1(msg),
      uecho_message_getehd2(msg),
      uecho_message_gettid(msg),
      uecho_message_getsourceobjectcode(msg),
      uecho_message_getdestinationobjectcode(msg),
      uecho_message_getesv(msg),
      opc);

  for (n = 0; n < opc; n++) {
    prop = uecho_message_getproperty(msg, n);
    printf("%02X(%d)", uecho_property_getcode(prop), uecho_property_getdatasize(prop));
  }

  printf("\n");
}

void uecho_test_object_messagelitener(uEchoObject* obj, uEchoMessage* msg)
{
#if defined(UECHO_TEST_VERBOSE)
  uecho_test_printrequest(msg);
#endif
}

bool uecho_test_property_requesthandler(uEchoObject* obj, uEchoProperty* prop, uEchoEsv esv, size_t pdc, byte* edt)
{
#if defined(UECHO_TEST_VERBOSE)
  byte status;

  printf("%02X %02X (%d)\n",
      esv,
      uecho_property_getcode(prop),
      pdc);
#endif

  if (pdc != 1)
    return false;

#if defined(UECHO_TEST_VERBOSE)
  status = edt[0];
  switch (status) {
  case UECHO_TEST_PROPERTY_SWITCH_ON:
    printf("POWER = %02X\n", status);
    break;
  case UECHO_TEST_PROPERTY_SWITCH_OFF:
    printf("POWER = %02X\n", status);
    break;
  }
#endif

  return true;
}

uEchoObject* uecho_test_createtestdevice()
{
  uEchoObject* obj = uecho_device_new();

  uecho_object_setmanufacturercode(obj, UECHO_TEST_MANCODE);
  uecho_object_setcode(obj, UECHO_TEST_OBJECTCODE);

  byte prop[32];

  // Operation status property
  uecho_object_setproperty(obj, UECHO_TEST_PROPERTY_SWITCHCODE, uEchoPropertyAttrReadWrite);
  prop[0] = UECHO_TEST_PROPERTY_SWITCH_ON;
  uecho_object_setpropertydata(obj, UECHO_TEST_PROPERTY_SWITCHCODE, prop, 1);

  // Set object listner

  uecho_object_setmessagelistener(obj, uecho_test_object_messagelitener);

  // Set property observer

  uecho_object_setpropertywriterequesthandler(obj, UECHO_TEST_PROPERTY_SWITCHCODE, uecho_test_property_requesthandler);

  return obj;
}

uEchoNode* uecho_test_createtestnode()
{
  uEchoNode* node = uecho_node_new();
  uEchoObject* dev = uecho_test_createtestdevice();
  uecho_node_addobject(node, dev);
  return node;
}
<commit_msg>Update uecho_test_printrequest()<commit_after>/************************************************************
 *
 * uEcho for C
 *
 * Copyright (C) Satoshi Konno 2015
 *
 * This is licensed under BSD-style license, see file COPYING.
 *
 ************************************************************/

#include "TestDevice.h"

#undef UECHO_TEST_VERBOSE

void uecho_test_printrequest(uEchoMessage* msg)
{
  uEchoProperty* prop;
  size_t opc, n;

  opc = uecho_message_getopc(msg);
  printf("%s %2X %2X %04X %06X %06X %02X %ld ",
      uecho_message_getsourceaddress(msg),
      uecho_message_getehd1(msg),
      uecho_message_getehd2(msg),
      uecho_message_gettid(msg),
      uecho_message_getsourceobjectcode(msg),
      uecho_message_getdestinationobjectcode(msg),
      uecho_message_getesv(msg),
      opc);

  for (n = 0; n < opc; n++) {
    prop = uecho_message_getproperty(msg, n);
    printf("%02X(%ld)", uecho_property_getcode(prop), uecho_property_getdatasize(prop));
  }

  printf("\n");
}

void uecho_test_object_messagelitener(uEchoObject* obj, uEchoMessage* msg)
{
#if defined(UECHO_TEST_VERBOSE)
  uecho_test_printrequest(msg);
#endif
}

bool uecho_test_property_requesthandler(uEchoObject* obj, uEchoProperty* prop, uEchoEsv esv, size_t pdc, byte* edt)
{
#if defined(UECHO_TEST_VERBOSE)
  byte status;

  printf("%02X %02X (%d)\n",
      esv,
      uecho_property_getcode(prop),
      pdc);
#endif

  if (pdc != 1)
    return false;

#if defined(UECHO_TEST_VERBOSE)
  status = edt[0];
  switch (status) {
  case UECHO_TEST_PROPERTY_SWITCH_ON:
    printf("POWER = %02X\n", status);
    break;
  case UECHO_TEST_PROPERTY_SWITCH_OFF:
    printf("POWER = %02X\n", status);
    break;
  }
#endif

  return true;
}

uEchoObject* uecho_test_createtestdevice()
{
  uEchoObject* obj = uecho_device_new();

  uecho_object_setmanufacturercode(obj, UECHO_TEST_MANCODE);
  uecho_object_setcode(obj, UECHO_TEST_OBJECTCODE);

  byte prop[32];

  // Operation status property
  uecho_object_setproperty(obj, UECHO_TEST_PROPERTY_SWITCHCODE, uEchoPropertyAttrReadWrite);
  prop[0] = UECHO_TEST_PROPERTY_SWITCH_ON;
  uecho_object_setpropertydata(obj, UECHO_TEST_PROPERTY_SWITCHCODE, prop, 1);

  // Set object listner

  uecho_object_setmessagelistener(obj, uecho_test_object_messagelitener);

  // Set property observer

  uecho_object_setpropertywriterequesthandler(obj, UECHO_TEST_PROPERTY_SWITCHCODE, uecho_test_property_requesthandler);

  return obj;
}

uEchoNode* uecho_test_createtestnode()
{
  uEchoNode* node = uecho_node_new();
  uEchoObject* dev = uecho_test_createtestdevice();
  uecho_node_addobject(node, dev);
  return node;
}
<|endoftext|>