瀏覽代碼

Merge branch 'develop' into SpellsRefactoring8

AlexVinS 9 年之前
父節點
當前提交
33d1895d21

+ 4 - 2
AI/VCAI/AIUtility.cpp

@@ -509,8 +509,10 @@ bool compareArtifacts(const CArtifactInstance *a1, const CArtifactInstance *a2)
 	auto art1 = a1->artType;
 	auto art2 = a2->artType;
 
-	if (art1->valOfBonuses(Bonus::PRIMARY_SKILL) > art2->valOfBonuses(Bonus::PRIMARY_SKILL))
+	if(art1->price == art2->price)
+		return art1->valOfBonuses(Bonus::PRIMARY_SKILL) > art2->valOfBonuses(Bonus::PRIMARY_SKILL);
+	else if(art1->price > art2->price)
 		return true;
 	else
-		return art1->price > art2->price;
+		return false;
 }

+ 1 - 1
AI/VCAI/Fuzzy.h

@@ -15,7 +15,7 @@
 class VCAI;
 class CArmedInstance;
 class CBank;
-class SectorMap;
+struct SectorMap;
 
 class engineBase
 {

+ 1 - 1
AI/VCAI/Goals.h

@@ -21,7 +21,7 @@ class FuzzyHelper;
 
 namespace Goals
 {
-	struct AbstractGoal;
+	class AbstractGoal;
 	class VisitTile;
 	typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal;
 	typedef std::vector<TSubgoal> TGoalVec;

+ 0 - 1
CCallback.cpp

@@ -226,7 +226,6 @@ void CCallback::trade(const CGObjectInstance *market, EMarketMode::EMarketMode m
 
 void CCallback::setFormation(const CGHeroInstance * hero, bool tight)
 {
-	const_cast<CGHeroInstance*>(hero)-> formation = tight;
 	SetFormation pack(hero->id,tight);
 	sendRequest(&pack);
 }

+ 1 - 1
client/CMT.cpp

@@ -407,7 +407,7 @@ int main(int argc, char** argv)
 			}
 		}
 
-		setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["displayIndex"].Float(), video["fullscreen"].Bool());
+		setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool(), video["displayIndex"].Float());
 		logGlobal->infoStream() <<"\tInitializing screen: "<<pomtime.getDiff();
 	}
 

+ 4 - 4
client/CPlayerInterface.cpp

@@ -529,17 +529,17 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	updateInfo(town);
 
-	if(town->garrisonHero && vstd::contains(wanderingHeroes,town->garrisonHero)) //wandering hero moved to the garrison
+	if(town->garrisonHero) //wandering hero moved to the garrison
 	{
 		CGI->mh->hideObject(town->garrisonHero);
-		if (town->garrisonHero->tempOwner == playerID) // our hero
+		if(town->garrisonHero->tempOwner == playerID && vstd::contains(wanderingHeroes,town->garrisonHero)) // our hero
 			wanderingHeroes -= town->garrisonHero;
 	}
 
-	if(town->visitingHero && !vstd::contains(wanderingHeroes,town->visitingHero)) //hero leaves garrison
+	if(town->visitingHero) //hero leaves garrison
 	{
 		CGI->mh->printObject(town->visitingHero);
-		if (town->visitingHero->tempOwner == playerID) // our hero
+		if(town->visitingHero->tempOwner == playerID && !vstd::contains(wanderingHeroes,town->visitingHero)) // our hero
 			wanderingHeroes.push_back(town->visitingHero);
 	}
 	adventureInt->heroList.update();

+ 12 - 12
client/NetPacksClient.cpp

@@ -451,19 +451,19 @@ void SetHeroesInTown::applyCl( CClient *cl )
 	CGHeroInstance *hGarr  = GS(cl)->getHero(this->garrison);
 	CGHeroInstance *hVisit = GS(cl)->getHero(this->visiting);
 
