diff --git a/binaries/data/mods/public/simulation/components/Player.js b/binaries/data/mods/public/simulation/components/Player.js index c6ca8342ca..2d087f6db6 100644 --- a/binaries/data/mods/public/simulation/components/Player.js +++ b/binaries/data/mods/public/simulation/components/Player.js @@ -18,6 +18,15 @@ Player.prototype.Init = function() }; }; +Player.prototype.GetColour = function() +{ + // TODO: need proper colour support + if (this.playerID == 1) + return { "r": 0.0, "g": 0.0, "b": 1.0, "a": 1.0 }; + else + return { "r": 1.0, "g": 0.0, "b": 0.0, "a": 1.0 }; +}; + Player.prototype.SetPlayerID = function(id) { this.playerID = id; diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp index 08592f8920..0cd1035432 100644 --- a/source/gui/MiniMap.cpp +++ b/source/gui/MiniMap.cpp @@ -45,7 +45,8 @@ #include "simulation/EntityTemplate.h" #include "simulation/LOSManager.h" #include "simulation/TerritoryManager.h" - +#include "simulation2/Simulation2.h" +#include "simulation2/components/ICmpMinimap.h" bool g_TerrainModified = false; bool g_GameRestarted = false; @@ -397,13 +398,6 @@ void CMiniMap::Draw() PROFILE_START("minimap units"); - // Draw unit points - const std::vector &units = m_UnitManager->GetUnits(); - std::vector::const_iterator iter = units.begin(); - CUnit *unit = 0; - CVector2D pos; - CLOSManager* losMgr = g_Game->GetWorld()->GetLOSManager(); - std::vector vertexArray; // TODO: don't reallocate this after every frame (but don't waste memory // after the number of units decreases substantially) @@ -412,41 +406,71 @@ void CMiniMap::Draw() // (~70msec/frame on a GF4 rendering a thousand points) glPointSize(3.f); - for(; iter != units.end(); ++iter) + if (g_UseSimulation2) { - unit = (CUnit *)(*iter); - if(unit && unit->GetEntity() && losMgr->GetUnitStatus(unit, g_Game->GetLocalPlayer()) != UNIT_HIDDEN) + float sx = m_scaleX / CELL_SIZE; + float sy = m_scaleY / CELL_SIZE; + + CSimulation2* sim = g_Game->GetSimulation2(); + const CSimulation2::InterfaceList& ents = sim->GetEntitiesWithInterface(IID_Minimap); + for (CSimulation2::InterfaceList::const_iterator it = ents.begin(); it != ents.end(); ++it) { - CEntity* entity = unit->GetEntity(); - CStrW& type = entity->m_base->m_minimapType; - MinimapUnitVertex v; - - if(type==L"Unit" || type==L"Structure" || type==L"Hero") { - // Use the player colour - const SPlayerColour& colour = entity->GetPlayer()->GetColour(); - v.r = cpu_i32FromFloat(colour.r*255.f); - v.g = cpu_i32FromFloat(colour.g*255.f); - v.b = cpu_i32FromFloat(colour.b*255.f); + ICmpMinimap* cmpMinimap = static_cast(it->second); + if (cmpMinimap->GetRenderData(v.r, v.g, v.b, v.x, v.y)) + { v.a = 255; + v.x = x + v.x*sx; + v.y = y - v.y*sy; + vertexArray.push_back(v); } - else { - CEntityTemplate* base = entity->m_base; - v.r = base->m_minimapR; - v.g = base->m_minimapG; - v.b = base->m_minimapB; - v.a = 255; - } - - pos = GetMapSpaceCoords(entity->m_position); - - v.x = x + pos.x; - v.y = y - pos.y; - vertexArray.push_back(v); } - } + } + else + { + // Draw unit points + const std::vector &units = m_UnitManager->GetUnits(); + std::vector::const_iterator iter = units.begin(); + CUnit *unit = 0; + CVector2D pos; + CLOSManager* losMgr = g_Game->GetWorld()->GetLOSManager(); - if (vertexArray.size()) + for(; iter != units.end(); ++iter) + { + unit = (CUnit *)(*iter); + if(unit && unit->GetEntity() && losMgr->GetUnitStatus(unit, g_Game->GetLocalPlayer()) != UNIT_HIDDEN) + { + CEntity* entity = unit->GetEntity(); + CStrW& type = entity->m_base->m_minimapType; + + MinimapUnitVertex v; + + if(type==L"Unit" || type==L"Structure" || type==L"Hero") { + // Use the player colour + const SPlayerColour& colour = entity->GetPlayer()->GetColour(); + v.r = cpu_i32FromFloat(colour.r*255.f); + v.g = cpu_i32FromFloat(colour.g*255.f); + v.b = cpu_i32FromFloat(colour.b*255.f); + v.a = 255; + } + else { + CEntityTemplate* base = entity->m_base; + v.r = base->m_minimapR; + v.g = base->m_minimapG; + v.b = base->m_minimapB; + v.a = 255; + } + + pos = GetMapSpaceCoords(entity->m_position); + + v.x = x + pos.x; + v.y = y - pos.y; + vertexArray.push_back(v); + } + } + } + + if (!vertexArray.empty()) { glPushMatrix(); glTranslatef(0, 0, z); diff --git a/source/simulation2/TypeList.h b/source/simulation2/TypeList.h index ad2a338573..9ca6eca7ad 100644 --- a/source/simulation2/TypeList.h +++ b/source/simulation2/TypeList.h @@ -59,6 +59,9 @@ COMPONENT(Footprint) INTERFACE(GuiInterface) COMPONENT(GuiInterfaceScripted) +INTERFACE(Minimap) +COMPONENT(Minimap) + INTERFACE(Motion) COMPONENT(MotionBall) COMPONENT(MotionScripted) diff --git a/source/simulation2/components/CCmpMinimap.cpp b/source/simulation2/components/CCmpMinimap.cpp new file mode 100644 index 0000000000..49201ffbb1 --- /dev/null +++ b/source/simulation2/components/CCmpMinimap.cpp @@ -0,0 +1,173 @@ +/* Copyright (C) 2010 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#include "precompiled.h" + +#include "simulation2/system/Component.h" +#include "ICmpMinimap.h" + +#include "simulation2/components/ICmpPlayerManager.h" +#include "simulation2/components/ICmpPlayer.h" +#include "simulation2/MessageTypes.h" + +#include "ps/Overlay.h" + +class CCmpMinimap : public ICmpMinimap +{ +public: + static void ClassInit(CComponentManager& componentManager) + { + componentManager.SubscribeToMessageType(MT_PositionChanged); + componentManager.SubscribeToMessageType(MT_OwnershipChanged); + } + + DEFAULT_COMPONENT_ALLOCATOR(Minimap) + + bool m_Active; + bool m_UsePlayerColour; + u8 m_R, m_G, m_B; + entity_pos_t m_X, m_Z; // cache the latest position for more efficient rendering + + static std::string GetSchema() + { + return + "" + "" + "food" + "wood" + "stone" + "metal" + "structure" + "settlement" + "unit" + "support" + "hero" + "" + "" + "" + "" + "" + "0255" + "" + "" + "0255" + "" + "" + "0255" + "" + "" + ""; + } + + virtual void Init(const CSimContext& context, const CParamNode& paramNode) + { + m_Active = true; + + const CParamNode& colour = paramNode.GetChild("Colour"); + if (colour.IsOk()) + { + m_UsePlayerColour = false; + m_R = colour.GetChild("@r").ToInt(); + m_G = colour.GetChild("@g").ToInt(); + m_B = colour.GetChild("@b").ToInt(); + } + else + { + m_UsePlayerColour = true; + // Choose a bogus colour which will get replaced once we have an owner + m_R = 255; + m_G = 0; + m_B = 255; + } + } + + virtual void Deinit(const CSimContext& UNUSED(context)) + { + } + + virtual void Serialize(ISerializer& serialize) + { + // TODO + } + + virtual void Deserialize(const CSimContext& context, const CParamNode& paramNode, IDeserializer& deserialize) + { + Init(context, paramNode); + + // TODO + } + + virtual void HandleMessage(const CSimContext& context, const CMessage& msg, bool UNUSED(global)) + { + switch (msg.GetType()) + { + case MT_PositionChanged: + { + const CMessagePositionChanged& data = static_cast (msg); + + if (data.inWorld) + { + m_Active = true; + m_X = data.x; + m_Z = data.z; + } + else + { + m_Active = false; + } + + break; + } + case MT_OwnershipChanged: + { + if (!m_UsePlayerColour) + break; + + const CMessageOwnershipChanged& msgData = static_cast (msg); + + // Find the new player's colour + CmpPtr cmpPlayerManager(context, SYSTEM_ENTITY); + if (cmpPlayerManager.null()) + break; + CmpPtr cmpPlayer(context, cmpPlayerManager->GetPlayerByID(msgData.to)); + if (cmpPlayer.null()) + break; + CColor colour = cmpPlayer->GetColour(); + m_R = (int)(colour.r*255.0); + m_G = (int)(colour.g*255.0); + m_B = (int)(colour.b*255.0); + + break; + } + } + } + + virtual bool GetRenderData(u8& r, u8& g, u8& b, float& x, float& z) + { + if (!m_Active) + return false; + + r = m_R; + g = m_G; + b = m_B; + x = m_X.ToFloat(); + z = m_Z.ToFloat(); + return true; + } +}; + +REGISTER_COMPONENT_TYPE(Minimap) diff --git a/source/simulation2/components/ICmpMinimap.cpp b/source/simulation2/components/ICmpMinimap.cpp new file mode 100644 index 0000000000..2751a98425 --- /dev/null +++ b/source/simulation2/components/ICmpMinimap.cpp @@ -0,0 +1,25 @@ +/* Copyright (C) 2010 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#include "precompiled.h" + +#include "ICmpMinimap.h" + +#include "simulation2/system/InterfaceScripted.h" + +BEGIN_INTERFACE_WRAPPER(Minimap) +END_INTERFACE_WRAPPER(Minimap) diff --git a/source/simulation2/components/ICmpMinimap.h b/source/simulation2/components/ICmpMinimap.h new file mode 100644 index 0000000000..56a3cef765 --- /dev/null +++ b/source/simulation2/components/ICmpMinimap.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2010 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#ifndef INCLUDED_ICMPMINIMAP +#define INCLUDED_ICMPMINIMAP + +#include "simulation2/system/Interface.h" + +/** + * Per-unit minimap data. + */ +class ICmpMinimap : public IComponent +{ +public: + /** + * Get the data for rendering this entity on the minimap. + * If it should not be drawn, returns false; otherwise the arguments are set + * to the colour and world position. + */ + virtual bool GetRenderData(u8& r, u8& g, u8& b, float& x, float& z) = 0; + + DECLARE_INTERFACE_TYPE(Minimap) +}; + +#endif // INCLUDED_ICMPMINIMAP diff --git a/source/simulation2/components/ICmpPlayer.cpp b/source/simulation2/components/ICmpPlayer.cpp index ca01dc2e7c..ab06e06d77 100644 --- a/source/simulation2/components/ICmpPlayer.cpp +++ b/source/simulation2/components/ICmpPlayer.cpp @@ -22,6 +22,8 @@ #include "simulation2/system/InterfaceScripted.h" #include "simulation2/scripting/ScriptComponent.h" +#include "ps/Overlay.h" + BEGIN_INTERFACE_WRAPPER(Player) END_INTERFACE_WRAPPER(Player) @@ -34,6 +36,11 @@ public: { m_Script.CallVoid("SetName", name); } + + virtual CColor GetColour() + { + return m_Script.Call("GetColour"); + } }; REGISTER_COMPONENT_SCRIPT_WRAPPER(PlayerScripted) diff --git a/source/simulation2/components/ICmpPlayer.h b/source/simulation2/components/ICmpPlayer.h index 08c1daae94..e9e9870984 100644 --- a/source/simulation2/components/ICmpPlayer.h +++ b/source/simulation2/components/ICmpPlayer.h @@ -20,10 +20,12 @@ #include "simulation2/system/Interface.h" +struct CColor; + /** * Player data. - * (This interface only includes the functions needed by native code for loading maps; - * most player interaction is handled by scripts instead.) + * (This interface only includes the functions needed by native code for loading maps, + * and for minimap rendering; most player interaction is handled by scripts instead.) */ class ICmpPlayer : public IComponent { @@ -31,6 +33,8 @@ public: virtual void SetName(const std::wstring& name) = 0; // TODO: some more data + virtual CColor GetColour() = 0; + DECLARE_INTERFACE_TYPE(Player) }; diff --git a/source/simulation2/components/ICmpPlayerManager.cpp b/source/simulation2/components/ICmpPlayerManager.cpp index 0f6c9282dd..f13156e481 100644 --- a/source/simulation2/components/ICmpPlayerManager.cpp +++ b/source/simulation2/components/ICmpPlayerManager.cpp @@ -34,6 +34,11 @@ public: { m_Script.CallVoid("AddPlayer", (int)ent); } + + virtual entity_id_t GetPlayerByID(int32_t id) + { + return m_Script.Call("GetPlayerByID", (int)id); + } }; REGISTER_COMPONENT_SCRIPT_WRAPPER(PlayerManagerScripted) diff --git a/source/simulation2/components/ICmpPlayerManager.h b/source/simulation2/components/ICmpPlayerManager.h index 1395923c06..7fa778ac1f 100644 --- a/source/simulation2/components/ICmpPlayerManager.h +++ b/source/simulation2/components/ICmpPlayerManager.h @@ -28,7 +28,7 @@ class ICmpPlayerManager : public IComponent public: virtual void AddPlayer(entity_id_t ent) = 0; - // Accessors are currently only available to scripts, since no C++ code needed them yet + virtual entity_id_t GetPlayerByID(int32_t id) = 0; DECLARE_INTERFACE_TYPE(PlayerManager) };