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->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;
00065 this->scv->gasCount = 0;
00066
00067 break;
00068 case MOVETOMINERALS:
00069 this->entity->engine->gameMgr->resources[this->scv->entityId.player].minerals += this->scv->mineralCount;
00070 this->entity->engine->gameMgr->resources[this->scv->entityId.player].gas += this->scv->gasCount;
00071 break;
00072 default:
00073 break;
00074 }
00075 }
00076
00077 inline void Gather::tick(double dt){
00078 switch(this->state){
00079 case RETURNTOCC:
00080
00081 moveToEntityTick(this->commandCenter, dt);
00082
00083 break;
00084
00085 case GATHERINGMINERALS:
00086 gatherTick(dt);
00087
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
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) {
00121 if(this->mineralEntity && this->mineralEntity->miner){
00122 Minerals* mineral = this->mineralEntity->engine->gameMgr->getMineralPatch(this->mineralEntity->mineralPatchId)->getNextMineral(this->mineralEntity);
00123 if(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();
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
00150 if(this->mineralEntity && (!this->mineralEntity->miner || this->mineralEntity->miner == this->entity )){
00151 float mineralsGathered = this->scv->mineralGatherRate * dt;
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;
00159 this->scv->gasCount = 0;
00160 this->scv->mineralCount = this->scv->maxMineralCount;
00161 this->mineralEntity->miner = 0;
00162 switchState(RETURNTOCC);
00163 }
00164
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
00175 else if(this->gasEntity && (!this->gasEntity->miner || this->gasEntity->miner == this->entity )){
00176 float gasGathered = this->scv->gasGatherRate * dt;
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;
00184 this->scv->mineralCount = 0;
00185 this->scv->gasCount = this->scv->maxGasCount;
00186 this->gasEntity->miner = 0;
00187 switchState(RETURNTOCC);
00188 }
00189
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 }