From 12c034ae3d0801a46842704acfe0a888c3d8a656 Mon Sep 17 00:00:00 2001 From: Roy Falk Date: Thu, 21 Nov 2024 06:56:28 +0200 Subject: [PATCH 1/2] Periodic Housekeeping PR 1 (#895) - Remove VS_PI and replace with standard M_PI - Fuel tank is integrated (can't upgrade). Remove options in base_computer. - Use standard ftl_energy.MaxLevel() instead of getWarpEnergy and warpCapData. - Remove support for additive and multiplicative capacitors and reactor. - Make unit_csv load reactor and capacitors the standard way using Load. - Remove WCfuelhack in unit_csv. Make energy source a configuration item. Game doesn't need to compute this every loop. - Remove vsfilesystem reference in unit_csv_factory. Breaks testing. - Remove reference to Unit in Cloak. Improves encapsulation. - Merge EnergyType enum into ComponentType. - Move GetUpgradeType to component_utils. - Remove Component::Describe. We'll do this in python along with the rest of the text in base_computer. - Make component query manifest for price, volume and description. - Add a whole bunch of getters to component. - Add support for infinite energy source. Useful for WC drive and reactor. - Move factors to configuration. You can now control utilization of drive and other components using the config file. - Add resiliency to Graphics2 and Manifest loading. Does not crash game if missing. - Save original figures without factors --- engine/CMakeLists.txt | 2 + engine/src/cmd/basecomputer.cpp | 35 +---- engine/src/cmd/jump_capable.cpp | 3 +- engine/src/cmd/planet.cpp | 2 +- engine/src/cmd/unit_csv.cpp | 68 ++++----- engine/src/cmd/unit_csv_factory.h | 2 - engine/src/cmd/unit_generic.cpp | 12 +- engine/src/cmd/unit_generic.h | 6 +- engine/src/cmd/unit_xml.cpp | 3 +- engine/src/cmd/upgradeable_unit.cpp | 99 ++++++------- engine/src/cmd/upgradeable_unit.h | 25 ---- engine/src/components/cloak.cpp | 8 +- engine/src/components/cloak.h | 14 +- engine/src/components/component.cpp | 43 +++++- engine/src/components/component.h | 49 ++++++- engine/src/components/component_utils.cpp | 131 ++++++++++++++++++ engine/src/components/component_utils.h | 43 ++++++ engine/src/components/energy_consumer.cpp | 32 ++++- engine/src/components/energy_consumer.h | 19 ++- engine/src/components/energy_container.cpp | 104 ++++++++------ engine/src/components/energy_container.h | 19 +-- engine/src/components/ftl_drive.cpp | 20 +-- engine/src/components/ftl_drive.h | 11 +- engine/src/components/jump_drive.cpp | 17 +-- engine/src/components/jump_drive.h | 10 +- engine/src/components/reactor.cpp | 17 ++- engine/src/components/reactor.h | 10 +- .../src/components/tests/balancing_tests.cpp | 29 +++- .../tests/energy_container_tests.cpp | 76 +++++++++- engine/src/configuration/configuration.cpp | 31 ++++- engine/src/configuration/configuration.h | 23 ++- engine/src/resource/manifest.cpp | 33 +++++ engine/src/resource/manifest.h | 1 + engine/src/resource/product.h | 2 + engine/src/resource/tests/manifest_tests.cpp | 1 - engine/src/vs_math.h | 1 - 36 files changed, 679 insertions(+), 322 deletions(-) create mode 100644 engine/src/components/component_utils.cpp create mode 100644 engine/src/components/component_utils.h diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 33bf911507..0d2b1f3506 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -727,6 +727,7 @@ SET(LIBPYTHON SET(LIBCOMPONENT src/components/component.cpp + src/components/component_utils src/components/energy_consumer.cpp src/components/energy_container.cpp @@ -1757,6 +1758,7 @@ IF (USE_GTEST) ADD_LIBRARY(vegastrike-testing ${LIBPYTHON} + ${LIBVS_LOGGING} ${LIBCONFIG} ${LIBDAMAGE} ${LIBRESOURCE} diff --git a/engine/src/cmd/basecomputer.cpp b/engine/src/cmd/basecomputer.cpp index 586ed33128..a292b38039 100644 --- a/engine/src/cmd/basecomputer.cpp +++ b/engine/src/cmd/basecomputer.cpp @@ -65,8 +65,6 @@ using VSFileSystem::SaveFile; #include "python/base_computer/ship_view.h" -//#define VS_PI 3.1415926535897931 - //for directory thing #if defined (_WIN32) && !defined (__CYGWIN__) @@ -2024,6 +2022,7 @@ void BaseComputer::updateTransactionControlsForSelection(TransactionList *tlist) } } //Description. + // TODO: this adds the description to the price. We should move everything to component. descString += item.GetDescription(); descString += tailString; @@ -5006,7 +5005,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C switch (replacement_mode) { case 0: //Replacement or new Module if (MODIFIES_ALTEMPTY(replacement_mode, &uc, &buc, radar.maxrange, FLT_MAX) - || MODIFIES_ALTEMPTY(replacement_mode, &uc, &buc, radar.maxcone, VS_PI)) { + || MODIFIES_ALTEMPTY(replacement_mode, &uc, &buc, radar.maxcone, M_PI)) { PRETTY_ADDU(statcolor + "Tracking range: #-c", uc.radar.maxrange / 1000, 0, "km"); if ((acos(uc.radar.maxcone) * 360 / PI) < 359) { PRETTY_ADDU(statcolor + "Tracking cone: #-c", acos(uc.radar.maxcone) * 2, 2, "radians"); @@ -5060,40 +5059,14 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C if (MODIFIES(replacement_mode, playerUnit, blankUnit, maxEnergyData())) PRETTY_ADDU(statcolor + "Installs main capacitor bank with storage capacity: #-c", (playerUnit->maxEnergyData() * RSconverter), 0, "MJ"); - if (MODIFIES(replacement_mode, playerUnit, blankUnit, getWarpEnergy())) + if (MODIFIES(replacement_mode, playerUnit, blankUnit, ftl_energy.MaxLevel())) PRETTY_ADDU(statcolor + "Installs warp capacitor bank with storage capacity: #-c", - playerUnit->getWarpEnergy() * RSconverter * Wconv, 0, "MJ"); + playerUnit->ftl_energy.MaxLevel() * RSconverter * Wconv, 0, "MJ"); if (buj.Installed() && !uj.Installed()) { text += statcolor + "#n#Allows travel via Jump Points.#n#Consult your personal info screen for ship specific energy requirements. #-c"; } break; - case 1: //Additive - if (MODIFIES(replacement_mode, playerUnit, blankUnit, reactor.Capacity())) - PRETTY_ADDU(statcolor + "Increases recharge rate by #-c", - playerUnit->reactor.Capacity() * RSconverter, 0, "MJ/s"); - if (MODIFIES(replacement_mode, playerUnit, blankUnit, maxEnergyData())) - PRETTY_ADDU(statcolor + "Adds #-c", - (playerUnit->maxEnergyData() * RSconverter), - 0, - "MJ of storage to main capacitor banks"); - if (MODIFIES(replacement_mode, playerUnit, blankUnit, getWarpEnergy())) - PRETTY_ADDU(statcolor + "Adds #-c", - playerUnit->getWarpEnergy() * RSconverter * Wconv, - 0, - "MJ of storage to warp capacitor bank"); - break; - case 2: //multiplicative - if (MODIFIES(replacement_mode, playerUnit, blankUnit, reactor.Capacity())) - PRETTY_ADDU(statcolor + "Increases reactor recharge rate by #-c", - 100.0 * (playerUnit->reactor.Capacity() - 1), 0, "%"); - if (MODIFIES(replacement_mode, playerUnit, blankUnit, maxEnergyData())) - PRETTY_ADDU(statcolor + "Increases main capacitor bank storage by #-c", - 100.0 * (playerUnit->maxEnergyData() - 1), 0, "%"); - if (MODIFIES(replacement_mode, playerUnit, blankUnit, getWarpEnergy())) - PRETTY_ADDU(statcolor + "Increases warp capacitor bank storage by #-c", - (playerUnit->getWarpEnergy() - 1) * 100, 0, "%"); - break; default: //Failure text += "Oh dear, this wasn't an upgrade. Please debug code."; break; diff --git a/engine/src/cmd/jump_capable.cpp b/engine/src/cmd/jump_capable.cpp index 1bd793f5a9..36be5dabd4 100644 --- a/engine/src/cmd/jump_capable.cpp +++ b/engine/src/cmd/jump_capable.cpp @@ -271,8 +271,7 @@ bool JumpCapable::AutoPilotToErrorMessage(const Unit *target, failuremessage = configuration()->graphics_config.hud.already_near_message; return false; } - unit->ftl_energy.Deplete(true, static_cast(totpercent) * unit->ftl_drive.GetAtomConsumption()); - // TODO: figure out to do unit->ftl_drive.Consume() instead + if (unsafe == false && totpercent == 0) { end = endne; } diff --git a/engine/src/cmd/planet.cpp b/engine/src/cmd/planet.cpp index 519410fc74..9daf89c276 100644 --- a/engine/src/cmd/planet.cpp +++ b/engine/src/cmd/planet.cpp @@ -462,7 +462,7 @@ void Planet::InitPlanet(QVector x, VSSprite *tmp = pImage->pHudImage; pImage->pHudImage = un->GetImageInformation().pHudImage; un->GetImageInformation().pHudImage = tmp; - ftl_energy.SetCapacity(un->warpCapData()); + ftl_energy.SetCapacity(un->ftl_energy.MaxLevel()); if (smartplanets) { SubUnits.prepend(un); un->SetRecursiveOwner(this); diff --git a/engine/src/cmd/unit_csv.cpp b/engine/src/cmd/unit_csv.cpp index 9642333ee2..5437344031 100644 --- a/engine/src/cmd/unit_csv.cpp +++ b/engine/src/cmd/unit_csv.cpp @@ -347,7 +347,7 @@ static vector GetSubUnits(const std::string &subunits) { Q.i = nextElementFloat(subunits, elemstart, elemend); Q.j = nextElementFloat(subunits, elemstart, elemend); Q.k = nextElementFloat(subunits, elemstart, elemend); - double restricted = cos(nextElementFloat(subunits, elemstart, elemend, 180) * VS_PI / 180.0); + double restricted = cos(nextElementFloat(subunits, elemstart, elemend, 180) * M_PI / 180.0); ret.push_back(SubUnitStruct(filename, pos, Q, R, restricted)); } else { @@ -609,9 +609,6 @@ void LoadCockpit(Unit *thus, const string &cockpit) { thus->pImage->CockpitCenter.k = nextElementFloat(cockpit, elemstart, elemend); } -float getFuelConversion() { - return configuration()->fuel.fuel_conversion; -} const std::string EMPTY_STRING(""); @@ -624,8 +621,8 @@ void YawPitchRollParser(std::string unit_key, float main_value = UnitCSVFactory::GetVariable(unit_key, main_string, 0.0f); float right_value = UnitCSVFactory::GetVariable(unit_key, right_string, 0.0f); float left_value = UnitCSVFactory::GetVariable(unit_key, left_string, 0.0f); - right_pointer = (right_value > 0 ? right_value : main_value) * VS_PI / 180.; - left_pointer = (left_value > 0 ? left_value : main_value) * VS_PI / 180.; + right_pointer = (right_value > 0 ? right_value : main_value) * M_PI / 180.; + left_pointer = (left_value > 0 ? left_value : main_value) * M_PI / 180.; } void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_game) { @@ -821,21 +818,10 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ // TODO: The following code has a bug. // It will set the max of the component as the current value loaded from the // CSV. If the component is damaged, this will be lower than the original value. - fuel.SetCapacity(UnitCSVFactory::GetVariable(unit_key, "Fuel_Capacity", 0.0), true); - energy.SetCapacity(UnitCSVFactory::GetVariable(unit_key, "Primary_Capacitor", 0.0), true); - ftl_energy.SetCapacity(UnitCSVFactory::GetVariable(unit_key, "Warp_Capacitor", 0.0), true); - reactor.SetCapacity(UnitCSVFactory::GetVariable(unit_key, "Reactor_Recharge", 0.0)); - - const bool WCfuelhack = configuration()->fuel.fuel_equals_warp; - - if (WCfuelhack) { - ftl_energy.SetCapacity(0); - fuel.SetCapacity(ftl_energy.MaxLevel()); - ftl_drive = FtlDrive(&fuel); - jump_drive = JumpDrive(&fuel); - // Add any other component that relies on FTL. - // Especially note the cloaking device support for FTL as an energy source. - } + fuel.Load("", unit_key); + energy.Load("", unit_key); + ftl_energy.Load("", unit_key); + reactor.Load("", unit_key); // End Energy @@ -845,7 +831,7 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ // Bleed factor hints at losing energy. However, here, at 2.0 it's a factor // for reducing warp cost double ftl_factor = configuration()->warp_config.bleed_factor; - ftl_drive.Load("", unit_key, ftl_factor); + ftl_drive.Load("", unit_key); jump_drive.Load("", unit_key); @@ -859,9 +845,9 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ afterburntype = UnitCSVFactory::GetVariable(unit_key, "Afterburner_Type", 0); //type 1 == "use fuel", type 0 == "use reactor energy", type 2 ==(hopefully) "use jump fuel" 3: NO AFTERBURNER - limits.yaw = UnitCSVFactory::GetVariable(unit_key, "Maneuver_Yaw", 0.0f) * VS_PI / 180.0; - limits.pitch = UnitCSVFactory::GetVariable(unit_key, "Maneuver_Pitch", 0.0f) * VS_PI / 180.0; - limits.roll = UnitCSVFactory::GetVariable(unit_key, "Maneuver_Roll", 0.0f) * VS_PI / 180.0; + limits.yaw = UnitCSVFactory::GetVariable(unit_key, "Maneuver_Yaw", 0.0f) * M_PI / 180.0; + limits.pitch = UnitCSVFactory::GetVariable(unit_key, "Maneuver_Pitch", 0.0f) * M_PI / 180.0; + limits.roll = UnitCSVFactory::GetVariable(unit_key, "Maneuver_Roll", 0.0f) * M_PI / 180.0; YawPitchRollParser(unit_key, "Yaw_Governor", @@ -941,9 +927,9 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ } computer.radar.maxrange = UnitCSVFactory::GetVariable(unit_key, "Radar_Range", FLT_MAX); - computer.radar.maxcone = cos(UnitCSVFactory::GetVariable(unit_key, "Max_Cone", 180.0f) * VS_PI / 180); - computer.radar.trackingcone = cos(UnitCSVFactory::GetVariable(unit_key, "Tracking_Cone", 180.0f) * VS_PI / 180); - computer.radar.lockcone = cos(UnitCSVFactory::GetVariable(unit_key, "Lock_Cone", 180.0f) * VS_PI / 180); + computer.radar.maxcone = cos(UnitCSVFactory::GetVariable(unit_key, "Max_Cone", 180.0f) * M_PI / 180); + computer.radar.trackingcone = cos(UnitCSVFactory::GetVariable(unit_key, "Tracking_Cone", 180.0f) * M_PI / 180); + computer.radar.lockcone = cos(UnitCSVFactory::GetVariable(unit_key, "Lock_Cone", 180.0f) * M_PI / 180); const static bool warp_energy_for_cloak = configuration()->warp_config.use_warp_energy_for_cloak; cloak = Cloak(unit_key, (warp_energy_for_cloak ? &ftl_energy : &energy)); @@ -1240,7 +1226,7 @@ const std::map Unit::UnitToMap() { subunits[k].Q.i, subunits[k].Q.j, subunits[k].Q.k, - ((double) acos(subunits[k].restricted) * 180. / VS_PI)); + ((double) acos(subunits[k].restricted) * 180. / M_PI)); str += "{" + subunits[k].filename + tmp; } unit["Sub_Units"] = str; @@ -1343,15 +1329,15 @@ const std::map Unit::UnitToMap() { unit["Wormhole"] = tos(forcejump != 0); unit["Afterburner_Usage_Cost"] = tos(afterburnenergy); unit["Afterburner_Type"] = tos(afterburntype); - unit["Maneuver_Yaw"] = tos(limits.yaw * 180 / (VS_PI)); - unit["Maneuver_Pitch"] = tos(limits.pitch * 180 / (VS_PI)); - unit["Maneuver_Roll"] = tos(limits.roll * 180 / (VS_PI)); - unit["Yaw_Governor_Right"] = tos(computer.max_yaw_right * 180 / VS_PI); - unit["Yaw_Governor_Left"] = tos(computer.max_yaw_left * 180 / VS_PI); - unit["Pitch_Governor_Up"] = tos(computer.max_pitch_up * 180 / VS_PI); - unit["Pitch_Governor_Down"] = tos(computer.max_pitch_down * 180 / VS_PI); - unit["Roll_Governor_Right"] = tos(computer.max_roll_right * 180 / VS_PI); - unit["Roll_Governor_Left"] = tos(computer.max_roll_left * 180 / VS_PI); + unit["Maneuver_Yaw"] = tos(limits.yaw * 180 / (M_PI)); + unit["Maneuver_Pitch"] = tos(limits.pitch * 180 / (M_PI)); + unit["Maneuver_Roll"] = tos(limits.roll * 180 / (M_PI)); + unit["Yaw_Governor_Right"] = tos(computer.max_yaw_right * 180 / M_PI); + unit["Yaw_Governor_Left"] = tos(computer.max_yaw_left * 180 / M_PI); + unit["Pitch_Governor_Up"] = tos(computer.max_pitch_up * 180 / M_PI); + unit["Pitch_Governor_Down"] = tos(computer.max_pitch_down * 180 / M_PI); + unit["Roll_Governor_Right"] = tos(computer.max_roll_right * 180 / M_PI); + unit["Roll_Governor_Left"] = tos(computer.max_roll_left * 180 / M_PI); const float game_accel = configuration()->physics_config.game_accel; const float game_speed = configuration()->physics_config.game_speed; unit["Afterburner_Accel"] = tos(limits.afterburn / (game_accel * game_speed)); @@ -1365,9 +1351,9 @@ const std::map Unit::UnitToMap() { unit["Can_Lock"] = tos(computer.radar.canlock); unit["Radar_Color"] = std::to_string(computer.radar.capability); unit["Radar_Range"] = tos(computer.radar.maxrange); - unit["Tracking_Cone"] = tos(acos(computer.radar.trackingcone) * 180. / VS_PI); - unit["Max_Cone"] = tos(acos(computer.radar.maxcone) * 180. / VS_PI); - unit["Lock_Cone"] = tos(acos(computer.radar.lockcone) * 180. / VS_PI); + unit["Tracking_Cone"] = tos(acos(computer.radar.trackingcone) * 180. / M_PI); + unit["Max_Cone"] = tos(acos(computer.radar.maxcone) * 180. / M_PI); + unit["Lock_Cone"] = tos(acos(computer.radar.lockcone) * 180. / M_PI); cloak.SaveToCSV(unit); unit["Repair_Droid"] = tos(repair_droid); diff --git a/engine/src/cmd/unit_csv_factory.h b/engine/src/cmd/unit_csv_factory.h index 62c0e46dee..6c9876e0c3 100644 --- a/engine/src/cmd/unit_csv_factory.h +++ b/engine/src/cmd/unit_csv_factory.h @@ -30,8 +30,6 @@ #include #include -#include "vsfilesystem.h" - const std::string keys[] = {"Key", "Directory", "Name", "STATUS", "Object_Type", "Combat_Role", "Textual_Description", "Hud_image", "Unit_Scale", "Cockpit", "CockpitX", "CockpitY", "CockpitZ", "Mesh", "Shield_Mesh", "Rapid_Mesh", "BSP_Mesh", diff --git a/engine/src/cmd/unit_generic.cpp b/engine/src/cmd/unit_generic.cpp index 5280228b51..566acdd91b 100644 --- a/engine/src/cmd/unit_generic.cpp +++ b/engine/src/cmd/unit_generic.cpp @@ -1267,14 +1267,14 @@ void Unit::DamageRandSys(float dam, const Vector &vec, float randnum, float degr switch(dist20(rng)) { case 0: fuel.Damage(); break; // Fuel - case 1: energy.Damage(); break; // Energy + case 1: energy.Damage(); break; // Energy case 2: ftl_energy.Damage(); break; case 3: ftl_drive.Damage(); break; case 4: jump_drive.Damage(); break; case 5: this->afterburnenergy += ((1 - dam) * reactor.Capacity()); break; case 6: CargoVolume *= dam; break; case 7: UpgradeVolume *= dam; break; - case 8: + case 8: //Do something NASTY to the cargo if (cargo.size() > 0) { unsigned int i = 0; @@ -3073,12 +3073,6 @@ bool Unit::UpAndDownGrade(const Unit *up, if (!csv_cell_null_check || force_change_on_nothing || cell_has_recursive_data(upgrade_name, up->faction, "ECM_Rating")) STDUPGRADE(ecm, up->ecm, templ->ecm, 0); //ecm is unsigned --chuck_starchaser - /*if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Primary_Capacitor")) { - temporary_upgrade_float_variable = static_cast(energy.MaxValue()); - STDUPGRADE(temporary_upgrade_float_variable, up->energy.MaxValue(), templ->energy.MaxValue(), 0); - energy.SetMaxValue(temporary_upgrade_float_variable); - }*/ } //Maneuvering stuff if (!csv_cell_null_check || force_change_on_nothing @@ -4266,7 +4260,7 @@ void Unit::UpdatePhysics3(const Transformation &trans, ActTurn(); static CloakingStatus previous_status = cloak.status; - cloak.Update(this); + cloak.Update(); // Play once per cloaking if(cloak.Cloaking() && previous_status != CloakingStatus::cloaking) { diff --git a/engine/src/cmd/unit_generic.h b/engine/src/cmd/unit_generic.h index 2ca6eae6b4..ffc3fc5eaa 100644 --- a/engine/src/cmd/unit_generic.h +++ b/engine/src/cmd/unit_generic.h @@ -163,9 +163,9 @@ class Unit : public Armed, public Audible, public Drawable, public Damageable, p public: // Components - EnergyContainer fuel = EnergyContainer(EnergyType::Fuel); - EnergyContainer energy = EnergyContainer(EnergyType::Energy); - EnergyContainer ftl_energy = EnergyContainer(EnergyType::FTL); + EnergyContainer fuel = EnergyContainer(ComponentType::Fuel); + EnergyContainer energy = EnergyContainer(ComponentType::Capacitor); + EnergyContainer ftl_energy = EnergyContainer(ComponentType::FtlCapacitor); // TODO: move this to a single constructor?! Reactor reactor = Reactor(&fuel, &energy, &ftl_energy); diff --git a/engine/src/cmd/unit_xml.cpp b/engine/src/cmd/unit_xml.cpp index cf9157150a..f23c954ad4 100644 --- a/engine/src/cmd/unit_xml.cpp +++ b/engine/src/cmd/unit_xml.cpp @@ -54,7 +54,6 @@ using namespace XMLSupport; /*ADDED FOR extensible use of unit pretty print and unit load */ UNITLOADTYPE current_unit_load_mode = DEFAULT; -extern float getFuelConversion(); string KillQuadZeros(string inp) { std::string::size_type text = 0; @@ -115,6 +114,8 @@ string MakeUnitXMLPretty(string str, Unit *un) { return writestr; } +// TODO: delete this at some point. +// We no longer support add/mul modes of upgrades int GetModeFromName(const char *input_buffer) { if (strlen(input_buffer) > 3) { if (input_buffer[0] == 'a' diff --git a/engine/src/cmd/upgradeable_unit.cpp b/engine/src/cmd/upgradeable_unit.cpp index 740ac874ea..150c5b52eb 100644 --- a/engine/src/cmd/upgradeable_unit.cpp +++ b/engine/src/cmd/upgradeable_unit.cpp @@ -33,6 +33,8 @@ #include #include +#include "components/component.h" +#include "components/component_utils.h" #include "unit_const_cache.h" #include "faction_generic.h" #include "unit_generic.h" @@ -67,6 +69,34 @@ std::vector ParseUnitUpgrades(const std::string &upgrades) { return upgrades_vector; } +// A simple struct for holding all the data +// TODO: figure out what the numbers mean +// TODO: move this to Cargo or a subclass of cargo +// TODO: separate cargo from upgrades +struct CargoUpgrade { + std::string name; + std::string category; + + CargoUpgrade(const std::string upgrade_string) { + if(upgrade_string.empty()) { + return; + } + + const std::string delimiter = ";"; + + std::vector upgrade_vector; + boost::split(upgrade_vector, upgrade_string, boost::is_any_of(delimiter)); + + // TODO: figure out format and change 3 to the real size and implement the rest + if(upgrade_vector.size() < 3) { + return; + } + + name = upgrade_vector.at(0); + category = upgrade_vector.at(1); + } +}; + // TODO: why do we have to use such kludges?! unsigned int convert_to_int(std::string s) { if(s.size() == 0) { @@ -87,97 +117,50 @@ UpgradeableUnit::UpgradeableUnit() extern int GetModeFromName(const char *input_buffer); -UpgradeType GetUpgradeType(const std::string upgrade_key) { - std::string upgrade_type_string = UnitCSVFactory::GetVariable(upgrade_key, "Upgrade_Type", std::string()); - std::string upgrade_name = UnitCSVFactory::GetVariable(upgrade_key, "Name", std::string()); - - if(upgrade_type_string.empty()) return UpgradeType::None; - - if(upgrade_type_string == "Armor") { - return UpgradeType::Armor; - } - //if(upgrade_type_string == "Hull") return UpgradeType::Hull; - if(upgrade_type_string == "Shield") { - return UpgradeType::Shield; - } - - if(upgrade_type_string == "Reactor") { - return UpgradeType::Reactor; - } - - if(upgrade_type_string == "FTL_Capacitor") { - return UpgradeType::FTL_Capacitor; - } - - if(upgrade_type_string == "Capacitor") { - return UpgradeType::Capacitor; - } - - if(upgrade_type_string == "FTL_Drive") { - return UpgradeType::FTL_Drive; - } - - if(upgrade_type_string == "Jump_Drive") { - return UpgradeType::Jump_Drive; - } - - if(upgrade_type_string == "Cloak") { - return UpgradeType::Cloak; - } - - if(upgrade_type_string == "Jump_Drive") { - return UpgradeType::Jump_Drive; - } - - if(upgrade_type_string == "Afterburner") { - return UpgradeType::Afterburner; - } - return UpgradeType::None; -} UpgradeOperationResult UpgradeableUnit::UpgradeUnit(const std::string upgrade_name, bool upgrade, bool apply) { Unit* unit = vega_dynamic_cast_ptr(this); const std::string upgrade_key = upgrade_name + UPGRADES_SUFFIX; - const UpgradeType upgrade_type = GetUpgradeType(upgrade_key); + const ComponentType component_type = GetComponentTypeFromName(upgrade_name); UpgradeOperationResult result; - switch(upgrade_type) { - /*case UpgradeType::Armor: + switch(component_type) { + /*case ComponentType::Armor: result.upgradeable = true; result.success = unit->armor->CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - case UpgradeType::Shield: + case ComponentType::Shield: result.upgradeable = true; result.success = unit->shield->CanWillUpDowngrade(upgrade_key, upgrade, apply); break;*/ - case UpgradeType::Capacitor: + case ComponentType::Capacitor: result.upgradeable = true; result.success = unit->energy.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - case UpgradeType::FTL_Capacitor: + case ComponentType::FtlCapacitor: result.upgradeable = true; result.success = unit->ftl_energy.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - case UpgradeType::Reactor: + case ComponentType::Reactor: result.upgradeable = true; result.success = unit->reactor.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - case UpgradeType::FTL_Drive: + case ComponentType::FtlDrive: result.upgradeable = true; result.success = unit->ftl_drive.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - case UpgradeType::Jump_Drive: + case ComponentType::JumpDrive: result.upgradeable = true; result.success = unit->jump_drive.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - case UpgradeType::Cloak: + case ComponentType::Cloak: result.upgradeable = true; result.success = unit->cloak.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; @@ -189,7 +172,7 @@ UpgradeOperationResult UpgradeableUnit::UpgradeUnit(const std::string upgrade_na case UpgradeType::Drive: result.upgradeable = true; result.success = unit->armor->CanWillUpDowngrade(upgrade_key, upgrade, apply); - break; + break;*/ /*case UpgradeType::ECM: diff --git a/engine/src/cmd/upgradeable_unit.h b/engine/src/cmd/upgradeable_unit.h index 3b01673bff..ad862e32f3 100644 --- a/engine/src/cmd/upgradeable_unit.h +++ b/engine/src/cmd/upgradeable_unit.h @@ -41,32 +41,7 @@ struct UpgradeOperationResult { bool upgradeable = false; // Temp variable. Until we map all types. }; -enum class UpgradeType { - None, - Armor, - //Hull, // Can't upgrade the hull right now - Shield, - - Capacitor, - FTL_Capacitor, - Reactor, - - Afterburner, - Drive, - Jump_Drive, - FTL_Drive, - - Cloak, - ECM, - Radar, - - Repair_Droid - - // TODO: all the rest of the upgrades, shady or not... -}; - -UpgradeType GetUpgradeType(const std::string upgrade_key); // TODO: make this into a subclass of unit later diff --git a/engine/src/components/cloak.cpp b/engine/src/components/cloak.cpp index a1db779cdf..8078d27468 100644 --- a/engine/src/components/cloak.cpp +++ b/engine/src/components/cloak.cpp @@ -24,7 +24,6 @@ #include "cloak.h" #include "unit_csv_factory.h" -#include "vegastrike.h" #include "configuration/configuration.h" #include "unit_generic.h" @@ -32,6 +31,7 @@ Cloak::Cloak() : Component(), EnergyConsumer(nullptr, 0, false) { + type = ComponentType::Cloak; _Downgrade(); } @@ -41,6 +41,7 @@ Cloak::Cloak(std::string unit_key, EnergyContainer* capacitor) : UnitCSVFactory::GetVariable(unit_key, "Cloak_Energy", 0.0), false) { + type = ComponentType::Cloak; _Upgrade(unit_key); } @@ -53,9 +54,6 @@ void Cloak::SaveToCSV(std::map& unit) const { unit["Cloak_Glass"] = std::to_string(glass); } -std::string Cloak::Describe() const { - return std::string(); -} bool Cloak::CanDowngrade() const { return true; @@ -117,7 +115,7 @@ bool Cloak::Installed() const { // Cloak Methods -void Cloak::Update(Unit *unit) +void Cloak::Update() { // Unit is not capable of cloaking or damaged or just not cloaking if(status == CloakingStatus::disabled || diff --git a/engine/src/components/cloak.h b/engine/src/components/cloak.h index 702beec803..3dbf8de292 100644 --- a/engine/src/components/cloak.h +++ b/engine/src/components/cloak.h @@ -22,19 +22,16 @@ * along with Vega Strike. If not, see . */ -#ifndef CLOAK_H -#define CLOAK_H +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_CLOAK_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_CLOAK_H #include #include -#include "energetic.h" -#include "damageable_layer.h" -#include "energy_container.h" #include "energy_consumer.h" // TODO: remove dependency on unit -class Unit; +class EnergyContainer; enum class CloakingStatus { disabled, @@ -69,7 +66,6 @@ class Cloak : public Component, public EnergyConsumer Cloak(std::string unit_key, EnergyContainer* capacitor); virtual void SaveToCSV(std::map& unit) const; - virtual std::string Describe() const; virtual bool CanDowngrade() const; @@ -86,7 +82,7 @@ class Cloak : public Component, public EnergyConsumer virtual bool Damaged() const; virtual bool Installed() const; - void Update(Unit *unit); + void Update(); void Toggle(); // Toggle cloak on/off bool Capable() const { @@ -150,4 +146,4 @@ class Cloak : public Component, public EnergyConsumer void _Upgrade(const std::string upgrade_key); }; -#endif // CLOAK_H +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_CLOAK_H diff --git a/engine/src/components/component.cpp b/engine/src/components/component.cpp index b625f4f954..7cc3993363 100644 --- a/engine/src/components/component.cpp +++ b/engine/src/components/component.cpp @@ -27,6 +27,10 @@ #include "component.h" #include "unit_csv_factory.h" +#include "resource/cargo.h" +#include "resource/manifest.h" + + const std::string NAME = "Name"; const std::string MASS = "Mass"; @@ -35,6 +39,8 @@ const std::string VOLUME = "Volume"; Component::Component(double mass, double volume, bool installed, bool integral): unit_key(""), upgrade_name(""), + description(""), + price(0.0), mass(mass), volume(volume), operational(Resource(100.0,0.0,100.0)), installed(installed), @@ -43,11 +49,23 @@ Component::Component(double mass, double volume, bool installed, bool integral): void Component::Load(std::string upgrade_key, std::string unit_key) { this->unit_key = unit_key; - upgrade_name = UnitCSVFactory::GetVariable(upgrade_key, "Name", std::string()); this->upgrade_key = upgrade_key; - - mass = UnitCSVFactory::GetVariable(upgrade_key, "Mass", 0.0); - // TODO: volume = UnitCSVFactory::GetVariable(upgrade_key, "Volume", 0.0); + + // Integrated components have no name, mass, price, volume or description + if(!integral) { + upgrade_name = UnitCSVFactory::GetVariable(upgrade_key, "Name", std::string()); + mass = UnitCSVFactory::GetVariable(upgrade_key, "Mass", 0.0); + + // Get volume and description from MasterPartList. + // We need try/catch for unit tests where MPL isn't loaded. + const Cargo cargo = Manifest::MPL().GetCargoByName(upgrade_key); + if(!cargo.GetName().empty()) { + price = cargo.GetPrice(); + volume = cargo.GetVolume(); + description = cargo.GetDescription(); + } + } + // TODO: bool integral = false; } @@ -124,4 +142,19 @@ double Component::Percent() const { void Component::SetIntegral(bool integral) { this->integral = integral; -} \ No newline at end of file +} + +// Getters +const std::string Component::GetUnitKey() const { return unit_key; } +const std::string Component::GetUpgradeName() const { return upgrade_name; } +const std::string Component::GetUpgradeKey() const { return upgrade_key; } +const std::string Component::GetDescription() const { return description; } + +const double Component::GetPrice() const { return price; } +const double Component::GetMass() const { return mass; } +const double Component::GetVolume() const { return volume; } + +const double Component::GetOperational() const { return operational.Value(); } + +const bool Component::GetInstalled() const { return installed; } +const bool Component::GetIntegral() const { return integral; } \ No newline at end of file diff --git a/engine/src/components/component.h b/engine/src/components/component.h index 4b2be46474..b9e68ccdba 100644 --- a/engine/src/components/component.h +++ b/engine/src/components/component.h @@ -25,8 +25,8 @@ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- -#ifndef COMPONENT_H -#define COMPONENT_H +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_COMPONENT_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_COMPONENT_H #include #include @@ -43,10 +43,27 @@ class Unit; // TODO: add complete list enum class ComponentType { + None, + Dummy, + Hull, Armor, Shield, - Drive + + Afterburner, + AfterburnerUpgrade, + Drive, + DriveUpgrade, + FtlDrive, + JumpDrive, + + Reactor, + Capacitor, + FtlCapacitor, + Fuel, + + Cloak + // TODO: all the rest of the upgrades, shady or not... }; class Component @@ -55,7 +72,9 @@ class Component std::string unit_key; // Areus.blank std::string upgrade_name; // Isometal Armor std::string upgrade_key; // armor03__upgrades + std::string description; // Long text and picture. Taken from master_parts_list + double price = 0; double mass = 0; double volume = 0; @@ -64,18 +83,19 @@ class Component bool installed = false; bool integral = false; // Part of the ship. Can't be upgraded/downgraded public: + ComponentType type = ComponentType::None; + Component(double mass = 0, double volume = 0, bool installed = false, bool integral = false); // Load from units dictionary - virtual void Load(std::string upgrade_key, std::string unit_key); + // TODO: we should really switch the two parameters around. + virtual void Load(std::string upgrade_key, std::string unit_key = ""); virtual void SaveToCSV(std::map& unit) const = 0; - virtual std::string Describe() const = 0; // Describe component in base_computer - // Handle the four cases of CanUpgrade/Upgrade/CanDowngrade/Downgrade bool CanWillUpDowngrade(const std::string upgrade_key, bool upgrade, bool apply); @@ -99,5 +119,20 @@ class Component bool Operational() const; void SetIntegral(bool integral); + + // Getters + const std::string GetUnitKey() const; + const std::string GetUpgradeName() const; + const std::string GetUpgradeKey() const; + const std::string GetDescription() const; + + const double GetPrice() const; + const double GetMass() const; + const double GetVolume() const; + + const double GetOperational() const; + + const bool GetInstalled() const; + const bool GetIntegral() const; }; -#endif // COMPONENT_H +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_COMPONENT_H diff --git a/engine/src/components/component_utils.cpp b/engine/src/components/component_utils.cpp new file mode 100644 index 0000000000..58f4ce77cb --- /dev/null +++ b/engine/src/components/component_utils.cpp @@ -0,0 +1,131 @@ +/* + * src/components/component_printer.cpp + * + * Copyright (C) 2001-2023 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, + * and other Vega Strike contributors. + * + * https://github.com/vegastrike/Vega-Strike-Engine-Source + * + * This file is part of Vega Strike. + * + * Vega Strike 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 3 of the License, or + * (at your option) any later version. + * + * Vega Strike 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 Vega Strike. If not, see . + */ + +#include "component_utils.h" + +#include "component.h" + +#include "reactor.h" +#include "energy_container.h" + +#include "jump_drive.h" +#include "ftl_drive.h" +#include "cloak.h" + +#include "unit_csv_factory.h" +#include "configuration/configuration.h" + +#include + + + +const ComponentType GetComponentTypeFromName(const std::string name) { + std::string upgrade_key = name + "__upgrades"; + + const std::string upgrade_category = UnitCSVFactory::GetVariable(upgrade_key, "Upgrade_Type", std::string()); + if(upgrade_category == "None") { + return ComponentType::None; + } else if(upgrade_category == "Dummy") { + return ComponentType::Dummy; + } else if(upgrade_category == "Hull") { + return ComponentType::Hull; + } else if(upgrade_category == "Armor") { + return ComponentType::Armor; + } else if(upgrade_category == "Shield") { + return ComponentType::Shield; + } else if(upgrade_category == "Afterburner") { + return ComponentType::Afterburner; + } else if(upgrade_category == "Afterburner_Upgrade") { + return ComponentType::AfterburnerUpgrade; + } else if(upgrade_category == "Drive") { + return ComponentType::Drive; + } else if(upgrade_category == "Drive_Upgrade") { + return ComponentType::DriveUpgrade; + } else if(upgrade_category == "Ftl_Drive") { + return ComponentType::FtlDrive; + } else if(upgrade_category == "Jump_Drive") { + return ComponentType::JumpDrive; + } else if(upgrade_category == "Reactor") { + return ComponentType::Reactor; + } else if(upgrade_category == "Capacitor") { + return ComponentType::Capacitor; + } else if(upgrade_category == "FTL_Capacitor") { + return ComponentType::FtlCapacitor; + } else if(upgrade_category == "Fuel") { + return ComponentType::Fuel; + } else if(upgrade_category == "Cloak") { + return ComponentType::Cloak; + } else { + return ComponentType::None; + } +} + + +EnergyContainer* GetSource(ComponentType component_type, EnergyContainer* fuel, + EnergyContainer* energy, EnergyContainer* ftl_energy) { + switch(component_type) { + case ComponentType::None: + case ComponentType::Dummy: + case ComponentType::Hull: + case ComponentType::Armor: + case ComponentType::AfterburnerUpgrade: + case ComponentType::DriveUpgrade: + case ComponentType::Capacitor: + case ComponentType::FtlCapacitor: + case ComponentType::Fuel: + return nullptr; + + case ComponentType::Shield: return energy; + + case ComponentType::FtlDrive: return ftl_energy; + + case ComponentType::Reactor: + return GetSourceFromConfiguration(configuration()->fuel.reactor_source, + fuel, energy, ftl_energy); + case ComponentType::Drive: + return GetSourceFromConfiguration(configuration()->fuel.drive_source, + fuel, energy, ftl_energy); + case ComponentType::Afterburner: + return GetSourceFromConfiguration(configuration()->fuel.afterburner_source, + fuel, energy, ftl_energy); + case ComponentType::JumpDrive: + return GetSourceFromConfiguration(configuration()->fuel.jump_drive_source, + fuel, energy, ftl_energy); + case ComponentType::Cloak: + return GetSourceFromConfiguration(configuration()->fuel.cloak_source, + fuel, energy, ftl_energy); + } +} + +// 0 infinite, 1 fuel, 2 energy, 3 ftl_energy, 4 disabled +EnergyContainer* GetSourceFromConfiguration(const EnergyConsumerSource source, EnergyContainer* fuel, + EnergyContainer* energy, EnergyContainer* ftl_energy) { + switch(source) { + case EnergyConsumerSource::Infinite: return nullptr; + case EnergyConsumerSource::Fuel: return fuel; + case EnergyConsumerSource::Energy: return energy; + case EnergyConsumerSource::FTLEnergy: return ftl_energy; + default: return nullptr; + } +} diff --git a/engine/src/components/component_utils.h b/engine/src/components/component_utils.h new file mode 100644 index 0000000000..f48661a615 --- /dev/null +++ b/engine/src/components/component_utils.h @@ -0,0 +1,43 @@ +/* + * src/components/component_printer.h + * + * Copyright (C) 2001-2023 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, + * and other Vega Strike contributors. + * + * https://github.com/vegastrike/Vega-Strike-Engine-Source + * + * This file is part of Vega Strike. + * + * Vega Strike 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 3 of the License, or + * (at your option) any later version. + * + * Vega Strike 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 Vega Strike. If not, see . + */ + +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_COMPONENT_UTILS_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_COMPONENT_UTILS_H + +#include "component.h" +#include "energy_consumer.h" +#include "energy_container.h" + +#include + +/** A collection of utility functions for lib component. */ +const ComponentType GetComponentTypeFromName(const std::string name); + +EnergyContainer* GetSource(ComponentType component_type, EnergyContainer* fuel, + EnergyContainer* energy, EnergyContainer* ftl_energy); + +EnergyContainer* GetSourceFromConfiguration(const EnergyConsumerSource source, EnergyContainer* fuel, + EnergyContainer* energy, EnergyContainer* ftl_energy); + +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_COMPONENT_UTILS_H diff --git a/engine/src/components/energy_consumer.cpp b/engine/src/components/energy_consumer.cpp index de9cfd0a88..857659969c 100644 --- a/engine/src/components/energy_consumer.cpp +++ b/engine/src/components/energy_consumer.cpp @@ -29,16 +29,30 @@ double EnergyConsumer::simulation_atom_var = 0.1; +EnergyConsumerSource GetSource(const int source) { + switch(source) { + case 0: return EnergyConsumerSource::Infinite; + case 1: return EnergyConsumerSource::Fuel; + case 2: return EnergyConsumerSource::Energy; + case 3: return EnergyConsumerSource::FTLEnergy; + default: return EnergyConsumerSource::None; + } +} + EnergyConsumer::EnergyConsumer(EnergyContainer *source, bool partial, - double consumption): - source(source), - partial(partial), + double consumption, bool infinite): consumption(consumption), - atom_consumption(consumption * simulation_atom_var) {} + atom_consumption(consumption * simulation_atom_var), + source(source), + partial(partial), + infinite(false) {} +bool EnergyConsumer::CanConsume() const { + if(infinite) { + return true; + } -bool EnergyConsumer::CanConsume() { // TODO: need to check if operational somewhere else if(!source) { return false; @@ -48,6 +62,10 @@ bool EnergyConsumer::CanConsume() { } double EnergyConsumer::Consume() { + if(infinite) { + return atom_consumption; + } + if(!source) { return 0.0; } @@ -73,5 +91,9 @@ void EnergyConsumer::SetSource(EnergyContainer* source) { } void EnergyConsumer::ZeroSource() { + if(!source) { + return; + } + source->Zero(); } \ No newline at end of file diff --git a/engine/src/components/energy_consumer.h b/engine/src/components/energy_consumer.h index ec7f5db049..287dd5b2c0 100644 --- a/engine/src/components/energy_consumer.h +++ b/engine/src/components/energy_consumer.h @@ -25,11 +25,17 @@ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- -#ifndef ENERGYCONSUMER_H -#define ENERGYCONSUMER_H +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_ENERGYCONSUMER_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_ENERGYCONSUMER_H #include "energy_container.h" +enum class EnergyConsumerSource { + Infinite, Fuel, Energy, FTLEnergy, None +}; + +EnergyConsumerSource GetSource(const int source); + class EnergyConsumer { protected: double consumption; // Directly converted to atomic. Mostly for book keeping. @@ -40,9 +46,12 @@ class EnergyConsumer { private: EnergyContainer *source; bool partial; // Can power consumer with less energy than requested + +protected: + bool infinite; // Connected to infinite power source. Ignore source field. Always work. public: - EnergyConsumer(EnergyContainer *source, bool partial, double consumption = 0.0); - bool CanConsume(); + EnergyConsumer(EnergyContainer *source = nullptr, bool partial = false, double consumption = 0.0, bool infinite = false); + bool CanConsume() const; double Consume(); double GetConsumption() const; double GetAtomConsumption() const; @@ -52,4 +61,4 @@ class EnergyConsumer { }; -#endif // ENERGYCONSUMER_H +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_ENERGYCONSUMER_H diff --git a/engine/src/components/energy_container.cpp b/engine/src/components/energy_container.cpp index e786c46f06..e292649be2 100644 --- a/engine/src/components/energy_container.cpp +++ b/engine/src/components/energy_container.cpp @@ -27,17 +27,29 @@ #include "energy_container.h" #include "unit_csv_factory.h" +#include "configuration/configuration.h" #include const std::string FUEL_CAPACITY = "Fuel_Capacity"; -const std::string CAPACITOR = "Warp_Capacitor"; -const std::string FTL_CAPACITOR = "Primary_Capacitor"; +const std::string CAPACITOR = "Primary_Capacitor"; +const std::string FTL_CAPACITOR = "Warp_Capacitor"; -EnergyContainer::EnergyContainer(EnergyType type): +EnergyContainer::EnergyContainer(ComponentType type): Component(0.0, 0.0, false), - type(type), - level(Resource(0.0,0.0,0.0)) {} + level(Resource(0.0,0.0,0.0)) { + switch(type) { + case ComponentType::Fuel: + case ComponentType::Capacitor: + case ComponentType::FtlCapacitor: + this->type = type; + break; + + default: + this->type = ComponentType::None; + break; + } +} // Return value - any surplus charge @@ -96,45 +108,51 @@ void EnergyContainer::Refill() { // Component Functions void EnergyContainer::Load(std::string upgrade_key, std::string unit_key) { // Component - upgrade_key = ""; + Component::Load(upgrade_key, unit_key); // TODO: nice to have - ship mass goes down as fuel depleted - mass = 0; - volume = 0; - double capacity = 0.0; - switch(type) { - case EnergyType::Fuel: - upgrade_name = "Fuel"; - capacity = UnitCSVFactory::GetVariable(unit_key, FUEL_CAPACITY, 1.0); + case ComponentType::Fuel: + level = Resource(UnitCSVFactory::GetVariable(unit_key, FUEL_CAPACITY, std::string("0.0")), configuration()->fuel.fuel_factor); break; - case EnergyType::Energy: - upgrade_name = "Capacitor"; - capacity = UnitCSVFactory::GetVariable(unit_key, CAPACITOR, 1.0); + case ComponentType::Capacitor: + level = Resource(UnitCSVFactory::GetVariable(unit_key, CAPACITOR, std::string("0.0")), configuration()->fuel.energy_factor); break; - case EnergyType::FTL: - upgrade_name = "FTL_Capacitor"; - capacity = UnitCSVFactory::GetVariable(unit_key, FTL_CAPACITOR, 1.0); - break; + case ComponentType::FtlCapacitor: + level = Resource(UnitCSVFactory::GetVariable(unit_key, FTL_CAPACITOR, std::string("0.0")), configuration()->fuel.ftl_energy_factor); + break; - case EnergyType::None: - break; + default: // This really can't happen + std::cerr << "Illegal container type in EnergyContainer::Load" << std::flush; + abort(); } - - SetCapacity(capacity); } void EnergyContainer::SaveToCSV(std::map& unit) const { - unit[FUEL_CAPACITY] = std::to_string(MaxLevel()); -} + switch(type) { + case ComponentType::Fuel: + unit[FUEL_CAPACITY] = std::to_string(MaxLevel() / configuration()->fuel.fuel_factor); + break; -std::string EnergyContainer::Describe() const { - return std::string(); + case ComponentType::Capacitor: + unit[FUEL_CAPACITY] = std::to_string(MaxLevel() / configuration()->fuel.energy_factor); + break; + + case ComponentType::FtlCapacitor: + unit[FUEL_CAPACITY] = std::to_string(MaxLevel() / configuration()->fuel.ftl_energy_factor); + break; + + default: // This really can't happen + std::cerr << "Illegal container type in EnergyContainer::SaveToCSV" << std::flush; + abort(); + } } + + bool EnergyContainer::CanDowngrade() const { return !Damaged(); } @@ -144,6 +162,9 @@ bool EnergyContainer::Downgrade() { return false; } + // Component + Component::Downgrade(); + level.SetMaxValue(0.0); return true; } @@ -157,29 +178,28 @@ bool EnergyContainer::Upgrade(const std::string upgrade_key) { return false; } - this->upgrade_key = upgrade_key; - upgrade_name = UnitCSVFactory::GetVariable(upgrade_key, "Name", std::string()); + // Component + Component::Upgrade(upgrade_key); + + // TODO: nice to have - ship mass goes down as fuel depleted - double capacity = 0.0; - switch(type) { - case EnergyType::Fuel: - capacity = UnitCSVFactory::GetVariable(upgrade_key, FUEL_CAPACITY, 1.0); + case ComponentType::Fuel: + level.SetMaxValue(UnitCSVFactory::GetVariable(upgrade_key, FUEL_CAPACITY, 0.0)); break; - case EnergyType::Energy: - capacity = UnitCSVFactory::GetVariable(upgrade_key, CAPACITOR, 1.0); + case ComponentType::Capacitor: + level.SetMaxValue(UnitCSVFactory::GetVariable(upgrade_key, CAPACITOR, 0.0)); break; - case EnergyType::FTL: - capacity = UnitCSVFactory::GetVariable(upgrade_key, FTL_CAPACITOR, 1.0); - break; + case ComponentType::FtlCapacitor: + level.SetMaxValue(UnitCSVFactory::GetVariable(upgrade_key, FTL_CAPACITOR, 0.0)); + break; - case EnergyType::None: - break; + default: // This really can't happen + abort(); } - SetCapacity(capacity); return true; } diff --git a/engine/src/components/energy_container.h b/engine/src/components/energy_container.h index 39b65ed7a6..99c7f459b7 100644 --- a/engine/src/components/energy_container.h +++ b/engine/src/components/energy_container.h @@ -25,8 +25,8 @@ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- -#ifndef ENERGYCONTAINER_H -#define ENERGYCONTAINER_H +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_ENERGYCONTAINER_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_ENERGYCONTAINER_H #include #include @@ -38,12 +38,6 @@ * it would be easier for a new developer or someone from WC * to figure what it means. */ -enum class EnergyType { - Fuel, // 1 - Energy, // 0 Capacitor - FTL, // 2 FTL - None // 3 Free Energy -}; /** @@ -52,11 +46,10 @@ enum class EnergyType { class EnergyContainer: public Component { private: - EnergyType type; Resource level; public: - EnergyContainer(EnergyType type); + EnergyContainer(ComponentType type); // Return value - any surplus charge double Charge(const double quantity); @@ -75,12 +68,10 @@ class EnergyContainer: public Component void Zero(); // Component - virtual void Load(std::string upgrade_key, std::string unit_key); + virtual void Load(std::string upgrade_key, std::string unit_key = ""); virtual void SaveToCSV(std::map& unit) const; - virtual std::string Describe() const; // Describe component in base_computer - virtual bool CanDowngrade() const; virtual bool Downgrade(); @@ -98,4 +89,4 @@ class EnergyContainer: public Component virtual bool Installed() const; }; -#endif // ENERGYCONTAINER_H +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_ENERGYCONTAINER_H diff --git a/engine/src/components/ftl_drive.cpp b/engine/src/components/ftl_drive.cpp index 908285721f..2d3a76e1a6 100644 --- a/engine/src/components/ftl_drive.cpp +++ b/engine/src/components/ftl_drive.cpp @@ -25,14 +25,19 @@ #include "ftl_drive.h" #include "unit_csv_factory.h" +#include "configuration/configuration.h" FtlDrive::FtlDrive() : Component(), - EnergyConsumer(nullptr, 0, false) {} + EnergyConsumer(nullptr, 0, false) { + type = ComponentType::FtlDrive; +} FtlDrive::FtlDrive(EnergyContainer *source): Component(0.0, 0.0, true), - EnergyConsumer(source, false) {} + EnergyConsumer(source, false) { + type = ComponentType::FtlDrive; +} bool FtlDrive::Enabled() const { @@ -42,25 +47,20 @@ bool FtlDrive::Enabled() const { // Component Methods void FtlDrive::Load(std::string upgrade_key, - std::string unit_key, - double ftl_factor) { + std::string unit_key) { Component::Load(upgrade_key, unit_key); // Consumer double energy = UnitCSVFactory::GetVariable(unit_key, "Warp_Usage_Cost", 0.0f); - SetConsumption(energy / ftl_factor); + SetConsumption(energy * configuration()->fuel.ftl_drive_factor); // FTL Drive } void FtlDrive::SaveToCSV(std::map& unit) const { - unit["Warp_Usage_Cost"] = std::to_string(consumption); + unit["Warp_Usage_Cost"] = std::to_string(consumption / configuration()->fuel.ftl_drive_factor); } -std::string FtlDrive::Describe() const { - return std::string(); -} - // FTL drive is integrated and so cannot be upgraded/downgraded bool FtlDrive::CanDowngrade() const { return false; diff --git a/engine/src/components/ftl_drive.h b/engine/src/components/ftl_drive.h index b9dcc6d249..19a7175ba3 100644 --- a/engine/src/components/ftl_drive.h +++ b/engine/src/components/ftl_drive.h @@ -22,8 +22,8 @@ * along with Vega Strike. If not, see . */ -#ifndef FTL_DRIVE_H -#define FTL_DRIVE_H +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_FTL_DRIVE_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_FTL_DRIVE_H #include "component.h" #include "energy_consumer.h" @@ -42,13 +42,10 @@ class FtlDrive : public Component, public EnergyConsumer { // Component Methods virtual void Load(std::string upgrade_key, - std::string unit_key, - double ftl_factor = 1.0); + std::string unit_key = ""); virtual void SaveToCSV(std::map& unit) const; - virtual std::string Describe() const; // Describe component in base_computer - virtual bool CanDowngrade() const; virtual bool Downgrade(); @@ -58,4 +55,4 @@ class FtlDrive : public Component, public EnergyConsumer { virtual bool Upgrade(const std::string upgrade_name); }; -#endif // FTL_DRIVE_H +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_FTL_DRIVE_H diff --git a/engine/src/components/jump_drive.cpp b/engine/src/components/jump_drive.cpp index 1c73ce80ec..d5be93a240 100644 --- a/engine/src/components/jump_drive.cpp +++ b/engine/src/components/jump_drive.cpp @@ -25,17 +25,22 @@ #include "jump_drive.h" #include "unit_csv_factory.h" +#include "configuration/configuration.h" JumpDrive::JumpDrive() : Component(), EnergyConsumer(nullptr, 0, false), destination(-1), - delay(0.0) {} + delay(0.0) { + type = ComponentType::JumpDrive; +} JumpDrive::JumpDrive(EnergyContainer *source): Component(0.0, 0.0, true), EnergyConsumer(source, false), - delay(0.0) {} + delay(0.0) { + type = ComponentType::JumpDrive; +} int JumpDrive::Destination() const { @@ -76,7 +81,7 @@ void JumpDrive::Load(std::string upgrade_key, std::string unit_key) { // Consumer double energy = UnitCSVFactory::GetVariable(unit_key, "Outsystem_Jump_Cost", 0.0f); // Jump drive is unique - consumption and atom_consumption are identical - atom_consumption = consumption = energy; + atom_consumption = consumption = energy * configuration()->fuel.jump_drive_factor; // Jump Drive @@ -91,13 +96,9 @@ void JumpDrive::Load(std::string upgrade_key, std::string unit_key) { void JumpDrive::SaveToCSV(std::map& unit) const { unit["Jump_Drive_Present"] = std::to_string(Installed()); unit["Jump_Drive_Delay"] = std::to_string(delay); - unit["Outsystem_Jump_Cost"] = std::to_string(consumption); + unit["Outsystem_Jump_Cost"] = std::to_string(consumption / configuration()->fuel.jump_drive_factor); } -std::string JumpDrive::Describe() const { - return std::string(); -} - bool JumpDrive::CanDowngrade() const { return !Damaged(); } diff --git a/engine/src/components/jump_drive.h b/engine/src/components/jump_drive.h index 897f05e97b..8938ab5587 100644 --- a/engine/src/components/jump_drive.h +++ b/engine/src/components/jump_drive.h @@ -22,8 +22,8 @@ * along with Vega Strike. If not, see . */ -#ifndef JUMP_DRIVE_H -#define JUMP_DRIVE_H +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_JUMP_DRIVE_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_JUMP_DRIVE_H #include "component.h" #include "energy_consumer.h" @@ -49,12 +49,10 @@ class JumpDrive : public Component, public EnergyConsumer { bool Enabled() const; // Component Methods - virtual void Load(std::string upgrade_key, std::string unit_key); + virtual void Load(std::string upgrade_key, std::string unit_key = ""); virtual void SaveToCSV(std::map& unit) const; - virtual std::string Describe() const; // Describe component in base_computer - virtual bool CanDowngrade() const; virtual bool Downgrade(); @@ -64,4 +62,4 @@ class JumpDrive : public Component, public EnergyConsumer { virtual bool Upgrade(const std::string upgrade_name); }; -#endif // JUMP_DRIVE_H +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_JUMP_DRIVE_H diff --git a/engine/src/components/reactor.cpp b/engine/src/components/reactor.cpp index aee793a724..b4726865f5 100644 --- a/engine/src/components/reactor.cpp +++ b/engine/src/components/reactor.cpp @@ -28,6 +28,7 @@ #include "reactor.h" #include "unit_csv_factory.h" +#include "configuration/configuration.h" #include @@ -46,23 +47,24 @@ Reactor::Reactor(EnergyContainer *source, conversion_ratio(conversion_ratio), energy(energy), ftl_energy(ftl_energy) { + type = ComponentType::Reactor; } void Reactor::Load(std::string upgrade_key, std::string unit_key) { - capacity = UnitCSVFactory::GetVariable(unit_key, REACTOR_RECHARGE, 0.0f); + Component::Load(upgrade_key, unit_key); + capacity = Resource(UnitCSVFactory::GetVariable(unit_key, REACTOR_RECHARGE, std::string("0.0")), + configuration()->fuel.reactor_factor); + atom_capacity = capacity * simulation_atom_var; SetConsumption(capacity * conversion_ratio); } void Reactor::SaveToCSV(std::map& unit) const { // TODO: This won't record damage to recharge - unit[REACTOR_RECHARGE] = std::to_string(capacity.MaxValue()); + unit[REACTOR_RECHARGE] = std::to_string(capacity.MaxValue() / configuration()->fuel.reactor_factor); } -std::string Reactor::Describe() const { - return std::string(); -} bool Reactor::CanDowngrade() const { return !Damaged(); @@ -92,7 +94,8 @@ bool Reactor::Upgrade(const std::string upgrade_key) { Component::Upgrade(upgrade_key); - capacity.SetMaxValue(UnitCSVFactory::GetVariable(upgrade_key, REACTOR_RECHARGE, 0.0)); + capacity = Resource(UnitCSVFactory::GetVariable(upgrade_key, REACTOR_RECHARGE, std::string("0.0")), + configuration()->fuel.reactor_factor); atom_capacity = capacity * simulation_atom_var; SetConsumption(capacity * conversion_ratio); @@ -144,7 +147,7 @@ double Reactor::MaxCapacity() const { } void Reactor::SetCapacity(double capacity) { - this->capacity.SetMaxValue(capacity); + this->capacity.SetMaxValue(capacity * configuration()->fuel.reactor_factor); atom_capacity = capacity * simulation_atom_var; SetConsumption(capacity * conversion_ratio); } \ No newline at end of file diff --git a/engine/src/components/reactor.h b/engine/src/components/reactor.h index 34b7980664..315f725a6d 100644 --- a/engine/src/components/reactor.h +++ b/engine/src/components/reactor.h @@ -25,8 +25,8 @@ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- -#ifndef REACTOR_H -#define REACTOR_H +#ifndef VEGA_STRIKE_ENGINE_COMPONENTS_REACTOR_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_REACTOR_H #include "component.h" #include "energy_container.h" @@ -52,12 +52,10 @@ class Reactor: public Component, public EnergyConsumer double conversion_ratio = 0.0001); // < 0.01 or very short flight - virtual void Load(std::string upgrade_key, std::string unit_key); + virtual void Load(std::string upgrade_key, std::string unit_key = ""); virtual void SaveToCSV(std::map& unit) const; - virtual std::string Describe() const; // Describe component in base_computer - virtual bool CanDowngrade() const; virtual bool Downgrade(); @@ -79,4 +77,4 @@ class Reactor: public Component, public EnergyConsumer void SetCapacity(double capacity); }; -#endif // REACTOR_H +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_REACTOR_H diff --git a/engine/src/components/tests/balancing_tests.cpp b/engine/src/components/tests/balancing_tests.cpp index 49376079b4..f2322ecbe5 100644 --- a/engine/src/components/tests/balancing_tests.cpp +++ b/engine/src/components/tests/balancing_tests.cpp @@ -1,7 +1,32 @@ +/* + * balancing_tests.cpp + * + * Copyright (C) 2001-2023 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, + * and other Vega Strike contributors. + * + * https://github.com/vegastrike/Vega-Strike-Engine-Source + * + * This file is part of Vega Strike. + * + * Vega Strike 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 3 of the License, or + * (at your option) any later version. + * + * Vega Strike 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 Vega Strike. If not, see . + */ + #include #include "energy_container.h" #include "reactor.h" +#include "configuration/game_config.h" double simulation_atom_var = 0.1; @@ -56,8 +81,8 @@ struct EnergyManager { EnergyManager(EnergySetup setup, double simulation_atom_var): - fuel(EnergyType::Fuel), energy(EnergyType::Energy), - ftl_energy(EnergyType::FTL), + fuel(ComponentType::Fuel), energy(ComponentType::Capacitor), + ftl_energy(ComponentType::FtlCapacitor), reactor(&fuel, &energy, &ftl_energy) { fuel.SetCapacity(setup.fuel_capacity); energy.SetCapacity(setup.energy_capacity); diff --git a/engine/src/components/tests/energy_container_tests.cpp b/engine/src/components/tests/energy_container_tests.cpp index 2a9aa271ca..554203fa09 100644 --- a/engine/src/components/tests/energy_container_tests.cpp +++ b/engine/src/components/tests/energy_container_tests.cpp @@ -1,7 +1,35 @@ +/* + * energy_container_tests.cpp + * + * Copyright (C) 2001-2023 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, + * and other Vega Strike contributors. + * + * https://github.com/vegastrike/Vega-Strike-Engine-Source + * + * This file is part of Vega Strike. + * + * Vega Strike 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 3 of the License, or + * (at your option) any later version. + * + * Vega Strike 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 Vega Strike. If not, see . + */ + #include +#include +// #include +// #include #include "energy_container.h" #include "energy_consumer.h" +#include "unit_csv_factory.h" void printContainer(EnergyContainer& container) { std::cout << "Max Level: " << container.MaxLevel(); @@ -10,7 +38,7 @@ void printContainer(EnergyContainer& container) { } TEST(EnergyContainer, Sanity) { - EnergyContainer container = EnergyContainer(EnergyType::Energy); + EnergyContainer container = EnergyContainer(ComponentType::Capacitor); EXPECT_EQ(container.Level(), 0.0); container.SetCapacity(10.0, true); @@ -31,4 +59,48 @@ TEST(EnergyContainer, Sanity) { // Uncomment to see prints //EXPECT_TRUE(consumer.CanConsume()); -} \ No newline at end of file +} + +const std::string ship_name = "DummyShip"; +const std::string capacitor_name = "DummyCapacitor"; + +static const std::string upgrades_suffix_string = "__upgrades"; +static const std::string capacitor_string = "capacitor"; +static const std::string upgrade_string = "upgrade"; + +static const std::map capacitor_map = { + { "Name", capacitor_name}, + { "Mass", "5.0"}, + { "Primary_Capacitor", "10.0" }, +}; + + +TEST(EnergyContainer, Upgrade) { + UnitCSVFactory::LoadUnit(ship_name, capacitor_map); + UnitCSVFactory::LoadUnit(capacitor_string + upgrades_suffix_string, capacitor_map); + + EnergyContainer ship_capacitor = EnergyContainer(ComponentType::Capacitor); + + ship_capacitor.Load(capacitor_string + upgrades_suffix_string, ship_name); + + // Check Values + EXPECT_EQ(ship_capacitor.GetUpgradeName(), capacitor_name); + EXPECT_EQ(ship_capacitor.GetMass(), 5.0); + + EXPECT_EQ(ship_capacitor.Level(), 10.0); + + // Downgrade + ship_capacitor.Downgrade(); + + EXPECT_EQ(ship_capacitor.GetUpgradeName(), ""); + EXPECT_EQ(ship_capacitor.GetMass(), 0.0); + + EXPECT_EQ(ship_capacitor.Level(), 0.0); + + ship_capacitor.Upgrade(capacitor_string + upgrades_suffix_string); + + EXPECT_EQ(ship_capacitor.GetUpgradeName(), capacitor_name); + EXPECT_EQ(ship_capacitor.GetMass(), 5.0); + + EXPECT_EQ(ship_capacitor.Level(), 10.0); +} diff --git a/engine/src/configuration/configuration.cpp b/engine/src/configuration/configuration.cpp index 779c3eef2f..7e5f20c6d6 100644 --- a/engine/src/configuration/configuration.cpp +++ b/engine/src/configuration/configuration.cpp @@ -36,11 +36,14 @@ using vega_config::GetGameConfig; Configuration::Configuration() { //logging.verbose_debug = GetGameConfig().GetBool("data.verbose_debug", false); + std::ifstream ifs("config.json", std::ifstream::in); std::stringstream buffer; - buffer << ifs.rdbuf(); - const std::string json_text = buffer.str(); - graphics2_config = Graphics2Config(json_text); + if(!ifs.fail()) { + buffer << ifs.rdbuf(); + const std::string json_text = buffer.str(); + graphics2_config = Graphics2Config(json_text); + } } /* Override the default value(provided by constructor) with the value from the user specified configuration file, if any. @@ -126,7 +129,7 @@ void Configuration::OverrideDefaultsWithUserConfiguration() { // fuel.fmec_exit_velocity_inverse = // 1.0F / GetGameConfig().GetFloat("physics.FMEC_exit_vel", 1.0F / 0.0000002F); fuel.fuel_efficiency = - GetGameConfig().GetFloat("physics.LithiumRelativeEfficiency_Lithium", fuel.fuel_efficiency); + GetGameConfig().GetDouble("physics.LithiumRelativeEfficiency_Lithium", fuel.fuel_efficiency); fuel.fuel_equals_warp = GetGameConfig().GetBool("physics.fuel_equals_warp", fuel.fuel_equals_warp); fuel.normal_fuel_usage = GetGameConfig().GetFloat("physics.FuelUsage", fuel.normal_fuel_usage); fuel.reactor_uses_fuel = GetGameConfig().GetBool("physics.reactor_uses_fuel", fuel.reactor_uses_fuel); @@ -141,7 +144,25 @@ void Configuration::OverrideDefaultsWithUserConfiguration() { fuel.reactor_idle_efficiency = GetGameConfig().GetFloat("physics.reactor_idle_efficiency", fuel.reactor_idle_efficiency); fuel.min_reactor_efficiency = GetGameConfig().GetFloat("physics.min_reactor_efficiency", fuel.min_reactor_efficiency); fuel.ecm_energy_cost = GetGameConfig().GetFloat("physics.ecm_energy_cost", fuel.ecm_energy_cost); - fuel.fuel_conversion = GetGameConfig().GetFloat("physics.FuelConversion", fuel.fuel_conversion); + + fuel.fuel_factor = GetGameConfig().GetDouble("physics.FuelFactor", fuel.fuel_factor); + fuel.energy_factor = GetGameConfig().GetDouble("physics.EnergyFactor", fuel.energy_factor); + fuel.ftl_energy_factor = GetGameConfig().GetDouble("physics.FtlEnergyFactor", fuel.ftl_energy_factor); + + fuel.reactor_factor = GetGameConfig().GetDouble("physics.ReactorFactor", fuel.reactor_factor); + + fuel.ftl_drive_factor = GetGameConfig().GetDouble("physics.FtlDriveFactor", fuel.ftl_drive_factor); + fuel.jump_drive_factor = GetGameConfig().GetDouble("physics.JumpDriveFactor", fuel.jump_drive_factor); + + // Inelegant. Hard coded defaults here and in header + fuel.drive_source = GetSource(GetGameConfig().GetUInt8("physics.DriveSource", 1)); + fuel.reactor_source = GetSource(GetGameConfig().GetUInt8("physics.ReactorSource", 1)); + fuel.afterburner_source = GetSource(GetGameConfig().GetUInt8("physics.AfterburnerSource", 1)); + fuel.jump_drive_source = GetSource(GetGameConfig().GetUInt8("physics.JumpDriveSource", 3)); + fuel.cloak_source = GetSource(GetGameConfig().GetUInt8("physics.CloakSource", 2)); + + fuel.minimum_drive = + GetGameConfig().GetDouble("physics.MinimumDriveFuntionality", fuel.minimum_drive); // graphics substruct graphics_config.automatic_landing_zone_warning = GetGameConfig().GetString("graphics.automatic_landing_zone_warning", graphics_config.automatic_landing_zone_warning); diff --git a/engine/src/configuration/configuration.h b/engine/src/configuration/configuration.h index 4c9a93c48f..4b5cb67ebd 100644 --- a/engine/src/configuration/configuration.h +++ b/engine/src/configuration/configuration.h @@ -30,6 +30,8 @@ #include #include +#include "components/energy_consumer.h" + #include "graphics_config.h" namespace vega_config { @@ -171,7 +173,7 @@ struct Fuel { * There's some relevant context that's been removed from the original name of this variable "Lithium6constant" -- * a better name would ultimately be "FuelToEnergyConversionRelativeToLithium6DeuterideFusion" - * that fully encodes what the efficiency is relative to. */ - float fuel_efficiency; + double fuel_efficiency{1.0}; bool fuel_equals_warp; float normal_fuel_usage; bool reactor_uses_fuel; @@ -184,7 +186,24 @@ struct Fuel { float reactor_idle_efficiency{0.98F}; float min_reactor_efficiency{0.00001F}; float ecm_energy_cost{0.05F}; - float fuel_conversion{0.00144F}; + + double fuel_factor{60.0}; // Multiply fuel by this to get fuel by minutes + double energy_factor{1.0}; + double ftl_energy_factor{1.0}; + + double reactor_factor{1.0}; + + double ftl_drive_factor{0.1}; + double jump_drive_factor{1.0}; + + // 0 infinite, 1 fuel, 2 energy, 3 ftl_energy, 4 disabled + EnergyConsumerSource drive_source{EnergyConsumerSource::Fuel}; + EnergyConsumerSource reactor_source{EnergyConsumerSource::Fuel}; + EnergyConsumerSource afterburner_source{EnergyConsumerSource::Fuel}; + EnergyConsumerSource jump_drive_source{EnergyConsumerSource::FTLEnergy}; + EnergyConsumerSource cloak_source{EnergyConsumerSource::Energy}; + + double minimum_drive{0.15}; Fuel(); }; diff --git a/engine/src/resource/manifest.cpp b/engine/src/resource/manifest.cpp index 69458175ad..53e3c896d7 100644 --- a/engine/src/resource/manifest.cpp +++ b/engine/src/resource/manifest.cpp @@ -33,6 +33,13 @@ #include "json.h" #include "random_utils.h" +// TODO: get rid of this function when we move to C++20 + +static bool ends_with(const std::string& str, const std::string& suffix){ + return str.size() >= suffix.size() && str.compare(str.size()-suffix.size(), suffix.size(), suffix) == 0; +} + + // TODO: get rid of this helper function and others like it. static std::string getJSONValue(const json::jobject& object, const std::string &key, const std::string &default_value) { @@ -85,6 +92,11 @@ Manifest::Manifest(int dummy) { for(const std::string& json_filename : json_filenames) { std::ifstream ifs(json_filename, std::ifstream::in); + + if(ifs.fail()) { + continue; + } + std::stringstream buffer; buffer << ifs.rdbuf(); @@ -115,6 +127,27 @@ Manifest& Manifest::MPL() { return mpl; } +Cargo Manifest::GetCargoByName(const std::string name) { + const std::string upgrades_suffix = "__upgrades"; + std::string filename; + + // Check if we need to remove __upgrades suffix + if(ends_with(name, upgrades_suffix)) { + filename = name.substr(0, name.length() - upgrades_suffix.length()); + } else { + filename = name; + } + + + for(const Cargo& c : getItems()) { + if(c.name == filename) { + return c; + } + } + + return Cargo(); +} + Cargo Manifest::GetRandomCargo(int quantity) { // TODO: Need to figure a better solution here if(_items.empty()) { diff --git a/engine/src/resource/manifest.h b/engine/src/resource/manifest.h index 2ffc146316..a231de49ad 100644 --- a/engine/src/resource/manifest.h +++ b/engine/src/resource/manifest.h @@ -44,6 +44,7 @@ class Manifest { Manifest(std::string category); // Create a subset of the MPL for a category static Manifest& MPL(); // Get the master part list singleton + Cargo GetCargoByName(const std::string name); Cargo GetRandomCargo(int quantity = 0); Cargo GetRandomCargoFromCategory(std::string category, int quantity = 0); Manifest GetCategoryManifest(std::string category); diff --git a/engine/src/resource/product.h b/engine/src/resource/product.h index d63d5e86eb..d82bb54b58 100644 --- a/engine/src/resource/product.h +++ b/engine/src/resource/product.h @@ -32,6 +32,8 @@ class Product std::string name; // TODO: Can be a fraction for things such as fuel, water, etc. But not for now. Resource quantity; + + // TODO: move to int and not deal with cents. double price; // Price per one of quantity friend bool operator==(const Product &lhs, const std::string &rhs); diff --git a/engine/src/resource/tests/manifest_tests.cpp b/engine/src/resource/tests/manifest_tests.cpp index 9ac51fc9fe..5b50119fa2 100644 --- a/engine/src/resource/tests/manifest_tests.cpp +++ b/engine/src/resource/tests/manifest_tests.cpp @@ -24,7 +24,6 @@ #include -#include #include #include "manifest.h" diff --git a/engine/src/vs_math.h b/engine/src/vs_math.h index 83492b36cd..84080ef36a 100644 --- a/engine/src/vs_math.h +++ b/engine/src/vs_math.h @@ -50,6 +50,5 @@ #define FINITE(x) ( std::isfinite( x ) ) #define ISNAN(x) ( std:: isnan( x ) ) -#define VS_PI 3.1415926535897931 #endif //VEGA_STRIKE_ENGINE_VS_MATH_H From 47eefd04ae0756b4d85240e330f08625d8ded0d3 Mon Sep 17 00:00:00 2001 From: Roy Falk Date: Thu, 21 Nov 2024 22:23:43 +0200 Subject: [PATCH 2/2] Clean and fix ship load code (#908) - fix code in RecursiveParse - Add single value UpdateFacets - support for 'armor' for single value armor - support for 'shield_strength' for single value shield - add shield_facets - start merging moment into mass --- engine/src/cmd/unit_csv.cpp | 101 ++++++++++++++--------- engine/src/cmd/unit_csv_factory.h | 13 ++- engine/src/cmd/unit_optimize_factory.cpp | 31 +++---- engine/src/cmd/unit_optimize_factory.h | 2 +- engine/src/damage/damageable_layer.cpp | 6 ++ engine/src/damage/damageable_layer.h | 1 + 6 files changed, 94 insertions(+), 60 deletions(-) diff --git a/engine/src/cmd/unit_csv.cpp b/engine/src/cmd/unit_csv.cpp index 5437344031..467b258c5b 100644 --- a/engine/src/cmd/unit_csv.cpp +++ b/engine/src/cmd/unit_csv.cpp @@ -735,7 +735,7 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ pImage->CockpitCenter.j = UnitCSVFactory::GetVariable(unit_key, "CockpitY", 0.0f) * xml.unitscale; pImage->CockpitCenter.k = UnitCSVFactory::GetVariable(unit_key, "CockpitZ", 0.0f) * xml.unitscale; Mass = UnitCSVFactory::GetVariable(unit_key, "Mass", 1.0f); - Momentofinertia = UnitCSVFactory::GetVariable(unit_key, "Moment_Of_Inertia", 1.0f); + Momentofinertia = Mass; // Hull @@ -746,14 +746,28 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ specInterdiction = UnitCSVFactory::GetVariable(unit_key, "Spec_Interdiction", 0.0f); // Init armor - std::string armor_keys[] = {"Armor_Front_Top_Left", "Armor_Front_Top_Right", + // We support 2 options: + // 1. armor = x. Could be 0, 40, etc. This populaes the 8 facets below + // 2. armor = "". Use the old method of reading all 8 facets. + const std::string armor_single_value_string = UnitCSVFactory::GetVariable(unit_key, "armor", std::string()); + float armor_values[8]; + + if(armor_single_value_string != "") { + int armor_single_value = std::stoi(armor_single_value_string, 0); + + for (int i = 0; i < 8; i++) { + armor_values[i] = armor_single_value; + } + } else { + std::string armor_keys[] = {"Armor_Front_Top_Left", "Armor_Front_Top_Right", "Armor_Front_Bottom_Left", "Armor_Front_Bottom_Right", "Armor_Back_Top_Left", "Armor_Back_Top_Right", "Armor_Back_Bottom_Left", "Armor_Back_Bottom_Right"}; - float armor_values[8]; - for (int i = 0; i < 8; i++) { - float tmp_armor_value = UnitCSVFactory::GetVariable(unit_key, armor_keys[i], 0.0f); - armor_values[i] = tmp_armor_value; + + for (int i = 0; i < 8; i++) { + float tmp_armor_value = UnitCSVFactory::GetVariable(unit_key, armor_keys[i], 0.0f); + armor_values[i] = tmp_armor_value; + } } armor->UpdateFacets(8, armor_values); @@ -773,44 +787,58 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ //float efficiency = UnitCSVFactory::GetVariable(unit_key, "Shield_Efficiency", 1.0f ); // Get shield count - - int shield_count = 0; - float shield_values[4]; std::string shield_string_values[4]; + std::vector shield_sections; + + const std::string shield_strength_string = UnitCSVFactory::GetVariable(unit_key, "shield_strength", std::string()); + const std::string shield_facets_string = UnitCSVFactory::GetVariable(unit_key, "shield_facets", std::string()); + + if(shield_strength_string != "" && shield_facets_string != "") { + int shield_strength = std::stoi(shield_strength_string); + int shield_facets = std::stoi(shield_facets_string); + shield->number_of_facets = shield_facets; + shield->UpdateFacets(shield_strength); + } else { + int shield_count = 0; + float shield_values[4]; + - // TODO: this mapping should really go away - // I love macros, NOT. - shield_string_values[0] = UnitCSVFactory::GetVariable(unit_key, "Shield_Front_Top_Right", std::string()); - shield_string_values[1] = UnitCSVFactory::GetVariable(unit_key, "Shield_Back_Top_Left", std::string()); - shield_string_values[2] = UnitCSVFactory::GetVariable(unit_key, "Shield_Front_Bottom_Right", std::string()); - shield_string_values[3] = UnitCSVFactory::GetVariable(unit_key, "Shield_Front_Bottom_Left", std::string()); + // TODO: this mapping should really go away + // I love macros, NOT. + shield_string_values[0] = UnitCSVFactory::GetVariable(unit_key, "Shield_Front_Top_Right", std::string()); + shield_string_values[1] = UnitCSVFactory::GetVariable(unit_key, "Shield_Back_Top_Left", std::string()); + shield_string_values[2] = UnitCSVFactory::GetVariable(unit_key, "Shield_Front_Bottom_Right", std::string()); + shield_string_values[3] = UnitCSVFactory::GetVariable(unit_key, "Shield_Front_Bottom_Left", std::string()); - for (int i = 0; i < 4; i++) { - shield_values[i] = 0.0f; + for (int i = 0; i < 4; i++) { + shield_values[i] = 0.0f; - if (shield_string_values[i].empty()) { - continue; + if (shield_string_values[i].empty()) { + continue; + } + + shield_values[i] = ::stof(shield_string_values[i]); + // Should add up to the shield type - quad or dual + shield_count++; } - shield_values[i] = ::stof(shield_string_values[i]); - // Should add up to the shield type - quad or dual - shield_count++; + /* + We are making the following assumptions: + 1. The CSV is correct + 2. Dual shields are 0 front and 1 rear + 3. Quad shields are front (0), rear(1), right(2) and left(3) + 4. There is no support for 8 facet shields in the game. + This has more to do with the cockpit code than anything else + 5. We map the above index to our own + */ + + if (shield_count == 4 || shield_count == 2) { + shield->number_of_facets = shield_count; + shield->UpdateFacets(shield_count, shield_values); + } } - /* - We are making the following assumptions: - 1. The CSV is correct - 2. Dual shields are 0 front and 1 rear - 3. Quad shields are front (0), rear(1), right(2) and left(3) - 4. There is no support for 8 facet shields in the game. - This has more to do with the cockpit code than anything else - 5. We map the above index to our own - */ - - if (shield_count == 4 || shield_count == 2) { - shield->number_of_facets = shield_count; - shield->UpdateFacets(shield_count, shield_values); - } + // End shield section @@ -1252,7 +1280,6 @@ const std::map Unit::UnitToMap() { unit["Cargo"] = carg; } unit["Mass"] = tos(Mass); - unit["Moment_Of_Inertia"] = tos(Momentofinertia); unit["Fuel_Capacity"] = tos(fuel.Level()); unit["Hull"] = tos(GetHullLayer().facets[0].health); unit["Spec_Interdiction"] = tos(specInterdiction); diff --git a/engine/src/cmd/unit_csv_factory.h b/engine/src/cmd/unit_csv_factory.h index 6c9876e0c3..5dcc613cde 100644 --- a/engine/src/cmd/unit_csv_factory.h +++ b/engine/src/cmd/unit_csv_factory.h @@ -30,9 +30,11 @@ #include #include -const std::string keys[] = {"Key", "Directory", "Name", "STATUS", "Object_Type", +const std::string keys[] = {"Key", "Directory", "Name", "Object_Type", "Combat_Role", "Textual_Description", "Hud_image", "Unit_Scale", "Cockpit", - "CockpitX", "CockpitY", "CockpitZ", "Mesh", "Shield_Mesh", "Rapid_Mesh", "BSP_Mesh", + "CockpitX", "CockpitY", "CockpitZ", "Mesh", "Shield_Mesh", + "Rapid_Mesh", // TODO: find out if used in WC + "BSP_Mesh", "Use_BSP", "Use_Rapid", "NoDamageParticles", "Mass", "Moment_Of_Inertia", "Fuel_Capacity", "Hull", "Armor_Front_Top_Right", "Armor_Front_Top_Left", "Armor_Front_Bottom_Right", "Armor_Front_Bottom_Left", "Armor_Back_Top_Right", @@ -61,7 +63,12 @@ const std::string keys[] = {"Key", "Directory", "Name", "STATUS", "Object_Type", "Upgrade_Type", "Facets", // These values are not in units.csv! There are probably more but I stopped mapping. // TODO: map all missing values using the commented out code below! - "FaceCamera", "Unit_Role", "Attack_Preference", "Hidden_Hold_Volume", "Equipment_Space"}; + "FaceCamera", "Unit_Role", "Attack_Preference", "Hidden_Hold_Volume", "Equipment_Space", + + // New stuff + "armor", "shield_strength", "shield_facets" + + }; class UnitCSVFactory { diff --git a/engine/src/cmd/unit_optimize_factory.cpp b/engine/src/cmd/unit_optimize_factory.cpp index d39a13baeb..17dc8447d5 100644 --- a/engine/src/cmd/unit_optimize_factory.cpp +++ b/engine/src/cmd/unit_optimize_factory.cpp @@ -28,7 +28,7 @@ #include "json.h" void UnitOptimizeFactory::RecursiveParse(std::map unit_attributes, - const std::string& json_text, bool is_root) { + const std::string& json_text) { json::jobject json = json::jobject::parse(json_text); // Parse the data section @@ -37,35 +37,28 @@ void UnitOptimizeFactory::RecursiveParse(std::map unit for (const std::string &key : keys) { // For some reason, parser adds quotes + if(data_json.has_key(key)) { const std::string attribute = data_json.get(key); const std::string stripped_attribute = attribute.substr(1, attribute.size() - 2); unit_attributes[key] = stripped_attribute; - } else { - // If we do this for non-root, we'll overwrite existing attributes - if(is_root) { - unit_attributes[key] = ""; - } - } + } + } + + if(unit_attributes.count("Key")) { + std::string unit_key = unit_attributes["Key"]; + UnitCSVFactory::units[unit_key] = unit_attributes; } + // Parse the units array if(json.has_key("units")) { std::vector units = json::parsing::parse_array(json.get("units").c_str()); // Iterate over root for (const std::string &unit_text : units) { - RecursiveParse(unit_attributes, unit_text, false); - } - } else { - // Add moment of intertia - if(unit_attributes.count("Mass")) { - unit_attributes["Moment_Of_Inertia"] = unit_attributes["Mass"]; + RecursiveParse(unit_attributes, unit_text); } - - std::string unit_key = unit_attributes["Key"]; - - UnitCSVFactory::units[unit_key] = unit_attributes; - } + } } @@ -79,5 +72,5 @@ void UnitOptimizeFactory::ParseJSON(VSFileSystem::VSFile &file) { // Add root unit_attributes["root"] = file.GetRoot(); - RecursiveParse(unit_attributes, json_text, true); + RecursiveParse(unit_attributes, json_text); } diff --git a/engine/src/cmd/unit_optimize_factory.h b/engine/src/cmd/unit_optimize_factory.h index 24e9a9004a..7ae09c773a 100644 --- a/engine/src/cmd/unit_optimize_factory.h +++ b/engine/src/cmd/unit_optimize_factory.h @@ -34,7 +34,7 @@ class UnitOptimizeFactory public: static void ParseJSON(VSFileSystem::VSFile &file); static void RecursiveParse(std::map unit_attributes, - const std::string& json_text, bool is_root); + const std::string& json_text); }; #endif //VEGA_STRIKE_ENGINE_CMD_UNIT_OPTIMIZE_FACTORY_H diff --git a/engine/src/damage/damageable_layer.cpp b/engine/src/damage/damageable_layer.cpp index dc3de05d3e..c458e72ccf 100644 --- a/engine/src/damage/damageable_layer.cpp +++ b/engine/src/damage/damageable_layer.cpp @@ -377,6 +377,12 @@ float DamageableLayer::GetRegeneration() { return facets[0].regeneration; } +void DamageableLayer::UpdateFacets(const float new_facet_strength) { + for (unsigned int i = 0; i < number_of_facets; i++) { + facets[i].Update(new_facet_strength); + } +} + void DamageableLayer::UpdateFacets(const unsigned int new_size, const float new_facets[4]) { assert(new_size == number_of_facets); diff --git a/engine/src/damage/damageable_layer.h b/engine/src/damage/damageable_layer.h index 2a158a2175..2acdbf6688 100644 --- a/engine/src/damage/damageable_layer.h +++ b/engine/src/damage/damageable_layer.h @@ -92,6 +92,7 @@ struct DamageableLayer { void Regenerate(float recharge_rate); void RegenerateOrDischarge(float recharge, bool velocity_discharge, float discharge_rate); float GetRegeneration(); + void UpdateFacets(const float new_facet_strength); void UpdateFacets(const unsigned int size, const float new_facets[4]); void UpdateRegeneration(const float &new_regeneration_value); };