00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <map>
00024
00025 #include "FSServer.h"
00026
00027 #include "Bombing.h"
00028 #include "Component.h"
00029 #include "algorithm"
00030
00031 #ifdef _DEBUG
00032 #define new DEBUG_NEW
00033 #endif
00034
00035
00036 Bombing::Bombing(const Location & loc) : Location(loc)
00037 {
00038 mTargetPlanet = NULL;
00039 mPopulationLoss = 0;
00040 mMinesLoss = mFactoriesLoss = mDefensesLoss = 0;
00041 }
00042
00043
00044 Bombing::~Bombing()
00045 {
00046 }
00047
00048 void Bombing::SetPlanet(Planet* targetPlanet)
00049 {
00050 mTargetPlanet = targetPlanet;
00051 }
00052
00053 void Bombing::AddFleets()
00054 {
00055
00056 for (unsigned int j = 0; j < TheGame->NumberPlayers(); ++j )
00057 {
00058 Player* player = TheGame->NCGetPlayer(j);
00059
00060 if(player->AddBombingFleets(this,mTargetPlanet->GetOwner(),BT_NORMAL))
00061 mNormalBombingPlayers.push_back(player);
00062
00063 if(player->AddBombingFleets(this,mTargetPlanet->GetOwner(),BT_SMART))
00064 mSmartBombingPlayers.push_back(player);
00065
00066 if(player->AddBombingFleets(this,mTargetPlanet->GetOwner(),BT_TERRA))
00067 mTerraBombingPlayers.push_back(player);
00068 }
00069 }
00070
00071 double Bombing::GetSmartKillper() const
00072 {
00073
00074
00075
00076
00077
00078
00079
00080 map<const Component*,int> bombtype_count;
00081
00082
00083 for (deque<Fleet*>::const_iterator k = mSmartBombingFleets.begin(); k != mSmartBombingFleets.end(); ++k)
00084 {
00085 for(deque<Stack>::const_iterator i = (*k)->mStacks.begin(); i != (*k)->mStacks.end(); ++i)
00086 {
00087 for(deque<Slot>::const_iterator j = i->mShip->mSlots.begin(); j != i->mShip->mSlots.end(); ++j )
00088 {
00089 const Component* comp = j->GetComp();
00090 if(comp->IsType(CT_BOMB) && comp->GetBombType() == BT_SMART)
00091 {
00092 if(bombtype_count.count(comp) == 0)
00093 bombtype_count[comp] = 1;
00094 else
00095 bombtype_count[comp]++;
00096 }
00097 }
00098 }
00099 }
00100
00101 double killper = 1;
00102 for (map<const Component*,int>::const_iterator t = bombtype_count.begin(); t != bombtype_count.end(); ++t)
00103 {
00104 double base = t->first->GetSmartKillper();
00105 double result = 1 - pow(base,t->second);
00106 killper *= result;
00107 }
00108
00109 return killper;
00110 }
00111
00112 void Bombing::DoPopulationLosses(const double& normal_killper, const long& normal_minimum , const double& smart_killper)
00113 {
00114 long population_loss = 0;
00115 long population = mTargetPlanet->GetPopulation();
00116 double normal_coverage = 1.0 - mTargetPlanet->GetDefenseValue();
00117 double smart_coverage = 1.0 - mTargetPlanet->GetSmartDefenseValue();
00118
00119
00120 if((normal_killper * normal_coverage * population) > (normal_minimum * normal_coverage))
00121 population_loss += static_cast<long>(normal_killper * normal_coverage * population);
00122 else
00123 population_loss += static_cast<long>(normal_minimum * normal_coverage);
00124
00125
00126 population_loss += static_cast<long>(smart_killper * smart_coverage);
00127
00128
00129 mTargetPlanet->AdjustPopulation(-mPopulationLoss);
00130 }
00131
00132 void Bombing::DoInstallationLosses(const long& installation_loss)
00133 {
00134 long installations_sum = mTargetPlanet->GetFactories() + mTargetPlanet->GetMines() + mTargetPlanet->GetDefenses();
00135 double coverage = 1.0 - mTargetPlanet->GetInstallationDefenseValue();
00136
00137
00138 if(long(installation_loss * coverage) > installations_sum)
00139 {
00140 mFactoriesLoss = mTargetPlanet->GetFactories();
00141 mMinesLoss = mTargetPlanet->GetMines();
00142 mDefensesLoss = mTargetPlanet->GetDefenses();
00143 }
00144 else
00145 {
00146 double factories_ratio, mines_ratio, defenses_ratio;
00147 factories_ratio = mTargetPlanet->GetFactories() / installations_sum;
00148 mines_ratio = mTargetPlanet->GetMines() / installations_sum;
00149 defenses_ratio = mTargetPlanet->GetDefenses() / installations_sum;
00150
00151 mFactoriesLoss = long(factories_ratio * installation_loss + 0.5);
00152 mDefensesLoss = long(defenses_ratio * installation_loss + 0.5);
00153 mMinesLoss = long(mines_ratio * installation_loss + 0.5);
00154 }
00155
00156
00157 mTargetPlanet->AdjustFactories(-mFactoriesLoss);
00158 mTargetPlanet->AdjustFactories(-mMinesLoss);
00159 mTargetPlanet->AdjustDefenses(-mDefensesLoss);
00160 }
00161
00162 void Bombing::DoTerraTransforming()
00163 {
00164 for (deque<Fleet*>::iterator k = mTerraBombingFleets.begin(); k != mTerraBombingFleets.end(); ++k)
00165 {
00166 (*k)->RemoteTerraform(true);
00167 }
00168 }
00169
00170 void Bombing::Resolve()
00171 {
00172
00173 if( mSmartBombingFleets.size() == 0 && mNormalBombingFleets.size() == 0 && mTerraBombingFleets.size() == 0)
00174 return;
00175
00176
00177 double normal_killper = 0.0;
00178 double smart_killper = 0.0;
00179 long normal_minimum = 0;
00180 long installation_loss = 0;
00181
00182
00183 for (deque<Fleet*>::iterator k = mNormalBombingFleets.begin(); k != mNormalBombingFleets.end(); ++k)
00184 {
00185 normal_killper += (*k)->GetNormalKillper();
00186 normal_minimum += (*k)->GetMinKill();
00187 installation_loss += (*k)->GetInstKill();
00188 }
00189
00190 smart_killper = GetSmartKillper();
00191
00192
00193 mNormalPercentageStopped = mTargetPlanet->GetDefenseValue();
00194 mSmartPercentageStopped = mTargetPlanet->GetSmartDefenseValue();
00195
00196
00197 DoPopulationLosses(normal_killper,normal_minimum,smart_killper);
00198
00199
00200 DoInstallationLosses(installation_loss);
00201
00202
00203
00204
00205 DoTerraTransforming();
00206
00207
00208 SendMessages();
00209 }
00210
00211 void Bombing::SendNormalMessages()
00212 {
00213
00214 if(mNormalBombingPlayers.size() == 0)
00215 return;
00216
00217
00218 Message * mess = mTargetPlanet->AddMessageOwner("PlanetBombed");
00219 mess->AddItem("Target", this);
00220 mess->AddLong("Population lost", mPopulationLoss);
00221 mess->AddFloat("Defense effectiveness", mNormalPercentageStopped);
00222 mess->AddLong("Factories lost", mFactoriesLoss);
00223 mess->AddLong("Mines lost", mMinesLoss);
00224 mess->AddLong("Defenses lost", mDefensesLoss);
00225
00226
00227 for (deque<Player*>::iterator i = mNormalBombingPlayers.begin(); i != mNormalBombingPlayers.end(); ++i)
00228 {
00229 Message * mess = (*i)->AddMessage("FleetBombed");
00230 mess->AddItem("Target", this);
00231 mess->AddLong("Population lost", mPopulationLoss);
00232 mess->AddFloat("Defense effectiveness", mNormalPercentageStopped);
00233 mess->AddLong("Installations lost", mFactoriesLoss + mMinesLoss + mDefensesLoss);
00234 }
00235 }
00236
00237 void Bombing::SendTerraMessages()
00238 {
00239
00240 if(mTerraBombingPlayers.size() == 0)
00241 return;
00242
00243
00244 Message * mess = mTargetPlanet->AddMessageOwner("PlanetTerraBombed");
00245 mess->AddItem("Target", this);
00246
00247
00248
00249
00250 for (deque<Player*>::iterator i = mTerraBombingPlayers.begin(); i != mTerraBombingPlayers.end(); ++i)
00251 {
00252 Message * mess = (*i)->AddMessage("FleetTerraBombed");
00253 mess->AddItem("Target", this);
00254
00255
00256 }
00257 }
00258
00259
00260 void Bombing::SendSmartMessages()
00261 {
00262
00263 if(mSmartBombingPlayers.size() == 0)
00264 return;
00265
00266
00267 Message * mess = mTargetPlanet->AddMessageOwner("PlanetSmartBombed");
00268 mess->AddItem("Target", this);
00269 mess->AddLong("Population lost", mPopulationLoss);
00270 mess->AddFloat("Defense effectiveness", mSmartPercentageStopped);
00271
00272
00273 for (deque<Player*>::iterator i = mSmartBombingPlayers.begin(); i != mSmartBombingPlayers.end(); ++i)
00274 {
00275 Message * mess = (*i)->AddMessage("FleetSmartBombed");
00276 mess->AddItem("Target", this);
00277 mess->AddLong("Population lost", mPopulationLoss);
00278 mess->AddFloat("Defense effectiveness", mSmartPercentageStopped);
00279 }
00280 }