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

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