00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
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;
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
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);
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 }