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

Creation.cpp

00001 /*
00002 Copyright 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 #include "Creation.h"
00029 
00030 #include <math.h>
00031 #include <ctype.h>
00032 
00033 #ifdef _DEBUG
00034 #define new DEBUG_NEW
00035 #endif
00036 
00037 
00038 Creation::Creation()
00039 {
00040         LastP = NULL;
00041         mNameCount = 1;
00042         mHW = mPrePlacedHWs.begin();
00043 }
00044 
00045 Creation::~Creation()
00046 {
00047 }
00048 
00049 bool Creation::LoadCreation(const TiXmlNode * options)
00050 {
00051         const TiXmlNode * child1;
00052         if (!options)
00053                 return false;
00054 
00055         mWorlds = GetLong(options->FirstChild("Worlds"));
00056         if (mWorlds <= 0) {
00057                 return false;
00058         }
00059 
00060         mMinDistance = GetLong(options->FirstChild("MinDistance"));
00061         if (mMinDistance < 1) {
00062                 return false;
00063         }
00064 
00065         mClusterOdds = GetDouble(options->FirstChild("ClusterOdds"));
00066         mClusterOddsDegrade = GetDouble(options->FirstChild("ClusterOddsDegrade"));
00067         mClusterMaxDistance = GetLong(options->FirstChild("ClusterMaxDistance"));
00068 
00069         if (mClusterOdds < 0.0 || mClusterOdds >= 1.0) {
00070                 return false;
00071         }
00072 
00073         if (mClusterOddsDegrade < 0.0 || mClusterOddsDegrade > mClusterOdds) {
00074                 return false;
00075         }
00076 
00077         if (mClusterMaxDistance <= mMinDistance) {
00078                 return false;
00079         }
00080 
00081         mCurrClusterOdds = mClusterOdds;
00082 
00083         mStartPositionCount = GetLong(options->FirstChild("StartPositionCount"));
00084         mStartPositionMin = GetLong(options->FirstChild("StartPositionMin"));
00085         mStartPositionMax = GetLong(options->FirstChild("StartPositionMax"));
00086         if (mStartPositionCount > 0) {
00087                 if (mStartPositionMin >= mStartPositionMax) {
00088                         return false;
00089                 }
00090                 if (mStartPositionMin <= 10) {
00091                         return false;
00092                 }
00093                 if (mStartPositionMax <= 100) {
00094                         return false;
00095                 }
00096         } else if (mStartPositionCount < 0) {
00097                 return false;
00098         }
00099 
00100 //      mMapFile = options->FirstChild("MapFile"));
00101 
00102         child1 = options->FirstChild("HomeWorld");
00103         if (child1 == NULL) {
00104                 return false;
00105         }
00106 
00107         mHWBasePop = GetLong(child1->FirstChild("BasePop"), 25000);
00108         mHWPopBonus = GetLong(child1->FirstChild("BonusTimesGR"), 500000);
00109         mHWFactories = GetLong(child1->FirstChild("Factories"), 10);
00110         mHWMines = GetLong(child1->FirstChild("Mines"), 10);
00111         mHWDefenses = GetLong(child1->FirstChild("Defenses"), 10);
00112 
00113         child1 = options->FirstChild("SecondWorld");
00114         if (!child1)
00115                 mSecondaryWorlds = false;
00116         else {
00117                 mSecondaryWorlds = true;
00118 
00119                 mPopMultiplierFor2nd = GetDouble(child1->FirstChild("PopMultiplierFor2nd"), 0.8);
00120                 if (mPopMultiplierFor2nd < .01) {
00121                         return false;
00122                 }
00123 
00124                 mSecondaryPop = GetDouble(child1->FirstChild("SecondaryPop"), 0.5);
00125                 if (mSecondaryPop < .01) {
00126                         return false;
00127                 }
00128 
00129                 mSWFactories = GetLong(child1->FirstChild("Factories"), 4);
00130                 mSWMines = GetLong(child1->FirstChild("Mines"), 10);
00131                 mSWDefenses = GetLong(child1->FirstChild("Defenses"), 0);
00132                 mSWMaxMin = GetLong(child1->FirstChild("MaxMinerals"), 300);
00133                 mSWMinMin = GetLong(child1->FirstChild("MinMinerals"), 100);
00134                 mMinSWDistance = GetLong(child1->FirstChild("MinDistance"), 100);
00135                 mMaxSWDistance = GetLong(child1->FirstChild("MaxDistance"), 300);
00136         }
00137 
00138         return true;
00139 }
00140 
00141 bool Creation::LoadNames(const char * NameFile)
00142 {
00143         if (!NameFile || !*NameFile)
00144                 return false;
00145 
00146         FILE * f = fopen(NameFile, "r");
00147         if (!f)
00148                 return false;
00149         
00150         char ptr[128];
00151         char * rv = ptr;
00152         while (rv != NULL) {
00153                 rv = fgets(ptr, 80, f);
00154                 while (isspace(ptr[strlen(ptr)-1]))
00155                         ptr[strlen(ptr)-1] = '\0';
00156 
00157                 if (rv != NULL)
00158                         mNames.push_back(ptr);
00159         }
00160 
00161         Random_Shuffle(mNames.begin(), mNames.end());
00162         mNamePos = mNames.begin();
00163 
00164         if (mNames.size() < mWorlds) {
00165                 return false;
00166         } else
00167                 return true;
00168 }
00169 
00170 void Creation::SetLocation(Planet * p)
00171 {
00172         int count = 0;
00173         long dist = 0;
00174         bool inCluster = Randodd(mCurrClusterOdds);
00175 
00176         while (count++ < 1000 || dist == 0) {   // hard coded max to planet placement for safety
00177                 if (LastP == NULL || !inCluster) {
00178                         p->SetPosX(Random(TheGalaxy->MinX(), TheGalaxy->MaxX()));
00179                         p->SetPosY(Random(TheGalaxy->MinY(), TheGalaxy->MaxY()));
00180                 } else {
00181                         // this gives higher density for nearby planets then distant ones
00182                         double angle = genrand_real2() * 2.0 * 3.1415926535;
00183                         long range = Random(mMinDistance, mClusterMaxDistance) + 1;
00184                         p->SetPosX(LastP->GetPosX() + long(sin(angle) * range));
00185                         if (p->GetPosX() < TheGalaxy->MinX() || p->GetPosX() >= TheGalaxy->MaxX())
00186                                 continue;
00187 
00188                         p->SetPosY(LastP->GetPosY() + long(cos(angle) * range));
00189                         if (p->GetPosY() < TheGalaxy->MinY() || p->GetPosY() >= TheGalaxy->MaxY())
00190                                 continue;
00191                 }
00192 
00193                 const Planet * cp = TheGalaxy->ClosestPlanet(p);
00194                 if (cp == NULL)
00195                         break; // first planet, place it anywhere
00196 
00197                 dist = long(p->Distance(*cp));
00198                 if (dist >= mMinDistance)       // min mMinDistance is 1, so dist has to be >= 1
00199                         break;  // far enough apart, go with it
00200         }
00201 
00202         if (LastP && inCluster)
00203                 mCurrClusterOdds -= mClusterOddsDegrade;
00204         else
00205                 mCurrClusterOdds = mClusterOdds;
00206 
00207         LastP = p;
00208 }
00209 
00210 string Creation::GetNextName()
00211 {
00212         string name;
00213         do {
00214                 if (mNamePos == mNames.end()) {
00215                         mNamePos = mNames.begin();
00216                         mNameCount++;
00217                 }
00218 
00219                 name = *mNamePos++;
00220                 if (mNameCount > 1)
00221                         name += " #" + Long2String(mNameCount);
00222         } while (TheGalaxy->GetPlanet(name.c_str()) != NULL);
00223 
00224         return name;
00225 }
00226 
00227 Planet * Creation::GetSecond(const Player * p)
00228 {
00229         map<const Player *, Planet *>::iterator iter;
00230 
00231         iter = mSecondWorlds.find(p);
00232         if (iter == mSecondWorlds.end())
00233                 return NULL;
00234         else
00235                 return iter->second;
00236 }

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