-	std::set<PlayerColor> playersToNotify;
-
-	if(vstd::contains(cl->playerint,t->tempOwner)) // our town
-		playersToNotify.insert(t->tempOwner);
-
-	if (hGarr && vstd::contains(cl->playerint,  hGarr->tempOwner))
-		playersToNotify.insert(hGarr->tempOwner);
-
-	if (hVisit && vstd::contains(cl->playerint, hVisit->tempOwner))
-		playersToNotify.insert(hVisit->tempOwner);
+	//inform all players that see this object
+	for(auto i = cl->playerint.cbegin(); i != cl->playerint.cend(); ++i)
+	{
+		if(i->first >= PlayerColor::PLAYER_LIMIT)
+			continue;
 
-	for(auto playerID : playersToNotify)
-		cl->playerint[playerID]->heroInGarrisonChange(t);
+		if(GS(cl)->isVisible(t, i->first) ||
+			(hGarr && GS(cl)->isVisible(hGarr, i->first)) ||
+			(hVisit && GS(cl)->isVisible(hVisit, i->first)))
+		{
+			cl->playerint[i->first]->heroInGarrisonChange(t);
+		}
+	}
 }
 
 // void SetHeroArtifacts::applyCl( CClient *cl )

+ 1 - 1
client/windows/CCreatureWindow.h

@@ -14,7 +14,7 @@
  *
  */
 
-class StackWindowInfo;
+struct StackWindowInfo;
 class CCommanderInstance;
 class CStackInstance;
 class CStack;

+ 8 - 1
lib/CPlayerState.h

@@ -43,7 +43,14 @@ public:
 	{
 		h & color & human & team & resources & status;
 		h & heroes & towns & availableHeroes & dwellings & quests & visitedObjects;
-		h & getBonusList(); //FIXME FIXME FIXME
+
+		if(version < 760)
+		{
+			//was: h & getBonusList();
+			BonusList junk;
+			h & junk;
+		}
+
 		h & status & daysWithoutCastle;
 		h & enteredLosingCheatCode & enteredWinningCheatCode;
 		h & static_cast<CBonusSystemNode&>(*this);

+ 1 - 1
lib/Connection.h

@@ -27,7 +27,7 @@
 #include "mapping/CCampaignHandler.h" //for CCampaignState
 #include "rmg/CMapGenerator.h" // for CMapGenOptions
 
-const ui32 version = 759;
+const ui32 version = 760;
 const ui32 minSupportedVersion = 753;
 
 class CISer;

+ 14 - 0
lib/NetPacks.h

@@ -535,6 +535,20 @@ struct UpdateCastleEvents : public CPackForClient //125
 	}
 };
 
+struct ChangeFormation : public CPackForClient //126
+{
+	ChangeFormation(){type = 126;}
+
+	ObjectInstanceID hid;
+	ui8 formation;
+
+	DLL_LINKAGE void applyGs(CGameState *gs);
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & hid & formation;
+	}
+};
+
 struct RemoveObject : public CPackForClient //500
 {
 	RemoveObject(){type = 500;};

+ 5 - 0
lib/NetPacksLib.cpp

@@ -157,6 +157,11 @@ DLL_LINKAGE void UpdateCastleEvents::applyGs(CGameState *gs)
 	t->events = events;
 }
 
+DLL_LINKAGE void ChangeFormation::applyGs(CGameState *gs)
+{
+	gs->getHero(hid)->setFormation(formation);
+}
+
 DLL_LINKAGE void HeroVisitCastle::applyGs( CGameState *gs )
 {
 	CGHeroInstance *h = gs->getHero(hid);

+ 1 - 0
lib/VCMI_lib.cbp

@@ -162,6 +162,7 @@
 		<Unit filename="CObstacleInstance.h" />
 		<Unit filename="CPathfinder.cpp" />
 		<Unit filename="CPathfinder.h" />
+		<Unit filename="CPlayerState.h" />
 		<Unit filename="CRandomGenerator.cpp" />
 		<Unit filename="CRandomGenerator.h" />
 		<Unit filename="CScriptingModule.h" />

+ 1 - 1
lib/filesystem/FileStream.cpp

@@ -272,7 +272,7 @@ zlib_filefunc64_def* FileStream::GetMinizipFilefunc()
 	return &MinizipFilefunc;
 }
 
-template class boost::iostreams::stream<FileBuf>;
+template struct boost::iostreams::stream<FileBuf>;
 
 /*static*/
 bool FileStream::CreateFile(const boost::filesystem::path& filename)

+ 1 - 1
lib/filesystem/FileStream.h

@@ -37,7 +37,7 @@ struct zlib_filefunc64_def_s;
 typedef zlib_filefunc64_def_s zlib_filefunc64_def;
 
 #ifdef VCMI_DLL
