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 #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
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) {
00177 if (LastP == NULL || !inCluster) {
00178 p->SetPosX(Random(TheGalaxy->MinX(), TheGalaxy->MaxX()));
00179 p->SetPosY(Random(TheGalaxy->MinY(), TheGalaxy->MaxY()));
00180 } else {
00181
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;
00196
00197 dist = long(p->Distance(*cp));
00198 if (dist >= mMinDistance)
00199 break;
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 }