Przeglądaj źródła

Implement ranged counterattack

dydzio 8 lat temu
rodzic
commit
21f4a0ba60
3 zmienionych plików z 28 dodań i 0 usunięć
  1. 12 0
      config/bonuses_texts.json
  2. 2 0
      lib/HeroBonus.h
  3. 14 0
      server/CGameHandler.cpp

+ 12 - 0
config/bonuses_texts.json

@@ -41,6 +41,12 @@
 		"name": "No retaliation",
 		"description": "Enemy cannot Retaliate"
 	},
+	
+	"BLOCKS_RANGED_RETALIATION":
+	{
+		"name": "No ranged retaliation",
+		"description": "Enemy cannot Retaliate by shooting"
+	},
 
 	"CATAPULT":
 	{
@@ -299,6 +305,12 @@
 		"name": "Random spellcaster",
 		"description": "Can cast random spell"
 	},
+	
+	"RANGED_RETALIATION":
+	{
+		"name": "Ranged retaliation",
+		"description": "Can perform ranged counterattack"
+	},
 
 	"RECEPTIVE":
 	{

+ 2 - 0
lib/HeroBonus.h

@@ -220,6 +220,8 @@ public:
 	BONUS_NAME(TRANSMUTATION) /*val - chance to trigger in %, subtype = 0 - resurrection based on HP, 1 - based on unit count, additional info - target creature ID (attacker default)*/\
 	BONUS_NAME(SUMMON_GUARDIANS) /*val - amount in % of stack count, subtype = creature ID*/\
 	BONUS_NAME(CATAPULT_EXTRA_SHOTS) /*val - number of additional shots, requires CATAPULT bonus to work*/\
+	BONUS_NAME(RANGED_RETALIATION) /*allows shooters to perform ranged retaliation*/\
+	BONUS_NAME(BLOCKS_RANGED_RETALIATION) /*disallows ranged retaliation for shooter unit, BLOCKS_RETALIATION bonus is for melee retaliation only*/\
 	/* end of list */
 
 

+ 14 - 0
server/CGameHandler.cpp

@@ -3993,6 +3993,20 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
 				handleAfterAttackCasting(bat);
 			}
 
+			//ranged counterattack
+			if (destinationStack
+				&& destinationStack->hasBonusOfType(Bonus::RANGED_RETALIATION)
+				&& !stack->hasBonusOfType(Bonus::BLOCKS_RANGED_RETALIATION)
+				&& destinationStack->ableToRetaliate()
+				&& stack->alive()) //attacker may have died (fire shield)
+			{
+				BattleAttack bat;
+				prepareAttack(bat, destinationStack, stack, 0, stack->position);
+				bat.flags |= BattleAttack::COUNTER | BattleAttack::SHOT;
+				sendAndApply(&bat);
+				handleAfterAttackCasting(bat);
+			}
+
 			//second shot for ballista, only if hero has advanced artillery
 
 			const CGHeroInstance * attackingHero = gs->curB->battleGetFightingHero(ba.side);