-extern template class DLL_LINKAGE boost::iostreams::stream<FileBuf>;
+extern template struct DLL_LINKAGE boost::iostreams::stream<FileBuf>;
 #endif
 
 class DLL_LINKAGE FileStream : public boost::iostreams::stream<FileBuf>

+ 6 - 1
lib/filesystem/ResourceID.cpp

@@ -38,7 +38,12 @@ static inline std::string readName(std::string name)
 {
 	const auto dotPos = name.find_last_of('.');
 
-	if (dotPos != std::string::npos)
+	//do not cut "extension" of directory name
+	auto delimPos = name.find_last_of('/');
+	if(delimPos == std::string::npos)
+		delimPos = name.find_last_of('\\');
+
+	if((delimPos == std::string::npos || delimPos < dotPos) && dotPos != std::string::npos)
 		name.resize(dotPos);
 
 	toUpper(name);

+ 4 - 4
lib/mapObjects/CObjectClassesHandler.cpp

@@ -433,11 +433,11 @@ boost::optional<std::string> AObjectTypeHandler::getCustomName() const
 	return objectName;
 }
 
-void AObjectTypeHandler::addTemplate(ObjectTemplate templ)
+void AObjectTypeHandler::addTemplate(const ObjectTemplate & templ)
 {
-	templ.id = Obj(type);
-	templ.subid = subtype;
 	templates.push_back(templ);
+	templates.back().id = Obj(type);
+	templates.back().subid = subtype;
 }
 
 void AObjectTypeHandler::addTemplate(JsonNode config)
@@ -449,7 +449,7 @@ void AObjectTypeHandler::addTemplate(JsonNode config)
 	tmpl.subid = subtype;
 	tmpl.stringID = ""; // TODO?
 	tmpl.readJson(config);
-	addTemplate(tmpl);
+	templates.push_back(tmpl);
 }
 
 std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates() const

+ 3 - 3
lib/mapObjects/CObjectClassesHandler.h

@@ -128,7 +128,7 @@ public:
 	/// Returns object-specific name, if set
 	boost::optional<std::string> getCustomName() const;
 
-	void addTemplate(ObjectTemplate templ);
+	void addTemplate(const ObjectTemplate & templ);
 	void addTemplate(JsonNode config);
 
 	/// returns all templates matching parameters
@@ -147,14 +147,14 @@ public:
 
 	/// Creates object and set up core properties (like ID/subID). Object is NOT initialized
 	/// to allow creating objects before game start (e.g. map loading)
-	virtual CGObjectInstance * create(ObjectTemplate tmpl) const = 0;
+	virtual CGObjectInstance * create(const ObjectTemplate & tmpl) const = 0;
 
 	/// Configures object properties. Should be re-entrable, resetting state of the object if necessarily
 	/// This should set remaining properties, including randomized or depending on map
 	virtual void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const = 0;
 
 	/// Returns object configuration, if available. Otherwise returns NULL
-	virtual std::unique_ptr<IObjectInfo> getObjectInfo(ObjectTemplate tmpl) const = 0;
+	virtual std::unique_ptr<IObjectInfo> getObjectInfo(const ObjectTemplate & tmpl) const = 0;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 2 - 2
lib/mapObjects/CRewardableConstructor.cpp

@@ -185,7 +185,7 @@ void CRewardableConstructor::initTypeData(const JsonNode & config)
 	objectInfo.init(config);
 }
 
-CGObjectInstance * CRewardableConstructor::create(ObjectTemplate tmpl) const
+CGObjectInstance * CRewardableConstructor::create(const ObjectTemplate & tmpl) const
 {
 	auto ret = new CRewardableObject();
 	preInitObject(ret);
@@ -198,7 +198,7 @@ void CRewardableConstructor::configureObject(CGObjectInstance * object, CRandomG
 	objectInfo.configureObject(dynamic_cast<CRewardableObject*>(object), rng);
 }
 
-std::unique_ptr<IObjectInfo> CRewardableConstructor::getObjectInfo(ObjectTemplate tmpl) const
+std::unique_ptr<IObjectInfo> CRewardableConstructor::getObjectInfo(const ObjectTemplate & tmpl) const
 {
 	return std::unique_ptr<IObjectInfo>(new CRandomRewardObjectInfo(objectInfo));
 }

+ 2 - 2
lib/mapObjects/CRewardableConstructor.h

@@ -50,9 +50,9 @@ class DLL_LINKAGE CRewardableConstructor : public AObjectTypeHandler
 public:
 	CRewardableConstructor();
 
-	CGObjectInstance * create(ObjectTemplate tmpl) const override;
+	CGObjectInstance * create(const ObjectTemplate & tmpl) const override;
 
 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
 
-	std::unique_ptr<IObjectInfo> getObjectInfo(ObjectTemplate tmpl) const override;
+	std::unique_ptr<IObjectInfo> getObjectInfo(const ObjectTemplate & tmpl) const override;
 };

