diff options
author | milo24x7@gmail.com <milo24x7@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544> | 2013-07-07 22:08:49 +0000 |
---|---|---|
committer | milo24x7@gmail.com <milo24x7@gmail.com@076cb2c4-205e-83fd-5cf3-1be9aa105544> | 2013-07-07 22:08:49 +0000 |
commit | d17521c8b9085a91d08fecfd0b51bbbf7b1dccac (patch) | |
tree | 4673104b47dc68a079cac9f94deefd48dfcb66fa /Stars45/System.cpp | |
parent | 1de4b2bdbb019be6f1b7262c3eba5568d7682edd (diff) | |
download | starshatter-d17521c8b9085a91d08fecfd0b51bbbf7b1dccac.zip starshatter-d17521c8b9085a91d08fecfd0b51bbbf7b1dccac.tar.gz starshatter-d17521c8b9085a91d08fecfd0b51bbbf7b1dccac.tar.bz2 |
Updated open source license declaration and fixed some formatting issues.
Diffstat (limited to 'Stars45/System.cpp')
-rw-r--r-- | Stars45/System.cpp | 822 |
1 files changed, 423 insertions, 399 deletions
diff --git a/Stars45/System.cpp b/Stars45/System.cpp index 96b86ed..86b4a5a 100644 --- a/Stars45/System.cpp +++ b/Stars45/System.cpp @@ -1,399 +1,423 @@ -/* Project Starshatter 4.5
- Destroyer Studios LLC
- Copyright © 1997-2004. All Rights Reserved.
-
- SUBSYSTEM: Stars.exe
- FILE: System.cpp
- AUTHOR: John DiCamillo
-
-
- OVERVIEW
- ========
- Generic Ship Subsystem class
-*/
-
-#include "MemDebug.h"
-#include "System.h"
-#include "SystemDesign.h"
-#include "Component.h"
-#include "NetUtil.h"
-
-#include "Game.h"
-
-// +----------------------------------------------------------------------+
-
-System::System(System::CATEGORY t, int s, const char* n, int maxv,
-double e, double c, double r)
-: type(t), id(0), ship(0), subtype(s), status(NOMINAL), availability(1.0f),
-safety(1.0f), stability(1.0f), crit_level(0.5f), net_avail(-1.0f),
-mount_rel(0.0f, 0.0f, 0.0f), radius(0.0f), safety_overload(0.0f),
-hull_factor(0.5f), energy((float) e), capacity((float) c), sink_rate((float) r),
-power_level(1.0f), power_flags(0), source_index(0), power_on(true),
-explosion_type(0), name(n), abrv(name), design(0), emcon(3)
-{
- if (maxv < 100)
- max_value = maxv;
- else
- max_value = (int) (maxv/100.0);
-
- emcon_power[0] = 100;
- emcon_power[1] = 100;
- emcon_power[2] = 100;
-}
-
-// +----------------------------------------------------------------------+
-
-System::System(const System& s)
-: type(s.type), id(s.id), ship(0), subtype(s.subtype), status(s.status),
-availability(s.availability), safety(s.safety), stability(s.stability),
-crit_level(s.crit_level), net_avail(-1.0f),
-mount_rel(s.mount_rel), radius(s.radius), safety_overload(0.0f),
-hull_factor(s.hull_factor), energy(s.energy), capacity(s.capacity),
-sink_rate(s.sink_rate), power_level(s.power_level), power_flags(s.power_flags),
-source_index(s.source_index), power_on(s.power_on), max_value(s.max_value),
-explosion_type(s.explosion_type), name(s.name), abrv(s.abrv), design(s.design),
-emcon(s.emcon)
-{
- if (design) {
- // cast-away const
- ListIter<Component> c = (List<Component>&) s.components;
- while (++c) {
- Component* comp = new(__FILE__,__LINE__) Component(*(c.value()));
- comp->SetSystem(this);
- components.append(comp);
- }
- }
-
- emcon_power[0] = s.emcon_power[0];
- emcon_power[1] = s.emcon_power[1];
- emcon_power[2] = s.emcon_power[2];
-}
-
-// +--------------------------------------------------------------------+
-
-System::~System()
-{
- components.destroy();
-}
-
-// +--------------------------------------------------------------------+
-
-void
-System::SetDesign(SystemDesign* d)
-{
- if (design) {
- design = 0;
- components.destroy();
- }
-
- if (d) {
- design = d;
-
- ListIter<ComponentDesign> cd = design->components;
- while (++cd) {
- Component* comp = new(__FILE__,__LINE__) Component(cd.value(), this);
- components.append(comp);
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-System::SetPowerLevel(double level)
-{
- if (level > 100)
- level = 100;
- else if (level < 0)
- level = 0;
-
- level /= 100;
-
- if (power_level != level) {
- // if the system is on emergency override power,
- // do not let the EMCON system use this method
- // to drop it back to normal power:
- if (power_level > 1 && level == 1)
- return;
-
- power_level = (float) level;
-
- NetUtil::SendSysStatus(ship, this);
- }
-}
-
-void
-System::SetOverride(bool over)
-{
- bool changed = false;
-
- if (over && power_level != 1.2f) {
- power_level = 1.2f;
- changed = true;
- }
-
- else if (!over && power_level > 1) {
- power_level = 1.0f;
- changed = true;
- }
-
- if (changed)
- NetUtil::SendSysStatus(ship, this);
-}
-
-void
-System::SetEMCONPower(int index, int power_level)
-{
- if (index >= 1 && index <= 3) {
- emcon_power[index-1] = (BYTE) power_level;
- }
-}
-
-int
-System::GetEMCONPower(int index)
-{
- if (index >= 1 && index <= 3) {
- return emcon_power[index-1];
- }
-
- return 100;
-}
-
-void
-System::DoEMCON(int index)
-{
- int e = GetEMCONPower(index);
-
- if (power_level * 100 > e || emcon != index) {
- if (e == 0) {
- PowerOff();
- }
- else {
- if (emcon != index)
- PowerOn();
-
- SetPowerLevel(e);
- }
- }
-
- emcon = index;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-System::ExecFrame(double seconds)
-{
- if (seconds < 0.01)
- seconds = 0.01;
-
- STATUS s = DESTROYED;
-
- if (availability > 0.99)
- s = NOMINAL;
- else if (availability > crit_level)
- s = DEGRADED;
- else
- s = CRITICAL;
-
- bool repair = false;
-
- if (components.size() > 0) {
- ListIter<Component> comp = components;
- while (++comp) {
- if (comp->Status() > Component::NOMINAL) {
- repair = true;
- break;
- }
- }
- }
-
- if (repair) {
- Repair();
- }
-
- else {
- if (status != s) {
- status = s;
- NetUtil::SendSysStatus(ship, this);
- }
-
- // collateral damage due to unsafe operation:
- if (power_on && power_level > safety) {
- safety_overload += (float) seconds;
-
- // inflict some damage now:
- if (safety_overload > 60) {
- safety_overload -= (float) (rand() / (1000 * (power_level-safety)));
- ApplyDamage(15);
-
- NetUtil::SendSysStatus(ship, this);
- }
- }
-
- else if (safety_overload > 0) {
- safety_overload -= (float) seconds;
- }
- }
-}
-
-void
-System::Repair()
-{
- if (status != MAINT) {
- status = MAINT;
- safety_overload = 0.0f;
-
- NetUtil::SendSysStatus(ship, this);
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-System::ExecMaintFrame(double seconds)
-{
- if (components.size() > 0) {
- ListIter<Component> comp = components;
- while (++comp) {
- if (comp->Status() > Component::NOMINAL) {
- comp->ExecMaintFrame(seconds);
- }
- }
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-System::ApplyDamage(double damage)
-{
- if (!power_on)
- damage /= 10;
-
- if (components.size() > 0) {
- int index = rand() % components.size();
-
- if (damage > 50) {
- damage/=2;
- components[index]->ApplyDamage(damage);
-
- index = rand() % components.size();
- }
-
- components[index]->ApplyDamage(damage);
-
- if (safety < 0.5)
- SetPowerLevel(50);
-
- else if (safety < 1.0)
- SetPowerLevel(safety * 100);
- }
- else {
- availability -= (float) (damage/100.0f);
- if (availability < 0.01) availability = 0.0f;
- }
-}
-
-void
-System::CalcStatus()
-{
- if (components.size() > 0) {
- availability = 1.0f;
- safety = 1.0f;
- stability = 1.0f;
-
- ListIter<Component> comp = components;
- while (++comp) {
- if (comp->DamageEfficiency())
- availability *= comp->Availability() / 100.0f;
-
- if (comp->DamageSafety())
- safety *= comp->Availability() / 100.0f;
-
- if (comp->DamageStability())
- stability *= comp->Availability() / 100.0f;
-
- if (comp->IsJerried()) {
- safety *= 0.95f;
- stability *= 0.95f;
- }
- }
-
- if (net_avail >= 0 && availability < net_avail)
- availability = net_avail;
- }
-}
-
-// +--------------------------------------------------------------------+
-
-void
-System::Mount(Point loc, float rad, float hull)
-{
- mount_rel = loc;
- radius = rad;
- hull_factor = hull;
-}
-
-void
-System::Mount(const System& system)
-{
- mount_rel = system.mount_rel;
- radius = system.radius;
- hull_factor = system.hull_factor;
-}
-
-// +--------------------------------------------------------------------+
-
-void
-System::Orient(const Physical* rep)
-{
- const Matrix& orientation = rep->Cam().Orientation();
- Point loc = rep->Location();
-
- mount_loc = (mount_rel * orientation) + loc;
-}
-
-// +----------------------------------------------------------------------+
-
-double
-System::GetRequest(double seconds) const
-{
- if (!power_on || capacity == energy)
- return 0;
-
- else
- return power_level * sink_rate * seconds;
-}
-
-// +----------------------------------------------------------------------+
-
-void
-System::Distribute(double delivered_energy, double seconds)
-{
- if (UsesWatts()) {
- if (seconds < 0.01)
- seconds = 0.01;
-
- // convert Joules to Watts:
- energy = (float) (delivered_energy/seconds);
- }
-
- else if (!Game::Paused()) {
- energy += (float) delivered_energy;
-
- if (energy > capacity)
- energy = capacity;
-
- else if (energy < 0)
- energy = 0.0f;
- }
-}
-
-// +----------------------------------------------------------------------+
-
-void
-System::DrainPower(double to_level)
-{
- energy = 0.0f;
-}
+/* Starshatter OpenSource Distribution + Copyright (c) 1997-2004, Destroyer Studios LLC. + All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name "Destroyer Studios" nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + SUBSYSTEM: Stars.exe + FILE: System.cpp + AUTHOR: John DiCamillo + + + OVERVIEW + ======== + Generic Ship Subsystem class +*/ + +#include "MemDebug.h" +#include "System.h" +#include "SystemDesign.h" +#include "Component.h" +#include "NetUtil.h" + +#include "Game.h" + +// +----------------------------------------------------------------------+ + +System::System(System::CATEGORY t, int s, const char* n, int maxv, +double e, double c, double r) +: type(t), id(0), ship(0), subtype(s), status(NOMINAL), availability(1.0f), +safety(1.0f), stability(1.0f), crit_level(0.5f), net_avail(-1.0f), +mount_rel(0.0f, 0.0f, 0.0f), radius(0.0f), safety_overload(0.0f), +hull_factor(0.5f), energy((float) e), capacity((float) c), sink_rate((float) r), +power_level(1.0f), power_flags(0), source_index(0), power_on(true), +explosion_type(0), name(n), abrv(name), design(0), emcon(3) +{ + if (maxv < 100) + max_value = maxv; + else + max_value = (int) (maxv/100.0); + + emcon_power[0] = 100; + emcon_power[1] = 100; + emcon_power[2] = 100; +} + +// +----------------------------------------------------------------------+ + +System::System(const System& s) +: type(s.type), id(s.id), ship(0), subtype(s.subtype), status(s.status), +availability(s.availability), safety(s.safety), stability(s.stability), +crit_level(s.crit_level), net_avail(-1.0f), +mount_rel(s.mount_rel), radius(s.radius), safety_overload(0.0f), +hull_factor(s.hull_factor), energy(s.energy), capacity(s.capacity), +sink_rate(s.sink_rate), power_level(s.power_level), power_flags(s.power_flags), +source_index(s.source_index), power_on(s.power_on), max_value(s.max_value), +explosion_type(s.explosion_type), name(s.name), abrv(s.abrv), design(s.design), +emcon(s.emcon) +{ + if (design) { + // cast-away const + ListIter<Component> c = (List<Component>&) s.components; + while (++c) { + Component* comp = new(__FILE__,__LINE__) Component(*(c.value())); + comp->SetSystem(this); + components.append(comp); + } + } + + emcon_power[0] = s.emcon_power[0]; + emcon_power[1] = s.emcon_power[1]; + emcon_power[2] = s.emcon_power[2]; +} + +// +--------------------------------------------------------------------+ + +System::~System() +{ + components.destroy(); +} + +// +--------------------------------------------------------------------+ + +void +System::SetDesign(SystemDesign* d) +{ + if (design) { + design = 0; + components.destroy(); + } + + if (d) { + design = d; + + ListIter<ComponentDesign> cd = design->components; + while (++cd) { + Component* comp = new(__FILE__,__LINE__) Component(cd.value(), this); + components.append(comp); + } + } +} + +// +--------------------------------------------------------------------+ + +void +System::SetPowerLevel(double level) +{ + if (level > 100) + level = 100; + else if (level < 0) + level = 0; + + level /= 100; + + if (power_level != level) { + // if the system is on emergency override power, + // do not let the EMCON system use this method + // to drop it back to normal power: + if (power_level > 1 && level == 1) + return; + + power_level = (float) level; + + NetUtil::SendSysStatus(ship, this); + } +} + +void +System::SetOverride(bool over) +{ + bool changed = false; + + if (over && power_level != 1.2f) { + power_level = 1.2f; + changed = true; + } + + else if (!over && power_level > 1) { + power_level = 1.0f; + changed = true; + } + + if (changed) + NetUtil::SendSysStatus(ship, this); +} + +void +System::SetEMCONPower(int index, int power_level) +{ + if (index >= 1 && index <= 3) { + emcon_power[index-1] = (BYTE) power_level; + } +} + +int +System::GetEMCONPower(int index) +{ + if (index >= 1 && index <= 3) { + return emcon_power[index-1]; + } + + return 100; +} + +void +System::DoEMCON(int index) +{ + int e = GetEMCONPower(index); + + if (power_level * 100 > e || emcon != index) { + if (e == 0) { + PowerOff(); + } + else { + if (emcon != index) + PowerOn(); + + SetPowerLevel(e); + } + } + + emcon = index; +} + +// +--------------------------------------------------------------------+ + +void +System::ExecFrame(double seconds) +{ + if (seconds < 0.01) + seconds = 0.01; + + STATUS s = DESTROYED; + + if (availability > 0.99) + s = NOMINAL; + else if (availability > crit_level) + s = DEGRADED; + else + s = CRITICAL; + + bool repair = false; + + if (components.size() > 0) { + ListIter<Component> comp = components; + while (++comp) { + if (comp->Status() > Component::NOMINAL) { + repair = true; + break; + } + } + } + + if (repair) { + Repair(); + } + + else { + if (status != s) { + status = s; + NetUtil::SendSysStatus(ship, this); + } + + // collateral damage due to unsafe operation: + if (power_on && power_level > safety) { + safety_overload += (float) seconds; + + // inflict some damage now: + if (safety_overload > 60) { + safety_overload -= (float) (rand() / (1000 * (power_level-safety))); + ApplyDamage(15); + + NetUtil::SendSysStatus(ship, this); + } + } + + else if (safety_overload > 0) { + safety_overload -= (float) seconds; + } + } +} + +void +System::Repair() +{ + if (status != MAINT) { + status = MAINT; + safety_overload = 0.0f; + + NetUtil::SendSysStatus(ship, this); + } +} + +// +--------------------------------------------------------------------+ + +void +System::ExecMaintFrame(double seconds) +{ + if (components.size() > 0) { + ListIter<Component> comp = components; + while (++comp) { + if (comp->Status() > Component::NOMINAL) { + comp->ExecMaintFrame(seconds); + } + } + } +} + +// +--------------------------------------------------------------------+ + +void +System::ApplyDamage(double damage) +{ + if (!power_on) + damage /= 10; + + if (components.size() > 0) { + int index = rand() % components.size(); + + if (damage > 50) { + damage/=2; + components[index]->ApplyDamage(damage); + + index = rand() % components.size(); + } + + components[index]->ApplyDamage(damage); + + if (safety < 0.5) + SetPowerLevel(50); + + else if (safety < 1.0) + SetPowerLevel(safety * 100); + } + else { + availability -= (float) (damage/100.0f); + if (availability < 0.01) availability = 0.0f; + } +} + +void +System::CalcStatus() +{ + if (components.size() > 0) { + availability = 1.0f; + safety = 1.0f; + stability = 1.0f; + + ListIter<Component> comp = components; + while (++comp) { + if (comp->DamageEfficiency()) + availability *= comp->Availability() / 100.0f; + + if (comp->DamageSafety()) + safety *= comp->Availability() / 100.0f; + + if (comp->DamageStability()) + stability *= comp->Availability() / 100.0f; + + if (comp->IsJerried()) { + safety *= 0.95f; + stability *= 0.95f; + } + } + + if (net_avail >= 0 && availability < net_avail) + availability = net_avail; + } +} + +// +--------------------------------------------------------------------+ + +void +System::Mount(Point loc, float rad, float hull) +{ + mount_rel = loc; + radius = rad; + hull_factor = hull; +} + +void +System::Mount(const System& system) +{ + mount_rel = system.mount_rel; + radius = system.radius; + hull_factor = system.hull_factor; +} + +// +--------------------------------------------------------------------+ + +void +System::Orient(const Physical* rep) +{ + const Matrix& orientation = rep->Cam().Orientation(); + Point loc = rep->Location(); + + mount_loc = (mount_rel * orientation) + loc; +} + +// +----------------------------------------------------------------------+ + +double +System::GetRequest(double seconds) const +{ + if (!power_on || capacity == energy) + return 0; + + else + return power_level * sink_rate * seconds; +} + +// +----------------------------------------------------------------------+ + +void +System::Distribute(double delivered_energy, double seconds) +{ + if (UsesWatts()) { + if (seconds < 0.01) + seconds = 0.01; + + // convert Joules to Watts: + energy = (float) (delivered_energy/seconds); + } + + else if (!Game::Paused()) { + energy += (float) delivered_energy; + + if (energy > capacity) + energy = capacity; + + else if (energy < 0) + energy = 0.0f; + } +} + +// +----------------------------------------------------------------------+ + +void +System::DrainPower(double to_level) +{ + energy = 0.0f; +} |