diff --git a/source/simulation2/components/CCmpObstruction.cpp b/source/simulation2/components/CCmpObstruction.cpp index c371c90b04..b32ca6771e 100644 --- a/source/simulation2/components/CCmpObstruction.cpp +++ b/source/simulation2/components/CCmpObstruction.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -48,11 +48,7 @@ public: // Template state: - enum { - STATIC, - UNIT, - CLUSTER - } m_Type; + EObstructionType m_Type; entity_pos_t m_Size0; // radius or width entity_pos_t m_Size1; // radius or depth @@ -462,6 +458,11 @@ public: return (m_TemplateFlags & ICmpObstructionManager::FLAG_BLOCK_MOVEMENT) != 0; } + virtual EObstructionType GetObstructionType() const + { + return m_Type; + } + virtual ICmpObstructionManager::tag_t GetObstruction() const { return m_Tag; diff --git a/source/simulation2/components/ICmpObstruction.h b/source/simulation2/components/ICmpObstruction.h index 3b197e144e..11079ae558 100644 --- a/source/simulation2/components/ICmpObstruction.h +++ b/source/simulation2/components/ICmpObstruction.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -38,6 +38,12 @@ public: FOUNDATION_CHECK_FAIL_TERRAIN_CLASS }; + enum EObstructionType { + STATIC, + UNIT, + CLUSTER + }; + virtual ICmpObstructionManager::tag_t GetObstruction() const = 0; /** @@ -56,6 +62,8 @@ public: virtual entity_pos_t GetUnitRadius() const = 0; + virtual EObstructionType GetObstructionType() const = 0; + virtual void SetUnitClearance(const entity_pos_t& clearance) = 0; virtual bool IsControlPersistent() const = 0; diff --git a/source/simulation2/components/tests/test_ObstructionManager.h b/source/simulation2/components/tests/test_ObstructionManager.h index 73d95dcb14..14c11cdd92 100644 --- a/source/simulation2/components/tests/test_ObstructionManager.h +++ b/source/simulation2/components/tests/test_ObstructionManager.h @@ -31,6 +31,7 @@ public: virtual bool GetPreviousObstructionSquare(ICmpObstructionManager::ObstructionSquare& UNUSED(out)) const { return true; } virtual entity_pos_t GetSize() const { return entity_pos_t::Zero(); } virtual entity_pos_t GetUnitRadius() const { return entity_pos_t::Zero(); } + virtual EObstructionType GetObstructionType() const { return ICmpObstruction::STATIC; } virtual void SetUnitClearance(const entity_pos_t& UNUSED(clearance)) { } virtual bool IsControlPersistent() const { return true; } virtual bool CheckShorePlacement() const { return true; } diff --git a/source/simulation2/helpers/Selection.cpp b/source/simulation2/helpers/Selection.cpp index 005c3b58c0..5ecf369cff 100644 --- a/source/simulation2/helpers/Selection.cpp +++ b/source/simulation2/helpers/Selection.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,7 +20,8 @@ #include "Selection.h" #include "graphics/Camera.h" -#include "simulation2/Simulation2.h" +#include "ps/CLogger.h" +#include "ps/Profiler2.h" #include "simulation2/components/ICmpIdentity.h" #include "simulation2/components/ICmpOwnership.h" #include "simulation2/components/ICmpRangeManager.h" @@ -29,8 +30,6 @@ #include "simulation2/components/ICmpVisual.h" #include "simulation2/components/ICmpUnitRenderer.h" #include "simulation2/system/ComponentManager.h" -#include "ps/CLogger.h" -#include "ps/Profiler2.h" entity_id_t EntitySelection::PickEntityAtPoint(CSimulation2& simulation, const CCamera& camera, int screenX, int screenY, player_id_t player, bool allowEditorSelectables) { @@ -92,7 +91,7 @@ entity_id_t EntitySelection::PickEntityAtPoint(CSimulation2& simulation, const C * 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 CheckEntityInRect(CEntityHandle handle, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, bool allowEditorSelectables) +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); diff --git a/source/simulation2/helpers/Selection.h b/source/simulation2/helpers/Selection.h index 6367c10df9..41fcafd0e4 100644 --- a/source/simulation2/helpers/Selection.h +++ b/source/simulation2/helpers/Selection.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,19 +18,18 @@ #ifndef INCLUDED_SELECTION #define INCLUDED_SELECTION -/** - * @file - * Helper functions related to entity selection - */ - +#include "simulation2/components/ICmpObstruction.h" +#include "simulation2/helpers/Player.h" +#include "simulation2/Simulation2.h" #include "simulation2/system/Entity.h" -#include "Player.h" #include class CSimulation2; class CCamera; +bool CheckEntityInRect(CEntityHandle handle, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, bool allowEditorSelectables); + namespace EntitySelection { @@ -70,6 +69,42 @@ std::vector PickEntitiesInRect(CSimulation2& simulation, const CCam */ std::vector PickNonGaiaEntitiesInRect(CSimulation2& simulation, const CCamera& camera, int sx0, int sy0, int sx1, int sy1, bool allowEditorSelectables); +/** + * Finds all entities with a given component belonging to any given player. + */ +struct DefaultComponentFilter +{ + bool operator()(IComponent* UNUSED(cmp)) + { + return true; + } +}; +template +std::vector GetEntitiesWithComponentInRect(CSimulation2& simulation, int cid, const CCamera& camera, int sx0, int sy0, int sx1, int sy1) +{ + PROFILE2("GetEntitiesWithObstructionInRect"); + + // Make sure sx0 <= sx1, and sy0 <= sy1 + if (sx0 > sx1) + std::swap(sx0, sx1); + if (sy0 > sy1) + std::swap(sy0, sy1); + + std::vector hitEnts; + + Filter filter; + const CSimulation2::InterfaceListUnordered& entities = simulation.GetEntitiesWithInterfaceUnordered(cid); + for (const std::pair& item : entities) + { + if (!filter(item.second)) + continue; + if (CheckEntityInRect(item.second->GetEntityHandle(), camera, sx0, sy0, sx1, sy1, false)) + hitEnts.push_back(item.first); + } + + return hitEnts; +} + /** * Finds all entities with the given entity template name, belonging to the given player. * diff --git a/source/simulation2/scripting/JSInterface_Simulation.cpp b/source/simulation2/scripting/JSInterface_Simulation.cpp index 75ab14ab7b..fc16a38b62 100644 --- a/source/simulation2/scripting/JSInterface_Simulation.cpp +++ b/source/simulation2/scripting/JSInterface_Simulation.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -117,6 +117,19 @@ std::vector JSI_Simulation::PickNonGaiaEntitiesOnScreen(ScriptInter return EntitySelection::PickNonGaiaEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres, false); } +std::vector JSI_Simulation::GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CxPrivate* pCxPrivate) +{ + struct StaticObstructionFilter + { + bool operator()(IComponent* cmp) + { + ICmpObstruction* cmpObstruction = static_cast(cmp); + return cmpObstruction->GetObstructionType() == ICmpObstruction::STATIC; + } + }; + return EntitySelection::GetEntitiesWithComponentInRect(*g_Game->GetSimulation2(), IID_Obstruction, *g_Game->GetView()->GetCamera(), 0, 0, g_xres, g_yres); +} + std::vector JSI_Simulation::PickSimilarPlayerEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations) { return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetViewedPlayerID(), includeOffScreen, matchRank, false, allowFoundations); @@ -143,6 +156,7 @@ void JSI_Simulation::RegisterScriptFunctions(const ScriptInterface& scriptInterf scriptInterface.RegisterFunction, int, int, int, int, int, &PickPlayerEntitiesInRect>("PickPlayerEntitiesInRect"); scriptInterface.RegisterFunction, int, &PickPlayerEntitiesOnScreen>("PickPlayerEntitiesOnScreen"); scriptInterface.RegisterFunction, &PickNonGaiaEntitiesOnScreen>("PickNonGaiaEntitiesOnScreen"); + scriptInterface.RegisterFunction, &GetEntitiesWithStaticObstructionOnScreen>("GetEntitiesWithStaticObstructionOnScreen"); scriptInterface.RegisterFunction, std::string, bool, bool, bool, &PickSimilarPlayerEntities>("PickSimilarPlayerEntities"); scriptInterface.RegisterFunction("SetBoundingBoxDebugOverlay"); } diff --git a/source/simulation2/scripting/JSInterface_Simulation.h b/source/simulation2/scripting/JSInterface_Simulation.h index 0c8d44c967..21d1aae8df 100644 --- a/source/simulation2/scripting/JSInterface_Simulation.h +++ b/source/simulation2/scripting/JSInterface_Simulation.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -31,6 +31,7 @@ namespace JSI_Simulation std::vector PickPlayerEntitiesInRect(ScriptInterface::CxPrivate* pCxPrivate, int x0, int y0, int x1, int y1, int player); std::vector PickPlayerEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate, int player); std::vector PickNonGaiaEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate); + std::vector GetEntitiesWithStaticObstructionOnScreen(ScriptInterface::CxPrivate* pCxPrivate); std::vector PickSimilarPlayerEntities(ScriptInterface::CxPrivate* pCxPrivate, const std::string& templateName, bool includeOffScreen, bool matchRank, bool allowFoundations); JS::Value GetAIs(ScriptInterface::CxPrivate* pCxPrivate); void SetBoundingBoxDebugOverlay(ScriptInterface::CxPrivate* pCxPrivate, bool enabled);