+ 5 - 5
lib/mapObjects/CommonConstructors.cpp

@@ -71,7 +71,7 @@ bool CTownInstanceConstructor::objectFilter(const CGObjectInstance * object, con
 	return false;
 }
 
-CGObjectInstance * CTownInstanceConstructor::create(ObjectTemplate tmpl) const
+CGObjectInstance * CTownInstanceConstructor::create(const ObjectTemplate & tmpl) const
 {
 	CGTownInstance * obj = createTyped(tmpl);
 	obj->town = faction->town;
@@ -126,7 +126,7 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, con
 	return false;
 }
 
-CGObjectInstance * CHeroInstanceConstructor::create(ObjectTemplate tmpl) const
+CGObjectInstance * CHeroInstanceConstructor::create(const ObjectTemplate & tmpl) const
 {
 	CGHeroInstance * obj = createTyped(tmpl);
 	obj->type = nullptr; //FIXME: set to valid value. somehow.
@@ -169,7 +169,7 @@ bool CDwellingInstanceConstructor::objectFilter(const CGObjectInstance *, const
 	return false;
 }
 
-CGObjectInstance * CDwellingInstanceConstructor::create(ObjectTemplate tmpl) const
+CGObjectInstance * CDwellingInstanceConstructor::create(const ObjectTemplate & tmpl) const
 {
 	CGDwelling * obj = createTyped(tmpl);
 
@@ -267,7 +267,7 @@ void CBankInstanceConstructor::initTypeData(const JsonNode & input)
 	bankResetDuration = input["resetDuration"].Float();
 }
 
-CGObjectInstance *CBankInstanceConstructor::create(ObjectTemplate tmpl) const
+CGObjectInstance *CBankInstanceConstructor::create(const ObjectTemplate & tmpl) const
 {
 	return createTyped(tmpl);
 }
@@ -448,7 +448,7 @@ bool CBankInfo::givesSpells() const
 }
 
 
-std::unique_ptr<IObjectInfo> CBankInstanceConstructor::getObjectInfo(ObjectTemplate tmpl) const
+std::unique_ptr<IObjectInfo> CBankInstanceConstructor::getObjectInfo(const ObjectTemplate & tmpl) const
 {
 	return std::unique_ptr<IObjectInfo>(new CBankInfo(levels));
 }

+ 8 - 8
lib/mapObjects/CommonConstructors.h

