00001
00002
00003
00004
00005
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;
00057
00058 break;
00059 case MOVETOMINERALS:
00060 this->entity->engine->gameMgr->resources[this->scv->entityId.player].minerals += this->scv->mineralCount;
00061 break;
00062 default:
00063 break;
00064 }
00065 }
00066
00067 inline void Gather::tick(double dt){
00068 switch(this->state){
00069 case RETURNTOCC:
00070
00071 moveToEntityTick(this->commandCenter, dt);
00072
00073 break;
00074
00075 case GATHERINGMINERALS:
00076 gatherTick(dt);
00077
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
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) {
00111 if(this->mineralEntity->miner){
00112 Minerals* mineral = this->mineralEntity->patch->getNextMineral(this->mineralEntity);
00113 if(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();
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 ){
00140 float mineralsGathered = this->scv->mineralGatherRate * dt;
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;
00148 this->scv->mineralCount = this->scv->maxMineralCount;
00149 this->mineralEntity->miner = 0;
00150 switchState(RETURNTOCC);
00151 }
00152
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 }