diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index d1d4a89bb..910df8b76 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -76,7 +76,7 @@ ENDIF () # This is an incrementing number similar to the Google Android API Version # allowing us to differentiate our Assets API across multiple versions. # If a release is missing this value, then version `1` can be assumed. -SET(VEGASTRIKE_ASSETS_API_VERSION "2") +SET(VEGASTRIKE_ASSETS_API_VERSION "3") #IF (COMMAND cmake_policy) # CMAKE_POLICY (SET CMP0003 NEW) @@ -778,7 +778,7 @@ SET(LIBPYTHON_SOURCES src/python/unit_wrapper.cpp src/python/universe_util_export.cpp - src/python/base_computer/ship_view.cpp + src/python/infra/get_string.cpp ) SET(LIBSCRIPT_SOURCES diff --git a/engine/src/cmd/basecomputer.cpp b/engine/src/cmd/basecomputer.cpp index bc97fe383..f15f9ad7b 100644 --- a/engine/src/cmd/basecomputer.cpp +++ b/engine/src/cmd/basecomputer.cpp @@ -62,8 +62,10 @@ using VSFileSystem::SaveFile; #include "facet_configuration.h" #include "vs_logging.h" #include "controls_factory.h" +#include "python/infra/get_string.h" + +#include #include "configuration/configuration.h" -#include "python/base_computer/ship_view.h" //for directory thing #if defined (_WIN32) && !defined (__CYGWIN__) @@ -79,6 +81,12 @@ using VSFileSystem::SaveFile; #include #include "vega_cast_utils.h" +// Can't declare in header because PyObject is problematic +extern const std::string GetString(const std::string function_name, + const std::string module_name, + const std::string file_name, + PyObject* args); + using namespace XMLSupport; // FIXME -- Shouldn't include an entire namespace, according to Google Style Guide -- stephengtuggy 2021-09-07 //end for directory thing @@ -3931,22 +3939,11 @@ string buildShipDescription(Cargo &item, std::string &texturedescription) { //UNDER CONSTRUCTION string buildUpgradeDescription(Cargo &item) { - //load the Unit - string blnk; //modifications to an upgrade item??? - Flightgroup *flightGroup = new Flightgroup(); //sigh - int fgsNumber = 0; - current_unit_load_mode = NO_MESH; - Unit *newPart = new Unit(item.GetName().c_str(), false, - FactionUtil::GetUpgradeFaction(), blnk, flightGroup, fgsNumber); - current_unit_load_mode = DEFAULT; - string str = ""; - str += item.GetDescription(); - - showUnitStats(newPart, str, 0, 1, item); - - newPart->Kill(); - // delete newPart; - return str; + const std::string key = item.GetName() + "__upgrades"; + PyObject* args = PyTuple_Pack(1, PyUnicode_FromString(key.c_str())); + const std::string text = GetString("get_upgrade_info", "upgrade_view", + "python/base_computer/upgrade_view.py", args); + return text; } class PriceSort { @@ -4476,86 +4473,39 @@ static std::string factionColorTextString(int faction) { return result; } + +// A utility to convert vector to list +boost::python::list VectorToList(const std::vector v) { + boost::python::list l; + for (const std::string& value : v) { + l.append(value); + } + + return l; +} + //Show the player's basic information. bool BaseComputer::showPlayerInfo(const EventCommandId &command, Control *control) { - //Heading. - string text = "#b#Factions:#-b#n1.7#"; - //Number of kills for each faction. - vector *killList = &_Universe->AccessCockpit()->savegame->getMissionData(string("kills")); - - //Make everything bold. - text += "#b#"; - - //A line for each faction. - const size_t numFactions = FactionUtil::GetNumFactions(); - size_t i = 0; - static string disallowedFactions = vs_config->getVariable("graphics", "unprintable_factions", ""); - int totkills = 0; - size_t fac_loc_before = 0, fac_loc = 0, fac_loc_after = 0; - for (; i < numFactions; i++) { - Unit *currentplayer = UniverseUtil::getPlayerX(UniverseUtil::getCurrentPlayer()); - float relation = 0; - size_t upgrades = FactionUtil::GetUpgradeFaction(); - size_t planets = FactionUtil::GetPlanetFaction(); - static size_t privateer = FactionUtil::GetFactionIndex("privateer"); - size_t neutral = FactionUtil::GetNeutralFaction(); - if (i < killList->size() && i != upgrades && i != planets && i != neutral && i != privateer) { - totkills += (int) (*killList)[i]; - } - string factionname = FactionUtil::GetFactionName(i); - fac_loc_after = 0; - fac_loc = disallowedFactions.find(factionname, fac_loc_after); - while (fac_loc != string::npos) { - if (fac_loc > 0) { - fac_loc_before = fac_loc - 1; - } else { - fac_loc_before = 0; - } - fac_loc_after = fac_loc + factionname.size(); - if ((fac_loc == 0 || disallowedFactions[fac_loc_before] == ' ' - || disallowedFactions[fac_loc_before] == '\t') - && (disallowedFactions[fac_loc_after] == ' ' || disallowedFactions[fac_loc_after] == '\t' - || disallowedFactions[fac_loc_after] == '\0')) { - break; - } - fac_loc = disallowedFactions.find(factionname, fac_loc_after); - } - if (fac_loc != string::npos) { - continue; - } - if (currentplayer) { - relation = UnitUtil::getRelationFromFaction(currentplayer, i); - } - if (relation < -1) { - relation = -1; - } - if (relation > 1) { - relation = 1; - } - const int percent = (int) (relation * 100.0); + vector *kill_list = &_Universe->AccessCockpit()->savegame->getMissionData(string("kills")); - //Faction name. - text += factionColorTextString(i) + FactionUtil::GetFactionName(i) + ":#-c "; + const std::vector names_vector = FactionUtil::GetFactionNames(); + const std::vector relations_vector = FactionUtil::GetFactionRelations(); + const std::vector kills_vector = FactionUtil::GetFactionKills(kill_list); - //Relation color. - float normRelation = - (relation + 1) / 2; //Move relation value into 0-1 range. - normRelation = guiMax(0, guiMin(1, normRelation)); //Make *sure* it's in the right range. - text += colorsToCommandString(1 - normRelation, normRelation, guiMin(1 - normRelation, normRelation)); + boost::python::list names_list = VectorToList(names_vector); + boost::python::list relations_list = VectorToList(relations_vector); + boost::python::list kills_list = VectorToList(kills_vector); - //End the line. - text += XMLSupport::tostring(percent) + "#-c"; - if (i < killList->size()) { - text += ", kills: " + XMLSupport::tostring((int) (*killList)[i]); - } - text += "#n#"; - } - //Total Kills if we have it. - text += "#n##b#Total Kills: " + XMLSupport::tostring(totkills) + "#-b#"; + PyObject* args = PyTuple_Pack(3, names_list.ptr(), relations_list.ptr(), kills_list.ptr()); + + const std::string text = GetString("get_player_info", "player_info", + "python/base_computer/player_info.py", args); + //Put this in the description. StaticDisplay *desc = static_cast< StaticDisplay * > ( window()->findControlById("Description")); assert(desc != NULL); + desc->setText(text); return true; @@ -4702,7 +4652,9 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C } if (!mode) { std::map ship_map = playerUnit->UnitToMap(); - text += GetShipView(ship_map); + text += GetString("get_ship_description", "ship_view", + "python/base_computer/ship_view.py", + ship_map); } if (mode && replacement_mode == 2 && playerUnit->getMass() != blankUnit->getMass()) PRETTY_ADDU(statcolor + "Effective Mass reduced by: #-c", 100.0 * (1.0 - playerUnit->getMass()), 0, "%"); diff --git a/engine/src/faction_generic.cpp b/engine/src/faction_generic.cpp index 75f39406e..d8a274906 100644 --- a/engine/src/faction_generic.cpp +++ b/engine/src/faction_generic.cpp @@ -67,3 +67,74 @@ void Faction::ParseAllies(unsigned int thisfaction) { } + +const std::map FactionUtil::GetRelationsMap(const int privateer_faction) { + std::map relations; + + for (int i = 0; i < (int)FactionUtil::GetNumFactions(); i++) { + float relation = FactionUtil::GetIntRelation(i, privateer_faction); + string faction_name = FactionUtil::GetFactionName(i); + const int percent = (int) (relation * 100.0); + relations.insert(std::pair(faction_name, std::to_string(percent))); + } + return relations; +} + +const std::map FactionUtil::GetKillsMap(const std::vector *kill_list) { + //Number of kills for each faction. + std::map kills; + for (int i; i < (int)FactionUtil::GetNumFactions(); i++) { + string faction_name = FactionUtil::GetFactionName(i); + int kills_for_faction = 0; + size_t upgrades = FactionUtil::GetUpgradeFaction(); + size_t planets = FactionUtil::GetPlanetFaction(); + static size_t privateer = FactionUtil::GetFactionIndex("privateer"); + size_t neutral = FactionUtil::GetNeutralFaction(); + if (i < kill_list->size() && i != upgrades && i != planets && i != neutral && i != privateer) { + kills_for_faction = (int) (*kill_list)[i]; + } + + kills.insert(std::pair(faction_name, std::to_string(kills_for_faction))); + } + + return kills; +} + +const std::vector FactionUtil::GetFactionNames() { + std::vector names; + + for (int i = 0; i < factions.size(); i++) { + string faction_name = std::string(factions[i]->factionname); + names.push_back(faction_name); + } + + return names; +} + +const std::vector FactionUtil::GetFactionRelations() { + static const int privateer_faction = FactionUtil::GetFactionIndex("privateer"); + + std::vector relations; + + for (int i = 0; i < factions.size(); i++) { + double relation = FactionUtil::GetIntRelation(i, privateer_faction); + relations.push_back(std::to_string(relation)); + } + + return relations; +} + +const std::vector FactionUtil::GetFactionKills(const std::vector *kill_list) { + std::vector kills; + + for (int i = 0; i < factions.size(); i++) { + int kills_for_faction = 0; + if (i < (int)kill_list->size()) { + kills_for_faction = (int) (*kill_list)[i]; + } + + kills.push_back(std::to_string(kills_for_faction)); + } + + return kills; +} diff --git a/engine/src/faction_generic.h b/engine/src/faction_generic.h index 31e40bba1..6a697f21f 100644 --- a/engine/src/faction_generic.h +++ b/engine/src/faction_generic.h @@ -23,6 +23,8 @@ #define VEGA_STRIKE_ENGINE_FACTION_GENERIC_H #include +#include +#include #include //#include @@ -179,6 +181,13 @@ Animation *GetRandExplosionAnimation(int whichfaction, std::string &which); void LoadFactionPlaylists(); /** Still in faction_xml.cpp because createUnit **/ void LoadContrabandLists(); + +const std::map GetRelationsMap(const int privateer_faction); +const std::map GetKillsMap(const std::vector *kill_list); + +const std::vector GetFactionNames(); +const std::vector GetFactionRelations(); +const std::vector GetFactionKills(const std::vector *kill_list); }; #endif //VEGA_STRIKE_ENGINE_FACTION_GENERIC_H diff --git a/engine/src/python/base_computer/ship_view.cpp b/engine/src/python/infra/get_string.cpp similarity index 70% rename from engine/src/python/base_computer/ship_view.cpp rename to engine/src/python/infra/get_string.cpp index 47d442869..1849e2cf9 100644 --- a/engine/src/python/base_computer/ship_view.cpp +++ b/engine/src/python/infra/get_string.cpp @@ -1,5 +1,5 @@ /* - * ship_view.cpp + * get_string.cpp * * Copyright (c) 2001-2002 Daniel Horn * Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors @@ -25,18 +25,21 @@ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- -#include "ship_view.h" +#include "get_string.h" #include "vsfilesystem.h" #include #include #include -static const std::string module_name = "ship_view"; -const std::string GetShipView(const std::map&ship_stats) { - if(!boost::filesystem::exists("python/base_computer/ship_view.py")) { - return "Error: ship description not found"; + +const std::string GetString(const std::string function_name, + const std::string module_name, + const std::string file_name, + PyObject* args) { + if(!boost::filesystem::exists(file_name)) { + return "Error:" + file_name + "not found"; } PyObject* module = PyImport_ImportModule(module_name.c_str()); @@ -46,24 +49,16 @@ const std::string GetShipView(const std::map&ship_stat return "Error: PyImport_ImportModule is null"; } - boost::python::dict dict; - for (auto const& pair : ship_stats) { - dict[pair.first] = pair.second; - } - - - PyObject* args = PyTuple_Pack(1, dict.ptr()); - if(args == nullptr) { - PyErr_Print(); - return "Error: PyTuple_Pack is null"; - } - - PyObject* function = PyObject_GetAttrString(module,"get_ship_description"); + PyObject* function = PyObject_GetAttrString(module, function_name.c_str()); if(!function) { PyErr_Print(); return "Error: PyObject_GetAttrString is null"; } + if(args == nullptr) { + PyErr_Print(); + return "Error: PyTuple_Pack is null"; + } PyObject* pyResult = PyObject_CallObject(function, args); @@ -75,4 +70,21 @@ const std::string GetShipView(const std::map&ship_stat std::string result = PyUnicode_AsUTF8(pyResult); return result; -} \ No newline at end of file +} + + +const std::string GetString(const std::string function_name, + const std::string module_name, + const std::string file_name, + const std::map& cpp_map) { + boost::python::dict dict; + for (auto const& pair : cpp_map) { + dict[pair.first] = pair.second; + } + + PyObject* args = PyTuple_Pack(1, dict.ptr()); + + return GetString(function_name, module_name, file_name, args); +} + + diff --git a/engine/src/python/base_computer/ship_view.h b/engine/src/python/infra/get_string.h similarity index 70% rename from engine/src/python/base_computer/ship_view.h rename to engine/src/python/infra/get_string.h index 4d6691e36..e0929b82e 100644 --- a/engine/src/python/base_computer/ship_view.h +++ b/engine/src/python/infra/get_string.h @@ -1,5 +1,5 @@ /* - * ship_view.h + * get_string.h * * Copyright (c) 2001-2002 Daniel Horn * Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors @@ -25,12 +25,16 @@ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- -#ifndef VEGA_STRIKE_ENGINE_PYTHON_BASE_COMPUTER_SHIP_VIEW_H -#define VEGA_STRIKE_ENGINE_PYTHON_BASE_COMPUTER_SHIP_VIEW_H +#ifndef VEGA_STRIKE_ENGINE_PYTHON_BASE_COMPUTER_GET_STRING_H +#define VEGA_STRIKE_ENGINE_PYTHON_BASE_COMPUTER_GET_STRING_H #include #include -const std::string GetShipView(const std::map&ship_stats); -#endif // VEGA_STRIKE_ENGINE_PYTHON_BASE_COMPUTER_SHIP_VIEW_H \ No newline at end of file +const std::string GetString(const std::string function_name, + const std::string module_name, + const std::string file_name, + const std::map& cpp_map); + +#endif // VEGA_STRIKE_ENGINE_PYTHON_BASE_COMPUTER_GET_STRING_H \ No newline at end of file