- added support for min / max hp associated with damage particles

This commit is contained in:
Mark Vejvoda 2011-07-01 21:47:54 +00:00
parent d2c8cc0187
commit 850825695e
7 changed files with 202 additions and 75 deletions

View File

@ -40,6 +40,10 @@ ParticleSystemType::ParticleSystemType() {
alternations=false; alternations=false;
texture=NULL; texture=NULL;
model=NULL; model=NULL;
minmaxEnabled=false;
minHp=0;
maxHp=0;
minmaxIsPercent=false;
} }
ParticleSystemType::~ParticleSystemType() { ParticleSystemType::~ParticleSystemType() {
@ -162,8 +166,7 @@ void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &d
const XmlNode *modeNode= particleSystemNode->getChild("mode"); const XmlNode *modeNode= particleSystemNode->getChild("mode");
mode= modeNode->getAttribute("value")->getRestrictedValue(); mode= modeNode->getAttribute("value")->getRestrictedValue();
} }
else else {
{
mode="normal"; mode="normal";
} }
} }

View File

@ -65,6 +65,11 @@ protected:
bool teamcolorEnergy; bool teamcolorEnergy;
int alternations; int alternations;
bool minmaxEnabled;
int minHp;
int maxHp;
bool minmaxIsPercent;
public: public:
ParticleSystemType(); ParticleSystemType();
~ParticleSystemType(); ~ParticleSystemType();
@ -76,6 +81,16 @@ public:
bool hasTexture() const { return(texture != NULL); } bool hasTexture() const { return(texture != NULL); }
bool hasModel() const { return(model != NULL); } bool hasModel() const { return(model != NULL); }
bool getMinmaxEnabled() const { return minmaxEnabled;}
int getMinHp() const { return minHp;}
int getMaxHp() const { return maxHp;}
bool getMinmaxIsPercent() const { return minmaxIsPercent; }
void setMinmaxEnabled(bool value) { minmaxEnabled=value;}
void setMinHp(int value) { minHp=value;}
void setMaxHp(int value) { maxHp=value;}
void setMinmaxIsPercent(bool value) { minmaxIsPercent=value; }
protected: protected:
}; };

View File

