Browse Source

Basic version of hero movement on map. Removed old code.

Ivan Savenko 2 years ago
parent
commit
4501036a04

+ 0 - 4
client/CMT.cpp

@@ -480,10 +480,6 @@ int main(int argc, char * argv[])
 
 		CCS->curh = new CursorHandler();
 		logGlobal->info("Screen handler: %d ms", pomtime.getDiff());
-		pomtime.getDiff();
-
-		graphics->load();//must be after Content loading but should be in main thread
-		logGlobal->info("Main graphics: %d ms", pomtime.getDiff());
 
 		CMessage::init();
 		logGlobal->info("Message handler: %d ms", pomtime.getDiff());

+ 11 - 71
client/CPlayerInterface.cpp

@@ -103,11 +103,6 @@ std::shared_ptr<BattleInterface> CPlayerInterface::battleInt;
 enum  EMoveState {STOP_MOVE, WAITING_MOVE, CONTINUE_MOVE, DURING_MOVE};
 CondSh<EMoveState> stillMoveHero(STOP_MOVE); //used during hero movement
 
-static bool objectBlitOrderSorter(const TerrainTileObject  & a, const TerrainTileObject & b)
-{
-	return CMapHandler::compareObjectBlitOrder(a.obj, b.obj);
-}
-
 struct HeroObjectRetriever : boost::static_visitor<const CGHeroInstance *>
 {
 	const CGHeroInstance * operator()(const ConstTransitivePtr<CGHeroInstance> &h) const
@@ -396,21 +391,9 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
 		return;
 
 	const CGHeroInstance * hero = cb->getHero(details.id); //object representing this hero
-	int3 hp = details.start;
-
-	if(!hero)
-	{
-		//AI hero left the visible area (we can't obtain info)
-		//TODO very evil workaround -> retrieve pointer to hero so we could animate it
-		// TODO -> we should not need full CGHeroInstance structure to display animation or it should not be handled by playerint (but by the client itself)
-		const TerrainTile2 & tile = CGI->mh->ttiles[hp.z][hp.x - 1][hp.y];
-		for(auto & elem : tile.objects)
-			if(elem.obj && elem.obj->id == details.id)
-				hero = dynamic_cast<const CGHeroInstance *>(elem.obj);
 
-		if(!hero) //still nothing...
-			return;
-	}
+	if (!hero)
+		return;
 
 	adventureInt->minimap->updateTile(hero->convertToVisitablePos(details.start));
 	adventureInt->minimap->updateTile(hero->convertToVisitablePos(details.end));
@@ -474,60 +457,24 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
 		return;
 	}
 
-	ui32 speed = 0;
-	if(settings["session"]["spectate"].Bool())
-	{
-		if(!settings["session"]["spectate-hero-speed"].isNull())
-			speed = static_cast<ui32>(settings["session"]["spectate-hero-speed"].Integer());
-	}
-	else if(makingTurn) // our turn, our hero moves
-		speed = static_cast<ui32>(settings["adventure"]["heroSpeed"].Float());
-	else
-		speed = static_cast<ui32>(settings["adventure"]["enemySpeed"].Float());
-
-	if(speed == 0)
-	{
-		//FIXME: is this a proper solution?
-		CGI->mh->hideObject(hero);
-		CGI->mh->printObject(hero);
-		return; // no animation
-	}
-
 	adventureInt->centerOn(hero); //actualizing screen pos
 	adventureInt->minimap->redraw();
 	adventureInt->heroList->redraw();
 
-	initMovement(details, hero, hp);
-
 	auto waitFrame = [&]()
 	{
 		int frameNumber = GH.mainFPSmng->getFrameNumber();
 
 		auto unlockPim = vstd::makeUnlockGuard(*pim);
 		while(frameNumber == GH.mainFPSmng->getFrameNumber())
-			boost::this_thread::sleep(boost::posix_time::milliseconds(5));
+			boost::this_thread::sleep(boost::posix_time::milliseconds(1));
 	};
 
-	//first initializing done
-
 	//main moving
-	for(int i = 1; i < 32; i += 2 * speed)
-	{
-		movementPxStep(details, i, hp, hero);
-#ifndef VCMI_ANDROID
-		// currently android doesn't seem to be able to handle all these full redraws here, so let's disable it so at least it looks less choppy;
-		// most likely this is connected with the way that this manual animation+framerate handling is solved
-		adventureInt->requestRedrawMapOnNextFrame();
-#endif
-
-		//evil returns here ...
-		//todo: get rid of it
+	while (CGI->mh->hasActiveAnimations())
 		waitFrame(); //for animation purposes
-	}
-	//main moving done
 
 	//finishing move
-	finishMovement(details, hp, hero);
 	hero->isStanding = true;
 
 	//move finished
@@ -570,6 +517,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
 		const_cast<CGHeroInstance *>(hero)->moveDir = dirLookup[posOffset.y][posOffset.x];
 	}
 }
+
 void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
@@ -711,14 +659,12 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 
 	if (town->garrisonHero) //wandering hero moved to the garrison
 	{
-		CGI->mh->hideObject(town->garrisonHero);
 		if (town->garrisonHero->tempOwner == playerID && vstd::contains(wanderingHeroes,town->garrisonHero)) // our hero
 			wanderingHeroes -= town->garrisonHero;
 	}
 
 	if (town->visitingHero) //hero leaves garrison
 	{
-		CGI->mh->printObject(town->visitingHero);
 		if (town->visitingHero->tempOwner == playerID && !vstd::contains(wanderingHeroes,town->visitingHero)) // our hero
 			wanderingHeroes.push_back(town->visitingHero);
 	}
@@ -1748,7 +1694,7 @@ int CPlayerInterface::getLastIndex( std::string namePrefix)
 		return (--dates.end())->second; //return latest file number
 	return 0;
 }
-
+/*
 void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroInstance * ho, const int3 &hp )
 {
 	auto subArr = (CGI->mh->ttiles)[hp.z];
@@ -1892,7 +1838,7 @@ void CPlayerInterface::finishMovement( const TryMoveHero &details, const int3 &h
 	//recompute hero sprite positioning using hero's final position
 	movementPxStep(details, 32, hp, ho);
 }
-
+*/
 void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult )
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
@@ -2510,9 +2456,6 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
 		// (i == 0) means hero went through all the path
 		adventureInt->updateMoveHero(h, (i != 0));
 		adventureInt->updateNextHero(h);
-
-		// ugly workaround to force instant update of adventure map
-		adventureInt->animValHitCount = 8;
 	}
 
 	setMovementStatus(false);
@@ -2558,13 +2501,10 @@ void CPlayerInterface::updateAmbientSounds(bool resetAll)
 	{
 		int dist = pos.dist(tile, int3::DIST_CHEBYSHEV);
 		// We want sound for every special terrain on tile and not just one on top
-		for(auto & ttObj : CGI->mh->ttiles[tile.z][tile.x][tile.y].objects)
-		{
-			if(ttObj.ambientSound)
-				updateSounds(ttObj.ambientSound.get(), dist);
-		}
-		if(CGI->mh->map->isCoastalTile(tile))
-			updateSounds("LOOPOCEA", dist);
+
+		for(auto & soundName : CGI->mh->getAmbientSounds(tile))
+			updateSounds(soundName, dist);
+
 	}
 	CCS->soundh->ambientUpdateChannels(currentSounds);
 }

+ 0 - 3
client/CPlayerInterface.h

@@ -256,9 +256,6 @@ public:
 
 	void stopMovement();
 	void moveHero(const CGHeroInstance *h, const CGPath& path);
-	void initMovement(const TryMoveHero &details, const CGHeroInstance * ho, const int3 &hp );//initializing objects and performing first step of move
-	void movementPxStep( const TryMoveHero &details, int i, const int3 &hp, const CGHeroInstance * ho );//performing step of movement
-	void finishMovement( const TryMoveHero &details, const int3 &hp, const CGHeroInstance * ho ); //finish movement
 
 	void acceptTurn(); //used during hot seat after your turn message is close
 	void tryDiggging(const CGHeroInstance *h);

+ 1 - 4
client/Client.cpp

@@ -404,11 +404,8 @@ void CClient::initMapHandler()
 	// During loading CPlayerInterface from serialized state it's depend on MH
 	if(!settings["session"]["headless"].Bool())
 	{
-		const_cast<CGameInfo *>(CGI)->mh = new CMapHandler();
-		CGI->mh->map = gs->map;
+		const_cast<CGameInfo *>(CGI)->mh = new CMapHandler(gs->map);
 		logNetwork->trace("Creating mapHandler: %d ms", CSH->th->getDiff());
-		CGI->mh->init();
-		logNetwork->trace("Initializing mapHandler (together): %d ms", CSH->th->getDiff());
 	}
 
 	pathCache.clear();

+ 1 - 1
client/Client.h

@@ -229,7 +229,7 @@ public:
 	void setMovePoints(SetMovePoints * smp) override {};
 	void setManaPoints(ObjectInstanceID hid, int val) override {};
 	void giveHero(ObjectInstanceID id, PlayerColor player) override {};
-	void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) override {};
+	void changeObjPos(ObjectInstanceID objid, int3 newPos) override {};
 	void sendAndApply(CPackForClient * pack) override {};
 	void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override {};
 

+ 31 - 29
client/NetPacksClient.cpp

@@ -342,14 +342,14 @@ void ApplyClientNetPackVisitor::visitGiveBonus(GiveBonus & pack)
 void ApplyFirstClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
 {
 	CGObjectInstance *obj = gs.getObjInstance(pack.objid);
-	if(pack.flags & 1 && CGI->mh)
-		CGI->mh->hideObject(obj);
+	if(CGI->mh)
+		CGI->mh->onObjectFadeOut(obj);
 }
 void ApplyClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
 {
 	CGObjectInstance *obj = gs.getObjInstance(pack.objid);
-	if(pack.flags & 1 && CGI->mh)
-		CGI->mh->printObject(obj);
+	if(CGI->mh)
+		CGI->mh->onObjectFadeIn(obj);
 
 	cl.invalidatePaths();
 }
