From 49beed4e42d18ce31ac57e9e267190b0d8c29fb9 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Sat, 17 Jul 2010 17:02:11 +0000 Subject: [PATCH] Support for secondary skill specialities. Lots of changes, may be buggy. --- hch/CArtHandler.cpp | 18 ++++---- hch/CObjectHandler.cpp | 95 ++++++++++++++++++++++++++--------------- hch/CObjectHandler.h | 1 + lib/CGameState.cpp | 45 ++----------------- lib/NetPacksLib.cpp | 3 +- server/CGameHandler.cpp | 18 ++------ 6 files changed, 78 insertions(+), 102 deletions(-) diff --git a/hch/CArtHandler.cpp b/hch/CArtHandler.cpp index 757d32299..6ca8c725a 100644 --- a/hch/CArtHandler.cpp +++ b/hch/CArtHandler.cpp @@ -536,23 +536,23 @@ void CArtHandler::addBonuses() giveArtBonus(53,Bonus::SIGHT_RADIOUS,+1);//Spyglass //necromancy bonus - giveArtBonus(54,Bonus::SECONDARY_SKILL_PREMY,+5,12);//Amulet of the Undertaker - giveArtBonus(55,Bonus::SECONDARY_SKILL_PREMY,+10,12);//Vampire's Cowl - giveArtBonus(56,Bonus::SECONDARY_SKILL_PREMY,+15,12);//Dead Man's Boots + giveArtBonus(54,Bonus::SECONDARY_SKILL_PREMY,+5,12, Bonus::ADDITIVE_VALUE);//Amulet of the Undertaker + giveArtBonus(55,Bonus::SECONDARY_SKILL_PREMY,+10,12, Bonus::ADDITIVE_VALUE);//Vampire's Cowl + giveArtBonus(56,Bonus::SECONDARY_SKILL_PREMY,+15,12, Bonus::ADDITIVE_VALUE);//Dead Man's Boots giveArtBonus(57,Bonus::MAGIC_RESISTANCE,+5);//Garniture of Interference giveArtBonus(58,Bonus::MAGIC_RESISTANCE,+10);//Surcoat of Counterpoise giveArtBonus(59,Bonus::MAGIC_RESISTANCE,+15);//Boots of Polarity //archery bonus - giveArtBonus(60,Bonus::SECONDARY_SKILL_PREMY,+5,1);//Bow of Elven Cherrywood - giveArtBonus(61,Bonus::SECONDARY_SKILL_PREMY,+10,1);//Bowstring of the Unicorn's Mane - giveArtBonus(62,Bonus::SECONDARY_SKILL_PREMY,+15,1);//Angel Feather Arrows + giveArtBonus(60,Bonus::SECONDARY_SKILL_PREMY,+5,1, Bonus::ADDITIVE_VALUE);//Bow of Elven Cherrywood + giveArtBonus(61,Bonus::SECONDARY_SKILL_PREMY,+10,1, Bonus::ADDITIVE_VALUE);//Bowstring of the Unicorn's Mane + giveArtBonus(62,Bonus::SECONDARY_SKILL_PREMY,+15,1, Bonus::ADDITIVE_VALUE);//Angel Feather Arrows //eagle eye bonus - giveArtBonus(63,Bonus::SECONDARY_SKILL_PREMY,+5,11);//Bird of Perception - giveArtBonus(64,Bonus::SECONDARY_SKILL_PREMY,+10,11);//Stoic Watchman - giveArtBonus(65,Bonus::SECONDARY_SKILL_PREMY,+15,11);//Emblem of Cognizance + giveArtBonus(63,Bonus::SECONDARY_SKILL_PREMY,+5,11, Bonus::ADDITIVE_VALUE);//Bird of Perception + giveArtBonus(64,Bonus::SECONDARY_SKILL_PREMY,+10,11, Bonus::ADDITIVE_VALUE);//Stoic Watchman + giveArtBonus(65,Bonus::SECONDARY_SKILL_PREMY,+15,11, Bonus::ADDITIVE_VALUE);//Emblem of Cognizance //reducing cost of surrendering giveArtBonus(66,Bonus::SURRENDER_DISCOUNT,+10);//Statesman's Medal diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index c424a3124..20df39cad 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -615,13 +615,7 @@ int3 CGHeroInstance::getPosition(bool h3m) const //h3m=true - returns position o si32 CGHeroInstance::manaLimit() const { - double modifier = 1.0; - switch(getSecSkillLevel(24)) //intelligence level - { - case 1: modifier+=0.25; break; - case 2: modifier+=0.5; break; - case 3: modifier+=1.0; break; - } + double modifier = (100.0f + valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 24)) / 100.0f; return si32(10*getPrimSkillLevel(3)*modifier); } //void CGHeroInstance::setPosition(int3 Pos, bool h3m) //as above, but sets position @@ -673,34 +667,12 @@ int CGHeroInstance::maxMovePoints(bool onLand) const if(onLand) { //logistics: - switch(getSecSkillLevel(2)) - { - case 1: - modifier = 0.1; - break; - case 2: - modifier = 0.2; - break; - case 3: - modifier = 0.3; - break; - } + modifier = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 2) / 100.0f; } else { //navigation: - switch(getSecSkillLevel(5)) - { - case 1: - modifier = 0.5; - break; - case 2: - modifier = 1.0; - break; - case 3: - modifier = 1.5; - break; - } + modifier = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 5) / 100.0f; } return int(base + base*modifier) + bonus; } @@ -1132,6 +1104,9 @@ void CGHeroInstance::initObj() tlog2 << "Unexpected hero speciality " << type <<'\n'; } } + //initialize bonuses + for (std::vector >::iterator it = secSkills.begin(); it != secSkills.end(); it++) + updateSkill(it->first, it->second, true); UpdateSpeciality(); } void CGHeroInstance::UpdateSpeciality() @@ -1145,7 +1120,8 @@ void CGHeroInstance::UpdateSpeciality() { case Bonus::SECONDARY_SKILL_PREMY: it->val = (speciality.valOfBonuses(Bonus::SPECIAL_SECONDARY_SKILL, it->subtype) * - valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, it->subtype) * level); //TODO: use only skills as bonuses + valOfBonuses(Selector::typeSybtype(Bonus::SECONDARY_SKILL_PREMY, it->subtype),this) * level); + //use only hero skills as bonuses to avoid feedback loop break; case Bonus::PRIMARY_SKILL: //for crearures, that is int creLevel = (*creatures)[it->additionalInfo]->level; @@ -1177,6 +1153,56 @@ void CGHeroInstance::UpdateSpeciality() } } } +void CGHeroInstance::updateSkill(int which, int val, bool abs) +{ + int skillVal = 0; + switch (which) + { + case 1: //Archery + switch (val) + { + case 1: + skillVal = 10; break; + case 2: + skillVal = 25; break; + case 3: + skillVal = 50; break; + } + break; + case 2: //Logistics + skillVal = 10 * val; break; + case 5: //Navigation + skillVal = 50 * val; break; + case 8: //Mysticism + skillVal = val; break; + case 11: //eagle Eye + skillVal = 30 + 10 * val; break; + case 12: //Necromancy + skillVal = 10 * val; break; + case 22: //Offense + skillVal = 10 * val; break; + case 23: //Armorer + skillVal = 5 * val; break; + case 24: //Intelligence + skillVal = 25 << val-1; break; + case 25: //Sorcery + skillVal = 5 * val; break; + case 26: //Resistance + skillVal = 5 << val-1; break; + case 27: //First Aid + skillVal = 25 + 25*val; break; + } + if(!hasBonusOfType(Bonus::SECONDARY_SKILL_PREMY, which)) + { + bonuses.push_back + (Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, id, skillVal, ID, which, Bonus::BASE_NUMBER)); + } + else + { + if (skillVal) + getBonus(Selector::typeSybtype(Bonus::SECONDARY_SKILL_PREMY, which))->val = skillVal; + } +} void CGHeroInstance::setPropertyDer( ui8 what, ui32 val ) { if(what == ObjProperty::PRIMARY_STACK_COUNT) @@ -1253,8 +1279,7 @@ CStackInstance CGHeroInstance::calculateNecromancy (const BattleResult &battleRe // Hero knows necromancy. if (necromancyLevel > 0) { - double necromancySkill = necromancyLevel*0.1 - + valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 12)/100.0; + double necromancySkill = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 12)/100.0; amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all... const std::map &casualties = battleResult.casualties[!battleResult.winner]; ui32 raisedUnits = 0; @@ -1334,7 +1359,7 @@ si32 CGHeroInstance::manaRegain() const if (hasBonusOfType(Bonus::FULL_MANA_REGENERATION)) return manaLimit(); - return 1 + getSecSkillLevel(8) + valOfBonuses(Bonus::MANA_REGENERATION); //1 + Mysticism level + return 1 + valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 8) + valOfBonuses(Bonus::MANA_REGENERATION); //1 + Mysticism level } si32 CGHeroInstance::getArtPos(int aid) const diff --git a/hch/CObjectHandler.h b/hch/CObjectHandler.h index 212b99e96..b39409707 100644 --- a/hch/CObjectHandler.h +++ b/hch/CObjectHandler.h @@ -380,6 +380,7 @@ public: void initHeroDefInfo(); void pushPrimSkill(int which, int val); void UpdateSpeciality(); + void updateSkill(int which, int val, bool abs); CGHeroInstance(); virtual ~CGHeroInstance(); diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 0a3df2712..9db49ce35 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -2623,56 +2623,17 @@ std::pair BattleInfo::calculateDmgRange( const CStack* attacker, con { if(shooting) { - switch(attackerHero->getSecSkillLevel(1)) //archery - { - case 1: //basic - additiveBonus += 0.1f; - break; - case 2: //advanced - additiveBonus += 0.25f; - break; - case 3: //expert - additiveBonus += 0.5f; - break; - } - - if(attackerHero->getSecSkillLevel(1) > 0) //non-none level - { - //apply artifact premy to archery - additiveBonus += attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 1) / 100.0f; - } + additiveBonus += attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 1) / 100.0f; } else { - switch(attackerHero->getSecSkillLevel(22)) //offense - { - case 1: //basic - additiveBonus += 0.1f; - break; - case 2: //advanced - additiveBonus += 0.2f; - break; - case 3: //expert - additiveBonus += 0.3f; - break; - } + additiveBonus += attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 22) / 100.0f; } } if(defendingHero) { - switch(defendingHero->getSecSkillLevel(23)) //armorer - { - case 1: //basic - multBonus *= 0.95f; - break; - case 2: //advanced - multBonus *= 0.9f; - break; - case 3: //expert - multBonus *= 0.85f; - break; - } + multBonus *= (std::max(0, 100-attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 23))) / 100.0f; } //handling hate effect diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 4a4c5a218..be6501523 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -83,7 +83,7 @@ DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs ) } else { - for(unsigned i=0;isecSkills.size();i++) + for (unsigned i=0; isecSkills.size(); i++) { if(hero->secSkills[i].first == which) { @@ -100,6 +100,7 @@ DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs ) } } } + hero->updateSkill(which, val, abs); } DLL_EXPORT void HeroVisitCastle::applyGs( CGameState *gs ) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 58f95b100..a7565afe7 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -3685,7 +3685,6 @@ bool CGameHandler::makeBattleAction( BattleAction &ba ) } case 12: //healing { - static const int healingPerLevel[] = {50, 50, 75, 100}; sendAndApply(&StartAction(ba)); const CGHeroInstance * attackingHero = gs->curB->heroes[ba.side]; CStack *healer = gs->curB->getStack(ba.stackNumber), @@ -3696,7 +3695,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba ) complain("There is either no healer, no destination, or healer cannot heal :P"); } int maxHealable = destStack->MaxHealth() - destStack->firstHPleft; - int maxiumHeal = healingPerLevel[ attackingHero->getSecSkillLevel(27) ]; + int maxiumHeal = std::max(10, attackingHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 27)); int healed = std::min(maxHealable, maxiumHeal); @@ -3932,19 +3931,8 @@ static std::vector calculateResistedStacks(const CSpell * sp, const CGHero { //bonusHero's resistance support (secondary skils and artifacts) prob += bonusHero->valOfBonuses(Bonus::MAGIC_RESISTANCE); - - switch(bonusHero->getSecSkillLevel(26)) //resistance - { - case 1: //basic - prob += 5; - break; - case 2: //advanced - prob += 10; - break; - case 3: //expert - prob += 20; - break; - } + //resistance skill + prob += bonusHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 26) / 100.0f; } if(prob > 100) prob = 100;