mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Nullkiller: various fixes for town portal and other
This commit is contained in:
		
				
					committed by
					
						 Andrii Danylchenko
						Andrii Danylchenko
					
				
			
			
				
	
			
			
			
						parent
						
							1a69a43f09
						
					
				
				
					commit
					e95ccda5de
				
			| @@ -258,6 +258,29 @@ bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater) | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool isObjectPassable(const CGObjectInstance * obj) | ||||
| { | ||||
| 	return isObjectPassable(obj, ai->playerID, cb->getPlayerRelations(obj->tempOwner, ai->playerID)); | ||||
| } | ||||
|  | ||||
| // Pathfinder internal helper | ||||
| bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations::PlayerRelations objectRelations) | ||||
| { | ||||
| 	if((obj->ID == Obj::GARRISON || obj->ID == Obj::GARRISON2) | ||||
| 		&& objectRelations != PlayerRelations::ENEMIES) | ||||
| 		return true; | ||||
|  | ||||
| 	if(obj->ID == Obj::BORDER_GATE) | ||||
| 	{ | ||||
| 		auto quest = dynamic_cast<const CGKeys *>(obj); | ||||
|  | ||||
| 		if(quest->passableFor(playerColor)) | ||||
| 			return true; | ||||
| 	} | ||||
|  | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool isBlockedBorderGate(int3 tileToHit) //TODO: is that function needed? should be handled by pathfinder | ||||
| { | ||||
| 	if(cb->getTile(tileToHit)->topVisitableId() != Obj::BORDER_GATE) | ||||
|   | ||||
| @@ -167,7 +167,9 @@ void foreach_neighbour(const int3 & pos, std::function<void(const int3 & pos)> f | ||||
| void foreach_neighbour(CCallback * cbp, const int3 & pos, std::function<void(CCallback * cbp, const int3 & pos)> foo); // avoid costly retrieval of thread-specific pointer | ||||
|  | ||||
| bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater); | ||||
| bool isBlockedBorderGate(int3 tileToHit); | ||||
| //bool isBlockedBorderGate(int3 tileToHit); | ||||
| bool isObjectPassable(const CGObjectInstance * obj); | ||||
| bool isObjectPassable(const CGObjectInstance * obj, PlayerColor playerColor, PlayerRelations::PlayerRelations objectRelations); | ||||
| bool isBlockVisitObj(const int3 & pos); | ||||
|  | ||||
| bool isWeeklyRevisitable(const CGObjectInstance * obj); | ||||
|   | ||||
| @@ -113,7 +113,8 @@ const CGObjectInstance * ObjectClusterizer::getBlocker(const AIPath & path) cons | ||||
| 			|| blocker->ID == Obj::QUEST_GUARD | ||||
| 			|| blocker->ID == Obj::BORDER_GATE) | ||||
| 		{ | ||||
| 			return blocker; | ||||
| 			if(!isObjectPassable(blocker)) | ||||
| 				return blocker; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -82,7 +82,7 @@ Goals::TGoalVec ClusterBehavior::decomposeCluster(std::shared_ptr<ObjectCluster> | ||||
| 		{ | ||||
| 			blockerPaths.back().nodes.insert(blockerPaths.back().nodes.begin(), *node); | ||||
|  | ||||
| 			if(node->coord == blockerPos) | ||||
| 			if(node->coord == blockerPos || cb->getGuardingCreaturePosition(node->coord) == blockerPos) | ||||
| 				break; | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,9 @@ | ||||
| #include "../../../lib/PathfinderUtil.h" | ||||
| #include "../../../lib/CPlayerState.h" | ||||
|  | ||||
| /// 1-3 - position on map, 4 - layer (air, water, land), 5 - chain (normal, battle, spellcast and combinations) | ||||
| boost::multi_array<AIPathNode, 5> nodes; | ||||
|  | ||||
| AINodeStorage::AINodeStorage(const int3 & Sizes) | ||||
| 	: sizes(Sizes) | ||||
| { | ||||
| @@ -827,6 +830,14 @@ void AINodeStorage::calculateTownPortalTeleportations(std::vector<CGPathNode *> | ||||
| 		actorsOfInitial.insert(aiNode->actor->baseActor); | ||||
| 	} | ||||
|  | ||||
| 	std::map<const CGHeroInstance *, int> maskMap; | ||||
|  | ||||
| 	for(std::shared_ptr<ChainActor> basicActor : actors) | ||||
| 	{ | ||||
| 		if(basicActor->hero) | ||||
| 			maskMap[basicActor->hero] = basicActor->chainMask; | ||||
| 	} | ||||
|  | ||||
| 	for(const ChainActor * actor : actorsOfInitial) | ||||
| 	{ | ||||
| 		if(!actor->hero) | ||||
| @@ -851,8 +862,15 @@ void AINodeStorage::calculateTownPortalTeleportations(std::vector<CGPathNode *> | ||||
| 			for(const CGTownInstance * targetTown : towns) | ||||
| 			{ | ||||
| 				// TODO: allow to hide visiting hero in garrison | ||||
| 				if(targetTown->visitingHero && targetTown->visitingHero != actor->hero) | ||||
| 					continue; | ||||
| 				if(targetTown->visitingHero) | ||||
| 				{ | ||||
| 					auto basicMask = maskMap[targetTown->visitingHero.get()]; | ||||
| 					bool heroIsInChain = (actor->chainMask & basicMask) != 0; | ||||
| 					bool sameActorInTown = actor->chainMask == basicMask; | ||||
|  | ||||
| 					if(sameActorInTown || !heroIsInChain) | ||||
| 						continue; | ||||
| 				} | ||||
|  | ||||
| 				auto nodeOptional = townPortalFinder.createTownPortalNode(targetTown); | ||||
|  | ||||
|   | ||||
| @@ -106,8 +106,6 @@ class AINodeStorage : public INodeStorage | ||||
| private: | ||||
| 	int3 sizes; | ||||
|  | ||||
| 	/// 1-3 - position on map, 4 - layer (air, water, land), 5 - chain (normal, battle, spellcast and combinations) | ||||
| 	boost::multi_array<AIPathNode, 5> nodes; | ||||
| 	const CPlayerSpecificInfoCallback * cb; | ||||
| 	const VCAI * ai; | ||||
| 	std::unique_ptr<FuzzyHelper> dangerEvaluator; | ||||
|   | ||||
| @@ -37,7 +37,7 @@ namespace AIPathfinding | ||||
| 			AIPathNode * dstMode, | ||||
| 			const AIPathNode * srcNode) const override; | ||||
|  | ||||
| 		virtual bool canAct(const AIPathNode * source) const; | ||||
| 		virtual bool canAct(const AIPathNode * source) const override; | ||||
|  | ||||
| 		virtual const ChainActor * getActor(const ChainActor * sourceActor) const override; | ||||
|  | ||||
|   | ||||
| @@ -26,20 +26,12 @@ namespace AIPathfinding | ||||
| 		if(source.node->action == CGPathNode::ENodeAction::BLOCKING_VISIT  | ||||
| 			|| source.node->action == CGPathNode::ENodeAction::VISIT) | ||||
| 		{ | ||||
| 			if(source.nodeObject) | ||||
| 			if(source.nodeObject | ||||
| 				&& isObjectPassable(source.nodeObject, pathfinderHelper->hero->tempOwner, source.objectRelations)) | ||||
| 			{ | ||||
| 				if((source.nodeObject->ID == Obj::GARRISON || source.nodeObject->ID == Obj::GARRISON2) | ||||
| 					&& source.heroRelations != PlayerRelations::ENEMIES) | ||||
| 					return; | ||||
|  | ||||
| 				if(source.nodeObject->ID == Obj::BORDER_GATE) | ||||
| 				{ | ||||
| 					auto quest = dynamic_cast<const CGBorderGate *>(source.nodeObject); | ||||
|  | ||||
| 					if(quest->wasMyColorVisited(pathfinderHelper->hero->tempOwner)) | ||||
| 						return; | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
|  | ||||
| 			// we can not directly bypass objects, we need to interact with them first | ||||
| 			destination.node->theNodeBefore = source.node; | ||||
|  | ||||
|   | ||||
| @@ -30,7 +30,7 @@ extern FuzzyHelper * fh; | ||||
|  | ||||
| class CGVisitableOPW; | ||||
|  | ||||
| const float SAFE_ATTACK_CONSTANT = 1.5; | ||||
| const float SAFE_ATTACK_CONSTANT = 1.2; | ||||
|  | ||||
| //one thread may be turn of AI and another will be handling a side effect for AI2 | ||||
| boost::thread_specific_ptr<CCallback> cb; | ||||
| @@ -758,13 +758,12 @@ void VCAI::makeTurn() | ||||
| 	boost::shared_lock<boost::shared_mutex> gsLock(CGameState::mutex); | ||||
| 	setThreadName("VCAI::makeTurn"); | ||||
|  | ||||
| 	switch(cb->getDate(Date::DAY_OF_WEEK)) | ||||
| 	{ | ||||
| 	case 1: | ||||
| 	if(cb->getDate(Date::DAY_OF_WEEK) == 1) | ||||
| 	{ | ||||
| 		townVisitsThisWeek.clear(); | ||||
| 		std::vector<const CGObjectInstance *> objs; | ||||
| 		retrieveVisitableObjs(objs, true); | ||||
|  | ||||
| 		for(const CGObjectInstance * obj : objs) | ||||
| 		{ | ||||
| 			if(isWeeklyRevisitable(obj)) | ||||
| @@ -773,15 +772,15 @@ void VCAI::makeTurn() | ||||
| 				vstd::erase_if_present(alreadyVisited, obj); | ||||
| 			} | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| 	} | ||||
|  | ||||
| 	markHeroAbleToExplore(primaryHero()); | ||||
| 	visitedHeroes.clear(); | ||||
|  | ||||
| 	if(cb->getDate(Date::DAY) == 1) | ||||
| 	{ | ||||
| 		retrieveVisitableObjs(); | ||||
| 		cb->sendMessage("vcmieagles"); | ||||
| 	} | ||||
|  | ||||
| 	try | ||||
|   | ||||
		Reference in New Issue
	
	Block a user