1 #pragma once 2 3 /** Handles an individual sector. 4 */ 5 6 namespace Gigalomania { 7 class Image; 8 class PanelPage; 9 class Button; 10 } 11 12 using namespace Gigalomania; 13 14 class Feature; 15 class Sector; 16 class PlayingGameState; 17 class Invention; 18 19 using std::vector; 20 using std::string; 21 using std::stringstream; 22 23 #include "TinyXML/tinyxml.h" 24 25 #include "common.h" 26 27 const int element_multiplier_c = 2; 28 const int n_gatherable_rate_c = 500; 29 const int max_grow_population_c = 500; 30 const int growth_rate_c = 200; // higher is slower; beware of having a growth rate too fast, as it means a killer strategy is just to wait around letting the population grow first 31 const int mine_rate_c = 30; // higher is slower 32 const int combat_rate_c = 50; // higher is slower combat 33 const int bombard_rate_c = 5; // higher is slower damage 34 const int max_gatherables_stored_c = 22; 35 36 bool isAirUnit(int epoch); 37 bool defenceNeedsMan(int epoch); 38 39 class Particle { 40 float xpos, ypos; // floats to allow for movement 41 int birth_time; 42 public: 43 Particle(); 44 getX()45 float getX() const { 46 return this->xpos; 47 } getY()48 float getY() const { 49 return this->ypos; 50 } setPos(float xpos,float ypos)51 void setPos(float xpos, float ypos) { 52 this->xpos = xpos; 53 this->ypos = ypos; 54 } getBirthTime()55 int getBirthTime() const { 56 return this->birth_time; 57 } 58 }; 59 60 class ParticleSystem { 61 protected: 62 vector<Particle> particles; 63 const Image *image; 64 float size; 65 66 public: ParticleSystem(const Image * image)67 ParticleSystem(const Image *image) : image(image), size(1.0f) { 68 } ~ParticleSystem()69 virtual ~ParticleSystem() { 70 } 71 setSize(float size)72 void setSize(float size) { 73 this->size = size; 74 } 75 76 void draw(int xpos, int ypos) const; 77 virtual void update()=0; 78 }; 79 80 class SmokeParticleSystem : public ParticleSystem { 81 float birth_rate; 82 int life_exp; 83 int last_emit_time; 84 float move_x, move_y; 85 public: 86 SmokeParticleSystem(const Image *image); ~SmokeParticleSystem()87 virtual ~SmokeParticleSystem() { 88 } 89 90 void setBirthRate(float birth_rate); setMove(float move_x,float move_y)91 void setMove(float move_x, float move_y) { 92 this->move_x = move_x; 93 this->move_y = move_y; 94 } setLifeExp(int life_exp)95 void setLifeExp(int life_exp) { 96 this->life_exp = life_exp; 97 } 98 99 virtual void update(); 100 }; 101 102 class Army { 103 int soldiers[n_epochs_c+1]; // unarmed men are soldiers[n_epochs_c]; // saved 104 int player; // no need to save, saved by caller 105 Sector *sector; // no need to save 106 PlayingGameState *gamestate; 107 108 public: 109 Army(PlayingGameState *gamestate, Sector *sector, int player); ~Army()110 ~Army() { 111 } 112 getPlayer()113 int getPlayer() const { 114 return this->player; 115 } getSector()116 Sector *getSector() const { 117 return this->sector; 118 } 119 int getTotal() const; 120 int getTotalMen() const; 121 bool any(bool include_unarmed) const; 122 int getStrength() const; 123 int getBombardStrength() const; getSoldiers(int index)124 int getSoldiers(int index) const { 125 return this->soldiers[index]; 126 } 127 void add(int i,int n); 128 void add(Army *army); 129 void remove(int i,int n); 130 void kill(int index); empty()131 void empty() { 132 for(int i=0;i<n_epochs_c+1;i++) 133 soldiers[i] = 0; 134 } 135 bool canLeaveSafely() const; 136 void retreat(bool only_air); 137 138 int getIndividualStrength(int i) const; 139 static int getIndividualStrength(int player, int i); 140 static int getIndividualBombardStrength(int i); 141 142 void saveState(stringstream &stream) const; 143 void loadStateParseXMLNode(const TiXmlNode *parent); 144 }; 145 146 class Element { 147 string name; 148 public: 149 enum Type { 150 GATHERABLE = 0, 151 OPENPITMINE = 1, 152 DEEPMINE = 2 153 }; 154 private: 155 Id id; 156 Type type; 157 158 public: 159 Element(const char *name,Id id,Type type); 160 ~Element(); 161 162 Image *getImage() const; getName()163 const char *getName() const { 164 return this->name.c_str(); 165 } getType()166 Type getType() const { 167 return this->type; 168 } 169 }; 170 171 class Design { 172 Invention *invention; 173 bool ergonomically_terrific; 174 int cost[N_ID]; 175 int save_id; 176 177 public: 178 Design(Invention *invention,bool ergonomically_terrific); 179 setCost(Id id,float cost)180 void setCost(Id id, float cost) { 181 this->cost[(int)id] = (int)(cost * element_multiplier_c); 182 } getCost(Id id)183 int getCost(Id id) { 184 return this->cost[(int)id]; 185 } isErgonomicallyTerrific()186 bool isErgonomicallyTerrific() const { 187 return this->ergonomically_terrific; 188 } getInvention()189 Invention *getInvention() const { 190 return this->invention; 191 } setSaveId(int save_id)192 void setSaveId(int save_id) { 193 this->save_id = save_id; 194 } getSaveId()195 int getSaveId() const { 196 return this->save_id; 197 } 198 199 static bool setupDesigns(); 200 }; 201 202 class Invention { 203 protected: 204 string name; 205 public: 206 enum Type { 207 UNKNOWN_TYPE = -1, 208 SHIELD = 0, 209 DEFENCE = 1, 210 WEAPON = 2, 211 N_TYPES = 3 212 }; 213 214 protected: 215 Type type; 216 int epoch; 217 vector<Design *> designs; 218 219 public: 220 Invention(const char *name,Type type,int epoch); 221 ~Invention(); 222 223 //int getRelativeEpoch(); 224 Image *getImage() const; getName()225 const char *getName() const { 226 return this->name.c_str(); 227 } getType()228 Type getType() const { 229 return this->type; 230 } getEpoch()231 int getEpoch() const { 232 return this->epoch; 233 } 234 void addDesign(Design *design); getNDesigns()235 size_t getNDesigns() const { 236 return this->designs.size(); 237 } getDesign(size_t i)238 Design *getDesign(size_t i) const { 239 return this->designs.at(i); 240 } 241 Design *findDesign(int save_id) const; 242 243 static Invention *getInvention(Invention::Type type,int epoch); 244 }; 245 246 class Weapon : public Invention { 247 int n_men; 248 public: Weapon(const char * name,int epoch,int n_men)249 Weapon(const char *name,int epoch,int n_men) : Invention(name,WEAPON,epoch) { 250 this->n_men = n_men; 251 } ~Weapon()252 ~Weapon() { 253 } getNMen()254 int getNMen() const { 255 return this->n_men; 256 } 257 }; 258 259 const int max_building_turrets_c = 4; 260 261 class Building { 262 private: 263 Type type; // saved 264 Sector *sector; 265 int health; // saved 266 int max_health; 267 int pos_x, pos_y; 268 int n_turrets; 269 int turret_man[max_building_turrets_c]; // saved 270 int turret_man_frame[max_building_turrets_c]; 271 PanelPage *building_button; 272 PanelPage *turret_buttons[max_building_turrets_c]; 273 PlayingGameState *gamestate; 274 275 public: 276 Building(PlayingGameState *gamestate, Sector *sector, Type type); 277 ~Building(); 278 getType()279 Type getType() const { 280 return this->type; 281 } getX()282 int getX() const { 283 return this->pos_x; 284 } getY()285 int getY() const { 286 return this->pos_y; 287 } getHealth()288 int getHealth() const { 289 return this->health; 290 } getMaxHealth()291 int getMaxHealth() const { 292 return this->max_health; 293 } addHealth(int v)294 void addHealth(int v) { 295 this->health += v; 296 if( this->health > this->max_health ) 297 this->health = this->max_health; 298 } 299 Image **getImages(); 300 void rotateDefenders(); getNDefenders()301 int getNDefenders() const { 302 int n = 0; 303 for(int i=0;i<n_turrets;i++) { 304 if( turret_man[i] != -1 ) 305 n++; 306 } 307 return n; 308 } getNDefenders(int type)309 int getNDefenders(int type) const { 310 int n = 0; 311 for(int i=0;i<n_turrets;i++) { 312 if( turret_man[i] == type ) 313 n++; 314 } 315 return n; 316 } 317 int getDefenderStrength() const; 318 void killIthDefender(int i); 319 void killDefender(int index); getBuildingButton()320 PanelPage *getBuildingButton() const { 321 return this->building_button; 322 } getNTurrets()323 int getNTurrets() const { 324 return this->n_turrets; 325 } 326 int getTurretMan(int turret) const; 327 int getTurretManFrame(int turret) const; 328 PanelPage *getTurretButton(int turret) const; 329 void clearTurretMan(int turret); 330 void setTurretMan(int turret, int epoch); 331 332 void saveState(stringstream &stream) const; 333 void loadStateParseXMLNode(const TiXmlNode *parent); 334 }; 335 336 class Sector { 337 vector<Feature *> features; 338 int xpos, ypos; // saved 339 int epoch; // saved 340 int player; // saved 341 bool is_shutdown; // saved 342 //int shutdown_player; 343 344 bool nuked; // saved 345 int nuke_by_player; // saved 346 int nuke_time; // saved 347 bool nuke_defence_animation; // saved 348 int nuke_defence_time; // saved 349 int nuke_defence_x; // saved 350 int nuke_defence_y; // saved 351 352 int population; // saved 353 int n_designers; // saved 354 int n_miners[N_ID]; // saved 355 int n_builders[N_BUILDINGS]; // saved 356 int n_workers; // saved 357 int n_famount; // saved 358 Design *current_design; // saved 359 Design *current_manufacture; // saved 360 int researched; // saved 361 int researched_lasttime; // saved 362 int manufactured; // saved 363 int manufactured_lasttime; // saved 364 int growth_lasttime; // saved 365 int mined_lasttime; // saved 366 int built_towers[n_players_c]; // for neutral sectors // saved 367 int built[N_BUILDINGS]; // NB: built[BUILDING_TOWER] should never be used // saved 368 int built_lasttime; // saved 369 370 int elements[N_ID]; // elements remaining // saved 371 int elementstocks[N_ID]; // elements mined // saved 372 int partial_elementstocks[N_ID]; // saved 373 374 void initTowerStuff(); 375 void consumeStocks(Design *design); 376 377 int getInventionCost() const; 378 int getManufactureCost() const; 379 bool inventions_known[3][n_epochs_c]; // not saved, inferred fom designs 380 vector<Design *> designs; // saved 381 382 static int getBuildingCost(Type type, int building_player); 383 void destroyBuilding(Type building_type,int client_player); 384 void destroyBuilding(Type building_type,bool silent,int client_player); 385 void updateWorkers(); 386 387 float getDefenceStrength() const; 388 void doCombat(int client_player); 389 void doPlayer(int client_player); 390 391 Design *loadStateParseXMLDesign(const TiXmlAttribute *attribute); 392 393 Building *buildings[N_BUILDINGS]; // saved 394 Army *assembled_army; 395 Army *stored_army; // saved 396 Army *armies[n_players_c]; // saved 397 int stored_defenders[n_epochs_c]; // saved 398 int stored_shields[4]; // saved 399 SmokeParticleSystem *smokeParticleSystem; 400 SmokeParticleSystem *jetParticleSystem; 401 SmokeParticleSystem *nukeParticleSystem; 402 SmokeParticleSystem *nukeDefenceParticleSystem; 403 404 PlayingGameState *gamestate; 405 public: 406 407 Sector(PlayingGameState *gamestate, int epoch, int xpos, int ypos, MapColour map_colour); 408 ~Sector(); 409 410 void createTower(int player,int population); 411 void destroyTower(bool nuked, int client_player); 412 bool canShutdown() const; 413 void shutdown(int client_player); isShutdown()414 bool isShutdown() const { 415 return this->is_shutdown; 416 } 417 Building *getBuilding(Type type) const; 418 int getNDefenders() const; 419 int getNDefenders(int type) const; 420 int getDefenderStrength() const; 421 void killDefender(int index); 422 bool canBuild(Type type) const; 423 bool canMine(Id id) const; 424 Design *canBuildDesign(Invention::Type type,int epoch) const; 425 bool canBuildDesign(Design *design) const; 426 bool canEverBuildDesign(Design *design) const; 427 void autoTrashDesigns(); 428 bool tryMiningMore() const; 429 bool usedUp() const; 430 void cheat(int client_player); // for testing 431 Design *knownDesign(Invention::Type type,int epoch) const; 432 Design *bestDesign(Invention::Type type,int epoch) const; 433 Design *canResearch(Invention::Type type,int epoch) const; 434 int getNDesigns() const; 435 //void consumeStocks(Design *design); 436 bool assembleArmy(int epoch,int n); 437 bool deployDefender(Building *building,int turret,int epoch); 438 void returnDefender(Building *building,int turret); 439 int getStoredDefenders(int epoch) const; 440 bool useShield(Building *building,int shield); 441 int getStoredShields(int shield) const; 442 void update(int client_player); 443 getNFeatures()444 int getNFeatures() const { 445 return this->features.size(); 446 } getFeature(int i)447 const Feature *getFeature(int i) const { 448 return this->features.at(i); 449 } getSmokeParticleSystem()450 const ParticleSystem *getSmokeParticleSystem() const { 451 return this->smokeParticleSystem; 452 } getSmokeParticleSystem()453 ParticleSystem *getSmokeParticleSystem() { 454 return this->smokeParticleSystem; 455 } getJetParticleSystem()456 const ParticleSystem *getJetParticleSystem() const { 457 return this->jetParticleSystem; 458 } getJetParticleSystem()459 ParticleSystem *getJetParticleSystem() { 460 return this->jetParticleSystem; 461 } getNukeParticleSystem()462 const ParticleSystem *getNukeParticleSystem() const { 463 return this->nukeParticleSystem; 464 } getNukeParticleSystem()465 ParticleSystem *getNukeParticleSystem() { 466 return this->nukeParticleSystem; 467 } getNukeDefenceParticleSystem()468 const ParticleSystem *getNukeDefenceParticleSystem() const { 469 return this->nukeDefenceParticleSystem; 470 } getNukeDefenceParticleSystem()471 ParticleSystem *getNukeDefenceParticleSystem() { 472 return this->nukeDefenceParticleSystem; 473 } 474 void setEpoch(int epoch); 475 int getEpoch() const; 476 int getBuildingEpoch() const; getXPos()477 int getXPos() const { 478 return xpos; 479 } getYPos()480 int getYPos() const { 481 return ypos; 482 } 483 484 int getPlayer() const; 485 int getActivePlayer() const; 486 487 void setCurrentDesign(Design *current_design); 488 const Design *getCurrentDesign() const; 489 void setCurrentManufacture(Design *current_manufacture); 490 const Design *getCurrentManufacture() const; 491 void inventionTimeLeft(int *halfdays,int *hours) const; 492 void manufactureTotalTime(int *halfdays,int *hours) const; 493 void manufactureTimeLeft(int *halfdays,int *hours) const; 494 bool inventionKnown(Invention::Type type,int epoch) const; 495 void trashDesign(Invention *invention); 496 void trashDesign(Design *design); 497 bool nukeSector(Sector *source); beingNuked(int * nuke_time)498 int beingNuked(int *nuke_time) const { 499 *nuke_time = this->nuke_time; 500 return nuke_by_player; 501 } isBeingNuked()502 bool isBeingNuked() const { 503 return nuke_by_player != -1; 504 } isNuked()505 bool isNuked() const { 506 return this->nuked; 507 } 508 void getNukePos(int *nuke_x, int *nuke_y) const; hasNuclearDefenceAnimation(int * nuke_defence_time,int * nuke_defence_x,int * nuke_defence_y)509 bool hasNuclearDefenceAnimation(int *nuke_defence_time, int *nuke_defence_x, int *nuke_defence_y) const { 510 *nuke_defence_time = this->nuke_defence_time; 511 *nuke_defence_x = this->nuke_defence_x; 512 *nuke_defence_y = this->nuke_defence_y; 513 return nuke_defence_animation; 514 } 515 516 void setElements(Id id,int n_elements); 517 void getElements(int *n,int *fraction,Id id) const; 518 bool anyElements(Id id) const; 519 void reduceElementStocks(Id id,int reduce); 520 void getElementStocks(int *n,int *fraction,Id id) const; 521 void getTotalElements(int *n,int *fraction,Id id) const; 522 523 void buildingTowerTimeLeft(int player,int *halfdays,int *hours) const; 524 void buildingTimeLeft(Type type,int *halfdays,int *hours) const; 525 526 void setPopulation(int population); 527 void setDesigners(int n_designers); 528 void setWorkers(int n_workers); 529 void setFAmount(int n_famount); 530 void setMiners(Id id,int n_miners); 531 void setBuilders(Type type,int n_builders); 532 533 int getPopulation() const; 534 int getSparePopulation() const; 535 int getAvailablePopulation() const; 536 int getDesigners() const; 537 int getWorkers() const; 538 int getFAmount() const; 539 int getMiners(Id id) const; 540 int getBuilders(Type type) const; getAssembledArmy()541 const Army *getAssembledArmy() const { 542 return assembled_army; 543 } getAssembledArmy()544 Army *getAssembledArmy() { 545 return assembled_army; 546 } getStoredArmy()547 const Army *getStoredArmy() const { 548 return stored_army; 549 } getStoredArmy()550 Army *getStoredArmy() { 551 return stored_army; 552 } 553 const Army *getArmy(int player) const; 554 Army *getArmy(int player); 555 bool enemiesPresent() const; 556 bool enemiesPresentWithBombardment() const; 557 bool enemiesPresent(int player) const; 558 bool enemiesPresent(int player,bool include_unarmed) const; 559 void returnAssembledArmy(); 560 bool returnArmy(); 561 bool returnArmy(Army *army); 562 bool moveArmy(Army *army); 563 void evacuate(); 564 void assembleAll(bool include_unarmed); 565 bool mineElement(int client_player, Id i); 566 void invent(int client_player); 567 void buildDesign(); 568 void buildBuilding(Type type); 569 void updateForNewBuilding(Type type); 570 571 void saveState(stringstream &stream) const; 572 void loadStateParseXMLNode(const TiXmlNode *parent); 573 574 void printDebugInfo() const; 575 }; 576