From 4a9836bffd28974abbcf0279066f78bd645468c6 Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Mon, 27 Mar 2023 11:40:45 +0200 Subject: [PATCH] AngelScript: added API for placing icons on surveymap New funcs in TerrainClass (the demo_script.as was updated to showcase it): ``` /** * Adds an icon with description to survey map (minimap). * @param type informational, optional * @param filename The file name. Don't forget to specify the resource group! * @param resource_group Leave empty to use TexturesRG ('icons.zip/famicons.zip'), otherwise use `BeamClass/TerrainClass getResourceGroup()` to read from actor/terrain ZIP. * @param caption optional * @param pos The world position of the point of interest, in meters. * @param angle The world yaw in radians. * @param id The race ID of the icon (>=0), or -1 if not a race icon. You can use larger negative numbers for custom IDs. */ void addSurveyMapEntity(const std::string& type, const std::string& filename, const std::string& resource_group, const std::string& caption, const Ogre::Vector3& pos, float angle, int id); /** * Removes all survey map icons with the given ID. * @param id The race ID of the icon (>=0), or -1 if not a race icon. You can use larger negative numbers for custom IDs. */ void delSurveyMapEntities(int id); ``` Internal changes: * new file 'SurveyMapEntity.h' - moved out from TerrainObjectManager * map icon filename is no longer constructed from 'type', instead specified fuly in SurveyMapEntity * added optional resource group string to SurveyMapEntity --- doc/angelscript/Script2Game/TerrainClass.h | 46 +++++++++++++++-- source/main/CMakeLists.txt | 1 + source/main/gui/panels/GUI_SurveyMap.cpp | 14 +++--- source/main/gui/panels/GUI_SurveyMap.h | 9 ++-- .../scripting/bindings/TerrainAngelscript.cpp | 10 ++++ source/main/terrain/SurveyMapEntity.h | 50 +++++++++++++++++++ source/main/terrain/Terrain.cpp | 18 +++++++ source/main/terrain/Terrain.h | 8 ++- source/main/terrain/TerrainObjectManager.cpp | 6 +-- source/main/terrain/TerrainObjectManager.h | 17 ++----- 10 files changed, 147 insertions(+), 32 deletions(-) create mode 100644 source/main/terrain/SurveyMapEntity.h diff --git a/doc/angelscript/Script2Game/TerrainClass.h b/doc/angelscript/Script2Game/TerrainClass.h index e8c4b166c9..9a70d2442e 100644 --- a/doc/angelscript/Script2Game/TerrainClass.h +++ b/doc/angelscript/Script2Game/TerrainClass.h @@ -16,6 +16,9 @@ namespace Script2Game { class TerrainClass { public: + /// @name General + /// @{ + /** * @return Full name of the terrain */ @@ -35,23 +38,58 @@ class TerrainClass * @return GUID (global unique ID) of the terrain, or empty string if not specified. */ string getGUID(); + + /** + * @return version of the terrain, as specified by author. + */ + int getVersion(); + + /// @} + + /// @name Landscape + /// @{ /** * @return true if specified as flat (no heightmap). */ bool isFlat(); - /** - * @return version of the terrain, as specified by author. - */ - int getVersion(); + /// @} + + /// @name Gameplay + /// @{ /** * @return Player spawn position when entering game. */ vector3 getSpawnPos(); + /** + * Adds an icon with description to survey map (minimap). + * @param type informational, optional + * @param filename The file name. Don't forget to specify the resource group! + * @param resource_group Leave empty to use TexturesRG ('icons.zip/famicons.zip'), otherwise use `BeamClass/TerrainClass getResourceGroup()` to read from actor/terrain ZIP. + * @param caption optional + * @param pos The world position of the point of interest, in meters. + * @param angle The world yaw in radians. + * @param id The race ID of the icon (>=0), or -1 if not a race icon. You can use larger negative numbers for custom IDs. + */ + void addSurveyMapEntity(const std::string& type, const std::string& filename, const std::string& resource_group, const std::string& caption, const Ogre::Vector3& pos, float angle, int id); + + /** + * Removes all survey map icons with the given ID. + * @param id The race ID of the icon (>=0), or -1 if not a race icon. You can use larger negative numbers for custom IDs. + */ + void delSurveyMapEntities(int id); + + /// @} + + /// @name Subsystems + /// @{ + ProceduralManagerClass @getProceduralManager(); + + /// @} }; /// @} //addtogroup Script2Game diff --git a/source/main/CMakeLists.txt b/source/main/CMakeLists.txt index b6f1e0f83c..9e47e47a27 100644 --- a/source/main/CMakeLists.txt +++ b/source/main/CMakeLists.txt @@ -199,6 +199,7 @@ set(SOURCE_FILES terrain/OgreTerrainPSSMMaterialGenerator.{h,cpp} terrain/ProceduralManager.{h,cpp} terrain/ProceduralRoad.{h,cpp} + terrain/SurveyMapEntity.h terrain/TerrainEditor.{h,cpp} terrain/TerrainGeometryManager.{h,cpp} terrain/Terrain.{h,cpp} diff --git a/source/main/gui/panels/GUI_SurveyMap.cpp b/source/main/gui/panels/GUI_SurveyMap.cpp index bccfc40b7a..3aa0c13716 100644 --- a/source/main/gui/panels/GUI_SurveyMap.cpp +++ b/source/main/gui/panels/GUI_SurveyMap.cpp @@ -267,16 +267,14 @@ void SurveyMap::Draw() if (App::gfx_surveymap_icons->getBool()) { // Draw terrain object icons - for (TerrainObjectManager::MapEntity& e: App::GetGameContext()->GetTerrain()->getObjectManager()->GetMapEntities()) + for (SurveyMapEntity& e: App::GetGameContext()->GetTerrain()->getSurveyMapEntities()) { int id = App::GetGameContext()->GetRaceSystem().GetRaceId(); bool visible = !((e.type == "checkpoint" && e.id != id) || (e.type == "racestart" && id != -1 && e.id != id)); - Str<100> filename; - filename << "icon_" << e.type << ".dds"; if ((visible) && (!App::gfx_declutter_map->getBool())) { - this->DrawMapIcon(tl_screen_pos, view_size, view_origin, filename.ToCStr(), e.name, e.pos.x, e.pos.z, e.rot); + this->DrawMapIcon(tl_screen_pos, view_size, view_origin, e.filename, e.caption, e.pos.x, e.pos.z, e.rot, e.resource_group); } } @@ -479,13 +477,15 @@ void SurveyMap::ToggleMode() void SurveyMap::DrawMapIcon(ImVec2 view_pos, ImVec2 view_size, Ogre::Vector2 view_origin, std::string const& filename, std::string const& caption, - float pos_x, float pos_y, float angle) + float pos_x, float pos_y, float angle, std::string resource_group /* ="" */) { Ogre::TexturePtr tex; + if (resource_group == "") + resource_group = ContentManager::ResourcePack::TEXTURES.resource_group_name; + try { - tex = Ogre::TextureManager::getSingleton().load( - filename, ContentManager::ResourcePack::TEXTURES.resource_group_name); + tex = Ogre::TextureManager::getSingleton().load(filename, resource_group); } catch (Ogre::FileNotFoundException) { diff --git a/source/main/gui/panels/GUI_SurveyMap.h b/source/main/gui/panels/GUI_SurveyMap.h index 232a1632a4..1af3fd22f3 100644 --- a/source/main/gui/panels/GUI_SurveyMap.h +++ b/source/main/gui/panels/GUI_SurveyMap.h @@ -24,11 +24,12 @@ /// @file #include "Application.h" -#include "SimData.h" - #include "OgreImGui.h" +#include "SimData.h" #include "SurveyMapTextureCreator.h" +#include + namespace RoR { namespace GUI { @@ -76,8 +77,8 @@ class SurveyMap const char* getAIType(ActorPtr actor); void DrawMapIcon(ImVec2 view_pos, ImVec2 view_size, Ogre::Vector2 view_origin, - std::string const& filename, std::string const& caption, - float pos_x, float pos_y, float angle); + std::string const& filename, std::string const& caption, + float pos_x, float pos_y, float angle, std::string resource_group = ""); ImVec2 DrawWaypoint(ImVec2 view_pos, ImVec2 view_size, Ogre::Vector2 view_origin, std::string const& caption, int idx); diff --git a/source/main/scripting/bindings/TerrainAngelscript.cpp b/source/main/scripting/bindings/TerrainAngelscript.cpp index ca8ccf4440..73bba83211 100644 --- a/source/main/scripting/bindings/TerrainAngelscript.cpp +++ b/source/main/scripting/bindings/TerrainAngelscript.cpp @@ -35,12 +35,22 @@ void RoR::RegisterTerrain(asIScriptEngine* engine) TerrainPtr::RegisterRefCountingObjectPtr(engine, "TerrainClassPtr", "TerrainClass"); int result = 0; + + // > General result = engine->RegisterObjectMethod("TerrainClass", "string getTerrainName()", asMETHOD(RoR::Terrain,getTerrainName), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("TerrainClass", "string getTerrainFileName()", asMETHOD(RoR::Terrain, getTerrainFileName), asCALL_THISCALL); ROR_ASSERT(result >= 0); result = engine->RegisterObjectMethod("TerrainClass", "string getTerrainFileResourceGroup()", asMETHOD(RoR::Terrain, getTerrainFileResourceGroup), asCALL_THISCALL); ROR_ASSERT(result >= 0); result = engine->RegisterObjectMethod("TerrainClass", "string getGUID()", asMETHOD(RoR::Terrain,getGUID), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("TerrainClass", "int getVersion()", asMETHOD(RoR::Terrain,getVersion), asCALL_THISCALL); ROR_ASSERT(result>=0); + + // > Landscape result = engine->RegisterObjectMethod("TerrainClass", "bool isFlat()", asMETHOD(RoR::Terrain,isFlat), asCALL_THISCALL); ROR_ASSERT(result>=0); + + // > Gameplay result = engine->RegisterObjectMethod("TerrainClass", "vector3 getSpawnPos()", asMETHOD(RoR::Terrain,getSpawnPos), asCALL_THISCALL); ROR_ASSERT(result>=0); + result = engine->RegisterObjectMethod("TerrainClass", "void addSurveyMapEntity(const string &in type, const string &in filename, const string &in resource_group, const string &in caption, const vector3 &in pos, float angle, int id)", asMETHOD(RoR::Terrain, addSurveyMapEntity), asCALL_THISCALL); ROR_ASSERT(result >= 0); + result = engine->RegisterObjectMethod("TerrainClass", "void delSurveyMapEntities(int id)", asMETHOD(RoR::Terrain, delSurveyMapEntities), asCALL_THISCALL); ROR_ASSERT(result >= 0); + + // > Subsystems result = engine->RegisterObjectMethod("TerrainClass", "ProceduralManagerClassPtr @getProceduralManager()", asMETHOD(RoR::Terrain, getProceduralManager), asCALL_THISCALL); ROR_ASSERT(result >= 0); } diff --git a/source/main/terrain/SurveyMapEntity.h b/source/main/terrain/SurveyMapEntity.h new file mode 100644 index 0000000000..3d09b8d0a8 --- /dev/null +++ b/source/main/terrain/SurveyMapEntity.h @@ -0,0 +1,50 @@ +/* + This source file is part of Rigs of Rods + Copyright 2005-2012 Pierre-Michel Ricordel + Copyright 2007-2012 Thomas Fischer + Copyright 2013-2023 Petr Ohlidal + + For more information, see http://www.rigsofrods.org/ + + Rigs of Rods is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3, as + published by the Free Software Foundation. + + Rigs of Rods 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 Rigs of Rods. If not, see . +*/ + +/// @file + +#pragma once + +#include +#include +#include + +namespace RoR { + + /// @addtogroup Terrain + /// @{ + + struct SurveyMapEntity + { + std::string type; //!< informational + std::string caption; //!< display caption + std::string filename; + std::string resource_group; //!< if empty, defaults to TexturesRG + Ogre::Vector3 pos; //!< world pos in meters + float rot; //!< world yaw in radians + int id; //!< race ID (>=0), or -1 if not a race icon. You can use larger negative numbers for custom IDs. + }; + + typedef std::vector SurveyMapEntityVec; + + /// @} // addtogroup Terrain + +} // namespace RoR diff --git a/source/main/terrain/Terrain.cpp b/source/main/terrain/Terrain.cpp index 21e2db367b..84f76ea429 100644 --- a/source/main/terrain/Terrain.cpp +++ b/source/main/terrain/Terrain.cpp @@ -37,11 +37,14 @@ #include "SkyXManager.h" #include "TerrainGeometryManager.h" #include "TerrainObjectManager.h" +#include "Utils.h" #include "Water.h" #include #include +#include + using namespace RoR; using namespace Ogre; @@ -574,3 +577,18 @@ std::string RoR::Terrain::getTerrainFileResourceGroup() { return m_cache_entry->resource_group; } + +void RoR::Terrain::addSurveyMapEntity(const std::string& type, const std::string& filename, const std::string& resource_group, const std::string& caption, const Ogre::Vector3& pos, float angle, int id) +{ + m_object_manager->m_map_entities.push_back({ type, caption, filename, resource_group, pos, angle, id }); +} + +void RoR::Terrain::delSurveyMapEntities(int id) +{ + EraseIf(m_object_manager->m_map_entities, [id](const SurveyMapEntity& e) { return e.id == id; }); +} + +SurveyMapEntityVec& RoR::Terrain::getSurveyMapEntities() +{ + return m_object_manager->m_map_entities; +} diff --git a/source/main/terrain/Terrain.h b/source/main/terrain/Terrain.h index 3261c80411..72bfd08baa 100644 --- a/source/main/terrain/Terrain.h +++ b/source/main/terrain/Terrain.h @@ -2,7 +2,7 @@ This source file is part of Rigs of Rods Copyright 2005-2012 Pierre-Michel Ricordel Copyright 2007-2012 Thomas Fischer - Copyright 2013-2020 Petr Ohlidal + Copyright 2013-2023 Petr Ohlidal For more information, see http://www.rigsofrods.org/ @@ -19,10 +19,13 @@ along with Rigs of Rods. If not, see . */ +/// @file + #pragma once #include "Application.h" #include "RefCountingObject.h" +#include "SurveyMapEntity.h" #include "TerrainEditor.h" #include "Terrn2FileFormat.h" @@ -74,6 +77,9 @@ class Terrain : public ZeroedMemoryAllocator, public RefCountingObject float getGravity() const { return m_cur_gravity; } Ogre::Vector3 getSpawnPos() { return m_def.start_position; } bool hasPredefinedActors(); + void addSurveyMapEntity(const std::string& type, const std::string& filename, const std::string& resource_group, const std::string& caption, const Ogre::Vector3& pos, float angle, int id); + void delSurveyMapEntities(int id); + SurveyMapEntityVec& getSurveyMapEntities(); /// @} /// @name Subsystems diff --git a/source/main/terrain/TerrainObjectManager.cpp b/source/main/terrain/TerrainObjectManager.cpp index 69001b1cac..e126865adb 100644 --- a/source/main/terrain/TerrainObjectManager.cpp +++ b/source/main/terrain/TerrainObjectManager.cpp @@ -907,7 +907,7 @@ void TerrainObjectManager::LoadTelepoints() { for (Terrn2Telepoint& telepoint: terrainManager->getTerrainDocument().telepoints) { - m_map_entities.push_back({"telepoint", telepoint.name, telepoint.position, 0}); + m_map_entities.push_back({"telepoint", "icon_telepoint.dds", /*resource_group:*/"", telepoint.name, telepoint.position, 0}); } } @@ -987,7 +987,7 @@ void TerrainObjectManager::ProcessODefCollisionBoxes(StaticObject* obj, ODefFile type = "racestart"; } int race_id = res.size() > 1 ? StringConverter::parseInt(res[1], -1) : -1; - m_map_entities.push_back({type, "", params.position, params.rotation.y, race_id}); + m_map_entities.push_back({type, fmt::format("icon_{}.dds", type), /*resource_group:*/"", /*name:*/"", params.position, params.rotation.y, race_id}); } else if (!params.type.empty()) { @@ -997,7 +997,7 @@ void TerrainObjectManager::ProcessODefCollisionBoxes(StaticObject* obj, ODefFile { caption = params.instance_name + " " + params.type; } - m_map_entities.push_back({params.type, caption, params.position, params.rotation.y, -1}); + m_map_entities.push_back({params.type, fmt::format("icon_{}.dds", params.type), /*resource_group:*/"", caption, params.position, params.rotation.y, -1}); } } } diff --git a/source/main/terrain/TerrainObjectManager.h b/source/main/terrain/TerrainObjectManager.h index a757a5b23f..052c34051a 100644 --- a/source/main/terrain/TerrainObjectManager.h +++ b/source/main/terrain/TerrainObjectManager.h @@ -2,6 +2,7 @@ This source file is part of Rigs of Rods Copyright 2005-2012 Pierre-Michel Ricordel Copyright 2007-2012 Thomas Fischer + Copyright 2013-2023 Petr Ohlidal For more information, see http://www.rigsofrods.org/ @@ -24,10 +25,9 @@ #include "Application.h" #include "ODefFileFormat.h" - - #include "MeshObject.h" #include "ProceduralManager.h" +#include "SurveyMapEntity.h" #ifdef USE_PAGED #include "PagedGeometry.h" @@ -48,6 +48,7 @@ namespace RoR { class TerrainObjectManager : public ZeroedMemoryAllocator { + friend class Terrain; public: struct EditorObject @@ -64,20 +65,10 @@ class TerrainObjectManager : public ZeroedMemoryAllocator int script_handler = -1; }; - struct MapEntity - { - Ogre::String type; - Ogre::String name; - Ogre::Vector3 pos; - float rot; - int id; - }; - TerrainObjectManager(Terrain* terrainManager); ~TerrainObjectManager(); std::vector& GetEditorObjects() { return m_editor_objects; } - std::vector& GetMapEntities() { return m_map_entities; } void LoadTObjFile(Ogre::String filename); bool LoadTerrainObject(const Ogre::String& name, const Ogre::Vector3& pos, const Ogre::Vector3& rot, const Ogre::String& instancename, const Ogre::String& type, float rendering_distance = 0, bool enable_collisions = true, int scripthandler = -1, bool uniquifyMaterial = false); void MoveObjectVisuals(const Ogre::String& instancename, const Ogre::Vector3& pos); @@ -169,7 +160,7 @@ class TerrainObjectManager : public ZeroedMemoryAllocator std::vector m_predefined_actors; std::vector m_animated_objects; std::vector m_mesh_objects; - std::vector m_map_entities; + SurveyMapEntityVec m_map_entities; Terrain* terrainManager; ProceduralManagerPtr m_procedural_manager; int m_entity_counter = 0;