@@ -29,7 +29,7 @@ template<class ObjectType>
 class CDefaultObjectTypeHandler : public AObjectTypeHandler
 {
 protected:
-	ObjectType * createTyped(ObjectTemplate tmpl) const
+	ObjectType * createTyped(const ObjectTemplate & tmpl) const
 	{
 		auto obj = new ObjectType();
 		preInitObject(obj);
@@ -39,7 +39,7 @@ protected:
 public:
 	CDefaultObjectTypeHandler(){}
 
-	CGObjectInstance * create(ObjectTemplate tmpl) const override
+	CGObjectInstance * create(const ObjectTemplate & tmpl) const override
 	{
 		return createTyped(tmpl);
 	}
@@ -48,7 +48,7 @@ public:
 	{
 	}
 
-	virtual std::unique_ptr<IObjectInfo> getObjectInfo(ObjectTemplate tmpl) const override
+	virtual std::unique_ptr<IObjectInfo> getObjectInfo(const ObjectTemplate & tmpl) const override
 	{
 		return nullptr;
 	}
@@ -73,7 +73,7 @@ public:
 	std::map<std::string, LogicalExpression<BuildingID>> filters;
 
 	CTownInstanceConstructor();
-	CGObjectInstance * create(ObjectTemplate tmpl) const override;
+	CGObjectInstance * create(const ObjectTemplate & tmpl) const override;
 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
 	void afterLoadFinalization() override;
 
@@ -96,7 +96,7 @@ public:
 	std::map<std::string, LogicalExpression<HeroTypeID>> filters;
 
 	CHeroInstanceConstructor();
-	CGObjectInstance * create(ObjectTemplate tmpl) const override;
+	CGObjectInstance * create(const ObjectTemplate & tmpl) const override;
 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
 	void afterLoadFinalization() override;
 
@@ -120,7 +120,7 @@ protected:
 public:
 
 	CDwellingInstanceConstructor();
-	CGObjectInstance * create(ObjectTemplate tmpl) const override;
+	CGObjectInstance * create(const ObjectTemplate & tmpl) const override;
 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
 
 	bool producesCreature(const CCreature * crea) const;
@@ -186,10 +186,10 @@ public:
 
 	CBankInstanceConstructor();
 
-	CGObjectInstance *create(ObjectTemplate tmpl) const override;
+	CGObjectInstance * create(const ObjectTemplate & tmpl) const override;
 	void configureObject(CGObjectInstance * object, CRandomGenerator & rng) const override;
 
-	std::unique_ptr<IObjectInfo> getObjectInfo(ObjectTemplate tmpl) const override;
+	std::unique_ptr<IObjectInfo> getObjectInfo(const ObjectTemplate & tmpl) const override;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 2 - 2
lib/mapObjects/JsonRandom.h

@@ -17,8 +17,8 @@ class JsonNode;
 typedef std::vector<JsonNode> JsonVector;
 class CRandomGenerator;
 
-class Bonus;
-class Component;
+struct Bonus;
+struct Component;
 class CStackBasicDescriptor;
 
 namespace JsonRandom

+ 31 - 0
lib/mapObjects/ObjectTemplate.cpp

@@ -58,6 +58,37 @@ ObjectTemplate::ObjectTemplate():
 {
 }
 
+ObjectTemplate::ObjectTemplate(const ObjectTemplate& other):
+	visitDir(other.visitDir),
+	allowedTerrains(other.allowedTerrains),
+	id(other.id),
+	subid(other.subid),
+	printPriority(other.printPriority),
+	animationFile(other.animationFile)
+{
+	//default copy constructor is failing with usedTiles this for unknown reason
+
+	usedTiles.resize(other.usedTiles.size());
+	for(size_t i = 0; i < usedTiles.size(); i++)
+		std::copy(other.usedTiles[i].begin(), other.usedTiles[i].end(), std::back_inserter(usedTiles[i]));
+}
+
+ObjectTemplate & ObjectTemplate::operator=(const ObjectTemplate & rhs)
+{
+	visitDir = rhs.visitDir;
+	allowedTerrains = rhs.allowedTerrains;
+	id = rhs.id;
+	subid = rhs.subid;
+	printPriority = rhs.printPriority;
+	animationFile = rhs.animationFile;
+
+	usedTiles.clear();
+	usedTiles.resize(rhs.usedTiles.size());
+	for(size_t i = 0; i < usedTiles.size(); i++)
+		std::copy(rhs.usedTiles[i].begin(), rhs.usedTiles[i].end(), std::back_inserter(usedTiles[i]));
+	return *this;
+}
+
 void ObjectTemplate::readTxt(CLegacyConfigParser & parser)
 {
 	std::string data = parser.readString();

+ 4 - 0
lib/mapObjects/ObjectTemplate.h

@@ -69,6 +69,10 @@ public:
 	bool canBePlacedAt(ETerrainType terrain) const;
 
 	ObjectTemplate();
+	//custom copy constructor is required
+	ObjectTemplate(const ObjectTemplate & other);
+
+	ObjectTemplate& operator=(const ObjectTemplate & rhs);
 
 	void readTxt(CLegacyConfigParser & parser);
 	void readMsk();

+ 31 - 16
lib/mapping/CMap.cpp

@@ -556,16 +556,9 @@ void CMap::eraseArtifactInstance(CArtifactInstance * art)
 	artInstances[art->id.getNum()].dellNull();
 }
 
-void CMap::addQuest(CGObjectInstance * quest)
-{
-	auto q = dynamic_cast<IQuestObject *>(quest);
-	q->quest->qid = quests.size();
-	quests.push_back(q->quest);
-}
-
 void CMap::addNewObject(CGObjectInstance * obj)
 {
-    if(obj->id != ObjectInstanceID(objects.size()))
+	if(obj->id != ObjectInstanceID(objects.size()))
 		throw std::runtime_error("Invalid object instance id");
 
 	if(obj->instanceName == "")
@@ -573,19 +566,41 @@ void CMap::addNewObject(CGObjectInstance * obj)
 
 	auto it = instanceNames.find(obj->instanceName);
 	if(it != instanceNames.end())
-		throw std::runtime_error("Object instance name duplicated:"+obj->instanceName);
+		throw std::runtime_error("Object instance name duplicated: "+obj->instanceName);
 
-    objects.push_back(obj);
-    instanceNames[obj->instanceName] = obj;
-    addBlockVisTiles(obj);
+	objects.push_back(obj);
+	instanceNames[obj->instanceName] = obj;
+	addBlockVisTiles(obj);
 
-	if(obj->ID == Obj::TOWN)
+	//todo: make this virtual method of CGObjectInstance
+	switch (obj->ID)
 	{
+	case Obj::TOWN:
 		towns.push_back(static_cast<CGTownInstance *>(obj));
-	}
-	if(obj->ID == Obj::HERO)
-	{
+		break;
+	case Obj::HERO:
 		heroesOnMap.push_back(static_cast<CGHeroInstance*>(obj));
+		break;
+	case Obj::SEER_HUT:
+	case Obj::QUEST_GUARD:
+	case Obj::BORDERGUARD:
+	case Obj::BORDER_GATE:
+		{
+			auto q = dynamic_cast<IQuestObject *>(obj);
+			q->quest->qid = quests.size();
+			quests.push_back(q->quest);
+		}
+		break;
+	case Obj::SPELL_SCROLL:
+		{
+			CGArtifact * art = dynamic_cast<CGArtifact *>(obj);
+
+			if(art->storedArtifact && art->storedArtifact->id.getNum() < 0)
+				addNewArtifactInstance(art->storedArtifact);
+		}
+		break;
+	default:
+		break;
 	}
 }
 

+ 1 - 1
lib/mapping/CMap.h

@@ -313,7 +313,7 @@ public:
 
 	void addNewArtifactInstance(CArtifactInstance * art);
 	void eraseArtifactInstance(CArtifactInstance * art);
-	void addQuest(CGObjectInstance * quest);
+
 	void addNewObject(CGObjectInstance * obj);
 
 	/// Gets object of specified type on requested position

+ 0 - 4
lib/mapping/MapFormatH3M.cpp

@@ -1112,7 +1112,6 @@ void CMapLoaderH3M::readObjects()
 		case Obj::SEER_HUT:
 			{
 				nobj = readSeerHut();
-				map->addQuest(nobj);
 				break;
 			}
 		case Obj::WITCH_HUT:
@@ -1363,7 +1362,6 @@ void CMapLoaderH3M::readObjects()
 		case Obj::QUEST_GUARD:
 			{
 				auto  guard = new CGQuestGuard();
-				map->addQuest(guard);
 				readQuest(guard);
 				nobj = guard;
 				break;
@@ -1400,13 +1398,11 @@ void CMapLoaderH3M::readObjects()
 		case Obj::BORDERGUARD:
 			{
 				nobj = new CGBorderGuard();
-				map->addQuest(nobj);
 				break;
 			}
 		case Obj::BORDER_GATE:
 			{
 				nobj = new CGBorderGate();
-				map->addQuest (nobj);
 				break;
 			}
 		case Obj::PYRAMID: //Pyramid of WoG object

+ 1 - 1
lib/mapping/MapFormatJson.h

@@ -17,7 +17,7 @@
 #include "../filesystem/CZipLoader.h"
 #include "../GameConstants.h"
 
-class TriggeredEvent;
+struct TriggeredEvent;
 struct TerrainTile;
 struct PlayerInfo;
 class CGObjectInstance;

+ 1 - 0
lib/registerTypes/RegisterTypes.h

@@ -227,6 +227,7 @@ void registerTypesClientPacks1(Serializer &s)
 	s.template registerType<CPackForClient, UpdateArtHandlerLists>();
 	s.template registerType<CPackForClient, UpdateMapEvents>();
 	s.template registerType<CPackForClient, UpdateCastleEvents>();
+	s.template registerType<CPackForClient, ChangeFormation>();
 	s.template registerType<CPackForClient, RemoveObject>();
 	s.template registerType<CPackForClient, TryMoveHero>();
 	//s.template registerType<CPackForClient, SetGarrisons>();

+ 2 - 6
lib/rmg/CRmgTemplateZone.cpp

@@ -451,7 +451,7 @@ void CRmgTemplateZone::createBorder(CMapGenerator* gen)
 					if (gen->isPossible(nearbyPos))
 						gen->setOccupied(nearbyPos, ETileType::BLOCKED);
 				});
-				edge = true; 
+				edge = true;
 			}
 		});
 	}
