소스 검색

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

DjWarmonger 15 년 전
부모
커밋
49beed4e42
6개의 변경된 파일78개의 추가작업 그리고 102개의 파일을 삭제
  1. 9 9
      hch/CArtHandler.cpp
  2. 60 35
      hch/CObjectHandler.cpp
  3. 1 0
      hch/CObjectHandler.h
  4. 3 42
      lib/CGameState.cpp
  5. 2 1
      lib/NetPacksLib.cpp
  6. 3 15
      server/CGameHandler.cpp

+ 9 - 9
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

+ 60 - 35
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<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

+ 1 - 0
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();

+ 3 - 42
lib/CGameState.cpp

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

+ 2 - 1
lib/NetPacksLib.cpp

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

+ 3 - 15
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<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;