Переглянути джерело

More mechanics for creature spells.

DjWarmonger 14 роки тому
батько
коміт
8c2dd9fdce
4 змінених файлів з 59 додано та 19 видалено
  1. 1 7
      client/CBattleInterface.cpp
  2. 30 8
      config/creatures.json
  3. 26 3
      lib/BattleState.cpp
  4. 2 1
      lib/BattleState.h

+ 1 - 7
client/CBattleInterface.cpp

@@ -3511,13 +3511,7 @@ void CBattleInterface::activateStack()
 	{
 		stackCanCastSpell = true;
 
-		TBonusListPtr bl = s->getBonuses(Selector::type(Bonus::SPELLCASTER));
-		BOOST_FOREACH(Bonus * b, *bl)
-		{
-			stackSpells.push_back(CGI->spellh->spells[b->subtype]);
-		}
-		if (stackSpells.size())
-			creatureSpellToCast = stackSpells[111 % stackSpells.size()]; //TODO: randomize? weighted chance?
+
 	}
 	else
 		stackCanCastSpell = false;

+ 30 - 8
config/creatures.json

@@ -396,7 +396,7 @@
 				"level": 5,
 				"name": [ "Caliph" ],
 				"faction": 2,
-				"ability_add": [ [ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],		//spells last 6 turns
+				"ability_add": [ [ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],		//spells last 6 turns
 							   	 [ "RANDOM_SPELLCASTER", 0, 0, 0 ],  		//master genies cast spells
 								 [ "CASTS", 3, 0, 0],
 								 [ "HATE", 50, 53, 0 ],
@@ -1291,8 +1291,11 @@
 				"level": 3,
 				"name": [ "IceElemental" ],
 				"faction": 8,
-				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],				//storm elementals shouldn't get morale
-							   	 [ "DOUBLE_WIDE", 0, 0, 0 ] ], 			//ice elemental should be treated as double-wide	//magma elementals shouldn't get morale
+				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],				
+							   	 [ "DOUBLE_WIDE", 0, 0, 0 ],					//ice elemental should be treated as double-wide
+								 [ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
+								 [ "CASTS", 3, 0, 0 ],
+								 [ "SPELLCASTER", 2, 32, 0 ]], 				
 				"defname": "CICEE.DEF",
 				"projectile_defname": "PICEE.DEF",
 				"projectile_spin": false
@@ -1303,7 +1306,10 @@
 				"level": 5,
 				"name": [ "StoneElemental" ],
 				"faction": 8,
-				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ],				//energy elementals shouldn't get morale
+				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],						//magma elementals shouldn't get morale
+								[ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
+								[ "CASTS", 3, 0, 0 ],
+								[ "SPELLCASTER", 2, 33, 0 ]],
 				"defname": "CSTONE.DEF"
 			},
 
@@ -1312,7 +1318,10 @@
 				"level": 2,
 				"name": [ "StormElemental" ],
 				"faction": 8,
-				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ],
+				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],						//storm elementals shouldn't get morale
+								[ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
+								[ "CASTS", 3, 0, 0 ],
+								[ "SPELLCASTER", 2, 30, 0 ]],				
 				"defname": "CSTORM.DEF",
 				"projectile_defname": "CPRGTIX.DEF",
 				"projectile_spin": false,
@@ -1323,8 +1332,11 @@
 				"id": 129,
 				"level": 4,
 				"name": [ "ElectricityElemental" ],
-				"faction": 8,
-				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ],						//Crystal Dragons do not fly
+				"faction": 8,									
+				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ,					//energy elementals shouldn't get morale //Crystal Dragons do not fly
+								[ "CREATURE_ENCHANT_POWER", 5, 0, 0 ],
+								[ "CASTS", 3, 0, 0 ],
+								[ "SPELLCASTER", 2, 31, 0 ]],						
 				"defname": "CNRG.DEF"
 			},
 
@@ -1371,7 +1383,17 @@
 				"level": 8,
 				"name": [ "FairieDragon" ],
 				"faction": -1,
