Skip to content

Commit

Permalink
Add support for ftl and jump drives (#875)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
royfalk authored Oct 5, 2024
1 parent 50f1678 commit 3615f5d
Show file tree
Hide file tree
Showing 49 changed files with 686 additions and 392 deletions.
2 changes: 2 additions & 0 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions engine/src/cmd/ai/aggressive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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",
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -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);
}
}
Expand Down
16 changes: 4 additions & 12 deletions engine/src/cmd/ai/docking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ QVector DockingOps::Movement(Unit *utdw) {
return loc;
}


bool DockingOps::DockToTarget(Unit *utdw) {
if (utdw->DockingPortLocations()[port].IsOccupied()) {
if (keeptrying) {
Expand All @@ -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) {
Expand All @@ -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;
}
}
Expand Down
2 changes: 1 addition & 1 deletion engine/src/cmd/ai/fire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion engine/src/cmd/ai/flykeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ void FlyByKeyboard::Execute(bool resetangvelocity) {
if ((counter - last_jumped) > static_cast<unsigned>(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");
Expand Down
3 changes: 2 additions & 1 deletion engine/src/cmd/ai/ikarus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion engine/src/cmd/ai/warpto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 13 additions & 13 deletions engine/src/cmd/basecomputer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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) {
Expand All @@ -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";
Expand All @@ -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";
}
Expand Down Expand Up @@ -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";
Expand Down
79 changes: 5 additions & 74 deletions engine/src/cmd/energetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Unit>(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<Unit>(this);
Expand All @@ -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;
Expand Down Expand Up @@ -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<Unit>(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<const Unit>(this);
Expand All @@ -164,28 +129,6 @@ void Energetic::rechargeEnergy() {
}
}

bool Energetic::refillWarpEnergy() {
Unit *unit = vega_dynamic_cast_ptr<Unit>(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;
}
Expand All @@ -201,18 +144,6 @@ float Energetic::warpCapData() const {
return unit->ftl_energy.MaxLevel();
}

float Energetic::warpEnergyData() const {
const Unit *unit = vega_dynamic_cast_ptr<const Unit>(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<const Unit>(this);
Expand All @@ -230,16 +161,16 @@ 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<Unit>(this);

// TODO: if we run out of fuel or energy, we die from lack of air

MaintainShields();
ExpendEnergyToRechargeShields();
MaintainECM();
DecreaseWarpEnergyInWarp();

RechargeWarpCapacitors(player_ship);

ExpendFuel();
unit->reactor.Generate();
}

void Energetic::ExpendEnergy(float usage) {
Expand Down
16 changes: 0 additions & 16 deletions engine/src/cmd/energetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ class Energetic {
Energetic();
virtual ~Energetic() = default;

void decreaseWarpEnergy(bool insys, double time);
void DecreaseWarpEnergyInWarp();


Expand All @@ -47,7 +46,6 @@ class Energetic {
void ExpendFuel();
float getWarpEnergy() const;

void increaseWarpEnergy(bool insys, double time);

float maxEnergyData() const;

Expand All @@ -56,7 +54,6 @@ class Energetic {

void rechargeEnergy();
void RechargeWarpCapacitors(const bool player_ship);
bool refillWarpEnergy();

void setAfterburnerEnergy(float aft);
void setEnergyRecharge(float enrech);
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 3615f5d

Please sign in to comment.