Procházet zdrojové kódy

- Hopefully fixed #1103
- Fixed #1137

DjWarmonger před 13 roky
rodič
revize
a7cea94247

+ 5 - 3
AI/VCAI/VCAI.cpp

@@ -376,9 +376,11 @@ ui64 evaluateDanger(crint3 tile, const CGHeroInstance *visitor)
 		}
 	}
 
-	int3 guardPos = cb->guardingCreaturePosition(tile);
-	if(guardPos.x >= 0 && guardPos != tile)
-		guardDanger = evaluateDanger(guardPos, visitor);
+	auto guards = cb->getGuardingCreatures(tile);
+	BOOST_FOREACH (auto cre, guards)
+	{
+		amax (guardDanger, evaluateDanger(cre) * fh->getTacticalAdvantage(visitor, dynamic_cast<const CArmedInstance*>(cre))); //we are interested in strongest monster around
+	}
 
 	//TODO mozna odwiedzic blockvis nie ruszajac straznika
 	return std::max(objectDanger, guardDanger);

+ 3 - 3
lib/BattleState.cpp

@@ -720,14 +720,14 @@ std::vector<ui32> BattleInfo::calculateResistedStacks(const CSpell * sp, const C
 	std::vector<ui32> ret;
 	for(auto it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
 	{
-		if(battleIsImmune(caster, sp, mode, (*it)->position) != ESpellCastProblem::OK)
+		if(battleIsImmune(caster, sp, mode, (*it)->position) != ESpellCastProblem::OK) //FIXME: immune stacks should not display resisted animation
 		{
 			ret.push_back((*it)->ID);
 			continue;
 		}
 
-		//non-negative spells on friendly stacks should always succeed, unless immune
-		if(!sp->isNegative() && (*it)->owner == casterSideOwner)
+		//non-negative spells should always succeed, unless immune
+		if(!sp->isNegative())// && (*it)->owner == casterSideOwner)
 			continue;
 
 		/*

+ 48 - 0
lib/CGameState.cpp

@@ -1889,6 +1889,54 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
  * @return int3(-1, -1, -1) if the tile is unguarded, or the position of
  * the monster guarding the tile.
  */
+const std::vector<CGObjectInstance*> CGameState::guardingCreatures (int3 pos) const
+{
+	std::vector<CGObjectInstance*> guards;
+	const int3 originalPos = pos;
+	if (!map->isInTheMap(pos))
+		return guards;
+
+	const TerrainTile &posTile = map->terrain[pos.x][pos.y][pos.z];
+	if (posTile.visitable)
+	{
+		BOOST_FOREACH (CGObjectInstance* obj, posTile.visitableObjects)
+		{
+			if(obj->blockVisit)
+			{
+				if (obj->ID == 54) // Monster
+					guards.push_back(obj);
+			}
+		}
+	}
+	pos -= int3(1, 1, 0); // Start with top left.
+	for (int dx = 0; dx < 3; dx++)
+	{
+		for (int dy = 0; dy < 3; dy++)
+		{
+			if (map->isInTheMap(pos))
+			{
+				TerrainTile &tile = map->terrain[pos.x][pos.y][pos.z];
+                if (tile.visitable && (tile.terType == ETerrainType::WATER) == (posTile.terType == ETerrainType::WATER))
+				{
+					BOOST_FOREACH (CGObjectInstance* obj, tile.visitableObjects)
+					{
+						if (obj->ID == 54  &&  checkForVisitableDir(pos, &map->getTile(originalPos), originalPos)) // Monster being able to attack investigated tile
+						{
+							guards.push_back(obj);
+						}
+					}
+				}
+			}
+
+			pos.y++;
+		}
+		pos.y -= 3;
+		pos.x++;
+	}
+	return guards;
+
+}
+
 int3 CGameState::guardingCreaturePosition (int3 pos) const
 {
 	const int3 originalPos = pos;

+ 1 - 0
lib/CGameState.h

@@ -423,6 +423,7 @@ public:
 	bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
 	void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or NULL if path does not exists
 	int3 guardingCreaturePosition (int3 pos) const;
+	const std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
 	int victoryCheck(ui8 player) const; //checks if given player is winner; -1 if std victory, 1 if special victory, 0 else
 	int lossCheck(ui8 player) const; //checks if given player is loser;  -1 if std loss, 1 if special, 0 else
 	ui8 checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 if no winner

+ 1 - 0
lib/CSpellHandler.cpp

@@ -366,6 +366,7 @@ void CSpellHandler::loadSpells()
 
 		s->counteredSpells = spell["counters"].StdVector<TSpell>();
 	}
+	//spell fixes
 
 	spells.push_back(spells[80]); //clone Acid Breath attributes for Acid Breath damage effect
 	//forgetfulness needs to get targets automatically on expert level

+ 6 - 0
lib/IGameCallback.cpp

@@ -386,6 +386,12 @@ int3 CGameInfoCallback::guardingCreaturePosition (int3 pos) const
 	return gs->guardingCreaturePosition(pos);
 }
 
+const std::vector<CGObjectInstance*> CGameInfoCallback::getGuardingCreatures (int3 pos) const
+{
+	ERROR_RET_VAL_IF(!isVisible(pos), "Tile is not visible!", std::vector<CGObjectInstance*>());
+	return gs->guardingCreatures (pos);
+}
+
 bool CGameInfoCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const
 {
 	const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(hero);

+ 1 - 0
lib/IGameCallback.h

@@ -116,6 +116,7 @@ public:
 
 	//map
 	int3 guardingCreaturePosition (int3 pos) const;
+	const std::vector<CGObjectInstance*> getGuardingCreatures (int3 pos) const;
 	const CMapHeader * getMapHeader()const;
 	int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
 	const TerrainTile * getTile(int3 tile, bool verbose = true) const;