diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 56a6c7c9..0ea06f0c 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -1718,6 +1718,7 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) { bool wasAlive = alive; int prevMaxHp = totalUpgrade.getMaxHp(); + int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); //printf("#1 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); totalUpgrade.apply(&boost->boostUpgrade, this); @@ -1727,6 +1728,16 @@ bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) { hp += (totalUpgrade.getMaxHp() - prevMaxHp); addItemToVault(&this->hp,this->hp); + //regenerate hp upgrade / or boost + if(totalUpgrade.getMaxHpRegeneration() != 0) { + checkItemInVault(&this->hp,this->hp); + hp += (totalUpgrade.getMaxHpRegeneration() - prevMaxHpRegen); + if(hp > totalUpgrade.getMaxHp()) { + hp = totalUpgrade.getMaxHp(); + } + addItemToVault(&this->hp,this->hp); + } + //printf("#2 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); if(showUnitParticles == true) { @@ -1788,6 +1799,7 @@ void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) { bool wasAlive = alive; int prevMaxHp = totalUpgrade.getMaxHp(); + int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); totalUpgrade.deapply(&boost->boostUpgrade, this); checkItemInVault(&this->hp,this->hp); @@ -1795,6 +1807,16 @@ void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) { hp -= (prevMaxHp - totalUpgrade.getMaxHp()); addItemToVault(&this->hp,this->hp); + //regenerate hp upgrade / or boost + if(totalUpgrade.getMaxHpRegeneration() != 0) { + checkItemInVault(&this->hp,this->hp); + hp -= (totalUpgrade.getMaxHpRegeneration() - prevMaxHpRegen); + if(hp > totalUpgrade.getMaxHp()) { + hp = totalUpgrade.getMaxHp(); + } + addItemToVault(&this->hp,this->hp); + } + if(wasAlive == true) { //printf("DE-APPLYING ATTACK BOOST wasalive = true to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); @@ -1872,6 +1894,30 @@ void Unit::tick() { } } + //regenerate hp upgrade / or boost + if(type->getTotalMaxHpRegeneration(&totalUpgrade) >= 0) { + checkItemInVault(&this->hp,this->hp); + hp += type->getTotalMaxHpRegeneration(&totalUpgrade); + if(hp > type->getTotalMaxHp(&totalUpgrade)) { + hp = type->getTotalMaxHp(&totalUpgrade); + } + addItemToVault(&this->hp,this->hp); + } + // If we have negative regeneration then check if the unit should die + else { + bool decHpResult = decHp(-type->getTotalMaxHpRegeneration(&totalUpgrade)); + if(decHpResult) { + Unit::game->getWorld()->getStats()->die(getFactionIndex()); + game->getScriptManager()->onUnitDied(this); + } + StaticSound *sound= this->getType()->getFirstStOfClass(scDie)->getSound(); + if(sound != NULL && + (this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() || + (game->getWorld()->getThisTeamIndex() == GameConstants::maxPlayers -1 + fpt_Observer))) { + SoundRenderer::getInstance().playFx(sound); + } + } + //stop DamageParticles stopDamageParticles(false); @@ -1882,6 +1928,16 @@ void Unit::tick() { ep = type->getTotalMaxEp(&totalUpgrade); } addItemToVault(&this->ep,this->ep); + + //regenerate ep upgrade / or boost + checkItemInVault(&this->ep,this->ep); + //regenerate ep + ep += type->getTotalMaxEpRegeneration(&totalUpgrade); + if(ep > type->getTotalMaxEp(&totalUpgrade)){ + ep = type->getTotalMaxEp(&totalUpgrade); + } + addItemToVault(&this->ep,this->ep); + } } @@ -2045,16 +2101,24 @@ string Unit::getDesc() const { //str += "\n"+lang.get("Hp")+ ": " + intToStr(hp) + "/" + intToStr(type->getTotalMaxHp(&totalUpgrade)) + " [" + floatToStr(getHpRatio()) + "] [" + floatToStr(animProgress) + "]"; str += "\n"+lang.get("Hp")+ ": " + intToStr(hp) + "/" + intToStr(type->getTotalMaxHp(&totalUpgrade)); - if(type->getHpRegeneration()!=0){ - str+= " (" + lang.get("Regeneration") + ": " + intToStr(type->getHpRegeneration()) + ")"; + if(type->getHpRegeneration() != 0) { + str+= " (" + lang.get("Regeneration") + ": " + intToStr(type->getHpRegeneration()); + if(type->getTotalMaxHpRegeneration(&totalUpgrade) != 0) { + str+= "/" + intToStr(type->getTotalMaxHpRegeneration(&totalUpgrade)); + } + str+= ")"; } //ep if(getType()->getMaxEp()!=0){ str+= "\n" + lang.get("Ep")+ ": " + intToStr(ep) + "/" + intToStr(type->getTotalMaxEp(&totalUpgrade)); } - if(type->getEpRegeneration()!=0){ - str+= " (" + lang.get("Regeneration") + ": " + intToStr(type->getEpRegeneration()) + ")"; + if(type->getEpRegeneration() != 0) { + str+= " (" + lang.get("Regeneration") + ": " + intToStr(type->getEpRegeneration()); + if(type->getTotalMaxEpRegeneration(&totalUpgrade) != 0) { + str += "/" + intToStr(type->getTotalMaxEpRegeneration(&totalUpgrade)); + } + str+= ")"; } //armor diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index c800899e..98389a3b 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -708,6 +708,13 @@ int UnitType::getTotalMaxHp(const TotalUpgrade *totalUpgrade) const { return result; } +int UnitType::getTotalMaxHpRegeneration(const TotalUpgrade *totalUpgrade) const { + checkItemInVault(&(this->hpRegeneration),this->hpRegeneration); + int result = hpRegeneration + totalUpgrade->getMaxHpRegeneration(); + result = max(0,result); + return result; +} + int UnitType::getTotalMaxEp(const TotalUpgrade *totalUpgrade) const { checkItemInVault(&(this->maxEp),this->maxEp); int result = maxEp + totalUpgrade->getMaxEp(); @@ -715,6 +722,13 @@ int UnitType::getTotalMaxEp(const TotalUpgrade *totalUpgrade) const { return result; } +int UnitType::getTotalMaxEpRegeneration(const TotalUpgrade *totalUpgrade) const { + checkItemInVault(&(this->epRegeneration),this->epRegeneration); + int result = epRegeneration + totalUpgrade->getMaxEpRegeneration(); + result = max(0,result); + return result; +} + int UnitType::getTotalArmor(const TotalUpgrade *totalUpgrade) const { checkItemInVault(&(this->armor),this->armor); int result = armor + totalUpgrade->getArmor(); diff --git a/source/glest_game/types/unit_type.h b/source/glest_game/types/unit_type.h index f8290b9d..16ccf956 100644 --- a/source/glest_game/types/unit_type.h +++ b/source/glest_game/types/unit_type.h @@ -188,7 +188,9 @@ public: //get totals int getTotalMaxHp(const TotalUpgrade *totalUpgrade) const; + int getTotalMaxHpRegeneration(const TotalUpgrade *totalUpgrade) const; int getTotalMaxEp(const TotalUpgrade *totalUpgrade) const; + int getTotalMaxEpRegeneration(const TotalUpgrade *totalUpgrade) const; int getTotalArmor(const TotalUpgrade *totalUpgrade) const; int getTotalSight(const TotalUpgrade *totalUpgrade) const; diff --git a/source/glest_game/types/upgrade_type.cpp b/source/glest_game/types/upgrade_type.cpp index e6362569..aba7c3be 100644 --- a/source/glest_game/types/upgrade_type.cpp +++ b/source/glest_game/types/upgrade_type.cpp @@ -38,6 +38,8 @@ namespace Glest{ namespace Game{ // ==================== get ==================== const string VALUE_PERCENT_MULTIPLIER_KEY_NAME = "value-percent-multiplier"; +const string VALUE_REGEN_KEY_NAME = "regeneration"; + void UpgradeTypeBase::load(const XmlNode *upgradeNode) { //values @@ -48,6 +50,13 @@ void UpgradeTypeBase::load(const XmlNode *upgradeNode) { //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); } + maxHpRegeneration = 0; + //maxHpRegenerationIsMultiplier = false; + if(upgradeNode->getChild("max-hp")->getAttribute(VALUE_REGEN_KEY_NAME,false) != NULL) { + maxHpRegeneration = upgradeNode->getChild("max-hp")->getAttribute(VALUE_REGEN_KEY_NAME)->getIntValue(); + + //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); + } maxEpIsMultiplier = false; maxEp= upgradeNode->getChild("max-ep")->getAttribute("value")->getIntValue(); @@ -56,6 +65,13 @@ void UpgradeTypeBase::load(const XmlNode *upgradeNode) { //printf("Found maxEpIsMultiplier = %d\n",maxEpIsMultiplier); } + maxEpRegeneration = 0; + //maxEpRegenerationIsMultiplier = false; + if(upgradeNode->getChild("max-ep")->getAttribute(VALUE_REGEN_KEY_NAME,false) != NULL) { + maxEpRegeneration = upgradeNode->getChild("max-ep")->getAttribute(VALUE_REGEN_KEY_NAME)->getIntValue(); + + //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); + } sightIsMultiplier = false; sight= upgradeNode->getChild("sight")->getAttribute("value")->getIntValue(); @@ -317,29 +333,76 @@ string UpgradeType::getReqDesc() const{ } } - if(maxHp!=0){ - str+= lang.get("Hp")+" +"+intToStr(maxHp); + if(maxHp != 0) { + if(maxHpIsMultiplier) { + str += lang.get("Hp") + " *" + intToStr(maxHp); + } + else { + str += lang.get("Hp") + " +" + intToStr(maxHp); + } + + if(maxHpRegeneration != 0) { + str += " [" + intToStr(maxHpRegeneration) + "]"; + } } - if(sight!=0){ - str+= lang.get("Sight")+" +"+intToStr(sight); + if(sight != 0) { + if(sightIsMultiplier) { + str+= lang.get("Sight") + " *" + intToStr(sight); + } + else { + str+= lang.get("Sight") + " +" + intToStr(sight); + } } - if(maxEp!=0){ - str+= lang.get("Ep")+" +"+intToStr(maxEp)+"\n"; + if(maxEp != 0) { + if(maxEpIsMultiplier) { + str+= lang.get("Ep") + " *" + intToStr(maxEp)+"\n"; + } + else { + str+= lang.get("Ep") + " +" + intToStr(maxEp)+"\n"; + } + if(maxEpRegeneration != 0) { + str += " [" + intToStr(maxEpRegeneration) + "]"; + } } - if(attackStrength!=0){ - str+= lang.get("AttackStrenght")+" +"+intToStr(attackStrength)+"\n"; + if(attackStrength != 0) { + if(attackStrengthIsMultiplier) { + str+= lang.get("AttackStrenght") + " *" + intToStr(attackStrength)+"\n"; + } + else { + str+= lang.get("AttackStrenght") + " +" + intToStr(attackStrength)+"\n"; + } } - if(attackRange!=0){ - str+= lang.get("AttackDistance")+" +"+intToStr(attackRange)+"\n"; + if(attackRange != 0) { + if(attackRangeIsMultiplier) { + str+= lang.get("AttackDistance") + " *" + intToStr(attackRange)+"\n"; + } + else { + str+= lang.get("AttackDistance") + " +" + intToStr(attackRange)+"\n"; + } } - if(armor!=0){ - str+= lang.get("Armor")+" +"+intToStr(armor)+"\n"; + if(armor != 0) { + if(armorIsMultiplier) { + str+= lang.get("Armor") + " *" + intToStr(armor)+"\n"; + } + else { + str+= lang.get("Armor") + " +" + intToStr(armor)+"\n"; + } } - if(moveSpeed!=0){ - str+= lang.get("WalkSpeed")+"+ "+intToStr(moveSpeed)+"\n"; + if(moveSpeed != 0) { + if(moveSpeedIsMultiplier) { + str+= lang.get("WalkSpeed") + " *" + intToStr(moveSpeed)+"\n"; + } + else { + str+= lang.get("WalkSpeed") + " +" + intToStr(moveSpeed)+"\n"; + } } - if(prodSpeed!=0){ - str+= lang.get("ProductionSpeed")+" +"+intToStr(prodSpeed)+"\n"; + if(prodSpeed != 0) { + if(prodSpeedIsMultiplier) { + str+= lang.get("ProductionSpeed") + " *" + intToStr(prodSpeed)+"\n"; + } + else { + str+= lang.get("ProductionSpeed") + " +" + intToStr(prodSpeed)+"\n"; + } } return str; @@ -357,13 +420,30 @@ TotalUpgrade::TotalUpgrade() { void TotalUpgrade::reset() { maxHp= 0; + maxHpIsMultiplier=false; + maxHpRegeneration = 0; + maxEp= 0; + maxEpIsMultiplier = false; + maxEpRegeneration = 0; + sight=0; + sightIsMultiplier=false; + armor= 0; + armorIsMultiplier=false; + attackStrength= 0; + attackStrengthIsMultiplier=false; + attackRange= 0; + attackRangeIsMultiplier=false; + moveSpeed= 0; + moveSpeedIsMultiplier=false; + prodSpeed=0; + prodSpeedIsMultiplier=false; } void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { @@ -379,18 +459,30 @@ void TotalUpgrade::sum(const UpgradeTypeBase *ut, const Unit *unit) { if(ut->getMaxHpIsMultiplier() == true) { //printf("#1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); maxHp += ((double)unit->getHp() * ((double)ut->getMaxHp() / (double)100)); + if(ut->getMaxHpRegeneration() != 0) { + maxHpRegeneration += ((double)unit->getType()->getHpRegeneration() * ((double)ut->getMaxHpRegeneration() / (double)100)); + } //printf("#1.1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); } else { //printf("#2 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); maxHp += ut->getMaxHp(); + if(ut->getMaxHpRegeneration() != 0) { + maxHpRegeneration += ut->getMaxHpRegeneration(); + } } if(ut->getMaxEpIsMultiplier() == true) { maxEp += ((double)unit->getEp() * ((double)ut->getMaxEp() / (double)100)); + if(ut->getMaxHpRegeneration() != 0) { + maxEpRegeneration += ((double)unit->getType()->getEpRegeneration() * ((double)ut->getMaxEpRegeneration() / (double)100)); + } } else { maxEp += ut->getMaxEp(); + if(ut->getMaxEpRegeneration() != 0) { + maxEpRegeneration += ut->getMaxEpRegeneration(); + } } if(ut->getSightIsMultiplier() == true) { @@ -490,16 +582,28 @@ void TotalUpgrade::deapply(const UpgradeTypeBase *ut,const Unit *unit) { if(ut->getMaxHpIsMultiplier() == true) { maxHp -= ((double)unit->getHp() * ((double)ut->getMaxHp() / (double)100)); + if(ut->getMaxHpRegeneration() != 0) { + maxHpRegeneration -= ((double)unit->getType()->getHpRegeneration() * ((double)ut->getMaxHpRegeneration() / (double)100)); + } } else { maxHp -= ut->getMaxHp(); + if(ut->getMaxHpRegeneration() != 0) { + maxHpRegeneration -= ut->getMaxHpRegeneration(); + } } if(ut->getMaxEpIsMultiplier() == true) { maxEp -= ((double)unit->getEp() * ((double)ut->getMaxEp() / (double)100)); + if(ut->getMaxEpRegeneration() != 0) { + maxEpRegeneration += ((double)unit->getType()->getEpRegeneration() * ((double)ut->getMaxEpRegeneration() / (double)100)); + } } else { maxEp -= ut->getMaxEp(); + if(ut->getMaxEpRegeneration() != 0) { + maxEpRegeneration += ut->getMaxEpRegeneration(); + } } if(ut->getSightIsMultiplier() == true) { diff --git a/source/glest_game/types/upgrade_type.h b/source/glest_game/types/upgrade_type.h index fbdd7ebe..f27a774e 100644 --- a/source/glest_game/types/upgrade_type.h +++ b/source/glest_game/types/upgrade_type.h @@ -41,12 +41,16 @@ class UpgradeTypeBase { protected: int maxHp; bool maxHpIsMultiplier; + int maxHpRegeneration; + //bool maxHpRegenerationIsMultiplier; int sight; bool sightIsMultiplier; int maxEp; bool maxEpIsMultiplier; + int maxEpRegeneration; + //bool maxEpRegenerationIsMultiplier; int armor; bool armorIsMultiplier; @@ -72,10 +76,17 @@ protected: public: int getMaxHp() const {return maxHp;} bool getMaxHpIsMultiplier() const {return maxHpIsMultiplier;} + int getMaxHpRegeneration() const {return maxHpRegeneration;} + //bool getMaxHpRegenerationIsMultiplier() const {return maxHpRegenerationIsMultiplier;} + int getSight() const {return sight;} bool getSightIsMultiplier() const {return sightIsMultiplier;} + int getMaxEp() const {return maxEp;} bool getMaxEpIsMultiplier() const {return maxEpIsMultiplier;} + int getMaxEpRegeneration() const {return maxEpRegeneration;} + //bool getMaxEpRegenerationIsMultiplier() const {return maxEpRegenerationIsMultiplier;} + int getArmor() const {return armor;} bool getArmorIsMultiplier() const {return armorIsMultiplier;} @@ -95,10 +106,17 @@ public: result += "maxHp = " + intToStr(maxHp); result += "maxHpIsMultiplier = " + intToStr(maxHpIsMultiplier); + result += "maxHpRegeneration = " + intToStr(maxHpRegeneration); + //result += "maxHpRegenerationIsMultiplier = " + intToStr(maxHpRegenerationIsMultiplier); + result += " sight = " + intToStr(sight); result += "sightIsMultiplier = " + intToStr(sightIsMultiplier); + result += " maxEp = " + intToStr(maxEp); result += "maxEpIsMultiplier = " + intToStr(maxEpIsMultiplier); + result += " maxEpRegeneration = " + intToStr(maxEpRegeneration); + //result += "maxEpRegenerationIsMultiplier = " + intToStr(maxEpRegenerationIsMultiplier); + result += " armor = " + intToStr(armor); result += "armorIsMultiplier = " + intToStr(armorIsMultiplier); result += " attackStrength = " + intToStr(attackStrength);