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 }