Ver Fonte

Merge branch 'develop' into VCAI_fixes

DjWarmonger há 7 anos atrás
pai
commit
5f39e92eb4

+ 2 - 0
AI/VCAI/VCAI.cbp

@@ -95,6 +95,8 @@
 		<Unit filename="MapObjectsEvaluator.h" />
 		<Unit filename="ResourceManager.cpp" />
 		<Unit filename="ResourceManager.h" />
+		<Unit filename="SectorMap.cpp" />
+		<Unit filename="SectorMap.h" />
 		<Unit filename="StdInc.h">
 			<Option compile="1" />
 			<Option weight="0" />

+ 8 - 6
AI/VCAI/VCAI.cpp

@@ -583,9 +583,10 @@ void VCAI::objectPropertyChanged(const SetObjectProperty * sop)
 void VCAI::buildChanged(const CGTownInstance * town, BuildingID buildingID, int what)
 {
 	LOG_TRACE_PARAMS(logAi, "what '%i'", what);
-	if (town->getOwner() == playerID && what == 1) //built
-		completeGoal(sptr(Goals::BuildThis(buildingID, town)));
 	NET_EVENT_HANDLER;
+
+	if(town->getOwner() == playerID && what == 1) //built
+		completeGoal(sptr(Goals::BuildThis(buildingID, town)));
 }
 
 void VCAI::heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain)
@@ -737,6 +738,7 @@ void VCAI::showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance *
 
 void VCAI::showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects)
 {
+	NET_EVENT_HANDLER;
 	status.addQuery(askID, "Map object select query");
 	requestActionASAP([=](){ answerQuery(askID, 0); });
 
@@ -873,7 +875,7 @@ void VCAI::mainLoop()
 
 	invalidPathHeroes.clear();
 
-	while (basicGoals.size()) 
+	while (basicGoals.size())
 	{
 		vstd::removeDuplicates(basicGoals); //TODO: container which does this automagically without has would be nice
 		goalsToAdd.clear();
@@ -925,7 +927,7 @@ void VCAI::mainLoop()
 					throw cannotFulfillGoalException("Goal %s is neither abstract nor elementar!" + basicGoal->name());
 			}
 		}
-		
+
 		//now choose one elementar goal to realize
 		Goals::TGoalVec possibleGoals(elementarGoals.begin(), elementarGoals.end()); //copy to vector
 		Goals::TSubgoal goalToRealize = sptr(Goals::Invalid());
@@ -1450,7 +1452,7 @@ void VCAI::wander(HeroPtr h)
 				dests.push_back(*boost::max_element(townsReachable, compareReinforcements));
 			}
 			else if(townsNotReachable.size())
