command.cpp

Go to the documentation of this file.
00001 /*
00002  * command.cpp
00003  *
00004  *  Created on: Jan 9, 2012
00005  *      Author: sushil
00006  */
00007 
00008 #include <const.h>
00009 #include <ent.h>
00010 #include <group.h>
00011 #include <target.h>
00012 #include <engine.h>
00013 #include <OgreVector3.h>
00014 #include "DEBUG.h"
00015 #include "buildings.h"
00016 #include "command.h"
00017 
00018 //#include <command.h>
00019 inline bool FastEcslent::Move::done() {
00020         return (entity->pos.squaredDistance((target->location)) <= entity->turningRadius);
00021 }
00022 
00023 void FastEcslent::Move::init(){
00024         Ogre::Vector3 diff = target->location - entity->pos;
00025         entity->desiredHeading = -atan2(diff.z, diff.x);
00026         entity->desiredSpeed = entity->maxSpeed;
00027         return;
00028 }
00029 
00030 inline void FastEcslent::Move::tick(double dt) {
00031         if(!done()) {
00032                 relativePos = target->location - entity->pos;
00033                 entity->desiredHeading = -atan2(relativePos.z, relativePos.x);
00034                 entity->desiredSpeed = entity->maxSpeed;
00035         } else {
00036                 entity->desiredSpeed = 0.0f;
00037         }
00038         return;
00039 }
00040 
00041 //Build for SCV building structures
00042 //----------------------------------------------------------------------------
00043 //inline bool FastEcslent::BuildStructure::done() {
00044 //      return (entity->pos.squaredDistance((target->location)) <= entity->turningRadius);
00045 //}
00046 //
00047 //void FastEcslent::BuildStructure::init(){
00048 //      Ogre::Vector3 diff = target->location - entity->pos;
00049 //      entity->desiredHeading = -atan2(diff.z, diff.x);
00050 //      entity->desiredSpeed = entity->maxSpeed;
00051 //      return;
00052 //}
00053 //
00054 //inline void FastEcslent::BuildStructure::tick(double dt) {
00055 //      if(!done()) {
00056 //              relativePos = target->location - entity->pos;
00057 //              entity->desiredHeading = -atan2(relativePos.z, relativePos.x);
00058 //              entity->desiredSpeed = entity->maxSpeed;
00059 //      } else {
00060 //              entity->desiredSpeed = 0.0f;
00061 //      }
00062 //      return;
00063 //}
00064 //Build for structures
00065 //------------------------------------------------------------------------------------------
00066 inline void FastEcslent::BuildCommand::init()
00067 {
00068     if(entity != NULL && entity->getAspect(BUILDER) != NULL)
00069     {
00070         //Building* structure = dynamic_cast<Building*>(entity);
00071         //structure->enqueue(type);
00072         //entity->getAspect(BUILDER);
00073         Builder* builder = dynamic_cast<Builder *> (entity->getAspect(BUILDER));
00074         //if(builder != NULL)
00075         //{
00076         builder->enqueue(entType);
00077         //}
00078     }
00079     isDone = true;
00080         
00081 
00082 }
00083 inline bool FastEcslent::BuildCommand::done(){
00084         return isDone;
00085 }
00086 
00087 inline void FastEcslent::BuildCommand::tick(double dt){
00088 //    if(!isDone)
00089 //        this->init();
00090 }
00091 //Gather for SCV
00092 //------------------------------------------------------------------------------------------
00093 inline void FastEcslent::Wait::init(){
00094         timeLeftToWait = target->waitTime;
00095 
00096 }
00097 inline bool FastEcslent::Wait::done(){
00098         return timeLeftToWait < 0.0;
00099 }
00100 
00101 inline void FastEcslent::Wait::tick(double dt){
00102         if(timeLeftToWait > 0) {
00103                 timeLeftToWait -= dt;
00104         } else {
00105                 DEBUG(std::cout << entity->uiname  << ": Done waiting" << std::endl;)
00106         }
00107 }
00108 //------------------------------------------------------------------------------------------
00109 
00110 //------------------------------------------------------------------------------------------
00111 inline void FastEcslent::GasFieldCommand::init(){
00112 
00113 }
00114 inline bool FastEcslent::GasFieldCommand::done(){
00115     return false;
00116 }
00117 
00118 inline void FastEcslent::GasFieldCommand::tick(double dt){
00119     if(((FastEcslent::Gas*)this->entity)->refinary != NULL && ((FastEcslent::Gas*)this->entity)->refinary->entityState != FastEcslent::DEAD)
00120     {
00121         this->entity->selectable = false;
00122         this->entity->isSelected = false;
00123         ((FastEcslent::Gas*)this->entity)->refinary= NULL;
00124     }
00125     else
00126     {
00127         this->entity->selectable = true;
00128     }
00129 }
00130 //------------------------------------------------------------------------------------------
00131 
00132 
00133 // Potential fields move for groups
00134 
00135 inline bool FastEcslent::PotentialMove::done(){
00136         //preturn false;
00137         return (entity->pos.squaredDistance(target->location) <= (entity->turningRadius * entity->turningRadius)*10.0);// && (int) ((entity->attractivePotential)) > -15);
00138 }
00139 
00140 void FastEcslent::PotentialMove::init(){
00141         Ogre::Vector3 diff = target->location - entity->pos;
00142         entity->desiredSpeed = entity->maxSpeed;
00143 
00144 }
00145 
00146 inline void FastEcslent::PotentialMove::tick(double dt){
00147         int nEnts = entity->engine->entityMgr->nEnts;
00148 
00149         if (!done()){
00150                 // compute force
00151                         double repulsivePotential = 0.0f;
00152                         entity->potentialVec = Ogre::Vector3::ZERO;
00153                         Ogre::Vector3 tmp;
00154                         int nInRange = 1; // at least one so that you don't multiply by 0 later
00155                         for (int i = 0; i < nEnts; i++){
00156                                 if(i != entity->entityId.id){// repulsed by all other entities
00157                                         if (entity->engine->distanceMgr->distance[entity->entityId.id][i] < RepulsionThresholdDistance) { // Don't care about entities too far away
00158                                                 nInRange += 1;
00159                                                 tmp = (entity->engine->distanceMgr->normalizedDistanceVec[i][entity->entityId.id]);
00160                                                 repulsivePotential =  (B * entity->engine->entityMgr->ents[i]->mass) / pow(entity->engine->distanceMgr->distance[entity->entityId.id][i], m);
00161                                                 if(repulsivePotential  > INT_MAX){   //repulsive potential could be infinite
00162                                                         repulsivePotential = INT_MAX;
00163                                                 }
00164                                                 entity->potentialVec += (tmp * repulsivePotential);
00165                                         }
00166                                 }
00167                         }
00168                         //attracted by target
00169                         tmp = (entity->pos - target->location);
00170                         //tmp = target->location - entity->pos;
00171                         double targetDistance = tmp.length();
00172                         entity->attractivePotential =  -(A ) / pow(targetDistance, n);// + (B) /pow (targetDistance, m);
00173                         entity->potentialVec += (tmp.normalisedCopy() * entity->attractivePotential * nInRange); // nInRange needs to be at least 1
00174                         //applyPotential(entity, potentialVec);
00175 
00176                         entity->desiredHeading = atan2(-entity->potentialVec.z, entity->potentialVec.x);
00177 
00178                         double cosDiffFrac = (1.0 - cos(entity->vel.angleBetween(entity->potentialVec).valueRadians()))/2.0;// between 0 and 2 divided by 2.0 gives something between 0 and 1
00179                         entity->desiredSpeed   = (entity->maxSpeed - entity->minSpeed) * (1.0 - cosDiffFrac);
00180 
00181 
00182 
00183                 // apply force
00184         } else {
00185                 DEBUG(std::cout << "Attractive Potential: " << entity->attractivePotential << std::endl;)
00186                 entity->desiredSpeed = 0.0f;
00187                 entity->desiredHeading = entity->heading;
00188         }
00189 }
00190 
00191 
00192 
00193 
00194 FastEcslent::Maintain::Maintain (Entity *ent, Target *tgt): UnitCommand(ent, MaintainCommand, tgt){
00195         if(valid(tgt->entity)) {
00196                 DEBUG(std::cout << "Maintaining with respect to: " << tgt->entity->uiname << std::endl;)
00197                 tgt->location = tgt->entity->pos + tgt->offset;
00198         }
00199 }
00200 bool FastEcslent::Maintain::valid(Entity *entity) {
00201         return true;
00202 }
00203 
00204 inline bool FastEcslent::Maintain::done() {
00205         return false;
00206 }
00207 
00208 void FastEcslent::Maintain::init(){
00209 
00210         if (kInvalidFloat == target->offsetDistance) { // offset must contain absolute position right now. Convert to offsetRot and offsetDistance
00211                 Ogre::Quaternion q = Ogre::Vector3(cos(-target->entity->heading) * 100.0f, 0.0f, sin(-target->entity->heading) * 100.0f).getRotationTo(target->offset);
00212                 target->offsetYaw = q.getYaw().valueRadians();
00213                 target->offsetDistance = (target->entity->pos - target->offset).length();
00214                 DEBUG(std::cout << "OffsetYaw: " << target->offsetYaw << " offsetDistance: " << target->offsetDistance << std::endl;)
00215         }
00216         return;
00217 }
00218 
00219 inline void FastEcslent::Maintain::tick(double dt) { //offsetRotation and offsetDistance set by init()
00220         target->offset = (target->entity->rot * Ogre::Quaternion(Ogre::Radian(target->offsetYaw), Ogre::Vector3::UNIT_Y)) * (Ogre::Vector3::UNIT_X * target->offsetDistance);
00221         target->location = target->entity->pos + target->offset;
00222 
00223         relativePos = target->location - entity->pos;
00224         relativeVel = target->entity->vel - entity->vel;
00225         relativeSpeed = relativeVel.length();
00226         predictedTimeToClose = relativePos.length()/relativeSpeed;
00227         predictedPos =  target->location + (target->entity->vel * predictedTimeToClose);
00228         interceptPos = predictedPos - entity->pos;
00229 
00230         entity->desiredHeading = -atan2(interceptPos.z, interceptPos.x);
00231         if ((relativeSpeed * predictedTimeToClose) > 30)
00232                 entity->desiredSpeed = entity->maxSpeed;
00233         else
00234                 entity->desiredSpeed = target->entity->speed;
00235 
00236         return;
00237 }
00238 
00239 
00240 void FastEcslent::Tactic::changeLeadership(LeadershipType selector){
00241 
00242         Ogre::Vector3 tpos;
00243         if(this->target->target.location == InvalidLocation){
00244                 tpos = this->target->target.entity->pos;
00245         } else {
00246                 tpos = this->target->target.location;
00247         }
00248         this->group->leaderIndex = 0;
00249         if (this->group->nEntitiesInGroup > 0) {
00250                 switch(selector){
00251                 case 0:
00252                         this->group->leaderIndex = closestToTarget(true, tpos);
00253                         break;
00254                 case 2:
00255                         this->group->leaderIndex = closestToTarget(false, tpos); //furthest from target
00256                         break;
00257                 case 3:
00258                         this->group->leaderIndex = mostMassive(true);
00259                         break;
00260                 case 4:
00261                         this->group->leaderIndex = mostMassive(true);//smallest mass
00262                         break;
00263                 case 5:
00264                         this->group->leaderIndex = randInt(0, this->group->nEntitiesInGroup);
00265                         break;
00266                 default:
00267                         this->group->leaderIndex = 0;
00268                         break;
00269                 }
00270         }
00271 
00272 }
00273 
00274 
00275 int FastEcslent::Tactic::mostMassive(bool massest){
00276         float minMass = 0;
00277         int minIndex = INT_MAX;
00278         float maxMass = 0;
00279         int maxIndex = 0;
00280         float mass;
00281         for (int i = 0; i < this->group->nEntitiesInGroup; i++){
00282                 mass = this->group->members[i]->mass;
00283                 if(mass < minMass){
00284                         minMass = mass;
00285                         minIndex = i;
00286                 }
00287                 if (mass > maxMass){
00288                         maxMass = mass;
00289                         maxIndex = i;
00290                 }
00291         }
00292         if(!massest) {
00293                 return minIndex;
00294         } else {
00295                 return maxIndex;
00296         }
00297 
00298 }
00299 
00300 
00301 int FastEcslent::Tactic::closestToTarget(bool closest, Ogre::Vector3 tpos){
00302         //Entity** members = this->group->members;
00303                 //int dist = members[leaderIndex]->pos.distance(this->target->target.location);
00304 
00305         float minDist = 0;
00306         int minIndex = INT_MAX;
00307         float maxDist = 0;
00308         int maxIndex = 0;
00309         float dist;
00310         for (int i = 0; i < this->group->nEntitiesInGroup; i++){
00311                 dist = this->group->members[i]->pos.distance(tpos);
00312                 if(dist < minDist) {
00313                         minDist = dist;
00314                         minIndex = i;
00315                 }
00316                 if (dist > maxDist){
00317                         maxDist = dist;
00318                         maxIndex = i;
00319                 }
00320         }
00321         if(closest) {
00322                 return minIndex;
00323         } else {
00324                 return maxIndex;
00325         }
00326 }

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