diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index 6b14ceb221..e362c0ee45 100644 --- a/source/gui/scripting/ScriptFunctions.cpp +++ b/source/gui/scripting/ScriptFunctions.cpp @@ -65,7 +65,6 @@ #include "simulation2/components/ICmpAIManager.h" #include "simulation2/components/ICmpCommandQueue.h" #include "simulation2/components/ICmpGuiInterface.h" -#include "simulation2/components/ICmpPlayerManager.h" #include "simulation2/components/ICmpRangeManager.h" #include "simulation2/components/ICmpSelectable.h" #include "simulation2/components/ICmpTemplateManager.h" @@ -167,27 +166,14 @@ std::vector PickPlayerEntitiesInRect(ScriptInterface::CxPrivate* UN return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false); } -std::vector PickPlayerEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate, int player) +std::vector PickPlayerEntitiesOnScreen(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int player) { - return PickPlayerEntitiesInRect(pCxPrivate, 0, 0, g_xres, g_yres, player); + return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, player, false); } -std::vector PickNonGaiaEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate) +std::vector PickNonGaiaEntitiesOnScreen(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) { - std::vector entities; - - CmpPtr cmpPlayerManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); - if (!cmpPlayerManager) - return entities; - - i32 numPlayers = cmpPlayerManager->GetNumPlayers(); - for (i32 player = 1; player < numPlayers; ++player) - { - std::vector ents = PickPlayerEntitiesOnScreen(pCxPrivate, player); - entities.insert(entities.end(), ents.begin(), ents.end()); - } - - return entities; + return EntitySelection::PickNonGaiaEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, false); } std::vector PickSimilarPlayerEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) diff --git a/source/simulation2/components/tests/test_RangeManager.h b/source/simulation2/components/tests/test_RangeManager.h index aba18fcd4b..6ddf4d2738 100644 --- a/source/simulation2/components/tests/test_RangeManager.h +++ b/source/simulation2/components/tests/test_RangeManager.h @@ -138,5 +138,21 @@ public: { CMessagePositionChanged msg(100, true, entity_pos_t::FromDouble(x), entity_pos_t::FromDouble(z), entity_angle_t::Zero()); cmp->HandleMessage(msg, false); } cmp->Verify(); } + + // Test OwnershipChange, GetEntitiesByPlayer, GetNonGaiaEntities + { + player_id_t previousOwner = -1; + for (player_id_t newOwner = 0; newOwner < 8; ++newOwner) + { + CMessageOwnershipChanged msg(100, previousOwner, newOwner); + cmp->HandleMessage(msg, false); + + for (player_id_t i = 0; i < 8; ++i) + TS_ASSERT_EQUALS(cmp->GetEntitiesByPlayer(i).size(), i == newOwner ? 1 : 0); + + TS_ASSERT_EQUALS(cmp->GetNonGaiaEntities().size(), newOwner > 0 ? 1 : 0); + previousOwner = newOwner; + } + } } }; diff --git a/source/simulation2/helpers/Selection.cpp b/source/simulation2/helpers/Selection.cpp index 99f362d221..005c3b58c0 100644 --- a/source/simulation2/helpers/Selection.cpp +++ b/source/simulation2/helpers/Selection.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -89,20 +89,16 @@ entity_id_t EntitySelection::PickEntityAtPoint(CSimulation2& simulation, const C } /** - * Returns true if the given entity is visible to the given player and visible in the given screen area. + * Returns true if the given entity is visible in the given screen area. * If the entity is a decorative, the function will only return true if allowEditorSelectables. */ -static bool CheckEntityVisibleAndInRect(CEntityHandle handle, CmpPtr cmpRangeManager, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, player_id_t owner, bool allowEditorSelectables) +static bool CheckEntityInRect(CEntityHandle handle, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, bool allowEditorSelectables) { // Check if this entity is only selectable in Atlas CmpPtr cmpSelectable(handle); if (!cmpSelectable || (!allowEditorSelectables && cmpSelectable->IsEditorOnly())) return false; - // Ignore entities hidden by LOS (or otherwise hidden, e.g. when not IsInWorld) - if (cmpRangeManager->GetLosVisibility(handle, owner) == ICmpRangeManager::VIS_HIDDEN) - return false; - // Find the current interpolated model position. // (We just use the centre position and not the whole bounding box, because maybe // that's better for users trying to select objects in busy areas) @@ -125,6 +121,18 @@ static bool CheckEntityVisibleAndInRect(CEntityHandle handle, CmpPtr cmpRangeManager, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, player_id_t player, bool allowEditorSelectables) +{ + // Ignore entities hidden by LOS (or otherwise hidden, e.g. when not IsInWorld) + if (cmpRangeManager->GetLosVisibility(handle, player) == ICmpRangeManager::VIS_HIDDEN) + return false; + + return CheckEntityInRect(handle, camera, sx0, sy0, sx1, sy1, allowEditorSelectables); +} + std::vector EntitySelection::PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, player_id_t owner, bool allowEditorSelectables) { PROFILE2("PickEntitiesInRect"); @@ -162,6 +170,29 @@ std::vector EntitySelection::PickEntitiesInRect(CSimulation2& simul return hitEnts; } +std::vector EntitySelection::PickNonGaiaEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, bool allowEditorSelectables) +{ + PROFILE2("PickNonGaiaEntitiesInRect"); + + // Make sure sx0 <= sx1, and sy0 <= sy1 + if (sx0 > sx1) + std::swap(sx0, sx1); + if (sy0 > sy1) + std::swap(sy0, sy1); + + CmpPtr cmpRangeManager(simulation, SYSTEM_ENTITY); + ENSURE(cmpRangeManager); + + std::vector hitEnts; + + CComponentManager& componentManager = simulation.GetSimContext().GetComponentManager(); + for (entity_id_t ent : cmpRangeManager->GetNonGaiaEntities()) + if (CheckEntityInRect(componentManager.LookupEntityHandle(ent), camera, sx0, sy0, sx1, sy1, allowEditorSelectables)) + hitEnts.push_back(ent); + + return hitEnts; +} + std::vector EntitySelection::PickSimilarEntities(CSimulation2& simulation, const CCamera& camera, const std::string& templateName, player_id_t owner, bool includeOffScreen, bool matchRank, bool allowEditorSelectables, bool allowFoundations) diff --git a/source/simulation2/helpers/Selection.h b/source/simulation2/helpers/Selection.h index c5e72732be..6367c10df9 100644 --- a/source/simulation2/helpers/Selection.h +++ b/source/simulation2/helpers/Selection.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2012 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -64,6 +64,12 @@ entity_id_t PickEntityAtPoint(CSimulation2& simulation, const CCamera& camera, i */ std::vector PickEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, player_id_t owner, bool allowEditorSelectables); +/** + * Finds all selectable entities within the given screen coordinate rectangle, + * belonging to any given player (excluding Gaia). Used for status bars. + */ +std::vector PickNonGaiaEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, bool allowEditorSelectables); + /** * Finds all entities with the given entity template name, belonging to the given player. *