@@ -416,7 +416,7 @@ void ApplyFirstClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
 	const CGObjectInstance *o = cl.getObj(pack.id);
 
 	if(CGI->mh)
-		CGI->mh->hideObject(o, true);
+		CGI->mh->onObjectFadeOut(o);
 
 	//notify interfaces about removal
 	for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
@@ -443,7 +443,7 @@ void ApplyFirstClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
 	for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
 	{
 		auto ps = gs.getPlayerState(i->first);
-		if(ps && (gs.isVisible(pack.start - int3(1, 0, 0), i->first) || gs.isVisible(pack.end - int3(1, 0, 0), i->first)))
+		if(ps && (gs.isVisible(h->convertToVisitablePos(pack.start), i->first) || gs.isVisible(h->convertToVisitablePos(pack.end), i->first)))
 		{
 			if(ps->human)
 				pack.humanKnows = true;
@@ -452,12 +452,6 @@ void ApplyFirstClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
 
 	if(!CGI->mh)
 		return;
-
-	if(pack.result == TryMoveHero::TELEPORTATION  || pack.result == TryMoveHero::EMBARK  || pack.result == TryMoveHero::DISEMBARK  ||  !pack.humanKnows)
-		CGI->mh->hideObject(h, pack.result == TryMoveHero::EMBARK && pack.humanKnows);
-
-	if(pack.result == TryMoveHero::DISEMBARK)
-		CGI->mh->printObject(h->boat);
 }
 
 void ApplyClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
@@ -467,11 +461,26 @@ void ApplyClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
 
 	if(CGI->mh)
 	{
-		if(pack.result == TryMoveHero::TELEPORTATION  || pack.result == TryMoveHero::EMBARK  || pack.result == TryMoveHero::DISEMBARK)
-			CGI->mh->printObject(h, pack.result == TryMoveHero::DISEMBARK);
-
-		if(pack.result == TryMoveHero::EMBARK)
-			CGI->mh->hideObject(h->boat);
+		switch(pack.result)
+		{
+			case TryMoveHero::FAILED:
+				break; // no-op
+			case TryMoveHero::SUCCESS:
+				CGI->mh->onHeroMoved(h, pack.start, pack.end);
+				break;
+			case TryMoveHero::TELEPORTATION:
+				CGI->mh->onHeroTeleported(h, pack.start, pack.end);
+				break;
+			case TryMoveHero::BLOCKING_VISIT:
+				CGI->mh->onHeroRotated(h, pack.start, pack.end);
+				break;
+			case TryMoveHero::EMBARK:
+				CGI->mh->onObjectFadeOut(h);
+				break;
+			case TryMoveHero::DISEMBARK:
+				CGI->mh->onObjectFadeIn(h);
+				break;
+		}
 	}
 
 	PlayerColor player = h->tempOwner;
@@ -485,19 +494,14 @@ void ApplyClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
 		if(i->first != PlayerColor::SPECTATOR && gs.checkForStandardLoss(i->first)) // Do not notify vanquished pack.player's interface
 			continue;
 
-		if(gs.isVisible(pack.start - int3(1, 0, 0), i->first)
-			|| gs.isVisible(pack.end - int3(1, 0, 0), i->first))
+		if(gs.isVisible(h->convertToVisitablePos(pack.start), i->first)
+			|| gs.isVisible(h->convertToVisitablePos(pack.end), i->first))
 		{
 			// pack.src and pack.dst of enemy hero move may be not visible => 'verbose' should be false
 			const bool verbose = cl.getPlayerRelations(i->first, player) != PlayerRelations::ENEMIES;
 			i->second->heroMoved(pack, verbose);
 		}
 	}
-
-	//maphandler didn't get update from playerint, do it now
-	//TODO: restructure nicely
-	if(!pack.humanKnows && CGI->mh)
-		CGI->mh->printObject(h);
 }
 
 void ApplyClientNetPackVisitor::visitNewStructures(NewStructures & pack)
@@ -569,21 +573,19 @@ void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
 		}
 	}
 	if(needsPrinting && CGI->mh)
-		CGI->mh->printObject(h);
+		CGI->mh->onObjectInstantAdd(h);
 }
 
 void ApplyClientNetPackVisitor::visitGiveHero(GiveHero & pack)
 {
 	CGHeroInstance *h = gs.getHero(pack.id);
 	if(CGI->mh)
-		CGI->mh->printObject(h);
+		CGI->mh->onObjectInstantAdd(h);
 	callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroCreated, h);
 }
 
 void ApplyFirstClientNetPackVisitor::visitGiveHero(GiveHero & pack)
 {
-	if(CGI->mh)
-		CGI->mh->hideObject(gs.getHero(pack.id));
 }
 
 void ApplyClientNetPackVisitor::visitInfoWindow(InfoWindow & pack)
@@ -950,7 +952,7 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack)
 
 	const CGObjectInstance *obj = cl.getObj(pack.id);
 	if(CGI->mh)
-		CGI->mh->printObject(obj, true);
+		CGI->mh->onObjectFadeIn(obj);
 
 	for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
 	{

+ 29 - 84
client/adventureMap/CAdvMapInt.cpp

@@ -90,7 +90,6 @@ CAdvMapInt::CAdvMapInt():
 	terrain(new CTerrainRect),
 	state(NA),
 	spellBeingCasted(nullptr), selection(nullptr),
-	redrawOnNextFrame(false), anim(0), animValHitCount(0), heroAnim(0), heroAnimValHitCount(0),
 	activeMapPanel(nullptr), duringAITurn(false), scrollingDir(0), scrollingState(false),
 	swipeEnabled(settings["general"]["swipe"].Bool()), swipeMovementRequested(false),
 	swipeTargetPosition(Point(0, 0))
@@ -239,9 +238,9 @@ CAdvMapInt::CAdvMapInt():
 
 	changeMode(EAdvMapMode::NORMAL);
 
-	underground->block(!CGI->mh->map->twoLevel);
-	questlog->block(!CGI->mh->map->quests.size());
-	worldViewUnderground->block(!CGI->mh->map->twoLevel);
+	underground->block(!CGI->mh->getMap()->twoLevel);
+	questlog->block(!CGI->mh->getMap()->quests.size());
+	worldViewUnderground->block(!CGI->mh->getMap()->twoLevel);
 
 	addUsedEvents(MOVE);
 }
@@ -254,7 +253,6 @@ void CAdvMapInt::fshowOverview()
 void CAdvMapInt::fworldViewBack()
 {
 	changeMode(EAdvMapMode::NORMAL);
-	CGI->mh->discardWorldViewCache();
 
 	auto hero = curHero();
 	if (hero)
@@ -280,7 +278,7 @@ void CAdvMapInt::fworldViewScale4x()
 void CAdvMapInt::fswitchLevel()
 {
 	// with support for future multi-level maps :)
-	int maxLevels = CGI->mh->map->levels();
+	int maxLevels = CGI->mh->getMap()->levels();
 	if (maxLevels < 2)
 		return;
 
@@ -292,7 +290,6 @@ void CAdvMapInt::fswitchLevel()
 	worldViewUnderground->setIndex(terrain->getLevel(), true);
 	worldViewUnderground->redraw();
 
-	redrawOnNextFrame = true;
 	minimap->setLevel(terrain->getLevel());
 }
 
@@ -322,7 +319,7 @@ void CAdvMapInt::fsleepWake()
 void CAdvMapInt::fmoveHero()
 {
 	const CGHeroInstance *h = curHero();
-	if (!h || !LOCPLINT->paths.hasPath(h) || !CGI->mh->canStartHeroMovement())
+	if (!h || !LOCPLINT->paths.hasPath(h) || CGI->mh->hasActiveAnimations())
 		return;
 
 	LOCPLINT->moveHero(h, LOCPLINT->paths.getPath(h));
@@ -530,7 +527,6 @@ void CAdvMapInt::showAll(SDL_Surface * to)
 	}
 	activeMapPanel->showAll(to);
 
-	redrawOnNextFrame = true;
 	minimap->showAll(to);
 	show(to);
 
@@ -564,20 +560,6 @@ void CAdvMapInt::show(SDL_Surface * to)
 	if(state != INGAME)
 		return;
 
-	++animValHitCount; //for animations
-
-	if(animValHitCount % 2 == 0)
-	{
-		++heroAnim;
-	}
-	if(animValHitCount >= 8)
-	{
-		CGI->mh->updateWater();
-		animValHitCount = 0;
-		++anim;
-		redrawOnNextFrame = true;
-	}
-
 	if(swipeEnabled)
 	{
 		handleSwipeUpdate();
@@ -596,18 +578,14 @@ void CAdvMapInt::show(SDL_Surface * to)
 		else
 			gems[i]->setFrame(LOCPLINT->playerID.getNum());
 	}
-	if(redrawOnNextFrame)
-	{
-		for(int i = 0; i < 4; i++)
-			gems[i]->showAll(to);
-		redrawOnNextFrame=false;
-		LOCPLINT->cingconsole->show(to);
-	}
 
 	terrain->show(to);
+
 	for(int i = 0; i < 4; i++)
 		gems[i]->showAll(to);
 
+	LOCPLINT->cingconsole->show(to);
+
 	infoBar->show(to);
 	statusbar->showAll(to);
 }