@ -360,7 +360,7 @@ Unit::~Unit() {
unitParticleSystems.back()->fade(); unitParticleSystems.back()->fade();
unitParticleSystems.pop_back(); unitParticleSystems.pop_back();
} }
stopDamageParticles(); stopDamageParticles(true);
while(currentAttackBoostEffects.empty() == false) { while(currentAttackBoostEffects.empty() == false) {
//UnitAttackBoostEffect &effect = currentAttackBoostEffects.back(); //UnitAttackBoostEffect &effect = currentAttackBoostEffects.back();
@ -1574,9 +1574,7 @@ void Unit::tick() {
} }
//stop DamageParticles //stop DamageParticles
if(hp > type->getTotalMaxHp(&totalUpgrade) / 2) { stopDamageParticles(false);
stopDamageParticles();
}
checkItemInVault(&this->ep,this->ep); checkItemInVault(&this->ep,this->ep);
//regenerate ep //regenerate ep
@ -1676,9 +1674,8 @@ bool Unit::repair(){
addItemToVault(&this->hp,this->hp); addItemToVault(&this->hp,this->hp);
//stop DamageParticles //stop DamageParticles
if(hp > type->getTotalMaxHp(&totalUpgrade)/2 ) { stopDamageParticles(false);
stopDamageParticles();
}
return false; return false;
} }
@ -1699,9 +1696,7 @@ bool Unit::decHp(int i) {
} }
//startDamageParticles //startDamageParticles
if(hp < type->getMaxHp() / 2 ) { startDamageParticles();
startDamageParticles();
}
//stop DamageParticles on death //stop DamageParticles on death
if(hp <= 0) { if(hp <= 0) {
@ -1709,7 +1704,7 @@ bool Unit::decHp(int i) {
hp=0; hp=0;
addItemToVault(&this->hp,this->hp); addItemToVault(&this->hp,this->hp);
stopDamageParticles(); stopDamageParticles(true);
return true; return true;
} }
return false; return false;
@ -2142,74 +2137,168 @@ CommandResult Unit::undoCommand(Command *command){
return crSuccess; return crSuccess;
} }
void Unit::stopDamageParticles() { void Unit::stopDamageParticles(bool force) {
if(force == true || (hp > type->getTotalMaxHp(&totalUpgrade) / 2) ) {
if(Renderer::getInstance().validateParticleSystemStillExists(fire,rsGame) == false) {
fire = NULL;
}
if(Renderer::getInstance().validateParticleSystemStillExists(fire,rsGame) == false) { // stop fire
fire = NULL; if(fire != NULL) {
fire->fade();
fire = NULL;
}
// stop additional particles
for(unsigned int i = damageParticleSystems.size()-1; i <= 0; --i) {
UnitParticleSystem *ps = damageParticleSystems[i];
UnitParticleSystemType *pst = NULL;
int foundParticleIndexType = -1;
for(std::map<int, UnitParticleSystem *>::iterator iterMap = damageParticleSystemsInUse.begin();
iterMap != damageParticleSystemsInUse.end(); ++iterMap) {
if(iterMap->second == ps) {
foundParticleIndexType = iterMap->first;
pst = type->damageParticleSystemTypes[foundParticleIndexType];
break;
}
}
if(force == true || pst == NULL ||
pst->getMinmaxEnabled() == false) {
damageParticleSystemsInUse.erase(foundParticleIndexType);
ps->fade();
damageParticleSystems.pop_back();
}
}
} }
// stop fire checkCustomizedParticleTriggers(force);
if(fire != NULL) { }
fire->fade();
fire = NULL; void Unit::checkCustomizedParticleTriggers(bool force) {
// Now check if we have special hp triggered particles
for(unsigned int i = damageParticleSystems.size()-1; i <= 0; --i) {
UnitParticleSystem *ps = damageParticleSystems[i];
UnitParticleSystemType *pst = NULL;
int foundParticleIndexType = -1;
for(std::map<int, UnitParticleSystem *>::iterator iterMap = damageParticleSystemsInUse.begin();
iterMap != damageParticleSystemsInUse.end(); ++iterMap) {
if(iterMap->second == ps) {
foundParticleIndexType = iterMap->first;
pst = type->damageParticleSystemTypes[foundParticleIndexType];
break;
}
}
if(force == true || (pst != NULL && pst->getMinmaxEnabled() == true)) {
bool stopParticle = force;
if(force == false && pst->getMinmaxIsPercent() == false) {
if(hp < pst->getMinHp() || hp > pst->getMaxHp()) {
stopParticle = true;
}
}
//printf("CHECKING to STOP customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d stopParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,stopParticle);
if(stopParticle == true) {
//printf("STOPPING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp);
damageParticleSystemsInUse.erase(foundParticleIndexType);
ps->fade();
damageParticleSystems.pop_back();
}
}
} }
// stop additional particles
while(damageParticleSystems.empty() == false) { // Now check if we have special hp triggered particles
damageParticleSystems.back()->fade(); //start additional particles
damageParticleSystems.pop_back(); if( showUnitParticles && (type->damageParticleSystemTypes.empty() == false) ) {
for(unsigned int i = 0; i < type->damageParticleSystemTypes.size(); ++i) {
UnitParticleSystemType *pst = type->damageParticleSystemTypes[i];
if(pst->getMinmaxEnabled() == true && damageParticleSystemsInUse.find(i) == damageParticleSystemsInUse.end()) {
bool showParticle = false;
if(pst->getMinmaxIsPercent() == false) {
if(hp >= pst->getMinHp() && hp <= pst->getMaxHp()) {
showParticle = true;
}
}
//printf("CHECKING to START customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d showParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,showParticle);
if(showParticle == true) {
//printf("STARTING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp);
UnitParticleSystem *ups = new UnitParticleSystem(200);
pst->setValues(ups);
ups->setPos(getCurrVector());
ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
damageParticleSystems.push_back(ups);
damageParticleSystemsInUse[i] = ups;
Renderer::getInstance().manageParticleSystem(ups, rsGame);
}
}
}
} }
} }
void Unit::startDamageParticles(){ void Unit::startDamageParticles() {
//start additional particles if(hp < type->getMaxHp() / 2 && hp > 0) {
if( showUnitParticles && (!type->damageParticleSystemTypes.empty()) //start additional particles
&& (damageParticleSystems.empty()) ){ if( showUnitParticles && (!type->damageParticleSystemTypes.empty()) ) {
for(UnitParticleSystemTypes::const_iterator it= type->damageParticleSystemTypes.begin(); it!=type->damageParticleSystemTypes.end(); ++it){ for(unsigned int i = 0; i < type->damageParticleSystemTypes.size(); ++i) {
UnitParticleSystem *ups; UnitParticleSystemType *pst = type->damageParticleSystemTypes[i];
ups= new UnitParticleSystem(200);
(*it)->setValues(ups);
ups->setPos(getCurrVector());
ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
damageParticleSystems.push_back(ups);
Renderer::getInstance().manageParticleSystem(ups, rsGame);
}
}
// start fire
if(type->getProperty(UnitType::pBurnable) && fire == NULL) {
FireParticleSystem *fps = new FireParticleSystem(200);
const Game *game = Renderer::getInstance().getGame();
fps->setSpeed(2.5f / game->getWorld()->getUpdateFps(this->getFactionIndex()));
fps->setPos(getCurrVector());
fps->setRadius(type->getSize()/3.f);
fps->setTexture(CoreData::getInstance().getFireTexture());
fps->setParticleSize(type->getSize()/3.f);
fire= fps;
fireParticleSystems.push_back(fps);
Renderer::getInstance().manageParticleSystem(fps, rsGame); if(pst->getMinmaxEnabled() == false && damageParticleSystemsInUse.find(i) == damageParticleSystemsInUse.end()) {
if(showUnitParticles) { UnitParticleSystem *ups = new UnitParticleSystem(200);
// smoke pst->setValues(ups);
UnitParticleSystem *ups= new UnitParticleSystem(400); ups->setPos(getCurrVector());
ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f)); ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0));
ups->setColor(Vec4f(0.115f, 0.115f, 0.115f, 0.22f)); damageParticleSystems.push_back(ups);
ups->setPos(getCurrVector()); damageParticleSystemsInUse[i] = ups;
ups->setBlendMode(ups->strToBlendMode("black")); Renderer::getInstance().manageParticleSystem(ups, rsGame);
ups->setOffset(Vec3f(0,2,0)); }
ups->setDirection(Vec3f(0,1,-0.2f)); }
ups->setRadius(type->getSize()/3.f); }
ups->setTexture(CoreData::getInstance().getFireTexture());
// start fire
if(type->getProperty(UnitType::pBurnable) && fire == NULL) {
FireParticleSystem *fps = new FireParticleSystem(200);
const Game *game = Renderer::getInstance().getGame(); const Game *game = Renderer::getInstance().getGame();
ups->setSpeed(2.0f / game->getWorld()->getUpdateFps(this->getFactionIndex())); fps->setSpeed(2.5f / game->getWorld()->getUpdateFps(this->getFactionIndex()));
ups->setGravity(0.0004f); fps->setPos(getCurrVector());
ups->setEmissionRate(1); fps->setRadius(type->getSize()/3.f);
ups->setMaxParticleEnergy(150); fps->setTexture(CoreData::getInstance().getFireTexture());
ups->setSizeNoEnergy(type->getSize()*0.6f); fps->setParticleSize(type->getSize()/3.f);
ups->setParticleSize(type->getSize()*0.8f); fire= fps;
damageParticleSystems.push_back(ups); fireParticleSystems.push_back(fps);
Renderer::getInstance().manageParticleSystem(ups, rsGame);
}
Renderer::getInstance().manageParticleSystem(fps, rsGame);
if(showUnitParticles) {
// smoke
UnitParticleSystem *ups= new UnitParticleSystem(400);
ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f));
ups->setColor(Vec4f(0.115f, 0.115f, 0.115f, 0.22f));
ups->setPos(getCurrVector());
ups->setBlendMode(ups->strToBlendMode("black"));
ups->setOffset(Vec3f(0,2,0));
ups->setDirection(Vec3f(0,1,-0.2f));
ups->setRadius(type->getSize()/3.f);
ups->setTexture(CoreData::getInstance().getFireTexture());
const Game *game = Renderer::getInstance().getGame();
ups->setSpeed(2.0f / game->getWorld()->getUpdateFps(this->getFactionIndex()));
ups->setGravity(0.0004f);
ups->setEmissionRate(1);
ups->setMaxParticleEnergy(150);
ups->setSizeNoEnergy(type->getSize()*0.6f);
ups->setParticleSize(type->getSize()*0.8f);
damageParticleSystems.push_back(ups);
damageParticleSystemsInUse[-1] = ups;
Renderer::getInstance().manageParticleSystem(ups, rsGame);
}
}
} }
checkCustomizedParticleTriggers(false);
} }
void Unit::setTargetVec(const Vec3f &targetVec) { void Unit::setTargetVec(const Vec3f &targetVec) {

View File

@ -1,4 +1,3 @@
// ==============================================================
// This file is part of Glest (www.glest.org) // This file is part of Glest (www.glest.org)
// //
// Copyright (C) 2001-2008 Marti<74>o Figueroa // Copyright (C) 2001-2008 Marti<74>o Figueroa
@ -328,6 +327,8 @@ private:
Observers observers; Observers observers;
vector<UnitParticleSystem*> unitParticleSystems; vector<UnitParticleSystem*> unitParticleSystems;
UnitParticleSystems damageParticleSystems; UnitParticleSystems damageParticleSystems;
std::map<int, UnitParticleSystem *> damageParticleSystemsInUse;
vector<ParticleSystem*> fireParticleSystems; vector<ParticleSystem*> fireParticleSystems;
CardinalDir modelFacing; CardinalDir modelFacing;
@ -573,10 +574,11 @@ private:
void clearCommands(); void clearCommands();
void deleteQueuedCommand(Command *command); void deleteQueuedCommand(Command *command);
CommandResult undoCommand(Command *command); CommandResult undoCommand(Command *command);
void stopDamageParticles(); void stopDamageParticles(bool force);
void startDamageParticles(); void startDamageParticles();
int getFrameCount() const; int getFrameCount() const;
void checkCustomizedParticleTriggers(bool force);
}; };
}}// end namespace }}// end namespace

