unitWeapons.cpp

Go to the documentation of this file.
00001 /*
00002  * weapon.cpp
00003  *
00004  *  Created on: Feb 28, 2012
00005  *      Author: sushil
00006  */
00007 #include <ent.h>
00008 #include <engine.h>
00009 #include <distanceMgr.h>
00010 #include "unitWeapons.h"
00011 #include "DEBUG.h"
00012 
00013 using namespace Ogre;
00014 
00015 FastEcslent::Weapon::Weapon(Entity* ent, UnitAspectType ast,const WeaponType *wtype): UnitAspect(ent, ast) {
00016         weaponType = wtype;
00017 }
00018 
00019 FastEcslent::Weapon::Weapon(Entity* ent, UnitAspectType ast): UnitAspect(ent, ast) {
00020         init();
00021 }
00022 
00023 void FastEcslent::Weapon::init(){
00024         distanceMgr = this->entity->engine->distanceMgr;
00025         weaponMgr   = this->entity->engine->weaponMgr;
00026         weaponType = weaponMgr->weaponType[this->entity->entityType];
00027 
00028         hitpoints = weaponMgr->maxHitpoints[this->entity->entityType];
00029         armor     = weaponMgr->initArmor[this->entity->entityType];
00030         damageMultiplier =  weaponMgr->initDamageMultiplier[this->entity->entityType];
00031 
00032         m_cooldown = 0;
00033         STANDSTILL = 10;
00034         m_onfire = 0;
00035         BEINGATTACKED = 100;
00036         m_beingAttacked = 0;
00037 }
00038 
00039 
00040 void FastEcslent::Weapon::tick(double dt) {
00041         if(m_beingAttacked > 0){
00042                 m_beingAttacked -=dt;
00043         }
00044 
00045         //onfile stand still
00046         if(m_onfire > 0){
00047                 m_onfire -= dt;
00048                 this->entity->speed = 0;
00049                 return;
00050         }
00051 
00052         if(m_cooldown <= 0 && distanceMgr->closestEnemyDistance[this->entity->entityId.id] < this->weaponType->maxRange()){//weaponMgr->range[weaponType]){
00053                 target.entity = this->entity->engine->entityMgr->ents[distanceMgr->closestEnemy[this->entity->entityId.id]];
00054                 if (target.entity->entityState == FastEcslent::ALIVE){
00055                         if(this->weaponType->explosionType() == FastEcslent::ExplosionTypes::Enemy_Splash){
00056                                 dealEnemySplashDamageToTarget(target,dt,this->weaponType->outerSplashRadius());  //radius splash damage
00057                         }else if(this->weaponType->explosionType() == FastEcslent::ExplosionTypes::Enemy_Line_Splash){
00058                                 dealLineSplashDamageToTarget(target, dt, this->weaponType->outerSplashRadius(), this->weaponType->innerSplashRadius());                //line splash damage
00059                         }else {
00060                                 dealDamageToTarget(target, dt);
00061                         }
00062                 }
00063 //              DEBUG(std::cout << "Entity: " << entity->entityId.id << ", Side: " << entity->entityId.side << " dealing : " << dealDamageToTarget(target, dt)
00064 //                              << " to TargetEntity:  " << target.entity->entityId.id << ", target's Side: " << target.entity->entityId.side << std::endl;)
00065         }else if(m_cooldown > 0){
00066                 m_cooldown -= dt;
00067         }
00068 }
00069 
00070 void FastEcslent::Weapon::dealDamageToTarget(Target tgt, double dt){
00071         //double damage = weaponMgr->damageMap[entity->entityType][tgt.entity->entityType] * damageMultiplier;
00072         double damage = this->weaponType->damageAmount();//weaponMgr->damageMap[tgt.entity->entityType][weaponType] * damageMultiplier*WeaponMgr::DAMAGESCALER;
00073         tgt.entity->weapon->takeDamage(damage);
00074         m_cooldown = this->weaponType->damageCooldown();//weaponMgr->cooldown[this->entity->entityType] * WeaponMgr::COOLDOWNSCALER;
00075         this->m_onfire = STANDSTILL;
00076 }
00077 
00078 void FastEcslent::Weapon::dealEnemySplashDamageToTarget(Target tgt, double dt, double radius){
00079         //double damage = weaponMgr->damageMap[entity->entityType][tgt.entity->entityType] * damageMultiplier;
00080         double damage = this->weaponType->damageAmount();//weaponMgr->damageMap[tgt.entity->entityType][weaponType] * damageMultiplier*WeaponMgr::DAMAGESCALER;
00081         std::vector<FastEcslent::Entity*> ents = this->getUnitsInRadius(tgt.entity, radius, true);
00082 
00083         for(unsigned int i=0;i<ents.size();i++){
00084                 ents[i]->weapon->takeDamage(damage);
00085         }
00086 
00087         m_cooldown = this->weaponType->damageCooldown();
00088         this->m_onfire = STANDSTILL;
00089 }
00090 
00091 void FastEcslent::Weapon::dealLineSplashDamageToTarget(Target tgt, double dt, double length, double width){
00092         double damage = this->weaponType->damageAmount();//weaponMgr->damageMap[tgt.entity->entityType][weaponType] * damageMultiplier*WeaponMgr::DAMAGESCALER;
00093 
00094         std::vector<FastEcslent::Entity*> ents = this->getUnitsInRectangle(this->entity, tgt.entity, length, width, true);
00095         for(unsigned int i=0;i<ents.size();i++){
00096                 ents[i]->weapon->takeDamage(damage);
00097         }
00098 
00099         m_cooldown = this->weaponType->damageCooldown();
00100         this->m_onfire = STANDSTILL;
00101 }
00102 
00103 void FastEcslent::Weapon::takeDamage(double amt) {
00104         if (this->entity->entityState == FastEcslent::ALIVE) {
00105                 m_beingAttacked = BEINGATTACKED;
00106                 hitpoints -= amt * armor;
00107                 if (hitpoints <= 0){
00108                         this->entity->switchState(DYING);
00109                         hitpoints = 0;
00110                 }
00111         }
00112 }
00113 void FastEcslent::Weapon::takeDamage(double amt, double dt) {
00114         if (this->entity->entityState == FastEcslent::ALIVE) {
00115                 hitpoints -= amt * armor * dt;
00116                 if (hitpoints <= 0){
00117                         this->entity->switchState(DYING);
00118                         hitpoints = 0;
00119                 }
00120         }
00121 }
00122 
00123 std::vector<FastEcslent::Entity*> FastEcslent::Weapon::getUnitsInRadius(Entity* ent, double radius, bool enemyOnly){
00124         std::vector<FastEcslent::Entity*> ents;
00125         for (int i = 0; i < this->entity->engine->entityMgr->nEnts; i++){
00126                 //ignore dead units
00127                 if(this->entity->engine->entityMgr->ents[i]->entityState != ALIVE){
00128                         continue;
00129                 }
00130                 //ignore own units if we only do damage to enemy units
00131                 if(enemyOnly && this->entity->engine->entityMgr->ents[i]->entityId.side == this->entity->entityId.side){
00132                         continue;
00133                 }
00134                 double distance = (ent->pos - this->entity->engine->entityMgr->ents[i]->pos).length();
00135                 if(distance <= radius){
00136                         ents.push_back(this->entity->engine->entityMgr->ents[i]);
00137                 }
00138         }
00139         return ents;
00140 }
00141 
00145 std::vector<FastEcslent::Entity*> FastEcslent::Weapon::getUnitsInRectangle(Entity* src, Entity* tgt, double length, double width, bool enemyOnly){
00146         Vector3 vec = tgt->pos - src->pos;
00147         Vector3 v1,v2,v3,v4;
00148 
00149         double xdelta = width/2 * sin(atan2(vec.z, vec.x));
00150         double zdelta = width/2 * cos(atan2(vec.z, vec.x));
00151         v1.x = src->pos.x - xdelta;
00152         v2.x = src->pos.x + xdelta;
00153 
00154         v1.z = src->pos.z + zdelta;
00155         v2.z = src->pos.z - zdelta;
00156 
00157         v3.x = v2.x + length* cos(atan2(vec.z, vec.x));
00158         v3.z = v2.z + length* sin(atan2(vec.z, vec.x));
00159 
00160         v4.x = v1.x + length* cos(atan2(vec.z, vec.x));
00161         v4.z = v1.z + length* sin(atan2(vec.z, vec.x));
00162 
00163         std::vector<FastEcslent::Entity*> ents;
00164         for (int i = 0; i < this->entity->engine->entityMgr->nEnts; i++){
00165                 if(this->entity->engine->entityMgr->ents[i]->entityState != ALIVE){
00166                         continue;
00167                 }
00168                 //ignore own units if we only do damage to enemy units
00169                 if(enemyOnly && this->entity->engine->entityMgr->ents[i]->entityId.side == this->entity->entityId.side){
00170                         continue;
00171                 }
00172 
00173                 if(this->isPointInRectangle(v1,v2,v3,v4, this->entity->engine->entityMgr->ents[i]->pos)){
00174                         ents.push_back(this->entity->engine->entityMgr->ents[i]);
00175                 }
00176         }
00177         return ents;
00178 }
00179 
00183 bool FastEcslent::Weapon::isPointInRectangle(Ogre::Vector3 sp1, Ogre::Vector3 sp2, Ogre::Vector3 sp3, Ogre::Vector3 sp4, Ogre::Vector3 point){
00184         double areaRectangle = (sp1-sp2).length() * (sp2-sp3).length();
00185         double area1 = this->getAreaTriangle(sp1,sp2,point);
00186         double area2 = this->getAreaTriangle(sp2,sp3,point);
00187         double area3 = this->getAreaTriangle(sp3,sp4,point);
00188         double area4 = this->getAreaTriangle(sp4,sp1,point);
00189         double sum = area1+area2+area3+area4;
00190         if(sum - areaRectangle < 50){   // 5 is the deviation
00191                 return true;
00192         }else {
00193                 return false;
00194         }
00195 }
00196 
00200 double FastEcslent::Weapon::getAreaTriangle(Ogre::Vector3 tp1, Ogre::Vector3 tp2, Ogre::Vector3 tp3){
00201         double a = (tp1-tp2).length();
00202         double b = (tp2-tp3).length();
00203         double c = (tp3-tp1).length();
00204         double p = (a + b + c)/2;
00205         return sqrt(p*(p-a)*(p-b)*(p-c));
00206 }

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