@@ -616,30 +594,28 @@ void CAdvMapInt::handleMapScrollingUpdate()
 {
 	int scrollSpeed = static_cast<int>(settings["adventure"]["scrollSpeed"].Float());
 	//if advmap needs updating AND (no dialog is shown OR ctrl is pressed)
-	if((animValHitCount % (4 / scrollSpeed)) == 0)
-	{
-		if(scrollingDir & LEFT)
-			terrain->moveViewBy(Point(-4, 0));
 
-		if(scrollingDir & RIGHT)
-			terrain->moveViewBy(Point(+4, 0));
+	if(scrollingDir & LEFT)
+		terrain->moveViewBy(Point(-scrollSpeed, 0));
 
-		if(scrollingDir & UP)
-			terrain->moveViewBy(Point(0, -4));
+	if(scrollingDir & RIGHT)
+		terrain->moveViewBy(Point(+scrollSpeed, 0));
 
-		if(scrollingDir & DOWN)
-			terrain->moveViewBy(Point(0, +4));
+	if(scrollingDir & UP)
+		terrain->moveViewBy(Point(0, -scrollSpeed));
 
-		if(scrollingDir)
-		{
-			setScrollingCursor(scrollingDir);
-			scrollingState = true;
-		}
-		else if(scrollingState)
-		{
-			CCS->curh->set(Cursor::Map::POINTER);
-			scrollingState = false;
-		}
+	if(scrollingDir & DOWN)
+		terrain->moveViewBy(Point(0, +scrollSpeed));
+
+	if(scrollingDir)
+	{
+		setScrollingCursor(scrollingDir);
+		scrollingState = true;
+	}
+	else if(scrollingState)
+	{
+		CCS->curh->set(Cursor::Map::POINTER);
+		scrollingState = false;
 	}
 }
 
@@ -649,7 +625,6 @@ void CAdvMapInt::handleSwipeUpdate()
 	{
 		terrain->setViewCenter(swipeTargetPosition, terrain->getLevel());
 		CCS->curh->set(Cursor::Map::POINTER);
-		redrawOnNextFrame = true;
 		minimap->redraw();
 		swipeMovementRequested = false;
 	}
@@ -673,7 +648,6 @@ void CAdvMapInt::centerOn(int3 on, bool fade)
 
 	terrain->setViewCenter(on);
 
-	redrawOnNextFrame=true;
 	underground->setIndex(on.z,true); //change underground switch button image
 	underground->redraw();
 	worldViewUnderground->setIndex(on.z, true);
@@ -859,7 +833,7 @@ void CAdvMapInt::keyPressed(const SDL_Keycode & key)
 			if(!h || !isActive())
 				return;
 
-			if (!CGI->mh->canStartHeroMovement())
+			if (CGI->mh->hasActiveAnimations())
 				return;
 
 			if(*direction == Point(0,0))
@@ -870,7 +844,7 @@ void CAdvMapInt::keyPressed(const SDL_Keycode & key)
 
 			int3 dst = h->visitablePos() + int3(direction->x, direction->y, 0);
 
-			if(dst != verifyPos(dst))
+			if (!CGI->mh->isInMap((dst)))
 				return;
 
 			if ( !LOCPLINT->paths.setPath(h, dst))
@@ -910,23 +884,6 @@ boost::optional<Point> CAdvMapInt::keyToMoveDirection(const SDL_Keycode & key)
 	return boost::none;
 }
 
-int3 CAdvMapInt::verifyPos(int3 ver)
-{
-	if (ver.x<0)
-		ver.x=0;
-	if (ver.y<0)
-		ver.y=0;
-	if (ver.z<0)
-		ver.z=0;
-	if (ver.x>=CGI->mh->sizes.x)
-		ver.x=CGI->mh->sizes.x-1;
-	if (ver.y>=CGI->mh->sizes.y)
-		ver.y=CGI->mh->sizes.y-1;
-	if (ver.z>=CGI->mh->sizes.z)
-		ver.z=CGI->mh->sizes.z-1;
-	return ver;
-}
-
 void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
 {
 	assert(sel);
@@ -1181,7 +1138,7 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos)
 			if(LOCPLINT->paths.hasPath(currentHero) &&
 			   LOCPLINT->paths.getPath(currentHero).endPos() == mapPos)//we'll be moving
 			{
-				if(CGI->mh->canStartHeroMovement())
+				if(!CGI->mh->hasActiveAnimations())
 					LOCPLINT->moveHero(currentHero, LOCPLINT->paths.getPath(currentHero));
 				return;
 			}
@@ -1556,15 +1513,3 @@ void CAdvMapInt::WorldViewOptions::clear()
 
 	iconPositions.clear();
 }
-
-void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info)
-{
-	info.showAllTerrain = showAllTerrain;
-
-	info.additionalIcons = &iconPositions;
-}
-
-void CAdvMapInt::requestRedrawMapOnNextFrame()
-{
-	redrawOnNextFrame = true;
-}

+ 0 - 13
client/adventureMap/CAdvMapInt.h

@@ -67,7 +67,6 @@ private:
 		std::vector<ObjectPosInfo> iconPositions;
 		WorldViewOptions();
 		void clear();
-		void adjustDrawingInfo(MapDrawingInfo & info);
 	};
 
 	bool swipeEnabled;
@@ -75,15 +74,7 @@ private:
 	Point swipeTargetPosition;
 
 	EGameStates state;
-
-	ui8 anim, animValHitCount; //animation frame
-	ui8 heroAnim, heroAnimValHitCount; //animation frame
-
-	/// top left corner of visible map part
-	//int3 position;
-
 	EAdvMapMode mode;
-
 	WorldViewOptions worldViewOptions;
 
 	/// Currently selected object, can be town, hero or null
@@ -166,7 +157,6 @@ private:
 
 	boost::optional<Point> keyToMoveDirection(const SDL_Keycode & key);
 
-	bool redrawOnNextFrame;
 public:
 	CAdvMapInt();
 
@@ -184,12 +174,9 @@ public:
 
 	// public interface
 
-	void requestRedrawMapOnNextFrame();
-
 	void select(const CArmedInstance *sel, bool centerView = true);
 	void centerOn(int3 on, bool fade = false);
 	void centerOn(const CGObjectInstance *obj, bool fade = false);
-	int3 verifyPos(int3 ver);
 
 	bool isHeroSleeping(const CGHeroInstance *hero);
 	void setHeroSleeping(const CGHeroInstance *hero, bool sleep);

+ 5 - 56
client/adventureMap/CTerrainRect.cpp

@@ -36,7 +36,6 @@
 
 CTerrainRect::CTerrainRect()
 	: fadeSurface(nullptr)
-	, lastRedrawStatus(EMapAnimRedrawStatus::OK)
 	, fadeAnim(std::make_shared<CFadeAnimation>())
 	, curHoveredTile(-1, -1, -1)
 	, isSwiping(false)
@@ -113,7 +112,7 @@ void CTerrainRect::clickRight(tribool down, bool previousState)
 		return;
 	int3 mp = whichTileIsIt();
 
-	if(CGI->mh->map->isInTheMap(mp) && down)
+	if(CGI->mh->isInMap(mp) && down)
 		adventureInt->tileRClicked(mp);
 }
 
@@ -180,18 +179,17 @@ bool CTerrainRect::handleSwipeStateChange(bool btnPressed)
 void CTerrainRect::handleHover(const Point & cursorPosition)
 {
 	int3 tHovered = whichTileIsIt(cursorPosition);
-	int3 pom = adventureInt->verifyPos(tHovered);
 
-	if(tHovered != pom) //tile outside the map
+	if(!CGI->mh->isInMap(tHovered))
 	{
 		CCS->curh->set(Cursor::Map::POINTER);
 		return;
 	}
 
-	if (pom != curHoveredTile)
+	if (tHovered != curHoveredTile)
 	{
-		curHoveredTile = pom;
-		adventureInt->tileHovered(pom);
+		curHoveredTile = tHovered;
+		adventureInt->tileHovered(tHovered);
 	}
 }
 
@@ -205,50 +203,6 @@ void CTerrainRect::hover(bool on)
 	//Hoverable::hover(on);
 }
 
-/*
-void CTerrainRect::show(SDL_Surface * to)
-{
-	if (adventureInt->mode == EAdvMapMode::NORMAL)
-	{
-		MapDrawingInfo info(adventureInt->position, LOCPLINT->cb->getVisibilityMap(), pos);
-		info.otherheroAnim = true;
-		info.anim = adventureInt->anim;
-		info.heroAnim = adventureInt->heroAnim;
-		if (ADVOPT.smoothMove)
-			info.movement = int3(moveX, moveY, 0);
-
-		lastRedrawStatus = CGI->mh->drawTerrainRectNew(to, &info);
-		if (fadeAnim->isFading())
-		{
-			Rect r(pos);
-			fadeAnim->update();
-			fadeAnim->draw(to, r.topLeft());
-		}
-	}
-}
-
-void CTerrainRect::showAll(SDL_Surface * to)
-{
-	// world view map is static and doesn't need redraw every frame
-	if (adventureInt->mode == EAdvMapMode::WORLD_VIEW)
-	{
-		MapDrawingInfo info(adventureInt->position, LOCPLINT->cb->getVisibilityMap(), pos, adventureInt->worldViewIcons);
-		info.scaled = true;
-		info.scale = adventureInt->worldViewScale;
-		adventureInt->worldViewOptions.adjustDrawingInfo(info);
-		CGI->mh->drawTerrainRectNew(to, &info);
-	}
-}
-
-void CTerrainRect::showAnim(SDL_Surface * to)
-{
-	if (!needsAnimUpdate())
-		return;
-
-	if (fadeAnim->isFading() || lastRedrawStatus == EMapAnimRedrawStatus::REDRAW_REQUESTED)
-		show(to);
-}
-*/
 int3 CTerrainRect::whichTileIsIt(const Point &position)
 {
 	return renderer->getModel()->getTileAtPoint(position - pos);
@@ -277,11 +231,6 @@ void CTerrainRect::fadeFromCurrentView()
 	fadeAnim->init(CFadeAnimation::EMode::OUT, fadeSurface);
 }
 