View File

@ -297,6 +297,7 @@ Model *SkillType::getAnimation(float animProgress, const Unit *unit,
if(modelIndex < 0 || animProgress > 1.0f) { if(modelIndex < 0 || animProgress > 1.0f) {
bool canCycle = CanCycleNextRandomAnimation(animationRandomCycleCount); bool canCycle = CanCycleNextRandomAnimation(animationRandomCycleCount);
if(canCycle == true) { if(canCycle == true) {
vector<int> filteredAnimations;
bool foundSpecificAnimation = false; bool foundSpecificAnimation = false;
if(unit != NULL) { if(unit != NULL) {
for(unsigned int i = 0; i < animationAttributes.size(); ++i) { for(unsigned int i = 0; i < animationAttributes.size(); ++i) {
@ -305,9 +306,9 @@ Model *SkillType::getAnimation(float animProgress, const Unit *unit,
if(unit->getHp() >= attributes.fromHp && unit->getHp() <= attributes.toHp) { if(unit->getHp() >= attributes.fromHp && unit->getHp() <= attributes.toHp) {
modelIndex = i; modelIndex = i;
foundSpecificAnimation = true; foundSpecificAnimation = true;
filteredAnimations.push_back(i);
//printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); //printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp());
break; //break;
} }
} }
} }
@ -321,6 +322,11 @@ Model *SkillType::getAnimation(float animProgress, const Unit *unit,
//const AnimationAttributes &attributes = animationAttributes[modelIndex]; //const AnimationAttributes &attributes = animationAttributes[modelIndex];
//printf("SELECTING RANDOM Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",modelIndex,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); //printf("SELECTING RANDOM Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",modelIndex,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp());
} }
else {
srand(time(NULL) + unit->getId());
int filteredModelIndex = rand() % filteredAnimations.size();
modelIndex = filteredAnimations[filteredModelIndex];
}
} }
} }
} }