@@ -2328,7 +2328,7 @@ ObjectInfo CRmgTemplateZone::getRandomObject(CMapGenerator* gen, CTreasurePileIn
 				continue;
 
 			total += oi.probability;
-			
+
 			thresholds.push_back (std::make_pair (total, &oi));
 		}
 	}
@@ -2522,7 +2522,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
 				}
 			}
 			auto a = CArtifactInstance::createScroll(RandomGeneratorUtil::nextItem(out, gen->rand)->toSpell());
-			gen->map->addNewArtifactInstance(a);
 			obj->storedArtifact = a;
 			return obj;
 		};
@@ -2760,7 +2759,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
 				obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
 
 				gen->banQuestArt(artid);
-				gen->map->addQuest(obj);
 
 				this->questArtZone->possibleObjects.push_back (generateArtInfo(artid));
 
@@ -2799,7 +2797,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
 				obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
 
 				gen->banQuestArt(artid);
-				gen->map->addQuest(obj);
 
 				this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));
 
@@ -2823,7 +2820,6 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
 				obj->quest->isCustomFirst = obj->quest->isCustomNext = obj->quest->isCustomComplete = false;
 
 				gen->banQuestArt(artid);
-				gen->map->addQuest(obj);
 
 				this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));
 

+ 16 - 5
server/CGameHandler.cpp