-bool CTerrainRect::needsAnimUpdate()
-{
-	return fadeAnim->isFading() || lastRedrawStatus == EMapAnimRedrawStatus::REDRAW_REQUESTED;
-}
-
 void CTerrainRect::setLevel(int level)
 {
 	renderer->setViewCenter(renderer->getModel()->getMapViewCenter(), level);

+ 0 - 4
client/adventureMap/CTerrainRect.h

@@ -16,7 +16,6 @@ VCMI_LIB_NAMESPACE_BEGIN
 struct CGPath;
 VCMI_LIB_NAMESPACE_END
 
-enum class EMapAnimRedrawStatus;
 class CFadeAnimation;
 class MapView;
 
@@ -26,7 +25,6 @@ class CTerrainRect : public CIntObject
 	std::shared_ptr<MapView> renderer;
 
 	SDL_Surface * fadeSurface;
-	EMapAnimRedrawStatus lastRedrawStatus;
 	std::shared_ptr<CFadeAnimation> fadeAnim;
 
 	Point swipeInitialViewPos;
@@ -48,8 +46,6 @@ class CTerrainRect : public CIntObject
 	int3 whichTileIsIt(const Point & position); //x,y are cursor position
 	int3 whichTileIsIt(); //uses current cursor pos
 
-	bool needsAnimUpdate();
-
 public:
 	CTerrainRect();
 	~CTerrainRect();

+ 66 - 75
client/adventureMap/MapRenderer.cpp

@@ -326,10 +326,12 @@ std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const CGObjectInsta
 		return std::shared_ptr<CAnimation>();
 	}
 
-	return getAnimation(info->animationFile);
+	bool generateMovementGroups = (info->id == Obj::BOAT) || (info->id == Obj::HERO);
+
+	return getAnimation(info->animationFile, generateMovementGroups);
 }
 
-std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const std::string & filename)
+std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const std::string & filename, bool generateMovementGroups)
 {
 	if (animations.count(filename))
 		return animations[filename];
@@ -338,73 +340,27 @@ std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const std::string &
 	animations[filename] = ret;
 	ret->preload();
 
+	if (generateMovementGroups)
+	{
+		ret->createFlippedGroup(1,13);
+		ret->createFlippedGroup(2,14);
+		ret->createFlippedGroup(3,15);
+
+		ret->createFlippedGroup(6,10);
+		ret->createFlippedGroup(7,11);
+		ret->createFlippedGroup(8,12);
+	}
 	return ret;
 }
 
-void MapRendererObjects::initializeObjects(const IMapRendererContext & context)
+MapRendererObjects::MapRendererObjects(const IMapRendererContext & context)
 {
 	auto mapSize = context.getMapSize();
 
 	objects.resize(boost::extents[mapSize.z][mapSize.x][mapSize.y]);
 
 	for(const auto & obj : context.getAllObjects())
-	{
-		if(!obj)
-			continue;
-
-		if(obj->ID == Obj::HERO && dynamic_cast<const CGHeroInstance *>(obj.get())->inTownGarrison)
-			continue;
-
-		if(obj->ID == Obj::BOAT && dynamic_cast<const CGBoat *>(obj.get())->hero)
-			continue;
-
-		std::shared_ptr<CAnimation> animation = getAnimation(obj);
-
-		//no animation at all, e.g. Event
-		if(!animation)
-			continue;
-
-		//empty animation. Illegal?
-		assert(animation->size(0) > 0);
-		if(animation->size(0) == 0)
-			continue;
-
-		auto image = animation->getImage(0, 0);
-
-		int imageWidthTiles = (image->width() + 31) / 32;
-		int imageHeightTiles = (image->height() + 31) / 32;
-
-		int objectWidth = std::min(obj->getWidth(), imageWidthTiles);
-		int objectHeight = std::min(obj->getHeight(), imageHeightTiles);
-
-		for(int fx = 0; fx < objectWidth; ++fx)
-		{
-			for(int fy = 0; fy < objectHeight; ++fy)
-			{
-				int3 currTile(obj->pos.x - fx, obj->pos.y - fy, obj->pos.z);
-
-				if(context.isInMap(currTile) && obj->coveringAt(currTile.x, currTile.y))
-					objects[currTile.z][currTile.x][currTile.y].push_back(obj->id);
-			}
-		}
-	}
-
-	for(int z = 0; z < mapSize.z; z++)
-	{
-		for(int x = 0; x < mapSize.x; x++)
-		{
-			for(int y = 0; y < mapSize.y; y++)
-			{
-				auto & array = objects[z][x][y];
-				std::sort(array.begin(), array.end(), MapObjectsSorter(context));
-			}
-		}
-	}
-}
-
-MapRendererObjects::MapRendererObjects(const IMapRendererContext & context)
-{
-	initializeObjects(context);
+		onObjectInstantAdd(context, obj);
 }
 
 std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectInstance* obj)
@@ -425,7 +381,7 @@ std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectI
 	{
 		assert(dynamic_cast<const CGHeroInstance *>(obj) != nullptr);
 		assert(obj->tempOwner.isValidPlayer());
-		return getAnimation(heroFlags[obj->tempOwner.getNum()]);
+		return getAnimation(heroFlags[obj->tempOwner.getNum()], true);
 	}
 	if(obj->ID == Obj::BOAT)
 	{
@@ -435,7 +391,7 @@ std::shared_ptr<CAnimation> MapRendererObjects::getFlagAnimation(const CGObjectI
 		assert(!boat->hero || boat->hero->tempOwner.isValidPlayer());
 
 		if(boat->hero)
-			return getAnimation(boatFlags[obj->subID][boat->hero->tempOwner.getNum()]);
+			return getAnimation(boatFlags[obj->subID][boat->hero->tempOwner.getNum()], true);
 	}
 	return nullptr;
 }
@@ -516,14 +472,59 @@ void MapRendererObjects::renderTile(const IMapRendererContext & context, Canvas
 	}
 }
 
-void MapRendererObjects::addObject(const IMapRendererContext & context, const CGObjectInstance * object)
+void MapRendererObjects::onObjectInstantAdd(const IMapRendererContext & context, const CGObjectInstance * obj)
 {
+	if(!obj)
+		return;
+
+	if(obj->ID == Obj::HERO && dynamic_cast<const CGHeroInstance *>(obj)->inTownGarrison)
+		return;
+
+	if(obj->ID == Obj::BOAT && dynamic_cast<const CGBoat *>(obj)->hero)
+		return;
+
+	std::shared_ptr<CAnimation> animation = getAnimation(obj);
+
+	//no animation at all, e.g. Event
+	if(!animation)
+		return;
+
+	//empty animation. Illegal?
+	assert(animation->size(0) > 0);
+	if(animation->size(0) == 0)
+		return;
+
+	auto image = animation->getImage(0, 0);
+
+	int imageWidthTiles = (image->width() + 31) / 32;
+	int imageHeightTiles = (image->height() + 31) / 32;
 
+	int objectWidth = std::min(obj->getWidth(), imageWidthTiles);
+	int objectHeight = std::min(obj->getHeight(), imageHeightTiles);
+
+	for(int fx = 0; fx < objectWidth; ++fx)
+	{
+		for(int fy = 0; fy < objectHeight; ++fy)
+		{
+			int3 currTile(obj->pos.x - fx, obj->pos.y - fy, obj->pos.z);
+
+			if(context.isInMap(currTile) && obj->coveringAt(currTile.x, currTile.y))
+			{
+				auto & container = objects[currTile.z][currTile.x][currTile.y];
+
+				container.push_back(obj->id);
+				boost::range::sort(container, MapObjectsSorter(context));
+			}
+		}
+	}
 }
 
-void MapRendererObjects::removeObject(const IMapRendererContext & context, const CGObjectInstance * object)
+void MapRendererObjects::onObjectInstantRemove(const IMapRendererContext & context, const CGObjectInstance * object)
 {
-
+	for(int z = 0; z < context.getMapSize().z; z++)
+		for(int x = 0; x < context.getMapSize().x; x++)
+			for(int y = 0; y < context.getMapSize().y; y++)
+				vstd::erase(objects[z][x][y], object->id);
 }
 
 void MapRendererDebugGrid::renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates)
@@ -656,13 +657,3 @@ void MapRenderer::renderTile(const IMapRendererContext & context, Canvas & targe
 	}
 	rendererDebugGrid.renderTile(context, target,coordinates);
 }
-
-void MapRenderer::addObject(const IMapRendererContext & context, const CGObjectInstance * object)
-{
-	rendererObjects.addObject(context, object);
-}
-
-void MapRenderer::removeObject(const IMapRendererContext & context, const CGObjectInstance * object)
-{
-	rendererObjects.addObject(context, object);
-}

+ 24 - 22
client/adventureMap/MapRenderer.h

@@ -9,6 +9,8 @@
  */
 #pragma once
 
+#include "MapRendererContext.h"
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 class int3;
@@ -20,31 +22,33 @@ VCMI_LIB_NAMESPACE_END
 class CAnimation;
 class IImage;
 class Canvas;
