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){
00016                         this->mineralEntity = dynamic_cast<Minerals *> (target->entity);
00017                 } else {
00018                         this->mineralEntity = 0;
00019                 }
00020                 this->commandCenter = findNearestCommandCenter();
00021                 this->finished = false;
00022                 this->state    = MOVETOMINERALS;
00023         }
00024 
00025         inline bool Gather::done(){
00026                 return finished;
00027         }
00028 
00029         inline void Gather::init(){
00030                 this->commandCenter = findNearestCommandCenter();
00031                 this->state = MOVETOMINERALS;
00032                 this->finished = false;
00033                 this->mineralEntity->miners++;
00034         }
00035 
00043         inline void Gather::postProcess(){
00044                 this->mineralEntity->miners--;
00045                 if(this->mineralEntity->miner == this->entity)
00046                         this->mineralEntity->miner = 0;
00047         }
00048 
00049         inline void Gather::switchState(GatherState newState){
00050                 this->state = newState;
00051                 switch(newState){
00052                 case RETURNTOCC:
00053                         this->commandCenter = findNearestCommandCenter();
00054                         break;
00055                 case GATHERINGMINERALS:
00056                         this->scv->mineralCount = 0; //what happens if you run out of minerals while gathering?
00057                         //if time to find a less utilized mineral ent, find and set your mineralEntity
00058                         break;
00059                 case MOVETOMINERALS:
00060                         this->entity->engine->gameMgr->resources[this->scv->entityId.player].minerals += this->scv->mineralCount; // should be 0 or maxMineralCount
00061                         break;
00062                 default:
00063                         break;
00064                 }
00065         }
00066 
00067         inline void Gather::tick(double dt){
00068                 switch(this->state){
00069                 case RETURNTOCC:
00070                         //this->commandCenter = findNearestCommandCenter();
00071                         moveToEntityTick(this->commandCenter, dt);
00072 
00073                         break;
00074 
00075                 case GATHERINGMINERALS:
00076                         gatherTick(dt);
00077                         //checks for switching in gatherTick
00078                         break;
00079 
00080                 case MOVETOMINERALS:
00081                         moveToEntityTick(this->mineralEntity, dt);
00082 
00083                         break;
00084                 default:
00085                         break;
00086                 }
00087         }
00088 
00089         void Gather::switchMoveToState(){
00090                 if (this->state == MOVETOMINERALS) {
00091                         switchState(GATHERINGMINERALS);
00092                 } else if (this->state == RETURNTOCC){
00093                         //increment player minerals by 5 == mineralCount == maxMineralCount here
00094                         switchState(MOVETOMINERALS);
00095                 }
00096         }
00097 
00104         inline void Gather::moveToEntityTick(Entity *targetEnt, double dt){
00105                 if(!targetEnt){
00106                         DEBUG(std::cout << "No target ent: state: " << this->state << std::endl;)
00107                         return;
00108                 }
00109                 relativePos = targetEnt->pos - this->entity->pos;
00110                 if (relativePos.length() < this->scv->length * 2) {  //in front of mineral
00111                         if(this->mineralEntity->miner){   //check if it is mining by another SCV
00112                                 Minerals* mineral = this->mineralEntity->patch->getNextMineral(this->mineralEntity); //check if there is optimal one
00113                                 if(mineral){ //if there is optimal, give up the original mineral and switch to the new mineral.
00114                                         this->mineralEntity->miners--;
00115                                         this->mineralEntity = mineral;
00116                                         this->mineralEntity->miners++;
00117                                         return;
00118                                 }
00119                         }
00120                         this->entity->desiredHeading = this->entity->heading;
00121                         this->entity->desiredSpeed = 0;
00122                         this->entity->speed = 0;
00123                         switchMoveToState();//and count additional resources if scv was at CC
00124 
00125                 } else {
00126                         this->entity->desiredHeading = -atan2(relativePos.z, relativePos.x);
00127                         this->entity->desiredSpeed = this->entity->maxSpeed;
00128                 }
00129         }
00130 
00131 
00138         inline void Gather::gatherTick(double dt){
00139                 if(!this->mineralEntity->miner || this->mineralEntity->miner == this->entity ){ //nobody mining, start to mine
00140                         float mineralsGathered = this->scv->mineralGatherRate * dt; // how does this change with number of scvs?
00141                         float fractionOverMaxMineralsPerTrip = 0.0f;
00142                         this->scv->mineralCount += mineralsGathered;
00143                         this->mineralEntity->mineralAmount -= mineralsGathered;
00144                         this->mineralEntity->miner = this->entity;
00145                         if(this->scv->mineralCount >= this->scv->maxMineralCount){
00146                                 fractionOverMaxMineralsPerTrip = this->scv->maxMineralCount - this->scv->mineralCount;
00147                                 this->mineralEntity->mineralAmount += fractionOverMaxMineralsPerTrip; // give back the fraction
00148                                 this->scv->mineralCount = this->scv->maxMineralCount;
00149                                 this->mineralEntity->miner = 0;
00150                                 switchState(RETURNTOCC);
00151                         }
00152                         // If you run out of minerals
00153                         if(this->mineralEntity->mineralAmount <= 0.0f){
00154                                 Entity *ent = this->entity->engine->gameMgr->findClosestEntityOfTypeWithinDistance(MINERALS, this->entity->pos, MaxMineralFindingDistance, this->entity->entityId.side, this->entity->entityId.player);
00155                                 if(ent){
00156                                         this->mineralEntity = dynamic_cast<Minerals *> (ent);
00157                                 } else {
00158                                         switchState(STOPPED);
00159                                 }
00160                         }
00161                 }
00162         }
00163 
00164 
00165         FastEcslent::CommandCenter * FastEcslent::Gather::findNearestCommandCenter(){
00166                 DEBUG(std::cout << "***************************Finding closest Command Center: " << std::endl;)
00167                 Entity *ent = this->entity->engine->gameMgr->findClosestEntityOfTypeWithinDistance(COMMANDCENTER, this->entity->pos, FLT_MAX, this->entity->entityId.side, this->entity->entityId.player);
00168                 if (ent){
00169                         DEBUG(std::cout << "-----------------Found command center: -------------" << ent->uiname  << std::endl;)
00170                         return dynamic_cast<CommandCenter*>(ent);
00171                 } else {
00172                         DEBUG(std::cout << "********************************************No command center found" << std::endl;)
00173                         return 0;
00174                 }
00175         }
00176 
00177 }

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