From 3615f5d766023c7e42575ee9bfb292ef436e11d0 Mon Sep 17 00:00:00 2001 From: Roy Falk Date: Sat, 5 Oct 2024 11:47:00 +0300 Subject: [PATCH] Add support for ftl and jump drives (#875) * Add support for ftl and jump drives Remove warp bleed factor. Report actual cost in computer. Keep removing (unused) functionality from Energetic class. Fix typo in Benjamen's name --- engine/CMakeLists.txt | 2 + engine/src/cmd/ai/aggressive.cpp | 14 +- engine/src/cmd/ai/docking.cpp | 16 +- engine/src/cmd/ai/fire.cpp | 2 +- engine/src/cmd/ai/flykeyboard.cpp | 2 +- engine/src/cmd/ai/ikarus.cpp | 3 +- engine/src/cmd/ai/warpto.cpp | 2 +- engine/src/cmd/basecomputer.cpp | 26 +- engine/src/cmd/energetic.cpp | 79 +----- engine/src/cmd/energetic.h | 16 -- engine/src/cmd/jump_capable.cpp | 18 +- engine/src/cmd/jump_capable.h | 2 - engine/src/cmd/ship.cpp | 2 +- engine/src/cmd/ship.h | 2 +- engine/src/cmd/unit_csv.cpp | 26 +- engine/src/cmd/unit_functions_generic.cpp | 42 ++-- engine/src/cmd/unit_generic.cpp | 226 +++++++----------- engine/src/cmd/unit_generic.h | 10 +- engine/src/cmd/unit_util_generic.cpp | 10 + engine/src/cmd/upgradeable_unit.cpp | 25 +- engine/src/cmd/upgradeable_unit.h | 3 +- engine/src/components/cloak.cpp | 2 +- engine/src/components/cloak.h | 2 +- engine/src/components/component.cpp | 40 +++- engine/src/components/component.h | 22 +- engine/src/components/energy_consumer.cpp | 9 + engine/src/components/energy_consumer.h | 1 + engine/src/components/ftl_drive.cpp | 80 +++++++ engine/src/components/ftl_drive.h | 61 +++++ engine/src/components/jump_drive.cpp | 129 ++++++++++ engine/src/components/jump_drive.h | 67 ++++++ .../src/components/tests/balancing_tests.cpp | 36 ++- .../tests/energy_container_tests.cpp | 4 + engine/src/damage/damageable_layer.cpp | 30 +-- engine/src/damage/damageable_layer.h | 1 + engine/src/gfx/cockpit.cpp | 6 +- engine/src/python/unit_wrapper_class.h | 11 +- engine/src/resource/manifest.cpp | 2 +- engine/src/resource/manifest.h | 2 +- engine/src/resource/random_utils.cpp | 2 +- engine/src/resource/random_utils.h | 2 +- engine/src/resource/resource.cpp | 18 +- engine/src/resource/resource.h | 2 +- engine/src/resource/tests/buy_sell.cpp | 2 +- engine/src/resource/tests/manifest_tests.cpp | 2 +- engine/src/resource/tests/random_tests.cpp | 2 +- engine/src/resource/tests/resource_test.cpp | 2 +- engine/src/star_system.cpp | 9 +- engine/src/star_system_jump.cpp | 4 +- 49 files changed, 686 insertions(+), 392 deletions(-) create mode 100644 engine/src/components/ftl_drive.cpp create mode 100644 engine/src/components/ftl_drive.h create mode 100644 engine/src/components/jump_drive.cpp create mode 100644 engine/src/components/jump_drive.h diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index f81f8b0c91..093eff7502 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -725,6 +725,8 @@ SET(LIBCOMPONENT src/components/reactor.cpp src/components/cloak.cpp + src/components/ftl_drive.cpp + src/components/jump_drive.cpp ) SET(LIBGUI_SOURCES diff --git a/engine/src/cmd/ai/aggressive.cpp b/engine/src/cmd/ai/aggressive.cpp index 37130116dd..0a71ff1d5d 100644 --- a/engine/src/cmd/ai/aggressive.cpp +++ b/engine/src/cmd/ai/aggressive.cpp @@ -1293,7 +1293,7 @@ static Unit *ChooseNavPoint(Unit *parent, Unit **otherdest, float *lurk_on_arriv int whichlist = 1; //friendly std::string fgname = UnitUtil::getFlightgroupName(parent); - bool insys = (parent->GetJumpStatus().drive == -2) || fgname.find(insysString) != std::string::npos; + bool insys = (!parent->jump_drive.Installed()) || fgname.find(insysString) != std::string::npos; std::string::size_type whereconvoy = fgname.find(arrowString); bool convoy = (whereconvoy != std::string::npos); size_t total_size = stats->navs[0].size() + stats->navs[whichlist].size(); //friendly and neutral @@ -1641,9 +1641,9 @@ void AggressiveAI::Execute() { bool isjumpable = target ? (!target->GetDestinations().empty()) : false; if (!ProcessCurrentFgDirective(fg)) { if (isjumpable) { - if (parent->GetJumpStatus().drive < 0) { + if (!parent->jump_drive.IsDestinationSet()) { parent->ActivateJumpDrive(0); - if (parent->GetJumpStatus().drive == -2) { + if (!parent->jump_drive.Installed()) { static bool AIjumpCheat = XMLSupport::parse_bool(vs_config->getVariable("AI", "always_have_jumpdrive_cheat", @@ -1654,15 +1654,15 @@ void AggressiveAI::Execute() { VS_LOG(warning, "FIXME: warning ship not equipped to jump"); i = 1; } - parent->jump.drive = -1; + parent->jump_drive.UnsetDestination(); } else { parent->Target(NULL); } - } else if (parent->GetJumpStatus().drive < 0) { + } else if (!parent->jump_drive.IsDestinationSet()) { static bool AIjumpCheat = XMLSupport::parse_bool(vs_config->getVariable("AI", "jump_cheat", "true")); if (AIjumpCheat) { - parent->jump.drive = 0; + parent->jump_drive.SetDestination(0); } } } @@ -1734,7 +1734,7 @@ void AggressiveAI::Execute() { isjumpable = target ? (!target->GetDestinations().empty()) : false; if (!isjumpable) { - if (parent->GetJumpStatus().drive >= 0) { + if (parent->jump_drive.IsDestinationSet()) { parent->ActivateJumpDrive(-1); } } diff --git a/engine/src/cmd/ai/docking.cpp b/engine/src/cmd/ai/docking.cpp index aa82b19a17..c1face31e4 100644 --- a/engine/src/cmd/ai/docking.cpp +++ b/engine/src/cmd/ai/docking.cpp @@ -182,6 +182,7 @@ QVector DockingOps::Movement(Unit *utdw) { return loc; } + bool DockingOps::DockToTarget(Unit *utdw) { if (utdw->DockingPortLocations()[port].IsOccupied()) { if (keeptrying) { @@ -197,19 +198,13 @@ bool DockingOps::DockToTarget(Unit *utdw) { float rad = utdw->DockingPortLocations()[port].GetRadius() + parent->rSize(); float diss = (parent->Position() - loc).MagnitudeSquared() - .1; bool isplanet = utdw->isUnit() == Vega_UnitType::planet; - static float MinimumCapacityToRefuelOnLand = - XMLSupport::parse_float(vs_config->getVariable("physics", - "MinimumWarpCapToRefuelDockeesAutomatically", - "0")); + if (diss <= (isplanet ? rad * rad : parent->rSize() * parent->rSize())) { DockedScript(parent, utdw); if (physicallyDock) { return parent->Dock(utdw); } else { - float maxWillingToRefill = utdw->warpCapData(); - if (maxWillingToRefill >= MinimumCapacityToRefuelOnLand) { - parent->refillWarpEnergy(); - } //BUCO! This needs its own units.csv column to see how much we refill! + rechargeShip(parent, 0); return true; } } else if (diss <= 1.2 * rad * rad) { @@ -219,10 +214,7 @@ bool DockingOps::DockToTarget(Unit *utdw) { if (physicallyDock) { return parent->Dock(utdw); } else { - float maxWillingToRefill = utdw->warpCapData(); - if (maxWillingToRefill >= MinimumCapacityToRefuelOnLand) { - parent->refillWarpEnergy(); - } //BUCO! This needs its own units.csv column to see how much we refill! + rechargeShip(parent, 0); return true; } } diff --git a/engine/src/cmd/ai/fire.cpp b/engine/src/cmd/ai/fire.cpp index 3c6d1b8769..9adbd18edf 100644 --- a/engine/src/cmd/ai/fire.cpp +++ b/engine/src/cmd/ai/fire.cpp @@ -773,7 +773,7 @@ bool FireAt::isJumpablePlanet(Unit *targ) { bool istargetjumpableplanet = targ->isUnit() == Vega_UnitType::planet; if (istargetjumpableplanet) { istargetjumpableplanet = - (!((Planet *) targ)->GetDestinations().empty()) && (parent->GetJumpStatus().drive >= 0); + (!((Planet *) targ)->GetDestinations().empty()) && (parent->jump_drive.IsDestinationSet()); } return istargetjumpableplanet; } diff --git a/engine/src/cmd/ai/flykeyboard.cpp b/engine/src/cmd/ai/flykeyboard.cpp index 8846f9ad83..73bcb4459d 100644 --- a/engine/src/cmd/ai/flykeyboard.cpp +++ b/engine/src/cmd/ai/flykeyboard.cpp @@ -453,7 +453,7 @@ void FlyByKeyboard::Execute(bool resetangvelocity) { if ((counter - last_jumped) > static_cast(jump_key_delay / SIMULATION_ATOM) || last_jumped == 0) { last_jumped = counter; parent->ActivateJumpDrive(); - if (parent->GetJumpStatus().drive >= 0) { + if (parent->jump_drive.IsDestinationSet()) { static soundContainer foobar; if (foobar.sound == -2) { static string str = vs_config->getVariable("cockpitaudio", "jump_engaged", "jump"); diff --git a/engine/src/cmd/ai/ikarus.cpp b/engine/src/cmd/ai/ikarus.cpp index 1c4fa38307..c0afd54e74 100644 --- a/engine/src/cmd/ai/ikarus.cpp +++ b/engine/src/cmd/ai/ikarus.cpp @@ -113,7 +113,8 @@ void Ikarus::Execute() { DecideTarget(); if (!ProcessCurrentFgDirective(fg)) { Unit *target = parent->Target(); - bool isjumpable = target ? ((!target->GetDestinations().empty()) && parent->GetJumpStatus().drive >= 0) : false; + bool isjumpable = target ? ((!target->GetDestinations().empty()) && + parent->jump_drive.IsDestinationSet()) : false; if (isjumpable) { AfterburnTurnTowards(this, parent); } else { diff --git a/engine/src/cmd/ai/warpto.cpp b/engine/src/cmd/ai/warpto.cpp index 5f3232ed24..4ba894886f 100644 --- a/engine/src/cmd/ai/warpto.cpp +++ b/engine/src/cmd/ai/warpto.cpp @@ -96,7 +96,7 @@ static void ActuallyWarpTo(Unit *parent, const QVector &tarpos, Vector tarvel, U XMLSupport::parse_float(vs_config->getVariable("AI", "min_energy_to_enter_warp", ".33")); static float min_warpfield_to_enter_warp = XMLSupport::parse_float(vs_config->getVariable("AI", "min_warp_to_try", "1.5")); - if ((parent->warpEnergyData() > min_energy_to_enter_warp) + if ((parent->ftl_energy.Percent() > min_energy_to_enter_warp) && (parent->GetMaxWarpFieldStrength(1) > min_warpfield_to_enter_warp)) { if (parent->graphicOptions.InWarp == 0) { parent->graphicOptions.InWarp = 1; //don't want the AI thrashing diff --git a/engine/src/cmd/basecomputer.cpp b/engine/src/cmd/basecomputer.cpp index d217ba348f..f739ba3cc9 100644 --- a/engine/src/cmd/basecomputer.cpp +++ b/engine/src/cmd/basecomputer.cpp @@ -4634,7 +4634,6 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C static Unit *blankUnit = new Unit("upgrading_dummy_unit", 1, FactionUtil::GetFactionIndex("upgrades")); static float warpenratio = XMLSupport::parse_float(vs_config->getVariable("physics", "warp_energy_multiplier", "0.12")); - static float warpbleed = XMLSupport::parse_float(vs_config->getVariable("physics", "warpbleed", "20")); static float shield_maintenance_cost = XMLSupport::parse_float(vs_config->getVariable("physics", "shield_maintenance_charge", ".25")); static bool shields_require_power = @@ -5177,8 +5176,9 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C break; } } - const Unit::UnitJump &uj = playerUnit->GetJumpStatus(); - const Unit::UnitJump &buj = blankUnit->GetJumpStatus(); + const JumpDrive &uj = playerUnit->jump_drive; + const FtlDrive &ftl = playerUnit->ftl_drive; + const JumpDrive &buj = blankUnit->jump_drive; if (!mode) { float maxshield = playerUnit->totalShieldEnergyCapacitance(); if (shields_require_power) { @@ -5197,23 +5197,23 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C text += "#n##n##c0:1:.5#" + prefix + "[SPEC SUBSYSTEM]#n##-c"; PRETTY_ADDU(statcolor + "Active SPEC Energy Requirements: #-c", - uj.insysenergy * RSconverter * Wconv / warpbleed, + ftl.GetConsumption() * RSconverter * Wconv, 0, "MJ/s"); text += "#n##n##c0:1:.5#" + prefix + "[JUMP SUBSYSTEM]#n##-c"; - if (uj.drive == -2) { + if (!uj.Installed()) { text += "#n##c1:.3:.3#No outsystem jump drive present#-c"; //fixed?? } else { PRETTY_ADDU(statcolor + "Energy cost for jumpnode travel: #-c", - uj.energy * RSconverter * Wconv, + uj.GetConsumption() * RSconverter * Wconv, 0, "MJ"); - if (uj.delay) - PRETTY_ADDU(statcolor + "Delay: #-c", uj.delay, 0, "seconds"); - if (uj.damage > 0) - PRETTY_ADDU(statcolor + "Damage to outsystem jump drive: #-c", uj.damage * VSDM, 0, "MJ"); - if (playerUnit->warpCapData() < uj.energy) { + if (uj.Delay() > 0) + PRETTY_ADDU(statcolor + "Delay: #-c", uj.Delay(), 0, "seconds"); + if (uj.Damaged()) + PRETTY_ADDU(statcolor + "Damage to outsystem jump drive: #-c", 1-uj.Percent(), 0, "%"); + if (playerUnit->ftl_energy.MaxLevel() < uj.GetAtomConsumption()) { text += "#n##c1:.3:.3#" + prefix + "WARNING: Warp capacitor banks under capacity for jump: upgrade warp capacitance#-c"; @@ -5232,7 +5232,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C if (MODIFIES(replacement_mode, playerUnit, blankUnit, getWarpEnergy())) PRETTY_ADDU(statcolor + "Installs warp capacitor bank with storage capacity: #-c", playerUnit->getWarpEnergy() * RSconverter * Wconv, 0, "MJ"); - if (buj.drive != uj.drive) { + 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"; } @@ -5627,7 +5627,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C + "WARNING: Capacitor banks are overdrawn: downgrade shield, upgrade reactor or purchase reactor capacitance!#-c"; } - if (uj.drive != -2 && playerUnit->warpCapData() < uj.energy) { + if (uj.Installed() && playerUnit->jump_drive.GetAtomConsumption() > playerUnit->ftl_energy.MaxLevel()) { text += "#n##c1:.3:.3#" + prefix + "WARNING: Warp capacitor banks under capacity for jump: upgrade warp capacitance#-c"; diff --git a/engine/src/cmd/energetic.cpp b/engine/src/cmd/energetic.cpp index 4744d5f1cd..a57d766ade 100644 --- a/engine/src/cmd/energetic.cpp +++ b/engine/src/cmd/energetic.cpp @@ -42,30 +42,10 @@ Energetic::Energetic() : constrained_charge_to_shields(0.0f), sufficient_energy_to_recharge_shields(true), - //fuel(0), afterburnenergy(0), afterburntype(0) { - jump.warpDriveRating = 0; - jump.energy = 100; - jump.insysenergy = configuration()->warp_config.insystem_jump_cost * jump.energy; - jump.drive = -2; - jump.delay = 5; - jump.damage = 0; } -void Energetic::decreaseWarpEnergy(bool insys, double time) { - Unit *unit = vega_dynamic_cast_ptr(this); - - if (configuration()->fuel.fuel_equals_warp) { - unit->ftl_energy.SetLevel(unit->fuel.Level()); - } - - unit->ftl_energy.Deplete(true, (insys ? jump.insysenergy / configuration()->warp_config.bleed_factor : jump.energy) * time); - - if (configuration()->fuel.fuel_equals_warp) { - unit->fuel.SetLevel(unit->ftl_energy.Level()); - } -} void Energetic::DecreaseWarpEnergyInWarp() { Unit *unit = vega_dynamic_cast_ptr(this); @@ -76,11 +56,8 @@ void Energetic::DecreaseWarpEnergyInWarp() { return; } - //FIXME FIXME FIXME - // Roy Falk - fix what? - float bleed = jump.insysenergy / configuration()->warp_config.bleed_factor * simulation_atom_var; - if (unit->ftl_energy.Level() > bleed) { - unit->ftl_energy.Deplete(true, bleed); + if(unit->ftl_drive.CanConsume()) { + unit->ftl_drive.Consume(); } else { unit->graphicOptions.InWarp = 0; unit->graphicOptions.WarpRamping = 1; @@ -139,18 +116,6 @@ float Energetic::getWarpEnergy() const { return unit->ftl_energy.Level(); } -void Energetic::increaseWarpEnergy(bool insys, double time) { - Unit *unit = vega_dynamic_cast_ptr(this); - if (configuration()->fuel.fuel_equals_warp) { - unit->ftl_energy.SetLevel(unit->fuel.Level()); - } - - unit->ftl_energy.Charge((insys ? jump.insysenergy : jump.energy) * time); - - if (configuration()->fuel.fuel_equals_warp) { - unit->fuel.SetLevel(unit->ftl_energy.Level()); - } -} float Energetic::maxEnergyData() const { const Unit *unit = vega_dynamic_cast_ptr(this); @@ -164,28 +129,6 @@ void Energetic::rechargeEnergy() { } } -bool Energetic::refillWarpEnergy() { - Unit *unit = vega_dynamic_cast_ptr(this); - if (configuration()->fuel.fuel_equals_warp) { - unit->ftl_energy.SetLevel(unit->fuel.Level()); - } - - // TODO: move this elsewhere. It should be evaluated every time. - if (unit->ftl_energy.MaxLevel() < this->jump.energy) { - unit->ftl_energy.SetCapacity(this->jump.energy, false); - } - - if(unit->ftl_energy.Level() < unit->ftl_energy.MaxLevel()) { - unit->ftl_energy.Refill(); - if (configuration()->fuel.fuel_equals_warp) { - unit->fuel.SetLevel(unit->ftl_energy.Level()); - } - return true; - } - - return false; -} - void Energetic::setAfterburnerEnergy(float aft) { afterburnenergy = aft; } @@ -201,18 +144,6 @@ float Energetic::warpCapData() const { return unit->ftl_energy.MaxLevel(); } -float Energetic::warpEnergyData() const { - const Unit *unit = vega_dynamic_cast_ptr(this); - if (unit->ftl_energy.MaxLevel() > 0) { - return unit->ftl_energy.Percent(); - } - - if (jump.energy > 0) { - return ((float) unit->ftl_energy.Level()) / ((float) jump.energy); - } - return 0.0f; -} - // Basically max or current shield x 0.2 float Energetic::totalShieldEnergyCapacitance() const { const Unit *unit = vega_dynamic_cast_ptr(this); @@ -230,6 +161,8 @@ float Energetic::totalShieldEnergyCapacitance() const { // or better yet, write plugable consumption models. //GAHHH reactor in units of 100MJ, shields in units of VSD=5.4MJ to make 1MJ of shield use 1/shieldenergycap MJ void Energetic::ExpendEnergy(const bool player_ship) { + Unit *unit = vega_dynamic_cast_ptr(this); + // TODO: if we run out of fuel or energy, we die from lack of air MaintainShields(); @@ -237,9 +170,7 @@ void Energetic::ExpendEnergy(const bool player_ship) { MaintainECM(); DecreaseWarpEnergyInWarp(); - RechargeWarpCapacitors(player_ship); - - ExpendFuel(); + unit->reactor.Generate(); } void Energetic::ExpendEnergy(float usage) { diff --git a/engine/src/cmd/energetic.h b/engine/src/cmd/energetic.h index d767d41f70..0ff4b43655 100644 --- a/engine/src/cmd/energetic.h +++ b/engine/src/cmd/energetic.h @@ -33,7 +33,6 @@ class Energetic { Energetic(); virtual ~Energetic() = default; - void decreaseWarpEnergy(bool insys, double time); void DecreaseWarpEnergyInWarp(); @@ -47,7 +46,6 @@ class Energetic { void ExpendFuel(); float getWarpEnergy() const; - void increaseWarpEnergy(bool insys, double time); float maxEnergyData() const; @@ -56,7 +54,6 @@ class Energetic { void rechargeEnergy(); void RechargeWarpCapacitors(const bool player_ship); - bool refillWarpEnergy(); void setAfterburnerEnergy(float aft); void setEnergyRecharge(float enrech); @@ -66,22 +63,9 @@ class Energetic { static float VSDPercent(); float warpCapData() const; - float warpEnergyData() const; float WarpEnergyMultiplier(const bool player_ship); - // TODO: move to StarFaring class when available - struct UnitJump { - float warpDriveRating; - float energy; //short fix - float insysenergy; //short fix - signed char drive; // disabled - unsigned char delay; - unsigned char damage; - //negative means fuel - } - jump{}; - float constrained_charge_to_shields; bool sufficient_energy_to_recharge_shields; diff --git a/engine/src/cmd/jump_capable.cpp b/engine/src/cmd/jump_capable.cpp index f0b815a33d..1bd793f5a9 100644 --- a/engine/src/cmd/jump_capable.cpp +++ b/engine/src/cmd/jump_capable.cpp @@ -104,8 +104,8 @@ JumpCapable::JumpCapable() : activeStarSystem(nullptr) { void JumpCapable::ActivateJumpDrive(int destination) { Unit *unit = static_cast(this); - if (((unit->docked & (unit->DOCKED | unit->DOCKED_INSIDE)) == 0) && unit->jump.drive != -2) { - unit->jump.drive = destination; + if (((unit->docked & (unit->DOCKED | unit->DOCKED_INSIDE)) == 0) && unit->jump_drive.Installed()) { + unit->jump_drive.SetDestination(destination); } } @@ -139,7 +139,7 @@ bool JumpCapable::AutoPilotToErrorMessage(const Unit *target, return AutoPilotToErrorMessage(targ, ignore_energy_requirements, failuremessage, recursive_level); } } - if (unit->ftl_energy.Level() < unit->jump.insysenergy) { + if (!unit->ftl_drive.CanConsume()) { if (!ignore_energy_requirements) { return false; } @@ -271,7 +271,8 @@ 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->jump.insysenergy); + 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; } @@ -490,9 +491,7 @@ float JumpCapable::CourseDeviation(const Vector &OriginalCourse, const Vector &F void JumpCapable::DeactivateJumpDrive() { Unit *unit = static_cast(this); - if (unit->jump.drive >= 0) { - unit->jump.drive = -1; - } + unit->jump_drive.UnsetDestination(); } const std::vector &JumpCapable::GetDestinations() const { @@ -500,11 +499,6 @@ const std::vector &JumpCapable::GetDestinations() const { return unit->pImage->destination; } -const Energetic::UnitJump &JumpCapable::GetJumpStatus() const { - const Unit *unit = vega_dynamic_cast_ptr(this); - return unit->jump; -} - StarSystem *JumpCapable::getStarSystem() { Unit *unit = static_cast(this); if (activeStarSystem) { diff --git a/engine/src/cmd/jump_capable.h b/engine/src/cmd/jump_capable.h index 7b238ae243..4a9c42b437 100644 --- a/engine/src/cmd/jump_capable.h +++ b/engine/src/cmd/jump_capable.h @@ -25,7 +25,6 @@ #define VEGA_STRIKE_ENGINE_CMD_JUMP_CAPABLE_H #include "star_system.h" -#include "energetic.h" #include @@ -48,7 +47,6 @@ class JumpCapable { float CourseDeviation(const Vector &OriginalCourse, const Vector &FinalCourse) const; void DeactivateJumpDrive(); const std::vector &GetDestinations() const; - const Energetic::UnitJump &GetJumpStatus() const; StarSystem *getStarSystem(); const StarSystem *getStarSystem() const; Vector GetWarpRefVelocity() const; diff --git a/engine/src/cmd/ship.cpp b/engine/src/cmd/ship.cpp index 29ff18061d..5480edcdb5 100644 --- a/engine/src/cmd/ship.cpp +++ b/engine/src/cmd/ship.cpp @@ -1,7 +1,7 @@ /* * ship.cpp * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 diff --git a/engine/src/cmd/ship.h b/engine/src/cmd/ship.h index bf67db9087..6b5880e670 100644 --- a/engine/src/cmd/ship.h +++ b/engine/src/cmd/ship.h @@ -1,7 +1,7 @@ /* * ship.h * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 diff --git a/engine/src/cmd/unit_csv.cpp b/engine/src/cmd/unit_csv.cpp index 6a2b9f873e..bcc7e8c5c1 100644 --- a/engine/src/cmd/unit_csv.cpp +++ b/engine/src/cmd/unit_csv.cpp @@ -820,10 +820,13 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ const bool WCfuelhack = configuration()->fuel.fuel_equals_warp; - //this is required to make sure we don't trigger the "globally out of fuel" if we use all warp charges -- save some afterburner for later!!! if (WCfuelhack) { - ftl_energy.SetCapacity(ftl_energy.MaxLevel() + jump.energy * 0.1f); + 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. } // End Energy @@ -831,17 +834,19 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ graphicOptions.MinWarpMultiplier = UnitCSVFactory::GetVariable(unit_key, "Warp_Min_Multiplier", 1.0f); graphicOptions.MaxWarpMultiplier = UnitCSVFactory::GetVariable(unit_key, "Warp_Max_Multiplier", 1.0f); + // 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); + jump_drive.Load("", unit_key); + - jump.drive = UnitCSVFactory::GetVariable(unit_key, "Jump_Drive_Present", false) ? -1 : -2; - jump.delay = UnitCSVFactory::GetVariable(unit_key, "Jump_Drive_Delay", 0); forcejump = UnitCSVFactory::GetVariable(unit_key, "Wormhole", false); graphicOptions.RecurseIntoSubUnitsOnCollision = UnitCSVFactory::GetVariable(unit_key, "Collide_Subunits", graphicOptions.RecurseIntoSubUnitsOnCollision ? true : false) ? 1 : 0; - jump.energy = UnitCSVFactory::GetVariable(unit_key, "Outsystem_Jump_Cost", 0.0f); - jump.insysenergy = UnitCSVFactory::GetVariable(unit_key, "Warp_Usage_Cost", 0.0f); - + afterburnenergy = UnitCSVFactory::GetVariable(unit_key, "Afterburner_Usage_Cost", 32767.0f); afterburntype = UnitCSVFactory::GetVariable(unit_key, "Afterburner_Type", @@ -1343,11 +1348,10 @@ string Unit::WriteUnitString() { unit["Warp_Max_Multiplier"] = tos(graphicOptions.MaxWarpMultiplier); unit["Primary_Capacitor"] = tos(energy.Level()); unit["Reactor_Recharge"] = tos(reactor.Capacity()); - unit["Jump_Drive_Present"] = tos(jump.drive >= -1); - unit["Jump_Drive_Delay"] = tos(jump.delay); + jump_drive.SaveToCSV(unit); + ftl_drive.SaveToCSV(unit); + unit["Wormhole"] = tos(forcejump != 0); - unit["Outsystem_Jump_Cost"] = tos(jump.energy); - unit["Warp_Usage_Cost"] = tos(jump.insysenergy); unit["Afterburner_Usage_Cost"] = tos(afterburnenergy); unit["Afterburner_Type"] = tos(afterburntype); unit["Maneuver_Yaw"] = tos(limits.yaw * 180 / (VS_PI)); diff --git a/engine/src/cmd/unit_functions_generic.cpp b/engine/src/cmd/unit_functions_generic.cpp index 351b3dbd0d..7fd60ec62e 100644 --- a/engine/src/cmd/unit_functions_generic.cpp +++ b/engine/src/cmd/unit_functions_generic.cpp @@ -250,28 +250,34 @@ int parseMountSizes(const char *str) { } void DealPossibleJumpDamage(Unit *un) { - - float speed = un->GetVelocity().Magnitude(); - float jump_damage = un->GetJumpStatus().damage + (rand() % 100 < 1) ? (rand() % 20) : 0; - static float jump_damage_multiplier = + static double jump_damage_multiplier = XMLSupport::parse_float(vs_config->getVariable("physics", "jump_damage_multiplier", ".1")); - static float max_damage = XMLSupport::parse_float(vs_config->getVariable("physics", "max_jump_damage", "100")); + static double max_damage = XMLSupport::parse_float(vs_config->getVariable("physics", "max_jump_damage", "100")); - jump_damage = std::min(speed * (jump_damage * jump_damage_multiplier), max_damage); + // Also damage multiplier + double chance_to_damage = ((double) rand() / (RAND_MAX)) + 1; - if (jump_damage > 1) { - Damage damage; - damage.normal_damage = jump_damage; - un->ApplyDamage((un->Position() + un->GetVelocity().Cast()), - un->GetVelocity(), - damage, - un, - GFXColor(((float) (rand() % 100)) / 100, - ((float) (rand() % 100)) / 100, - ((float) (rand() % 100)) / 100), NULL); - un->SetCurPosition( - un->LocalPosition() + (((float) rand()) / RAND_MAX) * jump_damage * un->GetVelocity().Cast()); + // If jump drive is fully operational, there's no chance for damage + if(un->jump_drive.Operational() >= chance_to_damage) { + return; } + + double speed = un->GetVelocity().Magnitude(); + double mass = un->GetMass(); + + double jump_damage = mass * speed * chance_to_damage * jump_damage_multiplier; + + jump_damage = std::min(jump_damage, max_damage); + + Damage damage; + damage.normal_damage = jump_damage; + un->ApplyDamage((un->Position() + un->GetVelocity().Cast()), + un->GetVelocity(), + damage, + un, + GFXColor(((float) (rand() % 100)) / 100, + ((float) (rand() % 100)) / 100, + ((float) (rand() % 100)) / 100), nullptr); } void Enslave(Unit *parent, bool enslave) { diff --git a/engine/src/cmd/unit_generic.cpp b/engine/src/cmd/unit_generic.cpp index e93efabdf7..4e08c7f954 100644 --- a/engine/src/cmd/unit_generic.cpp +++ b/engine/src/cmd/unit_generic.cpp @@ -84,6 +84,7 @@ #include #include #include +#include #ifdef _WIN32 #define strcasecmp stricmp @@ -651,7 +652,7 @@ float Unit::cosAngleTo(Unit *targ, float &dist, float speed, float range, bool t float rv = ittsangle - radangle - (turnmargin ? turnangle : 0); float rsize = targ->rSize() + rSize(); - if ((!targ->GetDestinations().empty() && jump.drive >= 0) || (targ->faction == faction)) { + if ((!targ->GetDestinations().empty() && jump_drive.IsDestinationSet()) || (targ->faction == faction)) { rsize = 0; } //HACK so missions work well if (range != 0) { @@ -993,13 +994,19 @@ float globQueryShell(QVector pos, QVector dir, float rad); extern void ActivateAnimation(Unit *jp); void TurnJumpOKLightOn(Unit *un, Cockpit *cp) { - if (cp) { - if (un->getWarpEnergy() >= un->GetJumpStatus().energy) { - if (un->GetJumpStatus().drive > -2) { - cp->jumpok = 1; - } - } + if(!cp) { + return; + } + + if(!un->jump_drive.Operational()) { + return; + } + + if (!un->jump_drive.CanConsume()) { + return; } + + cp->jumpok = 1; } bool Unit::jumpReactToCollision(Unit *smalle) { @@ -1017,20 +1024,20 @@ bool Unit::jumpReactToCollision(Unit *smalle) { return false; } //we have a drive - if ((!SPEC_interference && (smalle->GetJumpStatus().drive >= 0 - && //we have power - (smalle->ftl_energy.Level() >= smalle->GetJumpStatus().energy - //or we're being cheap - || (ai_jump_cheat && cp == nullptr) - ))) - || forcejump) { - //or the jump is being forced? - //NOW done in star_system_generic.cpp before TransferUnitToSystem smalle->warpenergy-=smalle->GetJumpStatus().energy; - int dest = smalle->GetJumpStatus().drive; - if (dest < 0) { - dest = 0; + if ((!SPEC_interference && + (smalle->jump_drive.IsDestinationSet() && //we have power + (smalle->jump_drive.CanConsume() || + //or we're being cheap + (ai_jump_cheat && cp == nullptr)) + ) + ) || forcejump) { + + if(!smalle->jump_drive.IsDestinationSet()) { + smalle->jump_drive.SetDestination(0); } - smalle->DeactivateJumpDrive(); + int dest = smalle->jump_drive.Destination(); + + smalle->jump_drive.UnsetDestination(); Unit *jumppoint = this; _Universe->activeStarSystem() ->JumpTo(smalle, jumppoint, GetDestinations()[dest % GetDestinations().size()]); @@ -1045,15 +1052,15 @@ bool Unit::jumpReactToCollision(Unit *smalle) { } else { return false; } - if ((!SPEC_interference && (GetJumpStatus().drive >= 0 - && (ftl_energy.Level() >= GetJumpStatus().energy || (ai_jump_cheat && cp == NULL)) + if ((!SPEC_interference && (jump_drive.IsDestinationSet() + && (jump_drive.CanConsume() || (ai_jump_cheat && cp == NULL)) )) || smalle->forcejump) { - ftl_energy.Deplete(false, GetJumpStatus().energy); - DeactivateJumpDrive(); + jump_drive.Consume(); + jump_drive.UnsetDestination(); Unit *jumppoint = smalle; _Universe->activeStarSystem()->JumpTo(this, jumppoint, - smalle->GetDestinations()[GetJumpStatus().drive + smalle->GetDestinations()[jump_drive.Destination() % smalle->GetDestinations().size()]); return true; @@ -1255,36 +1262,24 @@ void Unit::DamageRandSys(float dam, const Vector &vec, float randnum, float degr return; } if (degrees >= 35 && degrees < 60) { - //DAMAGE FUEL - static float fuel_damage_prob = 1.f - - XMLSupport::parse_float(vs_config->getVariable("physics", "fuel_damage_prob", ".25")); - static float warpenergy_damage_prob = fuel_damage_prob - - XMLSupport::parse_float(vs_config->getVariable("physics", - "warpenergy_damage_prob", - "0.05")); - static float ab_damage_prob = warpenergy_damage_prob - - XMLSupport::parse_float(vs_config->getVariable("physics", "ab_damage_prob", ".2")); - static float cargovolume_damage_prob = ab_damage_prob - - XMLSupport::parse_float(vs_config->getVariable("physics", - "cargovolume_damage_prob", - ".15")); - static float upgradevolume_damage_prob = cargovolume_damage_prob - - XMLSupport::parse_float(vs_config->getVariable("physics", - "upgradevolume_damage_prob", - ".1")); - static float cargo_damage_prob = upgradevolume_damage_prob - - XMLSupport::parse_float(vs_config->getVariable("physics", "cargo_damage_prob", "1")); - if (randnum >= fuel_damage_prob) { - fuel.Damage(); - } else if (randnum >= warpenergy_damage_prob) { - ftl_energy.Damage(); - } else if (randnum >= ab_damage_prob) { - this->afterburnenergy += ((1 - dam) * reactor.Capacity()); - } else if (randnum >= cargovolume_damage_prob) { - CargoVolume *= dam; - } else if (randnum >= upgradevolume_damage_prob) { - UpgradeVolume *= dam; - } else if (randnum >= cargo_damage_prob) { + // This code potentially damages a whole bunch of components. + // We generate a random int (0-19). 0-8 damages something. + // 9-19 doesn't. + // This is really a stopgap code until we refactor this better. + std::random_device dev; + std::mt19937 rng(dev()); + std::uniform_int_distribution dist20(0,19); // distribution in range [1, 6] + + switch(dist20(rng)) { + case 0: fuel.Damage(); break; // Fuel + 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: //Do something NASTY to the cargo if (cargo.size() > 0) { unsigned int i = 0; @@ -1296,7 +1291,11 @@ void Unit::DamageRandSys(float dam, const Vector &vec, float randnum, float degr || cargo[cargorand].GetMissionFlag()) && (++i) < cargo.size()); cargo[cargorand].SetQuantity(cargo[cargorand].GetQuantity() * float_to_int(dam)); } + break; + //default: + // No damage } + damages |= Damages::CARGOFUEL_DAMAGED; return; } @@ -1601,9 +1600,9 @@ void WarpPursuit(Unit *un, StarSystem *sourcess, std::string destination) { float ttime = (SystemLocation(sourcess->getFileName()) - SystemLocation(destination)).Magnitude() * seconds_per_parsec; - un->jump.delay += float_to_int(ttime); + un->jump_drive.SetDelay(float_to_int(ttime)); sourcess->JumpTo(un, NULL, destination, true, true); - un->jump.delay -= float_to_int(ttime); + un->jump_drive.SetDelay(-float_to_int(ttime)); } } @@ -1633,7 +1632,9 @@ void Unit::Target(Unit *targ) { LockTarget(false); } } else { - if (jump.drive != -1) { + // TODO: this is unclear code. I translated it fully but + // it doesn't really make sense. Maybe targets don't have destinations?! + if (!jump_drive.Installed() || jump_drive.IsDestinationSet()) { bool found = false; Unit *u; for (un_iter i = _Universe->activeStarSystem()->getUnitList().createIterator(); (u = *i) != NULL; ++i) { @@ -2028,7 +2029,27 @@ void Unit::PerformDockingOperations() { std::set arrested_list_do_not_dereference; +// A simple utility to recharge energy, ftl_energy and shields +// Also to charge for docking and refueling +void rechargeShip(Unit *unit, unsigned int cockpit) { + unit->energy.Refill(); + unit->ftl_energy.Refill(); + unit->shield->FullyCharge(); + + if (cockpit < 0 || cockpit >= _Universe->numPlayers()) { + return; + } + + // Refueling fee + static float refueling_fee = XMLSupport::parse_float(vs_config->getVariable("general", "fuel_docking_fee", "0")); + _Universe->AccessCockpit(cockpit)->credits -= refueling_fee; + static float docking_fee = XMLSupport::parse_float(vs_config->getVariable("general", "docking_fee", "0")); + _Universe->AccessCockpit(cockpit)->credits -= docking_fee; +} + + +// UTDW - unit to dock with int Unit::ForceDock(Unit *utdw, unsigned int whichdockport) { if (utdw->pImage->dockingports.size() <= whichdockport) { return 0; @@ -2052,37 +2073,10 @@ int Unit::ForceDock(Unit *utdw, unsigned int whichdockport) { } unsigned int cockpit = UnitUtil::isPlayerStarship(this); + + // Refuel and recharge and charge docking/refueling fees + rechargeShip(this, cockpit); - static float MinimumCapacityToRefuelOnLand = - XMLSupport::parse_float(vs_config->getVariable("physics", - "MinimumWarpCapToRefuelDockeesAutomatically", - "0")); - float capdata = utdw->warpCapData(); - if ((capdata >= MinimumCapacityToRefuelOnLand) && (this->refillWarpEnergy())) { - if (cockpit >= 0 && cockpit < _Universe->numPlayers()) { - static float - docking_fee = XMLSupport::parse_float(vs_config->getVariable("general", "fuel_docking_fee", "0")); - _Universe->AccessCockpit(cockpit)->credits -= docking_fee; - } - } - if ((capdata < MinimumCapacityToRefuelOnLand) && (this->faction == utdw->faction)) { - if (utdw->warpEnergyData() > this->warpEnergyData() && utdw->warpEnergyData() > this->jump.energy) { - this->increaseWarpEnergy(false, this->jump.energy); - utdw->decreaseWarpEnergy(false, this->jump.energy); - } - if (utdw->warpEnergyData() < this->warpEnergyData() && this->warpEnergyData() > utdw->jump.energy) { - utdw->increaseWarpEnergy(false, utdw->jump.energy); - this->decreaseWarpEnergy(false, utdw->jump.energy); - } - } - if (cockpit >= 0 && cockpit < _Universe->numPlayers()) { - static float docking_fee = XMLSupport::parse_float(vs_config->getVariable("general", "docking_fee", "0")); - if (_Universe->AccessCockpit(cockpit)->credits >= docking_fee) { - _Universe->AccessCockpit(cockpit)->credits -= docking_fee; - } else if (_Universe->AccessCockpit(cockpit)->credits >= 0) { - _Universe->AccessCockpit(cockpit)->credits = 0; - } - } std::set::iterator arrested = arrested_list_do_not_dereference.find(this); if (arrested != arrested_list_do_not_dereference.end()) { arrested_list_do_not_dereference.erase(arrested); @@ -3004,26 +2998,7 @@ bool Unit::UpAndDownGrade(const Unit *up, 1); } } - //Check jump and jump/SPEC stuff - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, - "Warp_Capacitor|Warp_Usage_Cost")) { - /*if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Warp_Capacitor")) - STDUPGRADE(maxwarpenergy, up->maxwarpenergy, templ->maxwarpenergy, 0);*/ - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Warp_Usage_Cost")) - STDUPGRADE(jump.insysenergy, up->jump.insysenergy, templ->jump.insysenergy, 0); - -// for when we'll need more than one jump drive upgrade (Elite Strike?) - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Outsystem_Jump_Cost")) - STDUPGRADE(jump.energy, up->jump.energy, templ->jump.energy, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Jump_Drive_Delay")) - STDUPGRADE(jump.delay, up->jump.delay, templ->jump.delay, 0); - - } + if (!csv_cell_null_check || force_change_on_nothing || cell_has_recursive_data(upgrade_name, up->faction, "Armor_Front_Top_Right")) { @@ -3332,32 +3307,6 @@ bool Unit::UpAndDownGrade(const Unit *up, } //NO CLUE FOR BELOW if (downgrade) { - if (jump.drive >= -1 && up->jump.drive >= -1) { - if (touchme) { - jump.drive = -2; - } - ++numave; - percentage += .5 * ((float) (100 - jump.damage)) / (101 - up->jump.damage); - if (gen_downgrade_list) { - AddToDowngradeMap(up->name, - up->jump.drive, - ((char *) &this->jump.drive) - ((char *) this), - tempdownmap); - } - } - if (cloak.Capable() && up->cloak.Capable()) { - if (touchme) { - cloak.Disable(); - } - ++numave; - ++percentage; - if (gen_downgrade_list) { - AddToDowngradeMap(up->name, - up->cloak.current, - ((char *) &this->cloak.current) - ((char *) this), - tempdownmap); - } - } //NOTE: Afterburner type 2 (jmp) //NOTE: Afterburner type 1 (gas) //NOTE: Afterburner type 0 (pwr) @@ -3399,15 +3348,6 @@ bool Unit::UpAndDownGrade(const Unit *up, && up->afterburnenergy < 32767) { cancompletefully = false; } - if ((jump.drive == -2 && up->jump.drive >= -1) || force_change_on_nothing) { - if (touchme) { - jump.drive = up->jump.drive; - jump.damage = 0; - } - ++numave; - } else if (jump.drive >= -1 && up->jump.drive >= -1) { - cancompletefully = false; - } } if (needs_redemption) { if (!can_be_redeemed) { diff --git a/engine/src/cmd/unit_generic.h b/engine/src/cmd/unit_generic.h index 088b887e71..fa00897d3c 100644 --- a/engine/src/cmd/unit_generic.h +++ b/engine/src/cmd/unit_generic.h @@ -87,6 +87,8 @@ void UncheckUnit( class Unit*un ); #include "components/cloak.h" #include "components/energy_container.h" #include "components/reactor.h" +#include "components/ftl_drive.h" +#include "components/jump_drive.h" extern char *GetUnitDir(const char *filename); @@ -160,6 +162,8 @@ class Unit : public Armed, public Audible, public Drawable, public Damageable, p Reactor reactor = Reactor(&fuel, &energy, &ftl_energy); Cloak cloak; + FtlDrive ftl_drive = FtlDrive(&ftl_energy); + JumpDrive jump_drive = JumpDrive(&ftl_energy); /// Radar and related systems // TODO: take a deeper look at this much later... @@ -1059,13 +1063,9 @@ extern std::set GetListOfDowngrades(); extern void ClearDowngradeMap(); #endif //VEGA_STRIKE_ENGINE_CMD_UNIT_H -/* - ************************************************************************************** - **** MESH ANIMATION STUFF *** - ************************************************************************************** - */ +void rechargeShip(Unit *unit, unsigned int cockpit); #endif //VEGA_STRIKE_ENGINE_CMD_UNIT_GENERIC_H diff --git a/engine/src/cmd/unit_util_generic.cpp b/engine/src/cmd/unit_util_generic.cpp index 09131f7fad..1f4512ceb2 100644 --- a/engine/src/cmd/unit_util_generic.cpp +++ b/engine/src/cmd/unit_util_generic.cpp @@ -921,6 +921,16 @@ float PercentOperational(Unit *un, std::string name, std::string category, bool return un->reactor.Damaged() ? 0.5 : 1.0; } + if(upgrade_category == "Jump_Drive") { + return un->jump_drive.Operational(); + } + + if(upgrade_category == "FTL Drive") { + return un->ftl_drive.Operational(); + } + + // TODO: make cloak.current a resource + // Then implement damage properly if(upgrade_category == "Cloak") { return un->cloak.Damaged() ? 0.5 : 1.0; } diff --git a/engine/src/cmd/upgradeable_unit.cpp b/engine/src/cmd/upgradeable_unit.cpp index 10252c1161..740ac874ea 100644 --- a/engine/src/cmd/upgradeable_unit.cpp +++ b/engine/src/cmd/upgradeable_unit.cpp @@ -1,7 +1,7 @@ /* * upgradeable_unit.cpp * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 @@ -113,6 +113,14 @@ UpgradeType GetUpgradeType(const std::string upgrade_key) { 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; } @@ -158,6 +166,17 @@ UpgradeOperationResult UpgradeableUnit::UpgradeUnit(const std::string upgrade_na result.upgradeable = true; result.success = unit->reactor.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; + + case UpgradeType::FTL_Drive: + result.upgradeable = true; + result.success = unit->ftl_drive.CanWillUpDowngrade(upgrade_key, upgrade, apply); + break; + + case UpgradeType::Jump_Drive: + result.upgradeable = true; + result.success = unit->jump_drive.CanWillUpDowngrade(upgrade_key, upgrade, apply); + break; + case UpgradeType::Cloak: result.upgradeable = true; result.success = unit->cloak.CanWillUpDowngrade(upgrade_key, upgrade, apply); @@ -171,10 +190,6 @@ UpgradeOperationResult UpgradeableUnit::UpgradeUnit(const std::string upgrade_na result.upgradeable = true; result.success = unit->armor->CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - case UpgradeType::Jump_Drive: - result.upgradeable = true; - result.success = unit->jump_drive.CanWillUpDowngrade(upgrade_key, upgrade, apply); - break; /*case UpgradeType::ECM: diff --git a/engine/src/cmd/upgradeable_unit.h b/engine/src/cmd/upgradeable_unit.h index e640f02781..3b01673bff 100644 --- a/engine/src/cmd/upgradeable_unit.h +++ b/engine/src/cmd/upgradeable_unit.h @@ -2,7 +2,7 @@ /* * upgradeable_unit.h * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, Benjamen R. Meyer, + * Copyright (C) 2001-2023 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, Benjamen R. Meyer, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -55,6 +55,7 @@ enum class UpgradeType { Afterburner, Drive, Jump_Drive, + FTL_Drive, Cloak, ECM, diff --git a/engine/src/components/cloak.cpp b/engine/src/components/cloak.cpp index 7a7b451ad5..a1db779cdf 100644 --- a/engine/src/components/cloak.cpp +++ b/engine/src/components/cloak.cpp @@ -1,7 +1,7 @@ /* * cloak.cpp * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 diff --git a/engine/src/components/cloak.h b/engine/src/components/cloak.h index 460bcc6f9a..702beec803 100644 --- a/engine/src/components/cloak.h +++ b/engine/src/components/cloak.h @@ -1,7 +1,7 @@ /* * cloak.h * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 diff --git a/engine/src/components/component.cpp b/engine/src/components/component.cpp index 2861b026ce..b625f4f954 100644 --- a/engine/src/components/component.cpp +++ b/engine/src/components/component.cpp @@ -32,10 +32,12 @@ const std::string NAME = "Name"; const std::string MASS = "Mass"; const std::string VOLUME = "Volume"; -Component::Component(double mass, double volume, bool integral): +Component::Component(double mass, double volume, bool installed, bool integral): unit_key(""), upgrade_name(""), mass(mass), volume(volume), + operational(Resource(100.0,0.0,100.0)), + installed(installed), integral(integral) {} @@ -73,7 +75,7 @@ bool Component::Downgrade() { mass = 0.0; volume = 0.0; - + installed = false; return true; } @@ -84,10 +86,42 @@ bool Component::Upgrade(const std::string upgrade_key) { mass = UnitCSVFactory::GetVariable(upgrade_key, MASS, 0.0); // TODO: volume currently not in units.json. need to merge with items list volume = UnitCSVFactory::GetVariable(upgrade_key, VOLUME, 0.0); - + installed = true; return true; } +void Component::Damage() { + operational.RandomDamage(); +} + +void Component::DamageByPercent(double percent) { + operational.DamageByPercent(percent); +} + +void Component::Repair() { + operational.RepairFully(); +} + +bool Component::Damaged() const { + return operational.Damaged(); +} + +bool Component::Destroyed() const { + return operational.Destroyed(); +} + +bool Component::Installed() const { + return installed; +} + +bool Component::Operational() const { + return Installed() && !Destroyed(); +} + +double Component::Percent() const { + return operational.Percent(); +} + void Component::SetIntegral(bool integral) { this->integral = integral; } \ No newline at end of file diff --git a/engine/src/components/component.h b/engine/src/components/component.h index 2288e417a2..4b2be46474 100644 --- a/engine/src/components/component.h +++ b/engine/src/components/component.h @@ -31,6 +31,8 @@ #include #include +#include "resource/resource.h" + /** * LibComponent is currently tightly coupled to LibDamage and * other various libraries in VegaStrike engine. @@ -57,10 +59,15 @@ class Component double mass = 0; double volume = 0; + Resource operational; // Percent operational + + bool installed = false; bool integral = false; // Part of the ship. Can't be upgraded/downgraded public: Component(double mass = 0, - double volume = 0, bool integral = false); + double volume = 0, + bool installed = false, + bool integral = false); // Load from units dictionary virtual void Load(std::string upgrade_key, std::string unit_key); @@ -81,12 +88,15 @@ class Component virtual bool Upgrade(const std::string upgrade_key); - virtual void Damage() = 0; - virtual void DamageByPercent(double percent) = 0; - virtual void Repair() = 0; + virtual void Damage(); + virtual void DamageByPercent(double percent); + virtual void Repair(); - virtual bool Damaged() const = 0; - virtual bool Installed() const = 0; + virtual bool Damaged() const; + bool Destroyed() const; + double Percent() const; + bool Installed() const; + bool Operational() const; void SetIntegral(bool integral); }; diff --git a/engine/src/components/energy_consumer.cpp b/engine/src/components/energy_consumer.cpp index 8fd618acd4..de9cfd0a88 100644 --- a/engine/src/components/energy_consumer.cpp +++ b/engine/src/components/energy_consumer.cpp @@ -38,6 +38,15 @@ EnergyConsumer::EnergyConsumer(EnergyContainer *source, atom_consumption(consumption * simulation_atom_var) {} +bool EnergyConsumer::CanConsume() { + // TODO: need to check if operational somewhere else + if(!source) { + return false; + } + + return source->Level() > atom_consumption; +} + double EnergyConsumer::Consume() { if(!source) { return 0.0; diff --git a/engine/src/components/energy_consumer.h b/engine/src/components/energy_consumer.h index cc1eee1097..ec7f5db049 100644 --- a/engine/src/components/energy_consumer.h +++ b/engine/src/components/energy_consumer.h @@ -42,6 +42,7 @@ class EnergyConsumer { bool partial; // Can power consumer with less energy than requested public: EnergyConsumer(EnergyContainer *source, bool partial, double consumption = 0.0); + bool CanConsume(); double Consume(); double GetConsumption() const; double GetAtomConsumption() const; diff --git a/engine/src/components/ftl_drive.cpp b/engine/src/components/ftl_drive.cpp new file mode 100644 index 0000000000..908285721f --- /dev/null +++ b/engine/src/components/ftl_drive.cpp @@ -0,0 +1,80 @@ +/* + * ftl_drive.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 "ftl_drive.h" + +#include "unit_csv_factory.h" + +FtlDrive::FtlDrive() : + Component(), + EnergyConsumer(nullptr, 0, false) {} + +FtlDrive::FtlDrive(EnergyContainer *source): + Component(0.0, 0.0, true), + EnergyConsumer(source, false) {} + + +bool FtlDrive::Enabled() const { + return Installed() && Operational(); +} + + +// Component Methods +void FtlDrive::Load(std::string upgrade_key, + std::string unit_key, + double ftl_factor) { + Component::Load(upgrade_key, unit_key); + + // Consumer + double energy = UnitCSVFactory::GetVariable(unit_key, "Warp_Usage_Cost", 0.0f); + SetConsumption(energy / ftl_factor); + + // FTL Drive +} + +void FtlDrive::SaveToCSV(std::map& unit) const { + unit["Warp_Usage_Cost"] = std::to_string(consumption); +} + +std::string FtlDrive::Describe() const { + return std::string(); +} + +// FTL drive is integrated and so cannot be upgraded/downgraded +bool FtlDrive::CanDowngrade() const { + return false; +} + +bool FtlDrive::Downgrade() { + return false; +} + +bool FtlDrive::CanUpgrade(const std::string upgrade_name) const { + return false; +} + +bool FtlDrive::Upgrade(const std::string upgrade_name) { + return false; +} + diff --git a/engine/src/components/ftl_drive.h b/engine/src/components/ftl_drive.h new file mode 100644 index 0000000000..b9dcc6d249 --- /dev/null +++ b/engine/src/components/ftl_drive.h @@ -0,0 +1,61 @@ +/* + * ftl_drive.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 FTL_DRIVE_H +#define FTL_DRIVE_H + +#include "component.h" +#include "energy_consumer.h" + +class EnergyContainer; + +class FtlDrive : public Component, public EnergyConsumer { + // TODO: implement damage so something will actually happen + // Right now, damage is recorded in component superclass but game doesn't + // take it into account. +public: + FtlDrive(); + FtlDrive(EnergyContainer *source); + + bool Enabled() const; + + // Component Methods + virtual void Load(std::string upgrade_key, + std::string unit_key, + double ftl_factor = 1.0); + + virtual void SaveToCSV(std::map& unit) const; + + virtual std::string Describe() const; // Describe component in base_computer + + virtual bool CanDowngrade() const; + + virtual bool Downgrade(); + + virtual bool CanUpgrade(const std::string upgrade_name) const; + + virtual bool Upgrade(const std::string upgrade_name); +}; + +#endif // FTL_DRIVE_H diff --git a/engine/src/components/jump_drive.cpp b/engine/src/components/jump_drive.cpp new file mode 100644 index 0000000000..1c73ce80ec --- /dev/null +++ b/engine/src/components/jump_drive.cpp @@ -0,0 +1,129 @@ +/* + * jump_drive.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 "jump_drive.h" + +#include "unit_csv_factory.h" + +JumpDrive::JumpDrive() : + Component(), + EnergyConsumer(nullptr, 0, false), + destination(-1), + delay(0.0) {} + +JumpDrive::JumpDrive(EnergyContainer *source): + Component(0.0, 0.0, true), + EnergyConsumer(source, false), + delay(0.0) {} + + +int JumpDrive::Destination() const { + return destination; +} + +bool JumpDrive::IsDestinationSet() const { + return !Destroyed() && destination != -1; +} + +void JumpDrive::SetDestination(int destination) { + if(!Destroyed()) { + this->destination = destination; + } +} + +void JumpDrive::UnsetDestination() { + destination = -1; +} + +double JumpDrive::Delay() const { + return delay; +} + +void JumpDrive::SetDelay(double delay) { + this->delay += delay; +} + +bool JumpDrive::Enabled() const { + return Installed() && !Destroyed(); +} + + +// Component Methods +void JumpDrive::Load(std::string upgrade_key, std::string unit_key) { + Component::Load(upgrade_key, 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; + + + // Jump Drive + bool installed = UnitCSVFactory::GetVariable(unit_key, "Jump_Drive_Present", false); + if(!installed) { + this->unit_key = ""; + } + + delay = UnitCSVFactory::GetVariable(unit_key, "Jump_Drive_Delay", 0); +} + +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); +} + +std::string JumpDrive::Describe() const { + return std::string(); +} + +bool JumpDrive::CanDowngrade() const { + return !Damaged(); +} + +bool JumpDrive::Downgrade() { + if(!CanDowngrade()) { + return false; + } + + Component::Downgrade(); + + return true; +} + +bool JumpDrive::CanUpgrade(const std::string upgrade_name) const { + return !Damaged() && !Installed(); +} + +bool JumpDrive::Upgrade(const std::string upgrade_name) { + if(!CanUpgrade(upgrade_name)) { + return false; + } + + Component::Upgrade(upgrade_key); + return true; +} + + + diff --git a/engine/src/components/jump_drive.h b/engine/src/components/jump_drive.h new file mode 100644 index 0000000000..897f05e97b --- /dev/null +++ b/engine/src/components/jump_drive.h @@ -0,0 +1,67 @@ +/* + * jump_drive.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 JUMP_DRIVE_H +#define JUMP_DRIVE_H + +#include "component.h" +#include "energy_consumer.h" + +class EnergyContainer; + +class JumpDrive : public Component, public EnergyConsumer { + int destination; // 0 is probably some kind of /dev/null + double delay; + +public: + JumpDrive(); + JumpDrive(EnergyContainer *source); + + int Destination() const; + bool IsDestinationSet() const; + void SetDestination(int destination); + void UnsetDestination(); + + double Delay() const; + void SetDelay(double delay); + + bool Enabled() const; + + // Component Methods + 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(); + + virtual bool CanUpgrade(const std::string upgrade_name) const; + + virtual bool Upgrade(const std::string upgrade_name); +}; + +#endif // JUMP_DRIVE_H diff --git a/engine/src/components/tests/balancing_tests.cpp b/engine/src/components/tests/balancing_tests.cpp index 081ab49f79..49376079b4 100644 --- a/engine/src/components/tests/balancing_tests.cpp +++ b/engine/src/components/tests/balancing_tests.cpp @@ -173,4 +173,38 @@ TEST(FuelBurn, RobinNaive_2) { std::cout << "NaiveFuelBurn_2 percent left: " << result.residue * 100 << std::endl; //EXPECT_EQ(0,1); // use these to see detailed prints -} \ No newline at end of file +} + +// Use this test to figure out why FTL drive is running out of energy +/*TEST(FTLDrive, Sanity) { + EnergySetup setup = {99.0, 25, 1.0, 1.0}; + EnergyManager manager = EnergyManager(setup, simulation_atom_var); + std::vector consumers = { + EnergyConsumer(&manager.ftl_energy, false, 120) // General consumer at 40 per second + }; + + manager.Print(-1); + EXPECT_FALSE(manager.fuel.Depleted()); + EXPECT_FALSE(manager.energy.Depleted()); + EXPECT_FALSE(manager.ftl_energy.Depleted()); + + int i = 0; + for(;i<10;i++) { + manager.Print(i); + + manager.reactor.Generate(); + for(EnergyConsumer& consumer : consumers) { + if(consumer.CanConsume()) { + consumer.Consume(); + } else { + std::cout << "Not enough FTL energy.\n"; + EXPECT_EQ(0,1); + } + + } + } + + FuelBurnResult result(manager.fuel.Percent(), i, i/60); + + EXPECT_EQ(0,1); // use these to see detailed prints +}*/ \ No newline at end of file diff --git a/engine/src/components/tests/energy_container_tests.cpp b/engine/src/components/tests/energy_container_tests.cpp index d5bed7838d..2a9aa271ca 100644 --- a/engine/src/components/tests/energy_container_tests.cpp +++ b/engine/src/components/tests/energy_container_tests.cpp @@ -23,8 +23,12 @@ TEST(EnergyContainer, Sanity) { int i=0; while(!container.Depleted() && i < 100) { + std::cout << " Can consume: " << consumer.CanConsume() << std::endl; consumer.Consume(); printContainer(container); i++; } + + // Uncomment to see prints + //EXPECT_TRUE(consumer.CanConsume()); } \ No newline at end of file diff --git a/engine/src/damage/damageable_layer.cpp b/engine/src/damage/damageable_layer.cpp index a0269c6235..dc3de05d3e 100644 --- a/engine/src/damage/damageable_layer.cpp +++ b/engine/src/damage/damageable_layer.cpp @@ -276,30 +276,6 @@ float DamageableLayer::AverageMaxLayerValue() { float CalculatePercentage(float numerator, float denominator) { return numerator / denominator; - - // All these checks potentially slow down the game - // and cause the graphics to flicker - /*if(denominator < numerator) { - return 0.0; // This should really be an error - } - - if(denominator <= 0.0f || numerator <0.0f) { - return 0.0; - } - - float percent = numerator / denominator; - - if(percent > 1.0f) { - return 1.0; - } - - if(percent <0.01) { - return 0.0f; - } - - // Possibly nicer alternative - //return roundf(percent * 100) / 100.0; - return percent;*/ } float DamageableLayer::GetMaxHealth() { @@ -375,6 +351,12 @@ float DamageableLayer::GetPercent(FacetName facet_name) { return percent; } +void DamageableLayer::FullyCharge() { + for (Health &facet : facets) { + facet.SetHealth(facet.adjusted_health); + } +} + void DamageableLayer::Regenerate(float recharge_rate) { for (Health &facet : facets) { facet.Regenerate(recharge_rate); diff --git a/engine/src/damage/damageable_layer.h b/engine/src/damage/damageable_layer.h index 46af49c25f..2a158a2175 100644 --- a/engine/src/damage/damageable_layer.h +++ b/engine/src/damage/damageable_layer.h @@ -88,6 +88,7 @@ struct DamageableLayer { float GetMaxHealth(); float GetPercent(FacetName facet_name); + void FullyCharge(); void Regenerate(float recharge_rate); void RegenerateOrDischarge(float recharge, bool velocity_discharge, float discharge_rate); float GetRegeneration(); diff --git a/engine/src/gfx/cockpit.cpp b/engine/src/gfx/cockpit.cpp index 6bec2be868..651cd79930 100644 --- a/engine/src/gfx/cockpit.cpp +++ b/engine/src/gfx/cockpit.cpp @@ -432,7 +432,7 @@ float GameCockpit::LookupUnitStat(int stat, Unit *target) { case UnitImages::WARPENERGY: { const bool warpifnojump = configuration()->graphics_config.hud.display_warp_energy_if_no_jump_drive; - return (warpifnojump || target->GetJumpStatus().drive != -2) ? target->warpEnergyData() : 0; + return (warpifnojump || target->jump_drive.Installed()) ? target->ftl_energy.Percent() : 0; } case UnitImages::HULL: if (maxhull < target->GetHull()) { @@ -728,9 +728,9 @@ float GameCockpit::LookupUnitStat(int stat, Unit *target) { return (float) UnitImages::NOMINAL; } case UnitImages::CANJUMP_MODAL: - if (-2 == target->GetJumpStatus().drive) { + if (!target->jump_drive.Installed() || !target->jump_drive.Operational()) { return (float) UnitImages::NODRIVE; - } else if (target->getWarpEnergy() < target->GetJumpStatus().energy) { + } else if (!target->jump_drive.CanConsume()) { return (float) UnitImages::NOTENOUGHENERGY; } else if (target->graphicOptions.InWarp) { //FIXME return (float) UnitImages::OFF; diff --git a/engine/src/python/unit_wrapper_class.h b/engine/src/python/unit_wrapper_class.h index f8bd44febc..e6f3d990d7 100644 --- a/engine/src/python/unit_wrapper_class.h +++ b/engine/src/python/unit_wrapper_class.h @@ -272,7 +272,16 @@ class UnitWrapper : public UnitContainer { { CHECKME -1; } - return unit->GetJumpStatus().drive; + + // Here is the last vestige of the old code + // -2 is no jump drive + // -1 is jump drive but no destination + // 0 and above is set destination + if(!unit->jump_drive.Installed()) { + return -2; + } + + return unit->jump_drive.Destination(); } void ApplyDamage(Vector pnt, diff --git a/engine/src/resource/manifest.cpp b/engine/src/resource/manifest.cpp index ca3344d883..91fd4fe501 100644 --- a/engine/src/resource/manifest.cpp +++ b/engine/src/resource/manifest.cpp @@ -1,7 +1,7 @@ /* * manifest.cpp * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 diff --git a/engine/src/resource/manifest.h b/engine/src/resource/manifest.h index 71d65aeced..12e758137c 100644 --- a/engine/src/resource/manifest.h +++ b/engine/src/resource/manifest.h @@ -1,7 +1,7 @@ /* * manifest.h * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 diff --git a/engine/src/resource/random_utils.cpp b/engine/src/resource/random_utils.cpp index 9a66ac35d0..ab2789cce6 100644 --- a/engine/src/resource/random_utils.cpp +++ b/engine/src/resource/random_utils.cpp @@ -1,7 +1,7 @@ /* * random_utils.cpp * - * Copyright (C) 2001-2024 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * Copyright (C) 2001-2024 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source diff --git a/engine/src/resource/random_utils.h b/engine/src/resource/random_utils.h index adc42b8687..2af2b7449a 100644 --- a/engine/src/resource/random_utils.h +++ b/engine/src/resource/random_utils.h @@ -1,7 +1,7 @@ /* * random_utils.h * - * Copyright (C) 2001-2024 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * Copyright (C) 2001-2024 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source diff --git a/engine/src/resource/resource.cpp b/engine/src/resource/resource.cpp index 4ee754d9cf..119ed5863f 100644 --- a/engine/src/resource/resource.cpp +++ b/engine/src/resource/resource.cpp @@ -140,21 +140,14 @@ void Resource::Destroy() { } template -bool Resource::Destroyed() { +bool Resource::Destroyed() const { return adjusted_max_value_ == min_value_; } template void Resource::RandomDamage() { const double severity = randomDouble(); - - if(severity > .95) { - // Destroy system - Destroy(); - } else { - // Damage system - DamageByPercent(severity); - } + DamageByPercent(severity); } template @@ -173,8 +166,11 @@ void Resource::DamageByPercent(const T &value) { return; } - adjusted_max_value_ = std::max(min_value_, adjusted_max_value_ - (max_value_ * value)); - value_ = std::min(value_, adjusted_max_value_); + if(value > .95) { + Destroy(); + } else { + DamageByValue(max_value_ * value); + } } template diff --git a/engine/src/resource/resource.h b/engine/src/resource/resource.h index 1059d50e8f..96f572fd92 100644 --- a/engine/src/resource/resource.h +++ b/engine/src/resource/resource.h @@ -102,7 +102,7 @@ class Resource { // Damage & Repair void Destroy(); // value_ = adjusted_max_value_ = min_value_; - bool Destroyed(); + bool Destroyed() const; void RandomDamage(); void DamageByValue(const T &value); void DamageByPercent(const T &value); diff --git a/engine/src/resource/tests/buy_sell.cpp b/engine/src/resource/tests/buy_sell.cpp index 85aed5156a..8396319e03 100644 --- a/engine/src/resource/tests/buy_sell.cpp +++ b/engine/src/resource/tests/buy_sell.cpp @@ -1,7 +1,7 @@ /* * buy_cell.cpp * - * Copyright (C) 2001-2024 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * Copyright (C) 2001-2024 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source diff --git a/engine/src/resource/tests/manifest_tests.cpp b/engine/src/resource/tests/manifest_tests.cpp index 696d3fe1af..9ac51fc9fe 100644 --- a/engine/src/resource/tests/manifest_tests.cpp +++ b/engine/src/resource/tests/manifest_tests.cpp @@ -1,7 +1,7 @@ /* * manifest.cpp * - * Copyright (C) 2001-2023 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * 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 diff --git a/engine/src/resource/tests/random_tests.cpp b/engine/src/resource/tests/random_tests.cpp index 8577f1b92c..85de6512a5 100644 --- a/engine/src/resource/tests/random_tests.cpp +++ b/engine/src/resource/tests/random_tests.cpp @@ -1,7 +1,7 @@ /* * random_tests.cpp * - * Copyright (C) 2001-2024 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * Copyright (C) 2001-2024 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source diff --git a/engine/src/resource/tests/resource_test.cpp b/engine/src/resource/tests/resource_test.cpp index c8eae4ccbb..a3b75265b6 100644 --- a/engine/src/resource/tests/resource_test.cpp +++ b/engine/src/resource/tests/resource_test.cpp @@ -1,7 +1,7 @@ /* * resource_tests.cpp * - * Copyright (C) 2001-2024 Daniel Horn, Benjaman Meyer, Roy Falk, Stephen G. Tuggy, + * Copyright (C) 2001-2024 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source diff --git a/engine/src/star_system.cpp b/engine/src/star_system.cpp index 48dad075a2..63ca448d74 100644 --- a/engine/src/star_system.cpp +++ b/engine/src/star_system.cpp @@ -1317,7 +1317,7 @@ void StarSystem::ProcessPendingJumps() { bool dosightandsound = ((pendingjump[kk]->dest == savedStarSystem) || _Universe->isPlayerStarship(un)); _Universe->setActiveStarSystem(pendingjump[kk]->orig); if (un->TransferUnitToSystem(kk, savedStarSystem, dosightandsound)) { - un->decreaseWarpEnergy(false, 1.0f); + un->jump_drive.Consume(); } if (dosightandsound) { _Universe->activeStarSystem()->DoJumpingComeSightAndSound(un); @@ -1398,9 +1398,8 @@ bool StarSystem::JumpTo(Unit *un, Unit *jumppoint, const std::string &system, bo return false; } - if (un->jump.drive >= 0) { - un->jump.drive = -1; - } + un->jump_drive.UnsetDestination(); + #ifdef JUMP_DEBUG VS_LOG(trace, (boost::format("jumping to %1%. ") % system)); #endif @@ -1424,7 +1423,7 @@ bool StarSystem::JumpTo(Unit *un, Unit *jumppoint, const std::string &system, bo ani = _Universe->activeStarSystem()->DoJumpingLeaveSightAndSound(un); } _Universe->AccessCockpit()->OnJumpBegin(un); - pendingjump.push_back(new unorigdest(un, jumppoint, this, ss, un->GetJumpStatus().delay, ani, justloaded, + pendingjump.push_back(new unorigdest(un, jumppoint, this, ss, un->jump_drive.Delay(), ani, justloaded, save_coordinates ? ComputeJumpPointArrival(un->Position(), this->getFileName(), system) : QVector(0, 0, 0))); diff --git a/engine/src/star_system_jump.cpp b/engine/src/star_system_jump.cpp index eb5e64f4a3..f85102703e 100644 --- a/engine/src/star_system_jump.cpp +++ b/engine/src/star_system_jump.cpp @@ -119,7 +119,7 @@ void StarSystem::DrawJumpStars() { un->Position() + r.Cast() * un->rSize() * (pendingjump[kk]->delay + .25)); JumpAnimations[k].a->SetOrientation(p, q, r); float dd = un->rSize() * game_options()->jumpgatesize - * (un->GetJumpStatus().delay - pendingjump[kk]->delay) / (float) un->GetJumpStatus().delay; + * (un->jump_drive.Delay() - pendingjump[kk]->delay) / (float) un->jump_drive.Delay(); JumpAnimations[k].a->SetDimensions(dd, dd); } } @@ -158,7 +158,7 @@ int StarSystem::DoJumpingLeaveSightAndSound(Unit *un) { int ani; Vector p, q, r; un->GetOrientation(p, q, r); - ani = AddJumpAnimation(un->Position() + r.Cast() * un->rSize() * (un->GetJumpStatus().delay + .25), + ani = AddJumpAnimation(un->Position() + r.Cast() * un->rSize() * (un->jump_drive.Delay() + .25), 10 * un->rSize()); static int jumpleave = AUDCreateSound(game_options()->jumpleave, false); AUDPlay(jumpleave, un->LocalPosition(), un->GetVelocity(), 1);