-class IMapRendererContext;
 
 class MapObjectsSorter
 {
 	const IMapRendererContext & context;
+
 public:
 	explicit MapObjectsSorter(const IMapRendererContext & context);
 
-	bool operator ()(const ObjectInstanceID & left, const ObjectInstanceID & right) const;
-	bool operator ()(const CGObjectInstance * left, const CGObjectInstance * right) const;
+	bool operator()(const ObjectInstanceID & left, const ObjectInstanceID & right) const;
+	bool operator()(const CGObjectInstance * left, const CGObjectInstance * right) const;
 };
 
 class MapTileStorage
 {
 	using TerrainAnimation = std::array<std::unique_ptr<CAnimation>, 4>;
 	std::vector<TerrainAnimation> animations;
+
 public:
-	explicit MapTileStorage( size_t capacity);
-	void load(size_t index, const std::string& filename);
-	std::shared_ptr<IImage> find(size_t fileIndex, size_t rotationIndex, size_t imageIndex );
+	explicit MapTileStorage(size_t capacity);
+	void load(size_t index, const std::string & filename);
+	std::shared_ptr<IImage> find(size_t fileIndex, size_t rotationIndex, size_t imageIndex);
 };
 
 class MapRendererTerrain
 {
 	MapTileStorage storage;
+
 public:
 	MapRendererTerrain();
 	void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
@@ -53,6 +57,7 @@ public:
 class MapRendererRiver
 {
 	MapTileStorage storage;
+
 public:
 	MapRendererRiver();
 	void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
@@ -61,36 +66,36 @@ public:
 class MapRendererRoad
 {
 	MapTileStorage storage;
+
 public:
 	MapRendererRoad();
 	void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
 };
 
-class MapRendererObjects
+class MapRendererObjects : public IMapObjectObserver
 {
 	using MapObject = ObjectInstanceID;
-	using MapTile   = std::vector<MapObject>;
+	using MapTile = std::vector<MapObject>;
 
 	boost::multi_array<MapTile, 3> objects;
 	std::map<std::string, std::shared_ptr<CAnimation>> animations;
 
-	std::shared_ptr<CAnimation> getFlagAnimation(const CGObjectInstance* obj);
-	std::shared_ptr<CAnimation> getAnimation(const CGObjectInstance* obj);
-	std::shared_ptr<CAnimation> getAnimation(const std::string & filename);
+	std::shared_ptr<CAnimation> getFlagAnimation(const CGObjectInstance * obj);
+	std::shared_ptr<CAnimation> getAnimation(const CGObjectInstance * obj);
+	std::shared_ptr<CAnimation> getAnimation(const std::string & filename, bool generateMovementGroups);
 
-	std::shared_ptr<IImage> getImage(const IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation>& animation) const;
+	std::shared_ptr<IImage> getImage(const IMapRendererContext & context, const CGObjectInstance * obj, const std::shared_ptr<CAnimation> & animation) const;
 	size_t getAnimationGroup(const IMapRendererContext & context, const CGObjectInstance * obj) const;
 
-	void initializeObjects(const IMapRendererContext & context);
-	void renderImage(Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage>& image);
+	void renderImage(Canvas & target, const int3 & coordinates, const CGObjectInstance * object, const std::shared_ptr<IImage> & image);
+	void renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance * obj);
 
-	void renderObject(const IMapRendererContext & context, Canvas & target, const int3 & coordinates, const CGObjectInstance* obj);
 public:
 	explicit MapRendererObjects(const IMapRendererContext & context);
 	void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
 
-	void addObject(const IMapRendererContext & context, const CGObjectInstance * object);
-	void removeObject(const IMapRendererContext & context, const CGObjectInstance * object);
+	void onObjectInstantAdd(const IMapRendererContext & context, const CGObjectInstance * object) final override;
+	void onObjectInstantRemove(const IMapRendererContext & context, const CGObjectInstance * object) final override;
 };
 
 class MapRendererBorder
@@ -98,6 +103,7 @@ class MapRendererBorder
 	std::unique_ptr<CAnimation> animation;
 
 	size_t getIndexForTile(const IMapRendererContext & context, const int3 & coordinates);
+
 public:
 	MapRendererBorder();
 	void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
@@ -120,12 +126,12 @@ class MapRendererPath
 	void renderImage(Canvas & target, bool reachableToday, size_t imageIndex);
 	void renderImageCross(Canvas & target, bool reachableToday, const int3 & curr);
 	void renderImageArrow(Canvas & target, bool reachableToday, const int3 & curr, const int3 & prev, const int3 & next);
+
 public:
 	MapRendererPath();
 	void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
 };
 
-
 class MapRendererDebugGrid
 {
 public:
@@ -147,8 +153,4 @@ public:
 	explicit MapRenderer(const IMapRendererContext & context);
 
 	void renderTile(const IMapRendererContext & context, Canvas & target, const int3 & coordinates);
-
-	void addObject(const IMapRendererContext & context, const CGObjectInstance * object);
-	void removeObject(const IMapRendererContext & context, const CGObjectInstance * object);
-
 };

+ 31 - 2
client/adventureMap/MapRendererContext.h

@@ -17,6 +17,7 @@ class int3;
 class Point;
 class ObjectInstanceID;
 class CGObjectInstance;
+class CGHeroInstance;
 struct TerrainTile;
 struct CGPath;
 
@@ -27,7 +28,7 @@ class IMapRendererContext
 public:
 	virtual ~IMapRendererContext() = default;
 
-	using ObjectsVector = std::vector< ConstTransitivePtr<CGObjectInstance> >;
+	using ObjectsVector = std::vector<ConstTransitivePtr<CGObjectInstance>>;
 
 	/// returns dimensions of current map
 	virtual int3 getMapSize() const = 0;
@@ -42,7 +43,7 @@ public:
 	virtual ObjectsVector getAllObjects() const = 0;
 
 	/// returns specific object by ID, or nullptr if not found
-	virtual const CGObjectInstance * getObject( ObjectInstanceID objectID ) const = 0;
+	virtual const CGObjectInstance * getObject(ObjectInstanceID objectID) const = 0;
 
 	/// returns path of currently active hero, or nullptr if none
 	virtual const CGPath * currentPath() const = 0;
@@ -62,3 +63,31 @@ public:
 	/// if true, map grid should be visible on map
 	virtual bool showGrid() const = 0;
 };