-			{			
+			{
 				//TODO pick the truly best
 				const CGTownInstance * t = *boost::max_element(townsNotReachable, compareReinforcements);
 				logAi->debug("%s can't reach any town, we'll try to make our way to %s at %s", h->name, t->name, t->visitablePos().toString());
@@ -2161,7 +2163,7 @@ void VCAI::tryRealize(Goals::BuyArmy & g)
 		{
 			auto ci = infoFromDC(t->creatures[i]);
 			ci.level = i; //this is important for Dungeon Summoning Portal
-			creaturesInDwellings.push_back(ci); 
+			creaturesInDwellings.push_back(ci);
 		}
 		vstd::erase_if(creaturesInDwellings, [](const creInfo & ci) -> bool
 		{

+ 6 - 4
client/CMT.cpp

@@ -1155,10 +1155,12 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn
 	{
 		SDL_RenderSetLogicalSize(mainRenderer, w, h);
 
-#ifndef VCMI_ANDROID
-		// on android this stretches the game to fit the screen, not preserving aspect and apparently this also breaks coordinates scaling in mouse events
-		SDL_RenderSetViewport(mainRenderer, nullptr);
-#endif
+//following line is bugged not only on android, do not re-enable without checking
+//#ifndef VCMI_ANDROID
+//		// on android this stretches the game to fit the screen, not preserving aspect and apparently this also breaks coordinates scaling in mouse events
+//		SDL_RenderSetViewport(mainRenderer, nullptr);
+//#endif
+
 	}
 
 

+ 3 - 2
client/CServerHandler.cpp

@@ -43,6 +43,7 @@
 #include <boost/uuid/uuid.hpp>
 #include <boost/uuid/uuid_io.hpp>
 #include <boost/uuid/uuid_generators.hpp>
+#include "../lib/serializer/Cast.h"
 
 template<typename T> class CApplyOnLobby;
 
@@ -613,7 +614,7 @@ void CServerHandler::threadHandleConnection()
 				// Though currently they'll be delivered and might cause crash.
 				vstd::clear_pointer(pack);
 			}
-			else if(auto lobbyPack = dynamic_cast<CPackForLobby *>(pack))
+			else if(auto lobbyPack = dynamic_ptr_cast<CPackForLobby>(pack))
 			{
 				if(applier->getApplier(typeList.getTypeID(pack))->applyOnLobbyHandler(this, pack))
 				{
@@ -624,7 +625,7 @@ void CServerHandler::threadHandleConnection()
 					}
 				}
 			}
-			else if(auto clientPack = dynamic_cast<CPackForClient *>(pack))
+			else if(auto clientPack = dynamic_ptr_cast<CPackForClient>(pack))
 			{
 				client->handlePack(clientPack);
 			}

+ 12 - 1
client/windows/CCastleInterface.cpp

@@ -37,6 +37,8 @@
 #include "../../lib/spells/CSpellHandler.h"
 #include "../../lib/CTownHandler.h"
 #include "../../lib/GameConstants.h"
+#include "../../lib/StartInfo.h"
+#include "../../lib/mapping/CCampaignHandler.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
 
@@ -874,7 +876,16 @@ void CCastleBuildings::enterMagesGuild()
 
 	if(hero && !hero->hasSpellbook()) //hero doesn't have spellbok
 	{
-		if(LOCPLINT->cb->getResourceAmount(Res::GOLD) < 500) //not enough gold to buy spellbook
+		const StartInfo *si = LOCPLINT->cb->getStartInfo();
+		// it would be nice to find a way to move this hack to config/mapOverrides.json
+		if(si && si->campState && si->campState->camp &&                // We're in campaign,
+			(si->campState->camp->header.filename == "DATA/YOG.H3C") && // which is "Birth of a Barbarian",
+			(hero->subID == 45))                                        // and the hero is Yog (based on Solmyr)
+		{
+			// "Yog has given up magic in all its forms..."
+			LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[736]);
+		}
+		else if(LOCPLINT->cb->getResourceAmount(Res::GOLD) < 500) //not enough gold to buy spellbook
 		{
 			openMagesGuild();
 			LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[213]);

+ 1 - 0
lib/CMakeLists.txt

@@ -267,6 +267,7 @@ set(lib_HEADERS
 		serializer/JsonDeserializer.h
 		serializer/JsonSerializeFormat.h
 		serializer/JsonSerializer.h
+		serializer/Cast.h
 
 		spells/AbilityCaster.h
 		spells/AdventureSpellMechanics.h

+ 2 - 0
lib/serializer/CSerializer.h

@@ -99,7 +99,9 @@ public:
 		else
 		{
 			assert(!i->second.empty());
+#ifndef __APPLE__
 			assert(i->second.type() == typeid(VectorizedObjectInfo<T, U>));
+#endif
 			VectorizedObjectInfo<T, U> *ret = &(boost::any_cast<VectorizedObjectInfo<T, U>&>(i->second));
 			return ret;
 		}

+ 62 - 0
lib/serializer/Cast.h

@@ -0,0 +1,62 @@
+/*
+ * Cast.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+#include <typeinfo>
+#include <string>
+#include "CTypeList.h"
+
+template<class T, class F>
+inline const T * dynamic_ptr_cast(const F * ptr)
+{
+#ifndef VCMI_APPLE
+	return dynamic_cast<const T *>(ptr);
+#else
+	if(!strcmp(typeid(*ptr).name(), typeid(T).name()))
+	{
+		return static_cast<const T *>(ptr);
+	}
+	try
+	{
+		auto * sourceTypeInfo = typeList.getTypeInfo(ptr);
+		auto * targetTypeInfo = &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type);
+		typeList.castRaw((void *)ptr, sourceTypeInfo, targetTypeInfo);
+	}
+	catch(...)
+	{
+		return nullptr;
+	}
+	return static_cast<const T *>(ptr);
+#endif
+}
+
+template<class T, class F>
+inline T * dynamic_ptr_cast(F * ptr)
+{
+#ifndef VCMI_APPLE
+	return dynamic_cast<T *>(ptr);
+#else
+	if(!strcmp(typeid(*ptr).name(), typeid(T).name()))
+	{
+		return static_cast<T *>(ptr);
+	}
+	try
+	{
+		auto * sourceTypeInfo = typeList.getTypeInfo(ptr);
+		auto * targetTypeInfo = &typeid(typename std::remove_const<typename std::remove_pointer<T>::type>::type);
+		typeList.castRaw((void *)ptr, sourceTypeInfo, targetTypeInfo);
+	}
+	catch(...)
+	{
+		return nullptr;
+	}
+	return static_cast<T *>(ptr);
+#endif
+}

+ 1 - 0
server/CGameHandler.cpp

@@ -46,6 +46,7 @@
 #include "../lib/registerTypes/RegisterTypes.h"
 #include "../lib/serializer/CTypeList.h"
 #include "../lib/serializer/Connection.h"
+#include "../lib/serializer/Cast.h"
 
 #ifndef _MSC_VER
 #include <boost/thread/xtime.hpp>

+ 1 - 0
server/CQuery.cpp

@@ -12,6 +12,7 @@
 #include "CGameHandler.h"
 #include "../lib/battle/BattleInfo.h"
 #include "../lib/mapObjects/MiscObjects.h"
+#include "../lib/serializer/Cast.h"
 
 boost::mutex Queries::mx;
 

+ 1 - 1
server/CVCMIServer.cpp

@@ -8,7 +8,6 @@
  *
  */
 #include "StdInc.h"
-
 #include <boost/asio.hpp>
 
 #include "../lib/filesystem/Filesystem.h"
@@ -42,6 +41,7 @@
 #include "../lib/CConfigHandler.h"
 #include "../lib/ScopeGuard.h"
 #include "../lib/serializer/CMemorySerializer.h"
+#include "../lib/serializer/Cast.h"
 
 #include "../lib/UnlockGuard.h"
 

+ 1 - 0
server/NetPacksServer.cpp

@@ -20,6 +20,7 @@
 #include "../lib/serializer/Connection.h"
 #include "../lib/spells/CSpellHandler.h"
 #include "../lib/spells/ISpellMechanics.h"
+#include "../lib/serializer/Cast.h"
 
 bool CPackForServer::isPlayerOwns(CGameHandler * gh, ObjectInstanceID id)
 {

+ 0 - 27
server/StdInc.h

@@ -18,30 +18,3 @@
 #include <boost/random/variate_generator.hpp>
 #include <boost/system/system_error.hpp>
 
-template<class T, class F>
-inline const T * dynamic_ptr_cast(const F * ptr)
-{
-	#ifndef __APPLE__
-  return dynamic_cast<const T*>(ptr);
-	#else
-	if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
-	{
-		return static_cast<const T*>(ptr);
-	}
-	return nullptr;
-	#endif
-}
-
-template<class T, class F>
-inline T * dynamic_ptr_cast(F * ptr)
-{
-	#ifndef __APPLE__
-  return dynamic_cast<T*>(ptr);
-	#else
-	if (!strcmp(typeid(*ptr).name(), typeid(T).name()))
-	{
-		return static_cast<T*>(ptr);
-	}
-	return nullptr;
-	#endif
-}