- working implementation of particles for new attack-boost xml tag

This commit is contained in:
Mark Vejvoda 2011-06-25 20:44:46 +00:00
parent 105e639bd8
commit 1700cbba2d
9 changed files with 456 additions and 113 deletions

View File

@ -45,7 +45,7 @@ int PathFinder::pathFindNodesMax = 1500;
const int PathFinder::pathFindRefresh = 10;
const int PathFinder::pathFindBailoutRadius = 20;
const int PathFinder::pathFindExtendRefreshForNodeCount = 25;
const int PathFinder::pathFindExtendRefreshNodeCountMin = 20;
const int PathFinder::pathFindExtendRefreshNodeCountMin = 40;
const int PathFinder::pathFindExtendRefreshNodeCountMax = 60;
PathFinder::PathFinder() {

View File

@ -33,6 +33,8 @@ namespace Glest{ namespace Game{
// =====================================================
ParticleSystemType::ParticleSystemType() {
//printf("++ Create ParticleSystemType [%p]\n",this);
teamcolorNoEnergy=false;
teamcolorEnergy=false;
alternations=false;
@ -40,6 +42,10 @@ ParticleSystemType::ParticleSystemType() {
model=NULL;
}
ParticleSystemType::~ParticleSystemType() {
//printf("-- Delete ParticleSystemType [%p] type = [%s]\n",this,type.c_str());
}
void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath) {

View File

@ -67,6 +67,8 @@ protected:
public:
ParticleSystemType();
~ParticleSystemType();
void load(const XmlNode *particleSystemNode, const string &dir,
RendererInterface *renderer, std::map<string,vector<pair<string, string> > > &loadedFileList,
string parentLoader, string techtreePath);

View File

@ -3112,15 +3112,16 @@ void Renderer::renderSelectionEffects() {
// Render Attack-boost circles
if(showDebugUI == true) {
const std::pair<const SkillType *,std::vector<Unit *> > &currentAttackBoostUnits = unit->getCurrentAttackBoostUnits();
//const std::pair<const SkillType *,std::vector<Unit *> > &currentAttackBoostUnits = unit->getCurrentAttackBoostUnits();
const UnitAttackBoostEffectOriginator &effect = unit->getAttackBoostOriginatorEffect();
if(currentAttackBoostUnits.first->isAttackBoostEnabled() == true) {
if(effect.skillType->isAttackBoostEnabled() == true) {
glColor4f(MAGENTA.x,MAGENTA.y,MAGENTA.z,MAGENTA.w);
renderSelectionCircle(currVec, unit->getType()->getSize(), currentAttackBoostUnits.first->getAttackBoost()->radius);
renderSelectionCircle(currVec, unit->getType()->getSize(), effect.skillType->getAttackBoost()->radius);
for(unsigned int i = 0; i < currentAttackBoostUnits.second.size(); ++i) {
for(unsigned int i = 0; i < effect.currentAttackBoostUnits.size(); ++i) {
// Remove attack boost upgrades from unit
Unit *affectedUnit = currentAttackBoostUnits.second[i];
Unit *affectedUnit = effect.currentAttackBoostUnits[i];
Vec3f currVecBoost = affectedUnit->getCurrVectorFlat();
currVecBoost.y += 0.3f;

View File

@ -179,6 +179,39 @@ Unit *UnitReference::getUnit() const{
return NULL;
}
UnitAttackBoostEffect::UnitAttackBoostEffect() {
boost = NULL;
source = NULL;
ups = NULL;
upst = NULL;
}
UnitAttackBoostEffect::~UnitAttackBoostEffect() {
if(ups != NULL) {
//ups->fade();
vector<UnitParticleSystem *> particleSystemToRemove;
particleSystemToRemove.push_back(ups);
Renderer::getInstance().cleanupUnitParticleSystems(particleSystemToRemove,rsGame);
ups = NULL;
}
delete upst;
upst = NULL;
}
UnitAttackBoostEffectOriginator::UnitAttackBoostEffectOriginator() {
skillType = NULL;
currentAppliedEffect = NULL;
}
UnitAttackBoostEffectOriginator::~UnitAttackBoostEffectOriginator() {
delete currentAppliedEffect;
currentAppliedEffect = NULL;
}
// =====================================================
// class Unit
// =====================================================
@ -278,7 +311,7 @@ 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;
this->currentAttackBoostOriginatorEffect.skillType = this->currSkill;
livingUnits.insert(id);
livingUnitsp.insert(this);
@ -328,6 +361,14 @@ Unit::~Unit() {
}
stopDamageParticles();
while(currentAttackBoostEffects.empty() == false) {
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
currentAttackBoostEffects.pop_back();
}
delete currentAttackBoostOriginatorEffect.currentAppliedEffect;
currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL;
delete this->unitPath;
this->unitPath = NULL;
@ -678,6 +719,18 @@ void Unit::setVisible(const bool visible) {
for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) {
(*it)->setVisible(visible);
}
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if(effect.ups != NULL) {
effect.ups->setVisible(visible);
}
}
if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) {
if(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != NULL) {
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setVisible(visible);
}
}
}
// =============================== Render related ==================================
@ -1019,15 +1072,15 @@ void Unit::undertake() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to undertake unit id = %d [%s] [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->id, this->getFullName().c_str(),this->getDesc().c_str());
// Remove any units that were previously in attack-boost range
if(currentAttackBoostUnits.second.size() > 0) {
for(unsigned int i = 0; i < currentAttackBoostUnits.second.size(); ++i) {
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0) {
for(unsigned int i = 0; i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); ++i) {
// Remove attack boost upgrades from unit
Unit *affectedUnit = currentAttackBoostUnits.second[i];
affectedUnit->deapplyAttackBoost(currentAttackBoostUnits.first->getAttackBoost(), this);
Unit *affectedUnit = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
//printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
currentAttackBoostUnits.second.clear();
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear();
}
UnitUpdater *unitUpdater = game->getWorld()->getUnitUpdater();
@ -1221,6 +1274,20 @@ bool Unit::update() {
(*it)->setRotation(getRotation());
}
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if(effect.ups != NULL) {
effect.ups->setPos(getCurrVector());
effect.ups->setRotation(getRotation());
}
}
if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) {
if(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != NULL) {
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos(getCurrVector());
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setRotation(getRotation());
}
}
//checks
if(animProgress > 1.f) {
animProgress = currSkill->getClass() == scDie? 1.f: 0.f;
@ -1245,34 +1312,124 @@ bool Unit::update() {
}
}
// Remove any units that were previously 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);
if(currSkill != currentAttackBoostOriginatorEffect.skillType) {
if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) {
delete currentAttackBoostOriginatorEffect.currentAppliedEffect;
currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL;
//printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
//printf("- #1 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
// Remove any units that were previously in range
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0) {
for(unsigned int i = 0; i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); ++i) {
// Remove attack boost upgrades from unit
Unit *affectedUnit = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
//printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear();
}
currentAttackBoostOriginatorEffect.skillType = 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) {
if(affectedUnit->applyAttackBoost(attackBoost, this) == true) {
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit);
//printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
}
}
if(showUnitParticles == true) {
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0) {
if(attackBoost->unitParticleSystemTypeForSourceUnit != NULL) {
currentAttackBoostOriginatorEffect.currentAppliedEffect = new UnitAttackBoostEffect();
currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = new UnitParticleSystemType();
*currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = *attackBoost->unitParticleSystemTypeForSourceUnit;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200);
currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups);
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos(getCurrVector());
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
Renderer::getInstance().manageParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, rsGame);
//printf("+ #1 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
}
}
}
currentAttackBoostUnits.second.clear();
}
currentAttackBoostUnits.first = currSkill;
else {
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();
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];
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);
std::vector<Unit *>::iterator iterFound = std::find(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(), currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end(), affectedUnit);
currentAttackBoostUnits.second.push_back(affectedUnit);
if(attackBoost->isAffected(this,affectedUnit) == true) {
if(iterFound == currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) {
if(affectedUnit->applyAttackBoost(attackBoost, this) == true) {
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit);
//printf("@@@@ APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
//printf("+ #2 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
}
}
else {
if(iterFound != currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) {
affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
currentAttackBoostOriginatorEffect.currentAttackBoostUnits.erase(iterFound);
//printf("- #2 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId());
}
}
}
if(showUnitParticles == true) {
if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0) {
if( attackBoost->unitParticleSystemTypeForSourceUnit != NULL &&
currentAttackBoostOriginatorEffect.currentAppliedEffect == NULL) {
currentAttackBoostOriginatorEffect.currentAppliedEffect = new UnitAttackBoostEffect();
currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = new UnitParticleSystemType();
*currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = *attackBoost->unitParticleSystemTypeForSourceUnit;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200);
currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups);
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos(getCurrVector());
currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
Renderer::getInstance().manageParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, rsGame);
//printf("+ #2 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
}
else if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() <= 0) {
if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) {
delete currentAttackBoostOriginatorEffect.currentAppliedEffect;
currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL;
//printf("- #2 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId());
}
}
}
}
}
@ -1280,6 +1437,94 @@ bool Unit::update() {
return return_value;
}
bool Unit::unitHasAttackBoost(const AttackBoost *boost, const Unit *source) const {
bool result = false;
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
const UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if( effect.boost == boost &&
effect.source->getType()->getId() == source->getType()->getId()) {
result = true;
break;
}
}
return result;
}
bool 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);
}
//printf("APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
bool shouldApplyAttackBoost = true;
if(boost->allowMultipleBoosts == false) {
// Check if we already have this boost from this unit type and multiples
// are not allowed
bool alreadyHasAttackBoost = this->unitHasAttackBoost(boost, source);
if(alreadyHasAttackBoost == true) {
shouldApplyAttackBoost = false;
}
}
if(shouldApplyAttackBoost == true) {
currentAttackBoostEffects.push_back(UnitAttackBoostEffect());
UnitAttackBoostEffect &effect = currentAttackBoostEffects[currentAttackBoostEffects.size()-1];
effect.boost = boost;
effect.source = source;
//if(boost->isAffected(source, this)) {
totalUpgrade.apply(&boost->boostUpgrade);
checkItemInVault(&this->hp,this->hp);
hp += boost->boostUpgrade.getMaxHp();
addItemToVault(&this->hp,this->hp);
//}
if(showUnitParticles == true) {
effect.upst = new UnitParticleSystemType();
*effect.upst = *boost->unitParticleSystemTypeForAffectedUnit;
//effect.upst = boost->unitParticleSystemTypeForAffectedUnit;
effect.ups = new UnitParticleSystem(200);
effect.upst->setValues(effect.ups);
effect.ups->setPos(getCurrVector());
effect.ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
Renderer::getInstance().manageParticleSystem(effect.ups, rsGame);
}
//currentAttackBoostEffects.push_back(effect);
}
return shouldApplyAttackBoost;
}
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);
}
//printf("DE-APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId());
//if(boost->isAffected(source, this)) {
totalUpgrade.deapply(&boost->boostUpgrade);
checkItemInVault(&this->hp,this->hp);
hp -= boost->boostUpgrade.getMaxHp();
addItemToVault(&this->hp,this->hp);
//}
for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) {
UnitAttackBoostEffect &effect = currentAttackBoostEffects[i];
if(effect.boost == boost && effect.source == source) {
currentAttackBoostEffects.erase(currentAttackBoostEffects.begin() + i);
break;
}
}
}
void Unit::tick() {
if(isAlive()) {
@ -1562,38 +1807,6 @@ 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]="";
@ -2182,7 +2395,7 @@ void Unit::setLastHarvestResourceTarget(const Vec2i *pos) {
// as a bad one
const int addInterval = (GameConstants::updateFps * 5);
if(lastHarvestResourceTarget.second - getFrameCount() >= addInterval) {
printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second);
//printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second);
addBadHarvestPos(resourceLocation);
}
}