+
+class IMapObjectObserver
+{
+public:
+	IMapObjectObserver();
+	virtual ~IMapObjectObserver();
+
+	/// Plays fade-in animation and adds object to map
+	virtual void onObjectFadeIn(const IMapRendererContext & context, const CGObjectInstance * obj) {}
+
+	/// Plays fade-out animation and removed object from map
+	virtual void onObjectFadeOut(const IMapRendererContext & context, const CGObjectInstance * obj) {}
+
+	/// Adds object to map instantly, with no animation
+	virtual void onObjectInstantAdd(const IMapRendererContext & context, const CGObjectInstance * obj) {}
+
+	/// Removes object from map instantly, with no animation
+	virtual void onObjectInstantRemove(const IMapRendererContext & context, const CGObjectInstance * obj) {}
+
+	/// Perform hero teleportation animation with terrain fade animation
+	virtual void onHeroTeleported(const IMapRendererContext & context, const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
+
+	/// Perform hero movement animation, moving hero across terrain
+	virtual void onHeroMoved(const IMapRendererContext & context, const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
+
+	/// Instantly rotates hero to face destination tile
+	virtual void onHeroRotated(const IMapRendererContext & context, const CGHeroInstance * obj, const int3 & from, const int3 & dest) {}
+};

+ 3 - 3
client/adventureMap/MapView.cpp

@@ -147,17 +147,17 @@ bool MapRendererContext::isInMap(const int3 & coordinates) const
 
 const TerrainTile & MapRendererContext::getMapTile(const int3 & coordinates) const
 {
-	return CGI->mh->map->getTile(coordinates);
+	return CGI->mh->getMap()->getTile(coordinates);
 }
 
 MapRendererContext::ObjectsVector MapRendererContext::getAllObjects() const
 {
-	return CGI->mh->map->objects;
+	return CGI->mh->getMap()->objects;
 }
 
 const CGObjectInstance * MapRendererContext::getObject(ObjectInstanceID objectID) const
 {
-	return CGI->mh->map->objects.at(objectID.getNum());
+	return CGI->mh->getMap()->objects.at(objectID.getNum());
 }
 
 bool MapRendererContext::isVisible(const int3 & coordinates) const

+ 8 - 4
client/adventureMap/MapView.h

@@ -18,7 +18,7 @@ class MapRenderer;
 
 class MapRendererContext : public IMapRendererContext
 {
-	Point tileSize = Point(32,32);
+	Point tileSize = Point(32, 32);
 	uint32_t animationTime = 0;
 
 public:
@@ -50,10 +50,11 @@ class MapViewModel
 	Point viewDimensions;
 
 	int mapLevel = 0;
+
 public:
-	void setTileSize(Point const & newValue);
-	void setViewCenter(Point const & newValue);
-	void setViewDimensions(Point const & newValue);
+	void setTileSize(const Point & newValue);
+	void setViewCenter(const Point & newValue);
+	void setViewDimensions(const Point & newValue);
 	void setLevel(int newLevel);
 
 	/// returns current size of map tile in pixels
@@ -112,6 +113,7 @@ class MapView : public CIntObject
 	std::unique_ptr<MapCache> tilesCache;
 
 	std::shared_ptr<MapViewModel> createModel(const Point & dimensions) const;
+
 public:
 	std::shared_ptr<const MapViewModel> getModel() const;
 
@@ -121,6 +123,8 @@ public:
 	void setViewCenter(const Point & position, int level);
 	void setTileSize(const Point & tileSize);
 
+	void moveHero();
+
 	void show(SDL_Surface * to) override;
 	void showAll(SDL_Surface * to) override;
 };

File diff suppressed because it is too large
+ 36 - 865
client/adventureMap/mapHandler.cpp


+ 26 - 307
client/adventureMap/mapHandler.h

@@ -9,12 +9,12 @@
  */
 #pragma once
 
+#include "../gui/CIntObject.h"
 
 #include "../../lib/int3.h"
 #include "../../lib/spells/ViewSpellInt.h"
 #include "../../lib/Rect.h"
 
-#include "../gui/CIntObject.h"
 
 #ifdef IN
 #undef IN
@@ -40,6 +40,7 @@ class CAnimation;
 class IImage;
 class CFadeAnimation;
 class CMapHandler;
+class IMapObjectObserver;
 
 enum class EWorldViewIcon
 {
@@ -72,12 +73,6 @@ enum class EMapObjectFadingType
 	OUT
 };
 
-enum class EMapAnimRedrawStatus
-{
-	OK,
-	REDRAW_REQUESTED // map blitter requests quick redraw due to current animation
-};
-
 struct TerrainTileObject
 {
 	const CGObjectInstance *obj;
@@ -94,319 +89,43 @@ struct TerrainTile2
 	std::vector<TerrainTileObject> objects; //pointers to objects being on this tile with rects to be easier to blit this tile on screen
 };
 
-struct MapDrawingInfo
-{
-	bool scaled;
-	int3 &topTile; // top-left tile in viewport [in tiles]
-	std::shared_ptr<const boost::multi_array<ui8, 3>> visibilityMap;
-	Rect drawBounds; // map rect drawing bounds on screen
-	std::shared_ptr<CAnimation> icons; // holds overlay icons for world view mode
-	float scale; // map scale for world view mode (only if scaled == true)
-
-	bool otherheroAnim;
-	ui8 anim;
-	ui8 heroAnim;
-
-	int3 movement; // used for smooth map movement
-
-	bool puzzleMode;
-	int3 grailPos; // location of grail for puzzle mode [in tiles]
-
-	const std::vector<ObjectPosInfo> * additionalIcons;
-
-	bool showAllTerrain; //for expert viewEarth
-
-	MapDrawingInfo(int3 &topTile_, std::shared_ptr<const boost::multi_array<ui8, 3>> visibilityMap_, const Rect & drawBounds_, std::shared_ptr<CAnimation> icons_ = nullptr)
-		: scaled(false),
-		  topTile(topTile_),
-
-		  visibilityMap(visibilityMap_),
-		  drawBounds(drawBounds_),
-		  icons(icons_),
-		  scale(1.0f),
-		  otherheroAnim(false),
-		  anim(0u),
-		  heroAnim(0u),
-		  movement(int3()),
-		  puzzleMode(false),
-		  grailPos(int3()),
-		  additionalIcons(nullptr),
-		  showAllTerrain(false)
-	{}
-
-	ui8 getHeroAnim() const { return otherheroAnim ? anim : heroAnim; }
-};
-
-
-template <typename T> class PseudoV
-{
-public:
-	PseudoV() : offset(0) { }
-	inline T & operator[](const int & n)
-	{
-		return inver[n+offset];
-	}
-	inline const T & operator[](const int & n) const
-	{
-		return inver[n+offset];
-	}
-	void resize(int rest, int before, int after)
-	{
-		inver.resize(before + rest + after);
-		offset=before;
-	}
-	int size() const
-	{
-		return static_cast<int>(inver.size());
-	}
-
-private:
-	int offset;
-	std::vector<T> inver;
-};
-
-enum class EMapCacheType : ui8
-{
-	TERRAIN, OBJECTS, ROADS, RIVERS, FOW, HEROES, HERO_FLAGS, FRAME, AFTER_LAST
-};
-
-/// temporarily caches rescaled frames for map world view redrawing
-class CMapCache
-{
-	std::array< std::map<intptr_t, std::shared_ptr<IImage>>, (ui8)EMapCacheType::AFTER_LAST> data;
-	float worldViewCachedScale;
-public:
-	CMapCache();
-	/// destroys all cached data (frees surfaces)
-	void discardWorldViewCache();
-	/// updates scale and determines if currently cached data is still valid
-	void updateWorldViewScale(float scale);
-	/// asks for cached data; @returns cached data if found, new scaled surface otherwise, may return nullptr in case of scaling error
-	std::shared_ptr<IImage> requestWorldViewCacheOrCreate(EMapCacheType type, std::shared_ptr<IImage> fullSurface);
-};
-
-/// helper struct to pass around resolved bitmaps of an object; images can be nullptr if object doesn't have bitmap of that type
-struct AnimBitmapHolder
-{
-	std::shared_ptr<IImage> objBitmap; // main object bitmap
-	std::shared_ptr<IImage> flagBitmap; // flag bitmap for the object (probably only for heroes and boats with heroes)
-	bool isMoving; // indicates if the object is moving (again, heroes/boats only)
-
-	AnimBitmapHolder(std::shared_ptr<IImage> objBitmap_ = nullptr, std::shared_ptr<IImage> flagBitmap_ = nullptr, bool moving = false)
-		: objBitmap(objBitmap_),
-		  flagBitmap(flagBitmap_),
-		  isMoving(moving)
-	{}
-};
-
-class CMapBlitter
-{
-protected:
-	const int FRAMES_PER_MOVE_ANIM_GROUP = 8;
-	CMapHandler * parent; // ptr to enclosing map handler; generally for legacy reasons, probably could/should be refactored out of here
-	int tileSize; // size of a tile drawn on map [in pixels]
-	int halfTileSizeCeil; // half of the tile size, rounded up
-	int3 tileCount; // number of tiles in current viewport
-	int3 topTile; // top-left tile of the viewport
-	int3 initPos; // starting drawing position [in pixels]
-	int3 pos; // current position [in tiles]
-	int3 realPos; // current position [in pixels]
-	Rect realTileRect; // default rect based on current pos: [realPos.x, realPos.y, tileSize, tileSize]
-	Rect defaultTileRect; // default rect based on 0: [0, 0, tileSize, tileSize]
-	const MapDrawingInfo * info; // data for drawing passed from outside
-
-	/// general drawing method, called internally by more specialized ones
-	virtual void drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, Rect * sourceRect, SDL_Surface * targetSurf, Rect * destRect) const = 0;
-
-	// first drawing pass
-
-	/// draws terrain bitmap (or custom bitmap if applicable) on current tile
-	virtual void drawTileTerrain(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile2 & tile) const;
-	/// draws a river segment on current tile
-	virtual void drawRiver(SDL_Surface * targetSurf, const TerrainTile & tinfo) const;
-	/// draws a road segment on current tile
-	virtual void drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const;
-	/// draws all objects on current tile (higher-level logic, unlike other draw*** methods)
-	virtual void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const;
-	virtual void drawObject(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, Rect * sourceRect, bool moving) const;
-	virtual void drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, Rect * sourceRect, Rect * destRect, bool moving) const;
-
-	// second drawing pass
-
-	/// current tile: draws overlay over the map, used to draw world view icons
-	virtual void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const = 0;
-	/// draws fog of war on current tile
-	virtual void drawFow(SDL_Surface * targetSurf) const;
-	/// draws map border frame on current position
-	virtual void drawFrame(SDL_Surface * targetSurf) const;
-	/// draws additional icons (for VIEW_AIR, VIEW_EARTH spells atm)
-	virtual void drawOverlayEx(SDL_Surface * targetSurf);
-
-	// third drawing pass
-
-	/// custom post-processing, if needed (used by puzzle view)
-	virtual void postProcessing(SDL_Surface * targetSurf) const {}
-
-	// misc methods
-
-	/// initializes frame-drawing (called at the start of every redraw)
-	virtual void init(const MapDrawingInfo * drawingInfo) = 0;
-	/// calculates clip region for map viewport
-	virtual Rect clip(SDL_Surface * targetSurf) const = 0;
-
-	virtual ui8 getHeroFrameGroup(ui8 dir, bool isMoving) const;
-	virtual ui8 getPhaseShift(const CGObjectInstance *object) const;
-
-	virtual bool canDrawObject(const CGObjectInstance * obj) const;
-	virtual bool canDrawCurrentTile() const;
-
-	// internal helper methods to choose correct bitmap(s) for object; called internally by findObjectBitmap
-	AnimBitmapHolder findHeroBitmap(const CGHeroInstance * hero, int anim) const;
-	AnimBitmapHolder findBoatBitmap(const CGBoat * hero, int anim) const;
-	std::shared_ptr<IImage> findFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const;
-	std::shared_ptr<IImage> findHeroFlagBitmap(const CGHeroInstance * obj, int anim, const PlayerColor * color, int group) const;
-	std::shared_ptr<IImage> findBoatFlagBitmap(const CGBoat * obj, int anim, const PlayerColor * color, int group, ui8 dir) const;
-	std::shared_ptr<IImage> findFlagBitmapInternal(std::shared_ptr<CAnimation> animation, int anim, int group, ui8 dir, bool moving) const;
-
-public:
-	CMapBlitter(CMapHandler * p);
-	virtual ~CMapBlitter();
-	void blit(SDL_Surface * targetSurf, const MapDrawingInfo * info);
-	/// helper method that chooses correct bitmap(s) for given object
-	AnimBitmapHolder findObjectBitmap(const CGObjectInstance * obj, int anim) const;
-};
-
-class CMapNormalBlitter : public CMapBlitter
-{
-protected:
-	void drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, Rect * sourceRect, SDL_Surface * targetSurf, Rect * destRect) const override;
-	void drawTileOverlay(SDL_Surface * targetSurf,const TerrainTile2 & tile) const override {}
-	void init(const MapDrawingInfo * info) override;
-	Rect clip(SDL_Surface * targetSurf) const override;
-public:
-	CMapNormalBlitter(CMapHandler * parent);
-	virtual ~CMapNormalBlitter(){}
-};
-
-class CMapWorldViewBlitter : public CMapBlitter
-{
-private:
-	std::shared_ptr<IImage> objectToIcon(Obj id, si32 subId, PlayerColor owner) const;
-protected:
-	void drawElement(EMapCacheType cacheType, std::shared_ptr<IImage> source, Rect * sourceRect, SDL_Surface * targetSurf, Rect * destRect) const override;
-	void drawTileOverlay(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override;
-	void drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, Rect * sourceRect, Rect * destRect, bool moving) const override;
-	void drawObject(SDL_Surface * targetSurf, std::shared_ptr<IImage> source, Rect * sourceRect, bool moving) const override;
-	void drawFrame(SDL_Surface * targetSurf) const override {}
-	void drawOverlayEx(SDL_Surface * targetSurf) override;
-	void init(const MapDrawingInfo * info) override;
-	Rect clip(SDL_Surface * targetSurf) const override;
-	ui8 getPhaseShift(const CGObjectInstance *object) const override { return 0u; }
-	void calculateWorldViewCameraPos();
-public:
-	CMapWorldViewBlitter(CMapHandler * parent);
-	virtual ~CMapWorldViewBlitter(){}
-};
-
-class CMapPuzzleViewBlitter : public CMapNormalBlitter
-{
-	std::vector<int> unblittableObjects;
-
-	void drawObjects(SDL_Surface * targetSurf, const TerrainTile2 & tile) const override;
-	void drawFow(SDL_Surface * targetSurf) const override {} // skipping FoW in puzzle view
-	void postProcessing(SDL_Surface * targetSurf) const override;
-	bool canDrawObject(const CGObjectInstance * obj) const override;
-	bool canDrawCurrentTile() const override { return true; }
-public:
-	CMapPuzzleViewBlitter(CMapHandler * parent);
-};
-
 class CMapHandler
 {
-	friend class CMapBlitter;
-	friend class CMapNormalBlitter;
-	friend class CMapWorldViewBlitter;
-
-	CMapCache cache;
-	CMapBlitter * normalBlitter;
-	CMapBlitter * worldViewBlitter;
-	CMapBlitter * puzzleViewBlitter;
-
-	std::map<int, std::pair<int3, CFadeAnimation*>> fadeAnims;
-	int fadeAnimCounter;
-
-	CMapBlitter * resolveBlitter(const MapDrawingInfo * info) const;
-	bool updateObjectsFade();
-	bool startObjectFade(TerrainTileObject & obj, bool in, int3 pos);
-
-	void initObjectRects();
-	void initBorderGraphics();
-	void initTerrainGraphics();
-	void prepareFOWDefs();
-
-public: //TODO: make private
-	boost::multi_array<TerrainTile2, 3> ttiles; //informations about map tiles [z][x][y]
-	int3 sizes; //map size (x = width, y = height, z = number of levels)
 	const CMap * map;
-private:
-	// Max number of tiles that will fit in the map screen. Tiles
-	// can be partial on each edges.
-	int tilesW;
-	int tilesH;
-
-	// size of each side of the frame around the whole map, in tiles
-	int frameH;
-	int frameW;
-
-	// Coord in pixels of the top left corner of the top left tile to
-	// draw. Values range is [-31..0]. A negative value
-	// implies that part of the tile won't be displayed.
-	int offsetX;
-	int offsetY;
-
-	//terrain graphics
-	//FIXME: unique_ptr should be enough, but fails to compile in MSVS 2013
-	typedef std::map<std::string, std::array<std::shared_ptr<CAnimation>, 4>> TFlippedAnimations; //[type, rotation]
-	typedef std::map<std::string, std::vector<std::array<std::shared_ptr<IImage>, 4>>> TFlippedCache;//[type, view type, rotation]
+	std::vector<IMapObjectObserver *> observers;
 
-	TFlippedAnimations terrainAnimations;//[terrain type, rotation]
-	TFlippedCache terrainImages;//[terrain type, view type, rotation]
-
-	TFlippedAnimations roadAnimations;//[road type, rotation]
-	TFlippedCache roadImages;//[road type, view type, rotation]
+public:
+	explicit CMapHandler(const CMap * map);
 
-	TFlippedAnimations riverAnimations;//[river type, rotation]
-	TFlippedCache riverImages;//[river type, view type, rotation]
+	const CMap * getMap();
 
-	//Fog of War cache (not owned)
-	std::vector<std::shared_ptr<IImage>> FoWfullHide;
-	boost::multi_array<ui8, 3> hideBitmap; //frame indexes (in FoWfullHide) of graphic that should be used to fully hide a tile
+	/// returns true if tile is within map bounds
+	bool isInMap(const int3 & tile);
 
-	std::vector<std::shared_ptr<IImage>> FoWpartialHide;
+	/// see MapObjectObserver interface
+	void onObjectFadeIn(const CGObjectInstance * obj);
+	void onObjectFadeOut(const CGObjectInstance * obj);
+	void onObjectInstantAdd(const CGObjectInstance * obj);
+	void onObjectInstantRemove(const CGObjectInstance * obj);
+	void onHeroTeleported(const CGHeroInstance * obj, const int3 & from, const int3 & dest);
+	void onHeroMoved(const CGHeroInstance * obj, const int3 & from, const int3 & dest);
+	void onHeroRotated(const CGHeroInstance * obj, const int3 & from, const int3 & dest);
 
-	//edge graphics
-	std::unique_ptr<CAnimation> egdeAnimation;
-	std::vector<std::shared_ptr<IImage>> egdeImages;//cache of links to egdeAnimation (for faster access)
-	PseudoV< PseudoV< PseudoV <ui8> > > edgeFrames; //frame indexes (in egdeImages) of tile outside of map
+	/// Add object to receive notifications on any changes in visible map state
+	void addMapObserver(IMapObjectObserver * observer);
+	void removeMapObserver(IMapObjectObserver * observer);
 
-	mutable std::map<const CGObjectInstance*, ui8> animationPhase;
+	/// returns string description for terrain interaction
+	void getTerrainDescr(const int3 & pos, std::string & out, bool isRMB) const;
 
-public:
-	CMapHandler();
-	~CMapHandler();
+	/// returns list of ambient sounds for specified tile
+	std::vector<std::string> getAmbientSounds(const int3 & tile);
 
-	void getTerrainDescr(const int3 & pos, std::string & out, bool isRMB) const; // isRMB = whether Right Mouse Button is clicked
-	bool printObject(const CGObjectInstance * obj, bool fadein = false); //puts appropriate things to tiles, so obj will be visible on map
-	bool hideObject(const CGObjectInstance * obj, bool fadeout = false); //removes appropriate things from ttiles, so obj will be no longer visible on map (but still will exist)
-	bool hasObjectHole(const int3 & pos) const; // Checks if TerrainTile2 tile has a pit remained after digging.
-	void init();
+	/// returns true if tile has hole from grail digging attempt
+	bool hasObjectHole(const int3 & pos) const;
 
-	EMapAnimRedrawStatus drawTerrainRectNew(SDL_Surface * targetSurface, const MapDrawingInfo * info, bool redrawOnlyAnim = false);
-	void updateWater();
 	/// determines if the map is ready to handle new hero movement (not available during fading animations)
-	bool canStartHeroMovement();
-
-	void discardWorldViewCache();
+	bool hasActiveAnimations();
 
 	static bool compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b);
 };

