Browse Source

* Added Blind to CCreatureHandler::getMindSpells()
* Fixed Angelic Alliance to the right factions.
* Added functions to determine good/evil status of a unit/faction. Was going to use it for both Evil Fog/Holy Ground and Angelic Alliance, but turned out the latter was a bit special. Could still be useful in the future with additional towns. CCreatureHandler seemed to be the best place for it.

OnionKnight 16 năm trước cách đây
mục cha
commit
a13d7fd595
4 tập tin đã thay đổi với 61 bổ sung24 xóa
  1. 45 0
      hch/CCreatureHandler.cpp
  2. 8 0
      hch/CCreatureHandler.h
  3. 4 4
      hch/CObjectHandler.cpp
  4. 4 20
      server/CGameHandler.cpp

+ 45 - 0
hch/CCreatureHandler.cpp

@@ -31,13 +31,20 @@ static std::vector<int> getMindSpells()
 	ret.push_back(59); //berserk
 	ret.push_back(60); //hypnotize
 	ret.push_back(61); //forgetfulness
+	ret.push_back(62); //blind
 	return ret;
 }
 
 CCreatureHandler::CCreatureHandler()
 {
 	VLC->creh = this;
+
+	// Set the faction alignments to the defaults:
+	// Good: Castle, Rampart, Tower	// Evil: Inferno, Necropolis, Dungeon
+	// Neutral: Stronghold, Fortess, Conflux
+	factionAlignments += 1, 1, 1, -1, -1, -1, 0, 0, 0;
 }
+
 int CCreature::getQuantityID(const int & quantity)
 {
 	if (quantity<5)
@@ -81,6 +88,24 @@ bool CCreature::isUndead() const
 	return vstd::contains(abilities, StackFeature::UNDEAD);
 }
 
+/**
+ * Determines if the creature is of a good alignment.
+ * @return true if the creture is good, false otherwise.
+ */
+bool CCreature::isGood () const
+{
+	return VLC->creh->isGood(faction);
+}
+
+/**
+ * Determines if the creature is of an evil alignment.
+ * @return true if the creature is evil, false otherwise.
+ */
+bool CCreature::isEvil () const
+{
+	return VLC->creh->isEvil(faction);
+}
+
 si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatures can be bought
 {
 	int ret = 2147483645;
@@ -119,6 +144,26 @@ float readFloat(int & befi, int & i, int andame, std::string & buf) //helper fun
 	return ret;
 }
 
+/**
+ * Determines if a faction is good.
+ * @param ID of the faction.
+ * @return true if the faction is good, false otherwise.
+ */
+bool CCreatureHandler::isGood (si8 faction) const
+{
+	return faction != -1 && factionAlignments[faction] == 1;
+}
+
+/**
+ * Determines if a faction is evil.
+ * @param ID of the faction.
+ * @return true if the faction is evil, false otherwise.
+ */
+bool CCreatureHandler::isEvil (si8 faction) const
+{
+	return faction != -1 && factionAlignments[faction] == -1;
+}
+
 void CCreatureHandler::loadCreatures()
 {
 	notUsedMonsters += 122,124,126,128,145,146,147,148,149,160,161,162,163,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191;

+ 8 - 0
hch/CCreatureHandler.h

@@ -63,6 +63,8 @@ public:
 	bool isFlying() const; //returns true if it is a flying unit
 	bool isShooting() const; //returns true if unit can shoot
 	bool isUndead() const; //returns true if unit is undead
+	bool isGood () const;
+	bool isEvil () const;
 	si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought
 	static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion
 
@@ -100,9 +102,15 @@ public:
 	std::map<std::string,int> nameToID;
 	std::map<int,std::string> idToProjectile;
 	std::map<int,bool> idToProjectileSpin; //if true, appropriate projectile is spinning during flight
+	std::vector<bool> factionAlignments; //1 for good, 0 for neutral and -1 for evil with faction ID as index
+
 	void loadCreatures();
 	void loadAnimationInfo();
 	void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
+
+	bool isGood (si8 faction) const;
+	bool isEvil (si8 faction) const;
+
 	CCreatureHandler();
 	~CCreatureHandler();
 

+ 4 - 4
hch/CObjectHandler.cpp

@@ -858,12 +858,12 @@ std::vector<std::pair<int,std::string> > CGHeroInstance::getCurrentMoraleModifie
 		std::set<si8> factions;
 		for(std::map<si32,std::pair<ui32,si32> >::const_iterator i=army.slots.begin(); i!=army.slots.end(); i++)
 		{
-			// Take Angelic Alliance troop-mixing freedom into account.
-			si8 faction = VLC->creh->creatures[i->second.first].faction;
+			// Take Angelic Alliance troop-mixing freedom of non-evil, non-Conflux units into account.
+			const si8 faction = VLC->creh->creatures[i->second.first].faction;
 			if (hasBonusOfType(HeroBonus::NONEVIL_ALIGNMENT_MIX)
-			    && (faction <= 2 || faction == 6 || faction == 8))
+				&& ((faction >= 0 && faction <= 2) || faction == 6 || faction == 7))
 			{
-				factions.insert(0); // Insert any non-evil alignment as arbitrary single faction, in this case Castle.
+				factions.insert(0); // Insert a single faction of the affected group, Castle will do.
 			}
 			else
 			{

+ 4 - 20
server/CGameHandler.cpp

@@ -1107,18 +1107,10 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
 		{
 			for(int g=0; g<stacks.size(); ++g) //+1 morale bonus for good creatures, -1 morale bonus for evil creatures
 			{
-				if(stacks[g]->creature->faction == 0
-					|| stacks[g]->creature->faction == 1
-					|| stacks[g]->creature->faction == 2) 
-				{
+				if (stacks[g]->creature->isGood())
 					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, 1, StackFeature::OTHER_SOURCE));
-				}
-				else if(stacks[g]->creature->faction == 3
-					|| stacks[g]->creature->faction == 4
-					|| stacks[g]->creature->faction == 5)
-				{
+				else if (stacks[g]->creature->isEvil())
 					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, -1, StackFeature::OTHER_SOURCE));
-				}
 			}
 			break;
 		}
@@ -1137,18 +1129,10 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
 		{
 			for(int g=0; g<stacks.size(); ++g) //-1 morale bonus for good creatures, +1 morale bonus for evil creatures
 			{
-				if(stacks[g]->creature->faction == 0
-					|| stacks[g]->creature->faction == 1
-					|| stacks[g]->creature->faction == 2) 
-				{
+				if (stacks[g]->creature->isGood())
 					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, -1, StackFeature::OTHER_SOURCE));
-				}
-				else if(stacks[g]->creature->faction == 3
-					|| stacks[g]->creature->faction == 4
-					|| stacks[g]->creature->faction == 5)
-				{
+				else if (stacks[g]->creature->isEvil())
 					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, 1, StackFeature::OTHER_SOURCE));
-				}
 			}
 			break;
 		}