Răsfoiți Sursa

* jousting support

mateuszb 16 ani în urmă
părinte
comite
56fe3b0547
4 a modificat fișierele cu 28 adăugiri și 15 ștergeri
  1. 5 1
      lib/CGameState.cpp
  2. 1 1
      lib/CGameState.h
  3. 20 11
      server/CGameHandler.cpp
  4. 2 2
      server/CGameHandler.h

+ 5 - 1
lib/CGameState.cpp

@@ -1898,7 +1898,7 @@ bool CGameState::checkForVisitableDir(const int3 & src, const int3 & dst) const
 	return true;
 }
 
-int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
+int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge)
 {
 	int attackDefenseBonus,
 		minDmg = attacker->creature->damageMin * attacker->amount, 
@@ -1986,6 +1986,10 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, con
 
 	float dmgBonusMultiplier = 1.0f;
 
+	//applying jousting bonus
+	if( attacker->hasFeatureOfType(StackFeature::JOUSTING) && !defender->hasFeatureOfType(StackFeature::CHARGE_IMMUNITY) )
+		dmgBonusMultiplier += charge * 0.05f;
+
 	//bonus from attack/defense skills
 	if(attackDefenseBonus < 0) //decreasing dmg
 	{

+ 1 - 1
lib/CGameState.h

@@ -136,7 +136,7 @@ struct DLL_EXPORT BattleInfo
 	bool isStackBlocked(int ID); //returns true if there is neighbouring enemy stack
 	static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
 	static std::vector<int> neighbouringTiles(int hex);
-	static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting); //TODO: add additional conditions and require necessary data
+	static int calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge); //charge - number of hexes travelled before attack (for champion's jousting) //TODO: add additional conditions and require necessary data
 	void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
 	std::set<CStack*> getAttackedCreatures(const CSpell * s, const CGHeroInstance * caster, int destinationTile); //calculates stack affected by given spell
 	static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster);

+ 20 - 11
server/CGameHandler.cpp

@@ -451,6 +451,7 @@ askInterfaceForMove:
 	
 	sendAndApply(&resultsApplied);
 }
+
 void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
 {	
 	bsa.killedAmount = bsa.damageAmount / def->MaxHealth();
@@ -478,7 +479,7 @@ void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
 	}
 }
 
-void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
+void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def, int distance)
 {
 	bat.bsa.clear();
 	bat.stackAttacking = att->ID;
@@ -490,7 +491,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
 	#endif
 
 	bsa->stackAttacked = def->ID;
-	bsa->damageAmount = BattleInfo::calculateDmg(att, def, gs->getHero(att->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), gs->getHero(def->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), bat.shot());//counting dealt damage
+	bsa->damageAmount = BattleInfo::calculateDmg(att, def, gs->getHero(att->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), gs->getHero(def->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), bat.shot(), distance);//counting dealt damage
 	if(att->Luck() > 0  &&  rand()%24 < att->Luck())
 	{
 		bsa->damageAmount *= 2;
@@ -546,8 +547,11 @@ handleConEnd:
 #undef SPELL_CAST_TEMPLATE_1
 #undef SPELL_CAST_TEMPLATE_2
 }
-void CGameHandler::moveStack(int stack, int dest)
-{							
+
+int CGameHandler::moveStack(int stack, int dest)
+{
+	int ret = 0;
+
 	CStack *curStack = gs->curB->getStack(stack),
 		*stackAtEnd = gs->curB->getStackT(dest);
 
@@ -579,7 +583,7 @@ void CGameHandler::moveStack(int stack, int dest)
 	}
 
 	if((stackAtEnd && stackAtEnd!=curStack && stackAtEnd->alive()) || !accessibility[dest])
-		return;
+		return 0;
 
 	bool accessibilityWithOccupyable[BFIELD_SIZE];
 	std::vector<int> accOc = gs->curB->getAccessibility(curStack->ID, true);
@@ -596,6 +600,9 @@ void CGameHandler::moveStack(int stack, int dest)
 	//	return false;
 
 	std::pair< std::vector<int>, int > path = gs->curB->getPath(curStack->position, dest, accessibilityWithOccupyable, curStack->hasFeatureOfType(StackFeature::FLYING), curStack->hasFeatureOfType(StackFeature::DOUBLE_WIDE), curStack->attackerOwned);
+
+	ret = path.second;
+
 	if(curStack->hasFeatureOfType(StackFeature::FLYING))
 	{
 		if(path.second <= curStack->Speed() && path.first.size() > 0)
@@ -623,6 +630,8 @@ void CGameHandler::moveStack(int stack, int dest)
 			sendAndApply(&sm);
 		}
 	}
+
+	return ret;
 }
 CGameHandler::CGameHandler(void)
 {
@@ -2323,7 +2332,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 	case 6: //walk or attack
 		{
 			sendAndApply(&StartAction(ba)); //start movement and attack
-			moveStack(ba.stackNumber,ba.destinationTile);
+			int distance = moveStack(ba.stackNumber, ba.destinationTile);
 			CStack *curStack = gs->curB->getStack(ba.stackNumber),
 				*stackAtEnd = gs->curB->getStackT(ba.additionalInfo);
 
@@ -2380,7 +2389,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 
 			//attack
 			BattleAttack bat;
-			prepareAttack(bat,curStack,stackAtEnd);
+			prepareAttack(bat, curStack, stackAtEnd, distance);
 			sendAndApply(&bat);
 
 			//counterattack
@@ -2390,7 +2399,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				&& !stackAtEnd->hasFeatureOfType(StackFeature::SIEGE_WEAPON)
 				&& !stackAtEnd->hasFeatureOfType(StackFeature::HYPNOTIZED))
 			{
-				prepareAttack(bat,stackAtEnd,curStack);
+				prepareAttack(bat, stackAtEnd, curStack, 0);
 				bat.flags |= 2;
 				sendAndApply(&bat);
 			}
@@ -2402,7 +2411,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				&& stackAtEnd->alive()  )
 			{
 				bat.flags = 0;
-				prepareAttack(bat,curStack,stackAtEnd);
+				prepareAttack(bat, curStack, stackAtEnd, 0);
 				sendAndApply(&bat);
 			}
 			sendAndApply(&EndAction());
@@ -2430,7 +2439,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 			sendAndApply(&StartAction(ba)); //start shooting
 
 			BattleAttack bat;
-			prepareAttack(bat,curStack,destStack);
+			prepareAttack(bat, curStack, destStack, 0);
 			bat.flags |= 1;
 			sendAndApply(&bat);
 
@@ -2440,7 +2449,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				&& curStack->shots
 				)
 			{
-				prepareAttack(bat,curStack,destStack);
+				prepareAttack(bat, curStack, destStack, 0);
 				sendAndApply(&bat);
 			}
 

+ 2 - 2
server/CGameHandler.h

@@ -83,9 +83,9 @@ public:
 
 	bool isAllowedExchange(int id1, int id2);
 	void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
-	void moveStack(int stack, int dest);
+	int moveStack(int stack, int dest); //returned value - travelled distance
 	void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
-	void prepareAttack(BattleAttack &bat, CStack *att, CStack *def); //if last parameter is true, attack is by shooting, if false it's a melee attack
+	void prepareAttack(BattleAttack &bat, CStack *att, CStack *def, int distance); //distance - number of hexes travelled before attacking
 	void prepareAttacked(BattleStackAttacked &bsa, CStack *def);
 	void checkForBattleEnd( std::vector<CStack*> &stacks );
 	void setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet &army1, const CCreatureSet &army2, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank, const CGTownInstance *town);