gather.cpp

Go to the documentation of this file.
00001 /*
00002  * gather.cpp
00003  *
00004  *  Created on: Mar 20, 2013
00005  *      Author: sushil
00006  */
00007 
00008 #include <ai/gather.h>
00009 #include "DEBUG.h"
00010 
00011 namespace FastEcslent {
00012 
00013         FastEcslent::Gather::Gather(Entity* ent, Target *target): UnitCommand(ent, GatherCommand, target) {
00014                 this->scv = dynamic_cast<SCVehicle *> (ent);
00015                 if (target->entity->entityType == MINERALS){
00016                         this->mineralEntity = dynamic_cast<Minerals *> (target->entity);
00017                         this->gasEntity = 0;
00018                 } else {
00019                         this->mineralEntity = 0;
00020                         this->gasEntity = dynamic_cast<Gas *> (target->entity);
00021                 }
00022                 this->commandCenter = findNearestCommandCenter();
00023                 this->finished = false;
00024                 this->state    = MOVETOMINERALS;
00025         }
00026 
00027         inline bool Gather::done(){
00028                 return finished;
00029         }
00030 
00031         inline void Gather::init(){
00032                 this->commandCenter = findNearestCommandCenter();
00033                 this->state = MOVETOMINERALS;
00034                 this->finished = false;
00035                 if(mineralEntity){
00036                         this->mineralEntity->miners++;
00037                 }
00038         }
00039 
00047         inline void Gather::postProcess(){
00048                 if(target->entity->entityType == MINERALS){
00049                         Minerals* min = dynamic_cast<Minerals *> (target->entity);
00050                         min ->miners--;
00051                         if(min->miner == this->entity){
00052                                 min->miner = 0;
00053                         }
00054                 }
00055         }
00056 
00057         inline void Gather::switchState(GatherState newState){
00058                 this->state = newState;
00059                 switch(newState){
00060                 case RETURNTOCC:
00061                         this->commandCenter = findNearestCommandCenter();
00062                         break;
00063                 case GATHERINGMINERALS:
00064                         this->scv->mineralCount = 0; //what happens if you run out of minerals while gathering?
00065                         this->scv->gasCount = 0;
00066                         //if time to find a less utilized mineral ent, find and set your mineralEntity
00067                         break;
00068                 case MOVETOMINERALS:
00069                         this->entity->engine->gameMgr->resources[this->scv->entityId.player].minerals += this->scv->mineralCount; // should be 0 or maxMineralCount
00070                         this->entity->engine->gameMgr->resources[this->scv->entityId.player].gas += this->scv->gasCount; // should be 0 or maxMineralCount
00071                         break;
00072                 default:
00073                         break;
00074                 }
00075         }
00076 
00077         inline void Gather::tick(double dt){
00078                 switch(this->state){
00079                 case RETURNTOCC:
00080                         //this->commandCenter = findNearestCommandCenter();
00081                         moveToEntityTick(this->commandCenter, dt);
00082 
00083                         break;
00084 
00085                 case GATHERINGMINERALS:
00086                         gatherTick(dt);
00087                         //checks for switching in gatherTick
00088                         break;
00089 
00090                 case MOVETOMINERALS:
00091                         moveToEntityTick(this->target->entity, dt);
00092 
00093                         break;
00094                 default:
00095                         break;
00096                 }
00097         }
00098 
00099         void Gather::switchMoveToState(){
00100                 if (this->state == MOVETOMINERALS) {
00101                         switchState(GATHERINGMINERALS);
00102                 } else if (this->state == RETURNTOCC){
00103                         //increment player minerals by 5 == mineralCount == maxMineralCount here
00104                         switchState(MOVETOMINERALS);
00105                 }
00106         }
00107 
00114         inline void Gather::moveToEntityTick(Entity *targetEnt, double dt){
00115                 if(!targetEnt){
00116                         DEBUG(std::cout << "No target ent: state: " << this->state << std::endl;)
00117                         return;
00118                 }
00119                 relativePos = targetEnt->pos - this->entity->pos;
00120                 if (relativePos.length() < this->scv->length * 2) {  //in front of mineral
00121                         if(this->mineralEntity && this->mineralEntity->miner){   //check if it is mining by another SCV
00122                                 Minerals* mineral = this->mineralEntity->engine->gameMgr->getMineralPatch(this->mineralEntity->mineralPatchId)->getNextMineral(this->mineralEntity); //check if there is optimal one
00123                                 if(mineral){ //if there is optimal, give up the original mineral and switch to the new mineral.
00124                                         this->mineralEntity->miners--;
00125                                         this->mineralEntity = mineral;
00126                                         this->mineralEntity->miners++;
00127                                         return;
00128                                 }
00129                         }
00130                         this->entity->desiredHeading = this->entity->heading;
00131                         this->entity->desiredSpeed = 0;
00132                         this->entity->speed = 0;
00133                         switchMoveToState();//and count additional resources if scv was at CC
00134 
00135                 } else {
00136                         this->entity->desiredHeading = -atan2(relativePos.z, relativePos.x);
00137                         this->entity->desiredSpeed = this->entity->maxSpeed;
00138                 }
00139         }
00140 
00141 
00148         inline void Gather::gatherTick(double dt){
00149                 //Mining Minerals
00150                 if(this->mineralEntity && (!this->mineralEntity->miner || this->mineralEntity->miner == this->entity )){ //nobody mining, start to mine
00151                         float mineralsGathered = this->scv->mineralGatherRate * dt; // how does this change with number of scvs?
00152                         float fractionOverMaxMineralsPerTrip = 0.0f;
00153                         this->scv->mineralCount += mineralsGathered;
00154                         this->mineralEntity->mineralAmount -= mineralsGathered;
00155                         this->mineralEntity->miner = this->entity;
00156                         if(this->scv->mineralCount >= this->scv->maxMineralCount){
00157                                 fractionOverMaxMineralsPerTrip = this->scv->maxMineralCount - this->scv->mineralCount;
00158                                 this->mineralEntity->mineralAmount += fractionOverMaxMineralsPerTrip; // give back the fraction
00159                                 this->scv->gasCount = 0;
00160                                 this->scv->mineralCount = this->scv->maxMineralCount;
00161                                 this->mineralEntity->miner = 0;
00162                                 switchState(RETURNTOCC);
00163                         }
00164                         // If you run out of minerals
00165                         if(this->mineralEntity->mineralAmount <= 0.0f){
00166                                 Entity *ent = this->entity->engine->gameMgr->findClosestEntityOfTypeWithinDistance(MINERALS, this->entity->pos, MaxMineralFindingDistance, this->entity->entityId.side, this->entity->entityId.player);
00167                                 if(ent){
00168                                         this->mineralEntity = dynamic_cast<Minerals *> (ent);
00169                                 } else {
00170                                         switchState(STOPPED);
00171                                 }
00172                         }
00173                 }
00174                 //Mining Gas
00175                 else if(this->gasEntity && (!this->gasEntity->miner || this->gasEntity->miner == this->entity )){
00176                         float gasGathered = this->scv->gasGatherRate * dt; // how does this change with number of scvs?
00177                         float fractionOverMaxMineralsPerTrip = 0.0f;
00178                         this->scv->gasCount += gasGathered;
00179                         this->gasEntity->gasAmount -= gasGathered;
00180                         this->gasEntity->miner = this->entity;
00181                         if(this->scv->gasCount >= this->scv->maxGasCount){
00182                                 fractionOverMaxMineralsPerTrip = this->scv->maxGasCount - this->scv->gasCount;
00183                                 this->gasEntity->gasAmount += fractionOverMaxMineralsPerTrip; // give back the fraction
00184                                 this->scv->mineralCount = 0;
00185                                 this->scv->gasCount = this->scv->maxGasCount;
00186                                 this->gasEntity->miner = 0;
00187                                 switchState(RETURNTOCC);
00188                         }
00189                         // If you run out of minerals
00190                         if(this->gasEntity->gasAmount <= 0.0f){
00191                                 switchState(STOPPED);
00192                         }
00193                 }
00194         }
00195 
00196 
00197         FastEcslent::CommandCenter * FastEcslent::Gather::findNearestCommandCenter(){
00198                 DEBUG(std::cout << "***************************Finding closest Command Center: " << std::endl;)
00199                 Entity *ent = this->entity->engine->gameMgr->findClosestEntityOfTypeWithinDistance(COMMANDCENTER, this->entity->pos, FLT_MAX, this->entity->entityId.side, this->entity->entityId.player);
00200                 if (ent){
00201                         DEBUG(std::cout << "-----------------Found command center: -------------" << ent->uiname  << std::endl;)
00202                         return dynamic_cast<CommandCenter*>(ent);
00203                 } else {
00204                         DEBUG(std::cout << "********************************************No command center found" << std::endl;)
00205                         return 0;
00206                 }
00207         }
00208 
00209 }

Generated on Fri Dec 13 14:54:16 2013 for FastECSLent by  doxygen 1.5.4