+ 0 - 164
client/render/Graphics.cpp

@@ -159,115 +159,6 @@ Graphics::~Graphics()
 	delete[] neutralColorPalette;
 }
 
-void Graphics::load()
-{
-	heroMoveArrows = std::make_shared<CAnimation>("ADAG");
-	heroMoveArrows->preload();
-
-	loadHeroAnimations();
-	loadHeroFlagAnimations();
-	loadFogOfWar();
-}
-
-void Graphics::loadHeroAnimations()
-{
-	for(auto & elem : CGI->heroh->classes.objects)
-	{
-		for (auto & templ : VLC->objtypeh->getHandlerFor(Obj::HERO, elem->getIndex())->getTemplates())
-		{
-			if (!heroAnimations.count(templ->animationFile))
-				heroAnimations[templ->animationFile] = loadHeroAnimation(templ->animationFile);
-		}
-	}
-
-	boatAnimations[0] = loadHeroAnimation("AB01_.DEF");
-	boatAnimations[1] = loadHeroAnimation("AB02_.DEF");
-	boatAnimations[2] = loadHeroAnimation("AB03_.DEF");
-
-
-	mapObjectAnimations["AB01_.DEF"] = boatAnimations[0];
-	mapObjectAnimations["AB02_.DEF"] = boatAnimations[1];
-	mapObjectAnimations["AB03_.DEF"] = boatAnimations[2];
-}
-void Graphics::loadHeroFlagAnimations()
-{
-	static const std::vector<std::string> HERO_FLAG_ANIMATIONS =
-	{
-		"AF00", "AF01","AF02","AF03",
-		"AF04", "AF05","AF06","AF07"
-	};
-
-	static const std::vector< std::vector<std::string> > BOAT_FLAG_ANIMATIONS =
-	{
-		{
-			"ABF01L", "ABF01G", "ABF01R", "ABF01D",
-			"ABF01B", "ABF01P", "ABF01W", "ABF01K"
-		},
-		{
-			"ABF02L", "ABF02G", "ABF02R", "ABF02D",
-			"ABF02B", "ABF02P", "ABF02W", "ABF02K"
-		},
-		{
-			"ABF03L", "ABF03G", "ABF03R", "ABF03D",
-			"ABF03B", "ABF03P", "ABF03W", "ABF03K"
-		}
-	};
-
-	for(const auto & name : HERO_FLAG_ANIMATIONS)
-		heroFlagAnimations.push_back(loadHeroFlagAnimation(name));
-
-	for(int i = 0; i < BOAT_FLAG_ANIMATIONS.size(); i++)
-		for(const auto & name : BOAT_FLAG_ANIMATIONS[i])
-			boatFlagAnimations[i].push_back(loadHeroFlagAnimation(name));
-}
-
-std::shared_ptr<CAnimation> Graphics::loadHeroFlagAnimation(const std::string & name)
-{
-	//first - group number to be rotated, second - group number after rotation
-	static const std::vector<std::pair<int,int> > rotations =
-	{
-		{6,10}, {7,11}, {8,12}, {1,13},
-		{2,14}, {3,15}
-	};
-
-	std::shared_ptr<CAnimation> anim = std::make_shared<CAnimation>(name);
-	anim->preload();
-
-	for(const auto & rotation : rotations)
-	{
-		const int sourceGroup = rotation.first;
-		const int targetGroup = rotation.second;
-
-		anim->createFlippedGroup(sourceGroup, targetGroup);
-	}
-
-	return anim;
-}
-
-std::shared_ptr<CAnimation> Graphics::loadHeroAnimation(const std::string &name)
-{
-	//first - group number to be rotated, second - group number after rotation
-	static const std::vector<std::pair<int,int> > rotations =
-	{
-		{6,10}, {7,11}, {8,12}, {1,13},
-		{2,14}, {3,15}
-	};
-
-	std::shared_ptr<CAnimation> anim = std::make_shared<CAnimation>(name);
-	anim->preload();
-
-
-	for(const auto & rotation : rotations)
-	{
-		const int sourceGroup = rotation.first;
-		const int targetGroup = rotation.second;
-
-		anim->createFlippedGroup(sourceGroup, targetGroup);
-	}
-
-	return anim;
-}
-
 void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
 {
 	if(sur->format->palette)
@@ -335,26 +226,6 @@ void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
 	}
 }
 
