1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Support for secondary skill specialities. Lots of changes, may be buggy.

This commit is contained in:
DjWarmonger
2010-07-17 17:02:11 +00:00
parent 91b0340540
commit 49beed4e42
6 changed files with 78 additions and 102 deletions

View File

@@ -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

View File

@@ -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<std::pair<ui8,ui8> >::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<ui32,si32> &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

View File

@@ -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();

View File

@@ -2623,56 +2623,17 @@ std::pair<ui32, ui32> 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

View File

@@ -83,7 +83,7 @@ DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs )
}
else
{
for(unsigned i=0;i<hero->secSkills.size();i++)
for (unsigned i=0; i<hero->secSkills.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 )

View File

@@ -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<ui32> 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;