diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 0d2b1f3506..d1d4a89bb9 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -727,13 +727,18 @@ SET(LIBPYTHON SET(LIBCOMPONENT src/components/component.cpp + src/components/dummy_component.cpp src/components/component_utils src/components/energy_consumer.cpp src/components/energy_container.cpp src/components/reactor.cpp + src/components/afterburner.cpp + src/components/afterburner_upgrade.cpp src/components/cloak.cpp + src/components/drive.cpp + src/components/drive_upgrade.cpp src/components/ftl_drive.cpp src/components/jump_drive.cpp ) @@ -1753,6 +1758,8 @@ IF (USE_GTEST) src/exit_unit_tests.cpp src/components/tests/energy_container_tests.cpp src/components/tests/balancing_tests.cpp + src/components/tests/drive_tests.cpp + src/components/tests/afterburner_tests.cpp src/components/tests/jump_drive_tests.cpp ) diff --git a/engine/objconv/basemaker/base_maker.cpp b/engine/objconv/basemaker/base_maker.cpp index 693d3b2eba..0b449932ea 100644 --- a/engine/objconv/basemaker/base_maker.cpp +++ b/engine/objconv/basemaker/base_maker.cpp @@ -2166,8 +2166,8 @@ int main(int argc, char **argv) { Base::CurrentBase = NULL; glutInit(&argc, argv); glutInitWindowSize(800, 600); - g_game.x_resolution = 800; - g_game.y_resolution = 600; + g_game.x_resolution = 1920; + g_game.y_resolution = 1080; glutInitWindowPosition(0, 0); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutCreateWindow("Vega Strike Base Maker"); diff --git a/engine/src/cmd/ai/aggressive.cpp b/engine/src/cmd/ai/aggressive.cpp index 0a71ff1d5d..d7191044e8 100644 --- a/engine/src/cmd/ai/aggressive.cpp +++ b/engine/src/cmd/ai/aggressive.cpp @@ -307,7 +307,7 @@ bool AggressiveAI::ExecuteLogicItem(const AIEvents::AIEvresult &item) { } bool AggressiveAI::ProcessLogicItem(const AIEvents::AIEvresult &item) { - float value = 0.0; + double value = 0.0; switch (abs(item.type)) { case DISTANCE: @@ -317,11 +317,11 @@ bool AggressiveAI::ProcessLogicItem(const AIEvents::AIEvresult &item) { Unit *targ = parent->Target(); if (targ) { Vector PosDifference = targ->Position().Cast() - parent->Position().Cast(); - float pdmag = PosDifference.Magnitude(); + double pdmag = PosDifference.Magnitude(); value = (pdmag - parent->rSize() - targ->rSize()); - float myvel = PosDifference.Dot(parent->GetVelocity() - targ->GetVelocity()) / value; ///pdmag; + double myvel = PosDifference.Dot(parent->GetVelocity() - targ->GetVelocity()) / value; ///pdmag; if (myvel > 0) { - value -= myvel * myvel / (2 * (parent->limits.retro / parent->getMass())); + value -= myvel * myvel / (2 * (parent->drive.retro / parent->getMass())); } } else { value = 10000; @@ -1727,7 +1727,7 @@ void AggressiveAI::Execute() { mag = 1 / mag; } parent->SetVelocity( - parent->GetVelocity() * (mag * parent->GetComputerData().max_speed() / getTimeCompression())); + parent->GetVelocity() * (mag * parent->MaxSpeed() / getTimeCompression())); parent->NetLocalForce = parent->NetForce = Vector(0, 0, 0); } target = parent->Target(); diff --git a/engine/src/cmd/ai/fire.cpp b/engine/src/cmd/ai/fire.cpp index 9adbd18edf..686003b457 100644 --- a/engine/src/cmd/ai/fire.cpp +++ b/engine/src/cmd/ai/fire.cpp @@ -110,11 +110,11 @@ bool FireAt::PursueTarget(Unit *un, bool leader) { bool CanFaceTarget(Unit *su, Unit *targ, const Matrix &matrix) { return true; - float limitmin = su->limits.limitmin; + float limitmin = su->limit_min; if (limitmin > -.99) { QVector pos = (targ->Position() - su->Position()).Normalize(); QVector pnorm = pos.Cast(); - Vector structurelimits = su->limits.structurelimits; + Vector structurelimits = su->structure_limits; Vector worldlimit = TransformNormal(matrix, structurelimits); if (pnorm.Dot(worldlimit) < limitmin) { return false; diff --git a/engine/src/cmd/ai/flybywire.cpp b/engine/src/cmd/ai/flybywire.cpp index a7af62bfe8..c2faba1fb0 100644 --- a/engine/src/cmd/ai/flybywire.cpp +++ b/engine/src/cmd/ai/flybywire.cpp @@ -192,16 +192,16 @@ FlyByWire::FlyByWire() : MatchVelocity(Vector(0, 0, 0), Vector(0, 0, 0), true, f } void FlyByWire::Stop(float per) { - SetDesiredVelocity(Vector(0, 0, per * parent->GetComputerData().max_speed()), true); + SetDesiredVelocity(Vector(0, 0, per * parent->MaxSpeed()), true); - parent->GetComputerData().set_speed = per * parent->GetComputerData().max_speed(); + parent->GetComputerData().set_speed = per * parent->MaxSpeed(); } void FlyByWire::Right(float per) { desired_ang_velocity += (-per * (per - > 0 ? parent->GetComputerData().max_yaw_left : parent->GetComputerData().max_yaw_right) + > 0 ? parent->drive.max_yaw_left : parent->drive.max_yaw_right) / getTimeCompression()) * Vector( 0, 1, @@ -212,7 +212,7 @@ void FlyByWire::Up(float per) { desired_ang_velocity += (-per * (per - > 0 ? parent->GetComputerData().max_pitch_down : parent->GetComputerData().max_pitch_up) + > 0 ? parent->drive.max_pitch_down : parent->drive.max_pitch_up) / getTimeCompression()) * Vector( 1, 0, @@ -223,7 +223,7 @@ void FlyByWire::RollRight(float per) { desired_ang_velocity += (-per * (per - > 0 ? parent->GetComputerData().max_roll_left : parent->GetComputerData().max_roll_right) + > 0 ? parent->drive.max_roll_left : parent->drive.max_roll_right) / getTimeCompression()) * Vector( 0, 0, @@ -235,9 +235,9 @@ void FlyByWire::Afterburn(float per) { afterburn = (per > .1); if (!sheltonslide && !inertial_flight_model) { - desired_velocity = Vector(0, 0, cpu->set_speed + per * (cpu->max_ab_speed() - cpu->set_speed)); + desired_velocity = Vector(0, 0, cpu->set_speed + per * (parent->MaxAfterburnerSpeed() - cpu->set_speed)); } else if (inertial_flight_model) { - DirectThrust += Vector(0, 0, parent->limits.afterburn * per); + DirectThrust += Vector(0, 0, parent->afterburner.thrust * per); } if (parent == _Universe->AccessCockpit()->GetParent()) { //printf("afterburn is %d\n",afterburn); // DELETEME WTF all this force feedback code and its unused. @@ -254,22 +254,22 @@ void FlyByWire::MatchSpeed(const Vector &vec) { Computer *cpu = &parent->GetComputerData(); cpu->set_speed = (vec).Magnitude(); - if (cpu->set_speed > cpu->max_speed()) { - cpu->set_speed = cpu->max_speed(); + if (cpu->set_speed > parent->MaxSpeed()) { + cpu->set_speed = parent->MaxSpeed(); } } void FlyByWire::Accel(float per) { Computer *cpu = &parent->GetComputerData(); - cpu->set_speed += per * cpu->max_speed() * simulation_atom_var; //SIMULATION_ATOM? - if (cpu->set_speed > cpu->max_speed()) { - cpu->set_speed = cpu->max_speed(); + cpu->set_speed += per * parent->MaxSpeed() * simulation_atom_var; //SIMULATION_ATOM? + if (cpu->set_speed > parent->MaxSpeed()) { + cpu->set_speed = parent->MaxSpeed(); } static float reverse_speed_limit = XMLSupport::parse_float(vs_config->getVariable("physics", "reverse_speed_limit", "1.0")); - if (cpu->set_speed < -cpu->max_speed() * reverse_speed_limit) { - cpu->set_speed = -cpu->max_speed() * reverse_speed_limit; + if (cpu->set_speed < -parent->MaxSpeed() * reverse_speed_limit) { + cpu->set_speed = -parent->MaxSpeed() * reverse_speed_limit; } afterburn = false; @@ -279,30 +279,30 @@ void FlyByWire::Accel(float per) { #define FBWABS(m) (m >= 0 ? m : -m) void FlyByWire::ThrustRight(float percent) { - DesiredShiftVelocity.i = parent->GetComputerData().max_speed() * percent; + DesiredShiftVelocity.i = parent->MaxSpeed() * percent; } void FlyByWire::ThrustUp(float percent) { - DesiredShiftVelocity.j = parent->GetComputerData().max_speed() * percent; + DesiredShiftVelocity.j = parent->MaxSpeed() * percent; } void FlyByWire::ThrustFront(float percent) { - DesiredShiftVelocity.k = parent->GetComputerData().max_speed() * percent; + DesiredShiftVelocity.k = parent->MaxSpeed() * percent; } void FlyByWire::DirectThrustRight(float percent) { - DirectThrust.i = parent->limits.lateral * percent; + DirectThrust.i = parent->drive.lateral * percent; } void FlyByWire::DirectThrustUp(float percent) { - DirectThrust.j = parent->limits.vertical * percent; + DirectThrust.j = parent->drive.vertical * percent; } void FlyByWire::DirectThrustFront(float percent) { if (percent > 0) { - DirectThrust.k = parent->limits.forward * percent; + DirectThrust.k = parent->drive.forward * percent; } else { - DirectThrust.k = parent->limits.retro * percent; + DirectThrust.k = parent->drive.retro * percent; } } @@ -312,8 +312,8 @@ void FlyByWire::Execute() { if (!inertial_flight_model) { //Must translate the thrust values to velocities, which is somewhat cumbersome. Vector Limit( - parent->limits.lateral, parent->limits.vertical, - ((DirectThrust.k > 0) ? parent->limits.forward : parent->limits.retro) + parent->drive.lateral, parent->drive.vertical, + ((DirectThrust.k > 0) ? parent->drive.forward : parent->drive.retro) ); if (Limit.i <= 1) { Limit.i = 1; @@ -330,7 +330,7 @@ void FlyByWire::Execute() { DirectThrust.k / Limit.k ); //Now, scale so that maximum shift velocity is max_speed - DesiredDrift *= parent->GetComputerData().max_speed(); + DesiredDrift *= parent->MaxSpeed(); //And apply DesiredShiftVelocity += DesiredDrift; } diff --git a/engine/src/cmd/ai/flyjoystick.cpp b/engine/src/cmd/ai/flyjoystick.cpp index a7134ed885..fbf92af001 100644 --- a/engine/src/cmd/ai/flyjoystick.cpp +++ b/engine/src/cmd/ai/flyjoystick.cpp @@ -233,7 +233,7 @@ void FlyByJoystick::Execute() { float(expamountc * (exp(expfactorc * axis_value) - 1) / norm + pamountc * pow(axis_value, pfactorc)); } - cpu->set_speed = axis_value * cpu->max_speed(); + cpu->set_speed = axis_value * parent->MaxSpeed(); desired_velocity = Vector(0, 0, cpu->set_speed); } } diff --git a/engine/src/cmd/ai/hard_coded_scripts.cpp b/engine/src/cmd/ai/hard_coded_scripts.cpp index 1c73d5b3f0..82e4a5cd1d 100644 --- a/engine/src/cmd/ai/hard_coded_scripts.cpp +++ b/engine/src/cmd/ai/hard_coded_scripts.cpp @@ -235,7 +235,7 @@ void BarrelRoll(Order *aisc, Unit *un) { bool afterburn = useAfterburner(); broll->MatchSpeed(Vector(0, 0, - afterburn ? un->GetComputerData().max_ab_speed() : un->GetComputerData().max_speed())); + afterburn ? un->MaxAfterburnerSpeed() : un->MaxSpeed())); broll->Afterburn(afterburn); } @@ -246,7 +246,7 @@ static void EvadeWavy(Order *aisc, Unit *un, bool updown, bool ab) { bool afterburn = ab && useAfterburner(); broll->MatchSpeed(Vector(0, 0, - afterburn ? un->GetComputerData().max_ab_speed() : un->GetComputerData().max_speed())); + afterburn ? un->MaxAfterburnerSpeed() : un->MaxSpeed())); broll->Afterburn(afterburn); } @@ -330,11 +330,10 @@ class LoopAround : public Orders::FaceTargetITTS { Vector r = targ->cumulative_transformation_matrix.getR(); bool afterburn = useAfterburner() && this->afterburn; bool ab_needed = - force_afterburn || targ->GetVelocity().MagnitudeSquared() > parent->GetComputerData().max_speed(); + force_afterburn || targ->GetVelocity().MagnitudeSquared() > parent->MaxSpeed(); m.SetDesiredVelocity(Vector(0, 0, afterburn - && ab_needed ? parent->GetComputerData().max_ab_speed() - : parent->GetComputerData(). - max_speed()), true); + && ab_needed ? parent->MaxAfterburnerSpeed() + : parent->MaxSpeed()), true); float spseed, grange = 0, mrange = 0; parent->getAverageGunSpeed(spseed, grange, mrange); if (r.Dot(relloc) < 0) { @@ -429,7 +428,7 @@ class LoopAroundAgro : public Orders::FaceTargetITTS { Vector r = targ->cumulative_transformation_matrix.getR(); bool afterburn = useAfterburner() && this->afterburn; bool ab_needed = - force_afterburn || targ->GetVelocity().MagnitudeSquared() > parent->GetComputerData().max_speed(); + force_afterburn || targ->GetVelocity().MagnitudeSquared() > parent->MaxSpeed(); if (r.Dot(relloc) < 0) { FaceTargetITTS::Execute(); m.SetAfterburn(afterburn && ab_needed); @@ -530,11 +529,10 @@ class FacePerpendicular : public Orders::FaceTargetITTS { Vector r = targ->cumulative_transformation_matrix.getR(); bool afterburn = useAfterburner() && this->afterburn; bool ab_needed = - force_afterburn || targ->GetVelocity().MagnitudeSquared() > parent->GetComputerData().max_speed(); + force_afterburn || targ->GetVelocity().MagnitudeSquared() > parent->MaxSpeed(); m.SetDesiredVelocity(Vector(0, 0, afterburn - && ab_needed ? parent->GetComputerData().max_ab_speed() - : parent->GetComputerData(). - max_speed()), true); + && ab_needed ? parent->MaxAfterburnerSpeed() + : parent->MaxSpeed()), true); float speed, grange = 0, mrange = 0; parent->getAverageGunSpeed(speed, grange, mrange); if (r.Dot(relloc) < 0) { @@ -585,7 +583,7 @@ void RollLeft(Order *aisc, Unit *un) { if (un->aistate) { AddOrd(un->aistate, un, - new Orders::ExecuteFor(new Orders::MatchRoll(un->GetComputerData().max_roll_right, false), 1.0f)); + new Orders::ExecuteFor(new Orders::MatchRoll(un->drive.max_roll_right, false), 1.0f)); } } @@ -593,7 +591,7 @@ void RollRight(Order *aisc, Unit *un) { if (un->aistate) { AddOrd(un->aistate, un, - new Orders::ExecuteFor(new Orders::MatchRoll(-un->GetComputerData().max_roll_left, false), 1.0f)); + new Orders::ExecuteFor(new Orders::MatchRoll(-un->drive.max_roll_left, false), 1.0f)); } } @@ -602,7 +600,7 @@ void RollLeftHard(Order *aisc, Unit *un) { if (un->aistate) { AddOrd(un->aistate, un, - new Orders::ExecuteFor(new Orders::MatchRoll(un->GetComputerData().max_roll_right, false), durvar)); + new Orders::ExecuteFor(new Orders::MatchRoll(un->drive.max_roll_right, false), durvar)); } } @@ -611,7 +609,7 @@ void RollRightHard(Order *aisc, Unit *un) { if (un->aistate) { AddOrd(un->aistate, un, - new Orders::ExecuteFor(new Orders::MatchRoll(-un->GetComputerData().max_roll_left, false), durvar)); + new Orders::ExecuteFor(new Orders::MatchRoll(-un->drive.max_roll_left, false), durvar)); } } diff --git a/engine/src/cmd/ai/navigation.cpp b/engine/src/cmd/ai/navigation.cpp index 5e75f06f73..b4e424f210 100644 --- a/engine/src/cmd/ai/navigation.cpp +++ b/engine/src/cmd/ai/navigation.cpp @@ -171,10 +171,10 @@ bool MoveToParent::Execute(Unit *parent, const QVector &targetlocation) { last_velocity = local_vel; Vector heading = parent->ToLocalCoordinates((targetlocation - parent->Position()).Cast()); - Vector thrust(parent->limits.lateral, parent->limits.vertical, - afterburn ? parent->limits.afterburn : parent->limits.forward); + Vector thrust(parent->drive.lateral, parent->drive.vertical, + afterburn ? parent->afterburner.thrust : parent->drive.forward); float max_speed = - (afterburn ? parent->GetComputerData().max_ab_speed() : parent->GetComputerData().max_speed()); + (afterburn ? parent->MaxAfterburnerSpeed() : parent->MaxSpeed()); Vector normheading = heading; normheading.Normalize(); Vector max_velocity = max_speed * normheading; @@ -222,18 +222,18 @@ bool MoveToParent::Execute(Unit *parent, const QVector &targetlocation) { } //start with Forward/Reverse: float t = - CalculateDecelTime(heading.k, last_velocity.k, thrust.k, parent->limits.retro / div, parent->getMass()); + CalculateDecelTime(heading.k, last_velocity.k, thrust.k, parent->drive.retro / div, parent->getMass()); if (t < THRESHOLD) { thrust.k = - (thrust.k > 0 ? -parent->limits.retro - / div : (afterburn ? parent->limits.afterburn / div : parent->limits.forward / div)); + (thrust.k > 0 ? -parent->drive.retro + / div : (afterburn ? parent->afterburner.thrust / div : parent->drive.forward / div)); } else if (t < simulation_atom_var) { thrust.k *= t / simulation_atom_var; thrust.k += (simulation_atom_var - t) - * (thrust.k > 0 ? -parent->limits.retro - / div : (afterburn ? parent->limits.afterburn / div : parent->limits.forward / div)) + * (thrust.k > 0 ? -parent->drive.retro + / div : (afterburn ? parent->afterburner.thrust / div : parent->drive.forward / div)) / simulation_atom_var; } OptimizeSpeed(parent, last_velocity.k, thrust.k, max_velocity.k / vdiv); @@ -349,7 +349,7 @@ void ChangeHeading::Execute() { bool cheater = false; static float min_for_no_oversteer = XMLSupport::parse_float(vs_config->getVariable("AI", "min_angular_accel_cheat", "50")); - if (AICheat && ((parent->limits.yaw + parent->limits.pitch) * 180 / (PI * parent->getMass()) > min_for_no_oversteer) + if (AICheat && ((parent->drive.yaw + parent->drive.pitch) * 180 / (PI * parent->getMass()) > min_for_no_oversteer) && !parent->isSubUnit()) { if (xswitch || yswitch) { Vector P, Q, R; @@ -388,7 +388,7 @@ void ChangeHeading::Execute() { if (done /*||(xswitch&&yswitch)*/) { return; } - Vector torque(parent->limits.pitch, parent->limits.yaw, 0); //set torque to max accel in any direction + Vector torque(parent->drive.pitch, parent->drive.yaw, 0); //set torque to max accel in any direction if (terminatingX > switchbacks && terminatingY > switchbacks) { if (Done(local_velocity)) { if (this->terminating) { @@ -404,14 +404,14 @@ void ChangeHeading::Execute() { TurnToward(atan2(local_heading.j, local_heading.k), local_velocity.i, torque.i); //find angle away from axis 0,0,1 in yz plane - OptimizeAngSpeed(turningspeed * parent->GetComputerData().max_pitch_down, - turningspeed * parent->GetComputerData().max_pitch_up, + OptimizeAngSpeed(turningspeed * parent->drive.max_pitch_down, + turningspeed * parent->drive.max_pitch_up, local_velocity.i, torque.i); TurnToward(atan2(local_heading.i, local_heading.k), -local_velocity.j, torque.j); torque.j = -torque.j; - OptimizeAngSpeed(turningspeed * parent->GetComputerData().max_yaw_left, - turningspeed * parent->GetComputerData().max_yaw_right, + OptimizeAngSpeed(turningspeed * parent->drive.max_yaw_left, + turningspeed * parent->drive.max_yaw_right, local_velocity.j, torque.j); torque.k = -parent->GetMoment() * local_velocity.k / simulation_atom_var; //try to counteract roll; @@ -506,9 +506,8 @@ void AutoLongHaul::MakeLinearVelocityOrder() { XMLSupport::parse_float(vs_config->getVariable("auto_physics", "auto_docking_speed_boost", "20")); float speed = - parent->GetComputerData().combat_mode ? parent->GetComputerData().max_combat_speed - : parent->GetComputerData(). - max_combat_ab_speed /*won't do insanity flight mode + spec = ludicrous speed*/; + parent->GetComputerData().combat_mode ? parent->drive.speed + : parent->afterburner.speed /*won't do insanity flight mode + spec = ludicrous speed*/; if (inside_landing_zone) { speed *= combat_mode_mult; } @@ -568,7 +567,7 @@ bool useJitteryAutopilot(Unit *parent, Unit *target, float minaccel) { if (parent->computer.combat_mode == false) { return true; } - float maxspeed = parent->GetComputerData().max_combat_ab_speed; + float maxspeed = parent->afterburner.speed; static float accel_auto_limit = XMLSupport::parse_float(vs_config->getVariable("physics", "max_accel_for_smooth_autopilot", "10")); static float speed_auto_limit = @@ -587,7 +586,7 @@ bool AutoLongHaul::InsideLandingPort(const Unit *obstacle) const { XMLSupport::parse_float(vs_config->getVariable("physics", "auto_landing_port_unclamped_seconds", "120")); return UnitUtil::getSignificantDistance(parent, obstacle) - < -landing_port_limit * parent->GetComputerData().max_combat_ab_speed; + < -landing_port_limit * parent->afterburner.speed; } void AutoLongHaul::Execute() { @@ -683,15 +682,15 @@ void AutoLongHaul::Execute() { if (parent->graphicOptions.InWarp == 0 && parent->graphicOptions.RampCounter == 0) { deactivatewarp = false; } - float mass = parent->getMass(); - float minaccel = - mymin(parent->limits.lateral, - mymin(parent->limits.vertical, mymin(parent->limits.forward, parent->limits.retro))); + double mass = parent->getMass(); + double minaccel = + mymin(parent->drive.lateral, + mymin(parent->drive.vertical, mymin(parent->drive.forward, parent->drive.retro))); if (mass) { minaccel /= mass; } QVector cfacing = parent->cumulative_transformation_matrix.getR(); //velocity.Cast(); - float speed = cfacing.Magnitude(); + double speed = cfacing.Magnitude(); if (StraightToTarget && useJitteryAutopilot(parent, target, minaccel)) { if (speed > .01) { cfacing = cfacing * (1. / speed); @@ -709,8 +708,8 @@ void AutoLongHaul::Execute() { if (parent->GetMaxWarpFieldStrength() < min_warpfield_to_enter_warp) { deactivatewarp = true; } - float maxspeed = - mymax(speed, parent->graphicOptions.WarpFieldStrength * parent->GetComputerData().max_combat_ab_speed); + double maxspeed = + mymax(speed, parent->graphicOptions.WarpFieldStrength * parent->afterburner.speed); double dis = UnitUtil::getSignificantDistance(parent, target); float time_to_destination = dis / maxspeed; @@ -749,10 +748,10 @@ void AutoLongHaul::Execute() { static bool do_auto_finish = XMLSupport::parse_bool(vs_config->getVariable("physics", "autopilot_terminate", "true")); bool stopnow = false; - maxspeed = parent->GetComputerData().max_combat_ab_speed; - if (maxspeed && parent->limits.retro) { - float time_to_destination = dis / maxspeed; //conservative - float time_to_stop = speed * mass / parent->limits.retro; + maxspeed = parent->afterburner.speed; + if (maxspeed && parent->drive.retro) { + double time_to_destination = dis / maxspeed; //conservative + double time_to_stop = speed * mass / parent->drive.retro; if (time_to_destination <= time_to_stop) { stopnow = true; } diff --git a/engine/src/cmd/ai/script.cpp b/engine/src/cmd/ai/script.cpp index 33849ff00c..6bba7d9564 100644 --- a/engine/src/cmd/ai/script.cpp +++ b/engine/src/cmd/ai/script.cpp @@ -810,19 +810,19 @@ void AIScript::LoadXML() { % parent->GetComputerData().threatlevel)); } if (_Universe->isPlayerStarship(parent->Target())) { - float value; - static float game_speed = XMLSupport::parse_float(vs_config->getVariable("physics", "game_speed", "1")); - static float game_accel = XMLSupport::parse_float(vs_config->getVariable("physics", "game_accel", "1")); + double value; + static const double game_speed = configuration()->physics_config.game_speed; + static const double game_accel = configuration()->physics_config.game_accel; { Unit *targ = parent->Target(); if (targ) { Vector PosDifference = (targ->Position() - parent->Position()).Cast(); - float pdmag = PosDifference.Magnitude(); + double pdmag = PosDifference.Magnitude(); value = (pdmag - parent->rSize() - targ->rSize()); - float myvel = + double myvel = pdmag > 0 ? PosDifference.Dot(parent->GetVelocity() - targ->GetVelocity()) / pdmag : 0; if (myvel > 0) { - value -= myvel * myvel / (2 * (parent->limits.retro / parent->getMass())); + value -= myvel * myvel / (2 * (parent->drive.retro / parent->getMass())); } } else { value = 10000; @@ -833,7 +833,7 @@ void AIScript::LoadXML() { UniverseUtil::IOmessage(0, parent->name, "all", string("using script ") + string( filename) + " threat " + XMLSupport::tostring( parent->GetComputerData().threatlevel) + " dis " - + XMLSupport::tostring(value)); + + std::to_string(value)); } } return; diff --git a/engine/src/cmd/ai/warpto.cpp b/engine/src/cmd/ai/warpto.cpp index 4ba894886f..e041070bed 100644 --- a/engine/src/cmd/ai/warpto.cpp +++ b/engine/src/cmd/ai/warpto.cpp @@ -44,7 +44,7 @@ bool DistanceWarrantsWarpTo(Unit *parent, float dist, bool following) { float toodamnclose = following ? tooclosefollowing : tooclose; float diff = 1; parent->GetVelocityDifficultyMult(diff); - float timetolive = dist / (diff * parent->GetComputerData().max_combat_speed); + float timetolive = dist / (diff * parent->drive.speed); if (timetolive > (5 * max_allowable_travel_time())) { return true; } else if (timetolive > (max_allowable_travel_time())) { @@ -69,7 +69,7 @@ bool DistanceWarrantsTravelTo(Unit *parent, float dist, bool following) { //first let us decide whether the target is far enough to warrant using warp float diff = 1; parent->GetVelocityDifficultyMult(diff); - float timetolive = dist / (diff * parent->GetComputerData().max_combat_speed); + float timetolive = dist / (diff * parent->drive.speed); if (timetolive > max_allowable_travel_time()) { return true; } diff --git a/engine/src/cmd/basecomputer.cpp b/engine/src/cmd/basecomputer.cpp index a292b38039..bc97fe3835 100644 --- a/engine/src/cmd/basecomputer.cpp +++ b/engine/src/cmd/basecomputer.cpp @@ -62,10 +62,9 @@ using VSFileSystem::SaveFile; #include "facet_configuration.h" #include "vs_logging.h" #include "controls_factory.h" +#include "configuration/configuration.h" #include "python/base_computer/ship_view.h" - - //for directory thing #if defined (_WIN32) && !defined (__CYGWIN__) #ifndef NOMINMAX @@ -3942,7 +3941,9 @@ string buildUpgradeDescription(Cargo &item) { current_unit_load_mode = DEFAULT; string str = ""; str += item.GetDescription(); + showUnitStats(newPart, str, 0, 1, item); + newPart->Kill(); // delete newPart; return str; @@ -4633,8 +4634,6 @@ static const char *WeaponTypeStrings[] = { void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, Cargo &item) { 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 shield_maintenance_cost = XMLSupport::parse_float(vs_config->getVariable("physics", "shield_maintenance_charge", ".25")); static bool shields_require_power = @@ -4644,7 +4643,6 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C static float shieldenergycap = XMLSupport::parse_float(vs_config->getVariable("physics", "shield_energy_capacitance", ".2")); - float Wconv = warpenratio == 0.0 ? 0.0 : (1.0 / warpenratio); //converts from reactor to warp energy scales char conversionBuffer[128]; string prefix = ""; for (int i = 0; i < subunitlevel; i++) { @@ -4654,7 +4652,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C static float kj_per_unit_damage = XMLSupport::parse_float(vs_config->getVariable("physics", "kilojoules_per_unit_damage", "5400")); float VSDM = kj_per_unit_damage / 1000.0; - float RSconverter = 100; //100MJ per reactor or shield recharge energy unit + float RSconverter = configuration()->fuel.megajoules_factor; //100MJ per reactor or shield recharge energy unit float totalWeaponEnergyUsage = 0; float totalWeaponDamage = 0; string MPLdesc = ""; @@ -4744,36 +4742,26 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C } } } - //following lines somewhat borken in terms of semantics for quantity of fuel - //and policy of upgrades to fuel - if (mode && blankUnit->fuelData() != playerUnit->fuelData()) { - switch (replacement_mode) { - case 0: //Replacement or new Module - break; - case 1: //Additive - PRETTY_ADDU(statcolor + "Adds #-c", - playerUnit->fuelData(), - 2, - "metric tons of Lithium-6 " /*+statcolor+"to Fuel Capacity #-c"*/ ); - break; - case 2: //multiplicative - break; - default: //Failure - text += "Oh dear, this wasn't an upgrade. Please debug code."; - break; - } - } + + const Computer &uc = playerUnit->ViewComputerData(); const Computer &buc = blankUnit->ViewComputerData(); - - if (playerUnit->limits.yaw == playerUnit->limits.pitch && playerUnit->limits.yaw == playerUnit->limits.roll) { - prettyPrintFloat(conversionBuffer, playerUnit->limits.yaw + if (!mode) { + text += "#n##n#" + prefix + "#c0:1:.5#[FLIGHT CHARACTERISTICS]#n##-c"; + text += "#n#" + prefix + statcolor + "Turning response: #-c"; + } + if (playerUnit->drive.yaw.MaxValue() == playerUnit->drive.pitch.MaxValue() && + playerUnit->drive.yaw.MaxValue() == playerUnit->drive.roll.MaxValue()) { + prettyPrintFloat(conversionBuffer, playerUnit->drive.yaw / ((playerUnit->GetMoment() != 0) ? playerUnit->GetMoment() : 1), 0, 4); - if (mode && MODIFIES(replacement_mode, playerUnit, blankUnit, limits.yaw)) { + if (!mode) { + text += conversionBuffer; + text += " radians/second^2#n#" + expstatcolor + " (yaw, pitch, roll)#-c"; + } else if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.yaw)) { switch (replacement_mode) { case 0: //Replacement or new Module PRETTY_ADDU(statcolor + "#n#Installs maneuvering jets with turning response #-c", - playerUnit->limits.yaw, + playerUnit->drive.yaw, 0, " radians/second^2#n#" + statcolor + " (yaw, pitch, roll)#-c"); break; @@ -4781,7 +4769,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C break; case 2: //multiplicative PRETTY_ADDU(statcolor + "#n#Increases turning response by #-c", - 100.0 * ((playerUnit->limits.yaw * 180 / PI) - 1), + 100.0 * ((playerUnit->drive.yaw * 180 / PI) - 1), 0, "%#n#" + statcolor + " (yaw, pitch, roll)#-c"); break; @@ -4791,30 +4779,30 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C } } } else { - if (mode && (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.yaw) - || MODIFIES(replacement_mode, playerUnit, blankUnit, limits.pitch) - || MODIFIES(replacement_mode, playerUnit, blankUnit, limits.roll))) { + if (mode && (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.yaw) + || MODIFIES(replacement_mode, playerUnit, blankUnit, drive.pitch) + || MODIFIES(replacement_mode, playerUnit, blankUnit, drive.roll))) { switch (replacement_mode) { case 0: //Replacement or new Module text += "#n#Replaces existing maneuvering system with one rated at: #-c#n#"; - PRETTY_ADDN(substatcolor + "Yaw #-c", playerUnit->limits.yaw, 2); - PRETTY_ADDN(substatcolor + " Pitch #-c", playerUnit->limits.pitch, 2); - PRETTY_ADDN(substatcolor + " Roll #-c", playerUnit->limits.roll, 2); + PRETTY_ADDN(substatcolor + "Yaw #-c", playerUnit->drive.yaw, 2); + PRETTY_ADDN(substatcolor + " Pitch #-c", playerUnit->drive.pitch, 2); + PRETTY_ADDN(substatcolor + " Roll #-c", playerUnit->drive.roll, 2); text += " metric-ton*radians/second^2"; break; case 1: //Additive text += "#n#Upgrades existing maneuvering system by the following amounts: #-c#n#"; - PRETTY_ADDN(substatcolor + "Yaw #-c", playerUnit->limits.yaw, 2); - PRETTY_ADDN(substatcolor + " Pitch #-c", playerUnit->limits.pitch, 2); - PRETTY_ADDN(substatcolor + " Roll #-c", playerUnit->limits.roll, 2); + PRETTY_ADDN(substatcolor + "Yaw #-c", playerUnit->drive.yaw, 2); + PRETTY_ADDN(substatcolor + " Pitch #-c", playerUnit->drive.pitch, 2); + PRETTY_ADDN(substatcolor + " Roll #-c", playerUnit->drive.roll, 2); text += " metric-ton*radians/second^2"; break; case 2: //multiplicative text += "#n#Increases performance of existing maneuvering system by the following percentages: #-c#n#"; - PRETTY_ADDN(substatcolor + "Yaw #-c", 100.0 * ((playerUnit->limits.yaw * 180 / PI) - 1), 0); - PRETTY_ADDN(substatcolor + " Pitch #-c", 100.0 * ((playerUnit->limits.pitch * 180 / PI) - 1), 0); - PRETTY_ADDN(substatcolor + " Roll #-c", 100.0 * ((playerUnit->limits.roll * 180 / PI) - 1), 0); + PRETTY_ADDN(substatcolor + "Yaw #-c", 100.0 * ((playerUnit->drive.yaw * 180 / PI) - 1), 0); + PRETTY_ADDN(substatcolor + " Pitch #-c", 100.0 * ((playerUnit->drive.pitch * 180 / PI) - 1), 0); + PRETTY_ADDN(substatcolor + " Roll #-c", 100.0 * ((playerUnit->drive.roll * 180 / PI) - 1), 0); break; default: //Failure text += "Oh dear, this wasn't an upgrade. Please debug code."; @@ -4826,97 +4814,97 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C if (mode) { switch (replacement_mode) { case 0: //Replacement or new Module - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.forward)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.forward)) { PRETTY_ADDU(statcolor + "Provides forward thrust rated at: #-c", - playerUnit->limits.forward / 1000.0, + playerUnit->drive.forward / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.retro)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.retro)) { PRETTY_ADDU(statcolor + "Provides aftward thrust rated at: #-c", - playerUnit->limits.retro / 1000.0, + playerUnit->drive.retro / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.vertical)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.vertical)) { PRETTY_ADDU(statcolor + "Provides vertical thrust rated at: #-c", - playerUnit->limits.vertical / 1000.0, + playerUnit->drive.vertical / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.lateral)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.lateral)) { PRETTY_ADDU(statcolor + "Provides lateral thrust rated at: #-c", - playerUnit->limits.lateral / 1000.0, + playerUnit->drive.lateral / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.afterburn)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, afterburner.thrust)) { PRETTY_ADDU(statcolor + "Overdrive thrust rated at: #-c", - playerUnit->limits.afterburn / 1000.0, + playerUnit->afterburner.thrust / 1000.0, 2, "MegaNewtons"); } break; case 1: //Additive - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.forward)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.forward)) { PRETTY_ADDU(statcolor + "Increases forward thrust rating by: #-c", - playerUnit->limits.forward / 1000.0, + playerUnit->drive.forward / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.retro)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.retro)) { PRETTY_ADDU(statcolor + "Increases aftward thrust rating by: #-c", - playerUnit->limits.retro / 1000.0, + playerUnit->drive.retro / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.vertical)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.vertical)) { PRETTY_ADDU(statcolor + "Increases vertical thrust rating by: #-c", - playerUnit->limits.vertical / 1000.0, + playerUnit->drive.vertical / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.lateral)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.lateral)) { PRETTY_ADDU(statcolor + "Increases lateral thrust rating by: #-c", - playerUnit->limits.lateral / 1000.0, + playerUnit->drive.lateral / 1000.0, 2, "MegaNewtons"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.afterburn)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, afterburner.thrust)) { PRETTY_ADDU(statcolor + "Increases overdrive thrust rating by: #-c", - playerUnit->limits.afterburn / 1000.0, + playerUnit->afterburner.thrust / 1000.0, 2, "MegaNewtons"); } break; case 2: //multiplicative - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.forward)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.forward)) { PRETTY_ADDU(statcolor + "Increases forward thrust rating by: #-c", - (playerUnit->limits.forward - 1) * 100, + (playerUnit->drive.forward - 1) * 100, 0, "%"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.retro)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.retro)) { PRETTY_ADDU(statcolor + "Increases aftward thrust rating by: #-c", - (playerUnit->limits.retro - 1) * 100, + (playerUnit->drive.retro - 1) * 100, 0, "%"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.vertical)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.vertical)) { PRETTY_ADDU(statcolor + "Increases vertical thrust rating by: #-c", - (playerUnit->limits.vertical - 1) * 100, + (playerUnit->drive.vertical - 1) * 100, 0, "%"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.lateral)) { + if (MODIFIES(replacement_mode, playerUnit, blankUnit, drive.lateral)) { PRETTY_ADDU(statcolor + "Increases lateral thrust rating by: #-c", - (playerUnit->limits.lateral - 1) * 100, + (playerUnit->drive.lateral - 1) * 100, 0, "%"); } - if (MODIFIES(replacement_mode, playerUnit, blankUnit, limits.afterburn)) + if (MODIFIES(replacement_mode, playerUnit, blankUnit, afterburner.thrust)) PRETTY_ADDU(statcolor + "Overdrive thrust rating by: #-c", - (playerUnit->limits.afterburn - 1) * 100, + (playerUnit->afterburner.thrust - 1) * 100, 0, "%"); break; @@ -4925,82 +4913,9 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C break; } } - static float non_combat_mode_mult = - XMLSupport::parse_float(vs_config->getVariable("physics", "combat_speed_boost", "100")); - if (mode) { - switch (replacement_mode) { - case 0: //Replacement or new Module - if (MODIFIES(replacement_mode, &uc, &buc, max_speed())) { - PRETTY_ADDU(statcolor + "Sets max combat speed governor to: #-c", uc.max_speed(), 0, "m/s"); - PRETTY_ADDU(statcolor + "Sets max non-combat speed governor to: #-c", - uc.max_speed() * non_combat_mode_mult, 0, "m/s"); - } - if (MODIFIES(replacement_mode, &uc, &buc, max_ab_speed())) - PRETTY_ADDU(statcolor + "Sets max overdrive combat speed governor to: #-c", - uc.max_ab_speed(), - 0, - "m/s"); - break; - case 1: //Additive - if (MODIFIES(replacement_mode, &uc, &buc, max_speed())) { - PRETTY_ADDU(statcolor + "Increases max combat speed governor setting by: #-c", - uc.max_speed(), - 0, - "m/s"); - PRETTY_ADDU(statcolor + "Increases max non-combat speed governor setting by: #-c", - uc.max_speed() * non_combat_mode_mult, 0, "m/s"); - } - if (MODIFIES(replacement_mode, &uc, &buc, max_ab_speed())) - PRETTY_ADDU(statcolor + "Increases max overdrive combat speed governor setting by: #-c", - uc.max_ab_speed(), 0, "m/s"); - break; - case 2: //multiplicative - if (MODIFIES(replacement_mode, &uc, &buc, max_speed())) { - PRETTY_ADDU(statcolor + "Increases max combat speed governor settings by: #-c", - 100.0 * (uc.max_speed() - 1), 0, "%"); - PRETTY_ADDU(statcolor + "Increases max non-combat speed governor settings by: #-c", - 100.0 * (uc.max_speed() - 1), 0, "%"); - } - if (MODIFIES(replacement_mode, &uc, &buc, max_ab_speed())) - PRETTY_ADDU(statcolor + "Increases max overdrive combat speed governor settings by: #-c", - (uc.max_ab_speed() - 1) * 100, 0, "%"); - break; - default: //Failure - text += "Oh dear, this wasn't an upgrade. Please debug code."; - break; - } - } - } - if (mode && (MODIFIES(replacement_mode, &uc, &buc, max_yaw_right) - || MODIFIES(replacement_mode, &uc, &buc, max_pitch_up) - || MODIFIES(replacement_mode, &uc, &buc, max_roll_right))) { - switch (replacement_mode) { - case 0: //Replacement or new Module - text += ("#n#" + prefix + "Governor settings for maximum turn rates set to: "); - PRETTY_ADDN(substatcolor + " yaw #-c", uc.max_yaw_right, 2); - PRETTY_ADDN(substatcolor + " pitch #-c", uc.max_pitch_up, 2); - PRETTY_ADDN(substatcolor + " roll #-c", uc.max_roll_right, 2); - text += " radians/second"; - break; - case 1: //Additive - text += ("#n#" + prefix + "Governor settings for maximum turn rates increased by: "); - PRETTY_ADDN(substatcolor + " yaw #-c", uc.max_yaw_right, 2); - PRETTY_ADDN(substatcolor + " pitch #-c", uc.max_pitch_up, 2); - PRETTY_ADDN(substatcolor + " roll #-c", uc.max_roll_right, 2); - text += " radians/second"; - break; - case 2: //multiplicative - text += ("#n#" + substatcolor + "Increases governor settings for maximum turn rates by: #-c"); - PRETTY_ADDN(substatcolor + " yaw #-c", 100.0 * ((uc.max_yaw_right * 180 / PI) - 1), 0); - PRETTY_ADDN(substatcolor + " pitch #-c", 100.0 * ((uc.max_pitch_up * 180 / PI) - 1), 0); - PRETTY_ADDN(substatcolor + " roll #-c", 100.0 * ((uc.max_roll_right * 180 / PI) - 1), 0); - text += " %"; - break; - default: //Failure - text += "Oh dear, this wasn't an upgrade. Please debug code."; - break; - } + } + if (mode) { switch (replacement_mode) { case 0: //Replacement or new Module @@ -5050,26 +4965,21 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C const JumpDrive &uj = playerUnit->jump_drive; const FtlDrive &ftl = playerUnit->ftl_drive; const JumpDrive &buj = blankUnit->jump_drive; - if (mode) { - switch (replacement_mode) { - case 0: //Replacement or new Module - if (MODIFIES(replacement_mode, playerUnit, blankUnit, reactor.Capacity())) - PRETTY_ADDU(statcolor + "Installs reactor with recharge rate: #-c", - playerUnit->reactor.Capacity() * RSconverter, 0, "MJ/s"); - 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, ftl_energy.MaxLevel())) - PRETTY_ADDU(statcolor + "Installs warp capacitor bank with storage capacity: #-c", - 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; - default: //Failure - text += "Oh dear, this wasn't an upgrade. Please debug code."; - break; + + if (mode && replacement_mode == 0) { + //Replacement or new Module + if (MODIFIES(replacement_mode, playerUnit, blankUnit, reactor.Capacity())) + PRETTY_ADDU(statcolor + "Installs reactor with recharge rate: #-c", + playerUnit->reactor.Capacity() * RSconverter, 0, "MJ/s"); + 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, ftl_energy.MaxLevel())) + PRETTY_ADDU(statcolor + "Installs SPEC capacitor bank with storage capacity: #-c", + playerUnit->ftl_energy.MaxLevel() * RSconverter, 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"; } } @@ -5216,14 +5126,14 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C if (playerUnit->cloak.Capable()) { if (!mode) { PRETTY_ADDU(statcolor + "Cloaking device available, energy usage: #-c", - playerUnit->cloak.GetConsumption() * RSconverter * Wconv, + playerUnit->cloak.GetConsumption() * RSconverter, 0, "MJ/s"); } else { switch (replacement_mode) { case 0: //Replacement or new Module PRETTY_ADDU(statcolor + "Installs a cloaking device.#n# Activated energy usage: #-c", - playerUnit->cloak.GetConsumption() * RSconverter * Wconv, + playerUnit->cloak.GetConsumption() * RSconverter, 0, "MJ/s"); break; @@ -5391,7 +5301,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C maxshield = 0; } PRETTY_ADDU(statcolor + "Minimum time to reach full overthrust speed: #-c", - playerUnit->getMass() * uc.max_ab_speed() / playerUnit->limits.afterburn, 2, "seconds"); + playerUnit->getMass() * playerUnit->MaxAfterburnerSpeed() / playerUnit->afterburner.thrust, 2, "seconds"); //reactor float avail = (playerUnit->maxEnergyData() * RSconverter - maxshield * VSDM); @@ -5414,7 +5324,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C 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"; + "WARNING: SPEC capacitor banks under capacity for jump: upgrade SPEC capacitance#-c"; } if (num_shields) { diff --git a/engine/src/cmd/computer.cpp b/engine/src/cmd/computer.cpp index 1f6b662e72..83d3d5f90e 100644 --- a/engine/src/cmd/computer.cpp +++ b/engine/src/cmd/computer.cpp @@ -32,33 +32,12 @@ Computer::Computer() : NavPoint(0, 0, 0), force_velocity_ref(false), threatlevel(0), set_speed(0), - max_combat_speed(1), - max_combat_ab_speed(1), - max_yaw_left(1), - max_yaw_right(1), - max_pitch_down(1), - max_pitch_up(1), - max_roll_left(1), - max_roll_right(1), slide_start(1), slide_end(1), itts(false), combat_mode(true) { } -float Computer::max_speed() const { - static float - combat_mode_mult = XMLSupport::parse_float(vs_config->getVariable("physics", "combat_speed_boost", "100")); - return (!combat_mode) ? combat_mode_mult * max_combat_speed : max_combat_speed; -} - -float Computer::max_ab_speed() const { - static float - combat_mode_mult = XMLSupport::parse_float(vs_config->getVariable("physics", "combat_speed_boost", "100")); - //same capped big speed as combat...else different - return (!combat_mode) ? combat_mode_mult * max_combat_speed : max_combat_ab_speed; -} - Computer::RADARLIM::RADARLIM() : maxrange(0), maxcone(-1), diff --git a/engine/src/cmd/computer.h b/engine/src/cmd/computer.h index 3ad4156c02..f455d96eba 100644 --- a/engine/src/cmd/computer.h +++ b/engine/src/cmd/computer.h @@ -107,26 +107,15 @@ class Computer { float threatlevel; //The speed the flybywire system attempts to maintain float set_speed; - //Computers limitation of speed - float max_combat_speed; - float max_combat_ab_speed; - //Computer's restrictions of YPR to limit space combat maneuvers - float max_yaw_left; - float max_yaw_right; - float max_pitch_down; - float max_pitch_up; - float max_roll_left; - float max_roll_right; + //Whether or not an 'lead' indicator appears in front of target unsigned char slide_start; unsigned char slide_end; bool itts; - //tells whether the speed is clamped draconian-like or not + + // In hud - Maneuver (true) Travel (false) bool combat_mode; - float max_speed() const; - float max_ab_speed() const; - Computer(); }; diff --git a/engine/src/cmd/drawable.cpp b/engine/src/cmd/drawable.cpp index 04e20c2678..58859f15d2 100644 --- a/engine/src/cmd/drawable.cpp +++ b/engine/src/cmd/drawable.cpp @@ -436,7 +436,7 @@ void Drawable::DrawNow(const Matrix &mato, float lod) { (un)->DrawNow(submat, lod); } } - float cmas = unit->computer.max_ab_speed() * unit->computer.max_ab_speed(); + float cmas = unit->MaxAfterburnerSpeed() * unit->MaxAfterburnerSpeed(); if (cmas == 0) { cmas = 1; } @@ -724,7 +724,7 @@ void Drawable::DrawHalo(bool on_screen, float apparent_size, Matrix wmat, Cloak float maxaccel = unit->GetMaxAccelerationInDirectionOf(wmat.getR(), true); Vector velocity = unit->GetVelocity(); - float cmas = unit->computer.max_ab_speed() * unit->computer.max_ab_speed(); + float cmas = unit->MaxAfterburnerSpeed() * unit->MaxAfterburnerSpeed(); if (cmas == 0) { cmas = 1; } diff --git a/engine/src/cmd/energetic.cpp b/engine/src/cmd/energetic.cpp index a57d766ade..48dd6b7b2f 100644 --- a/engine/src/cmd/energetic.cpp +++ b/engine/src/cmd/energetic.cpp @@ -42,7 +42,6 @@ Energetic::Energetic() : constrained_charge_to_shields(0.0f), sufficient_energy_to_recharge_shields(true), - afterburnenergy(0), afterburntype(0) { } @@ -73,48 +72,10 @@ float Energetic::getFuelUsage(bool afterburner) { return configuration()->fuel.normal_fuel_usage; } -/** - * @brief Energetic::WCWarpIsFuelHack - in Wing Commander, warp and fuel are the same variable. - * Therefore, we need to transfer from one to the other to maintain equality - * @param transfer_warp_to_fuel - true means fuel = warpenergy - */ -// TODO: this is still an ugly hack -void Energetic::WCWarpIsFuelHack(bool transfer_warp_to_fuel) { - Unit *unit = vega_dynamic_cast_ptr(this); - if (!configuration()->fuel.fuel_equals_warp) { - return; - } - if (transfer_warp_to_fuel) { - unit->fuel.SetLevel(unit->ftl_energy.Level()); - } else { - unit->ftl_energy.SetLevel(unit->fuel.Level()); - } -} -float Energetic::ExpendMomentaryFuelUsage(float magnitude) { - // TODO: have this make some kind of sense to someone other than the person who wrote the comment below. - //HACK this forces the reaction to be Li-6+D fusion with efficiency governed by the getFuelUsage function - float quantity = Energetic::getFuelUsage(false) * simulation_atom_var * magnitude * - configuration()->fuel.fmec_exit_velocity_inverse / configuration()->fuel.fuel_efficiency; - return ExpendFuel(quantity); -} -/** - * @brief expendFuel - reduce fuel by burning it - * @param quantity - requested quantity to use - * @return - actual quantity used - */ -float Energetic::ExpendFuel(double quantity) { - Unit *unit = vega_dynamic_cast_ptr(this); - return quantity * unit->fuel.Deplete(true, configuration()->fuel.normal_fuel_usage * quantity); -} - -float Energetic::getWarpEnergy() const { - const Unit *unit = vega_dynamic_cast_ptr(this); - return unit->ftl_energy.Level(); -} float Energetic::maxEnergyData() const { @@ -129,9 +90,6 @@ void Energetic::rechargeEnergy() { } } -void Energetic::setAfterburnerEnergy(float aft) { - afterburnenergy = aft; -} void Energetic::setEnergyRecharge(float enrech) { Unit *unit = vega_dynamic_cast_ptr(this); @@ -139,11 +97,6 @@ void Energetic::setEnergyRecharge(float enrech) { } -float Energetic::warpCapData() const { - const Unit *unit = vega_dynamic_cast_ptr(this); - return unit->ftl_energy.MaxLevel(); -} - // Basically max or current shield x 0.2 float Energetic::totalShieldEnergyCapacitance() const { const Unit *unit = vega_dynamic_cast_ptr(this); @@ -171,6 +124,8 @@ void Energetic::ExpendEnergy(const bool player_ship) { DecreaseWarpEnergyInWarp(); unit->reactor.Generate(); + + unit->drive.Consume(); } void Energetic::ExpendEnergy(float usage) { @@ -179,18 +134,6 @@ void Energetic::ExpendEnergy(float usage) { unit->energy.Deplete(true, usage); } -// The original code was a continuation of the comment above and simply unclear. -// I replaced it with a very simple model. -void Energetic::ExpendFuel() { - Unit *unit = vega_dynamic_cast_ptr(this); - - if (!configuration()->fuel.reactor_uses_fuel) { - return; - } - - const float fuel_usage = configuration()->fuel.fmec_exit_velocity_inverse * unit->reactor.Capacity() * simulation_atom_var; - unit->fuel.Deplete(true, fuel_usage); -} void Energetic::MaintainECM() { Unit *unit = vega_dynamic_cast_ptr(this); diff --git a/engine/src/cmd/energetic.h b/engine/src/cmd/energetic.h index 0ff4b43655..d7f462b444 100644 --- a/engine/src/cmd/energetic.h +++ b/engine/src/cmd/energetic.h @@ -37,14 +37,9 @@ class Energetic { static float getFuelUsage(bool afterburner); - void WCWarpIsFuelHack(bool transfer_warp_to_fuel); - float ExpendMomentaryFuelUsage(float magnitude); - float ExpendFuel(double quantity); void ExpendEnergy(const bool player_ship); void ExpendEnergy(float usage); void ExpendEnergyToRechargeShields(); - void ExpendFuel(); - float getWarpEnergy() const; float maxEnergyData() const; @@ -55,22 +50,19 @@ class Energetic { void rechargeEnergy(); void RechargeWarpCapacitors(const bool player_ship); - void setAfterburnerEnergy(float aft); void setEnergyRecharge(float enrech); float totalShieldEnergyCapacitance() const; static float VSDPercent(); - float warpCapData() const; - float WarpEnergyMultiplier(const bool player_ship); float constrained_charge_to_shields; bool sufficient_energy_to_recharge_shields; - float afterburnenergy; //short fix + // TODO: delete one and move the other to Afterburner class int afterburntype; //0--energy, 1--fuel //-1 means it is off. -2 means it doesn't exist. otherwise it's engaged to destination (positive number) }; diff --git a/engine/src/cmd/jump_capable.cpp b/engine/src/cmd/jump_capable.cpp index 36be5dabd4..474d4a38f5 100644 --- a/engine/src/cmd/jump_capable.cpp +++ b/engine/src/cmd/jump_capable.cpp @@ -481,8 +481,8 @@ float JumpCapable::CalculateNearestWarpUnit(float minmultiplier, float JumpCapable::CourseDeviation(const Vector &OriginalCourse, const Vector &FinalCourse) const { const Unit *unit = vega_dynamic_cast_ptr(this); - if (unit->ViewComputerData().max_ab_speed() > .001) { - return (OriginalCourse - (FinalCourse)).Magnitude() / unit->ViewComputerData().max_ab_speed(); + if (unit->MaxAfterburnerSpeed() > .001) { + return (OriginalCourse - (FinalCourse)).Magnitude() / unit->MaxAfterburnerSpeed(); } else { return (FinalCourse - OriginalCourse).Magnitude(); } diff --git a/engine/src/cmd/mount.cpp b/engine/src/cmd/mount.cpp index 1fc446e494..baa158740e 100644 --- a/engine/src/cmd/mount.cpp +++ b/engine/src/cmd/mount.cpp @@ -330,8 +330,8 @@ bool Mount::PhysicsAlignedFire(Unit *caller, type->radial_speed, type->pulse_speed /*detonation_radius*/); if (!match_speed_with_target) { - temp->GetComputerData().max_combat_speed = type->speed + velocity.Magnitude(); - temp->GetComputerData().max_combat_ab_speed = type->speed + velocity.Magnitude(); + temp->drive.speed = type->speed + velocity.Magnitude(); + temp->afterburner.speed = type->speed + velocity.Magnitude(); } } else { Flightgroup *testfg = caller->getFlightgroup(); diff --git a/engine/src/cmd/movable.cpp b/engine/src/cmd/movable.cpp index d7acbde776..f420456c18 100644 --- a/engine/src/cmd/movable.cpp +++ b/engine/src/cmd/movable.cpp @@ -113,12 +113,14 @@ Vector Movable::GetNetAngularAcceleration() const { } float Movable::GetMaxAccelerationInDirectionOf(const Vector &ref, bool afterburn) const { + const Unit *unit = vega_dynamic_const_cast_ptr(this); + Vector p, q, r; GetOrientation(p, q, r); Vector lref(ref * p, ref * q, ref * r); - float tp = (lref.i == 0) ? 0 : fabs(Limits().lateral / lref.i); - float tq = (lref.j == 0) ? 0 : fabs(Limits().vertical / lref.j); - float tr = (lref.k == 0) ? 0 : fabs(((lref.k > 0) ? Limits().forward : Limits().retro) / lref.k); + float tp = (lref.i == 0) ? 0 : fabs(unit->drive.lateral.Value() / lref.i); + float tq = (lref.j == 0) ? 0 : fabs(unit->drive.vertical.Value() / lref.j); + float tr = (lref.k == 0) ? 0 : fabs(((lref.k > 0) ? unit->drive.forward.Value() : unit->drive.retro.Value()) / lref.k); float trqmin = (tr < tq) ? tr : tq; float tm = tp < trqmin ? tp : trqmin; return lref.Magnitude() * tm / Mass; @@ -154,6 +156,7 @@ void Movable::UpdatePhysics(const Transformation &trans, if (resolveforces) { //clamp velocity + // TODO: use resource class to do this more elegantly ResolveForces(trans, transmat); float velocity_max = configuration()->physics_config.velocity_max; if (Velocity.i > velocity_max) { @@ -258,6 +261,7 @@ void Movable::UpdatePhysics2(const Transformation &trans, } void Movable::Rotate(const Vector &axis) { + const Unit *unit = vega_dynamic_const_cast_ptr(this); double theta = axis.Magnitude(); double ootheta = 0; if (theta == 0) { @@ -270,10 +274,10 @@ void Movable::Rotate(const Vector &axis) { rot = identity_quaternion; } curr_physical_state.orientation *= rot; - if (limits.limitmin > -1) { + if (unit->limit_min > -1) { Matrix mat; curr_physical_state.orientation.to_matrix(mat); - if (limits.structurelimits.Dot(mat.getR()) < limits.limitmin) { + if (unit->structure_limits.Dot(mat.getR()) < unit->limit_min) { curr_physical_state.orientation = prev_physical_state.orientation; } } @@ -474,8 +478,6 @@ double Movable::GetMaxWarpFieldStrength(float rampmult) const { void Movable::FireEngines(const Vector &Direction /*unit vector... might default to "r"*/, float FuelSpeed, float FMass) { - Unit *unit = vega_dynamic_cast_ptr(this); - FMass = unit->ExpendFuel(FMass); NetForce += Direction * ((double)FuelSpeed * (double)FMass / GetElapsedTime()); } @@ -526,32 +528,30 @@ void Movable::ApplyLocalTorque(const Vector &torque) { } Vector Movable::MaxTorque(const Vector &torque) { + const Unit *unit = vega_dynamic_const_cast_ptr(this); + //torque is a normal - return torque * (Vector(copysign(limits.pitch, torque.i), - copysign(limits.yaw, torque.j), - copysign(limits.roll, torque.k)) * torque); + return torque * (Vector(copysign(unit->drive.pitch.Value(), torque.i), + copysign(unit->drive.yaw.Value(), torque.j), + copysign(unit->drive.roll.Value(), torque.k)) * torque); } Vector Movable::ClampTorque(const Vector &amt1) { Unit *unit = vega_dynamic_cast_ptr(this); Vector Res = amt1; - unit->WCWarpIsFuelHack(true); - float fuelclamp = (unit->fuel.Level() <= 0) ? configuration()->fuel.no_fuel_thrust : 1; - if (fabs(amt1.i) > fuelclamp * limits.pitch) { - Res.i = copysign(fuelclamp * limits.pitch, amt1.i); + if (fabs(amt1.i) > fuelclamp * unit->drive.pitch) { + Res.i = copysign(fuelclamp * unit->drive.pitch, amt1.i); } - if (fabs(amt1.j) > fuelclamp * limits.yaw) { - Res.j = copysign(fuelclamp * limits.yaw, amt1.j); + if (fabs(amt1.j) > fuelclamp * unit->drive.yaw) { + Res.j = copysign(fuelclamp * unit->drive.yaw, amt1.j); } - if (fabs(amt1.k) > fuelclamp * limits.roll) { - Res.k = copysign(fuelclamp * limits.roll, amt1.k); + if (fabs(amt1.k) > fuelclamp * unit->drive.roll) { + Res.k = copysign(fuelclamp * unit->drive.roll, amt1.k); } //1/5,000,000 m/s - unit->ExpendMomentaryFuelUsage(Res.Magnitude()); - unit->WCWarpIsFuelHack(false); return Res; } @@ -559,55 +559,66 @@ Vector Movable::ClampTorque(const Vector &amt1) { Vector Movable::ClampVelocity(const Vector &velocity, const bool afterburn) { const Unit *unit = vega_dynamic_const_cast_ptr(this); - float fuelclamp = (unit->fuel.Level() <= 0) ? configuration()->fuel.no_fuel_thrust : 1; - float abfuelclamp = (unit->fuel.Level() <= 0 || (unit->energy.Level() < unit->afterburnenergy * static_cast(simulation_atom_var))) ? configuration()->fuel.no_fuel_afterburn : 1; + double max_speed; + double magnitude = velocity.Magnitude(); - float limit = - afterburn ? (abfuelclamp - * (unit->computer.max_ab_speed() - - unit->computer.max_speed()) + (fuelclamp * unit->computer.max_speed())) : fuelclamp - * unit->computer.max_speed(); - float tmp = velocity.Magnitude(); - if (tmp > fabs(limit)) { - return velocity * (limit / tmp); + // If we're using afterburn and have enough energy + // TODO: Need to make sure somewhere that damage to Afterburner.speed does not + // reduce it below Drive.speed + if(afterburn && (unit->afterburner.CanConsume() || configuration()->fuel.no_fuel_afterburn)) { + max_speed = unit->MaxAfterburnerSpeed(); + } else if(unit->drive.CanConsume() ) { //|| configuration()->fuel.no_fuel_thrust) { + max_speed = unit->MaxSpeed(); + } else { + max_speed = 0; } + + if(magnitude > max_speed) { + return velocity * (max_speed / magnitude); + } + return velocity; } +// TODO: move somewhere (drive?) or do something more elegant. +// Would this be fixed by simply setting the Resource and getting the value back? +// Yes. If we use the drive resources, we don't need this. Vector Movable::ClampAngVel(const Vector &velocity) { const Unit *unit = vega_dynamic_const_cast_ptr(this); Vector res(velocity); if (res.i >= 0) { - if (res.i > unit->computer.max_pitch_down) { - res.i = unit->computer.max_pitch_down; + if (res.i > unit->drive.max_pitch_down.Value()) { + res.i = unit->drive.max_pitch_down.Value(); } - } else if (-res.i > unit->computer.max_pitch_up) { - res.i = -unit->computer.max_pitch_up; + } else if (-res.i > unit->drive.max_pitch_up.Value()) { + res.i = -unit->drive.max_pitch_up.Value(); } if (res.j >= 0) { - if (res.j > unit->computer.max_yaw_left) { - res.j = unit->computer.max_yaw_left; + if (res.j > unit->drive.max_yaw_left.Value()) { + res.j = unit->drive.max_yaw_left.Value(); } - } else if (-res.j > unit->computer.max_yaw_right) { - res.j = -unit->computer.max_yaw_right; + } else if (-res.j > unit->drive.max_yaw_right.Value()) { + res.j = -unit->drive.max_yaw_right.Value(); } if (res.k >= 0) { - if (res.k > unit->computer.max_roll_left) { - res.k = unit->computer.max_roll_left; + if (res.k > unit->drive.max_roll_left.Value()) { + res.k = unit->drive.max_roll_left.Value(); } - } else if (-res.k > unit->computer.max_roll_right) { - res.k = -unit->computer.max_roll_right; + } else if (-res.k > unit->drive.max_roll_right.Value()) { + res.k = -unit->drive.max_roll_right.Value(); } return res; } Vector Movable::MaxThrust(const Vector &amt1) { + const Unit *unit = vega_dynamic_const_cast_ptr(this); + //amt1 is a normal - return amt1 * (Vector(copysign(limits.lateral, amt1.i), - copysign(limits.vertical, amt1.j), - amt1.k > 0 ? limits.forward : -limits.retro) * amt1); + return amt1 * (Vector(copysign(unit->drive.lateral.Value(), amt1.i), + copysign(unit->drive.vertical.Value(), amt1.j), + amt1.k > 0 ? unit->drive.forward.Value() : -unit->drive.retro.Value()) * amt1); } //CMD_FLYBYWIRE depends on new version of Clampthrust... don't change without resolving it @@ -615,173 +626,115 @@ Vector Movable::MaxThrust(const Vector &amt1) { Vector Movable::ClampThrust(const Vector &amt1, bool afterburn) { Unit *unit = vega_dynamic_cast_ptr(this); - const bool WCfuelhack = configuration()->fuel.fuel_equals_warp; const bool finegrainedFuelEfficiency = configuration()->fuel.variable_fuel_consumption; - if (WCfuelhack) { - // TODO: just don't use fuel in WC - if (unit->fuel.Level() > unit->ftl_energy.Level()) { - unit->fuel.SetLevel(unit->ftl_energy.Level()); - } - if (unit->fuel.Level() < unit->ftl_energy.Level()) { - unit->ftl_energy.SetLevel(unit->fuel.Level()); - } - } - float instantenergy = unit->afterburnenergy * simulation_atom_var; - if ((unit->afterburntype == 0) && unit->energy.Level() < instantenergy) { - afterburn = false; - } - if ((unit->afterburntype == 1) && unit->fuel.Level() < 0) { - unit->fuel.Zero(); - afterburn = false; - } - if ((unit->afterburntype == 2) && unit->ftl_energy.Level() < 0) { - unit->ftl_energy.SetCapacity(0); - afterburn = false; - } - if (3 == unit->afterburntype) { //no afterburner -- we should really make these types an enum :-/ + + + if(!unit->afterburner.CanConsume()) { afterburn = false; } + + Vector Res = amt1; float fuelclamp = (unit->fuel.Level() <= 0) ? configuration()->fuel.no_fuel_thrust : 1; float abfuelclamp = (unit->fuel.Level() <= 0) ? configuration()->fuel.no_fuel_afterburn : 1; - if (fabs(amt1.i) > fabs(fuelclamp * limits.lateral)) { - Res.i = copysign(fuelclamp * limits.lateral, amt1.i); + if (fabs(amt1.i) > fabs(fuelclamp * unit->drive.lateral)) { + Res.i = copysign(fuelclamp * unit->drive.lateral, amt1.i); } - if (fabs(amt1.j) > fabs(fuelclamp * limits.vertical)) { - Res.j = copysign(fuelclamp * limits.vertical, amt1.j); + if (fabs(amt1.j) > fabs(fuelclamp * unit->drive.vertical)) { + Res.j = copysign(fuelclamp * unit->drive.vertical, amt1.j); } float ablimit = afterburn - ? ((limits.afterburn - limits.forward) * abfuelclamp + limits.forward * fuelclamp) - : limits.forward; + ? ((unit->afterburner.thrust - unit->drive.forward.Value()) * abfuelclamp + unit->drive.forward.Value() * fuelclamp) + : unit->drive.forward.Value(); if (amt1.k > ablimit) { Res.k = ablimit; } - if (amt1.k < -limits.retro) { - Res.k = -limits.retro; - } - const float Lithium6constant = configuration()->fuel.deuterium_relative_efficiency_lithium; - //1/5,000,000 m/s - const float FMEC_exit_vel_inverse = configuration()->fuel.fmec_exit_velocity_inverse; - if (unit->afterburntype == 2) { - //Energy-consuming afterburner - //HACK this forces the reaction to be Li-6+Li-6 fusion with efficiency governed by the getFuelUsage function - unit->ftl_energy.Deplete(true, unit->afterburnenergy * Energetic::getFuelUsage(afterburn) * simulation_atom_var * Res.Magnitude() - * FMEC_exit_vel_inverse / Lithium6constant); - } - if (3 == unit->afterburntype || unit->afterburntype == 1) { - //fuel-burning overdrive - uses afterburner efficiency. In NO_AFTERBURNER case, "afterburn" will always be false, so can reuse code. - //HACK this forces the reaction to be Li-6+Li-6 fusion with efficiency governed by the getFuelUsage function - unit->fuel.Deplete(true, - ((afterburn - && finegrainedFuelEfficiency) ? unit->afterburnenergy : Energetic::getFuelUsage(afterburn)) - * simulation_atom_var * Res.Magnitude() - * FMEC_exit_vel_inverse / Lithium6constant); -#ifndef __APPLE__ - if (ISNAN(unit->fuel.Level())) { - VS_LOG(error, "Fuel is NAN A"); - unit->fuel.Zero(); - } -#endif - } - if (unit->afterburntype == 0) { - //fuel-burning afterburner - uses default efficiency - appears to check for available energy? FIXME - //HACK this forces the reaction to be Li-6+Li-6 fusion with efficiency governed by the getFuelUsage function - unit->fuel.Deplete(true, unit->getFuelUsage(false) * simulation_atom_var * Res.Magnitude() * FMEC_exit_vel_inverse / Lithium6constant); -#ifndef __APPLE__ - if (ISNAN(unit->fuel.Level())) { - VS_LOG(error, "Fuel is NAN B"); - unit->fuel.Zero(); - } -#endif - } - if ((afterburn) && (unit->afterburntype == 0)) { - unit->energy.Deplete(true, instantenergy); + if (amt1.k < -unit->drive.retro) { + Res.k = -unit->drive.retro; } - if (WCfuelhack) { - // TODO: just don't use fuel in WC - if (unit->fuel.Level() > unit->ftl_energy.Level()) { - unit->fuel.SetLevel(unit->ftl_energy.Level()); - } - if (unit->fuel.Level() < unit->ftl_energy.Level()) { - unit->ftl_energy.SetLevel(unit->fuel.Level()); - } + + if (afterburn) { + unit->afterburner.Consume(); } + return Res; } void Movable::LateralThrust(float amt) { + const Unit *unit = vega_dynamic_const_cast_ptr(this); + if (amt > 1.0) { amt = 1.0; } if (amt < -1.0) { amt = -1.0; } - ApplyLocalForce(amt * limits.lateral * Vector(1, 0, 0)); + ApplyLocalForce(amt * unit->drive.lateral.Value() * Vector(1, 0, 0)); } void Movable::VerticalThrust(float amt) { + const Unit *unit = vega_dynamic_const_cast_ptr(this); + if (amt > 1.0) { amt = 1.0; } if (amt < -1.0) { amt = -1.0; } - ApplyLocalForce(amt * limits.vertical * Vector(0, 1, 0)); + ApplyLocalForce(amt * unit->drive.vertical.Value() * Vector(0, 1, 0)); } void Movable::LongitudinalThrust(float amt) { + const Unit *unit = vega_dynamic_const_cast_ptr(this); + if (amt > 1.0) { amt = 1.0; } if (amt < -1.0) { amt = -1.0; } - ApplyLocalForce(amt * limits.forward * Vector(0, 0, 1)); + ApplyLocalForce(amt * unit->drive.forward.Value() * Vector(0, 0, 1)); } void Movable::YawTorque(float amt) { - if (amt > limits.yaw) { - amt = limits.yaw; - } else if (amt < -limits.yaw) { - amt = -limits.yaw; + const Unit *unit = vega_dynamic_const_cast_ptr(this); + + if (amt > unit->drive.yaw.Value()) { + amt = unit->drive.yaw.Value(); + } else if (amt < -unit->drive.yaw.Value()) { + amt = -unit->drive.yaw.Value(); } ApplyLocalTorque(amt * Vector(0, 1, 0)); } void Movable::PitchTorque(float amt) { - if (amt > limits.pitch) { - amt = limits.pitch; - } else if (amt < -limits.pitch) { - amt = -limits.pitch; + const Unit *unit = vega_dynamic_const_cast_ptr(this); + + if (amt > unit->drive.pitch.Value()) { + amt = unit->drive.pitch.Value(); + } else if (amt < -unit->drive.pitch.Value()) { + amt = -unit->drive.pitch.Value(); } ApplyLocalTorque(amt * Vector(1, 0, 0)); } void Movable::RollTorque(float amt) { - if (amt > limits.roll) { - amt = limits.roll; - } else if (amt < -limits.roll) { - amt = -limits.roll; + const Unit *unit = vega_dynamic_const_cast_ptr(this); + + if (amt > unit->drive.roll.Value()) { + amt = unit->drive.roll.Value(); + } else if (amt < -unit->drive.roll.Value()) { + amt = -unit->drive.roll.Value(); } ApplyLocalTorque(amt * Vector(0, 0, 1)); } void Movable::Thrust(const Vector &amt1, bool afterburn) { Unit *unit = vega_dynamic_cast_ptr(this); - - if (unit->afterburntype == 0) { - afterburn = afterburn && unit->energy.Level() > unit->afterburnenergy * static_cast(simulation_atom_var); - } //SIMULATION_ATOM; ? - if (unit->afterburntype == 1) { - afterburn = afterburn && unit->fuel.Level() > 0; - } - if (unit->afterburntype == 2) { - afterburn = afterburn && unit->ftl_energy.Level() > 0; - } - - + afterburn = afterburn && unit->afterburner.CanConsume(); + //Unit::Thrust( amt1, afterburn ); { Vector amt = ClampThrust(amt1, afterburn); @@ -830,3 +783,19 @@ void Movable::Thrust(const Vector &amt1, bool afterburn) { } } } + +// If in Travel mode (non-combat), speed is limited to x100 +double Movable::MaxSpeed() const { + static const double combat_mode_multiplier = configuration()->physics_config.combat_mode_multiplier; + const Unit *unit = vega_dynamic_const_cast_ptr(this); + return (unit->computer.combat_mode) ? unit->drive.speed.AdjustedValue() : combat_mode_multiplier * unit->drive.speed.AdjustedValue(); +} + +// Same as comment above. It makes less sense to limit travel speed with afterburners to afterburner speed x 100. +double Movable::MaxAfterburnerSpeed() const { + static const double combat_mode_multiplier = configuration()->physics_config.combat_mode_multiplier; + const Unit *unit = vega_dynamic_const_cast_ptr(this); + + //same capped big speed as combat...else different + return (unit->computer.combat_mode) ? unit->afterburner.speed.AdjustedValue() : combat_mode_multiplier * unit->drive.speed.AdjustedValue(); +} diff --git a/engine/src/cmd/movable.h b/engine/src/cmd/movable.h index e6c450659e..6b286b521e 100644 --- a/engine/src/cmd/movable.h +++ b/engine/src/cmd/movable.h @@ -25,7 +25,6 @@ #define VEGA_STRIKE_ENGINE_CMD_MOVABLE_H #include "gfx/vec.h" -#include "vs_limits.h" #include "gfx/quaternion.h" #include "star_system.h" @@ -59,8 +58,6 @@ class Movable { } // Fields - - Limits limits; //The velocity this unit has in World Space Vector cumulative_velocity; //The force applied from outside accrued over the whole physics frame @@ -295,6 +292,9 @@ class Movable { void PitchTorque(float amt); //Applies a roll of amt void RollTorque(float amt); + + double MaxSpeed() const; + double MaxAfterburnerSpeed() const; }; #endif //VEGA_STRIKE_ENGINE_CMD_MOVABLE_H diff --git a/engine/src/cmd/unit_csv.cpp b/engine/src/cmd/unit_csv.cpp index d8b65b9c83..a5c7103132 100644 --- a/engine/src/cmd/unit_csv.cpp +++ b/engine/src/cmd/unit_csv.cpp @@ -48,6 +48,7 @@ #include "unit_csv_factory.h" #include "upgradeable_unit.h" #include "resource/manifest.h" +#include "components/component_utils.h" extern int GetModeFromName(const char *input_buffer); extern void pushMesh(std::vector &mesh, @@ -376,13 +377,7 @@ static void AddSubUnits(Unit *thus, faction, modification, NULL)); //I set here the fg arg to NULL - if (xml.units.back()->name == "LOAD_FAILED") { - xml.units.back()->limits.yaw = 0; - xml.units.back()->limits.pitch = 0; - xml.units.back()->limits.roll = 0; - xml.units.back()->limits.lateral = xml.units.back()->limits.retro = xml.units.back()->limits.forward = - xml.units.back()->limits.afterburn = 0.0; - } + if (!thus->isSubUnit()) { //Useless to set recursive owner in subunits - as parent will do the same xml.units.back()->SetRecursiveOwner(thus); } @@ -390,8 +385,11 @@ static void AddSubUnits(Unit *thus, R.Normalize(); xml.units.back()->prev_physical_state = xml.units.back()->curr_physical_state; xml.units.back()->SetPosition(pos * xml.unitscale); - xml.units.back()->limits.structurelimits = R.Cast(); - xml.units.back()->limits.limitmin = restricted; + + // Subunit movement restrictions + xml.units.back()->structure_limits = R.Cast(); + xml.units.back()->limit_min = restricted; + xml.units.back()->name = filename; if (xml.units.back()->pImage->unitwriter != NULL) { xml.units.back()->pImage->unitwriter->setName(filename); @@ -401,7 +399,7 @@ static void AddSubUnits(Unit *thus, for (int a = xml.units.size() - 1; a >= 0; a--) { bool randomspawn = xml.units[a]->name.get().find("randomspawn") != string::npos; if (randomspawn) { - int chancetospawn = float_to_int(xml.units[a]->warpCapData()); + int chancetospawn = float_to_int(xml.units[a]->ftl_energy.MaxLevel()); if (chancetospawn > rand() % 100) { thus->SubUnits.prepend(xml.units[a]); } else { @@ -612,18 +610,7 @@ void LoadCockpit(Unit *thus, const string &cockpit) { const std::string EMPTY_STRING(""); -void YawPitchRollParser(std::string unit_key, - std::string main_string, - std::string left_string, - std::string right_string, - float &left_pointer, - float &right_pointer) { - 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) * 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) { Unit::XML xml; @@ -856,9 +843,14 @@ 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; + // Begin Drive Section + // Afterburner + afterburner = Afterburner(GetSource(ComponentType::Afterburner, &fuel, &energy, &ftl_energy)); + afterburner.Load("", unit_key); + + drive = Drive(GetSource(ComponentType::Drive, &fuel, &energy, &ftl_energy)); + drive.Load("", unit_key); + ftl_drive.Load("", unit_key); jump_drive.Load("", unit_key); @@ -868,54 +860,9 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ "Collide_Subunits", graphicOptions.RecurseIntoSubUnitsOnCollision ? true : false) ? 1 : 0; - - afterburnenergy = UnitCSVFactory::GetVariable(unit_key, "Afterburner_Usage_Cost", 32767.0f); - 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) * 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", - "Yaw_Governor", - "Yaw_Governor", - computer.max_yaw_right, - computer.max_yaw_left); - YawPitchRollParser(unit_key, - "Pitch_Governor", - "Pitch_Governor_Up", - "Pitch_Governor_Down", - computer.max_pitch_up, - computer.max_pitch_down); - YawPitchRollParser(unit_key, - "Roll_Governor", - "Roll_Governor_Right", - "Roll_Governor_Left", - computer.max_roll_right, - computer.max_roll_left); - - const float game_accel = configuration()->physics_config.game_accel; - const float game_speed = configuration()->physics_config.game_speed; - limits.afterburn = UnitCSVFactory::GetVariable(unit_key, "Afterburner_Accel", 0.0f) * game_accel * game_speed; - limits.forward = UnitCSVFactory::GetVariable(unit_key, "Forward_Accel", 0.0f) * game_accel * game_speed; - limits.retro = UnitCSVFactory::GetVariable(unit_key, "Retro_Accel", 0.0f) * game_accel * game_speed; - - float accel = UnitCSVFactory::GetVariable(unit_key, "accel", -1.0f); - if(accel != -1.0f) { - limits.lateral = limits.vertical = accel * game_accel * game_speed; - } else { - limits.lateral = 0.5 * (UnitCSVFactory::GetVariable(unit_key, "Left_Accel", 0.0f) + - UnitCSVFactory::GetVariable(unit_key, "Right_Accel", 0.0f)) * game_accel * game_speed; - - limits.vertical = 0.5 * (UnitCSVFactory::GetVariable(unit_key, "Top_Accel", 0.0f) + - UnitCSVFactory::GetVariable(unit_key, "Bottom_Accel", 0.0f)) * game_accel * game_speed; - } + + // End Drive Section - computer.max_combat_speed = UnitCSVFactory::GetVariable(unit_key, "Default_Speed_Governor", 0.0f) * game_speed; - computer.max_combat_ab_speed = - UnitCSVFactory::GetVariable(unit_key, "Afterburner_Speed_Governor", 0.0f) * game_speed; computer.itts = UnitCSVFactory::GetVariable(unit_key, "ITTS", true); computer.radar.canlock = UnitCSVFactory::GetVariable(unit_key, "Can_Lock", true); @@ -1356,30 +1303,16 @@ const std::map Unit::UnitToMap() { unit["Warp_Max_Multiplier"] = tos(graphicOptions.MaxWarpMultiplier); unit["Primary_Capacitor"] = tos(energy.Level()); unit["Reactor_Recharge"] = tos(reactor.Capacity()); + + afterburner.SaveToCSV(unit); + drive.SaveToCSV(unit); jump_drive.SaveToCSV(unit); ftl_drive.SaveToCSV(unit); + unit["Wormhole"] = tos(forcejump != 0); - unit["Afterburner_Usage_Cost"] = tos(afterburnenergy); - unit["Afterburner_Type"] = tos(afterburntype); - 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)); - unit["Forward_Accel"] = tos(limits.forward / (game_accel * game_speed)); - unit["Retro_Accel"] = tos(limits.retro / (game_accel * game_speed)); - unit["Left_Accel"] = unit["Right_Accel"] = tos(limits.lateral / (game_accel * game_speed)); - unit["Bottom_Accel"] = unit["Top_Accel"] = tos(limits.vertical / (game_accel * game_speed)); - unit["Default_Speed_Governor"] = tos(computer.max_combat_speed / game_speed); - unit["Afterburner_Speed_Governor"] = tos(computer.max_combat_ab_speed / game_speed); + + unit["ITTS"] = tos(computer.itts); unit["Can_Lock"] = tos(computer.radar.canlock); unit["Radar_Color"] = std::to_string(computer.radar.capability); diff --git a/engine/src/cmd/unit_generic.cpp b/engine/src/cmd/unit_generic.cpp index 566acdd91b..7d2687c3a5 100644 --- a/engine/src/cmd/unit_generic.cpp +++ b/engine/src/cmd/unit_generic.cpp @@ -531,9 +531,9 @@ static float tmpmax(float a, float b) { bool CheckAccessory(Unit *tur) { bool accessory = tur->name.get().find("accessory") != string::npos; if (accessory) { - tur->SetAngularVelocity(tur->DownCoordinateLevel(Vector(tur->GetComputerData().max_pitch_up, - tur->GetComputerData().max_yaw_right, - tur->GetComputerData().max_roll_right))); + tur->SetAngularVelocity(tur->DownCoordinateLevel(Vector(tur->drive.max_pitch_up, + tur->drive.max_yaw_right, + tur->drive.max_roll_right))); } return accessory; } @@ -635,11 +635,11 @@ float Unit::cosAngleTo(Unit *targ, float &dist, float speed, float range, bool t //Trial code float turnlimit = - tmpmax(tmpmax(computer.max_yaw_left, computer.max_yaw_right), - tmpmax(computer.max_pitch_up, computer.max_pitch_down)); + tmpmax(tmpmax(drive.max_yaw_left.Value(), drive.max_yaw_right.Value()), + tmpmax(drive.max_pitch_up.Value(), drive.max_pitch_down.Value())); float turnangle = simulation_atom_var * tmpmax(turnlimit, - tmpmax(simulation_atom_var * .5 * (limits.yaw + limits.pitch), + tmpmax(simulation_atom_var * .5 * (drive.yaw.Value() + drive.pitch.Value()), sqrtf(AngularVelocity.i * AngularVelocity.i + AngularVelocity.j * AngularVelocity.j))); float ittsangle = safeacos(Normal.Cast().Dot(totarget.Scale(1. / totarget.Magnitude()))); QVector edgeLocation = (targ->cumulative_transformation_matrix.getP() * targ->rSize() + totarget); @@ -1177,7 +1177,7 @@ void Unit::DamageRandSys(float dam, const Vector &vec, float randnum, float degr //THIS IS NOT YET SUPPORTED IN NETWORKING computer.target = nullptr; //set the target to NULL } else if (randnum >= .4) { - limits.retro *= dam; + drive.retro.RandomDamage(); } else if (randnum >= .3275) { const float maxdam = configuration()->physics_config.max_radar_cone_damage; computer.radar.maxcone += (1 - dam); @@ -1209,29 +1209,13 @@ void Unit::DamageRandSys(float dam, const Vector &vec, float randnum, float degr return; } if (rand01() < configuration()->physics_config.thruster_hit_chance) { - //DAMAGE ROLL/YAW/PITCH/THRUST - float orandnum = rand01() * .82 + .18; - if (randnum >= .9) { - computer.max_pitch_up *= orandnum; - } else if (randnum >= .8) { - computer.max_yaw_right *= orandnum; - } else if (randnum >= .6) { - computer.max_yaw_left *= orandnum; - } else if (randnum >= .4) { - computer.max_pitch_down *= orandnum; - } else if (randnum >= .2) { - computer.max_roll_right *= orandnum; - } else if (randnum >= .18) { - computer.max_roll_left *= orandnum; - } else if (randnum >= .17) { - limits.roll *= dam; - } else if (randnum >= .10) { - limits.yaw *= dam; - } else if (randnum >= .03) { - limits.pitch *= dam; - } else { - limits.lateral *= dam; - } + // This is fairly severe. One or two hits can disable the engine. + // Note that retro can be damaged by both this and above. + // Drive can also be damaged by code below - really computer. + // TODO: figure out a better damage system that doesn't rely on where + // the shots are coming from. + drive.Damage(); + afterburner.Damage(); damages |= Damages::LIMITS_DAMAGED; return; } @@ -1271,7 +1255,7 @@ void Unit::DamageRandSys(float dam, const Vector &vec, float randnum, float degr 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 5: afterburner.Damage(); break; case 6: CargoVolume *= dam; break; case 7: UpgradeVolume *= dam; break; case 8: @@ -1347,17 +1331,7 @@ void Unit::DamageRandSys(float dam, const Vector &vec, float randnum, float degr } if (degrees >= 150 && degrees <= 180) { //DAMAGE ENGINES - if (randnum >= .8) { - computer.max_combat_ab_speed *= dam; - } else if (randnum >= .6) { - computer.max_combat_speed *= dam; - } else if (randnum >= .4) { - limits.afterburn *= dam; - } else if (randnum >= .2) { - limits.vertical *= dam; - } else { - limits.forward *= dam; - } + drive.Damage(); damages |= Damages::LIMITS_DAMAGED; return; } @@ -2027,6 +2001,7 @@ 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->fuel.Refill(); unit->energy.Refill(); unit->ftl_energy.Refill(); unit->shield->FullyCharge(); @@ -2503,10 +2478,10 @@ bool Unit::UpgradeSubUnitsWithFactory(const Unit *up, int subunitoffset, bool to un->SetFaction(faction); un->curr_physical_state = addToMeCur; un->prev_physical_state = addToMePrev; - un->limits.yaw = 0; - un->limits.pitch = 0; - un->limits.roll = 0; - un->limits.lateral = un->limits.retro = un->limits.forward = un->limits.afterburn = 0.0; + un->drive.yaw = 0; + un->drive.pitch = 0; + un->drive.roll = 0; + un->drive.lateral = un->drive.retro = un->drive.forward = un->afterburner.thrust = 0.0; un->name = turSize + "_blank"; if (un->pImage->unitwriter != NULL) { @@ -2882,22 +2857,7 @@ bool Unit::UpAndDownGrade(const Unit *up, AddToDowngradeMap(up->name, 1, curdowngrademapoffset++, tempdownmap); } } - float tmax_speed = up->computer.max_combat_speed; - float tmax_ab_speed = up->computer.max_combat_ab_speed; - float tmax_yaw_right = up->computer.max_yaw_right; - float tmax_yaw_left = up->computer.max_yaw_left; - float tmax_pitch_up = up->computer.max_pitch_up; - float tmax_pitch_down = up->computer.max_pitch_down; - float tmax_roll_right = up->computer.max_roll_right; - float tmax_roll_left = up->computer.max_roll_left; - float tlimits_yaw = up->limits.yaw; - float tlimits_roll = up->limits.roll; - float tlimits_pitch = up->limits.pitch; - float tlimits_lateral = up->limits.lateral; - float tlimits_vertical = up->limits.vertical; - float tlimits_forward = up->limits.forward; - float tlimits_retro = up->limits.retro; - float tlimits_afterburn = up->limits.afterburn; + if (downgrade) { Adder = &SubtractUp; Percenter = &computeDowngradePercent; @@ -2909,22 +2869,6 @@ bool Unit::UpAndDownGrade(const Unit *up, } else if (additive == 2) { Adder = &MultUp; Percenter = &computeMultPercent; - tmax_speed = speedStarHandler(tmax_speed); - tmax_ab_speed = speedStarHandler(tmax_ab_speed); - tmax_yaw_right = speedStarHandler(tmax_yaw_right); - tmax_yaw_left = speedStarHandler(tmax_yaw_left); - tmax_pitch_up = speedStarHandler(tmax_pitch_up); - tmax_pitch_down = speedStarHandler(tmax_pitch_down); - tmax_roll_right = speedStarHandler(tmax_roll_right); - tmax_roll_left = speedStarHandler(tmax_roll_left); - tlimits_yaw = speedStarHandler(tlimits_yaw); - tlimits_pitch = speedStarHandler(tlimits_pitch); - tlimits_roll = speedStarHandler(tlimits_roll); - tlimits_forward = accelStarHandler(tlimits_forward); - tlimits_retro = accelStarHandler(tlimits_retro); - tlimits_lateral = accelStarHandler(tlimits_lateral); - tlimits_vertical = accelStarHandler(tlimits_vertical); - tlimits_afterburn = accelStarHandler(tlimits_afterburn); } else { Adder = &GetsB; Percenter = &computePercent; @@ -3074,60 +3018,7 @@ bool Unit::UpAndDownGrade(const Unit *up, || cell_has_recursive_data(upgrade_name, up->faction, "ECM_Rating")) STDUPGRADE(ecm, up->ecm, templ->ecm, 0); //ecm is unsigned --chuck_starchaser } - //Maneuvering stuff - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, - up->faction, - "Maneuver_Yaw|Maneuver_Pitch|Maneuver_Roll|Left_Accel|Top_Accel|Retro_Accel|Forward_Accel|Afterburner_Accel|Default_Speed_Governor|Afterburner_Speed_Governor|Yaw_Governor|Pitch_Governor|Roll_Speed_Governor")) { - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Maneuver_Yaw")) - STDUPGRADE(limits.yaw, tlimits_yaw, templ->limits.yaw, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Maneuver_Pitch")) - STDUPGRADE(limits.pitch, tlimits_pitch, templ->limits.pitch, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Maneuver_Roll")) - STDUPGRADE(limits.roll, tlimits_roll, templ->limits.roll, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Left_Accel")) - STDUPGRADE(limits.lateral, tlimits_lateral, templ->limits.lateral, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Top_Accel")) - STDUPGRADE(limits.vertical, tlimits_vertical, templ->limits.vertical, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Retro_Accel")) - STDUPGRADE(limits.retro, tlimits_retro, templ->limits.retro, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Forward_Accel")) - STDUPGRADE(limits.forward, tlimits_forward, templ->limits.forward, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Afterburner_Accel")) - STDUPGRADE(limits.afterburn, tlimits_afterburn, templ->limits.afterburn, 0); - /*if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Fuel_Capacity")) - STDUPGRADE(fuel, up->fuel, templ->fuel, 0);*/ - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Default_Speed_Governor")) - STDUPGRADE(computer.max_combat_speed, tmax_speed, templ->computer.max_combat_speed, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Afterburner_Speed_Governor")) - STDUPGRADE(computer.max_combat_ab_speed, tmax_ab_speed, templ->computer.max_combat_ab_speed, 0); - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Yaw_Governor")) { - STDUPGRADE(computer.max_yaw_right, tmax_yaw_right, templ->computer.max_yaw_right, 0); - STDUPGRADE(computer.max_yaw_left, tmax_yaw_left, templ->computer.max_yaw_left, 0); - } - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Pitch_Governor")) { - STDUPGRADE(computer.max_pitch_down, tmax_pitch_down, templ->computer.max_pitch_down, 0); - STDUPGRADE(computer.max_pitch_up, tmax_pitch_up, templ->computer.max_pitch_up, 0); - } - if (!csv_cell_null_check || force_change_on_nothing - || cell_has_recursive_data(upgrade_name, up->faction, "Roll_Speed_Governor")) { - STDUPGRADE(computer.max_roll_left, tmax_roll_left, templ->computer.max_roll_left, 0); - STDUPGRADE(computer.max_roll_right, tmax_roll_right, templ->computer.max_roll_right, 0); - } - } + //FIXME - do cell lookup later here static bool UpgradeCockpitDamage = XMLSupport::parse_bool(vs_config->getVariable("physics", "upgrade_cockpit_damage", "false")); @@ -3296,23 +3187,7 @@ bool Unit::UpAndDownGrade(const Unit *up, } //NO CLUE FOR BELOW if (downgrade) { - //NOTE: Afterburner type 2 (jmp) - //NOTE: Afterburner type 1 (gas) - //NOTE: Afterburner type 0 (pwr) - if (afterburnenergy < 32767 && afterburnenergy <= up->afterburnenergy && up->afterburnenergy != 32767 - && up->afterburnenergy != 0) { - if (touchme) { - afterburnenergy = 32767, afterburntype = 0; - } - ++numave; - ++percentage; - if (gen_downgrade_list) { - AddToDowngradeMap(up->name, - up->afterburntype, - ((char *) &this->afterburnenergy) - ((char *) this), - tempdownmap); - } - } + } else { //we are upgrading! if (touchme) { @@ -3322,21 +3197,6 @@ bool Unit::UpAndDownGrade(const Unit *up, } } } - - //NOTE: Afterburner type 2 (jmp) - //NOTE: Afterburner type 1 (gas) - //NOTE: Afterburner type 0 (pwr) - if (((afterburnenergy > up->afterburnenergy - || (afterburntype != up->afterburntype && up->afterburnenergy != 32767)) - && up->afterburnenergy > 0) || force_change_on_nothing) { - ++numave; - if (touchme) { - afterburnenergy = up->afterburnenergy, afterburntype = up->afterburntype; - } - } else if (afterburnenergy <= up->afterburnenergy && afterburnenergy >= 0 && up->afterburnenergy > 0 - && up->afterburnenergy < 32767) { - 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 ffc3fc5eaa..38803585fc 100644 --- a/engine/src/cmd/unit_generic.h +++ b/engine/src/cmd/unit_generic.h @@ -83,9 +83,13 @@ void UncheckUnit( class Unit*un ); #include "cargo_color.h" // Components +#include "components/afterburner.h" +#include "components/afterburner_upgrade.h" #include "components/cloak.h" #include "components/energy_container.h" #include "components/reactor.h" +#include "components/drive.h" +#include "components/drive_upgrade.h" #include "components/ftl_drive.h" #include "components/jump_drive.h" @@ -107,7 +111,6 @@ class Box; class StarSystem; struct colTrees; class Pilot; -class Limits; class MissileGeneric; class AsteroidGeneric; @@ -170,7 +173,11 @@ class Unit : public Armed, public Audible, public Drawable, public Damageable, p // TODO: move this to a single constructor?! Reactor reactor = Reactor(&fuel, &energy, &ftl_energy); + Afterburner afterburner; + AfterburnerUpgrade afterburner_upgrade = AfterburnerUpgrade(&afterburner); Cloak cloak; + Drive drive; + DriveUpgrade drive_upgrade = DriveUpgrade(&drive); FtlDrive ftl_drive = FtlDrive(&ftl_energy); JumpDrive jump_drive = JumpDrive(&ftl_energy); @@ -300,6 +307,15 @@ class Unit : public Armed, public Audible, public Drawable, public Damageable, p //the turrets and spinning parts fun fun stuff UnitCollection SubUnits; +// Turret limits + //the vector denoting the "front" of the turret cone! + // Again, an inconsistency between constructor and Init(). Chose Init + // value as it comes later + Vector structure_limits = Vector(0.0f, 0.0f, 1.0f); + + //the minimum dot that the current heading can have with the structurelimit + double limit_min = -1; + /** * Contains information about a particular Mount on a unit. * And the weapons it has, where it is, where it's aimed, diff --git a/engine/src/cmd/unit_util_generic.cpp b/engine/src/cmd/unit_util_generic.cpp index 1f4512ceb2..4f739f4be8 100644 --- a/engine/src/cmd/unit_util_generic.cpp +++ b/engine/src/cmd/unit_util_generic.cpp @@ -839,14 +839,14 @@ float maxSpeed(const Unit *my_unit) { if (!my_unit) { return 0; } - return my_unit->ViewComputerData().max_speed(); + return my_unit->MaxSpeed(); } float maxAfterburnerSpeed(const Unit *my_unit) { if (!my_unit) { return 0; } - return my_unit->ViewComputerData().max_ab_speed(); + return my_unit->MaxAfterburnerSpeed(); } void setECM(Unit *my_unit, int NewECM) { diff --git a/engine/src/cmd/upgradeable_unit.cpp b/engine/src/cmd/upgradeable_unit.cpp index 150c5b52eb..a619e1ef03 100644 --- a/engine/src/cmd/upgradeable_unit.cpp +++ b/engine/src/cmd/upgradeable_unit.cpp @@ -150,6 +150,16 @@ UpgradeOperationResult UpgradeableUnit::UpgradeUnit(const std::string upgrade_na result.success = unit->reactor.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; + case ComponentType::Afterburner: break; // Integrated + case ComponentType::AfterburnerUpgrade: + result.upgradeable = true; + result.success = unit->afterburner_upgrade.CanWillUpDowngrade(upgrade_key, upgrade, apply); + break; + case ComponentType::Drive: break; // Integrated + case ComponentType::DriveUpgrade: + result.upgradeable = true; + result.success = unit->drive_upgrade.CanWillUpDowngrade(upgrade_key, upgrade, apply); + break; case ComponentType::FtlDrive: result.upgradeable = true; result.success = unit->ftl_drive.CanWillUpDowngrade(upgrade_key, upgrade, apply); @@ -164,15 +174,6 @@ UpgradeOperationResult UpgradeableUnit::UpgradeUnit(const std::string upgrade_na result.upgradeable = true; result.success = unit->cloak.CanWillUpDowngrade(upgrade_key, upgrade, apply); break; - /*case UpgradeType::Afterburner: - result.upgradeable = true; - result.success = unit->afterburner.CanWillUpDowngrade(upgrade_key, upgrade, apply); - std::cout << "Afterburner upgraded successfully\n"; - break; - case UpgradeType::Drive: - result.upgradeable = true; - result.success = unit->armor->CanWillUpDowngrade(upgrade_key, upgrade, apply); - break;*/ /*case UpgradeType::ECM: @@ -225,6 +226,16 @@ void UpgradeableUnit::UpgradeUnit(const std::string &upgrades) { // TODO: change this when we make this a sub-class of unit Unit *unit = vega_dynamic_cast_ptr(this); unit->Upgrade(upgradee, mount_offset, subunit_offset, mode, true, percent, nullptr); + + // Code to handle DriveUpgrade and AfterburnerUpgrade + // Should eventually replace all the code above + CargoUpgrade cargo_upgrade(upgrade); + ComponentType component_type = GetComponentTypeFromName(cargo_upgrade.name); + if(component_type == ComponentType::AfterburnerUpgrade) { + unit->afterburner_upgrade.Load(cargo_upgrade.name + "__upgrades"); + } else if(component_type == ComponentType::DriveUpgrade) { + unit->drive_upgrade.Load(cargo_upgrade.name + "__upgrades"); + } } } diff --git a/engine/src/cmd/vs_limits.h b/engine/src/cmd/vs_limits.h deleted file mode 100644 index ac75198f70..0000000000 --- a/engine/src/cmd/vs_limits.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * vs_limits.h - * - * Copyright (c) 2001-2002 Daniel Horn - * Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors - * Copyright (c) 2019-2021 Stephen G. Tuggy, and other Vega Strike Contributors - * Copyright (C) 2022-2023 Stephen G. Tuggy, Benjamen R. Meyer - * - * 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 2 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_CMD_LIMITS_H -#define VEGA_STRIKE_ENGINE_CMD_LIMITS_H - -#include "gfx/vec.h" - -class Limits { -public: - // Init overrides default values of 0 with the following values -//max ypr--both pos/neg are symmetrical - float yaw = 2.55; - float pitch = 2.55; - float roll = 2.55; -//side-side engine thrust max - float lateral = 2; -//vertical engine thrust max - float vertical = 8; -//forward engine thrust max - float forward = 2; -//reverse engine thrust max - float retro = 2; -//after burner acceleration max - float afterburn = 5; -//the vector denoting the "front" of the turret cone! - // Again, an inconsistency between constructor and Init(). Chose Init - // value as it comes later - Vector structurelimits = Vector(0, 0, 1); -//the minimum dot that the current heading can have with the structurelimit - float limitmin = -1; -}; - -#endif //VEGA_STRIKE_ENGINE_CMD_LIMITS_H diff --git a/engine/src/components/afterburner.cpp b/engine/src/components/afterburner.cpp new file mode 100644 index 0000000000..8caaa9c8cd --- /dev/null +++ b/engine/src/components/afterburner.cpp @@ -0,0 +1,97 @@ +/* + * afterburner.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 "afterburner.h" + +#include "component_utils.h" +#include "unit_csv_factory.h" +#include "configuration/configuration.h" + +Afterburner::Afterburner(EnergyContainer *source) : + Component(0.0, 0.0, true, true), EnergyConsumer(source, false), thrust(1,0,1), speed(1,0,1) { + type = ComponentType::Afterburner; +} + + + +// Component Methods +void Afterburner::Load(std::string upgrade_key, + std::string unit_key) { + static const double game_speed = configuration()->physics_config.game_speed; + static const double game_accel = configuration()->physics_config.game_accel; + static const double game_accel_speed = game_speed * game_accel; + Component::Load(upgrade_key, unit_key); + + thrust = Resource(UnitCSVFactory::GetVariable(unit_key, "Afterburner_Accel", std::string("0.0")), game_accel_speed); + speed = Resource(UnitCSVFactory::GetVariable(unit_key, "Afterburner_Speed_Governor", std::string("0.0")), game_speed); + double consumption = UnitCSVFactory::GetVariable(unit_key, "Afterburner_Usage_Cost", 1.0); + SetConsumption(consumption); +} + +void Afterburner::SaveToCSV(std::map& unit) const { + static const double game_speed = configuration()->physics_config.game_speed; + static const double game_accel = configuration()->physics_config.game_accel; + static const double game_accel_speed = game_speed * game_accel; + unit["Afterburner_Accel"] = thrust.Serialize(game_accel_speed); + unit["Afterburner_Speed_Governor"] = speed.Serialize(game_speed); +} + +// Afterburner is integrated and so cannot be upgraded/downgraded +// Use AfterburnerUpgrade to make changes +bool Afterburner::CanDowngrade() const { + return false; +} + +bool Afterburner::Downgrade() { + return false; +} + +bool Afterburner::CanUpgrade(const std::string upgrade_name) const { + return false; +} + +bool Afterburner::Upgrade(const std::string upgrade_name) { + return false; +} + +void Afterburner::Damage() { + thrust.RandomDamage(); + speed.RandomDamage(); + + operational = (thrust.Percent() + speed.Percent()) / 2 * 100; +} + +void Afterburner::DamageByPercent(double percent) { + thrust.DamageByPercent(percent); + speed.DamageByPercent(percent); + + operational = (thrust.Percent() + speed.Percent()) / 2 * 100; +} + +void Afterburner::Repair() { + thrust.RepairFully(); + speed.RepairFully(); + + operational.RepairFully(); +} \ No newline at end of file diff --git a/engine/src/components/afterburner.h b/engine/src/components/afterburner.h new file mode 100644 index 0000000000..f904c9ecbd --- /dev/null +++ b/engine/src/components/afterburner.h @@ -0,0 +1,59 @@ +/* + * afterburner.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_AFTERBURNER_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_AFTERBURNER_H + +#include "component.h" +#include "energy_consumer.h" + +class EnergyContainer; + +/** We split this class from Drive for one reason - it may use a different source. */ +class Afterburner : public Component, public EnergyConsumer { +public: + //after burner acceleration max + Resource thrust; + + Resource speed; + + Afterburner(EnergyContainer *source = nullptr); + + // Component Methods + virtual void Load(std::string upgrade_key, + std::string unit_key = ""); + + virtual void SaveToCSV(std::map& unit) const; + + virtual bool CanDowngrade() const; + virtual bool Downgrade(); + virtual bool CanUpgrade(const std::string upgrade_name) const; + virtual bool Upgrade(const std::string upgrade_name); + + virtual void Damage(); + virtual void DamageByPercent(double percent); + virtual void Repair(); +}; + +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_AFTERBURNER_H diff --git a/engine/src/components/afterburner_upgrade.cpp b/engine/src/components/afterburner_upgrade.cpp new file mode 100644 index 0000000000..6e3eaa84bf --- /dev/null +++ b/engine/src/components/afterburner_upgrade.cpp @@ -0,0 +1,105 @@ +/* + * afterburner_upgrade.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 "afterburner_upgrade.h" + +#include "afterburner.h" +#include "unit_csv_factory.h" + +#include + + +AfterburnerUpgrade::AfterburnerUpgrade(Afterburner *afterburner): + Component(), afterburner(afterburner), thrust(1.0), + speed(1.0), consumption(1.0) { + type = ComponentType::AfterburnerUpgrade; +} + + + +// Component Methods +void AfterburnerUpgrade::Load(std::string upgrade_key, + std::string unit_key) { + Component::Load(upgrade_key, unit_key); + + thrust = UnitCSVFactory::GetVariable(upgrade_key, "Afterburner_Accel", 1.0); + speed = UnitCSVFactory::GetVariable(upgrade_key, "Afterburner_Speed_Governor", 1.0); + consumption = UnitCSVFactory::GetVariable(upgrade_key, "Afterburner_Usage_Cost", 1.0); +} + +void AfterburnerUpgrade::SaveToCSV(std::map& unit) const { + // Not supported with the current file format + // Instead, we save the modified Afterburner stats and load the upgrade above. + // Then, if we sell the upgrade, we get the original. +} + + +// Can only upgrade/downgrade if Afterburner is undamaged. +// Otherwise, there are a lot of edge cases. +bool AfterburnerUpgrade::CanDowngrade() const { + return !afterburner->Damaged(); +} + +bool AfterburnerUpgrade::Downgrade() { + if(!CanDowngrade()) { + return false; + } + + // Component + Component::Downgrade(); + + // Remove effects of upgrade on afterburner + afterburner->thrust.SetMaxValue(afterburner->thrust.MaxValue() / thrust); + afterburner->speed.SetMaxValue(afterburner->speed.MaxValue() / speed); + afterburner->SetConsumption(afterburner->GetConsumption() / consumption); + + // Remove modifiers + thrust = speed = consumption = 1.0; + + return true; +} + +bool AfterburnerUpgrade::CanUpgrade(const std::string upgrade_name) const { + return !afterburner->Damaged(); +} + +bool AfterburnerUpgrade::Upgrade(const std::string upgrade_name) { + if(!CanUpgrade(upgrade_name)) { + return false; + } + + // Component + Component::Upgrade(upgrade_name + "__upgrades"); + + // Load modifiers + Load(upgrade_name + "__upgrades"); + + // Add effects of upgrade on afterburner + afterburner->thrust.SetMaxValue(afterburner->thrust.MaxValue() * thrust); + afterburner->speed.SetMaxValue(afterburner->speed.MaxValue() * speed); + afterburner->SetConsumption(afterburner->GetConsumption() * consumption); + + return true; +} + diff --git a/engine/src/components/afterburner_upgrade.h b/engine/src/components/afterburner_upgrade.h new file mode 100644 index 0000000000..1d37ba2837 --- /dev/null +++ b/engine/src/components/afterburner_upgrade.h @@ -0,0 +1,65 @@ +/* + * afterburner_upgrade.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_AFTERBURNER_UPGRADE_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_AFTERBURNER_UPGRADE_H + +#include "component.h" + +class Afterburner; + +/** An AfterburnerUpgrade applies a modifier to Afterburner class. + * This is the same use case as DriveUpgrade. + * The game previously supported both additive and multiplicative upgrades. + * I've removed the additive one for simplicity's sake. + * The default value is 1.0 (no change). + */ +class AfterburnerUpgrade : public Component { + Afterburner *afterburner; +public: + //after burner acceleration + double thrust; + double speed; + double consumption; + + AfterburnerUpgrade(Afterburner *afterburner = nullptr); + + double MaxAfterburnerSpeed() const; + + // Component Methods + virtual void Load(std::string upgrade_key, + std::string unit_key = ""); + + virtual void SaveToCSV(std::map& unit) const; + + 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 // VEGA_STRIKE_ENGINE_COMPONENTS_AFTERBURNER_UPGRADE_H diff --git a/engine/src/components/cloak.cpp b/engine/src/components/cloak.cpp index 8078d27468..692cbaedda 100644 --- a/engine/src/components/cloak.cpp +++ b/engine/src/components/cloak.cpp @@ -25,7 +25,6 @@ #include "cloak.h" #include "unit_csv_factory.h" #include "configuration/configuration.h" -#include "unit_generic.h" Cloak::Cloak() : Component(), diff --git a/engine/src/components/component.cpp b/engine/src/components/component.cpp index 7cc3993363..4ac7f8c33f 100644 --- a/engine/src/components/component.cpp +++ b/engine/src/components/component.cpp @@ -69,6 +69,8 @@ void Component::Load(std::string upgrade_key, std::string unit_key) { // TODO: bool integral = false; } + + // TODO: convert to std::pair bool Component::CanWillUpDowngrade(const std::string upgrade_key, bool upgrade, bool apply) { diff --git a/engine/src/components/component_utils.cpp b/engine/src/components/component_utils.cpp index 58f4ce77cb..29fdf8651c 100644 --- a/engine/src/components/component_utils.cpp +++ b/engine/src/components/component_utils.cpp @@ -22,13 +22,21 @@ * along with Vega Strike. If not, see . */ +#define _USE_MATH_DEFINES +#include + #include "component_utils.h" #include "component.h" +#include "dummy_component.h" #include "reactor.h" #include "energy_container.h" +#include "afterburner.h" +#include "afterburner_upgrade.h" +#include "drive.h" +#include "drive_upgrade.h" #include "jump_drive.h" #include "ftl_drive.h" #include "cloak.h" @@ -36,7 +44,6 @@ #include "unit_csv_factory.h" #include "configuration/configuration.h" -#include @@ -129,3 +136,38 @@ EnergyContainer* GetSourceFromConfiguration(const EnergyConsumerSource source, E default: return nullptr; } } + + +// For Drive and DriveUpgrade +const std::string yaw_governor[] = {"Yaw_Governor", "Yaw_Governor", "Yaw_Governor"}; +const std::string pitch_governor[] = {"Pitch_Governor", "Pitch_Governor_Up", "Pitch_Governor_Down"}; +const std::string roll_governor[] = {"Roll_Governor", "Roll_Governor_Right", "Roll_Governor_Left"}; + +const std::string* GetGovernor(const YPR ypr) { + switch(ypr) { + case YPR::Yaw: return yaw_governor; break; + case YPR::Pitch: return pitch_governor; break; + case YPR::Roll: return roll_governor; break; + } +} + + +void DoubleYawPitchRollParser(std::string unit_key, const YPR ypr, + double &right_value, double &left_value) { + const std::string* governor = GetGovernor(ypr); + + const double main_value = UnitCSVFactory::GetVariable(unit_key, governor[0], 1.0); + right_value = UnitCSVFactory::GetVariable(unit_key, governor[1], main_value); + left_value = UnitCSVFactory::GetVariable(unit_key, governor[2], main_value); +} + +void ResourceYawPitchRollParser(std::string unit_key, const YPR ypr, + Resource &right_value, Resource &left_value, + const double minimum_functionality) { + double left, right; + DoubleYawPitchRollParser(unit_key, ypr, right, left); + left *= M_PI / 180.0; + right *= M_PI / 180.0; + right_value = Resource(right,right * minimum_functionality,right); + left_value = Resource(left,right * minimum_functionality,left); +} diff --git a/engine/src/components/component_utils.h b/engine/src/components/component_utils.h index f48661a615..6256ed2634 100644 --- a/engine/src/components/component_utils.h +++ b/engine/src/components/component_utils.h @@ -28,6 +28,7 @@ #include "component.h" #include "energy_consumer.h" #include "energy_container.h" +#include "resource/resource.h" #include @@ -39,5 +40,17 @@ EnergyContainer* GetSource(ComponentType component_type, EnergyContainer* fuel, EnergyContainer* GetSourceFromConfiguration(const EnergyConsumerSource source, EnergyContainer* fuel, EnergyContainer* energy, EnergyContainer* ftl_energy); + +enum class YPR { + Yaw, Pitch, Roll +}; + + +void DoubleYawPitchRollParser(std::string unit_key, const YPR ypr, + double &right_value, double &left_value); + + void ResourceYawPitchRollParser(std::string unit_key, const YPR ypr, + Resource &right_value, Resource &left_value, + const double minimum_functionality = 0.0); #endif // VEGA_STRIKE_ENGINE_COMPONENTS_COMPONENT_UTILS_H diff --git a/engine/src/components/drive.cpp b/engine/src/components/drive.cpp new file mode 100644 index 0000000000..36a9eba92d --- /dev/null +++ b/engine/src/components/drive.cpp @@ -0,0 +1,235 @@ +/* + * 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 . + */ + +#define _USE_MATH_DEFINES +#include +#include + +#include "drive.h" + +#include "component_utils.h" +#include "unit_csv_factory.h" +#include "configuration/configuration.h" + + + +Drive::Drive(EnergyContainer *source): + Component(0.0, 0.0, true, true), + EnergyConsumer(source, false), + yaw(1,0,1), pitch(1,0,1), roll(1,0,1), lateral(1,0,1), + vertical(1,0,1), forward(1,0,1), retro(1,0,1), + speed(1,0,1), max_yaw_left(1,0,1), + max_yaw_right(1,0,1), max_pitch_down(1,0,1), max_pitch_up(1,0,1), + max_roll_left(1,0,1), max_roll_right(1,0,1) { + type = ComponentType::Drive; +} + + +// Component Methods +void Drive::Load(std::string upgrade_key, + std::string unit_key) { + static const double game_speed = configuration()->physics_config.game_speed; + static const double game_accel = configuration()->physics_config.game_accel; + static const double game_accel_speed = game_speed * game_accel; + + // Minimum drive capability for limp home (in %) + static const double minimal_drive_functionality = configuration()->fuel.minimum_drive; + + Component::Load(upgrade_key, unit_key); + + // Consumer + // We do not support all options here. + if(configuration()->fuel.drive_source == EnergyConsumerSource::Fuel) { + SetConsumption(1.0); + } else { + SetConsumption(1.0); + infinite = true; + } + + // Drive + yaw = Resource(UnitCSVFactory::GetVariable(unit_key, "Maneuver_Yaw", std::string("0.0")), + M_PI / 180.0, minimal_drive_functionality); + pitch = Resource(UnitCSVFactory::GetVariable(unit_key, "Maneuver_Pitch", std::string("0.0")), + M_PI / 180.0, minimal_drive_functionality); + roll = Resource(UnitCSVFactory::GetVariable(unit_key, "Maneuver_Roll", std::string("0.0")), + M_PI / 180.0, minimal_drive_functionality); + + ResourceYawPitchRollParser(unit_key, YPR::Yaw, max_yaw_right, max_yaw_left); + ResourceYawPitchRollParser(unit_key, YPR::Pitch, max_pitch_up, max_pitch_down); + ResourceYawPitchRollParser(unit_key, YPR::Roll, max_roll_right, max_roll_left); + + forward = Resource(UnitCSVFactory::GetVariable(unit_key, "Forward_Accel", std::string("0.0")), + game_accel_speed, minimal_drive_functionality); + retro = Resource(UnitCSVFactory::GetVariable(unit_key, "Retro_Accel", std::string("0.0")), + game_accel_speed, minimal_drive_functionality); + + double accel = UnitCSVFactory::GetVariable(unit_key, "accel", -1.0f); + if(accel != -1.0f) { + const std::string accel_string = std::to_string(accel); + lateral = Resource(accel_string, game_accel_speed, minimal_drive_functionality); + vertical = Resource(accel_string, game_accel_speed, minimal_drive_functionality); + } else { + const double lateral_accel = 0.5 * UnitCSVFactory::GetVariable(unit_key, "Left_Accel", 0.0) + + 0.5 * UnitCSVFactory::GetVariable(unit_key, "Right_Accel", 0.0); + const std::string lateral_accel_string = std::to_string(lateral_accel); + lateral = Resource(lateral_accel_string, game_accel_speed, minimal_drive_functionality); + + const double vertical_accel = 0.5 * UnitCSVFactory::GetVariable(unit_key, "Top_Accel", 0.0) + + 0.5 * UnitCSVFactory::GetVariable(unit_key, "Bottom_Accel", 0.0); + const std::string vertical_accel_string = std::to_string(vertical_accel); + vertical = Resource(vertical_accel_string, game_accel_speed, minimal_drive_functionality); + } + + speed = Resource(UnitCSVFactory::GetVariable(unit_key, "Default_Speed_Governor", std::string("0.0")), + game_speed, minimal_drive_functionality); +} + + + + +void Drive::SaveToCSV(std::map& unit) const { + static const double game_speed = configuration()->physics_config.game_speed; + static const double game_accel = configuration()->physics_config.game_accel; + static const double game_accel_speed = game_speed * game_accel; + const double to_degrees = 180 / M_PI; + unit["Maneuver_Yaw"] = yaw.Serialize(to_degrees); + unit["Maneuver_Pitch"] = pitch.Serialize(to_degrees); + unit["Maneuver_Roll"] = roll.Serialize(to_degrees); + + unit["Yaw_Governor_Right"] = max_yaw_right.Serialize(to_degrees); + unit["Yaw_Governor_Left"] = max_yaw_left.Serialize(to_degrees); + unit["Pitch_Governor_Up"] = max_pitch_up.Serialize(to_degrees); + unit["Pitch_Governor_Down"] = max_pitch_down.Serialize(to_degrees); + unit["Roll_Governor_Right"] = max_roll_right.Serialize(to_degrees); + unit["Roll_Governor_Left"] = max_roll_left.Serialize(to_degrees); + + + unit["Forward_Accel"] = forward.Serialize(game_accel_speed); + unit["Retro_Accel"] = retro.Serialize(game_accel_speed); + unit["Left_Accel"] = unit["Right_Accel"] = lateral.Serialize(game_accel_speed); + unit["Bottom_Accel"] = unit["Top_Accel"] = vertical.Serialize(game_accel_speed); + + unit["Default_Speed_Governor"] = speed.Serialize(game_speed); +} + +// Drive is integrated and so cannot be upgraded/downgraded +// Use DriveUpgrade to make changes +bool Drive::CanDowngrade() const { + return false; +} + +bool Drive::Downgrade() { + return false; +} + +bool Drive::CanUpgrade(const std::string upgrade_name) const { + return false; +} + +bool Drive::Upgrade(const std::string upgrade_name) { + return false; +} + + +void Drive::Damage() { + yaw.RandomDamage(); + pitch.RandomDamage(); + roll.RandomDamage(); + + lateral.RandomDamage(); + vertical.RandomDamage(); + forward.RandomDamage(); + retro.RandomDamage(); + + speed.RandomDamage(); + + max_yaw_left.RandomDamage(); + max_yaw_right.RandomDamage(); + max_pitch_down.RandomDamage(); + max_pitch_up.RandomDamage(); + max_roll_left.RandomDamage(); + max_roll_right.RandomDamage(); + + operational = (yaw.Percent() + pitch.Percent() + roll.Percent() + + lateral.Percent() + vertical.Percent() + forward.Percent() + + retro.Percent() + speed.Percent() + + max_yaw_left.Percent() + max_yaw_right.Percent() + max_pitch_down.Percent() + + max_pitch_up.Percent() + max_roll_left.Percent() + max_roll_right.Percent()) / 14 * 100; +} + +void Drive::DamageByPercent(double percent) { + yaw.DamageByPercent(percent); + pitch.DamageByPercent(percent); + roll.DamageByPercent(percent); + + lateral.DamageByPercent(percent); + vertical.DamageByPercent(percent); + forward.DamageByPercent(percent); + retro.DamageByPercent(percent); + + speed.DamageByPercent(percent); + + max_yaw_left.DamageByPercent(percent); + max_yaw_right.DamageByPercent(percent); + max_pitch_down.DamageByPercent(percent); + max_pitch_up.DamageByPercent(percent); + max_roll_left.DamageByPercent(percent); + max_roll_right.DamageByPercent(percent); + + operational = (yaw.Percent() + pitch.Percent() + roll.Percent() + + lateral.Percent() + vertical.Percent() + forward.Percent() + + retro.Percent() + speed.Percent() + + max_yaw_left.Percent() + max_yaw_right.Percent() + max_pitch_down.Percent() + + max_pitch_up.Percent() + max_roll_left.Percent() + max_roll_right.Percent()) / 14 * 100; +} + +void Drive::Repair() { + yaw.RepairFully(); + pitch.RepairFully(); + roll.RepairFully(); + + lateral.RepairFully(); + vertical.RepairFully(); + forward.RepairFully(); + retro.RepairFully(); + + speed.RepairFully(); + + max_yaw_left.RepairFully(); + max_yaw_right.RepairFully(); + max_pitch_down.RepairFully(); + max_pitch_up.RepairFully(); + max_roll_left.RepairFully(); + max_roll_right.RepairFully(); + + operational.RepairFully(); +} + + + + + + + + diff --git a/engine/src/components/drive.h b/engine/src/components/drive.h new file mode 100644 index 0000000000..edbaccc9bd --- /dev/null +++ b/engine/src/components/drive.h @@ -0,0 +1,96 @@ +/* + * 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 VEGA_STRIKE_ENGINE_COMPONENTS_DRIVE_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_DRIVE_H + +#include "component.h" +#include "energy_consumer.h" + +#include "resource/resource.h" + +class EnergyContainer; + +class Drive : 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. + + /* @discussion use of Resource class in Drive + Unlike other use cases, where max, adjusted and value are all used, here + we only use max and adjusted. This shouldn't be an issue as adjusted and + value should be identical unless someone sets value to less. */ + + /* Afterburner was split from drive. Same comments apply there. */ +public: +// Limits + //max ypr--both pos/neg are symmetrical + Resource yaw; + Resource pitch; + Resource roll; + + //side-side engine thrust max + Resource lateral; + + //vertical engine thrust max + Resource vertical; + + //forward engine thrust max + Resource forward; + + //reverse engine thrust max + Resource retro; + +// Computer + //Computers limitation of speed during combat + Resource speed; + + //Computer's restrictions of YPR to limit space combat maneuvers + Resource max_yaw_left; + Resource max_yaw_right; + Resource max_pitch_down; + Resource max_pitch_up; + Resource max_roll_left; + Resource max_roll_right; + +// Constructors + Drive(EnergyContainer *source = nullptr); + + // Component Methods + virtual void Load(std::string upgrade_key, + std::string unit_key = ""); + + virtual void SaveToCSV(std::map& unit) const; + + virtual bool CanDowngrade() const; + virtual bool Downgrade(); + virtual bool CanUpgrade(const std::string upgrade_name) const; + virtual bool Upgrade(const std::string upgrade_name); + + virtual void Damage(); + virtual void DamageByPercent(double percent); + virtual void Repair(); +}; + +#endif // VEGA_STRIKE_ENGINE_COMPONENTS_DRIVE_H diff --git a/engine/src/components/drive_upgrade.cpp b/engine/src/components/drive_upgrade.cpp new file mode 100644 index 0000000000..8e542bf132 --- /dev/null +++ b/engine/src/components/drive_upgrade.cpp @@ -0,0 +1,171 @@ +/* + * drive_upgrade.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 "drive_upgrade.h" + +#include "drive.h" +#include "component_utils.h" +#include "unit_csv_factory.h" + + +DriveUpgrade::DriveUpgrade(Drive *drive) : + Component(), + drive(drive), + yaw(1.0), pitch(1.0), roll(1.0), lateral(1.0), + vertical(1.0), forward(1.0), retro(1.0), afterburn(1.0), + speed(1.0), max_yaw_left(1.0), + max_yaw_right(1.0), max_pitch_down(1.0), max_pitch_up(1.0), + max_roll_left(1.0), max_roll_right(1.0), fuel_consumption(1.0) { + type = ComponentType::DriveUpgrade; +} + + + +// Component Methods +void DriveUpgrade::Load(std::string upgrade_key, + std::string unit_key) { + Component::Load(upgrade_key, unit_key); + + // Consumer + fuel_consumption = UnitCSVFactory::GetVariable(upgrade_key, "Fuel_Consumption", 1.0); + + // DriveUpgrade + yaw = UnitCSVFactory::GetVariable(upgrade_key, "Maneuver_Yaw", 1.0); + pitch = UnitCSVFactory::GetVariable(upgrade_key, "Maneuver_Pitch", 1.0); + roll = UnitCSVFactory::GetVariable(upgrade_key, "Maneuver_Roll", 1.0); + + DoubleYawPitchRollParser(upgrade_key, YPR::Yaw, max_yaw_right, max_yaw_left); + DoubleYawPitchRollParser(upgrade_key, YPR::Pitch, max_pitch_up, max_pitch_down); + DoubleYawPitchRollParser(upgrade_key, YPR::Roll, max_roll_right, max_roll_left); + + forward = UnitCSVFactory::GetVariable(upgrade_key, "Forward_Accel", 1.0); + retro = UnitCSVFactory::GetVariable(upgrade_key, "Retro_Accel", 1.0); + lateral = 0.5 * (UnitCSVFactory::GetVariable(upgrade_key, "Left_Accel", 1.0) + + UnitCSVFactory::GetVariable(upgrade_key, "Right_Accel", 1.0)); + + vertical = 0.5 * (UnitCSVFactory::GetVariable(upgrade_key, "Top_Accel", 1.0) + + UnitCSVFactory::GetVariable(upgrade_key, "Bottom_Accel", 1.0)); + + speed = UnitCSVFactory::GetVariable(upgrade_key, "Default_Speed_Governor", 1.0); +} + + +void DriveUpgrade::SaveToCSV(std::map& unit) const { + unit["Yaw_Governor_Right"] = max_yaw_right; + unit["Yaw_Governor_Left"] = max_yaw_left; + unit["Pitch_Governor_Up"] = max_pitch_up; + unit["Pitch_Governor_Down"] = max_pitch_down; + unit["Roll_Governor_Right"] = max_roll_right; + unit["Roll_Governor_Left"] = max_roll_left; + + unit["Forward_Accel"] = forward; + unit["Retro_Accel"] = retro; + unit["Left_Accel"] = unit["Right_Accel"] = lateral; + unit["Bottom_Accel"] = unit["Top_Accel"] = vertical; + + unit["Default_Speed_Governor"] = speed; +} + + +// Can only upgrade/downgrade if Drive is undamaged. +// Otherwise, there are a lot of edge cases. +bool DriveUpgrade::CanDowngrade() const { + return !drive->Damaged(); +} + +bool DriveUpgrade::Downgrade() { + if(!CanDowngrade()) { + return false; + } + + // Component + Component::Downgrade(); + + // Add effects of upgrade on drive + drive->yaw.SetMaxValue(drive->yaw.MaxValue() / yaw); + drive->pitch.SetMaxValue(drive->pitch.MaxValue() / pitch); + drive->roll.SetMaxValue(drive->roll.MaxValue() / roll); + + drive->lateral.SetMaxValue(drive->lateral.MaxValue() / lateral); + drive->vertical.SetMaxValue(drive->vertical.MaxValue() / vertical); + drive->forward.SetMaxValue(drive->forward.MaxValue() / forward); + drive->retro.SetMaxValue(drive->retro.MaxValue() / retro); + + drive->speed.SetMaxValue(drive->speed.MaxValue() / speed); + + drive->max_yaw_left.SetMaxValue(drive->max_yaw_left.MaxValue() / max_yaw_left); + drive->max_yaw_right.SetMaxValue(drive->max_yaw_right.MaxValue() / max_yaw_right); + drive->max_pitch_up.SetMaxValue(drive->max_pitch_up.MaxValue() / max_pitch_up); + drive->max_pitch_down.SetMaxValue(drive->max_pitch_down.MaxValue() / max_pitch_down); + drive->max_roll_left.SetMaxValue(drive->max_roll_left.MaxValue() / max_roll_left); + drive->max_roll_right.SetMaxValue(drive->max_roll_right.MaxValue() / max_roll_right); + + drive->SetConsumption(drive->GetConsumption() / fuel_consumption); + + yaw = pitch = roll = lateral = vertical = forward = retro = speed = fuel_consumption = 1.0; + max_yaw_left = max_yaw_right = max_pitch_up = max_pitch_down = max_roll_left = max_roll_right = 1.0; + + return true; +} + +bool DriveUpgrade::CanUpgrade(const std::string upgrade_name) const { + return !drive->Damaged(); +} + +bool DriveUpgrade::Upgrade(const std::string upgrade_name) { + if(!CanUpgrade(upgrade_name)) { + return false; + } + + // Component + Component::Upgrade(upgrade_name + "__upgrades"); + + // Load modifiers + Load(upgrade_name + "__upgrades"); + + // Add effects of upgrade on drive + drive->yaw.SetMaxValue(drive->yaw.MaxValue() * yaw); + drive->pitch.SetMaxValue(drive->pitch.MaxValue() * pitch); + drive->roll.SetMaxValue(drive->roll.MaxValue() * roll); + + drive->lateral.SetMaxValue(drive->lateral.MaxValue() * lateral); + drive->vertical.SetMaxValue(drive->vertical.MaxValue() * vertical); + drive->forward.SetMaxValue(drive->forward.MaxValue() * forward); + drive->retro.SetMaxValue(drive->retro.MaxValue() * retro); + + drive->speed.SetMaxValue(drive->speed.MaxValue() * speed); + + drive->max_yaw_left.SetMaxValue(drive->max_yaw_left.MaxValue() * max_yaw_left); + drive->max_yaw_right.SetMaxValue(drive->max_yaw_right.MaxValue() * max_yaw_right); + drive->max_pitch_up.SetMaxValue(drive->max_pitch_up.MaxValue() * max_pitch_up); + drive->max_pitch_down.SetMaxValue(drive->max_pitch_down.MaxValue() * max_pitch_down); + drive->max_roll_left.SetMaxValue(drive->max_roll_left.MaxValue() * max_roll_left); + drive->max_roll_right.SetMaxValue(drive->max_roll_right.MaxValue() * max_roll_right); + + drive->SetConsumption(drive->GetConsumption() * fuel_consumption); + + return true; +} + + diff --git a/engine/src/components/drive_upgrade.h b/engine/src/components/drive_upgrade.h new file mode 100644 index 0000000000..c394c587a2 --- /dev/null +++ b/engine/src/components/drive_upgrade.h @@ -0,0 +1,96 @@ +/* + * drive_upgrade.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_DRIVE_UPGRADE_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_DRIVE_UPGRADE_H + +#include "component.h" + +class Drive; + +/** A DriveUpgrade applies a modifier to Drive class. + * This is a unique use case from other components, as allowing a slow + * ship (e.g. cargo) to upgrade to a fighter engine would break both + * game balance and believability. + * The game previously supported both additive and multiplicative upgrades. + * I've removed the additive one for simplicity's sake. + */ +class DriveUpgrade : public Component { +public: + Drive *drive; + +// Limits + //max ypr--both pos/neg are symmetrical + double yaw; + double pitch; + double roll; + + //side-side engine thrust max + double lateral; + + //vertical engine thrust max + double vertical; + + //forward engine thrust max + double forward; + + //reverse engine thrust max + double retro; + + //after burner acceleration max + double afterburn; + +// Computer + //Computers limitation of speed + double speed; + + //Computer's restrictions of YPR to limit space combat maneuvers + double max_yaw_left; + double max_yaw_right; + double max_pitch_down; + double max_pitch_up; + double max_roll_left; + double max_roll_right; + + double fuel_consumption; + +// Constructors + DriveUpgrade(Drive *drive = nullptr); + + // Component Methods + virtual void Load(std::string upgrade_key, + std::string unit_key = ""); + + virtual void SaveToCSV(std::map& unit) const; + + 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 // VEGA_STRIKE_ENGINE_COMPONENTS_DRIVE_UPGRADE_H diff --git a/engine/src/components/dummy_component.cpp b/engine/src/components/dummy_component.cpp new file mode 100644 index 0000000000..df352c17e0 --- /dev/null +++ b/engine/src/components/dummy_component.cpp @@ -0,0 +1,57 @@ +/* + * dummy_component.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 "dummy_component.h" + + +DummyComponent::DummyComponent() : + Component() { + type = ComponentType::Dummy; +} + + +// Component Methods +void DummyComponent::Load(std::string upgrade_key, + std::string unit_key) { + Component::Load(upgrade_key, unit_key); +} + +void DummyComponent::SaveToCSV(std::map& unit) const {} + +bool DummyComponent::CanDowngrade() const { + return false; +} + +bool DummyComponent::Downgrade() { + return false; +} + +bool DummyComponent::CanUpgrade(const std::string upgrade_name) const { + return false; +} + +bool DummyComponent::Upgrade(const std::string upgrade_name) { + return false; +} + diff --git a/engine/src/components/dummy_component.h b/engine/src/components/dummy_component.h new file mode 100644 index 0000000000..39861b4df2 --- /dev/null +++ b/engine/src/components/dummy_component.h @@ -0,0 +1,50 @@ +/* + * dummy_component.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_DUMMY_COMPONENT_H +#define VEGA_STRIKE_ENGINE_COMPONENTS_DUMMY_COMPONENT_H + +#include "component.h" + +/** A dummy component. Does nothing. Comes in useful in some places. */ +class DummyComponent : public Component { +public: + DummyComponent(); + + // Component Methods + virtual void Load(std::string upgrade_key, + std::string unit_key = ""); + + virtual void SaveToCSV(std::map& unit) const; + + 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 // VEGA_STRIKE_ENGINE_COMPONENTS_DUMMY_COMPONENT_H diff --git a/engine/src/components/jump_drive.cpp b/engine/src/components/jump_drive.cpp index d5be93a240..0a882df5b6 100644 --- a/engine/src/components/jump_drive.cpp +++ b/engine/src/components/jump_drive.cpp @@ -82,14 +82,9 @@ void JumpDrive::Load(std::string upgrade_key, std::string unit_key) { 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 * configuration()->fuel.jump_drive_factor; - // Jump Drive - bool installed = UnitCSVFactory::GetVariable(unit_key, "Jump_Drive_Present", false); - if(!installed) { - this->unit_key = ""; - } - + installed = UnitCSVFactory::GetVariable(unit_key, "Jump_Drive_Present", false); delay = UnitCSVFactory::GetVariable(unit_key, "Jump_Drive_Delay", 0); } diff --git a/engine/src/components/tests/afterburner_tests.cpp b/engine/src/components/tests/afterburner_tests.cpp new file mode 100644 index 0000000000..6aaa60ff83 --- /dev/null +++ b/engine/src/components/tests/afterburner_tests.cpp @@ -0,0 +1,119 @@ +/* + * afterburner_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 "afterburner.h" +#include "afterburner_upgrade.h" + +#include "unit_csv_factory.h" + +static const std::string upgrades_suffix_string = "__upgrades"; +const std::string afterburner_string = "afterburner"; +const std::string upgrade_string = "upgrade"; + +std::map afterburner_map = { + { "Name", "Afterburner"}, + { "Mass", "5.0"}, + { "Afterburner_Accel", "10"}, + { "Afterburner_Speed_Governor", "100"}, + { "Afterburner_Usage_Cost", "2.0"} +}; + +std::map afterburner_upgrade_map = { + { "Name", "AfterburnerUpgrade"}, + { "Mass", "5.0"}, + { "Afterburner_Accel", "1.5"}, + { "Afterburner_Speed_Governor", "1.5"}, + { "Afterburner_Usage_Cost", "1.5"} +}; + +TEST(Afterburner, Sanity) { + UnitCSVFactory::LoadUnit(afterburner_string + upgrades_suffix_string, afterburner_map); + UnitCSVFactory::LoadUnit(upgrade_string + upgrades_suffix_string, afterburner_upgrade_map); + + Afterburner afterburner; + AfterburnerUpgrade upgrade(&afterburner); + + afterburner.Load("", afterburner_string + upgrades_suffix_string); + upgrade.Load(upgrade_string + upgrades_suffix_string); + + EXPECT_EQ(afterburner.GetMass(), 0.0); + EXPECT_EQ(afterburner.thrust.MaxValue(), 10.0); + EXPECT_EQ(afterburner.speed.MaxValue(), 100.0); + EXPECT_EQ(afterburner.GetConsumption(), 2.0); + + EXPECT_EQ(upgrade.GetMass(), 5.0); + EXPECT_EQ(upgrade.thrust, 1.5); + EXPECT_EQ(upgrade.speed, 1.5); + EXPECT_EQ(upgrade.consumption, 1.5); +} + +TEST(Afterburner, UpgradeDowngrade) { + UnitCSVFactory::LoadUnit(afterburner_string + upgrades_suffix_string, afterburner_map); + UnitCSVFactory::LoadUnit(upgrade_string + upgrades_suffix_string, afterburner_upgrade_map); + + Afterburner afterburner; + AfterburnerUpgrade upgrade(&afterburner); + + afterburner.Load("", afterburner_string + upgrades_suffix_string); + + // Original + EXPECT_EQ(afterburner.GetMass(), 0.0); + EXPECT_EQ(afterburner.thrust.MaxValue(), 10.0); + EXPECT_EQ(afterburner.speed.MaxValue(), 100.0); + EXPECT_EQ(afterburner.GetConsumption(), 2.0); + + EXPECT_EQ(upgrade.GetMass(), 0.0); + EXPECT_EQ(upgrade.thrust, 1.0); + EXPECT_EQ(upgrade.speed, 1.0); + EXPECT_EQ(upgrade.consumption, 1.0); + + // Upgrade + upgrade.Upgrade(upgrade_string); + + EXPECT_EQ(afterburner.GetMass(), 0.0); + EXPECT_EQ(afterburner.thrust.MaxValue(), 15.0); + EXPECT_EQ(afterburner.speed.MaxValue(), 150.0); + EXPECT_EQ(afterburner.GetConsumption(), 3.0); + + EXPECT_EQ(upgrade.GetMass(), 5.0); + EXPECT_EQ(upgrade.thrust, 1.5); + EXPECT_EQ(upgrade.speed, 1.5); + EXPECT_EQ(upgrade.consumption, 1.5); + + // Downgrade + upgrade.Downgrade(); + + EXPECT_EQ(afterburner.GetMass(), 0.0); + EXPECT_EQ(afterburner.thrust.MaxValue(), 10.0); + EXPECT_EQ(afterburner.speed.MaxValue(), 100.0); + EXPECT_EQ(afterburner.GetConsumption(), 2.0); + + EXPECT_EQ(upgrade.GetMass(), 0.0); + EXPECT_EQ(upgrade.thrust, 1.0); + EXPECT_EQ(upgrade.speed, 1.0); + EXPECT_EQ(upgrade.consumption, 1.0); +} \ No newline at end of file diff --git a/engine/src/components/tests/drive_tests.cpp b/engine/src/components/tests/drive_tests.cpp new file mode 100644 index 0000000000..b76305c04c --- /dev/null +++ b/engine/src/components/tests/drive_tests.cpp @@ -0,0 +1,221 @@ +/* + * drive_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 "drive.h" +#include "drive_upgrade.h" + +#include "unit_csv_factory.h" + +using boost::math::float_constants::pi; + +static const std::string upgrades_suffix_string = "__upgrades"; +static const std::string drive_string = "drive"; +static const std::string upgrade_string = "upgrade"; + +static const std::map drive_map = { + { "Name", "Drive"}, + { "Mass", "5.0"}, + { "Maneuver_Yaw", "10.0" }, + { "Maneuver_Pitch", "10.0" }, + { "Maneuver_Roll", "10.0" }, + { "Forward_Accel", "10.0" }, + { "Retro_Accel", "10.0" }, + { "Left_Accel", "10.0" }, + { "Right_Accel", "10.0" }, + { "Top_Accel", "10.0" }, + { "Bottom_Accel", "10.0" }, + { "Default_Speed_Governor", "10.0" }, + { "Yaw_Governor", "10.0" }, + { "Yaw_Governor", "10.0" }, + { "Yaw_Governor", "10.0" }, + { "Pitch_Governor", "10.0" }, + { "Pitch_Governor_Up", "10.0" }, + { "Pitch_Governor_Down", "10.0" }, + { "Roll_Governor", "10.0" }, + { "Roll_Governor_Right", "10.0" }, + { "Roll_Governor_Left", "10.0" } +}; + +static const std::map drive_upgrade_map = { + { "Name", "Upgrade"}, + { "Mass", "5.0"}, + { "Fuel_Consumption", "1.5"}, + { "Maneuver_Yaw", "1.5" }, + { "Maneuver_Pitch", "1.5" }, + { "Maneuver_Roll", "1.5" }, + { "Forward_Accel", "1.5" }, + { "Retro_Accel", "1.5" }, + { "Left_Accel", "1.5" }, + { "Right_Accel", "1.5" }, + { "Top_Accel", "1.5" }, + { "Bottom_Accel", "1.5" }, + { "Default_Speed_Governor", "1.5" }, + { "Yaw_Governor", "1.5" }, + { "Yaw_Governor", "1.5" }, + { "Yaw_Governor", "1.5" }, + { "Pitch_Governor", "1.5" }, + { "Pitch_Governor_Up", "1.5" }, + { "Pitch_Governor_Down", "1.5" }, + { "Roll_Governor", "1.5" }, + { "Roll_Governor_Right", "1.5" }, + { "Roll_Governor_Left", "1.5" } +}; + +static void DriveExpectEq(const Drive& drive, const double value) { + EXPECT_FLOAT_EQ(drive.yaw.MaxValue(), value * pi / 180.0); + EXPECT_FLOAT_EQ(drive.pitch.MaxValue(), value * pi / 180.0); + EXPECT_FLOAT_EQ(drive.roll.MaxValue(), value * pi / 180.0); + EXPECT_EQ(drive.forward.MaxValue(), value); + EXPECT_EQ(drive.retro.MaxValue(), value); + EXPECT_EQ(drive.lateral.MaxValue(), value); + EXPECT_EQ(drive.vertical.MaxValue(), value); + EXPECT_EQ(drive.speed.MaxValue(), value); + + EXPECT_FLOAT_EQ(drive.max_pitch_down.MaxValue(), value * pi / 180.0); + EXPECT_FLOAT_EQ(drive.max_pitch_up.MaxValue(), value * pi / 180.0); + EXPECT_FLOAT_EQ(drive.max_roll_left.MaxValue(), value * pi / 180.0); + EXPECT_FLOAT_EQ(drive.max_roll_right.MaxValue(), value * pi / 180.0); + EXPECT_FLOAT_EQ(drive.max_yaw_left.MaxValue(), value * pi / 180.0); + EXPECT_FLOAT_EQ(drive.max_yaw_right.MaxValue(), value * pi / 180.0); +} + +static void DriveUpgradeExpectEq(const DriveUpgrade& upgrade, const double value) { + EXPECT_EQ(upgrade.yaw, value); + EXPECT_EQ(upgrade.pitch, value); + EXPECT_EQ(upgrade.roll, value); + EXPECT_EQ(upgrade.forward, value); + EXPECT_EQ(upgrade.retro, value); + EXPECT_EQ(upgrade.lateral, value); + EXPECT_EQ(upgrade.vertical, value); + + EXPECT_EQ(upgrade.max_pitch_down, value); + EXPECT_EQ(upgrade.max_pitch_up, value); + EXPECT_EQ(upgrade.max_roll_left, value); + EXPECT_EQ(upgrade.max_roll_right, value); + EXPECT_EQ(upgrade.max_yaw_left, value); + EXPECT_EQ(upgrade.max_yaw_right, value); +} + + +TEST(Drive, Sanity) { + UnitCSVFactory::LoadUnit(drive_string + upgrades_suffix_string, drive_map); + UnitCSVFactory::LoadUnit(upgrade_string + upgrades_suffix_string, drive_upgrade_map); + + Drive drive; + DriveUpgrade upgrade(&drive); + + drive.Load("", drive_string + upgrades_suffix_string); + upgrade.Load(upgrade_string + upgrades_suffix_string); + + // Check Drive Values + EXPECT_EQ(drive.GetUpgradeName(), ""); // Integrated + EXPECT_EQ(drive.GetMass(), 0.0); + + DriveExpectEq(drive, 10.0); + + EXPECT_EQ(drive.GetConsumption(), 1.0); + + // Check DriveUpgrade Values + EXPECT_EQ(upgrade.GetUpgradeName(), "Upgrade"); + EXPECT_EQ(upgrade.GetMass(), 5.0); + + DriveUpgradeExpectEq(upgrade, 1.5); + + EXPECT_EQ(upgrade.fuel_consumption, 1.5); +} + +TEST(Drive, UpgradeDowngrade) { + UnitCSVFactory::LoadUnit(drive_string + upgrades_suffix_string, drive_map); + UnitCSVFactory::LoadUnit(upgrade_string + upgrades_suffix_string, drive_upgrade_map); + + Drive drive; + DriveUpgrade upgrade(&drive); + + drive.Load("", drive_string + upgrades_suffix_string); + +// Original + std::cout << "Original\n--------\n"; + + // Drive + EXPECT_EQ(drive.GetUpgradeName(), ""); + EXPECT_EQ(drive.GetMass(), 0.0); + + DriveExpectEq(drive, 10.0); + + EXPECT_EQ(drive.GetConsumption(), 1.0); + + // Upgrade + EXPECT_EQ(upgrade.GetUpgradeName(), ""); + EXPECT_EQ(upgrade.GetMass(), 0.0); + + DriveUpgradeExpectEq(upgrade, 1.0); + + EXPECT_EQ(upgrade.fuel_consumption, 1.0); + +// Upgrade + std::cout << "Upgrade\n-------\n"; + + // Drive + upgrade.Upgrade(upgrade_string); + + EXPECT_EQ(drive.GetUpgradeName(), ""); + EXPECT_EQ(drive.GetMass(), 0.0); + + DriveExpectEq(drive, 15.0); + + EXPECT_EQ(drive.GetConsumption(), 1.5); + + // Upgrade + EXPECT_EQ(upgrade.GetUpgradeName(), "Upgrade"); + EXPECT_EQ(upgrade.GetMass(), 5.0); + + DriveUpgradeExpectEq(upgrade, 1.5); + + EXPECT_EQ(upgrade.fuel_consumption, 1.5); + +// Downgrade + std::cout << "Downgrade\n---------\n"; + // Drive + upgrade.Downgrade(); + + EXPECT_EQ(drive.GetUpgradeName(), ""); + EXPECT_EQ(drive.GetMass(), 0.0); + + DriveExpectEq(drive, 10.0); + + EXPECT_EQ(drive.GetConsumption(), 1.0); + + // Upgrade + EXPECT_EQ(upgrade.GetUpgradeName(), ""); + EXPECT_EQ(upgrade.GetMass(), 0.0); + + DriveUpgradeExpectEq(upgrade, 1.0); + + EXPECT_EQ(upgrade.fuel_consumption, 1.0); +} \ No newline at end of file diff --git a/engine/src/configuration/configuration.cpp b/engine/src/configuration/configuration.cpp index 7e5f20c6d6..c3fc7f80fa 100644 --- a/engine/src/configuration/configuration.cpp +++ b/engine/src/configuration/configuration.cpp @@ -328,8 +328,9 @@ void Configuration::OverrideDefaultsWithUserConfiguration() { physics_config.max_ecm = GetGameConfig().GetSizeT("physics.max_ecm", physics_config.max_ecm); physics_config.max_lost_target_live_time = GetGameConfig().GetFloat("physics.max_lost_target_live_time", physics_config.max_lost_target_live_time); physics_config.percent_missile_match_target_velocity = GetGameConfig().GetFloat("physics.percent_missile_match_target_velocity", physics_config.percent_missile_match_target_velocity); - physics_config.game_speed = GetGameConfig().GetFloat("physics.game_speed", physics_config.game_speed); - physics_config.game_accel = GetGameConfig().GetFloat("physics.game_accel", physics_config.game_accel); + physics_config.game_speed = GetGameConfig().GetDouble("physics.game_speed", physics_config.game_speed); + physics_config.game_accel = GetGameConfig().GetDouble("physics.game_accel", physics_config.game_accel); + physics_config.combat_mode_multiplier = GetGameConfig().GetDouble("physics.combat_mode_multiplier", physics_config.combat_mode_multiplier); physics_config.velocity_max = GetGameConfig().GetFloat("physics.velocity_max", physics_config.velocity_max); physics_config.max_player_rotation_rate = GetGameConfig().GetFloat("physics.maxplayerrot", physics_config.max_player_rotation_rate); physics_config.max_non_player_rotation_rate = GetGameConfig().GetFloat("physics.maxNPCrot", physics_config.max_non_player_rotation_rate); diff --git a/engine/src/configuration/configuration.h b/engine/src/configuration/configuration.h index 4b5cb67ebd..766d4e4cec 100644 --- a/engine/src/configuration/configuration.h +++ b/engine/src/configuration/configuration.h @@ -187,6 +187,7 @@ struct Fuel { float min_reactor_efficiency{0.00001F}; float ecm_energy_cost{0.05F}; + double megajoules_factor{100}; 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}; @@ -382,8 +383,9 @@ struct PhysicsConfig { uintmax_t max_ecm{4U}; float max_lost_target_live_time{30.0F}; float percent_missile_match_target_velocity{1.0F}; - float game_speed{1.0F}; - float game_accel{1.0F}; + double game_speed{1.0}; + double game_accel{1.0}; + double combat_mode_multiplier{100.0}; float velocity_max{10000.0F}; float max_player_rotation_rate{24.0F}; float max_non_player_rotation_rate{360.0F}; diff --git a/engine/src/gfx/cockpit.cpp b/engine/src/gfx/cockpit.cpp index 651cd79930..fbcdcf9c41 100644 --- a/engine/src/gfx/cockpit.cpp +++ b/engine/src/gfx/cockpit.cpp @@ -559,13 +559,13 @@ float GameCockpit::LookupUnitStat(int stat, Unit *target) { value = target->GetComputerData().set_speed; break; case UnitImages::MAXKPS: - value = target->GetComputerData().max_speed(); + value = target->MaxSpeed(); break; case UnitImages::MAXCOMBATKPS: - value = target->GetComputerData().max_combat_speed; + value = target->drive.speed.Value(); break; case UnitImages::MAXCOMBATABKPS: - value = target->GetComputerData().max_combat_ab_speed; + value = target->afterburner.speed.Value(); break; default: value = 0; diff --git a/engine/src/gfx/nav/drawsystem.cpp b/engine/src/gfx/nav/drawsystem.cpp index 13d04729fd..ce164c5997 100644 --- a/engine/src/gfx/nav/drawsystem.cpp +++ b/engine/src/gfx/nav/drawsystem.cpp @@ -303,7 +303,7 @@ void NavigationSystem::DrawSystem() { * {*/ if (UnitUtil::isSignificant(*blah)) { //capship or station - if ((*blah)->GetComputerData().max_speed() == 0) { + if ((*blah)->MaxSpeed() == 0) { //is this item STATIONARY? insert_type = navstation; insert_size = navstationsize; diff --git a/engine/src/main.cpp b/engine/src/main.cpp index 94d27443d5..bb505ab6b2 100644 --- a/engine/src/main.cpp +++ b/engine/src/main.cpp @@ -121,8 +121,8 @@ void setup_game_data() { g_game.music_volume = 1; g_game.warning_level = 20; g_game.capture_mouse = GFXFALSE; - g_game.y_resolution = 768; - g_game.x_resolution = 1024; + g_game.y_resolution = 1080; + g_game.x_resolution = 1920; g_game.fov = 78; g_game.MouseSensitivityX = 2; g_game.MouseSensitivityY = 4; diff --git a/engine/src/options.cpp b/engine/src/options.cpp index ebff525fd9..efe411ff9b 100644 --- a/engine/src/options.cpp +++ b/engine/src/options.cpp @@ -22,6 +22,7 @@ #include "options.h" #include "configxml.h" +#include "configuration/configuration.h" extern VegaConfig *vs_config; @@ -189,8 +190,8 @@ void vs_options::init() { rgb_pixel_format = vs_config->getVariable("graphics", "rgb_pixel_format", "undefined"); gl_accelerated_visual = XMLSupport::parse_bool(vs_config->getVariable("graphics", "gl_accelerated_visual", "true")); z_pixel_format = XMLSupport::parse_int(vs_config->getVariable("graphics", "z_pixel_format", "24")); - x_resolution = XMLSupport::parse_int(vs_config->getVariable("graphics", "x_resolution", "1024")); - y_resolution = XMLSupport::parse_int(vs_config->getVariable("graphics", "y_resolution", "768")); + x_resolution = configuration()->graphics2_config.resolution_x; + y_resolution = configuration()->graphics2_config.resolution_y; fullscreen = XMLSupport::parse_bool(vs_config->getVariable("graphics", "fullscreen", "false")); colordepth = XMLSupport::parse_int(vs_config->getVariable("graphics", "colordepth", "32")); glut_stencil = XMLSupport::parse_bool(vs_config->getVariable("graphics", "glut_stencil", "true")); diff --git a/engine/src/ship_commands.cpp b/engine/src/ship_commands.cpp index 07ed7a2267..ffa98e0f32 100644 --- a/engine/src/ship_commands.cpp +++ b/engine/src/ship_commands.cpp @@ -149,7 +149,7 @@ void ShipCommands::setkps(const char *in) { } else { kps /= game_options()->display_in_meters ? 1.0f : 3.6f; } - player->GetComputerData().set_speed = fmin(player->GetComputerData().max_speed(), kps); + player->GetComputerData().set_speed = fmin(player->MaxSpeed(), kps); } }