-void Graphics::loadFogOfWar()
-{
-	fogOfWarFullHide = std::make_shared<CAnimation>("TSHRC");
-	fogOfWarFullHide->preload();
-	fogOfWarPartialHide = std::make_shared<CAnimation>("TSHRE");
-	fogOfWarPartialHide->preload();
-
-	static const int rotations [] = {22, 15, 2, 13, 12, 16, 28, 17, 20, 19, 7, 24, 26, 25, 30, 32, 27};
-
-	size_t size = fogOfWarPartialHide->size(0);//group size after next rotation
-
-	for(const int rotation : rotations)
-	{
-		fogOfWarPartialHide->duplicateImage(0, rotation, 0);
-		auto image = fogOfWarPartialHide->getImage(size, 0);
-		image->verticalFlip();
-		size++;
-	}
-}
-
 void Graphics::loadFonts()
 {
 	const JsonNode config(ResourceID("config/fonts.json"));
@@ -378,41 +249,6 @@ void Graphics::loadFonts()
 	}
 }
 
-std::shared_ptr<CAnimation> Graphics::getAnimation(const CGObjectInstance* obj)
-{
-	return getAnimation(obj->appearance);
-}
-
-std::shared_ptr<CAnimation> Graphics::getAnimation(std::shared_ptr<const ObjectTemplate> info)
-{
-	//the only(?) invisible object
-	if(info->id == Obj::EVENT)
-	{
-		return std::shared_ptr<CAnimation>();
-	}
-
-	if(info->animationFile.empty())
-	{
-		logGlobal->warn("Def name for obj (%d,%d) is empty!", info->id, info->subid);
-		return std::shared_ptr<CAnimation>();
-	}
-
-	std::shared_ptr<CAnimation> ret = mapObjectAnimations[info->animationFile];
-
-	//already loaded
-	if(ret)
-	{
-		ret->preload();
-		return ret;
-	}
-
-	ret = std::make_shared<CAnimation>(info->animationFile);
-	mapObjectAnimations[info->animationFile] = ret;
-
-	ret->preload();
-	return ret;
-}
-
 void Graphics::loadErmuToPicture()
 {
 	//loading ERMU to picture

+ 0 - 34
client/render/Graphics.h

@@ -39,23 +39,11 @@ enum EFonts : int
 class Graphics
 {
 	void addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName);
-
 	void addImageListEntries(const EntityService * service);
 
 	void initializeBattleGraphics();
 	void loadPaletteAndColors();
-
-	void loadHeroAnimations();
-	//loads animation and adds required rotated frames
-	std::shared_ptr<CAnimation> loadHeroAnimation(const std::string &name);
-
-	void loadHeroFlagAnimations();
-
-	//loads animation and adds required rotated frames
-	std::shared_ptr<CAnimation> loadHeroFlagAnimation(const std::string &name);
-
 	void loadErmuToPicture();
-	void loadFogOfWar();
 	void loadFonts();
 	void initializeImageLists();
 
@@ -70,23 +58,6 @@ public:
 	SDL_Color * playerColorPalette; //palette to make interface colors good - array of size [256]
 	SDL_Color * neutralColorPalette;
 
-	std::shared_ptr<CAnimation> heroMoveArrows;
-
-	// [hero class def name]  //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
-	std::map< std::string, std::shared_ptr<CAnimation> > heroAnimations;
-	std::vector< std::shared_ptr<CAnimation> > heroFlagAnimations;
-
-	// [boat type: 0 .. 2]  //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
-	std::array< std::shared_ptr<CAnimation>, 3> boatAnimations;
-
-	std::array< std::vector<std::shared_ptr<CAnimation> >, 3> boatFlagAnimations;
-
-	//all other objects (not hero or boat)
-	std::map< std::string, std::shared_ptr<CAnimation> > mapObjectAnimations;
-
-	std::shared_ptr<CAnimation> fogOfWarFullHide;
-	std::shared_ptr<CAnimation> fogOfWarPartialHide;
-
 	std::map<std::string, JsonNode> imageLists;
 
 	//towns
@@ -98,12 +69,7 @@ public:
 	Graphics();
 	~Graphics();
 
-	void load();
-
 	void blueToPlayersAdv(SDL_Surface * sur, PlayerColor player); //replaces blue interface colour with a color of player
-
-	std::shared_ptr<CAnimation> getAnimation(const CGObjectInstance * obj);
-	std::shared_ptr<CAnimation> getAnimation(std::shared_ptr<const ObjectTemplate> info);
 };
 
 extern Graphics * graphics;

+ 8 - 8
client/windows/GUIClasses.cpp

@@ -21,7 +21,6 @@
 #include "../CVideoHandler.h"
 #include "../CServerHandler.h"
 
-#include "../adventureMap/mapHandler.h"
 #include "../adventureMap/CResDataBar.h"
 #include "../battle/BattleInterfaceClasses.h"
 #include "../battle/BattleInterface.h"
@@ -1159,14 +1158,15 @@ CPuzzleWindow::CPuzzleWindow(const int3 & GrailPos, double discoveredRatio)
 
 void CPuzzleWindow::showAll(SDL_Surface * to)
 {
-	int3 moveInt = int3(8, 9, 0);
-	Rect mapRect = Rect(Point(pos.x + 8, pos.y + 7), Point(544, 591));
-	int3 topTile = grailPos - moveInt;
+	assert(0);
+	//int3 moveInt = int3(8, 9, 0);
+	//Rect mapRect = Rect(Point(pos.x + 8, pos.y + 7), Point(544, 591));
+	//int3 topTile = grailPos - moveInt;
 
-	MapDrawingInfo info(topTile, LOCPLINT->cb->getVisibilityMap(), mapRect);
-	info.puzzleMode = true;
-	info.grailPos = grailPos;
-	CGI->mh->drawTerrainRectNew(to, &info);
+	//MapDrawingInfo info(topTile, LOCPLINT->cb->getVisibilityMap(), mapRect);
+	//info.puzzleMode = true;
+	//info.grailPos = grailPos;
+	//CGI->mh->drawTerrainRectNew(to, &info);
 
 	CWindowObject::showAll(to);
 }

+ 1 - 1
lib/IGameCallback.h

@@ -126,7 +126,7 @@ public:
 	virtual void setMovePoints(SetMovePoints * smp)=0;
 	virtual void setManaPoints(ObjectInstanceID hid, int val)=0;
 	virtual void giveHero(ObjectInstanceID id, PlayerColor player)=0;
-	virtual void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags)=0;
+	virtual void changeObjPos(ObjectInstanceID objid, int3 newPos)=0;
 	virtual void sendAndApply(CPackForClient * pack) = 0;
 	virtual void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)=0; //when two heroes meet on adventure map
 	virtual void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) = 0;

+ 0 - 3
lib/NetPacks.h

@@ -380,7 +380,6 @@ struct DLL_LINKAGE ChangeObjPos : public CPackForClient
 
 	ObjectInstanceID objid;
 	int3 nPos;
-	ui8 flags = 0; //bit flags: 1 - redraw
 
 	virtual void visitTyped(ICPackVisitor & visitor) override;
 
@@ -388,7 +387,6 @@ struct DLL_LINKAGE ChangeObjPos : public CPackForClient
 	{
 		h & objid;
 		h & nPos;
-		h & flags;
 	}
 };
 
@@ -583,7 +581,6 @@ struct DLL_LINKAGE TryMoveHero : public CPackForClient
 		FAILED,
 		SUCCESS,
 		TELEPORTATION,
-		RESERVED_,
 		BLOCKING_VISIT,
 		EMBARK,
 		DISEMBARK

+ 5 - 3
lib/Point.h

@@ -22,11 +22,13 @@ public:
 	Point()
 	{
 		x = y = 0;
-	};
+	}
 
 	Point(int X, int Y)
-		:x(X),y(Y)
-	{};
+		: x(X)
+		, y(Y)
+	{
+	}
 
 	explicit DLL_LINKAGE Point(const int3 &a);
 

+ 0 - 1
lib/spells/AdventureSpellMechanics.cpp

@@ -200,7 +200,6 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
 		ChangeObjPos cop;
 		cop.objid = nearest->id;
 		cop.nPos = summonPos + int3(1,0,0);
-		cop.flags = 1;
 		env->apply(&cop);
 	}
 	else if(schoolLevel < 2) //none or basic level -> cannot create boat :(

+ 1 - 2
server/CGameHandler.cpp

@@ -2773,12 +2773,11 @@ void CGameHandler::giveHero(ObjectInstanceID id, PlayerColor player)
 	sendAndApply(&gh);
 }
 
-void CGameHandler::changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags)
+void CGameHandler::changeObjPos(ObjectInstanceID objid, int3 newPos)
 {
 	ChangeObjPos cop;
 	cop.objid = objid;
 	cop.nPos = newPos;
-	cop.flags = flags;
 	sendAndApply(&cop);
 }
 

+ 1 - 1
server/CGameHandler.h

@@ -195,7 +195,7 @@ public:
 	void setMovePoints(SetMovePoints * smp) override;
 	void setManaPoints(ObjectInstanceID hid, int val) override;
 	void giveHero(ObjectInstanceID id, PlayerColor player) override;
-	void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) override;
+	void changeObjPos(ObjectInstanceID objid, int3 newPos) override;
 	void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override;
 
 	void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) override;

Some files were not shown because too many files changed in this diff