- 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::pathFindRefresh = 10;
const int PathFinder::pathFindBailoutRadius = 20; const int PathFinder::pathFindBailoutRadius = 20;
const int PathFinder::pathFindExtendRefreshForNodeCount = 25; const int PathFinder::pathFindExtendRefreshForNodeCount = 25;
const int PathFinder::pathFindExtendRefreshNodeCountMin = 20; const int PathFinder::pathFindExtendRefreshNodeCountMin = 40;
const int PathFinder::pathFindExtendRefreshNodeCountMax = 60; const int PathFinder::pathFindExtendRefreshNodeCountMax = 60;
PathFinder::PathFinder() { PathFinder::PathFinder() {

View File

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

View File

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

View File

@ -3112,15 +3112,16 @@ void Renderer::renderSelectionEffects() {
// Render Attack-boost circles // Render Attack-boost circles
if(showDebugUI == true) { 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); 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 // Remove attack boost upgrades from unit
Unit *affectedUnit = currentAttackBoostUnits.second[i]; Unit *affectedUnit = effect.currentAttackBoostUnits[i];
Vec3f currVecBoost = affectedUnit->getCurrVectorFlat(); Vec3f currVecBoost = affectedUnit->getCurrVectorFlat();
currVecBoost.y += 0.3f; currVecBoost.y += 0.3f;

View File

@ -179,6 +179,39 @@ Unit *UnitReference::getUnit() const{
return NULL; 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 // class Unit
// ===================================================== // =====================================================
@ -278,7 +311,7 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType
//starting skill //starting skill
this->lastModelIndexForCurrSkillType = -1; this->lastModelIndexForCurrSkillType = -1;
this->currSkill = getType()->getFirstStOfClass(scStop); this->currSkill = getType()->getFirstStOfClass(scStop);
this->currentAttackBoostUnits.first = this->currSkill; this->currentAttackBoostOriginatorEffect.skillType = this->currSkill;
livingUnits.insert(id); livingUnits.insert(id);
livingUnitsp.insert(this); livingUnitsp.insert(this);
@ -328,6 +361,14 @@ Unit::~Unit() {
} }
stopDamageParticles(); stopDamageParticles();
while(currentAttackBoostEffects.empty() == false) {
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
currentAttackBoostEffects.pop_back();
}
delete currentAttackBoostOriginatorEffect.currentAppliedEffect;
currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL;
delete this->unitPath; delete this->unitPath;
this->unitPath = NULL; this->unitPath = NULL;
@ -678,6 +719,18 @@ void Unit::setVisible(const bool visible) {
for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) { for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) {
(*it)->setVisible(visible); (*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 ================================== // =============================== 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()); 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 // Remove any units that were previously in attack-boost range
if(currentAttackBoostUnits.second.size() > 0) { if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() > 0) {
for(unsigned int i = 0; i < currentAttackBoostUnits.second.size(); ++i) { for(unsigned int i = 0; i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); ++i) {
// Remove attack boost upgrades from unit // Remove attack boost upgrades from unit
Unit *affectedUnit = currentAttackBoostUnits.second[i]; Unit *affectedUnit = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i];
affectedUnit->deapplyAttackBoost(currentAttackBoostUnits.first->getAttackBoost(), this); affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this);
//printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); //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(); UnitUpdater *unitUpdater = game->getWorld()->getUnitUpdater();
@ -1221,6 +1274,20 @@ bool Unit::update() {
(*it)->setRotation(getRotation()); (*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 //checks
if(animProgress > 1.f) { if(animProgress > 1.f) {
animProgress = currSkill->getClass() == scDie? 1.f: 0.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(currSkill != currentAttackBoostOriginatorEffect.skillType) {
if(currentAttackBoostUnits.second.size() > 0) { if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) {
for(unsigned int i = 0; i < currentAttackBoostUnits.second.size(); ++i) { delete currentAttackBoostOriginatorEffect.currentAppliedEffect;
// Remove attack boost upgrades from unit currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL;
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()); //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) { const AttackBoost *attackBoost = currSkill->getAttackBoost();
// Search for units in range of this unit which apply to the vector<Unit *> candidates = unitUpdater->findUnitsInRange(this, attackBoost->radius);
// attack-boost and temporarily upgrade them for(unsigned int i = 0; i < candidates.size(); ++i) {
UnitUpdater *unitUpdater = this->game->getWorld()->getUnitUpdater(); Unit *affectedUnit = candidates[i];
const AttackBoost *attackBoost = currSkill->getAttackBoost(); std::vector<Unit *>::iterator iterFound = std::find(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(), currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end(), affectedUnit);
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); 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; 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() { void Unit::tick() {
if(isAlive()) { if(isAlive()) {
@ -1562,38 +1807,6 @@ string Unit::getDesc() const {
return str; 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){ void Unit::applyUpgrade(const UpgradeType *upgradeType){
if(upgradeType == NULL) { if(upgradeType == NULL) {
char szBuf[4096]=""; char szBuf[4096]="";
@ -2182,7 +2395,7 @@ void Unit::setLastHarvestResourceTarget(const Vec2i *pos) {
// as a bad one // as a bad one
const int addInterval = (GameConstants::updateFps * 5); const int addInterval = (GameConstants::updateFps * 5);
if(lastHarvestResourceTarget.second - getFrameCount() >= addInterval) { if(lastHarvestResourceTarget.second - getFrameCount() >= addInterval) {
printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second); //printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second);
addBadHarvestPos(resourceLocation); addBadHarvestPos(resourceLocation);
} }
} }

View File

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

View File

@ -30,47 +30,70 @@ namespace Glest{ namespace Game{
AttackBoost::AttackBoost() { AttackBoost::AttackBoost() {
enabled = false; enabled = false;
radius = 0; allowMultipleBoosts = false;
boostAllUnits = 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 AttackBoost::isAffected(const Unit *source, const Unit *dest) const {
bool result = false; bool result = false;
if(enabled == true && source != NULL && dest != NULL && if(enabled == true && source != NULL && dest != NULL && source != dest) {
source != dest) { bool destUnitMightApply = false;
// All units are affected (including enemies) // 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()); float distance = source->getCenteredPos().dist(dest->getCenteredPos());
if(distance <= radius) { if(distance <= radius) {
result = true; 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; return result;
@ -185,17 +208,63 @@ void SkillType::load(const XmlNode *sn, const string &dir, const TechTree *tt,
attackBoost.enabled = true; attackBoost.enabled = true;
const XmlNode *attackBoostNode = sn->getChild("attack-boost"); 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.radius = attackBoostNode->getChild("radius")->getAttribute("value")->getIntValue();
attackBoost.boostAllUnits = attackBoostNode->getChild("boost-all-units")->getAttribute("value")->getBoolValue();
if(attackBoost.boostAllUnits == false) { string targetType = attackBoostNode->getChild("target")->getAttribute("value")->getValue();
for(int i = 0; i < attackBoostNode->getChild("boost-all-units")->getChildCount(); ++i) { if(targetType == "ally") {
const XmlNode *boostUnitNode= attackBoostNode->getChild("boost-all-units")->getChild("unit-type", i); 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.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 { 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 /// A basic action that an unit can perform
// ===================================================== // =====================================================
enum AttackBoostTargetType {
abtAlly,
abtFoe,
abtFaction,
abtUnitTypes,
abtAll
};
class AttackBoost { class AttackBoost {
public: public:
AttackBoost(); AttackBoost();
~AttackBoost();
bool enabled; bool enabled;
bool allowMultipleBoosts;
int radius; int radius;
bool boostAllUnits; AttackBoostTargetType targetType;
vector<const UnitType *> boostUnitList; vector<const UnitType *> boostUnitList;
UpgradeTypeBase boostUpgrade; UpgradeTypeBase boostUpgrade;
UnitParticleSystemType *unitParticleSystemTypeForSourceUnit;
UnitParticleSystemType *unitParticleSystemTypeForAffectedUnit;
bool isAffected(const Unit *source, const Unit *dest) const; bool isAffected(const Unit *source, const Unit *dest) const;
}; };

View File

@ -33,7 +33,9 @@ namespace Graphics {
// class ParticleSystem // class ParticleSystem
// ===================================================== // =====================================================
ParticleSystem::ParticleSystem(int particleCount){ ParticleSystem::ParticleSystem(int particleCount) {
//printf("++ Create ParticleSystem [%p]\n",this);
//init particle vector //init particle vector
blendMode= bmOne; blendMode= bmOne;
//particles= new Particle[particleCount]; //particles= new Particle[particleCount];
@ -67,6 +69,8 @@ ParticleSystem::ParticleSystem(int particleCount){
} }
ParticleSystem::~ParticleSystem(){ ParticleSystem::~ParticleSystem(){
//printf("-- Delete ParticleSystem [%p]\n",this);
//delete [] particles; //delete [] particles;
particles.clear(); particles.clear();
} }
@ -182,6 +186,13 @@ void ParticleSystem::setVisible(bool visible){
// =============== MISC ========================= // =============== MISC =========================
void ParticleSystem::fade(){ void ParticleSystem::fade(){
if(particleObserver != NULL){ 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); assert(state == sPlay);
} }
state= sFade; state= sFade;