-				"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ] ],			//faerie dragon is a dragon
+				"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ],			//faerie dragon is a dragon
+								[ "CASTS", 5, 0, 0 ],
+								[ "CREATURE_SPELL_POWER", 500, 0, 0], 	//5 spell power per dragon
+								[ "SPELLCASTER", 2, 15, 10 ],			//magic arrow
+								[ "SPELLCASTER", 2, 16, 22 ],			//ice bolt
+								[ "SPELLCASTER", 2, 17, 22 ],			//thunderbolt
+								[ "SPELLCASTER", 2, 19, 5 ],			//chain lightning
+								[ "SPELLCASTER", 2, 20, 10 ],			//frost ring
+								[ "SPELLCASTER", 2, 21, 21 ],			//fireball
+								[ "SPELLCASTER", 2, 22, 5 ],			//inferno
+								[ "SPELLCASTER", 2, 23, 5 ]],			//meteor shower
 				"defname": "CFDRGN.DEF"
 			},
 

+ 26 - 3
lib/BattleState.cpp

@@ -1909,7 +1909,7 @@ SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpell( int player,
 	return SpellCasting::OK;
 }
 
-SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpellHere( int player, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest )
+SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpellHere( int player, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest ) const
 {
 	SpellCasting::ESpellCastProblem moreGeneralProblem = battleCanCastThisSpell(player, spell, mode);
 	if(moreGeneralProblem != SpellCasting::OK)
@@ -1924,11 +1924,14 @@ SpellCasting::ESpellCastProblem BattleInfo::battleCanCastThisSpellHere( int play
 TSpell BattleInfo::getRandomBeneficialSpell(const CStack * subject) const
 {
 	std::vector<TSpell> possibleSpells;
+	CSpell * spell;
 	for (int i = 0; i < SPELLS_QUANTITY; ++i) //should not use future spells added by mods
 	{
-		if (VLC->spellh->spells[i]->positiveness == 1) //only positive
+		spell = VLC->spellh->spells[i];
+		if (spell->positiveness == 1) //only positive
 		{
-			if (subject->hasBonusFrom(Bonus::SPELL_EFFECT, i))
+			if (subject->hasBonusFrom(Bonus::SPELL_EFFECT, i) ||
+				!battleCanCastThisSpellHere(subject->owner, spell, SpellCasting::CREATURE_ACTIVE_CASTING, subject->position))
 				continue;
 			switch (i)
 			{
@@ -2013,6 +2016,26 @@ TSpell BattleInfo::getRandomBeneficialSpell(const CStack * subject) const
 	else
 		return -1;
 }
+TSpell BattleInfo::getRandomCastedSpell(const CStack * caster) const
+{
+	int totalWeight = 0;
+	TBonusListPtr bl = caster->getBonuses(Selector::type(Bonus::SPELLCASTER));
+	BOOST_FOREACH(Bonus * b, *bl)
+	{
+		totalWeight += std::max(b->additionalInfo, 1); //minimal chance to cast is 1
+	}
+	int randomPos = ran() % totalWeight;
+	BOOST_FOREACH(Bonus * b, *bl)
+	{
+		randomPos -= b->additionalInfo;
+		if(randomPos < 0)
+		{
+			return b->subtype;
+		}
+	}
+
+	return -1;
+}
 
 const CGHeroInstance * BattleInfo::getHero( int player ) const
 {

+ 2 - 1
lib/BattleState.h

@@ -125,9 +125,10 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
 	SpellCasting::ESpellCastProblem battleCanCastSpell(int player, SpellCasting::ECastingMode mode) const; //returns true if there are no general issues preventing from casting a spell
 	SpellCasting::ESpellCastProblem battleCanCastThisSpell(int player, const CSpell * spell, SpellCasting::ECastingMode mode) const; //checks if given player can cast given spell
 	SpellCasting::ESpellCastProblem battleIsImmune(const CGHeroInstance * caster, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest) const; //checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into acount general problems such as not having spellbook or mana points etc.
-	SpellCasting::ESpellCastProblem battleCanCastThisSpellHere(int player, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest); //checks if given player can cast given spell at given tile in given mode
+	SpellCasting::ESpellCastProblem battleCanCastThisSpellHere(int player, const CSpell * spell, SpellCasting::ECastingMode mode, THex dest) const; //checks if given player can cast given spell at given tile in given mode
 	bool battleTestElementalImmunity(const CStack * subject, const CSpell * spell, Bonus::BonusType element, bool damageSpell) const;
 	TSpell getRandomBeneficialSpell(const CStack * subject) const;
+	TSpell getRandomCastedSpell(const CStack * caster) const; //called at the beginning of turn for Faerie Dragon
 
 	std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHeroInstance * caster, const CGHeroInstance * hero2, const std::set<CStack*> affectedCreatures, int casterSideOwner, SpellCasting::ECastingMode mode) const;