mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 19:52:25 +01:00
- initial implementation of attack-boost logic (this is in progress code which is only triggered by new xml entries). Will explain later once tested.
This commit is contained in:
parent
5dda269151
commit
c252402e71
@ -278,6 +278,8 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType
|
||||
//starting skill
|
||||
this->lastModelIndexForCurrSkillType = -1;
|
||||
this->currSkill = getType()->getFirstStOfClass(scStop);
|
||||
this->currentAttackBoostUnits.first = this->currSkill;
|
||||
|
||||
livingUnits.insert(id);
|
||||
livingUnitsp.insert(this);
|
||||
|
||||
@ -1231,6 +1233,40 @@ bool Unit::update() {
|
||||
}
|
||||
}
|
||||
|
||||
//if(currSkill != currentAttackBoostUnits.first) {
|
||||
// First remove any units that were previosuly in range
|
||||
if(currentAttackBoostUnits.second.size() > 0) {
|
||||
for(unsigned int i = 0; i < currentAttackBoostUnits.second.size(); ++i) {
|
||||
// Remove attack boost upgrades from unit
|
||||
Unit *affectedUnit = currentAttackBoostUnits.second[i];
|
||||
affectedUnit->deapplyAttackBoost(currentAttackBoostUnits.first->getAttackBoost(), this);
|
||||
|
||||
//printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
|
||||
}
|
||||
currentAttackBoostUnits.second.clear();
|
||||
}
|
||||
//}
|
||||
currentAttackBoostUnits.first = currSkill;
|
||||
|
||||
if(currSkill->isAttackBoostEnabled() == true) {
|
||||
// Search for units in range of this unit which apply to the
|
||||
// attack-boost and temporarily upgrade them
|
||||
UnitUpdater *unitUpdater = this->game->getWorld()->getUnitUpdater();
|
||||
|
||||
const AttackBoost *attackBoost = currSkill->getAttackBoost();
|
||||
vector<Unit *> candidates = unitUpdater->findUnitsInRange(this, attackBoost->radius);
|
||||
for(unsigned int i = 0; i < candidates.size(); ++i) {
|
||||
Unit *affectedUnit = candidates[i];
|
||||
if(attackBoost->isAffected(this,affectedUnit) == true) {
|
||||
affectedUnit->applyAttackBoost(attackBoost, this);
|
||||
|
||||
currentAttackBoostUnits.second.push_back(affectedUnit);
|
||||
|
||||
//printf("@@@@ APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
@ -1516,6 +1552,38 @@ string Unit::getDesc() const {
|
||||
return str;
|
||||
}
|
||||
|
||||
void Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) {
|
||||
if(boost == NULL) {
|
||||
char szBuf[4096]="";
|
||||
sprintf(szBuf,"In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str());
|
||||
throw runtime_error(szBuf);
|
||||
}
|
||||
|
||||
if(boost->isAffected(source, this)) {
|
||||
totalUpgrade.apply(&boost->boostUpgrade);
|
||||
|
||||
checkItemInVault(&this->hp,this->hp);
|
||||
hp += boost->boostUpgrade.getMaxHp();
|
||||
addItemToVault(&this->hp,this->hp);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) {
|
||||
if(boost == NULL) {
|
||||
char szBuf[4096]="";
|
||||
sprintf(szBuf,"In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str());
|
||||
throw runtime_error(szBuf);
|
||||
}
|
||||
|
||||
if(boost->isAffected(source, this)) {
|
||||
totalUpgrade.deapply(&boost->boostUpgrade);
|
||||
|
||||
checkItemInVault(&this->hp,this->hp);
|
||||
hp -= boost->boostUpgrade.getMaxHp();
|
||||
addItemToVault(&this->hp,this->hp);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::applyUpgrade(const UpgradeType *upgradeType){
|
||||
if(upgradeType == NULL) {
|
||||
char szBuf[4096]="";
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "game_constants.h"
|
||||
#include <set>
|
||||
#include "platform_common.h"
|
||||
#include <vector>
|
||||
#include "leak_dumper.h"
|
||||
|
||||
namespace Glest { namespace Game {
|
||||
@ -49,6 +50,7 @@ class UpgradeType;
|
||||
class Level;
|
||||
class MorphCommandType;
|
||||
class Game;
|
||||
class Unit;
|
||||
|
||||
enum CommandResult{
|
||||
crSuccess,
|
||||
@ -342,6 +344,8 @@ private:
|
||||
bool usePathfinderExtendedMaxNodes;
|
||||
int maxQueuedCommandDisplayCount;
|
||||
|
||||
std::pair<const SkillType *,std::vector<Unit *> > currentAttackBoostUnits;
|
||||
|
||||
public:
|
||||
Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
|
||||
~Unit();
|
||||
@ -463,6 +467,10 @@ public:
|
||||
int update2();
|
||||
bool update();
|
||||
void tick();
|
||||
|
||||
void applyAttackBoost(const AttackBoost *boost, const Unit *source);
|
||||
void deapplyAttackBoost(const AttackBoost *boost, const Unit *source);
|
||||
|
||||
void applyUpgrade(const UpgradeType *upgradeType);
|
||||
void computeTotalUpgrade();
|
||||
void incKills(int team);
|
||||
|
@ -28,6 +28,55 @@ using namespace Shared::Graphics;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
|
||||
|
||||
AttackBoost::AttackBoost() {
|
||||
enabled = false;
|
||||
radius = 0;
|
||||
boostAllUnits = false;
|
||||
}
|
||||
bool AttackBoost::isAffected(const Unit *source, const Unit *dest) const {
|
||||
bool result = false;
|
||||
if(enabled == true && source != NULL && dest != NULL &&
|
||||
source != dest) {
|
||||
// All units are affected (including enemies)
|
||||
if(boostAllUnits == true) {
|
||||
float distance = source->getCenteredPos().dist(dest->getCenteredPos());
|
||||
if(distance <= radius) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Only same faction units are affected
|
||||
if(boostUnitList.size() == 0) {
|
||||
//if(source->isAlly(dest) == true) {
|
||||
//}
|
||||
if(source->getFactionIndex() == dest->getFactionIndex()) {
|
||||
float distance = source->getCenteredPos().dist(dest->getCenteredPos());
|
||||
if(distance <= radius) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Specify which units are affected
|
||||
else {
|
||||
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
|
||||
const UnitType *ut = boostUnitList[i];
|
||||
if(dest->getType()->getId() == ut->getId()) {
|
||||
float distance = source->getCenteredPos().dist(dest->getCenteredPos());
|
||||
if(distance <= radius) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// =====================================================
|
||||
// class SkillType
|
||||
// =====================================================
|
||||
|
@ -41,6 +41,7 @@ class FactionType;
|
||||
class TechTree;
|
||||
class Lang;
|
||||
class TotalUpgrade;
|
||||
class Unit;
|
||||
|
||||
|
||||
enum Field{
|
||||
@ -75,16 +76,14 @@ typedef list<UnitParticleSystemType*> UnitParticleSystemTypes;
|
||||
|
||||
class AttackBoost {
|
||||
public:
|
||||
AttackBoost() {
|
||||
enabled = false;
|
||||
radius = 0;
|
||||
boostAllUnits = false;
|
||||
}
|
||||
AttackBoost();
|
||||
bool enabled;
|
||||
int radius;
|
||||
bool boostAllUnits;
|
||||
vector<const UnitType *> boostUnitList;
|
||||
UpgradeTypeBase boostUpgrade;
|
||||
|
||||
bool isAffected(const Unit *source, const Unit *dest) const;
|
||||
};
|
||||
|
||||
class SkillType {
|
||||
@ -123,6 +122,9 @@ public:
|
||||
StaticSound *getSound() const {return sounds.getRandSound();}
|
||||
float getSoundStartTime() const {return soundStartTime;}
|
||||
|
||||
bool isAttackBoostEnabled() const { return attackBoost.enabled; }
|
||||
const AttackBoost * getAttackBoost() const { return &attackBoost; }
|
||||
|
||||
//other
|
||||
virtual string toString() const= 0;
|
||||
virtual int getTotalSpeed(const TotalUpgrade *) const {return speed;}
|
||||
|
@ -232,11 +232,11 @@ string UpgradeType::getReqDesc() const{
|
||||
// class TotalUpgrade
|
||||
// ===============================
|
||||
|
||||
TotalUpgrade::TotalUpgrade(){
|
||||
TotalUpgrade::TotalUpgrade() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void TotalUpgrade::reset(){
|
||||
void TotalUpgrade::reset() {
|
||||
maxHp= 0;
|
||||
maxEp= 0;
|
||||
sight=0;
|
||||
@ -247,7 +247,7 @@ void TotalUpgrade::reset(){
|
||||
prodSpeed=0;
|
||||
}
|
||||
|
||||
void TotalUpgrade::sum(const UpgradeType *ut){
|
||||
void TotalUpgrade::sum(const UpgradeTypeBase *ut) {
|
||||
maxHp+= ut->getMaxHp();
|
||||
maxEp+= ut->getMaxEp();
|
||||
sight+= ut->getSight();
|
||||
@ -258,11 +258,26 @@ void TotalUpgrade::sum(const UpgradeType *ut){
|
||||
prodSpeed+= ut->getProdSpeed();
|
||||
}
|
||||
|
||||
void TotalUpgrade::incLevel(const UnitType *ut){
|
||||
void TotalUpgrade::incLevel(const UnitType *ut) {
|
||||
maxHp+= ut->getMaxHp()*50/100;
|
||||
maxEp+= ut->getMaxEp()*50/100;
|
||||
sight+= ut->getSight()*20/100;
|
||||
armor+= ut->getArmor()*50/100;
|
||||
}
|
||||
|
||||
void TotalUpgrade::apply(const UpgradeTypeBase *ut) {
|
||||
sum(ut);
|
||||
}
|
||||
|
||||
void TotalUpgrade::deapply(const UpgradeTypeBase *ut) {
|
||||
maxHp-= ut->getMaxHp();
|
||||
maxEp-= ut->getMaxEp();
|
||||
sight-= ut->getSight();
|
||||
armor-= ut->getArmor();
|
||||
attackStrength-= ut->getAttackStrength();
|
||||
attackRange-= ut->getAttackRange();
|
||||
moveSpeed-= ut->getMoveSpeed();
|
||||
prodSpeed-= ut->getProdSpeed();
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
|
@ -22,7 +22,7 @@ using Shared::Util::Checksum;
|
||||
using namespace Shared::Util;
|
||||
using namespace Shared::Xml;
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
namespace Glest { namespace Game {
|
||||
|
||||
class TechTree;
|
||||
class FactionType;
|
||||
@ -75,7 +75,7 @@ public:
|
||||
// class UpgradeType
|
||||
// ===============================
|
||||
|
||||
class UpgradeType: public UpgradeTypeBase, public ProducibleType{
|
||||
class UpgradeType: public UpgradeTypeBase, public ProducibleType {
|
||||
private:
|
||||
vector<const UnitType*> effects;
|
||||
|
||||
@ -98,13 +98,16 @@ public:
|
||||
// class TotalUpgrade
|
||||
// ===============================
|
||||
|
||||
class TotalUpgrade: public UpgradeTypeBase{
|
||||
class TotalUpgrade: public UpgradeTypeBase {
|
||||
public:
|
||||
TotalUpgrade();
|
||||
|
||||
void reset();
|
||||
void sum(const UpgradeType *ut);
|
||||
void sum(const UpgradeTypeBase *ut);
|
||||
void incLevel(const UnitType *ut);
|
||||
|
||||
void apply(const UpgradeTypeBase *ut);
|
||||
void deapply(const UpgradeTypeBase *ut);
|
||||
};
|
||||
|
||||
}}//end namespace
|
||||
|
@ -2330,6 +2330,49 @@ vector<Unit*> UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillT
|
||||
return enemies;
|
||||
}
|
||||
|
||||
|
||||
void UnitUpdater::findUnitsForCell(Cell *cell, const Unit *unit,vector<Unit*> &units) {
|
||||
//all fields
|
||||
for(int k = 0; k < fieldCount; k++) {
|
||||
Field f= static_cast<Field>(k);
|
||||
|
||||
//check field
|
||||
Unit *cellUnit = cell->getUnit(f);
|
||||
|
||||
if(cellUnit != NULL && cellUnit->isAlive()) {
|
||||
units.push_back(cellUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<Unit*> UnitUpdater::findUnitsInRange(const Unit *unit, int radius) {
|
||||
int range = radius;
|
||||
vector<Unit*> units;
|
||||
|
||||
//aux vars
|
||||
int size = unit->getType()->getSize();
|
||||
Vec2i center = unit->getPos();
|
||||
Vec2f floatCenter = unit->getFloatCenteredPos();
|
||||
|
||||
//nearby cells
|
||||
UnitRangeCellsLookupItem cacheItem;
|
||||
for(int i = center.x - range; i < center.x + range + size; ++i) {
|
||||
for(int j = center.y - range; j < center.y + range + size; ++j) {
|
||||
//cells inside map and in range
|
||||
#ifdef USE_STREFLOP
|
||||
if(map->isInside(i, j) && streflop::floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){
|
||||
#else
|
||||
if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){
|
||||
#endif
|
||||
Cell *cell = map->getCell(i,j);
|
||||
findUnitsForCell(cell,unit,units);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class ParticleDamager
|
||||
// =====================================================
|
||||
|
@ -121,6 +121,9 @@ public:
|
||||
vector<Unit*> enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast);
|
||||
void findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector<Unit*> &enemies, bool attackersOnly) const;
|
||||
|
||||
void findUnitsForCell(Cell *cell, const Unit *unit,vector<Unit*> &units);
|
||||
vector<Unit*> findUnitsInRange(const Unit *unit, int radius);
|
||||
|
||||
private:
|
||||
//attack
|
||||
void hit(Unit *attacker);
|
||||
|
Loading…
x
Reference in New Issue
Block a user