Browse Source

Merge pull request #5823 from IvanSavenko/bugfixing

Fixes for bugs & regressions
Ivan Savenko 4 months ago
parent
commit
de893a3575

+ 2 - 0
client/NetPacksClient.cpp

@@ -568,6 +568,8 @@ void ApplyClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
 			i->second->heroMoved(pack, verbose);
 		}
 	}
+
+	GAME->map().waitForOngoingAnimations();
 }
 
 void ApplyClientNetPackVisitor::visitNewStructures(NewStructures & pack)

+ 2 - 0
client/eventsSDL/InputHandler.cpp

@@ -289,12 +289,14 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
 		return;
 	}
 
+#ifndef VCMI_EMULATE_TOUCHSCREEN_WITH_MOUSE
 	//preprocessing
 	if(ev.type == SDL_MOUSEMOTION)
 	{
 		std::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 		ENGINE->cursor().cursorMove(ev.motion.x, ev.motion.y);
 	}
+#endif
 
 	{
 		std::unique_lock<std::mutex> lock(eventsMutex);

+ 14 - 3
client/eventsSDL/InputSourceTouch.cpp

@@ -65,15 +65,18 @@ void InputSourceTouch::handleEventFingerMotion(const SDL_TouchFingerEvent & tfin
 	if(std::abs(motionAccumulatedX[tfinger.fingerId]) < motionThreshold && std::abs(motionAccumulatedY[tfinger.fingerId]) < motionThreshold)
 		return;
 
+	int scalingFactor = ENGINE->screenHandler().getScalingFactor();
+
 	if (settings["video"]["cursor"].String() == "software" && state != TouchState::RELATIVE_MODE)
-		ENGINE->cursor().cursorMove(ENGINE->getCursorPosition().x, ENGINE->getCursorPosition().y);
+	{
+		Point cursorPosition = Point(tfinger.x * screenSize.x, tfinger.y * screenSize.y) * scalingFactor;
+		ENGINE->cursor().cursorMove(cursorPosition.x, cursorPosition.y);
+	}
 
 	switch(state)
 	{
 		case TouchState::RELATIVE_MODE:
 		{
-			int scalingFactor = ENGINE->screenHandler().getScalingFactor();
-
 			Point moveDistance {
 				static_cast<int>(screenSize.x * params.relativeModeSpeedFactor * motionAccumulatedX[tfinger.fingerId]),
 				static_cast<int>(screenSize.y * params.relativeModeSpeedFactor * motionAccumulatedY[tfinger.fingerId])
@@ -134,6 +137,14 @@ void InputSourceTouch::handleEventFingerDown(const SDL_TouchFingerEvent & tfinge
 
 	lastTapTimeTicks = tfinger.timestamp;
 
+	if (settings["video"]["cursor"].String() == "software" && state != TouchState::RELATIVE_MODE)
+	{
+		int scalingFactor = ENGINE->screenHandler().getScalingFactor();
+		Point screenSize = ENGINE->screenDimensions();
+		Point cursorPosition = Point(tfinger.x * screenSize.x, tfinger.y * screenSize.y) * scalingFactor;
+		ENGINE->cursor().cursorMove(cursorPosition.x, cursorPosition.y);
+	}
+
 	switch(state)
 	{
 		case TouchState::RELATIVE_MODE:

+ 1 - 1
client/media/CSoundHandler.cpp

@@ -201,7 +201,7 @@ int CSoundHandler::playSoundImpl(const AudioPath & sound, int repeats, bool useC
 
 	if(chunk)
 	{
-		channel = Mix_PlayChannel(-1, chunk, 0);
+		channel = Mix_PlayChannel(-1, chunk, repeats);
 		if(channel == -1)
 		{
 			logGlobal->error("Unable to play sound file %s , error %s", sound.getOriginalName(), Mix_GetError());

+ 1 - 1
config/schemas/bonus.json

@@ -3,7 +3,7 @@
 	"$schema" : "http://json-schema.org/draft-04/schema",
 	"title" : "VCMI bonus type format",
 	"description" : "Definition of bonus types",
-	"required" : ["type"],
+	"required" : [],
 	"additionalProperties" : false,
 	"properties" : {
 		"hidden" : {

+ 2 - 6
config/schemas/spell.json

@@ -197,12 +197,8 @@
 		"school" : {
 			"type" : "object",
 			"description" : "List of spell schools this spell belongs to",
-			"additionalProperties" : false,
-			"properties" : {
-				"air" : {"type" : "boolean"},
-				"fire" : {"type" : "boolean"},
-				"earth" : {"type" : "boolean"},
-				"water" : {"type" : "boolean"}
+			"additionalProperties" : {
+				"type" : "boolean"
 			}
 		},
 		"level" : {

+ 13 - 0
lib/gameState/GameStatePackVisitor.cpp

@@ -418,6 +418,18 @@ void GameStatePackVisitor::visitRemoveObject(RemoveObject & pack)
 		return;
 	}
 
+	if(obj->ID == Obj::TOWN)
+	{
+		auto * town = dynamic_cast<CGTownInstance *>(obj);
+		town->setVisitingHero(nullptr);
+
+		if (town->getGarrisonHero())
+		{
+			town->setGarrisonedHero(nullptr);
+			gs.getMap().showObject(gs.getHero(town->getGarrisonHero()->id));
+		}
+	}
+
 	const auto * quest = dynamic_cast<const IQuestObject *>(obj);
 	if (quest)
 	{
@@ -429,6 +441,7 @@ void GameStatePackVisitor::visitRemoveObject(RemoveObject & pack)
 		}
 	}
 
+	obj->detachFromBonusSystem(gs);
 	gs.getMap().eraseObject(pack.objectID);
 	gs.getMap().calculateGuardingGreaturePositions();//FIXME: excessive, update only affected tiles
 }

+ 1 - 1
lib/mapObjects/CGTownInstance.cpp

@@ -310,7 +310,7 @@ void CGTownInstance::onHeroVisit(IGameEventCallback & gameEvents, const CGHeroIn
 			const CArmedInstance * defendingArmy = defendingHero ? static_cast<const CArmedInstance*>(defendingHero) : this;
 			const bool isBattleOutside = isBattleOutsideTown(defendingHero);
 
-			if(!isBattleOutside && defendingHero == getVisitingHero())
+			if(!isBattleOutside && defendingHero && defendingHero == getVisitingHero())
 				mergeGarrisonOnSiege(gameEvents);
 
 			gameEvents.startBattle(h, defendingArmy, getSightCenter(), h, defendingHero, BattleLayout::createDefaultLayout(*cb, h, defendingArmy), (isBattleOutside ? nullptr : this));

+ 9 - 4
server/CGameHandler.cpp

@@ -889,10 +889,15 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
 		return complainRet("You cannot move your hero there. Simultaneous turns are active and another player is interacting with this map object!");
 
 	if (objectToVisit &&
-		objectToVisit->getOwner().isValidPlayer() &&
-		gameInfo().getPlayerRelations(objectToVisit->getOwner(), h->getOwner()) == PlayerRelations::ENEMIES &&
-		!turnOrder->isContactAllowed(objectToVisit->getOwner(), h->getOwner()))
-		return complainRet("You cannot move your hero there. This object belongs to another player and simultaneous turns are still active!");
+		objectToVisit->getOwner().isValidPlayer())
+	{
+		if (gameInfo().getPlayerRelations(objectToVisit->getOwner(), h->getOwner()) == PlayerRelations::ENEMIES &&
+		   !turnOrder->isContactAllowed(objectToVisit->getOwner(), h->getOwner()))
+			return complainRet("You cannot move your hero there. This object belongs to another player and simultaneous turns are still active!");
+
+		if (gs->getBattle(objectToVisit->getOwner()) != nullptr)
+			return complainRet("You cannot move your hero there. This object belongs to another player who is engaged in battle and simultaneous turns are still active!");
+	}
 
 	//it's a rock or blocked and not visitable tile
 	//OR hero is on land and dest is water and (there is not present only one object - boat)

+ 4 - 3
server/NetPacksLobbyServer.cpp

@@ -15,12 +15,13 @@
 
 #include "../lib/StartInfo.h"
 
+#include "../lib/CRandomGenerator.h"
 #include "../lib/campaign/CampaignState.h"
 #include "../lib/entities/faction/CTownHandler.h"
+#include "../lib/filesystem/Filesystem.h"
 #include "../lib/gameState/CGameState.h"
-#include "../lib/serializer/Connection.h"
 #include "../lib/mapping/CMapInfo.h"
-#include "../lib/filesystem/Filesystem.h"
+#include "../lib/serializer/Connection.h"
 
 void ClientPermissionsCheckerNetPackVisitor::visitForLobby(CPackForLobby & pack)
 {
@@ -368,7 +369,7 @@ void ApplyOnServerNetPackVisitor::visitLobbyPvPAction(LobbyPvPAction & pack)
 	switch(pack.action) {
 		case LobbyPvPAction::COIN:
 			txt.appendTextID("vcmi.lobby.pvp.coin.hover");
-			txt.appendRawString(" - " + std::to_string(srv.gh->getRandomGenerator().nextInt(1)));
+			txt.appendRawString(" - " + std::to_string(CRandomGenerator::getDefault().nextInt(1)));
 			srv.announceTxt(txt);
 			break;
 		case LobbyPvPAction::RANDOM_TOWN: