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 #ifdef _DEBUG
00029 #define new DEBUG_NEW
00030 #endif
00031 
00032 BattlePlan::BattlePlan(bool defined)
00033 {
00034         mDefined = defined;
00035         SetDefault();
00036 }
00037 
00038 BattlePlan::~BattlePlan()
00039 {
00040 }
00041 
00042 void BattlePlan::SetDefault()
00043 {
00044         
00045         mPrimary = HC_ARMED;
00046         mSecondary = HC_ALL;
00047         mTactic = BPT_MAXRATIO;
00048         mEnemy = BPE_ENEMY;
00049         mDumpCargo = false;
00050 }
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 bool BattlePlan::ParseNode(const TiXmlNode * node, Player * owner)
00064 {
00065         const char * ptr;
00066 
00067         int num;
00068         node->ToElement()->Attribute("IDNumber", &num);
00069         if (num < 0 || num >= Rules::GetConstant("MaxBattlePlans")) {
00070                 Message * mess = owner->AddMessage("Error: Invalid battle plan number");
00071                 mess->AddLong("Battle Plan #", num);
00072                 return false;
00073         }
00074 
00075         ptr = GetString(node->FirstChild("Name"));
00076         if (!ptr) {
00077                 Message * mess = owner->AddMessage("Error: Battle Plan has no name");
00078                 mess->AddLong("Battle Plan #", num);
00079                 return false;
00080         }
00081 
00082         mName = ptr;
00083 
00084         ptr = GetString(node->FirstChild("PrimaryTarget"));
00085         if (ptr == NULL) {
00086                 Message * mess = owner->AddMessage("Error: Battle Plan has no Primary target");
00087                 mess->AddLong("Battle Plan #", num);
00088                 return false;
00089         }
00090 
00091         mPrimary = GetTarget(ptr);
00092         if (mPrimary == HC_UNKNOWN) {
00093                 Message * mess = owner->AddMessage("Error: Battle Plan has invalid Primary target");
00094                 mess->AddLong("Battle Plan #", num);
00095                 mess->AddItem("Battle Plan target", ptr);
00096                 return false;
00097         }
00098 
00099         ptr = GetString(node->FirstChild("SecondaryTarget"));
00100         if (ptr == NULL) {
00101                 Message * mess = owner->AddMessage("Error: Battle Plan has no Secondary target");
00102                 mess->AddLong("Battle Plan #", num);
00103                 return false;
00104         }
00105 
00106         mSecondary = GetTarget(ptr);
00107         if (mSecondary == HC_NONE) {
00108                 Message * mess = owner->AddMessage("Error: Battle Plan has invalid Secondary target");
00109                 mess->AddLong("Battle Plan #", num);
00110                 mess->AddItem("Battle Plan target", ptr);
00111                 return false;
00112         }
00113 
00114         ptr = GetString(node->FirstChild("Tactic"));
00115         if (ptr == NULL) {
00116                 Message * mess = owner->AddMessage("Error: Battle Plan has no tactic");
00117                 mess->AddLong("Battle Plan #", num);
00118                 return false;
00119         }
00120 
00121         if (stricmp(ptr, "Disengage") == 0)
00122                 mTactic = BPT_DISENGAGE;
00123         else if (stricmp(ptr, "DisengageIfChallenged") == 0)
00124                 mTactic = BPT_DISIFHIT;
00125         else if (stricmp(ptr, "MinimizeDamageSelf") == 0)
00126                 mTactic = BPT_MINDAM;
00127         else if (stricmp(ptr, "MaximizeNetDamage") == 0)
00128                 mTactic = BPT_MAXNET;
00129         else if (stricmp(ptr, "MaximizeDamageRatio") == 0)
00130                 mTactic = BPT_MAXRATIO;
00131         else if (stricmp(ptr, "MaximizeDamage") == 0)
00132                 mTactic = BPT_MAXDAM;
00133         else {
00134                 Message * mess = owner->AddMessage("Error: Battle Plan has invalid tactic");
00135                 mess->AddLong("Battle Plan #", num);
00136                 mess->AddItem("Battle Plan tactic", ptr);
00137                 return false;
00138         }
00139 
00140         ptr = GetString(node->FirstChild("AttackWho"));
00141         if (ptr == NULL) {
00142                 Message * mess = owner->AddMessage("Error: Battle Plan has no enemy");
00143                 mess->AddLong("Battle Plan #", num);
00144                 return false;
00145         }
00146 
00147         if (stricmp(ptr, "Nobody") == 0)
00148                 mEnemy = BPE_NONE;
00149         else if (stricmp(ptr, "Enemies") == 0)
00150                 mEnemy = BPE_ENEMY;
00151         else if (stricmp(ptr, "EnemiesNeutrals") == 0)
00152                 mEnemy = BPE_ENEMYNEUTRAL;
00153         else if (stricmp(ptr, "Everyone") == 0)
00154                 mEnemy = BPE_ALL;
00155         else {
00156                 unsigned long num = atol(ptr);
00157                 if (num > TheGame->NumberPlayers()) {
00158                         Message * mess = owner->AddMessage("Error: Battle Plan has invalid enemy");
00159                         mess->AddLong("Battle Plan #", num);
00160                         mess->AddItem("Battle Plan enemy", ptr);
00161                         return false;
00162                 }
00163         }
00164 
00165         ptr = GetString(node->FirstChild("DumpCargo"));
00166         if (ptr && stricmp(ptr, "true") == 0)
00167                 mDumpCargo = true;
00168 
00169         mDefined = true;
00170         return true;
00171 }
00172 
00173 void BattlePlan::WriteNode(TiXmlNode * node) const
00174 {
00175         AddString(node, "Name", mName.c_str());
00176         AddString(node, "PrimaryTarget", WriteTarget(mPrimary));
00177         AddString(node, "SecondaryTarget", WriteTarget(mSecondary));
00178         if (mTactic == BPT_DISENGAGE)
00179                 AddString(node, "Tactic", "Disengage");
00180         else if (mTactic == BPT_DISIFHIT)
00181                 AddString(node, "Tactic", "DisengageIfChallenged");
00182         else if (mTactic == BPT_MINDAM)
00183                 AddString(node, "Tactic", "MinimizeDamageSelf");
00184         else if (mTactic == BPT_MAXNET)
00185                 AddString(node, "Tactic", "MaximizeNetDamage");
00186         else if (mTactic == BPT_MAXRATIO)
00187                 AddString(node, "Tactic", "MaximizeDamageRatio");
00188         else if (mTactic == BPT_MAXDAM)
00189                 AddString(node, "Tactic", "MaximizeDamage");
00190         else {
00191                 TheGame->AddMessage("Error: Battle Plan has invalid Primary target");
00192                 AddString(node, "Tactic", "");
00193         }
00194 
00195         if (mEnemy == BPE_NONE)
00196                 AddString(node, "AttackWho", "Nobody");
00197         else if (mEnemy == BPE_ENEMY)
00198                 AddString(node, "AttackWho", "Enemies");
00199         else if (mEnemy == BPE_ENEMYNEUTRAL)
00200                 AddString(node, "AttackWho", "EnemiesNeutrals");
00201         else if (mEnemy == BPE_ALL)
00202                 AddString(node, "AttackWho", "Everyone");
00203         else
00204                 AddLong(node, "AttackWho", mEnemy);
00205 
00206         if (mDumpCargo)
00207                 AddString(node, "DumpCargo", "true");
00208 }
00209 
00210 void BattlePlan::WriteNodeBattle(TiXmlNode * node) const
00211 {
00212         AddString(node, "PrimaryTarget", WriteTarget(mPrimary));
00213         AddString(node, "SecondaryTarget", WriteTarget(mSecondary));
00214         if (mTactic == BPT_DISENGAGE)
00215                 AddString(node, "Tactic", "Disengage");
00216         else if (mTactic == BPT_DISIFHIT)
00217                 AddString(node, "Tactic", "DisengageIfChallenged");
00218         else if (mTactic == BPT_MINDAM)
00219                 AddString(node, "Tactic", "MinimizeDamageSelf");
00220         else if (mTactic == BPT_MAXNET)
00221                 AddString(node, "Tactic", "MaximizeNetDamage");
00222         else if (mTactic == BPT_MAXRATIO)
00223                 AddString(node, "Tactic", "MaximizeDamageRatio");
00224         else if (mTactic == BPT_MAXDAM)
00225                 AddString(node, "Tactic", "MaximizeDamage");
00226         else
00227                 AddString(node, "Tactic", "Unknown");
00228 }
00229 
00230 HullType BattlePlan::GetTarget(const char * ptr)
00231 {
00232         if (stricmp(ptr, "NoneDisengage") == 0)
00233                 return HC_NONE;
00234         else if (stricmp(ptr, "Any") == 0)
00235                 return HC_ALL;
00236         else if (stricmp(ptr, "Starbase") == 0)
00237                 return HC_BASE;
00238         else if (stricmp(ptr, "Armed") == 0)
00239                 return HC_ARMED;
00240         else if (stricmp(ptr, "BombersFreighters") == 0)
00241                 return HC_FREIGHTER | HC_BOMBER;
00242         else if (stricmp(ptr, "Unarmed") == 0)
00243                 return HC_UNARMED;
00244         else if (stricmp(ptr, "FuelXports") == 0)
00245                 return HC_FUEL;
00246         else if (stricmp(ptr, "Freighters") == 0)
00247                 return HC_FREIGHTER;
00248         else
00249                 return HC_UNKNOWN;
00250 }
00251 
00252 const char * BattlePlan::WriteTarget(HullType target)
00253 {
00254         if (target == HC_NONE)
00255                 return "NoneDisengage";
00256         else if (target == HC_ALL)
00257                 return "Any";
00258         else if (target == HC_BASE)
00259                 return "Starbase";
00260         else if (target == HC_ARMED)
00261                 return "Armed";
00262         else if (target == (HC_FREIGHTER | HC_BOMBER))
00263                 return "BombersFreighters";
00264         else if (target == HC_UNARMED)
00265                 return "Unarmed";
00266         else if (target == HC_FUEL)
00267                 return "FuelXports";
00268         else if (target == HC_FREIGHTER)
00269                 return "Freighters";
00270         else {
00271                 TheGame->AddMessage("Error: Battle Plan has invalid target");
00272                 return "";
00273         }
00274 }
00275 
00276 
00277 bool BattlePlan::WillFight(const Player * attacker, const Player * defender) const
00278 {
00279         if (attacker == defender)
00280                 return false;
00281         if (GetEnemy() == BPE_NONE)
00282                 return false;
00283         else if (GetEnemy() == BPE_ALL)
00284                 return true;
00285         else if (GetEnemy() == BPE_ENEMY)
00286                 return attacker->GetRelations(defender) <= PR_ENEMY;
00287         else if (GetEnemy() == BPE_ENEMYNEUTRAL)
00288                 return attacker->GetRelations(defender) <= PR_NEUTRAL;
00289         else
00290                 return GetEnemy() == defender->GetID();
00291 }