View File

@ -52,7 +52,7 @@ class MorphCommandType;
class Game;
class Unit;
enum CommandResult{
enum CommandResult {
crSuccess,
crFailRes,
crFailReqs,
@ -61,7 +61,7 @@ enum CommandResult{
crSomeFailed
};
enum InterestingUnitType{
enum InterestingUnitType {
iutIdleHarvester,
iutBuiltBuilding,
iutProducer,
@ -73,7 +73,7 @@ enum InterestingUnitType{
// class UnitObserver
// =====================================================
class UnitObserver{
class UnitObserver {
public:
enum Event{
eKill
@ -88,7 +88,7 @@ public:
// class UnitReference
// =====================================================
class UnitReference{
class UnitReference {
private:
int id;
Faction *faction;
@ -236,6 +236,30 @@ public:
/// A game unit or building
// ===============================
class UnitAttackBoostEffect {
public:
UnitAttackBoostEffect();
~UnitAttackBoostEffect();
const AttackBoost *boost;
const Unit *source;
UnitParticleSystem *ups;
UnitParticleSystemType *upst;
};
class UnitAttackBoostEffectOriginator {
public:
UnitAttackBoostEffectOriginator();
~UnitAttackBoostEffectOriginator();
const SkillType *skillType;
std::vector<Unit *> currentAttackBoostUnits;
UnitAttackBoostEffect *currentAppliedEffect;
};
class Unit : public ValueCheckerVault {
private:
typedef list<Command*> Commands;
@ -344,7 +368,9 @@ private:
bool usePathfinderExtendedMaxNodes;
int maxQueuedCommandDisplayCount;
std::pair<const SkillType *,std::vector<Unit *> > currentAttackBoostUnits;
UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect;
std::vector<UnitAttackBoostEffect> currentAttackBoostEffects;
public:
Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing);
@ -352,7 +378,9 @@ public:
static void setGame(Game *value) { game=value;}
const std::pair<const SkillType *,std::vector<Unit *> > & getCurrentAttackBoostUnits() const { return currentAttackBoostUnits; }
//const std::pair<const SkillType *,std::vector<Unit *> > & getCurrentAttackBoostUnits() const { return currentAttackBoostUnits; }
const UnitAttackBoostEffectOriginator & getAttackBoostOriginatorEffect() const { return currentAttackBoostOriginatorEffect; }
bool unitHasAttackBoost(const AttackBoost *boost, const Unit *source) const;
//queries
void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;}
@ -470,7 +498,7 @@ public:
bool update();
void tick();
void applyAttackBoost(const AttackBoost *boost, const Unit *source);
bool applyAttackBoost(const AttackBoost *boost, const Unit *source);
void deapplyAttackBoost(const AttackBoost *boost, const Unit *source);
void applyUpgrade(const UpgradeType *upgradeType);

View File

@ -30,47 +30,70 @@ namespace Glest{ namespace Game{
AttackBoost::AttackBoost() {
enabled = false;
radius = 0;
boostAllUnits = false;
enabled = false;
allowMultipleBoosts = false;
radius = 0;
targetType = abtFaction;
unitParticleSystemTypeForSourceUnit = NULL;
unitParticleSystemTypeForAffectedUnit = NULL;
}
AttackBoost::~AttackBoost() {
delete unitParticleSystemTypeForSourceUnit;
unitParticleSystemTypeForSourceUnit = NULL;
delete unitParticleSystemTypeForAffectedUnit;
unitParticleSystemTypeForAffectedUnit = NULL;
}
bool AttackBoost::isAffected(const Unit *source, const Unit *dest) const {
bool result = false;
if(enabled == true && source != NULL && dest != NULL &&
source != dest) {
if(enabled == true && source != NULL && dest != NULL && source != dest) {
bool destUnitMightApply = false;
// All units are affected (including enemies)
if(boostAllUnits == true) {
if(targetType == abtAll) {
destUnitMightApply = true;
}
// Only same faction units are affected
else if(targetType == abtFaction) {
if(boostUnitList.size() == 0) {
if(source->getFactionIndex() == dest->getFactionIndex()) {
destUnitMightApply = true;
}
}
}
// Only ally units are affected
else if(targetType == abtAlly) {
if(boostUnitList.size() == 0) {
if(source->isAlly(dest) == true) {
destUnitMightApply = true;
}
}
}
// Only foe units are affected
else if(targetType == abtFoe) {
if(boostUnitList.size() == 0) {
if(source->isAlly(dest) == false) {
destUnitMightApply = true;
}
}
}
else if(targetType == abtUnitTypes) {
// Specify which units are affected
for(unsigned int i = 0; i < boostUnitList.size(); ++i) {
const UnitType *ut = boostUnitList[i];
if(dest->getType()->getId() == ut->getId()) {
destUnitMightApply = true;
}
}
}
if(destUnitMightApply == 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;
@ -185,17 +208,63 @@ void SkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt,
attackBoost.enabled = true;
const XmlNode *attackBoostNode = sn->getChild("attack-boost");
attackBoost.allowMultipleBoosts = attackBoostNode->getChild("allow-multiple-boosts")->getAttribute("value")->getBoolValue();
attackBoost.radius = attackBoostNode->getChild("radius")->getAttribute("value")->getIntValue();
attackBoost.boostAllUnits = attackBoostNode->getChild("boost-all-units")->getAttribute("value")->getBoolValue();
if(attackBoost.boostAllUnits == false) {
for(int i = 0; i < attackBoostNode->getChild("boost-all-units")->getChildCount(); ++i) {
const XmlNode *boostUnitNode= attackBoostNode->getChild("boost-all-units")->getChild("unit-type", i);
string targetType = attackBoostNode->getChild("target")->getAttribute("value")->getValue();
if(targetType == "ally") {
attackBoost.targetType = abtAlly;
}
else if(targetType == "foe") {
attackBoost.targetType = abtFoe;
}
else if(targetType == "faction") {
attackBoost.targetType = abtFaction;
}
else if(targetType == "unit-types") {
attackBoost.targetType = abtUnitTypes;
for(int i = 0; i < attackBoostNode->getChild("target")->getChildCount(); ++i) {
const XmlNode *boostUnitNode= attackBoostNode->getChild("target")->getChild("unit-type", i);
attackBoost.boostUnitList.push_back(ft->getUnitType(boostUnitNode->getAttribute("name")->getRestrictedValue()));
}
}
attackBoost.boostUpgrade.load(attackBoostNode);
}
else if(targetType == "all") {
attackBoost.targetType = abtAll;
}
else {
char szBuf[4096]="";
sprintf(szBuf,"Unsupported target [%s] specified for attack boost for skill [%s] in [%s]",targetType.c_str(),name.c_str(),parentLoader.c_str());
throw runtime_error(szBuf);
}
attackBoost.boostUpgrade.load(attackBoostNode);
//particles
if(attackBoostNode->hasChild("particles") == true) {
const XmlNode *particleNode= attackBoostNode->getChild("particles");
bool particleEnabled= particleNode->getAttribute("value")->getBoolValue();
if(particleEnabled == true) {
if(particleNode->hasChild("originator-particle-file") == true) {
const XmlNode *particleFileNode= particleNode->getChild("originator-particle-file");
string path= particleFileNode->getAttribute("path")->getRestrictedValue();
attackBoost.unitParticleSystemTypeForSourceUnit = new UnitParticleSystemType();
attackBoost.unitParticleSystemTypeForSourceUnit->load(dir, currentPath + path, &Renderer::getInstance(),
loadedFileList,parentLoader,tt->getPath());
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue()));
}
if(particleNode->hasChild("affected-particle-file") == true) {
const XmlNode *particleFileNode= particleNode->getChild("affected-particle-file");
string path= particleFileNode->getAttribute("path")->getRestrictedValue();
attackBoost.unitParticleSystemTypeForAffectedUnit = new UnitParticleSystemType();
attackBoost.unitParticleSystemTypeForAffectedUnit->load(dir, currentPath + path, &Renderer::getInstance(),
loadedFileList,parentLoader,tt->getPath());
loadedFileList[currentPath + path].push_back(make_pair(parentLoader,particleFileNode->getAttribute("path")->getRestrictedValue()));
}
}
}
}
}
Model *SkillType::getAnimation(float animProgress, const Unit *unit, int *lastAnimationIndex) const {

View File

@ -74,15 +74,28 @@ typedef list<UnitParticleSystemType*> UnitParticleSystemTypes;
/// A basic action that an unit can perform
// =====================================================
enum AttackBoostTargetType {
abtAlly,
abtFoe,
abtFaction,
abtUnitTypes,
abtAll
};
class AttackBoost {
public:
AttackBoost();
~AttackBoost();
bool enabled;
bool allowMultipleBoosts;
int radius;
bool boostAllUnits;
AttackBoostTargetType targetType;
vector<const UnitType *> boostUnitList;
UpgradeTypeBase boostUpgrade;
UnitParticleSystemType *unitParticleSystemTypeForSourceUnit;
UnitParticleSystemType *unitParticleSystemTypeForAffectedUnit;
bool isAffected(const Unit *source, const Unit *dest) const;
};

View File

@ -33,7 +33,9 @@ namespace Graphics {
// class ParticleSystem
// =====================================================
ParticleSystem::ParticleSystem(int particleCount){
ParticleSystem::ParticleSystem(int particleCount) {
//printf("++ Create ParticleSystem [%p]\n",this);
//init particle vector
blendMode= bmOne;
//particles= new Particle[particleCount];
@ -67,6 +69,8 @@ ParticleSystem::ParticleSystem(int particleCount){
}
ParticleSystem::~ParticleSystem(){
//printf("-- Delete ParticleSystem [%p]\n",this);
//delete [] particles;
particles.clear();
}
@ -182,6 +186,13 @@ void ParticleSystem::setVisible(bool visible){
// =============== MISC =========================
void ParticleSystem::fade(){
if(particleObserver != NULL){
if(state != sPlay) {
char szBuf[4096]="";
sprintf(szBuf,"state != sPlay, state = [%d]",state);
//throw runtime_error(szBuf);
//printf(szBuf);
SystemFlags::OutputDebug(SystemFlags::debugError,"%s",szBuf);
}
assert(state == sPlay);
}
state= sFade;