@@ -1913,7 +1913,7 @@ void CGameHandler::giveSpells(const CGTownInstance *t, const CGHeroInstance *h)
 
 void CGameHandler::setBlockVis(ObjectInstanceID objid, bool bv)
 {
-	SetObjectProperty sop(objid,2,bv);
+	SetObjectProperty sop(objid, ObjProperty::BLOCKVIS, bv);
 	sendAndApply(&sop);
 }
 
@@ -1935,7 +1935,7 @@ bool CGameHandler::removeObject( const CGObjectInstance * obj )
 
 void CGameHandler::setAmount(ObjectInstanceID objid, ui32 val)
 {
-	SetObjectProperty sop(objid,3,val);
+	SetObjectProperty sop(objid, ObjProperty::PRIMARY_STACK_COUNT, val);
 	sendAndApply(&sop);
 }
 
@@ -2151,7 +2151,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
 void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner)
 {
 	PlayerColor oldOwner = getOwner(obj->id);
-	SetObjectProperty sop(obj->id, 1, owner.getNum());
+	SetObjectProperty sop(obj->id, ObjProperty::OWNER, owner.getNum());
 	sendAndApply(&sop);
 
 	std::set<PlayerColor> playerColors = {owner, oldOwner};
@@ -3501,9 +3501,20 @@ bool CGameHandler::sendResources(ui32 val, PlayerColor player, Res::ERes r1, Pla
 	return true;
 }
 
-bool CGameHandler::setFormation( ObjectInstanceID hid, ui8 formation )
+bool CGameHandler::setFormation(ObjectInstanceID hid, ui8 formation)
 {
-	gs->getHero(hid)-> formation = formation;
+	const CGHeroInstance *h = getHero(hid);
+	if(!h)
+	{
+		logGlobal->error("Hero doesn't exist!");
+		return false;
+	}
+
+	ChangeFormation cf;
+	cf.hid = hid;
+	cf.formation = formation;
+	sendAndApply(&cf);
+
 	return true;
 }