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

BattlePlan.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 #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         // defaults to a reasonable battle plan
00045         mPrimary = HC_ARMED;
00046         mSecondary = HC_ALL;
00047         mTactic = BPT_MAXRATIO;
00048         mEnemy = BPE_ENEMY;
00049         mDumpCargo = false;
00050 }
00051 
00052 /*
00053         <BattlePlan>
00054                 <BattlePlanNum>1</BattlePlanNum>
00055                 <BattlePlanName>Run like hell, but don't forget to shoot</BattlePlanName>
00056                 <PrimaryTarget>NoneDisengage</PrimaryTarget> <!-- NoneDisengage, Any, Starbase, Armed, BombersFreighters, Unarmed, FuelXports, Freighters -->
00057                 <SecondaryTarget>Any</SecondaryTarget> <!-- NoneDisengage, Any, Starbase, Armed, BombersFreighters, Unarmed, FuelXports, Freighters -->
00058                 <Tactic>DisengageIfChallenged</Tactic> <!-- Disengage, DisengageIfChallenged, MinimizeDamageSelf, MaximizeNetDamage, MaximizeDamageRatio, MaximizeDamage -->
00059                 <AttackWho>Enemies</AttackWho> <!-- Nobody, Enemies, EnemiesNeutrals, Everyone, 1, 2, 3, etc. (for player numbers)-->
00060                 <DumpCargo>True</DumpCargo>
00061         </BattlePlan>
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 // does 'attacker' want to fight 'defender'
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 }

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