mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Allow sending requests to move across multiple tiles at once
This commit is contained in:
		| @@ -1216,7 +1216,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h) | ||||
| 	{ | ||||
| 		//FIXME: this assertion fails also if AI moves onto defeated guarded object | ||||
| 		//assert(cb->getVisitableObjs(dst).size() > 1); //there's no point in revisiting tile where there is no visitable object | ||||
| 		cb->moveHero(*h, h->convertFromVisitablePos(dst)); | ||||
| 		cb->moveHero(*h, h->convertFromVisitablePos(dst), false); | ||||
| 		afterMovementCheck(); // TODO: is it feasible to hero get killed there if game work properly? | ||||
| 		// If revisiting, teleport probing is never done, and so the entries into the list would remain unused and uncleared | ||||
| 		teleportChannelProbingList.clear(); | ||||
| @@ -1278,7 +1278,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h) | ||||
| 			destinationTeleport = exitId; | ||||
| 			if(exitPos.valid()) | ||||
| 				destinationTeleportPos = h->convertFromVisitablePos(exitPos); | ||||
| 			cb->moveHero(*h, h->pos); | ||||
| 			cb->moveHero(*h, h->pos, false); | ||||
| 			destinationTeleport = ObjectInstanceID(); | ||||
| 			destinationTeleportPos = int3(-1); | ||||
| 			afterMovementCheck(); | ||||
|   | ||||
| @@ -1837,7 +1837,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h) | ||||
| 	{ | ||||
| 		//FIXME: this assertion fails also if AI moves onto defeated guarded object | ||||
| 		assert(cb->getVisitableObjs(dst).size() > 1); //there's no point in revisiting tile where there is no visitable object | ||||
| 		cb->moveHero(*h, h->convertFromVisitablePos(dst)); | ||||
| 		cb->moveHero(*h, h->convertFromVisitablePos(dst), false); | ||||
| 		afterMovementCheck(); // TODO: is it feasible to hero get killed there if game work properly? | ||||
| 		// If revisiting, teleport probing is never done, and so the entries into the list would remain unused and uncleared | ||||
| 		teleportChannelProbingList.clear(); | ||||
| @@ -1899,7 +1899,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h) | ||||
| 			destinationTeleport = exitId; | ||||
| 			if(exitPos.valid()) | ||||
| 				destinationTeleportPos = h->convertFromVisitablePos(exitPos); | ||||
| 			cb->moveHero(*h, h->pos); | ||||
| 			cb->moveHero(*h, h->pos, false); | ||||
| 			destinationTeleport = ObjectInstanceID(); | ||||
| 			destinationTeleportPos = int3(-1); | ||||
| 			afterMovementCheck(); | ||||
|   | ||||
| @@ -34,11 +34,16 @@ bool CCallback::teleportHero(const CGHeroInstance *who, const CGTownInstance *wh | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool CCallback::moveHero(const CGHeroInstance *h, int3 dst, bool transit) | ||||
| void CCallback::moveHero(const CGHeroInstance *h, const int3 & destination, bool transit) | ||||
| { | ||||
| 	MoveHero pack(dst,h->id,transit); | ||||
| 	MoveHero pack({destination}, h->id, transit); | ||||
| 	sendRequest(&pack); | ||||
| } | ||||
|  | ||||
| void CCallback::moveHero(const CGHeroInstance *h, const std::vector<int3> & path, bool transit) | ||||
| { | ||||
| 	MoveHero pack(path, h->id, transit); | ||||
| 	sendRequest(&pack); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| int CCallback::selectionMade(int selection, QueryID queryID) | ||||
|   | ||||
| @@ -67,7 +67,8 @@ class IGameActionCallback | ||||
| { | ||||
| public: | ||||
| 	//hero | ||||
| 	virtual bool moveHero(const CGHeroInstance *h, int3 dst, bool transit) =0; //dst must be free, neighbouring tile (this function can move hero only by one tile) | ||||
| 	virtual void moveHero(const CGHeroInstance *h, const std::vector<int3> & path, bool transit) =0; //moves hero alongside provided path | ||||
| 	virtual void moveHero(const CGHeroInstance *h, const int3 & destination, bool transit) =0; //moves hero alongside provided path | ||||
| 	virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses given hero; true - successfuly, false - not successfuly | ||||
| 	virtual void dig(const CGObjectInstance *hero)=0; | ||||
| 	virtual void castSpell(const CGHeroInstance *hero, SpellID spellID, const int3 &pos = int3(-1, -1, -1))=0; //cast adventure map spell | ||||
| @@ -159,7 +160,8 @@ public: | ||||
| 	void unregisterBattleInterface(std::shared_ptr<IBattleEventsReceiver> battleEvents); | ||||
|  | ||||
| //commands | ||||
| 	bool moveHero(const CGHeroInstance *h, int3 dst, bool transit = false) override; //dst must be free, neighbouring tile (this function can move hero only by one tile) | ||||
| 	void moveHero(const CGHeroInstance *h, const std::vector<int3> & path, bool transit) override; | ||||
| 	void moveHero(const CGHeroInstance *h, const int3 & destination, bool transit) override; | ||||
| 	bool teleportHero(const CGHeroInstance *who, const CGTownInstance *where); | ||||
| 	int selectionMade(int selection, QueryID queryID) override; | ||||
| 	int sendQueryReply(std::optional<int32_t> reply, QueryID queryID) override; | ||||
|   | ||||
| @@ -355,22 +355,38 @@ void HeroMovementController::requestMovementStart(const CGHeroInstance * h, cons | ||||
|  | ||||
| void HeroMovementController::moveInstant(const CGHeroInstance * h, const CGPath & path) | ||||
| { | ||||
| 	stopMovementSound(); | ||||
| 	bool useTransit = path.nextNode().layer == EPathfindingLayer::AIR || path.nextNode().layer == EPathfindingLayer::WATER; | ||||
| 	std::vector<int3> pathToMove; | ||||
|  | ||||
| 	for (auto const & node : boost::adaptors::reverse(path.nodes)) | ||||
| 	{ | ||||
| 		if (node.coord == h->visitablePos()) | ||||
| 			continue; // first node, ignore - this is hero current position | ||||
|  | ||||
| 		if(node.isTeleportAction()) | ||||
| 			return; // pause after monolith / subterra gates | ||||
| 			break; // pause after monolith / subterra gates | ||||
|  | ||||
| 		if (node.turns != 0) | ||||
| 			return; // ran out of MP | ||||
| 			break; // ran out of move points | ||||
|  | ||||
| 		bool useTransitHere = node.layer == EPathfindingLayer::AIR || node.layer == EPathfindingLayer::WATER; | ||||
| 		if (useTransitHere != useTransit) | ||||
| 			break; | ||||
|  | ||||
| 		int3 coord = h->convertFromVisitablePos(node.coord); | ||||
| 		pathToMove.push_back(coord); | ||||
|  | ||||
| 		bool useTransit = node.layer == EPathfindingLayer::AIR || node.layer == EPathfindingLayer::WATER; | ||||
| 		LOCPLINT->cb->moveHero(h, coord, useTransit); | ||||
| 		if (LOCPLINT->cb->guardingCreaturePosition(node.coord) != int3(-1, -1, -1)) | ||||
| 			break; // we reached zone-of-control of wandering monster | ||||
|  | ||||
| 		if (!LOCPLINT->cb->getVisitableObjs(node.coord).empty()) | ||||
| 			break; // we reached event, garrison or some other visitable object - end this movement batch | ||||
| 	} | ||||
|  | ||||
| 	if (!pathToMove.empty()) | ||||
| 	{ | ||||
| 		//updateMovementSound(h, path.currNode().coord, path.nextNode().coord, path.nextNode().action); | ||||
| 		LOCPLINT->cb->moveHero(h, pathToMove, useTransit); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -314,7 +314,7 @@ void AdventureMapShortcuts::visitObject() | ||||
| 	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero(); | ||||
|  | ||||
| 	if(h) | ||||
| 		LOCPLINT->cb->moveHero(h, h->pos); | ||||
| 		LOCPLINT->cb->moveHero(h, h->pos, false); | ||||
| } | ||||
|  | ||||
| void AdventureMapShortcuts::openObject() | ||||
|   | ||||
| @@ -59,22 +59,23 @@ struct DLL_LINKAGE DismissHero : public CPackForServer | ||||
| struct DLL_LINKAGE MoveHero : public CPackForServer | ||||
| { | ||||
| 	MoveHero() = default; | ||||
| 	MoveHero(const int3 & Dest, const ObjectInstanceID & HID, bool Transit) | ||||
| 		: dest(Dest) | ||||
| 	MoveHero(const std::vector<int3> & path, const ObjectInstanceID & HID, bool Transit) | ||||
| 		: path(path) | ||||
| 		, hid(HID) | ||||
| 		, transit(Transit) | ||||
| 	{ | ||||
| 	} | ||||
| 	int3 dest; | ||||
| 	std::vector<int3> path; | ||||
| 	ObjectInstanceID hid; | ||||
| 	bool transit = false; | ||||
|  | ||||
| 	void visitTyped(ICPackVisitor & visitor) override; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler & h) | ||||
| 	template<typename Handler> | ||||
| 	void serialize(Handler & h) | ||||
| 	{ | ||||
| 		h & static_cast<CPackForServer &>(*this); | ||||
| 		h & dest; | ||||
| 		h & path; | ||||
| 		h & hid; | ||||
| 		h & transit; | ||||
| 	} | ||||
|   | ||||
| @@ -59,7 +59,17 @@ void ApplyGhNetPackVisitor::visitDismissHero(DismissHero & pack) | ||||
| void ApplyGhNetPackVisitor::visitMoveHero(MoveHero & pack) | ||||
| { | ||||
| 	gh.throwIfWrongOwner(&pack, pack.hid); | ||||
| 	result = gh.moveHero(pack.hid, pack.dest, 0, pack.transit, pack.player); | ||||
|  | ||||
| 	for (auto const & dest : pack.path) | ||||
| 	{ | ||||
| 		if (!gh.moveHero(pack.hid, dest, 0, pack.transit, pack.player)) | ||||
| 		{ | ||||
| 			result = false; | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	result = true; | ||||
| } | ||||
|  | ||||
| void ApplyGhNetPackVisitor::visitCastleTeleportHero(CastleTeleportHero & pack) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user