Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List

Stack.cpp

00001 /*
00002 Copyright 2003 - 2005 Elliott Kleinrock, Dan Neely, Kurt W. Over, Damon Domjan
00003 
00004 This file is part of FreeStars, a free clone of the Stars! game.
00005 
00006 FreeStars is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 FreeStars is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with FreeStars; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 The full GPL Copyright notice should be in the file COPYING.txt
00021 
00022 Contact:
00023 Email Elliott at 9jm0tjj02@sneakemail.com
00024 */
00025 
00026 #include "FSServer.h"
00027 
00028 #include "Stack.h"
00029 
00030 #include "Hull.h"
00031 
00032 #ifdef _DEBUG
00033 #define new DEBUG_NEW
00034 #endif
00035 
00036 Stack::~Stack()
00037 {
00038 }
00039 
00040 void Stack::AddFromFleet(long fleet, long ships, long damaged)
00041 {
00042         assert(ships <= mShips);
00043         assert(damaged <= mDamaged);
00044         deque<Origin>::iterator iter;
00045         for (iter = mOrigins.begin(); iter != mOrigins.end(); ++iter) {
00046                 if (iter->fleet == fleet)
00047                         break;
00048         }
00049 
00050         if (iter == mOrigins.end()) {
00051                 iter = mOrigins.insert(mOrigins.end(), Origin());
00052                 iter->fleet = fleet;
00053         }
00054 
00055         iter->ships += ships;
00056         iter->damaged += damaged;
00057 }
00058 
00059 bool Stack::ParseNode(const TiXmlNode * node, Player * owner)
00060 {
00061         long num = GetLong(node->FirstChild("ShipDesign"), -1);
00062         if (num < 1 || num > Rules::GetConstant("MaxShipDesigns")) {
00063                 Message * mess = owner->AddMessage("Error: Invalid ship design number");
00064                 mess->AddLong("", num);
00065                 return false;
00066         }
00067 
00068         mShip = owner->GetShipDesign(num);
00069         mShips = GetLong(node->FirstChild("ShipCount"));
00070         if (mShips < 1 || mShips > Rules::GetConstant("MaxShips")) {
00071                 Message * mess = owner->AddMessage("Error: Invalid number of ships");
00072                 mess->AddLong(mShip->GetName().c_str(), mShips);
00073                 return false;
00074         }
00075 
00076         mDamaged = GetLong(node->FirstChild("Damaged"));
00077         if (mDamaged < 0 || mDamaged > mShips) {
00078                 Message * mess = owner->AddMessage("Error: Invalid number of damaged ships");
00079                 mess->AddLong(mShip->GetName().c_str(), mDamaged);
00080                 return false;
00081         }
00082 
00083         mDamage = GetLong(node->FirstChild("Damage"));
00084         // extra check of Damage > 0 so it doesn't have to calc GetArmor if not needed
00085         if (mDamage < 0 || (mDamage > 0 && mDamage > mShip->GetArmor(owner))) {
00086                 Message * mess = owner->AddMessage("Error: Invalid amount of damage");
00087                 mess->AddLong(mShip->GetName().c_str(), mDamage);
00088                 return false;
00089         }
00090 
00091         return true;
00092 }
00093 
00094 void Stack::WriteNode(TiXmlNode * node, const Player * owner, const Player * viewer) const
00095 {
00096         AddLong(node, "ShipDesign", owner->GetShipNumber(mShip)+1);
00097         AddLong(node, "ShipCount", mShips);
00098         if (mDamaged > 0 && viewer == NULL || viewer == owner) {
00099                 AddLong(node, "Damaged", mDamaged);
00100                 AddLong(node, "Damage", mDamage);
00101         }
00102 }
00103 
00104 void Stack::WriteNode(TiXmlNode * node) const
00105 {
00106         AddLong(node, "Owner", mFleetIn->GetOwner()->GetID());
00107         WriteNode(node, NULL, NULL);
00108 
00109         // add battle stuff
00110         AddLong(node, "Armor", bArmor);
00111         AddLong(node, "Shield", bShield);
00112         AddLong(node, "Speed", bSpeed);
00113         AddLong(node, "XPos", bx);
00114         AddLong(node, "YPos", by);
00115         mFleetIn->GetBattlePlan()->WriteNodeBattle(node);
00116 }
00117 
00118 void Stack::SetupBase(const Planet * planet)
00119 {
00120         mFleetIn = NULL;
00121         mDamage = planet->GetBaseDamage();
00122         if (mDamage > 0)
00123                 mDamaged = 1;
00124         else
00125                 mDamaged = 0;
00126 
00127         mShip = planet->GetBaseDesign();
00128         mShips = 1;
00129         bShips = 1;
00130         bArmor = mShip->GetArmor(planet->GetOwner()) - mDamage;
00131         bIsBase = true;
00132         bMass = 0;      // not strictly true, but base mass isn't needed
00133         bShield = mShip->GetShield(planet->GetOwner());
00134         bSpeed = 0;
00135         bPlan = BPT_MAXDAM;
00136         bFlee = 0;
00137 }
00138 
00139 void Stack::SetupShips(const Player * owner, long cargo)
00140 {
00141         bShips = mShips;
00142         bArmor = mShip->GetArmor(owner) * GetCount() - GetDamage() * GetDamaged();
00143         assert(bArmor > 0);
00144         bShield = mShip->GetShield(owner) * GetCount();
00145         bSpeed = mShip->GetNetSpeed();
00146         bMass = mShip->GetMass();
00147         bMass += cargo;
00148         bSpeed -= bMass / (70 * mShip->GetHull()->GetSlot(0).GetCount());
00149         bSpeed += long(owner->BattleSpeedBonus() * 4 + .1);
00150         if (bSpeed > 10)
00151                 bSpeed = 10;
00152         if (bSpeed < 2)
00153                 bSpeed = 2;
00154         long lmin = long(bMass * 0.85 + .5);
00155         long lmax = long(bMass * 1.15 + .5);
00156         bMass = Random(lmin, lmax);
00157         bPlan = mFleetIn->GetBattlePlan()->GetTactic();
00158         bFlee = 0;
00159 }
00160 
00161 bool Stack::KillShips(long count, bool salvage)
00162 {
00163         if (count <= 0)
00164                 return false;
00165 
00166         if (count > GetCount())
00167                 count = GetCount();
00168 
00169         Salvage * sal = NULL;
00170         if (salvage)
00171                 sal = TheGalaxy->AddSalvage(*GetFleetIn());
00172 
00173         // lose a portion of the fleets cargo
00174         double cargolost = double(GetDesign()->GetFuelCapacity() * count) / GetFleetIn()->GetFuelCapacity();
00175         GetFleetIn()->AdjustFuel(-long(cargolost * GetFleetIn()->GetFuel() +.5));
00176 
00177         if (GetDesign()->GetCargoCapacity() > 0 && GetFleetIn()->GetCargoCapacity() > 0) {
00178                 cargolost = double(GetDesign()->GetCargoCapacity() * count) / GetFleetIn()->GetCargoCapacity();
00179                 GetFleetIn()->AdjustAmounts(POPULATION, -long(cargolost * GetFleetIn()->GetContain(POPULATION) + .5));
00180                 long amount;
00181                 for (int ct = 0; ct < Rules::MaxMinType; ++ct) {
00182                         amount = long(cargolost * GetFleetIn()->GetContain(ct) + .5);
00183                         GetFleetIn()->AdjustAmounts(ct, -amount);
00184                         if (salvage) {
00185                                 amount += GetDesign()->GetCost(GetFleetIn()->GetOwner())[ct] / 3;
00186                                 sal->AdjustAmounts(ct, amount);
00187                         }
00188                 }
00189         }
00190 
00191         SetCount(GetCount() - count);
00192         SetDamaged(GetDamaged() - count);       // kill damaged ships first
00193         if (GetCount() <= 0)
00194                 return true;
00195         else
00196                 return false;
00197 }
00198 
00199 long Stack::DamageAllShips(long damage)
00200 {
00201         long Result = 0;
00202         if (damage > GetDesign()->GetArmor(GetFleetIn()->GetOwner()))
00203                 Result = GetCount();
00204         else if (GetDamage() + damage > GetDesign()->GetArmor(GetFleetIn()->GetOwner())) {
00205                 Result = GetDamaged();
00206                 SetDamaged(GetCount());
00207                 SetDamage(damage);
00208         } else {
00209                 damage += long(GetDamage() * GetDamaged() / GetCount() + .5);
00210                 SetDamaged(GetCount());
00211                 SetDamage(damage);
00212         }
00213 
00214         return Result;
00215 }

Generated on Mon Aug 8 21:33:45 2005 for Freestars by  doxygen 1.4.2-20050421