From 3c487c5cd69c53d6fea948643c0a76df03516605 Mon Sep 17 00:00:00 2001 From: Aki Date: Fri, 1 Apr 2022 21:23:39 +0200 Subject: Moved Stars45 to StarsEx --- StarsEx/QuantumDrive.cpp | 245 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 StarsEx/QuantumDrive.cpp (limited to 'StarsEx/QuantumDrive.cpp') diff --git a/StarsEx/QuantumDrive.cpp b/StarsEx/QuantumDrive.cpp new file mode 100644 index 0000000..bcc8356 --- /dev/null +++ b/StarsEx/QuantumDrive.cpp @@ -0,0 +1,245 @@ +/* Starshatter: The Open Source Project + Copyright (c) 2021-2022, Starshatter: The Open Source Project Contributors + Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors + Copyright (c) 1997-2006, Destroyer Studios LLC. + + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + Quantum Drive class +*/ + +#include "QuantumDrive.h" +#include "Ship.h" +#include "Explosion.h" +#include "Drive.h" +#include "Sim.h" +#include "SimEvent.h" +#include "StarSystem.h" + +#include "Game.h" +#include "ContentBundle.h" +#include "Random.h" + +// +----------------------------------------------------------------------+ + +static int drive_value = 3; + +// +----------------------------------------------------------------------+ + +QuantumDrive::QuantumDrive(SUBTYPE s, double cap, double rate) +: System(DRIVE, s, "Quantum", drive_value, (float) cap, (float) cap, (float) rate), +dst_rgn(0), active_state(ACTIVE_READY), warp_fov(1), jump_time(0), countdown(5) +{ + name = ContentBundle::GetInstance()->GetText("sys.quantum"); + abrv = ContentBundle::GetInstance()->GetText("sys.quantum.abrv"); + + emcon_power[0] = 0; + emcon_power[1] = 0; + emcon_power[2] = 100; +} + +// +----------------------------------------------------------------------+ + +QuantumDrive::QuantumDrive(const QuantumDrive& d) +: System(d), +dst_rgn(0), active_state(ACTIVE_READY), warp_fov(1), jump_time(0), +countdown(d.countdown) +{ + Mount(d); + SetAbbreviation(d.Abbreviation()); + + energy = capacity; +} + +// +--------------------------------------------------------------------+ + +QuantumDrive::~QuantumDrive() +{ } + +// +--------------------------------------------------------------------+ + +void +QuantumDrive::SetDestination(SimRegion* rgn, const Point& loc) +{ + dst_rgn = rgn; + dst_loc = loc; +} + +// +--------------------------------------------------------------------+ + +bool +QuantumDrive::Engage(bool immediate) +{ + if (active_state == ACTIVE_READY && ship != 0 && + IsPowerOn() && Status() == NOMINAL && energy == capacity) { + + active_state = ACTIVE_COUNTDOWN; + if (immediate) { + jump_time = 1; + return true; + } + + jump_time = countdown; + + SimRegion* rgn = ship->GetRegion(); + + ListIter s_iter = rgn->Ships(); + while (++s_iter) { + Ship* s = s_iter.value(); + + if (s != ship) { + double dist = Point(s->Location() - ship->Location()).length(); + + if (dist < 25e3) + jump_time += 5; + + else if (dist < 50e3) + jump_time += 2; + + else if (dist < 100e3) + jump_time += 1; + + else if (dist < 200e3) + jump_time += 0.5; + } + } + + return true; + } + + return false; +} + +void +QuantumDrive::PowerOff() +{ + System::PowerOff(); + AbortJump(); +} + +void +QuantumDrive::AbortJump() +{ + active_state = ACTIVE_READY; + jump_time = 0; + energy = 0; + warp_fov = 1; + + ship->SetWarp(warp_fov); + + SimRegion* r = ship->GetRegion(); + ListIter neighbor = r->Ships(); + + while (++neighbor) { + if (neighbor->IsDropship()) { + Ship* s = neighbor.value(); + Point delta = s->Location() - ship->Location(); + + if (delta.length() < 5e3) + s->SetWarp(warp_fov); + } + } +} + +// +--------------------------------------------------------------------+ + +void +QuantumDrive::ExecFrame(double seconds) +{ + System::ExecFrame(seconds); + + if (active_state == ACTIVE_READY) + return; + + if (ship) { + bool warping = false; + + if (active_state == ACTIVE_COUNTDOWN) { + if (jump_time > 0) { + jump_time -= seconds; + } + + else { + jump_time = 0; + active_state = ACTIVE_PREWARP; + } + } + + else if (active_state == ACTIVE_PREWARP) { + if (warp_fov < 5000) { + warp_fov *= 1.5; + } + else { + Jump(); + energy = 0.0f; + } + + warping = true; + } + + else if (active_state == ACTIVE_POSTWARP) { + if (warp_fov > 1) { + warp_fov *= 0.75; + } + else { + warp_fov = 1; + active_state = ACTIVE_READY; + } + + warping = true; + } + + if (warping) { + ship->SetWarp(warp_fov); + + SimRegion* r = ship->GetRegion(); + ListIter neighbor = r->Ships(); + + while (++neighbor) { + if (neighbor->IsDropship()) { + Ship* s = neighbor.value(); + Point delta = s->Location() - ship->Location(); + + if (delta.length() < 5e3) + s->SetWarp(warp_fov); + } + } + } + } +} + +// +--------------------------------------------------------------------+ + +void +QuantumDrive::Jump() +{ + Sim* sim = Sim::GetSim(); + + if (ship && sim) { + double dist = 150e3 + Random(0, 60e3); + Point esc_vec = dst_rgn->GetOrbitalRegion()->Location() - + dst_rgn->GetOrbitalRegion()->Primary()->Location(); + + esc_vec.Normalize(); + esc_vec *= dist; + esc_vec += RandomDirection() * Random(15e3, 22e3); + + if (subtype == HYPER) + sim->CreateExplosion(ship->Location(), Point(0,0,0), Explosion::HYPER_FLASH, 1, 1, ship->GetRegion()); + else + sim->CreateExplosion(ship->Location(), Point(0,0,0), Explosion::QUANTUM_FLASH, 1, 0, ship->GetRegion()); + + sim->RequestHyperJump(ship, dst_rgn, esc_vec); + + ShipStats* stats = ShipStats::Find(ship->Name()); + stats->AddEvent(SimEvent::QUANTUM_JUMP, dst_rgn->Name()); + } + + dst_rgn = 0; + dst_loc = Point(); + + active_state = ACTIVE_POSTWARP; +} -- cgit v1.1