View File

@ -304,6 +304,18 @@ void UnitType::load(int id,const string &dir, const TechTree *techTree,
//Renderer::getInstance().endLastTexture(rsGame,true); //Renderer::getInstance().endLastTexture(rsGame,true);
//} //}
if(particleFileNode->getAttribute("minHp",false) != NULL && particleFileNode->getAttribute("maxHp",false) != NULL) {
unitParticleSystemType->setMinmaxEnabled(true);
unitParticleSystemType->setMinHp(particleFileNode->getAttribute("minHp")->getIntValue());
unitParticleSystemType->setMaxHp(particleFileNode->getAttribute("maxHp")->getIntValue());
if(particleFileNode->getAttribute("ispercentbased",false) != NULL) {
unitParticleSystemType->setMinmaxIsPercent(particleFileNode->getAttribute("ispercentbased")->getBoolValue());
}
//printf("Found customized particle trigger by HP [%d to %d]\n",unitParticleSystemType->getMinHp(),unitParticleSystemType->getMaxHp());
}
damageParticleSystemTypes.push_back(unitParticleSystemType); damageParticleSystemTypes.push_back(unitParticleSystemType);
} }
} }

View File

@ -64,7 +64,7 @@ enum UnitClass {
ucBuilding ucBuilding
}; };
typedef list<UnitParticleSystemType*> DamageParticleSystemTypes; typedef vector<UnitParticleSystemType*> DamageParticleSystemTypes;
class UnitType: public ProducibleType, public ValueCheckerVault { class UnitType: public ProducibleType, public ValueCheckerVault {
public: public: