浏览代码

* Mutare's special ability
* implemented vial of dragon blood

* problems with teams discovered:
maps with noncontinuous player occupancy (e.g. only red and teal) crash on loading. hideTiles has obvious bugs - loop goes through teams and team numbers, but fw.player is set to team number, as is the 4th argument to getTielsInRange.

mateuszb 15 年之前
父节点
当前提交
ec5fa1dc22
共有 9 个文件被更改,包括 77 次插入16 次删除
  1. 13 0
      config/cr_abils.txt
  2. 1 1
      config/settings.txt
  3. 2 2
      config/specials.txt
  4. 6 1
      hch/CArtHandler.cpp
  5. 1 1
      hch/CArtHandler.h
  6. 10 8
      hch/CObjectHandler.cpp
  7. 2 2
      lib/CGameState.cpp
  8. 23 1
      lib/HeroBonus.cpp
  9. 19 0
      lib/HeroBonus.h

+ 13 - 0
config/cr_abils.txt

@@ -25,8 +25,10 @@
 +  25 SPELL_RESISTANCE_AURA 0 55 0 	//war unicorn
 +  26 LEVEL_SPELL_IMMUNITY 3 0 0 	//green dragon's spell immunity
 +  26 TWO_HEX_ATTACK_BREATH 0 0 0  	//green dragon's breath
++  26 DRAGON_NATURE 0 0 0			//green dragon is a dragon
 +  27 LEVEL_SPELL_IMMUNITY 4 0 0 	//gold dragon's spell immunity
 +  27 TWO_HEX_ATTACK_BREATH 0 0 0  	//gold dragon's breath
++  27 DRAGON_NATURE 0 0 0			//gold dragon is a dragon
 +  30 NON_LIVING 0 0 0  	  		//stone gargoyles are non-living
 +  31 NON_LIVING 0 0 0  			//obsidian gargoyles are non-living
 +  32 NON_LIVING 0 0 0  			//stone golems are non-living
@@ -88,8 +90,10 @@
 +  67 DOUBLE_DAMAGE_CHANCE 20 0 0	//vampire lords
 +  67 SPELL_AFTER_ATTACK 0 42 20 	//dread knights
 +  68 ENEMY_MORALE_DECREASING -1 0 0		//bone dragon
++  68 DRAGON_NATURE 0 0 0			//bone dragon is a dragon
 +  69 ENEMY_MORALE_DECREASING -1 0 0 		//ghost dragon
 +  69 SPELL_AFTER_ATTACK 0 75 20   	//ghost dragon
++  69 DRAGON_NATURE 0 0 0			//ghost dragon is a dragon
 +  70 SPELL_IMMUNITY 0 62 0	  	   	//troglodytes are immune to blind
 +  71 SPELL_IMMUNITY 0 62 0		   	//infernal troglodytes are immune to blind
 +  72 RETURN_AFTER_STRIKE 0 0 0	   	//Harpies return after attack
@@ -101,7 +105,9 @@
 +  79 SELF_MORALE 0 0 0			   	//minotaur kings
 +  81 SPELL_AFTER_ATTACK 0 74 20   	//scorpicore
 +  82 LEVEL_SPELL_IMMUNITY 3 0 0   	//red dragon's spell immunity
++  82 DRAGON_NATURE 0 0 0			//red dragon is a dragon
 +  83 LEVEL_SPELL_IMMUNITY 5 0 0   	//black dragon's spell immunity
++  83 DRAGON_NATURE 0 0 0			//black dragon is a dragon
 +  87 ADDITIONAL_ATTACK 1 0 0		//wolf raider
 +  91 SPELLCASTER 2 43 6   	   	   	//ogre magi cast bloodlust
 +  93 SPELL_AFTER_ATTACK 0 77 20   	//thunderbirds
@@ -166,13 +172,20 @@
 + 125 NON_LIVING 0 0 0				//magma elementals shouldn't get morale
 + 127 NON_LIVING 0 0 0				//storm elementals shouldn't get morale
 + 129 NON_LIVING 0 0 0				//energy elementals shouldn't get morale
++ 132 DRAGON_NATURE 0 0 0			//azure dragon is a dragon
 - 133 FLYING						//Crystal Dragons do not fly
++ 133 DRAGON_NATURE 0 0 0			//crystal dragon is a dragon
++ 134 DRAGON_NATURE 0 0 0			//faerie dragon is a dragon
++ 135 DRAGON_NATURE 0 0 0			//rust dragon is a dragon
 + 140 DOUBLE_WIDE 0 0 0 			//boar should be treated as double-wide
 + 142 DOUBLE_WIDE 0 0 0 			//nomads should be treated as double-wide
 + 144 FULL_HP_REGENERATION 0 0 0 			//troll
 + 147 HEALER 0 0 0					//first aid tent can heal
 + 148 NOT_ACTIVE 0 0 0				//Ammo Cart
 + 149 SHOOTER 0 0 0					//arrow turret
++ 151 DRAGON_NATURE 0 0 0			//diamond dragon is a dragon
++ 154 DRAGON_NATURE 0 0 0			//blood dragon is a dragon
++ 155 DRAGON_NATURE 0 0 0			//darkness dragon is a dragon
 -  46 FLYING		  				//hell hound doesn't fly
 -  47 FLYING			  			//cerberus doesn't fly
 - 120 DOUBLE_WIDE					//psychic elemental

+ 1 - 1
config/settings.txt

@@ -4,7 +4,7 @@ clientSettings
 {
 	port=3030;
 	resolution=800x600; // format: WxH
-	bpp=24; // bytes per pixels: 24 or 32
+	bpp=24; // bits per pixels: 16, 24 or 32
 	fullscreen=0; //0 - windowed mode, 1 - fullscreen
 	server=127.0.0.1; //use 127.0.0.1 for localhost
 	localInformation=2; //0 - *all* information sent from server (safest and slowest); 1 - map information sent from server; 2 - all information local-storaged

+ 2 - 2
config/specials.txt

@@ -165,8 +165,8 @@
 150	4	5	1	66
 150	4	5	2	66
 150	4	10	3	66
-151	13	1	1	5
-151	13	1	2	5
+151	13	5	1	0
+151	13	5	2	0
 152	1	0	0	4
 153	13	1	1	5
 153	13	1	1	5

+ 6 - 1
hch/CArtHandler.cpp

@@ -448,10 +448,11 @@ void CArtHandler::getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArti
 		out.push_back(art);
 	}
 }
-void CArtHandler::giveArtBonus( int aid, Bonus::BonusType type, int val, int subtype, int valType )
+void CArtHandler::giveArtBonus( int aid, Bonus::BonusType type, int val, int subtype, int valType, ILimiter * limiter )
 {
 	Bonus added(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
 	added.valType = valType;
+	added.limiter = limiter;
 	if(type == Bonus::MORALE || Bonus::LUCK)
 		added.description = "\n" + artifacts[aid]->Name()  + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
 	artifacts[aid]->bonuses.push_back(added);
@@ -643,6 +644,10 @@ void CArtHandler::addBonuses()
 	giveArtBonus(125,Bonus::ENEMY_CANT_ESCAPE,0); //Shackles of War
 	giveArtBonus(126,Bonus::BLOCK_SPELLS_ABOVE_LEVEL,0);//Orb of Inhibition
 
+	//vial of dragon blood
+	giveArtBonus(127, Bonus::PRIMARY_SKILL, +5, PrimarySkill::ATTACK, Bonus::BASE_NUMBER, new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE));
+	giveArtBonus(127, Bonus::PRIMARY_SKILL, +5, PrimarySkill::DEFENSE, Bonus::BASE_NUMBER, new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE));
+
 	//Armageddon's Blade
 	giveArtBonus(128, Bonus::SPELL, 3, 26, Bonus::INDEPENDENT_MAX);
 	giveArtBonus(128, Bonus::SPELL_IMMUNITY,0, 26);

+ 1 - 1
hch/CArtHandler.h

@@ -54,7 +54,7 @@ public:
 
 class DLL_EXPORT CArtHandler //handles artifacts
 {
-	void giveArtBonus(int aid, Bonus::BonusType type, int val, int subtype = -1, int valType = Bonus::BASE_NUMBER);
+	void giveArtBonus(int aid, Bonus::BonusType type, int val, int subtype = -1, int valType = Bonus::BASE_NUMBER, ILimiter * limiter = NULL);
 public:
 	std::vector<CArtifact*> treasures, minors, majors, relics;
 	std::vector<CArtifact *> artifacts;

+ 10 - 8
hch/CObjectHandler.cpp

@@ -1130,14 +1130,16 @@ void CGHeroInstance::initObj()
 						bonus.subtype = PrimarySkill::DEFENSE;
 						break;
 				}
-				for (std::vector<CCreature*>::iterator i = VLC->creh->creatures.begin(); i != VLC->creh->creatures.end(); i++)
-				{ //TODO: what if creature changes type during the game (Dragon Eye Ring?)
-					if ((*i)->hasBonusOfType(Bonus::DRAGON_NATURE)) //TODO: implement it!
-					{
-						bonus.limiter = new CCreatureTypeLimiter (**i, false);
-						speciality.bonuses.push_back (bonus);
-					}
-				}
+// 				for (std::vector<CCreature*>::iterator i = VLC->creh->creatures.begin(); i != VLC->creh->creatures.end(); i++)
+// 				{ //TODO: what if creature changes type during the game (Dragon Eye Ring?)
+// 					if ((*i)->hasBonusOfType(Bonus::DRAGON_NATURE)) //TODO: implement it!
+// 					{
+// 						bonus.limiter = new CCreatureTypeLimiter (**i, false);
+// 						speciality.bonuses.push_back (bonus);
+// 					}
+// 				}
+				bonus.limiter = new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE);
+				speciality.bonuses.push_back (bonus);
 				break;
 			default:
 				tlog2 << "Unexpected hero speciality " << type <<'\n';

+ 2 - 2
lib/CGameState.cpp

@@ -3255,10 +3255,10 @@ ui32 BattleInfo::calculateSpellDmg( const CSpell * sp, const CGHeroInstance * ca
 	ret = usedSpellPower * dmgMultipliers[sp->id];
 	ret += sp->powers[spellSchoolLevel];
 	
-	//applying sorcerery secondary skill
+	//applying sorcery secondary skill
 	if(caster)
 	{
-		ret *= (100.f + caster->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 25)) / 100.0f; //mysticism
+		ret *= (100.f + caster->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 25)) / 100.0f; //sorcery
 		ret *= (100.f + caster->valOfBonuses(Bonus::SPELL_DAMAGE) + caster->valOfBonuses(Bonus::SPECIFIC_SPELL_DAMAGE, sp->id)) / 100.0f;
 
 		if(sp->air)

+ 23 - 1
lib/HeroBonus.cpp

@@ -498,4 +498,26 @@ CCreatureTypeLimiter::CCreatureTypeLimiter()
 {
 	creature = NULL;
 	includeUpgrades = false;
-}
+}
+
+HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus )
+	: type(bonus), subtype(0), isSubtypeRelevant(false)
+{
+}
+
+HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus, TBonusSubtype _subtype )
+	: type(bonus), subtype(_subtype), isSubtypeRelevant(true)
+{
+}
+
+bool HasAnotherBonusLimiter::limit( const Bonus &b, const CBonusSystemNode &node ) const
+{
+	if(isSubtypeRelevant)
+	{
+		return !node.hasBonusOfType(static_cast<Bonus::BonusType>(type), subtype);
+	}
+	else
+	{
+		return !node.hasBonusOfType(static_cast<Bonus::BonusType>(type));
+	}
+}

+ 19 - 0
lib/HeroBonus.h

@@ -479,6 +479,25 @@ public:
 		h & creature & includeUpgrades;
 	}
 };
+
+class HasAnotherBonusLimiter : public ILimiter //applies only to nodes that have another bonus working
+{
+public:
+	TBonusType type;
+	TBonusSubtype subtype;
+	ui8 isSubtypeRelevant; //check for subtype only if this is true
+
+	HasAnotherBonusLimiter(TBonusType bonus);
+	HasAnotherBonusLimiter(TBonusType bonus, TBonusSubtype _subtype);
+
+	bool limit(const Bonus &b, const CBonusSystemNode &node) const;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & type & subtype & isSubtypeRelevant;
+	}
+};
+
 namespace Selector
 {
 	extern DLL_EXPORT CSelectFieldEqual<TBonusType> type;