From 91336b346a4e78c57fe996a00b43b9e70b6c6c65 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Sun, 15 Jun 2014 21:23:32 +0200 Subject: [PATCH 01/39] Placing towns according to template. --- config/rmg.json | 2 +- lib/rmg/CRmgTemplateZone.cpp | 90 ++++++++++++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/config/rmg.json b/config/rmg.json index 3913cd385..9df21b1b8 100644 --- a/config/rmg.json +++ b/config/rmg.json @@ -290,7 +290,7 @@ "5" : { "type" : "treasure", "size" : 40, - "neutralTowns" : { "towns" : 2 }, + "neutralTowns" : { "castles" : 2 }, "terrainTypes" : [ "sand" ], "matchTerrainToTown" : false, "monsters" : "strong", "mines" : {"gold" : 4}, diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index 35bd43f42..c8a9dacb2 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -710,28 +710,35 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos) } void CRmgTemplateZone::initTownType (CMapGenerator* gen) { + + //FIXME: handle case that this player is not present -> towns should be set to neutral + int totalTowns = 0; + if ((type == ETemplateZoneType::CPU_START) || (type == ETemplateZoneType::PLAYER_START)) { + //set zone types to player faction, generate main town logGlobal->infoStream() << "Preparing playing zone"; int player_id = *owner - 1; auto & playerInfo = gen->map->players[player_id]; if (playerInfo.canAnyonePlay()) { PlayerColor player(player_id); - auto town = new CGTownInstance(); - town->ID = Obj::TOWN; townType = gen->mapGenOptions->getPlayersSettings().find(player)->second.getStartingTown(); if(townType == CMapGenOptions::CPlayerSettings::RANDOM_TOWN) townType = *RandomGeneratorUtil::nextItem(VLC->townh->getAllowedFactions(), gen->rand); // all possible towns, skip neutral + + auto town = new CGTownInstance(); + town->ID = Obj::TOWN; town->subID = townType; town->tempOwner = player; town->builtBuildings.insert(BuildingID::FORT); town->builtBuildings.insert(BuildingID::DEFAULT); - placeObject(gen, town, getPos() + town->getVisitableOffset()); //towns are big objects and should be centered around visitable position + totalTowns++; + logGlobal->traceStream() << "Fill player info " << player_id; // Update player info @@ -741,6 +748,42 @@ void CRmgTemplateZone::initTownType (CMapGenerator* gen) playerInfo.posOfMainTown = town->pos - int3(2, 0, 0); playerInfo.generateHeroAtMainTown = true; + //now create actual towns + for (int i = 1; i < playerTowns.getCastleCount(); i++) + { + auto town = new CGTownInstance(); + town->ID = Obj::TOWN; + + if (townsAreSameType) + town->subID = townType; + else + town->subID = *RandomGeneratorUtil::nextItem(VLC->townh->getAllowedFactions(), gen->rand); //TODO: check allowed town types for this zone + + town->tempOwner = player; + town->builtBuildings.insert(BuildingID::FORT); + town->builtBuildings.insert(BuildingID::DEFAULT); + + addRequiredObject (town); + totalTowns++; + } + + for (int i = 0; i < playerTowns.getTownCount(); i++) + { + auto town = new CGTownInstance(); + town->ID = Obj::TOWN; + + if (townsAreSameType) + town->subID = townType; + else + town->subID = *RandomGeneratorUtil::nextItem(VLC->townh->getAllowedFactions(), gen->rand); //TODO: check allowed town types for this zone + + town->tempOwner = player; + town->builtBuildings.insert(BuildingID::DEFAULT); + + addRequiredObject (town); + totalTowns++; + } + //requiredObjects.push_back(town); } else @@ -754,6 +797,47 @@ void CRmgTemplateZone::initTownType (CMapGenerator* gen) { townType = *RandomGeneratorUtil::nextItem(VLC->townh->getAllowedFactions(), gen->rand); } + + for (int i = 0; i < neutralTowns.getCastleCount(); i++) + { + auto town = new CGTownInstance(); + town->ID = Obj::TOWN; + + if (townsAreSameType || totalTowns == 0) //first town must match zone type + town->subID = townType; + else + town->subID = *RandomGeneratorUtil::nextItem(VLC->townh->getAllowedFactions(), gen->rand); //TODO: check allowed town types for this zone + + town->tempOwner = PlayerColor::NEUTRAL; + town->builtBuildings.insert(BuildingID::FORT); + town->builtBuildings.insert(BuildingID::DEFAULT); + + if (!totalTowns) //first town in zone goes in the middle + placeObject(gen, town, getPos() + town->getVisitableOffset()); + else + addRequiredObject (town); + totalTowns++; + } + + for (int i = 0; i < neutralTowns.getTownCount(); i++) + { + auto town = new CGTownInstance(); + town->ID = Obj::TOWN; + + if (townsAreSameType || totalTowns == 0) + town->subID = townType; + else + town->subID = *RandomGeneratorUtil::nextItem(VLC->townh->getAllowedFactions(), gen->rand); //TODO: check allowed town types for this zone + + town->tempOwner = PlayerColor::NEUTRAL; + town->builtBuildings.insert(BuildingID::DEFAULT); + + if (!totalTowns) + placeObject(gen, town, getPos() + town->getVisitableOffset()); + else + addRequiredObject (town); + totalTowns++; + } } void CRmgTemplateZone::initTerrainType (CMapGenerator* gen) From f84e25fa786f8a7e0b9bc4a79019324724753d7a Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Wed, 18 Jun 2014 09:57:36 +0200 Subject: [PATCH 02/39] Somewhat better algorithm for paths, helps balance object distribution. --- lib/int3.h | 20 +++++++++++++++++++- lib/rmg/CMapGenerator.cpp | 4 ++-- lib/rmg/CRmgTemplateZone.cpp | 10 ++++++++-- lib/rmg/CRmgTemplateZone.h | 3 ++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lib/int3.h b/lib/int3.h index b094654d8..41a8dd908 100644 --- a/lib/int3.h +++ b/lib/int3.h @@ -155,4 +155,22 @@ struct ShashInt3 }; static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0), - int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) }; \ No newline at end of file + int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) }; + +//FIXME: make sure it's container and not just any +template +int3 findClosestTile (Container & container, int3 dest) +{ + int3 result(-1,-1,-1); + ui32 distance = std::numeric_limits::max(); + for (int3 tile : container) + { + ui32 currentDistance = dest.dist2dSQ(tile); + if (currentDistance < distance) + { + result = tile; + distance = currentDistance; + } + } + return result; +} \ No newline at end of file diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index cf2c65636..23b9242f0 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -253,8 +253,8 @@ void CMapGenerator::createConnections() setOccupied (guardPos, ETileType::FREE); //just in case monster is too weak to spawn zoneA->addMonster (this, guardPos, connection.getGuardStrength()); //TODO: set value according to template //zones can make paths only in their own area - zoneA->crunchPath (this, guardPos, zoneA->getPos(), zoneA->getId()); //make connection towards our zone center - zoneB->crunchPath (this, guardPos, zoneB->getPos(), zoneB->getId()); //make connection towards other zone center + zoneA->crunchPath (this, guardPos, zoneA->getPos(), zoneA->getId(), zoneA->getFreePaths()); //make connection towards our zone center + zoneB->crunchPath (this, guardPos, zoneB->getPos(), zoneB->getId(), zoneB->getFreePaths()); //make connection towards other zone center break; //we're done with this connection } } diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index c8a9dacb2..f1d969bde 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -313,7 +313,6 @@ void CRmgTemplateZone::setCenter(const float3 &f) center = float3 (std::min(std::max(f.x, 0.f), 1.f), std::min(std::max(f.y, 0.f), 1.f), f.z); } - bool CRmgTemplateZone::pointIsIn(int x, int y) { return true; @@ -338,6 +337,11 @@ std::set CRmgTemplateZone::getTileInfo () const return tileinfo; } +std::set* CRmgTemplateZone::getFreePaths() +{ + return &freePaths; +} + void CRmgTemplateZone::createBorder(CMapGenerator* gen) { for (auto tile : tileinfo) @@ -651,6 +655,7 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos) int3 zoneCenter = getPos(); int3 closestTile = int3(-1,-1,-1); float minDistance = 1e10; + for (auto treasure : treasures) { if (zoneCenter.dist2d(treasure.first) < minDistance) @@ -1180,8 +1185,9 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object, for (auto tile : tiles) { //crunching path may fail if center of teh zone is dirrectly over wide object - if (crunchPath (gen, tile, getPos(), id)) //make sure object is accessible before surrounding it with blocked tiles + if (crunchPath (gen, tile, findClosestTile(freePaths, tile), id, &freePaths)) //required objects will contitute our core free paths { + //make sure object is accessible before surrounding it with blocked tiles guardTile = tile; break; } diff --git a/lib/rmg/CRmgTemplateZone.h b/lib/rmg/CRmgTemplateZone.h index 2ebd79589..3eb277b94 100644 --- a/lib/rmg/CRmgTemplateZone.h +++ b/lib/rmg/CRmgTemplateZone.h @@ -149,6 +149,7 @@ public: std::vector getConnections() const; void addTreasureInfo(CTreasureInfo & info); std::vector getTreasureInfo(); + std::set* getFreePaths(); ObjectInfo getRandomObject (CMapGenerator* gen, ui32 value); @@ -182,7 +183,7 @@ private: float3 center; std::set tileinfo; //irregular area assined to zone std::vector connections; //list of adjacent zones - std::map alreadyConnected; //TODO: allow multiple connections between two zones? + std::set freePaths; //core paths of free tiles that all other objects will be linked to bool pointIsIn(int x, int y); void addAllPossibleObjects (CMapGenerator* gen); //add objects, including zone-specific, to possibleObjects From d3134a12900d18c72c91d645df07c3803f0c15a4 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Wed, 18 Jun 2014 10:31:08 +0200 Subject: [PATCH 03/39] Add free tiles around unguarded objects. --- lib/rmg/CRmgTemplateZone.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index f1d969bde..980886802 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -1208,8 +1208,14 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object, gen->setOccupied (guardTile, ETileType::USED); } - else - gen->setOccupied (guardTile, ETileType::FREE); + else //make sure no other stuff spawns next to unguarded object + { + for (auto tile : tiles) + { + if (!gen->isBlocked(tile)) + gen->setOccupied (tile, ETileType::FREE); + } + } return true; } From 79036484dd1268c870b2d97a89f6bb0a28d56af6 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Mon, 23 Jun 2014 19:58:19 +0200 Subject: [PATCH 04/39] Trying to sort out project changes and compile issues. --- client/VCMI_client.vcxproj | 1 - client/VCMI_client.vcxproj.filters | 1 - lib/VCMI_lib.vcxproj | 38 +++++++-- lib/VCMI_lib.vcxproj.filters | 104 +++++++++++++++++++++-- lib/mapObjects/CArmedInstance.cpp | 2 +- lib/mapObjects/CArmedInstance.h | 2 +- lib/mapObjects/CBank.cpp | 2 +- lib/mapObjects/CBank.h | 2 +- lib/mapObjects/CGHeroInstance.cpp | 2 +- lib/mapObjects/CGHeroInstance.h | 2 +- lib/mapObjects/CGMarket.cpp | 2 +- lib/mapObjects/CGMarket.h | 2 +- lib/mapObjects/CGPandoraBox.cpp | 2 +- lib/mapObjects/CGPandoraBox.h | 2 +- lib/mapObjects/CGTownInstance.cpp | 2 +- lib/mapObjects/CGTownInstance.h | 2 +- lib/mapObjects/CObjectClassesHandler.cpp | 4 +- lib/mapObjects/CObjectClassesHandler.h | 4 +- lib/mapObjects/CObjectHandler.cpp | 2 +- lib/mapObjects/CObjectHandler.h | 2 +- lib/mapObjects/ObjectTemplate.cpp | 2 +- lib/rmg/CRmgTemplateZone.cpp | 3 + scripting/erm/ERMInterpreter.cpp | 3 +- 23 files changed, 152 insertions(+), 36 deletions(-) diff --git a/client/VCMI_client.vcxproj b/client/VCMI_client.vcxproj index 6bc9b673d..7b1226997 100644 --- a/client/VCMI_client.vcxproj +++ b/client/VCMI_client.vcxproj @@ -229,7 +229,6 @@ - diff --git a/client/VCMI_client.vcxproj.filters b/client/VCMI_client.vcxproj.filters index 89dd439e0..ab9f794a4 100644 --- a/client/VCMI_client.vcxproj.filters +++ b/client/VCMI_client.vcxproj.filters @@ -78,7 +78,6 @@ - diff --git a/lib/VCMI_lib.vcxproj b/lib/VCMI_lib.vcxproj index 18e150ee1..2cad8a718 100644 --- a/lib/VCMI_lib.vcxproj +++ b/lib/VCMI_lib.vcxproj @@ -135,8 +135,7 @@ - /Oy- %(AdditionalOptions) /bigobj - /Zm150 + /Oy- /bigobj /Zm150 VCMI_DLL;%(PreprocessorDefinitions) StdInc.h Use @@ -177,13 +176,11 @@ - - @@ -204,6 +201,21 @@ + + + + + + + + + + + + + + + @@ -259,13 +271,11 @@ - - @@ -293,6 +303,22 @@ + + + + + + + + + + + + + + + + diff --git a/lib/VCMI_lib.vcxproj.filters b/lib/VCMI_lib.vcxproj.filters index 4650865c0..2bc0e6327 100644 --- a/lib/VCMI_lib.vcxproj.filters +++ b/lib/VCMI_lib.vcxproj.filters @@ -23,6 +23,9 @@ {927d9b6e-3dc5-4370-b603-1b9887095509} + + {ee24c7f7-f4e2-4d35-b994-94a6e29ea92f} + @@ -30,10 +33,8 @@ - - @@ -157,6 +158,51 @@ + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + @@ -201,18 +247,12 @@ Header Files - - Header Files - Header Files Header Files - - Header Files - Header Files @@ -399,5 +439,53 @@ rmg + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + + + mapObjects + \ No newline at end of file diff --git a/lib/mapObjects/CArmedInstance.cpp b/lib/mapObjects/CArmedInstance.cpp index 050c10f38..72be9775f 100644 --- a/lib/mapObjects/CArmedInstance.cpp +++ b/lib/mapObjects/CArmedInstance.cpp @@ -1,4 +1,4 @@ -/* +/* * CArmedInstance.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder diff --git a/lib/mapObjects/CArmedInstance.h b/lib/mapObjects/CArmedInstance.h index f85b8a07e..bb771fc4e 100644 --- a/lib/mapObjects/CArmedInstance.h +++ b/lib/mapObjects/CArmedInstance.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "CObjectHandler.h" #include "../CCreatureSet.h" diff --git a/lib/mapObjects/CBank.cpp b/lib/mapObjects/CBank.cpp index 8f4f52582..1c74a4fad 100644 --- a/lib/mapObjects/CBank.cpp +++ b/lib/mapObjects/CBank.cpp @@ -1,4 +1,4 @@ -/* +/* * CBank.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder diff --git a/lib/mapObjects/CBank.h b/lib/mapObjects/CBank.h index c8f8471aa..a08cb9874 100644 --- a/lib/mapObjects/CBank.h +++ b/lib/mapObjects/CBank.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "CObjectHandler.h" #include "CArmedInstance.h" diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 61e5da8c5..20fe4e870 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -1,4 +1,4 @@ -/* +/* * CGHeroInstance.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index 327c0725b..602342a20 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "CObjectHandler.h" #include "CArmedInstance.h" diff --git a/lib/mapObjects/CGMarket.cpp b/lib/mapObjects/CGMarket.cpp index 98205974e..4968f9594 100644 --- a/lib/mapObjects/CGMarket.cpp +++ b/lib/mapObjects/CGMarket.cpp @@ -1,4 +1,4 @@ -/* +/* * * CGMarket.cpp, part of VCMI engine * diff --git a/lib/mapObjects/CGMarket.h b/lib/mapObjects/CGMarket.h index 8f010a705..8858c3a66 100644 --- a/lib/mapObjects/CGMarket.h +++ b/lib/mapObjects/CGMarket.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "CObjectHandler.h" diff --git a/lib/mapObjects/CGPandoraBox.cpp b/lib/mapObjects/CGPandoraBox.cpp index 8f102e0a0..ed368c63c 100644 --- a/lib/mapObjects/CGPandoraBox.cpp +++ b/lib/mapObjects/CGPandoraBox.cpp @@ -1,4 +1,4 @@ -/* +/* * CGPandoraBox.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder diff --git a/lib/mapObjects/CGPandoraBox.h b/lib/mapObjects/CGPandoraBox.h index 227615cdf..828ce4697 100644 --- a/lib/mapObjects/CGPandoraBox.h +++ b/lib/mapObjects/CGPandoraBox.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "CObjectHandler.h" #include "CArmedInstance.h" diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index ed7d51c84..89a0edba6 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -1,4 +1,4 @@ -/* +/* * CGTownInstance.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index fda070a30..1b56fc99b 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "CObjectHandler.h" #include "CGMarket.h" // For IMarket interface diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index 122068eb6..b02d8c174 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -1,9 +1,9 @@ -#include "StdInc.h" +#include "StdInc.h" #include "CObjectClassesHandler.h" #include "../filesystem/Filesystem.h" #include "../filesystem/CBinaryReader.h" -#include "../lib/VCMI_Lib.h" +#include "../VCMI_Lib.h" #include "../GameConstants.h" #include "../StringConstants.h" #include "../CGeneralTextHandler.h" diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index 413deea9e..0d7bed369 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "ObjectTemplate.h" @@ -93,7 +93,7 @@ public: class CGObjectInstance; -class AObjectTypeHandler : public boost::noncopyable +class DLL_EXPORT AObjectTypeHandler : public boost::noncopyable { RandomMapInfo rmgInfo; diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index bdc06a286..a74eaaf74 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -1,4 +1,4 @@ -/* +/* * CObjectHandler.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder diff --git a/lib/mapObjects/CObjectHandler.h b/lib/mapObjects/CObjectHandler.h index e1031a123..b340ac919 100644 --- a/lib/mapObjects/CObjectHandler.h +++ b/lib/mapObjects/CObjectHandler.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "ObjectTemplate.h" diff --git a/lib/mapObjects/ObjectTemplate.cpp b/lib/mapObjects/ObjectTemplate.cpp index 6cec38ba1..fd17e9810 100644 --- a/lib/mapObjects/ObjectTemplate.cpp +++ b/lib/mapObjects/ObjectTemplate.cpp @@ -3,7 +3,7 @@ #include "../filesystem/Filesystem.h" #include "../filesystem/CBinaryReader.h" -#include "../lib/VCMI_Lib.h" +#include "../VCMI_Lib.h" #include "../GameConstants.h" #include "../StringConstants.h" #include "../CGeneralTextHandler.h" diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index bdc6bcb4e..b8824ba9a 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -20,6 +20,9 @@ #include "../CSpellHandler.h" //for choosing random spells #include "../mapObjects/CObjectClassesHandler.h" +//#include "../mapObjects/CGPandoraBox.h" +//#include "../mapObjects/CRewardableObject.h" +#include "../mapObjects/MapObjects.h" class CMap; class CMapEditManager; diff --git a/scripting/erm/ERMInterpreter.cpp b/scripting/erm/ERMInterpreter.cpp index e769ddc14..8abd3096d 100644 --- a/scripting/erm/ERMInterpreter.cpp +++ b/scripting/erm/ERMInterpreter.cpp @@ -2,7 +2,8 @@ #include "ERMInterpreter.h" #include -#include "../../lib/CObjectHandler.h" +#include "../../lib/mapObjects/CObjectHandler.h" +#include "../../lib/mapObjects/MapObjects.h" #include "../../lib/CHeroHandler.h" #include "../../lib/CCreatureHandler.h" #include "../../lib/VCMIDirs.h" From 5ebc0e8614ddd77243d32cea06905a823c3ccd94 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 24 Jun 2014 02:26:36 +0300 Subject: [PATCH 05/39] First part of object instance API cleanup - removed passability() method in favour of passableFor(PlayerColor) - moved operator < code to map handler - updated class documentation --- client/CPlayerInterface.cpp | 92 +++++++++++++++---------------- client/mapHandler.cpp | 43 +++++++++------ client/mapHandler.h | 2 + lib/mapObjects/CGHeroInstance.cpp | 4 +- lib/mapObjects/CGHeroInstance.h | 2 +- lib/mapObjects/CGTownInstance.cpp | 19 +++---- lib/mapObjects/CGTownInstance.h | 4 +- lib/mapObjects/CObjectHandler.cpp | 39 +------------ lib/mapObjects/CObjectHandler.h | 75 +++++++++++++++++-------- lib/mapObjects/CQuest.cpp | 7 +-- lib/mapObjects/CQuest.h | 2 +- lib/mapObjects/MiscObjects.cpp | 17 +++--- lib/mapObjects/MiscObjects.h | 2 +- 13 files changed, 151 insertions(+), 157 deletions(-) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 68d53d1ca..5654b867e 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -91,16 +91,10 @@ CondSh stillMoveHero; //used during hero movement int CPlayerInterface::howManyPeople = 0; - -struct OCM_HLP_CGIN +static bool objectBlitOrderSorter(const std::pair & a, const std::pair & b) { - bool inline operator ()(const std::pair & a, const std::pair & b) const - { - return (*a.first)<(*b.first); - } -} ocmptwo_cgin ; - - + return CMapHandler::compareObjectBlitOrder(a.first, b.first); +} CPlayerInterface::CPlayerInterface(PlayerColor Player) { @@ -1708,14 +1702,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 33, 33), ho->id); subRect(hp.x, hp.y, hp.z, genRect(32, 32, 65, 33), ho->id); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), objectBlitOrderSorter); } else if(details.end.x == details.start.x && details.end.y+1 == details.start.y) //t { @@ -1733,9 +1727,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 32, 33), ho->id); subRect(hp.x, hp.y, hp.z, genRect(32, 32, 64, 33), ho->id); - std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); } else if(details.end.x-1 == details.start.x && details.end.y+1 == details.start.y) //tr { @@ -1756,14 +1750,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns subRect(hp.x, hp.y, hp.z, genRect(32, 32, 63, 33), ho->id); CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 95, 33))); - std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-2][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), objectBlitOrderSorter); } else if(details.end.x-1 == details.start.x && details.end.y == details.start.y) //r { @@ -1779,9 +1773,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns subRect(hp.x, hp.y, hp.z, genRect(32, 32, 63, 32), ho->id); CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 95, 32))); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), objectBlitOrderSorter); } else if(details.end.x-1 == details.start.x && details.end.y-1 == details.start.y) //br { @@ -1802,14 +1796,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 63, 63))); CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 95, 63))); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x+1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); } else if(details.end.x == details.start.x && details.end.y-1 == details.start.y) //b { @@ -1827,9 +1821,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 32, 63))); CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 64, 63))); - std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); } else if(details.end.x+1 == details.start.x && details.end.y-1 == details.start.y) //bl { @@ -1850,14 +1844,14 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 33, 63))); CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.push_back(std::make_pair(ho, genRect(32, 32, 65, 63))); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-2][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-1][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x][hp.y+1][hp.z].objects.end(), objectBlitOrderSorter); } else if(details.end.x+1 == details.start.x && details.end.y == details.start.y) //l { @@ -1873,9 +1867,9 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 33, 32), ho->id); subRect(hp.x, hp.y, hp.z, genRect(32, 32, 65, 32), ho->id); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y-1][hp.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.begin(), CGI->mh->ttiles[hp.x-3][hp.y][hp.z].objects.end(), objectBlitOrderSorter); } } @@ -2105,13 +2099,13 @@ void CPlayerInterface::finishMovement( const TryMoveHero &details, const int3 &h subRect(details.end.x, details.end.y, details.end.z, genRect(32, 32, 64, 32), ho->id); //restoring good order of objects - std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y-1][details.end.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y-1][details.end.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y-1][details.end.z].objects.end(), objectBlitOrderSorter); - std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.end(), ocmptwo_cgin); - std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.end(), ocmptwo_cgin); + std::stable_sort(CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-2][details.end.y][details.end.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x-1][details.end.y][details.end.z].objects.end(), objectBlitOrderSorter); + std::stable_sort(CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.begin(), CGI->mh->ttiles[details.end.x][details.end.y][details.end.z].objects.end(), objectBlitOrderSorter); } void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult ) diff --git a/client/mapHandler.cpp b/client/mapHandler.cpp index 84496ea4b..75f034e94 100644 --- a/client/mapHandler.cpp +++ b/client/mapHandler.cpp @@ -75,21 +75,10 @@ std::string nameFromType (int typ) return std::string(); } -struct OCM_HLP +static bool objectBlitOrderSorter(const std::pair & a, const std::pair & b) { - bool operator ()(const std::pair & a, const std::pair & b) - { - return (*a.first)<(*b.first); - } -} ocmptwo ; - -// void alphaTransformDef(CGDefInfo * defInfo) -// { -// for(int yy=0; yyhandler->ourImages.size(); ++yy) -// { -// CSDL_Ext::alphaTransform(defInfo->handler->ourImages[yy].bitmap); -// } -// } + return CMapHandler::compareObjectBlitOrder(a.first, b.first); +} void CMapHandler::prepareFOWDefs() { @@ -308,7 +297,7 @@ void CMapHandler::initObjectRects() { for(int iz=0; izappearance.printPriority != b->appearance.printPriority) + return a->appearance.printPriority > b->appearance.printPriority; + + if(a->pos.y != b->pos.y) + return a->pos.y < b->pos.y; + + if(b->ID==Obj::HERO && a->ID!=Obj::HERO) + return true; + if(b->ID!=Obj::HERO && a->ID==Obj::HERO) + return false; + + if(!a->isVisitable() && b->isVisitable()) + return true; + if(!b->isVisitable() && a->isVisitable()) + return false; + if(a->pos.x < b->pos.x) + return true; + return false; +} diff --git a/client/mapHandler.h b/client/mapHandler.h index 09d4eaae9..edc5e964c 100644 --- a/client/mapHandler.h +++ b/client/mapHandler.h @@ -127,4 +127,6 @@ public: void validateRectTerr(SDL_Rect * val, const SDL_Rect * ext); //terrainRect helper static ui8 getDir(const int3 & a, const int3 & b); //returns direction number in range 0 - 7 (0 is left top, clockwise) [direction: form a to b] + static bool compareObjectBlitOrder(const CGObjectInstance * a, const CGObjectInstance * b); + }; diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 61e5da8c5..eac90bcc8 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -999,11 +999,11 @@ void CGHeroInstance::showNecromancyDialog(const CStackBasicDescriptor &raisedSta cb->showInfoDialog(&iw); } - +/* int3 CGHeroInstance::getSightCenter() const { return getPosition(false); -} +}*/ int CGHeroInstance::getSightRadious() const { diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index 327c0725b..b0422f197 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -113,7 +113,7 @@ public: } } skillsInfo; - int3 getSightCenter() const; //"center" tile from which the sight distance is calculated + //int3 getSightCenter() const; //"center" tile from which the sight distance is calculated int getSightRadious() const; //sight distance (should be used if player-owned structure) ////////////////////////////////////////////////////////////////////////// diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index db903cbb9..2e0e1b8a4 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -644,25 +644,22 @@ void CGTownInstance::newTurn() const } } } - +/* int3 CGTownInstance::getSightCenter() const { return pos - int3(2,0,0); } - -ui8 CGTownInstance::getPassableness() const +*/ +bool CGTownInstance::passableFor(PlayerColor color) const { if (!armedGarrison())//empty castle - anyone can visit - return GameConstants::ALL_PLAYERS; + return true; if ( tempOwner == PlayerColor::NEUTRAL )//neutral guarded - no one can visit - return 0; + return false; - ui8 mask = 0; - TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner); - for(PlayerColor it : ts->players) - mask |= 1<getPlayerRelations(tempOwner, color) != PlayerRelations::ENEMIES) + return true; + return false; } void CGTownInstance::getOutOffsets( std::vector &offsets ) const diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index fda070a30..ce6301033 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -200,8 +200,8 @@ public: ////////////////////////////////////////////////////////////////////////// - ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used - int3 getSightCenter() const override; //"center" tile from which the sight distance is calculated + bool passableFor(PlayerColor color) const; + //int3 getSightCenter() const override; //"center" tile from which the sight distance is calculated int getSightRadious() const override; //returns sight distance int getBoatType() const; //0 - evil (if a ship can be evil...?), 1 - good, 2 - neutral void getOutOffsets(std::vector &offsets) const; //offsets to obj pos when we boat can be placed diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index bdc06a286..8c138a86d 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -137,9 +137,6 @@ CGObjectInstance::CGObjectInstance(): } CGObjectInstance::~CGObjectInstance() { - //if (state) - // delete state; - //state=nullptr; } const std::string & CGObjectInstance::getHoverText() const @@ -148,10 +145,7 @@ const std::string & CGObjectInstance::getHoverText() const } void CGObjectInstance::setOwner(PlayerColor ow) { - //if (state) - // state->owner = ow; - //else - tempOwner = ow; + tempOwner = ow; } int CGObjectInstance::getWidth() const//returns width of object graphic in tiles { @@ -203,29 +197,6 @@ std::set CGObjectInstance::getBlockedOffsets() const return ret; } - -bool CGObjectInstance::operator<(const CGObjectInstance & cmp) const //screen printing priority comparing -{ - if (appearance.printPriority != cmp.appearance.printPriority) - return appearance.printPriority > cmp.appearance.printPriority; - - if(pos.y != cmp.pos.y) - return pos.y < cmp.pos.y; - - if(cmp.ID==Obj::HERO && ID!=Obj::HERO) - return true; - if(cmp.ID!=Obj::HERO && ID==Obj::HERO) - return false; - - if(!isVisitable() && cmp.isVisitable()) - return true; - if(!cmp.isVisitable() && isVisitable()) - return false; - if(this->pos.xgameState()->map->getTile(visitablePos()); @@ -291,6 +262,7 @@ void CGObjectInstance::getSightTiles(std::unordered_set &tiles) { cb->getTilesInRange(tiles, getSightCenter(), getSightRadious(), tempOwner, 1); } + void CGObjectInstance::hideTiles(PlayerColor ourplayer, int radius) const { for (auto i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++) @@ -366,11 +338,6 @@ void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const } } -ui8 CGObjectInstance::getPassableness() const -{ - return 0; -} - int3 CGObjectInstance::visitablePos() const { return pos - getVisitableOffset(); @@ -383,7 +350,7 @@ bool CGObjectInstance::isVisitable() const bool CGObjectInstance::passableFor(PlayerColor color) const { - return getPassableness() & 1< &tiles) const; //returns reference to the set PlayerColor getOwner() const; void setOwner(PlayerColor ow); + + /// APPEARANCE ACCESSORS /// + int getWidth() const; //returns width of object graphic in tiles int getHeight() const; //returns height of object graphic in tiles - virtual bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos) - virtual int3 getVisitableOffset() const; //returns (x,y,0) offset to first visitable tile from bottom right obj tile (0,0,0) (h3m pos) + bool visitableAt(int x, int y) const; //returns true if object is visitable at location (x, y) (h3m pos) int3 visitablePos() const; bool blockingAt(int x, int y) const; //returns true if object is blocking location (x, y) (h3m pos) bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) (h3m pos) std::set getBlockedPos() const; //returns set of positions blocked by this object std::set getBlockedOffsets() const; //returns set of relative positions blocked by this object bool isVisitable() const; //returns true if object is visitable - bool operator<(const CGObjectInstance & cmp) const; //screen printing priority comparing - void hideTiles(PlayerColor ourplayer, int radius) const; - CGObjectInstance(); - virtual ~CGObjectInstance(); - //CGObjectInstance(const CGObjectInstance & right); - //CGObjectInstance& operator=(const CGObjectInstance & right); - virtual const std::string & getHoverText() const; + /// HELPERS THAT SHOULD BE REMOVED /// + + /// fills set with tiles which are visible from this object. TODO: remove? + void getSightTiles(std::unordered_set &tiles) const; + /// Hides tiles visible for any player but ours. TODO: move to callback/game state? + void hideTiles(PlayerColor ourplayer, int radius) const; + + /// VIRTUAL METHODS /// + + /// Returns true if player can pass through visitable tiles of this object + virtual bool passableFor(PlayerColor color) const; + /// Range of revealed map around this object, counting from getSightCenter() + virtual int getSightRadious() const; + /// returns (x,y,0) offset to a visitable tile of object + virtual int3 getVisitableOffset() const; + /// returns text visible in status bar + /// TODO: should accept selected hero as parameter and possibly - moved into object handler + virtual const std::string & getHoverText() const; + /// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman") virtual void setType(si32 ID, si32 subID); - ///IObjectInterface + ///IObjectInterface OVERRIDES + void initObj() override; void onHeroVisit(const CGHeroInstance * h) const override; - void setProperty(ui8 what, ui32 val) override;//synchr - - friend class CGameHandler; + /// method for synchronous update. Note: For new properties classes should override setPropertyDer instead + void setProperty(ui8 what, ui32 val) override; + //friend class CGameHandler; template void serialize(Handler &h, const int version) { @@ -146,9 +169,13 @@ public: //definfo is handled by map serializer } protected: - virtual void setPropertyDer(ui8 what, ui32 val);//synchr + /// virtual method that allows synchronously update object state on server and all clients + virtual void setPropertyDer(ui8 what, ui32 val); + /// Adds (visited) text if selected hero has visited object + /// TODO: remove? void getNameVis(std::string &hname) const; + /// Gives dummy bonus from this object to hero. Can be used to track visited state void giveDummyBonus(ObjectInstanceID heroID, ui8 duration = Bonus::ONE_DAY) const; }; diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index c899b4071..e9ed17781 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -853,10 +853,7 @@ void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passabi } } -ui8 CGBorderGate::getPassableness() const +bool CGBorderGate::passableFor(PlayerColor color) const { - ui8 ret = 0; - for (int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++) - ret |= wasMyColorVisited(PlayerColor(i))< void serialize(Handler &h, const int version) { diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 4fbfade1b..7674a8ece 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1250,19 +1250,18 @@ void CGGarrison::onHeroVisit (const CGHeroInstance *h) const cb->showGarrisonDialog(id, h->id, removableUnits); } -ui8 CGGarrison::getPassableness() const +bool CGGarrison::passableFor(PlayerColor player) const { + //FIXME: identical to same method in CGTownInstance + if ( !stacksCount() )//empty - anyone can visit - return GameConstants::ALL_PLAYERS; + return true; if ( tempOwner == PlayerColor::NEUTRAL )//neutral guarded - no one can visit - return 0; + return false; - ui8 mask = 0; - TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner); - for(PlayerColor it : ts->players) - mask |= 1<getPlayerRelations(tempOwner, player) != PlayerRelations::ENEMIES) + return true; + return false; } void CGGarrison::battleFinished(const CGHeroInstance *hero, const BattleResult &result) const diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index c53db75d7..8f66bb31e 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -138,7 +138,7 @@ class DLL_LINKAGE CGGarrison : public CArmedInstance public: bool removableUnits; - ui8 getPassableness() const; + bool passableFor(PlayerColor color) const override; void onHeroVisit(const CGHeroInstance * h) const override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; From ad632d1e8a30b46cc7b7c013e39e337676f63b4a Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 24 Jun 2014 14:50:27 +0300 Subject: [PATCH 06/39] Moved FoW management from CGObjectInstance to callback --- client/Client.h | 3 +++ lib/CGameState.cpp | 2 +- lib/IGameCallback.h | 2 ++ lib/NetPacksLib.cpp | 2 +- lib/mapObjects/CGTownInstance.cpp | 2 +- lib/mapObjects/CObjectHandler.cpp | 30 +----------------------------- lib/mapObjects/CObjectHandler.h | 13 +++---------- lib/mapObjects/MiscObjects.cpp | 7 ++++++- server/CGameHandler.cpp | 26 +++++++++++++++++++++++--- server/CGameHandler.h | 2 ++ 10 files changed, 43 insertions(+), 46 deletions(-) diff --git a/client/Client.h b/client/Client.h index 8ebb49d98..f19410001 100644 --- a/client/Client.h +++ b/client/Client.h @@ -218,6 +218,9 @@ public: void sendAndApply(CPackForClient * info) override {}; void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override {}; + void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) override {} + void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) override {} + ////////////////////////////////////////////////////////////////////////// friend class CCallback; //handling players actions friend class CBattleCallback; //handling players actions diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 45b1510a0..1de0f422b 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1637,7 +1637,7 @@ void CGameState::initFogOfWar() if(!obj || !vstd::contains(elem.second.players, obj->tempOwner)) continue; //not a flagged object std::unordered_set tiles; - obj->getSightTiles(tiles); + getTilesInRange(tiles, obj->getSightCenter(), obj->getSightRadious(), obj->tempOwner, 1); for(int3 tile : tiles) { elem.second.fogOfWarMap[tile.x][tile.y][tile.z] = 1; diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index e6183e2b2..dda271759 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -93,6 +93,8 @@ public: virtual void sendAndApply(CPackForClient * info)=0; virtual void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2)=0; //when two heroes meet on adventure map virtual void addQuest(int player, QuestInfo & quest){}; + virtual void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) = 0; + virtual void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) = 0; }; class DLL_LINKAGE CNonConstInfoCallback : public CPrivilagedInfoCallback diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 50df1a5a9..cfef3489f 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -177,7 +177,7 @@ DLL_LINKAGE void FoWChange::applyGs( CGameState *gs ) case Obj::TOWN: case Obj::ABANDONED_MINE: if(vstd::contains(team->players, o->tempOwner)) //check owned observators - o->getSightTiles(tilesRevealed); + gs->getTilesInRange(tiles, o->getSightCenter(), o->getSightRadious(), o->tempOwner, 1); break; } } diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 2e0e1b8a4..48bd08f0c 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -1007,7 +1007,7 @@ void CGTownInstance::battleFinished(const CGHeroInstance *hero, const BattleResu FoWChange fw; fw.player = hero->tempOwner; fw.mode = 1; - getSightTiles (fw.tiles); //update visibility for castle structures + cb->getTilesInRange(fw.tiles, getSightCenter(), getSightRadious(), tempOwner, 1); cb->sendAndApply (&fw); } } diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 8c138a86d..5d00cce34 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -246,42 +246,14 @@ void CGObjectInstance::setPropertyDer( ui8 what, ui32 val ) int3 CGObjectInstance::getSightCenter() const { - //return vistiable tile if possible - for(int i=0; i < 8; i++) - for(int j=0; j < 6; j++) - if(visitableAt(i,j)) - return(pos + int3(i-7, j-5, 0)); - return pos; + return visitablePos(); } int CGObjectInstance::getSightRadious() const { return 3; } -void CGObjectInstance::getSightTiles(std::unordered_set &tiles) const //returns reference to the set -{ - cb->getTilesInRange(tiles, getSightCenter(), getSightRadious(), tempOwner, 1); -} -void CGObjectInstance::hideTiles(PlayerColor ourplayer, int radius) const -{ - for (auto i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++) - { - if ( !vstd::contains(i->second.players, ourplayer ))//another team - { - for (auto & elem : i->second.players) - if ( cb->getPlayer(elem)->status == EPlayerStatus::INGAME )//seek for living player (if any) - { - FoWChange fw; - fw.mode = 0; - fw.player = elem; - cb->getTilesInRange (fw.tiles, pos, radius, (elem), -1); - cb->sendAndApply (&fw); - break; - } - } - } -} int3 CGObjectInstance::getVisitableOffset() const { for(int y = 0; y < appearance.getHeight(); y++) diff --git a/lib/mapObjects/CObjectHandler.h b/lib/mapObjects/CObjectHandler.h index 90d890dc6..3ebb74a65 100644 --- a/lib/mapObjects/CObjectHandler.h +++ b/lib/mapObjects/CObjectHandler.h @@ -121,7 +121,7 @@ public: PlayerColor getOwner() const; void setOwner(PlayerColor ow); - /// APPEARANCE ACCESSORS /// + /** APPEARANCE ACCESSORS **/ int getWidth() const; //returns width of object graphic in tiles int getHeight() const; //returns height of object graphic in tiles @@ -133,14 +133,7 @@ public: std::set getBlockedOffsets() const; //returns set of relative positions blocked by this object bool isVisitable() const; //returns true if object is visitable - /// HELPERS THAT SHOULD BE REMOVED /// - - /// fills set with tiles which are visible from this object. TODO: remove? - void getSightTiles(std::unordered_set &tiles) const; - /// Hides tiles visible for any player but ours. TODO: move to callback/game state? - void hideTiles(PlayerColor ourplayer, int radius) const; - - /// VIRTUAL METHODS /// + /** VIRTUAL METHODS **/ /// Returns true if player can pass through visitable tiles of this object virtual bool passableFor(PlayerColor color) const; @@ -154,7 +147,7 @@ public: /// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman") virtual void setType(si32 ID, si32 subID); - ///IObjectInterface OVERRIDES + /** OVERRIDES OF IObjectInterface **/ void initObj() override; void onHeroVisit(const CGHeroInstance * h) const override; diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 7674a8ece..d5136a697 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1048,7 +1048,12 @@ void CGObservatory::onHeroVisit( const CGHeroInstance * h ) const case Obj::COVER_OF_DARKNESS: { iw.text.addTxt (MetaString::ADVOB_TXT, 31); - hideTiles(h->tempOwner, 20); + for (auto player : cb->gameState()->players) + { + if (cb->getPlayerStatus(player.first) == EPlayerStatus::INGAME && + cb->getPlayerRelations(player.first, h->tempOwner) == PlayerRelations::ENEMIES) + cb->changeFogOfWar(visitablePos(), 20, player.first, true); + } break; } } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 98255ea42..de78ebab4 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1351,9 +1351,13 @@ void CGameHandler::newTurn() } if (t->hasBonusOfType (Bonus::DARKNESS)) { - t->hideTiles(t->getOwner(), t->getBonusLocalFirst(Selector::type(Bonus::DARKNESS))->val); + for (auto player : gameState()->players) + { + if (getPlayerStatus(player.first) == EPlayerStatus::INGAME && + getPlayerRelations(player.first, t->tempOwner) == PlayerRelations::ENEMIES) + changeFogOfWar(t->visitablePos(), t->getBonusLocalFirst(Selector::type(Bonus::DARKNESS))->val, player.first, true); + } } - //unhiding what shouldn't be hidden? //that's handled in netpacks client } if(newMonth) @@ -2523,7 +2527,7 @@ bool CGameHandler::buildStructure( ObjectInstanceID tid, BuildingID requestedID, FoWChange fw; fw.player = t->tempOwner; fw.mode = 1; - t->getSightTiles(fw.tiles); + getTilesInRange(fw.tiles, t->getSightCenter(), t->getSightRadious(), t->tempOwner, 1); sendAndApply(&fw); if(t->visitingHero) @@ -6252,6 +6256,22 @@ void CGameHandler::removeAfterVisit(const CGObjectInstance *object) assert("This function needs to be called during the object visit!"); } +void CGameHandler::changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) +{ + std::unordered_set tiles; + getTilesInRange(tiles, center, radius, player, hide? -1 : 1); + changeFogOfWar(tiles, player, hide); +} + +void CGameHandler::changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) +{ + FoWChange fow; + fow.tiles = tiles; + fow.player = player; + fow.mode = hide? 0 : 1; + sendAndApply(&fow); +} + bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) { if(auto topQuery = queries.topQuery(hero->getOwner())) diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 36798d519..e09dd9152 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -174,6 +174,8 @@ public: void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) override; void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) override; + void changeFogOfWar(int3 center, ui32 radius, PlayerColor player, bool hide) override; + void changeFogOfWar(std::unordered_set &tiles, PlayerColor player, bool hide) override; bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) override; From a0689fa3773b07871edd636143289467470e16ba Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 24 Jun 2014 20:39:36 +0300 Subject: [PATCH 07/39] Refactoring of hoverText from objects: - removed hoverText field - split getHoverText() method into 3: - - getObjectName() for generic name - - getHoverText(Player) for player-specific text - - getHoverText(Hero) for hero-specific strings --- AI/VCAI/Goals.cpp | 6 +- AI/VCAI/VCAI.cpp | 12 +- client/AdventureMapClasses.cpp | 2 +- client/CAdvmapInterface.cpp | 3 +- client/CKingdomInterface.cpp | 4 +- client/CMT.cpp | 2 +- client/CQuestLog.cpp | 2 +- client/Client.h | 1 - client/GUIClasses.cpp | 10 +- client/mapHandler.cpp | 2 +- client/mapHandler.h | 1 - lib/CCreatureSet.cpp | 1 + lib/CGameInfoCallback.cpp | 12 -- lib/CGameInfoCallback.h | 1 - lib/CGameState.cpp | 3 +- lib/IGameCallback.h | 1 - lib/NetPacks.h | 15 --- lib/NetPacksLib.cpp | 10 +- lib/mapObjects/CBank.cpp | 7 +- lib/mapObjects/CBank.h | 2 +- lib/mapObjects/CGHeroInstance.cpp | 8 +- lib/mapObjects/CGHeroInstance.h | 2 +- lib/mapObjects/CGTownInstance.cpp | 10 +- lib/mapObjects/CGTownInstance.h | 3 +- lib/mapObjects/CObjectHandler.cpp | 39 +++--- lib/mapObjects/CObjectHandler.h | 22 ++-- lib/mapObjects/CQuest.cpp | 35 ++---- lib/mapObjects/CQuest.h | 6 +- lib/mapObjects/CRewardableObject.cpp | 19 ++- lib/mapObjects/CRewardableObject.h | 3 +- lib/mapObjects/MiscObjects.cpp | 179 ++++++++++++++------------- lib/mapObjects/MiscObjects.h | 24 ++-- lib/mapping/CMap.cpp | 2 +- lib/registerTypes/RegisterTypes.h | 1 - server/CGameHandler.cpp | 8 +- server/CGameHandler.h | 1 - server/CQuery.cpp | 4 +- 37 files changed, 212 insertions(+), 251 deletions(-) diff --git a/AI/VCAI/Goals.cpp b/AI/VCAI/Goals.cpp index adb4e35bb..b4929f180 100644 --- a/AI/VCAI/Goals.cpp +++ b/AI/VCAI/Goals.cpp @@ -66,7 +66,7 @@ std::string Goals::AbstractGoal::name() const //TODO: virtualize { auto obj = cb->getObjInstance(ObjectInstanceID(objid)); if (obj) - desc = "GET OBJ " + obj->getHoverText(); + desc = "GET OBJ " + obj->getObjectName(); } case FIND_OBJ: desc = "FIND OBJ " + boost::lexical_cast(objid); @@ -75,7 +75,7 @@ std::string Goals::AbstractGoal::name() const //TODO: virtualize { auto obj = cb->getObjInstance(ObjectInstanceID(objid)); if (obj) - desc = "VISIT HERO " + obj->getHoverText(); + desc = "VISIT HERO " + obj->getObjectName(); } break; case GET_ART_TYPE: @@ -493,7 +493,7 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals() if (topObj->ID == Obj::HERO && cb->getPlayerRelations(h->tempOwner, topObj->tempOwner) != PlayerRelations::ENEMIES) if (topObj != hero.get(true)) //the hero we want to free - logAi->errorStream() << boost::format("%s stands in the way of %s") % topObj->getHoverText() % h->getHoverText(); + logAi->errorStream() << boost::format("%s stands in the way of %s") % topObj->getObjectName() % h->getObjectName(); if (topObj->ID == Obj::QUEST_GUARD || topObj->ID == Obj::BORDERGUARD) { if (shouldVisit(h, topObj)) diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index ba857730b..f850d1996 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -81,7 +81,7 @@ struct ObjInfo ObjInfo(){} ObjInfo(const CGObjectInstance *obj): pos(obj->pos), - name(obj->getHoverText()) + name(obj->getObjectName()) { } }; @@ -241,7 +241,7 @@ void VCAI::artifactDisassembled(const ArtifactLocation &al) void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visitedObj, bool start) { - LOG_TRACE_PARAMS(logAi, "start '%i'; obj '%s'", start % (visitedObj ? visitedObj->hoverName : std::string("n/a"))); + LOG_TRACE_PARAMS(logAi, "start '%i'; obj '%s'", start % (visitedObj ? visitedObj->getObjectName() : std::string("n/a"))); NET_EVENT_HANDLER; if(start) { @@ -780,13 +780,13 @@ void VCAI::makeTurnInternal() bool VCAI::goVisitObj(const CGObjectInstance * obj, HeroPtr h) { int3 dst = obj->visitablePos(); - logAi->debugStream() << boost::format("%s will try to visit %s at (%s)") % h->name % obj->getHoverText() % strFromInt3(dst); + logAi->debugStream() << boost::format("%s will try to visit %s at (%s)") % h->name % obj->getObjectName() % strFromInt3(dst); return moveHeroToTile(dst, h); } void VCAI::performObjectInteraction(const CGObjectInstance * obj, HeroPtr h) { - LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->name % obj->getHoverText() % obj->pos); + LOG_TRACE_PARAMS(logAi, "Hero %s and object %s at %s", h->name % obj->getObjectName() % obj->pos); switch (obj->ID) { case Obj::CREATURE_GENERATOR1: @@ -1434,7 +1434,7 @@ void VCAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int assert(playerID > PlayerColor::PLAYER_LIMIT || status.getBattle() == UPCOMING_BATTLE); status.setBattle(ONGOING_BATTLE); const CGObjectInstance *presumedEnemy = backOrNull(cb->getVisitableObjs(tile)); //may be nullptr in some very are cases -> eg. visited monolith and fighting with an enemy at the FoW covered exit - battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->hoverName : "unknown enemy") % tile); + battlename = boost::str(boost::format("Starting battle of %s attacking %s at %s") % (hero1 ? hero1->name : "a army") % (presumedEnemy ? presumedEnemy->getObjectName() : "unknown enemy") % tile); CAdventureAI::battleStart(army1, army2, tile, hero1, hero2, side); } @@ -1468,7 +1468,7 @@ void VCAI::reserveObject(HeroPtr h, const CGObjectInstance *obj) { reservedObjs.insert(obj); reservedHeroesMap[h].insert(obj); - logAi->debugStream() << "reserved object id=" << obj->id << "; address=" << (intptr_t)obj << "; name=" << obj->getHoverText(); + logAi->debugStream() << "reserved object id=" << obj->id << "; address=" << (intptr_t)obj << "; name=" << obj->getObjectName(); } void VCAI::unreserveObject(HeroPtr h, const CGObjectInstance *obj) diff --git a/client/AdventureMapClasses.cpp b/client/AdventureMapClasses.cpp index 31960805f..515a519ff 100644 --- a/client/AdventureMapClasses.cpp +++ b/client/AdventureMapClasses.cpp @@ -317,7 +317,7 @@ void CTownList::CTownItem::showTooltip() std::string CTownList::CTownItem::getHoverText() { - return town->hoverName; + return town->getObjectName(); } CTownList::CTownList(int size, Point position, std::string btnUp, std::string btnDown): diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index 4dfba348d..ea075bcf7 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -1234,10 +1234,9 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) } const CGObjectInstance *objAtTile = getBlockingObject(mapPos); - //std::vector temp = LOCPLINT->cb->getObjDescriptions(mapPos); if (objAtTile) { - std::string text = objAtTile->getHoverText(); + std::string text = curHero() ? objAtTile->getHoverText(curHero()) : objAtTile->getHoverText(LOCPLINT->playerID); boost::replace_all(text,"\n"," "); statusbar.setText(text); } diff --git a/client/CKingdomInterface.cpp b/client/CKingdomInterface.cpp index 83f730515..2c6dfb235 100644 --- a/client/CKingdomInterface.cpp +++ b/client/CKingdomInterface.cpp @@ -500,7 +500,7 @@ void CKingdomInterface::generateObjectsList(const std::vectorsubID]; if (info.count++ == 0) { - info.hoverText = object->getHoverText(); + info.hoverText = object->getObjectName(); info.imageID = object->subID; } } @@ -511,7 +511,7 @@ void CKingdomInterface::generateObjectsList(const std::vectorsecond]; if (info.count++ == 0) { - info.hoverText = object->hoverName; + info.hoverText = object->getObjectName(); info.imageID = iter->second; } } diff --git a/client/CMT.cpp b/client/CMT.cpp index 070b2cce1..6fed20903 100644 --- a/client/CMT.cpp +++ b/client/CMT.cpp @@ -589,7 +589,7 @@ void processCommand(const std::string &message) } else if(cn == "bonuses") { - std::cout << "Bonuses of " << adventureInt->selection->getHoverText() << std::endl + std::cout << "Bonuses of " << adventureInt->selection->getObjectName() << std::endl << adventureInt->selection->getBonusList() << std::endl; std::cout << "\nInherited bonuses:\n"; diff --git a/client/CQuestLog.cpp b/client/CQuestLog.cpp index 1eb621ce4..05cf409c4 100644 --- a/client/CQuestLog.cpp +++ b/client/CQuestLog.cpp @@ -140,7 +140,7 @@ void CQuestLog::init() MetaString text; quests[i].quest->getRolloverText (text, false); if (quests[i].obj) - text.addReplacement (quests[i].obj->getHoverText()); //get name of the object + text.addReplacement (quests[i].obj->getObjectName()); //get name of the object CQuestLabel * label = new CQuestLabel (Rect(28, 199 + i * 24, 172,30), FONT_SMALL, TOPLEFT, Colors::WHITE, text.toString()); label->callback = boost::bind(&CQuestLog::selectQuest, this, i); labels.push_back(label); diff --git a/client/Client.h b/client/Client.h index f19410001..ed16a87c6 100644 --- a/client/Client.h +++ b/client/Client.h @@ -170,7 +170,6 @@ public: bool removeObject(const CGObjectInstance * obj) override {return false;}; void setBlockVis(ObjectInstanceID objid, bool bv) override {}; void setOwner(const CGObjectInstance * obj, PlayerColor owner) override {}; - void setHoverName(const CGObjectInstance * obj, MetaString * name) override {}; void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false) override {}; void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) override {}; diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index 3ffa2bd1e..b2d824fb6 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -1848,7 +1848,7 @@ CObjectListWindow::CObjectListWindow(const std::vector &_items, CIntObject items.reserve(_items.size()); for(int id : _items) { - items.push_back(std::make_pair(id, CGI->mh->map->objects[id]->hoverName)); + items.push_back(std::make_pair(id, CGI->mh->map->objects[id]->getObjectName())); } init(titlePic, _title, _descr); @@ -2614,7 +2614,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket *Market, const CGHeroInstan break; case Obj::BLACK_MARKET: title = CGI->generaltexth->allTexts[349]; break; case Obj::TRADING_POST: title = CGI->generaltexth->allTexts[159]; break; case Obj::TRADING_POST_SNOW: title = CGI->generaltexth->allTexts[159]; - break; default: title = market->o->getHoverText(); + break; default: title = market->o->getObjectName(); } } @@ -4571,7 +4571,7 @@ void CHeroArea::clickRight(tribool down, bool previousState) void CHeroArea::hover(bool on) { if (on && hero) - GH.statusbar->setText(hero->hoverName); + GH.statusbar->setText(hero->getObjectName()); else GH.statusbar->clear(); } @@ -5634,7 +5634,7 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn slotsCount=7; resources = CDefHandler::giveDefEss("SMALRES.DEF"); - new CLabel(325, 32, FONT_BIG, CENTER, Colors::YELLOW, fort->hoverName);//Hill Fort + new CLabel(325, 32, FONT_BIG, CENTER, Colors::YELLOW, fort->getObjectName());//Hill Fort heroPic = new CHeroArea(30, 60, hero); @@ -6181,7 +6181,7 @@ void CRClickPopup::createAndPush(const CGObjectInstance *obj, const Point &p, EA if(iWin) GH.pushInt(iWin); else - CRClickPopup::createAndPush(obj->getHoverText()); + CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID)); } CRClickPopup::CRClickPopup() diff --git a/client/mapHandler.cpp b/client/mapHandler.cpp index 75f034e94..3080f5a11 100644 --- a/client/mapHandler.cpp +++ b/client/mapHandler.cpp @@ -1054,7 +1054,7 @@ void CMapHandler::getTerrainDescr( const int3 &pos, std::string & out, bool terN { if(elem.first->ID == Obj::HOLE) //Hole { - out = elem.first->hoverName; + out = elem.first->getObjectName(); return; } } diff --git a/client/mapHandler.h b/client/mapHandler.h index edc5e964c..7700c47a5 100644 --- a/client/mapHandler.h +++ b/client/mapHandler.h @@ -108,7 +108,6 @@ public: std::pair getVisBitmap(const int3 & pos, const std::vector< std::vector< std::vector > > & visibilityMap) const; //returns appropriate bitmap and info if alpha blitting is necessary ui8 getPhaseShift(const CGObjectInstance *object) const; - std::vector< std::string > getObjDescriptions(int3 pos); //returns desriptions of objects blocking given position void getTerrainDescr(const int3 &pos, std::string & out, bool terName); //if tername == false => empty string when tile is clear CGObjectInstance * createObject(int id, int subid, int3 pos, int owner=254); //creates a new object with a certain id and subid bool printObject(const CGObjectInstance * obj); //puts appropriate things to ttiles, so obj will be visible on map diff --git a/lib/CCreatureSet.cpp b/lib/CCreatureSet.cpp index f33019a81..7dea9f9f0 100644 --- a/lib/CCreatureSet.cpp +++ b/lib/CCreatureSet.cpp @@ -224,6 +224,7 @@ ui64 CCreatureSet::getPower (SlotID slot) const { return getStack(slot).getPower(); } + std::string CCreatureSet::getRoughAmount (SlotID slot) const { int quantity = CCreature::getQuantityID(getStackCount(slot)); diff --git a/lib/CGameInfoCallback.cpp b/lib/CGameInfoCallback.cpp index eb62696ff..5281bccb1 100644 --- a/lib/CGameInfoCallback.cpp +++ b/lib/CGameInfoCallback.cpp @@ -260,18 +260,6 @@ int CGameInfoCallback::getDate(Date::EDateType mode) const //boost::shared_lock lock(*gs->mx); return gs->getDate(mode); } -std::vector < std::string > CGameInfoCallback::getObjDescriptions(int3 pos) const -{ - //boost::shared_lock lock(*gs->mx); - std::vector ret; - const TerrainTile *t = getTile(pos); - ERROR_RET_VAL_IF(!t, "Not a valid tile given!", ret); - - - for(const CGObjectInstance * obj : t->blockingObjects) - ret.push_back(obj->getHoverText()); - return ret; -} bool CGameInfoCallback::isVisible(int3 pos, boost::optional Player) const { diff --git a/lib/CGameInfoCallback.h b/lib/CGameInfoCallback.h index aeade6a56..ae740b29d 100644 --- a/lib/CGameInfoCallback.h +++ b/lib/CGameInfoCallback.h @@ -83,7 +83,6 @@ public: std::vector getVisitableObjs(int3 pos, bool verbose = true)const; std::vector getFlaggableObjects(int3 pos) const; const CGObjectInstance * getTopObj (int3 pos) const; - std::vector getObjDescriptions(int3 pos)const; //returns descriptions of objects at pos in order from the lowest to the highest PlayerColor getOwner(ObjectInstanceID heroID) const; const CGObjectInstance *getObjByQuestIdentifier(int identifier) const; //nullptr if object has been removed (eg. killed) diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 1de0f422b..110521f73 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1053,7 +1053,6 @@ void CGameState::randomizeMapObjects() if(!obj) continue; randomizeObject(obj); - obj->hoverName = VLC->objtypeh->getObjectName(obj->ID); //handle Favouring Winds - mark tiles under it if(obj->ID == Obj::FAVORABLE_WINDS) @@ -2980,7 +2979,7 @@ void InfoAboutArmy::initFromArmy(const CArmedInstance *Army, bool detailed) { army = ArmyDescriptor(Army, detailed); owner = Army->tempOwner; - name = Army->getHoverText(); + name = Army->getObjectName(); } void InfoAboutHero::assign(const InfoAboutHero & iah) diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index dda271759..abbb5d64b 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -48,7 +48,6 @@ public: virtual bool removeObject(const CGObjectInstance * obj)=0; virtual void setBlockVis(ObjectInstanceID objid, bool bv)=0; virtual void setOwner(const CGObjectInstance * objid, PlayerColor owner)=0; - virtual void setHoverName(const CGObjectInstance * obj, MetaString * name)=0; virtual void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false)=0; virtual void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false)=0; virtual void showBlockingDialog(BlockingDialog *iw) =0; diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 5f8c0d666..0e590903e 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1045,21 +1045,6 @@ struct SetObjectProperty : public CPackForClient//1001 } }; -struct SetHoverName : public CPackForClient//1002 -{ - DLL_LINKAGE void applyGs(CGameState *gs); - - ObjectInstanceID id; - MetaString name; - SetHoverName(){type = 1002;} - SetHoverName(ObjectInstanceID ID, MetaString& Name):id(ID),name(Name){type = 1002;} - - template void serialize(Handler &h, const int version) - { - h & id & name; - } -}; - struct ChangeObjectVisitors : public CPackForClient // 1003 { enum VisitMode diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index cfef3489f..2dfe20ef6 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -302,7 +302,7 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs ) { CGObjectInstance *obj = gs->getObjInstance(id); - logGlobal->debugStream() << "removing object id=" << id << "; address=" << (intptr_t)obj << "; name=" << obj->getHoverText(); + logGlobal->debugStream() << "removing object id=" << id << "; address=" << (intptr_t)obj << "; name=" << obj->getObjectName(); //unblock tiles gs->map->removeBlockVisTiles(obj); @@ -608,14 +608,13 @@ DLL_LINKAGE void NewObject::applyGs( CGameState *gs ) const TerrainTile &t = gs->map->getTile(pos); o->appearance = VLC->objtypeh->getHandlerFor(o->ID, o->subID)->getTemplates(t.terType).front(); id = o->id = ObjectInstanceID(gs->map->objects.size()); - o->hoverName = VLC->objtypeh->getObjectName(ID); gs->map->objects.push_back(o); gs->map->addBlockVisTiles(o); o->initObj(); gs->map->calculateGuardingGreaturePositions(); - logGlobal->debugStream() << "added object id=" << id << "; address=" << (intptr_t)o << "; name=" << o->getHoverText(); + logGlobal->debugStream() << "added object id=" << id << "; address=" << (intptr_t)o << "; name=" << o->getObjectName(); } DLL_LINKAGE void NewArtifact::applyGs( CGameState *gs ) @@ -1012,11 +1011,6 @@ DLL_LINKAGE void SetObjectProperty::applyGs( CGameState *gs ) } } -DLL_LINKAGE void SetHoverName::applyGs( CGameState *gs ) -{ - name.toString(gs->getObj(id)->hoverName); -} - DLL_LINKAGE void HeroLevelUp::applyGs( CGameState *gs ) { CGHeroInstance * h = gs->getHero(hero->id); diff --git a/lib/mapObjects/CBank.cpp b/lib/mapObjects/CBank.cpp index 8f4f52582..076b1d131 100644 --- a/lib/mapObjects/CBank.cpp +++ b/lib/mapObjects/CBank.cpp @@ -41,11 +41,12 @@ void CBank::initObj() VLC->objtypeh->getHandlerFor(ID, subID)->configureObject(this, cb->gameState()->getRandomGenerator()); } -const std::string & CBank::getHoverText() const +std::string CBank::getHoverText(PlayerColor player) const { + // TODO: USE BANK_SPECIFIC NAMES + // TODO: record visited players bool visited = (bc == nullptr); - hoverName = visitedTxt(visited); // FIXME: USE BANK_SPECIFIC NAMES - return hoverName; + return visitedTxt(visited); } void CBank::setConfig(const BankConfig & config) diff --git a/lib/mapObjects/CBank.h b/lib/mapObjects/CBank.h index c8f8471aa..abf19f86a 100644 --- a/lib/mapObjects/CBank.h +++ b/lib/mapObjects/CBank.h @@ -32,7 +32,7 @@ public: void setConfig(const BankConfig & bc); void initObj() override; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; void newTurn() const override; bool wasVisited (PlayerColor player) const override; void onHeroVisit(const CGHeroInstance * h) const override; diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index eac90bcc8..0d62cf0ae 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -418,19 +418,17 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const } } -const std::string & CGHeroInstance::getHoverText() const +std::string CGHeroInstance::getObjectName() const { if(ID != Obj::PRISON) { - hoverName = VLC->generaltexth->allTexts[15]; + std::string hoverName = VLC->generaltexth->allTexts[15]; boost::algorithm::replace_first(hoverName,"%s",name); boost::algorithm::replace_first(hoverName,"%s", type->heroClass->name); return hoverName; } else - hoverName = VLC->objtypeh->getObjectName(ID); - - return hoverName; + return CGObjectInstance::getObjectName(); } const std::string & CGHeroInstance::getBiography() const diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index b0422f197..a593e40d7 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -205,7 +205,7 @@ public: void initObj() override; void onHeroVisit(const CGHeroInstance * h) const override; - const std::string & getHoverText() const override; + std::string getObjectName() const override; protected: void setPropertyDer(ui8 what, ui32 val) override;//synchr diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 48bd08f0c..ef61d5cd3 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -55,7 +55,7 @@ void CGDwelling::initObj() } } -void CGDwelling::setProperty(ui8 what, ui32 val) +void CGDwelling::setPropertyDer(ui8 what, ui32 val) { switch (what) { @@ -77,8 +77,8 @@ void CGDwelling::setProperty(ui8 what, ui32 val) creatures[0].second[0] = CreatureID(val); break; } - CGObjectInstance::setProperty(what,val); } + void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const { if(ID == Obj::REFUGEE_CAMP && !creatures[0].first) //Refugee Camp, no available cres @@ -523,11 +523,15 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const cb->stopHeroVisitCastle(this, h); } +std::string CGTownInstance::getObjectName() const +{ + return name + ", " + town->faction->name; +} + void CGTownInstance::initObj() ///initialize town structures { blockVisit = true; - hoverName = name + ", " + town->faction->name; if (subID == ETownType::DUNGEON) creatures.resize(GameConstants::CREATURES_PER_TOWN+1);//extra dwelling for Dungeon diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index ce6301033..a1102bca1 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -59,7 +59,7 @@ public: void initObj() override; void onHeroVisit(const CGHeroInstance * h) const override; void newTurn() const override; - void setProperty(ui8 what, ui32 val) override; + void setPropertyDer(ui8 what, ui32 val) override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; @@ -243,6 +243,7 @@ public: void onHeroLeave(const CGHeroInstance * h) const override; void initObj() override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; + std::string getObjectName() const override; protected: void setPropertyDer(ui8 what, ui32 val) override; }; diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 5d00cce34..54f73d843 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -53,12 +53,6 @@ static void showInfoDialog(const CGHeroInstance* h, const ui32 txtID, const ui16 showInfoDialog(playerID,txtID,soundID); } -static std::string & visitedTxt(const bool visited) -{ - int id = visited ? 352 : 353; - return VLC->generaltexth->allTexts[id]; -} - ///IObjectInterface void IObjectInterface::onHeroVisit(const CGHeroInstance * h) const {} @@ -139,10 +133,6 @@ CGObjectInstance::~CGObjectInstance() { } -const std::string & CGObjectInstance::getHoverText() const -{ - return hoverName; -} void CGObjectInstance::setOwner(PlayerColor ow) { tempOwner = ow; @@ -223,6 +213,8 @@ void CGObjectInstance::initObj() void CGObjectInstance::setProperty( ui8 what, ui32 val ) { + setPropertyDer(what, val); // call this before any actual changes (needed at least for dwellings) + switch(what) { case ObjProperty::OWNER: @@ -238,7 +230,6 @@ void CGObjectInstance::setProperty( ui8 what, ui32 val ) subID = val; break; } - setPropertyDer(what, val); } void CGObjectInstance::setPropertyDer( ui8 what, ui32 val ) @@ -265,17 +256,6 @@ int3 CGObjectInstance::getVisitableOffset() const return int3(0,0,0); } -void CGObjectInstance::getNameVis( std::string &hname ) const -{ - const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); - hname = VLC->objtypeh->getObjectName(ID); - if(h) - { - const bool visited = h->hasBonusFrom(Bonus::OBJECT,ID); - hname + " " + visitedTxt(visited); - } -} - void CGObjectInstance::giveDummyBonus(ObjectInstanceID heroID, ui8 duration) const { GiveBonus gbonus; @@ -287,6 +267,21 @@ void CGObjectInstance::giveDummyBonus(ObjectInstanceID heroID, ui8 duration) con cb->giveHeroBonus(&gbonus); } +std::string CGObjectInstance::getObjectName() const +{ + return VLC->objtypeh->getObjectName(ID); +} + +std::string CGObjectInstance::getHoverText(PlayerColor player) const +{ + return getObjectName(); +} + +std::string CGObjectInstance::getHoverText(const CGHeroInstance * hero) const +{ + return getHoverText(hero->tempOwner); +} + void CGObjectInstance::onHeroVisit( const CGHeroInstance * h ) const { switch(ID) diff --git a/lib/mapObjects/CObjectHandler.h b/lib/mapObjects/CObjectHandler.h index 3ebb74a65..4faaa0f92 100644 --- a/lib/mapObjects/CObjectHandler.h +++ b/lib/mapObjects/CObjectHandler.h @@ -95,8 +95,6 @@ public: class DLL_LINKAGE CGObjectInstance : public IObjectInterface { public: - mutable std::string hoverName; - /// Position of bottom-right corner of object on map int3 pos; /// Type of object, e.g. town, hero, creature. @@ -141,33 +139,37 @@ public: virtual int getSightRadious() const; /// returns (x,y,0) offset to a visitable tile of object virtual int3 getVisitableOffset() const; - /// returns text visible in status bar - /// TODO: should accept selected hero as parameter and possibly - moved into object handler - virtual const std::string & getHoverText() const; /// Called mostly during map randomization to turn random object into a regular one (e.g. "Random Monster" into "Pikeman") virtual void setType(si32 ID, si32 subID); + /// returns text visible in status bar with specific hero/player active. + + /// Returns generic name of object, without any player-specific info + virtual std::string getObjectName() const; + + /// Returns hover name for situation when there are no selected heroes. Default = object name + virtual std::string getHoverText(PlayerColor player) const; + /// Returns hero-specific hover name, including visited/not visited info. Default = player-specific name + virtual std::string getHoverText(const CGHeroInstance * hero) const; + /** OVERRIDES OF IObjectInterface **/ void initObj() override; void onHeroVisit(const CGHeroInstance * h) const override; /// method for synchronous update. Note: For new properties classes should override setPropertyDer instead - void setProperty(ui8 what, ui32 val) override; + void setProperty(ui8 what, ui32 val) override final; //friend class CGameHandler; template void serialize(Handler &h, const int version) { - h & hoverName & pos & ID & subID & id & tempOwner & blockVisit & appearance; + h & pos & ID & subID & id & tempOwner & blockVisit & appearance; //definfo is handled by map serializer } protected: /// virtual method that allows synchronously update object state on server and all clients virtual void setPropertyDer(ui8 what, ui32 val); - /// Adds (visited) text if selected hero has visited object - /// TODO: remove? - void getNameVis(std::string &hname) const; /// Gives dummy bonus from this object to hero. Can be used to track visited state void giveDummyBonus(ObjectInstanceID heroID, ui8 duration = Bonus::ONE_DAY) const; }; diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index e9ed17781..368c3493a 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -434,25 +434,15 @@ void CGSeerHut::getRolloverText (MetaString &text, bool onHover) const text.addReplacement(seerName); } -const std::string & CGSeerHut::getHoverText() const +std::string CGSeerHut::getHoverText(PlayerColor player) const { - switch (ID) + std::string hoverName = getObjectName(); + if (ID == Obj::SEER_HUT && quest->progress != CQuest::NOT_ACTIVE) { - case Obj::SEER_HUT: - if (quest->progress != CQuest::NOT_ACTIVE) - { - hoverName = VLC->generaltexth->allTexts[347]; - boost::algorithm::replace_first(hoverName,"%s", seerName); - } - else //just seer hut - hoverName = VLC->objtypeh->getObjectName(ID); - break; - case Obj::QUEST_GUARD: - hoverName = VLC->objtypeh->getObjectName(ID); - break; - default: - logGlobal->debugStream() << "unrecognized quest object"; + hoverName = VLC->generaltexth->allTexts[347]; + boost::algorithm::replace_first(hoverName,"%s", seerName); } + if (quest->progress & quest->missionType) //rollover when the quest is active { MetaString ms; @@ -757,19 +747,14 @@ bool CGKeys::wasMyColorVisited (PlayerColor player) const return false; } -const std::string& CGKeys::getHoverText() const +std::string CGKeys::getHoverText(PlayerColor player) const { - bool visited = wasMyColorVisited (cb->getLocalPlayer()); - hoverName = getName() + "\n" + visitedTxt(visited); - return hoverName; + return getObjectName() + "\n" + visitedTxt(wasMyColorVisited(player)); } - -const std::string CGKeys::getName() const +std::string CGKeys::getObjectName() const { - std::string name; - name = VLC->generaltexth->tentColors[subID] + " " + VLC->objtypeh->getObjectName(ID); - return name; + return VLC->generaltexth->tentColors[subID] + " " + CGObjectInstance::getObjectName(); } bool CGKeymasterTent::wasVisited (PlayerColor player) const diff --git a/lib/mapObjects/CQuest.h b/lib/mapObjects/CQuest.h index ef39b61fb..788969106 100644 --- a/lib/mapObjects/CQuest.h +++ b/lib/mapObjects/CQuest.h @@ -95,7 +95,7 @@ public: CGSeerHut() : IQuestObject(){}; void initObj() override; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; void newTurn() const override; void onHeroVisit(const CGHeroInstance * h) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; @@ -138,10 +138,10 @@ public: static std::map > playerKeyMap; //[players][keysowned] //SubID 0 - lightblue, 1 - green, 2 - red, 3 - darkblue, 4 - brown, 5 - purple, 6 - white, 7 - black - const std::string getName() const; //depending on color bool wasMyColorVisited (PlayerColor player) const; - const std::string & getHoverText() const override; + std::string getObjectName() const override; //depending on color + std::string getHoverText(PlayerColor player) const override; template void serialize(Handler &h, const int version) { diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 5fc3731ff..94c7b6386 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -375,19 +375,18 @@ static std::string & visitedTxt(const bool visited) return VLC->generaltexth->allTexts[id]; } -const std::string & CRewardableObject::getHoverText() const +std::string CRewardableObject::getHoverText(PlayerColor player) const { - const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); - hoverName = VLC->objtypeh->getObjectName(ID); if(visitMode != VISIT_UNLIMITED) - { - bool visited = wasVisited(cb->getCurrentPlayer()); - if (h) - visited |= wasVisited(h); + return getObjectName() + " " + visitedTxt(wasVisited(player)); + return getObjectName(); +} - hoverName += " " + visitedTxt(visited); - } - return hoverName; +std::string CRewardableObject::getHoverText(const CGHeroInstance * hero) const +{ + if(visitMode != VISIT_UNLIMITED) + return getObjectName() + " " + visitedTxt(wasVisited(hero)); + return getObjectName(); } void CRewardableObject::setPropertyDer(ui8 what, ui32 val) diff --git a/lib/mapObjects/CRewardableObject.h b/lib/mapObjects/CRewardableObject.h index 58d83c2c0..a32abcedd 100644 --- a/lib/mapObjects/CRewardableObject.h +++ b/lib/mapObjects/CRewardableObject.h @@ -209,7 +209,8 @@ protected: public: void setPropertyDer(ui8 what, ui32 val) override; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; + std::string getHoverText(const CGHeroInstance * hero) const override; /// Visitability checks. Note that hero check includes check for hero owner (returns true if object was visited by player) bool wasVisited (PlayerColor player) const override; diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index d5136a697..7e596288e 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -78,17 +78,16 @@ bool CPlayersVisited::wasVisited( TeamID team ) const return false; } -const std::string & CGCreature::getHoverText() const +std::string CGCreature::getHoverText(PlayerColor player) const { if(stacks.empty()) { - static const std::string errorValue("!!!INVALID_STACK!!!"); - //should not happen... logGlobal->errorStream() << "Invalid stack at tile " << pos << ": subID=" << subID << "; id=" << id; - return errorValue; // references to temporary are illegal - use pre-constructed string + return "!!!INVALID_STACK!!!"; } + std::string hoverName; MetaString ms; int pom = stacks.begin()->second->getQuantityID(); pom = 172 + 3*pom; @@ -96,30 +95,34 @@ const std::string & CGCreature::getHoverText() const ms << " " ; ms.addTxt(MetaString::CRE_PL_NAMES,subID); ms.toString(hoverName); - - if(const CGHeroInstance *selHero = cb->getSelectedHero(cb->getCurrentPlayer())) - { - const JsonNode & texts = VLC->generaltexth->localizedTexts["adventureMap"]["monsterThreat"]; - - hoverName += texts["title"].String(); - int choice; - double ratio = ((double)getArmyStrength() / selHero->getTotalStrength()); - if (ratio < 0.1) choice = 0; - else if (ratio < 0.25) choice = 1; - else if (ratio < 0.6) choice = 2; - else if (ratio < 0.9) choice = 3; - else if (ratio < 1.1) choice = 4; - else if (ratio < 1.3) choice = 5; - else if (ratio < 1.8) choice = 6; - else if (ratio < 2.5) choice = 7; - else if (ratio < 4) choice = 8; - else if (ratio < 8) choice = 9; - else if (ratio < 20) choice = 10; - else choice = 11; - hoverName += texts["levels"].Vector()[choice].String(); - } return hoverName; } + +std::string CGCreature::getHoverText(const CGHeroInstance * hero) const +{ + std::string hoverName = getHoverText(hero->tempOwner); + + const JsonNode & texts = VLC->generaltexth->localizedTexts["adventureMap"]["monsterThreat"]; + + hoverName += texts["title"].String(); + int choice; + double ratio = ((double)getArmyStrength() / hero->getTotalStrength()); + if (ratio < 0.1) choice = 0; + else if (ratio < 0.25) choice = 1; + else if (ratio < 0.6) choice = 2; + else if (ratio < 0.9) choice = 3; + else if (ratio < 1.1) choice = 4; + else if (ratio < 1.3) choice = 5; + else if (ratio < 1.8) choice = 6; + else if (ratio < 2.5) choice = 7; + else if (ratio < 4) choice = 8; + else if (ratio < 8) choice = 9; + else if (ratio < 20) choice = 10; + else choice = 11; + hoverName += texts["levels"].Vector()[choice].String(); + return hoverName; +} + void CGCreature::onHeroVisit( const CGHeroInstance * h ) const { int action = takenAction(h); @@ -443,21 +446,6 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult & } else { - //int killedAmount=0; - //for(std::set >::iterator i=result->casualties[1].begin(); i!=result->casualties[1].end(); i++) - // if(i->first == subID) - // killedAmount += i->second; - //cb->setAmount(id, slots.find(0)->second.second - killedAmount); - - /* - MetaString ms; - int pom = slots.find(0)->second.getQuantityID(); - pom = 174 + 3*pom + 1; - ms << std::pair(6,pom) << " " << std::pair(7,subID); - cb->setHoverName(id,&ms); - cb->setObjProperty(id, 11, slots.begin()->second.count * 1000); - */ - //merge stacks into one TSlots::const_iterator i; CCreature * cre = VLC->creh->creatures[formation.basicType]; @@ -554,38 +542,48 @@ void CGMine::initObj() assert(!possibleResources.empty()); producedResource = *RandomGeneratorUtil::nextItem(possibleResources, cb->gameState()->getRandomGenerator()); tempOwner = PlayerColor::NEUTRAL; - hoverName = VLC->generaltexth->mines[7].first + "\n" + VLC->generaltexth->allTexts[202] + " " + troglodytes->getQuantityTXT(false) + " " + troglodytes->type->namePl; } else { producedResource = static_cast(subID); - - MetaString ms; - ms << std::pair(9,producedResource); if(tempOwner >= PlayerColor::PLAYER_LIMIT) tempOwner = PlayerColor::NEUTRAL; - else - ms << " (" << std::pair(6,23+tempOwner.getNum()) << ")"; - ms.toString(hoverName); } producedQuantity = defaultResProduction(); } +std::string CGMine::getObjectName() const +{ + return VLC->generaltexth->mines.at(subID).first; +} + +std::string CGMine::getHoverText(PlayerColor player) const +{ + + std::string hoverName = getObjectName(); // Sawmill + + if (tempOwner != PlayerColor::NEUTRAL) + { + hoverName += "\n"; + hoverName += VLC->generaltexth->arraytxt[23 + tempOwner.getNum()]; // owned by Red Player + hoverName += "\n(" + VLC->generaltexth->restypes[producedResource] + ")"; + } + + for (auto & slot : Slots()) // guarded by a few Pikeman + { + hoverName += "\n"; + hoverName += getRoughAmount(slot.first); + hoverName += getCreature(slot.first)->namePl; + } + return hoverName; +} + void CGMine::flagMine(PlayerColor player) const { assert(tempOwner != player); cb->setOwner(this, player); //not ours? flag it! - MetaString ms; - ms << std::pair(9,subID) << "\n(" << std::pair(6,23+player.getNum()) << ")"; - if(subID == 7) - { - ms << "(%s)"; - ms.addReplacement(MetaString::RES_NAMES, producedResource); - } - cb->setHoverName(this,&ms); - InfoWindow iw; iw.soundID = soundBase::FLAGMINE; iw.text.addTxt(MetaString::MINE_EVNTS,producedResource); //not use subID, abandoned mines uses default mine texts @@ -626,10 +624,14 @@ void CGMine::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) con cb->startBattleI(hero, this); } +std::string CGResource::getHoverText(PlayerColor player) const +{ + return VLC->generaltexth->restypes[subID]; +} + void CGResource::initObj() { blockVisit = true; - hoverName = VLC->generaltexth->restypes[subID]; if(!amount) { @@ -866,7 +868,6 @@ void CGArtifact::initObj() blockVisit = true; if(ID == Obj::ARTIFACT) { - hoverName = VLC->arth->artifacts[subID]->Name(); if(!storedArtifact->artType) storedArtifact->setType(VLC->arth->artifacts[subID]); } @@ -879,6 +880,11 @@ void CGArtifact::initObj() //assert(storedArtifact->artType->id == subID); //this does not stop desync } +std::string CGArtifact::getObjectName() const +{ + return VLC->arth->artifacts[subID]->Name(); +} + void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const { if(!stacksCount()) @@ -985,20 +991,25 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const cb->showInfoDialog(&iw); } -const std::string & CGWitchHut::getHoverText() const +std::string CGWitchHut::getHoverText(PlayerColor player) const { - hoverName = VLC->objtypeh->getObjectName(ID); - if(wasVisited(cb->getLocalPlayer())) + std::string hoverName = getObjectName(); + if(wasVisited(player)) { hoverName += "\n" + VLC->generaltexth->allTexts[356]; // + (learn %s) boost::algorithm::replace_first(hoverName,"%s",VLC->generaltexth->skillName[ability]); - const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); - if(h && h->getSecSkillLevel(SecondarySkill(ability))) //hero knows that ability - hoverName += "\n\n" + VLC->generaltexth->allTexts[357]; // (Already learned) } return hoverName; } +std::string CGWitchHut::getHoverText(const CGHeroInstance * hero) const +{ + std::string hoverName = getHoverText(hero->tempOwner); + if(hero->getSecSkillLevel(SecondarySkill(ability))) //hero knows that ability + hoverName += "\n\n" + VLC->generaltexth->allTexts[357]; // (Already learned) + return hoverName; +} + void CGMagicWell::onHeroVisit( const CGHeroInstance * h ) const { int message; @@ -1020,10 +1031,9 @@ void CGMagicWell::onHeroVisit( const CGHeroInstance * h ) const showInfoDialog(h,message,soundBase::faerie); } -const std::string & CGMagicWell::getHoverText() const +std::string CGMagicWell::getHoverText(const CGHeroInstance * hero) const { - getNameVis(hoverName); - return hoverName; + return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(Bonus::OBJECT,ID)); } void CGObservatory::onHeroVisit( const CGHeroInstance * h ) const @@ -1120,20 +1130,25 @@ void CGShrine::initObj() } } -const std::string & CGShrine::getHoverText() const +std::string CGShrine::getHoverText(PlayerColor player) const { - hoverName = VLC->objtypeh->getObjectName(ID); - if(wasVisited(cb->getCurrentPlayer())) //TODO: use local player, not current + std::string hoverName = getObjectName(); + if(wasVisited(player)) { hoverName += "\n" + VLC->generaltexth->allTexts[355]; // + (learn %s) boost::algorithm::replace_first(hoverName,"%s", spell.toSpell()->name); - const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer()); - if(h && vstd::contains(h->spells,spell)) //hero knows that ability - hoverName += "\n\n" + VLC->generaltexth->allTexts[354]; // (Already learned) } return hoverName; } +std::string CGShrine::getHoverText(const CGHeroInstance * hero) const +{ + std::string hoverName = getHoverText(hero->tempOwner); + if(vstd::contains(hero->spells, spell)) //hero knows that spell + hoverName += "\n\n" + VLC->generaltexth->allTexts[354]; // (Already learned) + return hoverName; +} + void CGSignBottle::initObj() { //if no text is set than we pick random from the predefined ones @@ -1329,10 +1344,9 @@ void CGSirens::initObj() blockVisit = true; } -const std::string & CGSirens::getHoverText() const +std::string CGSirens::getHoverText(const CGHeroInstance * hero) const { - getNameVis(hoverName); - return hoverName; + return getObjectName() + " " + visitedTxt(hero->hasBonusFrom(Bonus::OBJECT,ID)); } void CGSirens::onHeroVisit( const CGHeroInstance * h ) const @@ -1503,11 +1517,9 @@ void CGObelisk::initObj() obeliskCount++; } -const std::string & CGObelisk::getHoverText() const +std::string CGObelisk::getHoverText(PlayerColor player) const { - bool visited = wasVisited(cb->getLocalPlayer()); - hoverName = VLC->objtypeh->getObjectName(ID) + " " + visitedTxt(visited); - return hoverName; + return getObjectName() + " " + visitedTxt(wasVisited(player)); } void CGObelisk::setPropertyDer( ui8 what, ui32 val ) @@ -1557,11 +1569,10 @@ void CGLighthouse::initObj() } } -const std::string & CGLighthouse::getHoverText() const +std::string CGLighthouse::getHoverText(PlayerColor player) const { - hoverName = VLC->objtypeh->getObjectName(ID); //TODO: owned by %s player - return hoverName; + return getObjectName(); } void CGLighthouse::giveBonusTo( PlayerColor player ) const diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index 8f66bb31e..01d6d813f 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -48,7 +48,8 @@ public: bool refusedJoining; void onHeroVisit(const CGHeroInstance * h) const override; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; + std::string getHoverText(const CGHeroInstance * hero) const override; void initObj() override; void newTurn() const override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; @@ -106,7 +107,8 @@ public: std::vector allowedAbilities; ui32 ability; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; + std::string getHoverText(const CGHeroInstance * hero) const override; void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; template void serialize(Handler &h, const int version) @@ -159,6 +161,8 @@ public: void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; + std::string getObjectName() const override; + void pick( const CGHeroInstance * h ) const; void initObj() override; @@ -179,6 +183,7 @@ public: void initObj() override; void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override; void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override; + std::string getHoverText(PlayerColor player) const override; void collectRes(PlayerColor player) const; @@ -195,7 +200,8 @@ public: SpellID spell; //id of spell or NONE if random void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; + std::string getHoverText(const CGHeroInstance * hero) const override; template void serialize(Handler &h, const int version) { @@ -217,6 +223,10 @@ public: void flagMine(PlayerColor player) const; void newTurn() const override; void initObj() override; + + std::string getObjectName() const override; + std::string getHoverText(PlayerColor player) const override; + template void serialize(Handler &h, const int version) { h & static_cast(*this); @@ -245,7 +255,7 @@ class DLL_LINKAGE CGMagicWell : public CGObjectInstance //objects giving bonuses { public: void onHeroVisit(const CGHeroInstance * h) const override; - const std::string & getHoverText() const override; + std::string getHoverText(const CGHeroInstance * hero) const override; template void serialize(Handler &h, const int version) { @@ -257,7 +267,7 @@ class DLL_LINKAGE CGSirens : public CGObjectInstance { public: void onHeroVisit(const CGHeroInstance * h) const override; - const std::string & getHoverText() const override; + std::string getHoverText(const CGHeroInstance * hero) const override; void initObj() override; template void serialize(Handler &h, const int version) @@ -352,7 +362,7 @@ public: void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; template void serialize(Handler &h, const int version) { @@ -367,7 +377,7 @@ class DLL_LINKAGE CGLighthouse : public CGObjectInstance public: void onHeroVisit(const CGHeroInstance * h) const override; void initObj() override; - const std::string & getHoverText() const override; + std::string getHoverText(PlayerColor player) const override; template void serialize(Handler &h, const int version) { diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index 15e66c26e..1d53f8d88 100644 --- a/lib/mapping/CMap.cpp +++ b/lib/mapping/CMap.cpp @@ -432,7 +432,7 @@ const CGObjectInstance * CMap::getObjectiveObjectFrom(int3 pos, Obj::EObj type) } assert(bestMatch != nullptr); // if this happens - victory conditions or map itself is very, very broken - logGlobal->errorStream() << "Will use " << bestMatch->getHoverText() << " from " << bestMatch->pos; + logGlobal->errorStream() << "Will use " << bestMatch->getObjectName() << " from " << bestMatch->pos; return bestMatch; } diff --git a/lib/registerTypes/RegisterTypes.h b/lib/registerTypes/RegisterTypes.h index dd7467108..d8de270c7 100644 --- a/lib/registerTypes/RegisterTypes.h +++ b/lib/registerTypes/RegisterTypes.h @@ -234,7 +234,6 @@ void registerTypesClientPacks1(Serializer &s) s.template registerType(); s.template registerType(); s.template registerType(); - s.template registerType(); s.template registerType(); s.template registerType(); s.template registerType(); diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index de78ebab4..a3285eb6d 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1849,12 +1849,6 @@ void CGameHandler::setOwner(const CGObjectInstance * obj, PlayerColor owner) } } -void CGameHandler::setHoverName(const CGObjectInstance * obj, MetaString* name) -{ - SetHoverName shn(obj->id, *name); - sendAndApply(&shn); -} - void CGameHandler::showBlockingDialog( BlockingDialog *iw ) { auto dialogQuery = make_shared(*iw); @@ -4992,7 +4986,7 @@ bool CGameHandler::isAllowedExchange( ObjectInstanceID id1, ObjectInstanceID id2 void CGameHandler::objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h ) { - logGlobal->traceStream() << h->nodeName() << " visits " << obj->getHoverText(); + logGlobal->traceStream() << h->nodeName() << " visits " << obj->getObjectName(); auto visitQuery = make_shared(obj, h, obj->visitablePos()); queries.addQuery(visitQuery); //TODO real visit pos diff --git a/server/CGameHandler.h b/server/CGameHandler.h index e09dd9152..1b91ee901 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -127,7 +127,6 @@ public: bool removeObject(const CGObjectInstance * obj) override; void setBlockVis(ObjectInstanceID objid, bool bv) override; void setOwner(const CGObjectInstance * obj, PlayerColor owner) override; - void setHoverName(const CGObjectInstance * objid, MetaString * name) override; void changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs=false) override; void changeSecSkill(const CGHeroInstance * hero, SecondarySkill which, int val, bool abs=false) override; //void showInfoDialog(InfoWindow *iw) override; diff --git a/server/CQuery.cpp b/server/CQuery.cpp index e7ecb0355..45bffae79 100644 --- a/server/CQuery.cpp +++ b/server/CQuery.cpp @@ -322,7 +322,7 @@ CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(const HeroLevelUp &Hlu) void CHeroLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color) { assert(answer); - logGlobal->traceStream() << "Completing hero level-up query. " << hlu.hero->getHoverText() << " gains skill " << *answer; + logGlobal->traceStream() << "Completing hero level-up query. " << hlu.hero->getObjectName() << " gains skill " << *answer; gh->levelUpHero(hlu.hero, hlu.skills[*answer]); } @@ -340,7 +340,7 @@ CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(const CommanderLevelU void CCommanderLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color) { assert(answer); - logGlobal->traceStream() << "Completing commander level-up query. Commander of hero " << clu.hero->getHoverText() << " gains skill " << *answer; + logGlobal->traceStream() << "Completing commander level-up query. Commander of hero " << clu.hero->getObjectName() << " gains skill " << *answer; gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]); } From 6e3eaeee218fd1dcea2c00e4c3f0be81e9bb1e7f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 25 Jun 2014 00:23:56 +0300 Subject: [PATCH 08/39] Minor fix to schema, server will print visited objects in debug log --- config/schemas/mod.json | 5 +++++ server/CGameHandler.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/config/schemas/mod.json b/config/schemas/mod.json index be0e5b9fd..8206b04d0 100644 --- a/config/schemas/mod.json +++ b/config/schemas/mod.json @@ -87,6 +87,11 @@ "description": "List of configuration files for heroes", "items": { "type":"string", "format" : "textFile" } }, + "objects": { + "type":"array", + "description": "List of configuration files for objects", + "items": { "type":"string", "format" : "textFile" } + }, "spells": { "type":"array", "description": "List of configuration files for spells", diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index a3285eb6d..703ac2346 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -4986,7 +4986,7 @@ bool CGameHandler::isAllowedExchange( ObjectInstanceID id1, ObjectInstanceID id2 void CGameHandler::objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h ) { - logGlobal->traceStream() << h->nodeName() << " visits " << obj->getObjectName(); + logGlobal->debugStream() << h->nodeName() << " visits " << obj->getObjectName() << "(" << obj->ID << ":" << obj->subID << ")"; auto visitQuery = make_shared(obj, h, obj->visitablePos()); queries.addQuery(visitQuery); //TODO real visit pos From 3b0ecee678d81aa4db43fba5257057a54fccf554 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 25 Jun 2014 00:37:33 +0300 Subject: [PATCH 09/39] Ugly workaround for DLL_LINKAGE issue. Should be removed once I figure out what's triggering it. --- lib/NetPacks.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 0e590903e..9a6bbf182 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1512,7 +1512,13 @@ struct ObstaclesRemoved : public CPackForClient //3014 } }; +//FIXME: figure out why gcc fails to find type_info for this class with -fvisibility=hidden flag set +#ifdef __linux__ +struct DLL_LINKAGE CatapultAttack : public CPackForClient //3015 +#else struct CatapultAttack : public CPackForClient //3015 +#endif + { struct AttackInfo { From 32240da34eba95cc17f72075d52ff574b4172958 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 25 Jun 2014 17:11:07 +0300 Subject: [PATCH 10/39] Reduced number of #include's in headers. May break compilation on Win since some net packs now need DLL_LINKAGE --- AI/VCAI/VCAI.cpp | 1 + client/NetPacksClient.cpp | 1 + client/battle/CBattleInterfaceClasses.cpp | 1 + lib/BattleState.cpp | 6 +- lib/BattleState.h | 9 +- lib/CArtHandler.h | 4 +- lib/CBattleCallback.cpp | 4 +- lib/CGameInfoCallback.cpp | 1 + lib/CGameState.cpp | 53 ---------- lib/CGameState.h | 66 +----------- lib/CGameStateFwd.h | 120 ++++++++++++++++++++++ lib/CMakeLists.txt | 3 +- lib/IGameCallback.cpp | 3 + lib/IHandlerBase.cpp | 19 ++++ lib/IHandlerBase.h | 10 +- lib/NetPacks.h | 31 +++--- lib/NetPacksLib.cpp | 16 ++- lib/mapObjects/CArmedInstance.h | 3 + lib/mapObjects/CBank.cpp | 2 + lib/mapObjects/CGHeroInstance.cpp | 5 +- lib/mapObjects/CGHeroInstance.h | 2 + lib/mapObjects/CGMarket.cpp | 3 + lib/mapObjects/CGPandoraBox.cpp | 2 + lib/mapObjects/CGPandoraBox.h | 3 + lib/mapObjects/CGTownInstance.cpp | 3 + lib/mapObjects/CGTownInstance.h | 1 + lib/mapObjects/CObjectClassesHandler.h | 1 + lib/mapObjects/CObjectHandler.cpp | 3 + lib/mapObjects/CObjectHandler.h | 5 +- lib/mapObjects/CQuest.cpp | 2 + lib/mapObjects/CQuest.h | 2 + lib/mapObjects/CRewardableConstructor.cpp | 1 + lib/mapObjects/CRewardableObject.cpp | 2 + lib/mapObjects/CRewardableObject.h | 1 + lib/mapObjects/CommonConstructors.cpp | 2 + lib/mapObjects/MiscObjects.cpp | 3 + lib/mapObjects/MiscObjects.h | 1 + lib/registerTypes/RegisterTypes.h | 1 + server/CGameHandler.cpp | 2 +- server/CGameHandler.h | 2 +- 40 files changed, 241 insertions(+), 159 deletions(-) create mode 100644 lib/CGameStateFwd.h create mode 100644 lib/IHandlerBase.cpp diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index f850d1996..c18d5ca18 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -5,6 +5,7 @@ #include "../../lib/mapObjects/MapObjects.h" #include "../../lib/CConfigHandler.h" #include "../../lib/CHeroHandler.h" +#include "../../lib/CModHandler.h" /* diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 7f6f5028c..29d36f43f 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -15,6 +15,7 @@ #include "../lib/VCMIDirs.h" #include "../lib/CSpellHandler.h" #include "../lib/CSoundBase.h" +#include "../lib/StartInfo.h" #include "mapHandler.h" #include "GUIClasses.h" #include "../lib/CConfigHandler.h" diff --git a/client/battle/CBattleInterfaceClasses.cpp b/client/battle/CBattleInterfaceClasses.cpp index fcf3d878e..cbfa489bc 100644 --- a/client/battle/CBattleInterfaceClasses.cpp +++ b/client/battle/CBattleInterfaceClasses.cpp @@ -17,6 +17,7 @@ #include "../../lib/NetPacks.h" #include "../../lib/CCreatureHandler.h" #include "../../lib/BattleState.h" +#include "../../lib/StartInfo.h" #include "../CMusicHandler.h" #include "../CVideoHandler.h" #include "../../lib/CTownHandler.h" diff --git a/lib/BattleState.cpp b/lib/BattleState.cpp index 8b8395157..fb2b1eeff 100644 --- a/lib/BattleState.cpp +++ b/lib/BattleState.cpp @@ -365,13 +365,11 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp if(town) { curB->town = town; - curB->siege = town->fortLevel(); curB->terrainType = VLC->townh->factions[town->subID]->nativeTerrain; } else { curB->town = nullptr; - curB->siege = CGTownInstance::NONE; curB->terrainType = terrain; } @@ -574,13 +572,13 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, ETerrainType terrain, BFieldTyp } - if (curB->siege == CGTownInstance::CITADEL || curB->siege == CGTownInstance::CASTLE) + if (curB->town && curB->town->fortLevel() >= CGTownInstance::CITADEL) { // keep tower CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -2); stacks.push_back(stack); - if (curB->siege == CGTownInstance::CASTLE) + if (curB->town->fortLevel() >= CGTownInstance::CASTLE) { // lower tower + upper tower CStack * stack = curB->generateNewStack(CStackBasicDescriptor(CreatureID::ARROW_TOWERS, 1), false, SlotID(255), -4); diff --git a/lib/BattleState.h b/lib/BattleState.h index 3d8ac4587..4eb774f4d 100644 --- a/lib/BattleState.h +++ b/lib/BattleState.h @@ -4,8 +4,8 @@ #include "BattleHex.h" #include "HeroBonus.h" #include "CCreatureSet.h" -#include "mapObjects/CGTownInstance.h" -#include "mapObjects/CGHeroInstance.h" +#include "mapObjects/CArmedInstance.h" // for army serialization +#include "mapObjects/CGHeroInstance.h" // for commander serialization #include "CCreatureHandler.h" #include "CObstacleInstance.h" #include "ConstTransitivePtr.h" @@ -83,8 +83,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb { std::array sides; //sides[0] - attacker, sides[1] - defender si32 round, activeStack, selectedStack; - CGTownInstance::EFortLevel siege; - const CGTownInstance * town; //used during town siege - id of attacked town; -1 if not town defence + const CGTownInstance * town; //used during town siege, nullptr if this is not a siege (note that fortless town IS also a siege) int3 tile; //for background and bonuses std::vector stacks; std::vector > obstacles; @@ -99,7 +98,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb template void serialize(Handler &h, const int version) { h & sides; - h & round & activeStack & selectedStack & siege & town & tile & stacks & obstacles + h & round & activeStack & selectedStack & town & tile & stacks & obstacles & si & battlefieldType & terrainType; h & tacticsSide & tacticDistance; h & static_cast(*this); diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index 592e1de58..805cc6aeb 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -2,8 +2,8 @@ #include "../lib/HeroBonus.h" -#include "../lib/ConstTransitivePtr.h" -#include "JsonNode.h" +//#include "../lib/ConstTransitivePtr.h" +//#include "JsonNode.h" #include "GameConstants.h" #include "IHandlerBase.h" diff --git a/lib/CBattleCallback.cpp b/lib/CBattleCallback.cpp index 1744ca27a..10692aa8d 100644 --- a/lib/CBattleCallback.cpp +++ b/lib/CBattleCallback.cpp @@ -409,7 +409,7 @@ ui8 CBattleInfoEssentials::playerToSide(PlayerColor player) const ui8 CBattleInfoEssentials::battleGetSiegeLevel() const { RETURN_IF_NOT_BATTLE(0); - return getBattle()->siege; + return getBattle()->town ? getBattle()->town->fortLevel() : CGTownInstance::NONE; } bool CBattleInfoEssentials::battleCanSurrender(PlayerColor player) const @@ -429,7 +429,7 @@ bool CBattleInfoEssentials::battleHasHero(ui8 side) const si8 CBattleInfoEssentials::battleGetWallState(int partOfWall) const { RETURN_IF_NOT_BATTLE(0); - if(getBattle()->siege == CGTownInstance::NONE) + if(getBattle()->town == nullptr || getBattle()->town->fortLevel() == CGTownInstance::NONE) return EWallState::NONE; assert(partOfWall >= 0 && partOfWall < EWallPart::PARTS_COUNT); diff --git a/lib/CGameInfoCallback.cpp b/lib/CGameInfoCallback.cpp index 5281bccb1..2f249dec8 100644 --- a/lib/CGameInfoCallback.cpp +++ b/lib/CGameInfoCallback.cpp @@ -16,6 +16,7 @@ #include "StartInfo.h" // for StartInfo #include "BattleState.h" // for BattleInfo #include "NetPacks.h" // for InfoWindow +#include "CModHandler.h" //TODO make clean #define ERROR_VERBOSE_OR_NOT_RET_VAL_IF(cond, verbose, txt, retVal) do {if(cond){if(verbose)logGlobal->errorStream() << BOOST_CURRENT_FUNCTION << ": " << txt; return retVal;}} while(0) diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 110521f73..a5fe9923b 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -3509,59 +3509,6 @@ CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance allowEmbarkAndDisembark = true; } -EVictoryLossCheckResult::EVictoryLossCheckResult() : - intValue(0) -{ -} - -EVictoryLossCheckResult::EVictoryLossCheckResult(si32 intValue, std::string toSelf, std::string toOthers) : - messageToSelf(toSelf), - messageToOthers(toOthers), - intValue(intValue) -{ -} - -bool EVictoryLossCheckResult::operator==(EVictoryLossCheckResult const & other) const -{ - return intValue == other.intValue; -} - -bool EVictoryLossCheckResult::operator!=(EVictoryLossCheckResult const & other) const -{ - return intValue != other.intValue; -} - -bool EVictoryLossCheckResult::victory() const -{ - return intValue == VICTORY; -} - -bool EVictoryLossCheckResult::loss() const -{ - return intValue == DEFEAT; -} - -EVictoryLossCheckResult EVictoryLossCheckResult::invert() -{ - return EVictoryLossCheckResult(-intValue, messageToOthers, messageToSelf); -} - -EVictoryLossCheckResult EVictoryLossCheckResult::victory(std::string toSelf, std::string toOthers) -{ - return EVictoryLossCheckResult(VICTORY, toSelf, toOthers); -} - -EVictoryLossCheckResult EVictoryLossCheckResult::defeat(std::string toSelf, std::string toOthers) -{ - return EVictoryLossCheckResult(DEFEAT, toSelf, toOthers); -} - -std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult) -{ - os << victoryLossCheckResult.messageToSelf; - return os; -} - CRandomGenerator & CGameState::getRandomGenerator() { return rand; diff --git a/lib/CGameState.h b/lib/CGameState.h index 0d8a8c8f2..222e9ce76 100644 --- a/lib/CGameState.h +++ b/lib/CGameState.h @@ -15,6 +15,7 @@ #include "ResourceSet.h" #include "int3.h" #include "CRandomGenerator.h" +#include "CGameStateFwd.h" /* * CGameState.h, part of VCMI engine @@ -355,39 +356,6 @@ public: struct BattleInfo; -class DLL_LINKAGE EVictoryLossCheckResult -{ -public: - static EVictoryLossCheckResult victory(std::string toSelf, std::string toOthers); - static EVictoryLossCheckResult defeat(std::string toSelf, std::string toOthers); - - EVictoryLossCheckResult(); - bool operator==(EVictoryLossCheckResult const & other) const; - bool operator!=(EVictoryLossCheckResult const & other) const; - bool victory() const; - bool loss() const; - - EVictoryLossCheckResult invert(); - - std::string messageToSelf; - std::string messageToOthers; - - template void serialize(Handler &h, const int version) - { - h & intValue & messageToSelf & messageToOthers; - } -private: - enum EResult - { - DEFEAT = -1, - INGAME = 0, - VICTORY= +1 - }; - - EVictoryLossCheckResult(si32 intValue, std::string toSelf, std::string toOthers); - si32 intValue; // uses EResult -}; - DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult); class DLL_LINKAGE CGameState : public CNonConstInfoCallback @@ -533,35 +501,3 @@ private: friend class CMapHandler; friend class CGameHandler; }; - -struct DLL_LINKAGE QuestInfo //universal interface for human and AI -{ - const CQuest * quest; - const CGObjectInstance * obj; //related object, most likely Seer Hut - int3 tile; - - QuestInfo(){}; - QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) : - quest (Quest), obj (Obj), tile (Tile){}; - - //FIXME: assignment operator should return QuestInfo & - bool operator= (const QuestInfo &qi) - { - quest = qi.quest; - obj = qi.obj; - tile = qi.tile; - return true; - } - - bool operator== (const QuestInfo & qi) const - { - return (quest == qi.quest && obj == qi.obj); - } - - //std::vector > texts //allow additional info for quest log? - - template void serialize(Handler &h, const int version) - { - h & quest & obj & tile; - } -}; diff --git a/lib/CGameStateFwd.h b/lib/CGameStateFwd.h new file mode 100644 index 000000000..b284373e3 --- /dev/null +++ b/lib/CGameStateFwd.h @@ -0,0 +1,120 @@ +#pragma once + +/* + * CGameStateFwd.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 + * + */ + +class CQuest; +class CGObjectInstance; + +class DLL_LINKAGE EVictoryLossCheckResult +{ +public: + static EVictoryLossCheckResult victory(std::string toSelf, std::string toOthers) + { + return EVictoryLossCheckResult(VICTORY, toSelf, toOthers); + } + + static EVictoryLossCheckResult defeat(std::string toSelf, std::string toOthers) + { + return EVictoryLossCheckResult(DEFEAT, toSelf, toOthers); + } + + EVictoryLossCheckResult(): + intValue(0) + { + } + + bool operator==(EVictoryLossCheckResult const & other) const + { + return intValue == other.intValue; + } + + bool operator!=(EVictoryLossCheckResult const & other) const + { + return intValue != other.intValue; + } + + bool victory() const + { + return intValue == VICTORY; + } + bool loss() const + { + return intValue == DEFEAT; + } + + EVictoryLossCheckResult invert() + { + return EVictoryLossCheckResult(-intValue, messageToOthers, messageToSelf); + } + + std::string messageToSelf; + std::string messageToOthers; + + template void serialize(Handler &h, const int version) + { + h & intValue & messageToSelf & messageToOthers; + } +private: + enum EResult + { + DEFEAT = -1, + INGAME = 0, + VICTORY= +1 + }; + + EVictoryLossCheckResult(si32 intValue, std::string toSelf, std::string toOthers): + messageToSelf(toSelf), + messageToOthers(toOthers), + intValue(intValue) + { + } + + si32 intValue; // uses EResult +}; + +/*static std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult) +{ + os << victoryLossCheckResult.messageToSelf; + return os; +}*/ + +struct DLL_LINKAGE QuestInfo //universal interface for human and AI +{ + const CQuest * quest; + const CGObjectInstance * obj; //related object, most likely Seer Hut + int3 tile; + + QuestInfo(){}; + QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) : + quest (Quest), obj (Obj), tile (Tile){}; + + //FIXME: assignment operator should return QuestInfo & + bool operator= (const QuestInfo &qi) + { + quest = qi.quest; + obj = qi.obj; + tile = qi.tile; + return true; + } + + bool operator== (const QuestInfo & qi) const + { + return (quest == qi.quest && obj == qi.obj); + } + + //std::vector > texts //allow additional info for quest log? + + template void serialize(Handler &h, const int version) + { + h & quest & obj & tile; + } +}; + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index f426a13a6..62764080e 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -82,6 +82,7 @@ set(lib_SRCS ResourceSet.cpp VCMI_Lib.cpp VCMIDirs.cpp + IHandlerBase.cpp IGameCallback.cpp CGameInfoCallback.cpp @@ -118,8 +119,8 @@ set(lib_HEADERS GameConstants.h StringConstants.h IGameEventsReceiver.h - IHandlerBase.h int3.h + CGameStateFwd.h Interprocess.h NetPacks.h NetPacksBase.h diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index 98bcf2c4a..7712b192b 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -15,9 +15,12 @@ #include "CSpellHandler.h" // for CSpell #include "NetPacks.h" #include "CBonusTypeHandler.h" +#include "CModHandler.h" #include "Connection.h" // for SAVEGAME_MAGIC #include "mapObjects/CObjectClassesHandler.h" +#include "StartInfo.h" +#include "CGameState.h" void CPrivilagedInfoCallback::getFreeTiles (std::vector &tiles) const { diff --git a/lib/IHandlerBase.cpp b/lib/IHandlerBase.cpp new file mode 100644 index 000000000..bddbae3ba --- /dev/null +++ b/lib/IHandlerBase.cpp @@ -0,0 +1,19 @@ +/* + * IHandlerBase.cpp, 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 + * + */ + +#include "StdInc.h" +#include "IHandlerBase.h" +#include "CModHandler.h" + + +void IHandlerBase::registerObject(std::string scope, std::string type_name, std::string name, si32 index) +{ + return VLC->modh->identifiers.registerObject(scope, type_name, name, index); +} diff --git a/lib/IHandlerBase.h b/lib/IHandlerBase.h index 2ae74235e..c26b6f944 100644 --- a/lib/IHandlerBase.h +++ b/lib/IHandlerBase.h @@ -11,7 +11,7 @@ */ #include "../lib/ConstTransitivePtr.h" #include "VCMI_Lib.h" - #include "CModHandler.h" + //#include "CModHandler.h" class JsonNode; @@ -22,6 +22,9 @@ class DLL_LINKAGE IHandlerBase // Object * loadFromJson(const JsonNode & json); // where Object is type of data loaded by handler // primary used in loadObject methods +protected: + /// Calls modhandler. Mostly needed to avoid large number of includes in headers + void registerObject(std::string scope, std::string type_name, std::string name, si32 index); public: /// loads all original game data in vector of json nodes @@ -48,7 +51,6 @@ public: virtual ~IHandlerBase(){} }; - template class CHandlerBase: public IHandlerBase { public: @@ -68,7 +70,7 @@ public: objects.push_back(object); - VLC->modh->identifiers.registerObject(scope, type_name, name, object->id); + registerObject(scope, type_name, name, object->id); } void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override { @@ -80,7 +82,7 @@ public: assert(objects[index] == nullptr); // ensure that this id was not loaded before objects[index] = object; - VLC->modh->identifiers.registerObject(scope,type_name, name, object->id); + registerObject(scope,type_name, name, object->id); } diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 9a6bbf182..f82189e48 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -3,16 +3,18 @@ #include "NetPacksBase.h" #include "BattleAction.h" -#include "HeroBonus.h" +//#include "HeroBonus.h" #include "mapObjects/CGHeroInstance.h" -#include "CCreatureSet.h" -#include "mapping/CMapInfo.h" -#include "StartInfo.h" +//#include "CCreatureSet.h" +//#include "mapping/CMapInfo.h" +//#include "StartInfo.h" #include "ConstTransitivePtr.h" #include "int3.h" #include "ResourceSet.h" +//#include "CObstacleInstance.h" +#include "CGameStateFwd.h" +#include "mapping/CMap.h" #include "CObstacleInstance.h" -#include "CGameState.h" /* * NetPacks.h, part of VCMI engine @@ -37,7 +39,8 @@ class CArtifactInstance; struct StackLocation; struct ArtSlotInfo; struct QuestInfo; - +class CMapInfo; +class StartInfo; struct CPackForClient : public CPack @@ -2127,7 +2130,7 @@ struct PlayerJoined : public CPregamePackToHost } }; -struct SelectMap : public CPregamePackToPropagate +struct DLL_LINKAGE SelectMap : public CPregamePackToPropagate { const CMapInfo *mapInfo; bool free; @@ -2142,11 +2145,7 @@ struct SelectMap : public CPregamePackToPropagate mapInfo = nullptr; free = true; } - ~SelectMap() - { - if(free) - delete mapInfo; - } + DLL_LINKAGE ~SelectMap(); void apply(CSelectionScreen *selScreen); //that functions are implemented in CPreGame.cpp @@ -2157,7 +2156,7 @@ struct SelectMap : public CPregamePackToPropagate }; -struct UpdateStartOptions : public CPregamePackToPropagate +struct DLL_LINKAGE UpdateStartOptions : public CPregamePackToPropagate { StartInfo *options; bool free; @@ -2174,11 +2173,7 @@ struct UpdateStartOptions : public CPregamePackToPropagate options = nullptr; free = true; } - ~UpdateStartOptions() - { - if(free) - delete options; - } + DLL_LINKAGE ~UpdateStartOptions(); template void serialize(Handler &h, const int version) { diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 2dfe20ef6..7504af7db 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -14,6 +14,8 @@ #include "CGameState.h" #include "BattleState.h" #include "CTownHandler.h" +#include "mapping/CMapInfo.h" +#include "StartInfo.h" /* * NetPacksLib.cpp, part of VCMI engine @@ -60,6 +62,18 @@ DLL_LINKAGE void SetSecSkill::applyGs( CGameState *gs ) hero->setSecSkillLevel(which, val, abs); } +DLL_LINKAGE SelectMap::~SelectMap() +{ + if(free) + delete mapInfo; +} + +DLL_LINKAGE UpdateStartOptions::~UpdateStartOptions() +{ + if(free) + delete options; +} + DLL_LINKAGE void SetCommanderProperty::applyGs(CGameState *gs) { CCommanderInstance * commander = gs->getHero(heroid)->commander; @@ -1501,7 +1515,7 @@ DLL_LINKAGE CatapultAttack::~CatapultAttack() DLL_LINKAGE void CatapultAttack::applyGs( CGameState *gs ) { - if(gs->curB && gs->curB->siege != CGTownInstance::NONE) //if there is a battle and it's a siege + if(gs->curB && gs->curB->town && gs->curB->town->fortLevel() != CGTownInstance::NONE) //if there is a battle and it's a siege { for(const auto &it :attackedParts) { diff --git a/lib/mapObjects/CArmedInstance.h b/lib/mapObjects/CArmedInstance.h index f85b8a07e..f80b94d76 100644 --- a/lib/mapObjects/CArmedInstance.h +++ b/lib/mapObjects/CArmedInstance.h @@ -13,6 +13,9 @@ * */ +class BattleInfo; +class CGameState; + class DLL_LINKAGE CArmedInstance: public CGObjectInstance, public CBonusSystemNode, public CCreatureSet { public: diff --git a/lib/mapObjects/CBank.cpp b/lib/mapObjects/CBank.cpp index 076b1d131..34c980cf6 100644 --- a/lib/mapObjects/CBank.cpp +++ b/lib/mapObjects/CBank.cpp @@ -16,6 +16,8 @@ #include "../CSoundBase.h" #include "CommonConstructors.h" #include "../CSpellHandler.h" +#include "../IGameCallback.h" +#include "../CGameState.h" using namespace boost::assign; diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 0d62cf0ae..83028ef8f 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -14,10 +14,13 @@ #include "../NetPacks.h" #include "../CGeneralTextHandler.h" #include "../CHeroHandler.h" +#include "../CModHandler.h" #include "../CSoundBase.h" #include "../CSpellHandler.h" #include "CObjectClassesHandler.h" - +#include "../IGameCallback.h" +#include "../CGameState.h" +#include "../CCreatureHandler.h" using namespace boost::assign; diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index a593e40d7..4e762dfa7 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -18,6 +18,8 @@ class CHero; class CGBoat; +class CGTownInstance; +class TerrainTile; class CGHeroPlaceholder : public CGObjectInstance { diff --git a/lib/mapObjects/CGMarket.cpp b/lib/mapObjects/CGMarket.cpp index 98205974e..e7db026f9 100644 --- a/lib/mapObjects/CGMarket.cpp +++ b/lib/mapObjects/CGMarket.cpp @@ -14,6 +14,9 @@ #include "../NetPacks.h" #include "../CGeneralTextHandler.h" +#include "../IGameCallback.h" +#include "../CCreatureHandler.h" +#include "../CGameState.h" using namespace boost::assign; diff --git a/lib/mapObjects/CGPandoraBox.cpp b/lib/mapObjects/CGPandoraBox.cpp index 8f102e0a0..2dd5e1db2 100644 --- a/lib/mapObjects/CGPandoraBox.cpp +++ b/lib/mapObjects/CGPandoraBox.cpp @@ -15,6 +15,8 @@ #include "../CSoundBase.h" #include "../CSpellHandler.h" +#include "../StartInfo.h" +#include "../IGameCallback.h" using namespace boost::assign; diff --git a/lib/mapObjects/CGPandoraBox.h b/lib/mapObjects/CGPandoraBox.h index 227615cdf..fb14be309 100644 --- a/lib/mapObjects/CGPandoraBox.h +++ b/lib/mapObjects/CGPandoraBox.h @@ -2,6 +2,7 @@ #include "CObjectHandler.h" #include "CArmedInstance.h" +#include "../ResourceSet.h" /* * CGPandoraBox.h, part of VCMI engine @@ -13,6 +14,8 @@ * */ +class InfoWindow; + class DLL_LINKAGE CGPandoraBox : public CArmedInstance { public: diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index ef61d5cd3..6404f1558 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -14,6 +14,9 @@ #include "../NetPacks.h" #include "../CGeneralTextHandler.h" +#include "../CModHandler.h" +#include "../IGameCallback.h" +#include "../CGameState.h" using namespace boost::assign; diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index a1102bca1..678d2b2ff 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -17,6 +17,7 @@ */ class CCastleEvent; +class CGTownInstance; class DLL_LINKAGE CSpecObjInfo { diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index 95b32fc49..403b18830 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -5,6 +5,7 @@ #include "../GameConstants.h" #include "../ConstTransitivePtr.h" #include "../IHandlerBase.h" +#include "../JsonNode.h" /* * CObjectClassesHandler.h, part of VCMI engine diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 54f73d843..e658cb134 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -15,6 +15,9 @@ #include "../CGeneralTextHandler.h" #include "../CHeroHandler.h" #include "../CSoundBase.h" +#include "../filesystem/ResourceID.h" +#include "../IGameCallback.h" +#include "../CGameState.h" #include "CObjectClassesHandler.h" diff --git a/lib/mapObjects/CObjectHandler.h b/lib/mapObjects/CObjectHandler.h index 4faaa0f92..1469c1395 100644 --- a/lib/mapObjects/CObjectHandler.h +++ b/lib/mapObjects/CObjectHandler.h @@ -2,7 +2,7 @@ #include "ObjectTemplate.h" -#include "../IGameCallback.h" +//#include "../IGameCallback.h" #include "../int3.h" #include "../HeroBonus.h" @@ -17,6 +17,9 @@ */ class CGHeroInstance; +class IGameCallback; +class CGObjectInstance; +class MetaString; struct BattleResult; class DLL_LINKAGE IObjectInterface diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index 368c3493a..ad301eb61 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -17,6 +17,8 @@ #include "../CGeneralTextHandler.h" #include "../CHeroHandler.h" #include "CObjectClassesHandler.h" +#include "../IGameCallback.h" +#include "../CGameState.h" using namespace boost::assign; diff --git a/lib/mapObjects/CQuest.h b/lib/mapObjects/CQuest.h index 788969106..884acb807 100644 --- a/lib/mapObjects/CQuest.h +++ b/lib/mapObjects/CQuest.h @@ -16,6 +16,8 @@ * */ +class CGCreature; + class DLL_LINKAGE CQuest { public: diff --git a/lib/mapObjects/CRewardableConstructor.cpp b/lib/mapObjects/CRewardableConstructor.cpp index e5b02e0c9..3d4c27112 100644 --- a/lib/mapObjects/CRewardableConstructor.cpp +++ b/lib/mapObjects/CRewardableConstructor.cpp @@ -5,6 +5,7 @@ #include "../StringConstants.h" #include "../CCreatureHandler.h" #include "JsonRandom.h" +#include "../IGameCallback.h" /* * CRewardableConstructor.cpp, part of VCMI engine diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 94c7b6386..4b8561e48 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -15,6 +15,8 @@ #include "../CGeneralTextHandler.h" #include "../CSoundBase.h" #include "../NetPacks.h" +#include "../IGameCallback.h" +#include "../CGameState.h" #include "CObjectClassesHandler.h" diff --git a/lib/mapObjects/CRewardableObject.h b/lib/mapObjects/CRewardableObject.h index a32abcedd..9905ae238 100644 --- a/lib/mapObjects/CRewardableObject.h +++ b/lib/mapObjects/CRewardableObject.h @@ -4,6 +4,7 @@ #include "CArmedInstance.h" #include "../NetPacksBase.h" +#include "../ResourceSet.h" /* * CRewardableObject.h, part of VCMI engine diff --git a/lib/mapObjects/CommonConstructors.cpp b/lib/mapObjects/CommonConstructors.cpp index 14f45fd9c..af259e564 100644 --- a/lib/mapObjects/CommonConstructors.cpp +++ b/lib/mapObjects/CommonConstructors.cpp @@ -8,6 +8,8 @@ #include "../CHeroHandler.h" #include "../CCreatureHandler.h" #include "JsonRandom.h" +#include "../CModHandler.h" +#include "../IGameCallback.h" /* * CommonConstructors.cpp, part of VCMI engine diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index 7e596288e..d5e9fa2d8 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -14,9 +14,12 @@ #include "../NetPacks.h" #include "../CGeneralTextHandler.h" #include "../CSoundBase.h" +#include "../CModHandler.h" #include "CObjectClassesHandler.h" #include "../CSpellHandler.h" +#include "../IGameCallback.h" +#include "../CGameState.h" using namespace boost::assign; diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index 01d6d813f..ca1601c6a 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -2,6 +2,7 @@ #include "CObjectHandler.h" #include "CArmedInstance.h" +#include "../ResourceSet.h" /* * MiscObjects.h, part of VCMI engine diff --git a/lib/registerTypes/RegisterTypes.h b/lib/registerTypes/RegisterTypes.h index d8de270c7..8bf37da4d 100644 --- a/lib/registerTypes/RegisterTypes.h +++ b/lib/registerTypes/RegisterTypes.h @@ -12,6 +12,7 @@ #include "../mapObjects/CRewardableConstructor.h" #include "../mapObjects/CommonConstructors.h" #include "../mapObjects/MapObjects.h" +#include "../CObstacleInstance.h" /* * RegisterTypes.h, part of VCMI engine diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 703ac2346..93bcbc02b 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -5225,7 +5225,7 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player) } } -void CGameHandler::getVictoryLossMessage(PlayerColor player, EVictoryLossCheckResult victoryLossCheckResult, InfoWindow & out) const +void CGameHandler::getVictoryLossMessage(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult, InfoWindow & out) const { out.player = player; out.text.clear(); diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 1b91ee901..1a3791522 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -290,7 +290,7 @@ public: private: std::list generatePlayerTurnOrder() const; void makeStackDoNothing(const CStack * next); - void getVictoryLossMessage(PlayerColor player, EVictoryLossCheckResult victoryLossCheckResult, InfoWindow & out) const; + void getVictoryLossMessage(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult, InfoWindow & out) const; // Check for victory and loss conditions void checkVictoryLossConditionsForPlayer(PlayerColor player); From 955552488e01aaf5ff92378e42bf3a0e9e119bda Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 25 Jun 2014 20:26:47 +0300 Subject: [PATCH 11/39] - H3M parser will create objects that don't have data in map file via object handler. - Added large number of missing objects to config --- config/objects/generic.json | 223 ++++++++++++----------- config/objects/moddables.json | 45 ++++- config/objects/rewardable.json | 79 ++++---- lib/mapObjects/CObjectClassesHandler.cpp | 6 +- lib/mapping/MapFormatH3M.cpp | 171 +---------------- 5 files changed, 220 insertions(+), 304 deletions(-) diff --git a/config/objects/generic.json b/config/objects/generic.json index bc1e1dcf8..f916b5be0 100644 --- a/config/objects/generic.json +++ b/config/objects/generic.json @@ -8,126 +8,145 @@ "prison" : { "index" : 0 } } }, + + "altarOfSacrifice" : { "index" :2, "handler": "market", "types" : { "object" : { "index" : 0} } }, + "tradingPost" : { "index" :221, "handler": "market", "types" : { "object" : { "index" : 0} } }, + "tradingPostDUPLICATE" : { "index" :99, "handler": "market", "types" : { "object" : { "index" : 0} } }, + "freelancersGuild" : { "index" :213, "handler": "market", "types" : { "object" : { "index" : 0} } }, + + "blackMarket" : { "index" :7, "handler": "blackMarket", "types" : { "object" : { "index" : 0} } }, + + "pandoraBox" : { "index" :6, "handler": "pandora", "types" : { "object" : { "index" : 0} } }, + "event" : { "index" :26, "handler": "event", "types" : { "object" : { "index" : 0} } }, + + "redwoodObservatory" : { "index" :58, "handler": "observatory", "types" : { "object" : { "index" : 0} } }, + "pillarOfFire" : { "index" :60, "handler": "observatory", "types" : { "object" : { "index" : 0} } }, + "coverOfDarkness" : { "index" :15, "handler": "observatory", "types" : { "object" : { "index" : 0} } }, - "altarOfSacrifice" : { "index" :2, "handler": "market" }, - "tradingPost" : { "index" :221, "handler": "market" }, - "tradingPostDUPLICATE" : { "index" :99, "handler": "market" }, - "freelancersGuild" : { "index" :213, "handler": "market" }, + "whirlpool" : { "index" :111, "handler": "teleport", "types" : { "object" : { "index" : 0} } }, + "subterraneanGate" : { + "index" :103, + "handler": "teleport", + "types" : { + "object" : { "index" : 0 }, + "objectWoG" : { "index" : 1 } // WoG object? Present on VCMI Test 2011b + } + }, - "blackMarket" : { "index" :7, "handler": "blackMarket" }, + "refugeeCamp" : { "index" :78, "handler": "dwelling", "types" : { "object" : { "index" : 0} } }, + "warMachineFactory" : { "index" :106, "handler": "dwelling", "types" : { "object" : { "index" : 0} } }, - "pandoraBox" : { "index" :6, "handler": "pandora" }, - "event" : { "index" :26, "handler": "event" }, + "shrineOfMagicLevel1" : { "index" :88, "handler": "shrine", "types" : { "object" : { "index" : 0} } }, + "shrineOfMagicLevel2" : { "index" :89, "handler": "shrine", "types" : { "object" : { "index" : 0} } }, + "shrineOfMagicLevel3" : { "index" :90, "handler": "shrine", "types" : { "object" : { "index" : 0} } }, - "redwoodObservatory" : { "index" :58, "handler": "observatory" }, - "pillarOfFire" : { "index" :60, "handler": "observatory" }, - "coverOfDarkness" : { "index" :15, "handler": "observatory" }, - - "subterraneanGate" : { "index" :103, "handler": "teleport" }, - "whirlpool" : { "index" :111, "handler": "teleport" }, + "eyeOfTheMagi" : { "index" :27, "handler": "magi", "types" : { "object" : { "index" : 0} } }, + "hutOfTheMagi" : { "index" :37, "handler": "magi", "types" : { "object" : { "index" : 0} } }, - "refugeeCamp" : { "index" :78, "handler": "dwelling" }, - "warMachineFactory" : { "index" :106, "handler": "dwelling" }, - - "shrineOfMagicLevel1" : { "index" :88, "handler": "shrine" }, - "shrineOfMagicLevel2" : { "index" :89, "handler": "shrine" }, - "shrineOfMagicLevel3" : { "index" :90, "handler": "shrine" }, - - "eyeOfTheMagi" : { "index" :27, "handler": "magi" }, - "hutOfTheMagi" : { "index" :37, "handler": "magi" }, - - "lighthouse" : { "index" :42, "handler": "lighthouse" }, - "magicWell" : { "index" :49, "handler": "magicWell" }, - "obelisk" : { "index" :57, "handler": "obelisk" }, - "oceanBottle" : { "index" :59, "handler": "sign" }, - "scholar" : { "index" :81, "handler": "scholar" }, - "shipyard" : { "index" :87, "handler": "shipyard" }, - "sign" : { "index" :91, "handler": "sign" }, - "sirens" : { "index" :92, "handler": "siren" }, - "denOfThieves" : { "index" :97, "handler": "denOfThieves" }, - "university" : { "index" :104, "handler": "university" }, - "witchHut" : { "index" :113, "handler": "witch" }, - "questGuard" : { "index" :215, "handler": "questGuard" }, + "lighthouse" : { "index" :42, "handler": "lighthouse", "types" : { "object" : { "index" : 0} } }, + "obelisk" : { "index" :57, "handler": "obelisk", "types" : { "object" : { "index" : 0} } }, + "oceanBottle" : { "index" :59, "handler": "sign", "types" : { "object" : { "index" : 0} } }, + "scholar" : { "index" :81, "handler": "scholar", "types" : { "object" : { "index" : 0} } }, + "shipyard" : { "index" :87, "handler": "shipyard", "types" : { "object" : { "index" : 0} } }, + "sign" : { "index" :91, "handler": "sign", "types" : { "object" : { "index" : 0} } }, + "sirens" : { "index" :92, "handler": "siren", "types" : { "object" : { "index" : 0} } }, + "denOfThieves" : { "index" :97, "handler": "denOfThieves", "types" : { "object" : { "index" : 0} } }, + "university" : { "index" :104, "handler": "university", "types" : { "object" : { "index" : 0} } }, + "witchHut" : { "index" :113, "handler": "witch", "types" : { "object" : { "index" : 0} } }, + "questGuard" : { "index" :215, "handler": "questGuard", "types" : { "object" : { "index" : 0} } }, + "magicWell" : { + "index" :49, + "handler": "magicWell", + "types" : { + "object" : { "index" : 0}, + "objectWoG" : { "index" : 1} // WoG object? Present on VCMI_Test 2011b + } + }, /// Random objects - "randomResource" : { "index" :76, "handler": "resource" }, - "randomTown" : { "index" :77, "handler": "town" }, - "randomHero" : { "index" :70, "handler": "hero" }, + "randomResource" : { "index" :76, "handler": "resource" }, + "randomTown" : { "index" :77, "handler": "town" }, + "randomHero" : { "index" :70, "handler": "hero" }, "randomDwelling" : { "index" :216, "handler": "dwelling" }, - "randomArtifact" : { "index" :65, "handler": "artifact" }, - "randomArtifactTreasure" : { "index" :66, "handler": "artifact" }, - "randomArtifactMinor" : { "index" :67, "handler": "artifact" }, - "randomArtifactMajor" : { "index" :68, "handler": "artifact" }, - "randomArtifactRelic" : { "index" :69, "handler": "artifact" }, + "randomArtifact" : { "index" :65, "handler": "artifact" }, + "randomArtifactTreasure" : { "index" :66, "handler": "artifact" }, + "randomArtifactMinor" : { "index" :67, "handler": "artifact" }, + "randomArtifactMajor" : { "index" :68, "handler": "artifact" }, + "randomArtifactRelic" : { "index" :69, "handler": "artifact" }, - "randomMonster" : { "index" :71, "handler": "monster" }, - "randomMonsterLevel1" : { "index" :72, "handler": "monster" }, - "randomMonsterLevel2" : { "index" :73, "handler": "monster" }, - "randomMonsterLevel3" : { "index" :74, "handler": "monster" }, - "randomMonsterLevel4" : { "index" :75, "handler": "monster" }, + "randomMonster" : { "index" :71, "handler": "monster" }, + "randomMonsterLevel1" : { "index" :72, "handler": "monster" }, + "randomMonsterLevel2" : { "index" :73, "handler": "monster" }, + "randomMonsterLevel3" : { "index" :74, "handler": "monster" }, + "randomMonsterLevel4" : { "index" :75, "handler": "monster" }, "randomMonsterLevel5" : { "index" :162, "handler": "monster" }, "randomMonsterLevel6" : { "index" :163, "handler": "monster" }, "randomMonsterLevel7" : { "index" :164, "handler": "monster" }, /// Classes without dedicated object - "hillFort" : { "index" :35, "handler": "generic" }, - "grail" : { "index" :36, "handler": "generic" }, - "tavern" : { "index" :95, "handler": "generic" }, - "sanctuary" : { "index" :80, "handler": "generic" }, + "hillFort" : { "index" :35, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "grail" : { "index" :36, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "tavern" : { "index" :95, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "sanctuary" : { "index" :80, "handler": "generic", "types" : { "object" : { "index" : 0} } }, /// Passive objects, terrain overlays - "cursedGround" : { "index" :21, "handler": "generic" }, - "magicPlains" : { "index" :46, "handler": "generic" }, - "swampFoliage" : { "index" :211, "handler": "generic" }, - "cloverField" : { "index" :222, "handler": "generic" }, - "cursedGroundDUPLICATE" : { "index" :223, "handler": "generic" }, - "evilFog" : { "index" :224, "handler": "generic" }, - "favorableWinds" : { "index" :225, "handler": "generic" }, - "fieryFields" : { "index" :226, "handler": "generic" }, - "holyGround" : { "index" :227, "handler": "generic" }, - "lucidPools" : { "index" :228, "handler": "generic" }, - "magicClouds" : { "index" :229, "handler": "generic" }, - "magicPlainsDUPLICATE" : { "index" :230, "handler": "generic" }, - "rocklands" : { "index" :231, "handler": "generic" }, + "cursedGround" : { "index" :21, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "magicPlains" : { "index" :46, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "swampFoliage" : { "index" :211, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "cloverField" : { "index" :222, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "cursedGroundDUPLICATE" : { "index" :223, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "evilFog" : { "index" :224, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "favorableWinds" : { "index" :225, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "fieryFields" : { "index" :226, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "holyGround" : { "index" :227, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "lucidPools" : { "index" :228, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "magicClouds" : { "index" :229, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "magicPlainsDUPLICATE" : { "index" :230, "handler": "generic", "types" : { "object" : { "index" : 0} } }, + "rocklands" : { "index" :231, "handler": "generic", "types" : { "object" : { "index" : 0} } }, /// Decorations - "cactus" : { "index" :116, "handler": "static" }, - "canyon" : { "index" :117, "handler": "static" }, - "crater" : { "index" :118, "handler": "static" }, - "deadVegetation" : { "index" :119, "handler": "static" }, - "flowers" : { "index" :120, "handler": "static" }, - "frozenLake" : { "index" :121, "handler": "static" }, - "hole" : { "index" :124, "handler": "static" }, - "kelp" : { "index" :125, "handler": "static" }, - "lake" : { "index" :126, "handler": "static" }, - "lavaFlow" : { "index" :127, "handler": "static" }, - "lavaLake" : { "index" :128, "handler": "static" }, - "mushrooms" : { "index" :129, "handler": "static" }, - "log" : { "index" :130, "handler": "static" }, - "mandrake" : { "index" :131, "handler": "static" }, - "moss" : { "index" :132, "handler": "static" }, - "mound" : { "index" :133, "handler": "static" }, - "mountain" : { "index" :134, "handler": "static" }, - "oakTrees" : { "index" :135, "handler": "static" }, - "outcropping" : { "index" :136, "handler": "static" }, - "pineTrees" : { "index" :137, "handler": "static" }, - "riverDelta" : { "index" :143, "handler": "static" }, - "rock" : { "index" :147, "handler": "static" }, - "sandDune" : { "index" :148, "handler": "static" }, - "sandPit" : { "index" :149, "handler": "static" }, - "shrub" : { "index" :150, "handler": "static" }, - "skull" : { "index" :151, "handler": "static" }, - "stump" : { "index" :153, "handler": "static" }, - "trees" : { "index" :155, "handler": "static" }, - "volcano" : { "index" :158, "handler": "static" }, - "reef" : { "index" :161, "handler": "static" }, - "lakeDUPLICATE" : { "index" :177, "handler": "static" }, - "treesDUPLICATE" : { "index" :199, "handler": "static" }, - "desertHills" : { "index" :206, "handler": "static" }, - "dirtHills" : { "index" :207, "handler": "static" }, - "grassHills" : { "index" :208, "handler": "static" }, - "roughHills" : { "index" :209, "handler": "static" }, - "subterraneanRocks" : { "index" :210, "handler": "static" } + "cactus" : { "index" :116, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "canyon" : { "index" :117, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "crater" : { "index" :118, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "deadVegetation" : { "index" :119, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "flowers" : { "index" :120, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "frozenLake" : { "index" :121, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "hole" : { "index" :124, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "kelp" : { "index" :125, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "lake" : { "index" :126, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "lavaFlow" : { "index" :127, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "lavaLake" : { "index" :128, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "mushrooms" : { "index" :129, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "log" : { "index" :130, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "mandrake" : { "index" :131, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "moss" : { "index" :132, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "mound" : { "index" :133, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "mountain" : { "index" :134, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "oakTrees" : { "index" :135, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "outcropping" : { "index" :136, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "pineTrees" : { "index" :137, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "riverDelta" : { "index" :143, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "rock" : { "index" :147, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "sandDune" : { "index" :148, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "sandPit" : { "index" :149, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "shrub" : { "index" :150, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "skull" : { "index" :151, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "stump" : { "index" :153, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "trees" : { "index" :155, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "volcano" : { "index" :158, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "reef" : { "index" :161, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "lakeDUPLICATE" : { "index" :177, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "treesDUPLICATE" : { "index" :199, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "desertHills" : { "index" :206, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "dirtHills" : { "index" :207, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "grassHills" : { "index" :208, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "roughHills" : { "index" :209, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "subterraneanRocks" : { "index" :210, "handler": "static", "types" : { "object" : { "index" : 0} } }, + + //These are WoG objects? They are not available in H3 + "frozenLakeDUPLICATE" : { "index" :172, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "oakTreesDUPLICATE" : { "index" :186, "handler": "static", "types" : { "object" : { "index" : 0} } }, + "plant" : { "index" :189, "handler": "static", "types" : { "object" : { "index" : 0} } } } diff --git a/config/objects/moddables.json b/config/objects/moddables.json index b03c5f6a5..51268b93c 100644 --- a/config/objects/moddables.json +++ b/config/objects/moddables.json @@ -189,9 +189,48 @@ "garrisonVertical" : { "index" :219, "handler": "garrison" }, // Subtype: paired monoliths - "monolithOneWayEntrance" : { "index" :43, "handler": "teleport" }, - "monolithOneWayExit" : { "index" :44, "handler": "teleport" }, - "monolithTwoWay" : { "index" :45, "handler": "teleport" }, + "monolithOneWayEntrance" : { + "index" :43, + "handler": "teleport", + "types" : { + "monolith1" : { "index" : 0 }, + "monolith2" : { "index" : 1 }, + "monolith3" : { "index" : 2 }, + "monolith4" : { "index" : 3 }, + "monolith5" : { "index" : 4 }, + "monolith6" : { "index" : 5 }, + "monolith7" : { "index" : 6 }, + "monolith8" : { "index" : 7 } + } + }, + "monolithOneWayExit" : { + "index" :44, + "handler": "teleport", + "types" : { + "monolith1" : { "index" : 0 }, + "monolith2" : { "index" : 1 }, + "monolith3" : { "index" : 2 }, + "monolith4" : { "index" : 3 }, + "monolith5" : { "index" : 4 }, + "monolith6" : { "index" : 5 }, + "monolith7" : { "index" : 6 }, + "monolith8" : { "index" : 7 } + } + }, + "monolithTwoWay" : { + "index" :45, + "handler": "teleport", + "types" : { + "monolith1" : { "index" : 0 }, + "monolith2" : { "index" : 1 }, + "monolith3" : { "index" : 2 }, + "monolith4" : { "index" : 3 }, + "monolith5" : { "index" : 4 }, + "monolith6" : { "index" : 5 }, + "monolith7" : { "index" : 6 }, + "monolith8" : { "index" : 7 } + } + }, // subtype: different appearance. That's all? "seerHut" : { "index" :83, "handler": "seerHut" }, diff --git a/config/objects/rewardable.json b/config/objects/rewardable.json index 7b6a06984..b0847471e 100644 --- a/config/objects/rewardable.json +++ b/config/objects/rewardable.json @@ -1,44 +1,51 @@ { /// These are objects that covered by concept of "configurable object" /// Most or even all of their configuration located in this file - "magicSpring" : { "index" :48, "handler": "magicSpring" }, + "magicSpring" : { "index" :48, "handler": "magicSpring", "types" : { "object" : { "index" : 0} } }, - "mysticalGarden" : { "index" :55, "handler": "oncePerWeek" }, - "windmill" : { "index" :112, "handler": "oncePerWeek" }, - "waterWheel" : { "index" :109, "handler": "oncePerWeek" }, + "mysticalGarden" : { "index" :55, "handler": "oncePerWeek", "types" : { "object" : { "index" : 0} } }, + "windmill" : { "index" :112, "handler": "oncePerWeek", "types" : { "object" : { "index" : 0} } }, + "waterWheel" : { "index" :109, "handler": "oncePerWeek", "types" : { "object" : { "index" : 0} } }, - "leanTo" : { "index" :39, "handler": "onceVisitable" }, - "corpse" : { "index" :22, "handler": "onceVisitable" }, - "wagon" : { "index" :105, "handler": "onceVisitable" }, - "warriorTomb" : { "index" :108, "handler": "onceVisitable" }, + "leanTo" : { "index" :39, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } }, + "corpse" : { "index" :22, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } }, + "wagon" : { "index" :105, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } }, + "warriorTomb" : { "index" :108, "handler": "onceVisitable", "types" : { "object" : { "index" : 0} } }, - "campfire" : { "index" :12, "handler": "pickable" }, - "flotsam" : { "index" :29, "handler": "pickable" }, - "seaChest" : { "index" :82, "handler": "pickable" }, - "shipwreckSurvivor" : { "index" :86, "handler": "pickable" }, - "treasureChest" : { "index" :101, "handler": "pickable" }, + "campfire" : { "index" :12, "handler": "pickable", "types" : { "object" : { "index" : 0} } }, + "flotsam" : { "index" :29, "handler": "pickable", "types" : { "object" : { "index" : 0} } }, + "seaChest" : { "index" :82, "handler": "pickable", "types" : { "object" : { "index" : 0} } }, + "shipwreckSurvivor" : { "index" :86, "handler": "pickable", "types" : { "object" : { "index" : 0} } }, + "treasureChest" : { "index" :101, "handler": "pickable", "types" : { "object" : { "index" : 0} } }, - "arena" : { "index" :4, "handler": "oncePerHero" }, - "marlettoTower" : { "index" :23, "handler": "oncePerHero" }, - "gardenOfRevelation" : { "index" :32, "handler": "oncePerHero" }, - "libraryOfEnlightenment" : { "index" :41, "handler": "oncePerHero" }, - "mercenaryCamp" : { "index" :51, "handler": "oncePerHero" }, - "starAxis" : { "index" :61, "handler": "oncePerHero" }, - "learningStone" : { "index" :100, "handler": "oncePerHero" }, - "treeOfKnowledge" : { "index" :102, "handler": "oncePerHero" }, - "schoolOfMagic" : { "index" :47, "handler": "oncePerHero" }, - "schoolOfWar" : { "index" :107, "handler": "oncePerHero" }, - - "buoy" : { "index" :11, "handler": "bonusingObject" }, - "swanPond" : { "index" :14, "handler": "bonusingObject" }, - "faerieRing" : { "index" :28, "handler": "bonusingObject" }, - "fountainOfFortune" : { "index" :30, "handler": "bonusingObject" }, - "fountainOfYouth" : { "index" :31, "handler": "bonusingObject" }, - "idolOfFortune" : { "index" :38, "handler": "bonusingObject" }, - "mermaids" : { "index" :52, "handler": "bonusingObject" }, - "oasis" : { "index" :56, "handler": "bonusingObject" }, - "stables" : { "index" :94, "handler": "bonusingObject" }, - "temple" : { "index" :96, "handler": "bonusingObject" }, - "rallyFlag" : { "index" :64, "handler": "bonusingObject" }, - "wateringHole" : { "index" :110, "handler": "bonusingObject" }, + "arena" : { "index" :4, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "marlettoTower" : { "index" :23, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "gardenOfRevelation" : { "index" :32, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "libraryOfEnlightenment" : { "index" :41, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "mercenaryCamp" : { "index" :51, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "starAxis" : { "index" :61, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "treeOfKnowledge" : { "index" :102, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "schoolOfMagic" : { "index" :47, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "schoolOfWar" : { "index" :107, "handler": "oncePerHero", "types" : { "object" : { "index" : 0} } }, + "learningStone" : { + "index" :100, + "handler": "oncePerHero", + "types" : { + "object" : { "index" : 0}, + "objectWoG" : { "index" : 1} // WoG object? Present on VCMI_Tests 2011 + } + }, + + "buoy" : { "index" :11, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "swanPond" : { "index" :14, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "faerieRing" : { "index" :28, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "fountainOfFortune" : { "index" :30, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "fountainOfYouth" : { "index" :31, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "idolOfFortune" : { "index" :38, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "mermaids" : { "index" :52, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "oasis" : { "index" :56, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "stables" : { "index" :94, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "temple" : { "index" :96, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "rallyFlag" : { "index" :64, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } }, + "wateringHole" : { "index" :110, "handler": "bonusingObject", "types" : { "object" : { "index" : 0} } } } diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index 122068eb6..e543a70ee 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -276,8 +276,10 @@ void CObjectClassesHandler::afterLoadFinalization() std::string CObjectClassesHandler::getObjectName(si32 type) const { - assert(objects.count(type)); - return objects.at(type)->name; + if (objects.count(type)) + return objects.at(type)->name; + logGlobal->errorStream() << "Access to non existing object of type " << type; + return ""; } void AObjectTypeHandler::setType(si32 type, si32 subtype) diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index f064cc70a..5e7694528 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -1063,56 +1063,6 @@ void CMapLoaderH3M::readObjects() nobj = readHero(idToBeGiven); break; } - case Obj::ARENA: - case Obj::MERCENARY_CAMP: - case Obj::MARLETTO_TOWER: - case Obj::STAR_AXIS: - case Obj::GARDEN_OF_REVELATION: - case Obj::LEARNING_STONE: - case Obj::TREE_OF_KNOWLEDGE: - case Obj::LIBRARY_OF_ENLIGHTENMENT: - case Obj::SCHOOL_OF_MAGIC: - case Obj::SCHOOL_OF_WAR: - { - nobj = new CGVisitableOPH(); - break; - } - case Obj::MYSTICAL_GARDEN: - case Obj::WINDMILL: - case Obj::WATER_WHEEL: - { - nobj = new CGVisitableOPW(); - break; - } - case Obj::MONOLITH_ONE_WAY_ENTRANCE: - case Obj::MONOLITH_ONE_WAY_EXIT: - case Obj::MONOLITH_TWO_WAY: - case Obj::SUBTERRANEAN_GATE: - case Obj::WHIRLPOOL: - { - nobj = new CGTeleport(); - break; - } - case Obj::CAMPFIRE: - case Obj::FLOTSAM: - case Obj::SEA_CHEST: - case Obj::SHIPWRECK_SURVIVOR: - { - nobj = new CGPickable(); - break; - } - case Obj::TREASURE_CHEST: - if(objTempl.subid == 0) - { - nobj = new CGPickable(); - } - else - { - //WoG pickable object - //TODO: possible special handling - nobj = new CGObjectInstance(); - } - break; case Obj::MONSTER: //Monster case Obj::RANDOM_MONSTER: case Obj::RANDOM_MONSTER_L1: @@ -1330,12 +1280,6 @@ void CMapLoaderH3M::readObjects() reader.skip(3); break; } - case Obj::REFUGEE_CAMP: - case Obj::WAR_MACHINE_FACTORY: - { - nobj = new CGDwelling(); - break; - } case Obj::SHRINE_OF_MAGIC_INCANTATION: case Obj::SHRINE_OF_MAGIC_GESTURE: case Obj::SHRINE_OF_MAGIC_THOUGHT: @@ -1458,52 +1402,6 @@ void CMapLoaderH3M::readObjects() nobj = guard; break; } - case Obj::FAERIE_RING: - case Obj::SWAN_POND: - case Obj::IDOL_OF_FORTUNE: - case Obj::FOUNTAIN_OF_FORTUNE: - case Obj::RALLY_FLAG: - case Obj::OASIS: - case Obj::TEMPLE: - case Obj::WATERING_HOLE: - case Obj::FOUNTAIN_OF_YOUTH: - case Obj::BUOY: - case Obj::MERMAID: - case Obj::STABLES: - { - nobj = new CGBonusingObject(); - break; - } - case Obj::MAGIC_WELL: - { - nobj = new CGMagicWell(); - break; - } - case Obj::COVER_OF_DARKNESS: - case Obj::REDWOOD_OBSERVATORY: - case Obj::PILLAR_OF_FIRE: - { - nobj = new CGObservatory(); - break; - } - case Obj::CORPSE: - case Obj::LEAN_TO: - case Obj::WAGON: - case Obj::WARRIORS_TOMB: - { - nobj = new CGOnceVisitable(); - break; - } - case Obj::BOAT: - { - nobj = new CGBoat(); - break; - } - case Obj::SIRENS: - { - nobj = new CGSirens(); - break; - } case Obj::SHIPYARD: { nobj = new CGShipyard(); @@ -1531,11 +1429,6 @@ void CMapLoaderH3M::readObjects() hp->power = 0; } - break; - } - case Obj::KEYMASTER: - { - nobj = new CGKeymasterTent(); break; } case Obj::BORDERGUARD: @@ -1550,21 +1443,6 @@ void CMapLoaderH3M::readObjects() map->addQuest (nobj); break; } - case Obj::EYE_OF_MAGI: - case Obj::HUT_OF_MAGI: - { - nobj = new CGMagi(); - break; - } - case Obj::CREATURE_BANK: - case Obj::DERELICT_SHIP: - case Obj::DRAGON_UTOPIA: - case Obj::CRYPT: - case Obj::SHIPWRECK: - { - nobj = new CBank(); - break; - } case Obj::PYRAMID: //Pyramid of WoG object { if(objTempl.subid == 0) @@ -1579,53 +1457,24 @@ void CMapLoaderH3M::readObjects() } break; } - case Obj::CARTOGRAPHER: - { - nobj = new CCartographer(); - break; - } - case Obj::MAGIC_SPRING: - { - nobj = new CGMagicSpring(); - break; - } - case Obj::DEN_OF_THIEVES: - { - nobj = new CGDenOfthieves(); - break; - } - case Obj::OBELISK: - { - nobj = new CGObelisk(); - break; - } case Obj::LIGHTHOUSE: //Lighthouse { nobj = new CGLighthouse(); nobj->tempOwner = PlayerColor(reader.readUInt32()); break; } - case Obj::ALTAR_OF_SACRIFICE: - case Obj::TRADING_POST: - case Obj::FREELANCERS_GUILD: - case Obj::TRADING_POST_SNOW: - { - nobj = new CGMarket(); - break; - } - case Obj::UNIVERSITY: - { - nobj = new CGUniversity(); - break; - } - case Obj::BLACK_MARKET: - { - nobj = new CGBlackMarket(); - break; - } default: //any other object { - nobj = new CGObjectInstance(); + if (VLC->objtypeh->knownSubObjects(objTempl.id).count(objTempl.subid)) + { + nobj = VLC->objtypeh->getHandlerFor(objTempl.id, objTempl.subid)->create(objTempl); + } + else + { + logGlobal->warnStream() << "Unrecognized object: " << objTempl.id << ":" << objTempl.subid << " at " << objPos + << " on map " << map->name; + nobj = new CGObjectInstance(); + } break; } } From ce6940e272c995358c1f5d940ee4c27205b211ed Mon Sep 17 00:00:00 2001 From: Haryaalcar Date: Thu, 26 Jun 2014 01:23:12 +0300 Subject: [PATCH 12/39] build fix for mac os: 1) type_info visibility for CatapultAttack 2) using IObjectInfo::CArmyStructure in min_element : operator< should be const --- lib/NetPacks.h | 2 +- lib/mapObjects/CObjectClassesHandler.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/NetPacks.h b/lib/NetPacks.h index f82189e48..2d7f30e15 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1516,7 +1516,7 @@ struct ObstaclesRemoved : public CPackForClient //3014 }; //FIXME: figure out why gcc fails to find type_info for this class with -fvisibility=hidden flag set -#ifdef __linux__ +#if defined(__linux__) || defined(__APPLE__) struct DLL_LINKAGE CatapultAttack : public CPackForClient //3015 #else struct CatapultAttack : public CPackForClient //3015 diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index 403b18830..3d5886901 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -65,7 +65,7 @@ public: walkersStrength(0) {} - bool operator <(const CArmyStructure & other) + bool operator <(const CArmyStructure & other) const { return this->totalStrength < other.totalStrength; } From 88122ee253f26e6e8d384032a12eec090759761c Mon Sep 17 00:00:00 2001 From: Haryaalcar Date: Thu, 26 Jun 2014 02:18:59 +0300 Subject: [PATCH 13/39] another build fix: Undefined symbols for architecture x86_64: "operator<<(std::__1::basic_ostream >&, EVictoryLossCheckResult const&) --- AI/VCAI/VCAI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index c18d5ca18..fbf9f1831 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -196,7 +196,7 @@ void VCAI::showShipyardDialog(const IShipyard *obj) void VCAI::gameOver(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult) { - LOG_TRACE_PARAMS(logAi, "victoryLossCheckResult '%s'", victoryLossCheckResult); + LOG_TRACE_PARAMS(logAi, "victoryLossCheckResult '%s'", victoryLossCheckResult.messageToSelf); NET_EVENT_HANDLER; logAi->debugStream() << boost::format("Player %d: I heard that player %d %s.") % playerID % player.getNum() % (victoryLossCheckResult.victory() ? "won" : "lost"); if(player == playerID) From af1ce59ab4078f26c06a9fc265006156461940a5 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 26 Jun 2014 18:16:09 +0300 Subject: [PATCH 14/39] Fixed path to header in ERM module --- scripting/erm/ERMInterpreter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripting/erm/ERMInterpreter.cpp b/scripting/erm/ERMInterpreter.cpp index e769ddc14..f6fdaa3a4 100644 --- a/scripting/erm/ERMInterpreter.cpp +++ b/scripting/erm/ERMInterpreter.cpp @@ -2,7 +2,7 @@ #include "ERMInterpreter.h" #include -#include "../../lib/CObjectHandler.h" +#include "../../lib/mapObjects/CObjectHandler.h" #include "../../lib/CHeroHandler.h" #include "../../lib/CCreatureHandler.h" #include "../../lib/VCMIDirs.h" From 00b6232ff6972ed422d3a867dd18602a65f656e4 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 26 Jun 2014 18:34:54 +0300 Subject: [PATCH 15/39] Replaced usage of DLL_LINKAGE with ELF_VISIBILITY in netpacks. Please make sure that compilation now works on all platforms --- Global.h | 6 +++++- lib/NetPacks.h | 11 +++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Global.h b/Global.h index a9c81fe59..def02d647 100644 --- a/Global.h +++ b/Global.h @@ -152,9 +152,11 @@ typedef boost::lock_guard TLockGuardRec; # else # define DLL_EXPORT __declspec(dllexport) # endif +# define ELF_VISIBILITY #else # ifdef __GNUC__ -# define DLL_EXPORT __attribute__ ((visibility("default"))) +# define DLL_EXPORT __attribute__ ((visibility("default"))) +# define ELF_VISIBILITY __attribute__ ((visibility("default"))) # endif #endif @@ -164,9 +166,11 @@ typedef boost::lock_guard TLockGuardRec; # else # define DLL_IMPORT __declspec(dllimport) # endif +# define ELF_VISIBILITY #else # ifdef __GNUC__ # define DLL_IMPORT __attribute__ ((visibility("default"))) +# define ELF_VISIBILITY __attribute__ ((visibility("default"))) # endif #endif diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 2d7f30e15..14234899d 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -1515,12 +1515,7 @@ struct ObstaclesRemoved : public CPackForClient //3014 } }; -//FIXME: figure out why gcc fails to find type_info for this class with -fvisibility=hidden flag set -#if defined(__linux__) || defined(__APPLE__) -struct DLL_LINKAGE CatapultAttack : public CPackForClient //3015 -#else -struct CatapultAttack : public CPackForClient //3015 -#endif +struct ELF_VISIBILITY CatapultAttack : public CPackForClient //3015 { struct AttackInfo @@ -2130,7 +2125,7 @@ struct PlayerJoined : public CPregamePackToHost } }; -struct DLL_LINKAGE SelectMap : public CPregamePackToPropagate +struct ELF_VISIBILITY SelectMap : public CPregamePackToPropagate { const CMapInfo *mapInfo; bool free; @@ -2156,7 +2151,7 @@ struct DLL_LINKAGE SelectMap : public CPregamePackToPropagate }; -struct DLL_LINKAGE UpdateStartOptions : public CPregamePackToPropagate +struct ELF_VISIBILITY UpdateStartOptions : public CPregamePackToPropagate { StartInfo *options; bool free; From c28b5f6633fe1930e85bf3b499328e2bdd6d086c Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Thu, 26 Jun 2014 20:41:27 +0400 Subject: [PATCH 16/39] fix mingw build --- lib/NetPacks.h | 24 ++++-------------------- lib/NetPacksLib.cpp | 23 +++++++++++++++++++++++ lib/VCMI_lib.cbp | 1 + 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 14234899d..155f487bf 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -2130,16 +2130,8 @@ struct ELF_VISIBILITY SelectMap : public CPregamePackToPropagate const CMapInfo *mapInfo; bool free; - SelectMap(const CMapInfo &src) - { - mapInfo = &src; - free = false; - } - SelectMap() - { - mapInfo = nullptr; - free = true; - } + DLL_LINKAGE SelectMap(const CMapInfo &src); + DLL_LINKAGE SelectMap(); DLL_LINKAGE ~SelectMap(); void apply(CSelectionScreen *selScreen); //that functions are implemented in CPreGame.cpp @@ -2158,16 +2150,8 @@ struct ELF_VISIBILITY UpdateStartOptions : public CPregamePackToPropagate void apply(CSelectionScreen *selScreen); //that functions are implemented in CPreGame.cpp - UpdateStartOptions(StartInfo &src) - { - options = &src; - free = false; - } - UpdateStartOptions() - { - options = nullptr; - free = true; - } + DLL_LINKAGE UpdateStartOptions(StartInfo &src); + DLL_LINKAGE UpdateStartOptions(); DLL_LINKAGE ~UpdateStartOptions(); template void serialize(Handler &h, const int version) diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 7504af7db..2c700b101 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -62,12 +62,35 @@ DLL_LINKAGE void SetSecSkill::applyGs( CGameState *gs ) hero->setSecSkillLevel(which, val, abs); } + +DLL_LINKAGE SelectMap::SelectMap(const CMapInfo &src) +{ + mapInfo = &src; + free = false; +} +DLL_LINKAGE SelectMap::SelectMap() +{ + mapInfo = nullptr; + free = true; +} + DLL_LINKAGE SelectMap::~SelectMap() { if(free) delete mapInfo; } +DLL_LINKAGE UpdateStartOptions::UpdateStartOptions(StartInfo &src) +{ + options = &src; + free = false; +} +DLL_LINKAGE UpdateStartOptions::UpdateStartOptions() +{ + options = nullptr; + free = true; +} + DLL_LINKAGE UpdateStartOptions::~UpdateStartOptions() { if(free) diff --git a/lib/VCMI_lib.cbp b/lib/VCMI_lib.cbp index aaff61c72..a1cdd70e0 100644 --- a/lib/VCMI_lib.cbp +++ b/lib/VCMI_lib.cbp @@ -128,6 +128,7 @@ + From aea5a7ba758f3e68e76443483f599a0cb70f4412 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Thu, 26 Jun 2014 20:49:18 +0400 Subject: [PATCH 17/39] add comment. no code changes. --- lib/NetPacks.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 155f487bf..61cfedba6 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -2128,7 +2128,7 @@ struct PlayerJoined : public CPregamePackToHost struct ELF_VISIBILITY SelectMap : public CPregamePackToPropagate { const CMapInfo *mapInfo; - bool free; + bool free;//local flag, do not serialize DLL_LINKAGE SelectMap(const CMapInfo &src); DLL_LINKAGE SelectMap(); @@ -2146,7 +2146,7 @@ struct ELF_VISIBILITY SelectMap : public CPregamePackToPropagate struct ELF_VISIBILITY UpdateStartOptions : public CPregamePackToPropagate { StartInfo *options; - bool free; + bool free;//local flag, do not serialize void apply(CSelectionScreen *selScreen); //that functions are implemented in CPreGame.cpp From 20b0dd6211cf535d618bbdf04735917c66fa9086 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Thu, 26 Jun 2014 21:23:00 +0300 Subject: [PATCH 18/39] Renamed readme to readme.md to enable formatting in github UI --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From bac83d8bd01678279881e0343ab780867b0da91c Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 27 Jun 2014 00:07:09 +0300 Subject: [PATCH 19/39] Compatiblity for last version of Cove (and likely any other town mods) --- lib/CTownHandler.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index a31d0a65e..edb3e92b9 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -688,7 +688,19 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod JsonNode config = data["town"]["mapObject"]; config["faction"].String() = object->identifier; config["faction"].meta = scope; + if (config.meta.empty())// MODS COMPATIBILITY FOR 0.96 + config.meta = scope; VLC->objtypeh->loadSubObject(object->identifier, config, index, object->index); + + // MODS COMPATIBILITY FOR 0.96 + auto & advMap = data["town"]["adventureMap"]; + if (!advMap.isNull()) + { + logGlobal->warnStream() << "Outdated town mod. Will try to generate valid templates out of fort"; + JsonNode config; + config["animation"] = advMap["castle"]; + VLC->objtypeh->getHandlerFor(index, object->index)->addTemplate(config); + } }); } @@ -717,15 +729,6 @@ void CTownHandler::loadObject(std::string scope, std::string name, const JsonNod config["faction"].String() = object->identifier; config["faction"].meta = scope; VLC->objtypeh->loadSubObject(object->identifier, config, index, object->index); - - // MODS COMPATIBILITY FOR 0.96 - auto & advMap = data["town"]["adventureMap"]; - if (!advMap["fort"].isNull()) - { - JsonNode config; - config["appearance"] = advMap["fort"]; - VLC->objtypeh->getHandlerFor(index, object->index)->addTemplate(config); - } }); } From f63b1256d337b0543437eb46eeb11dcc7abc3597 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Fri, 27 Jun 2014 12:12:45 +0400 Subject: [PATCH 20/39] [ERM] Fix build * update project --- scripting/erm/ERM.cbp | 3 +-- scripting/erm/ERMInterpreter.cpp | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripting/erm/ERM.cbp b/scripting/erm/ERM.cbp index 47b15783f..279b417b6 100644 --- a/scripting/erm/ERM.cbp +++ b/scripting/erm/ERM.cbp @@ -48,7 +48,7 @@ - + @@ -58,7 +58,6 @@ - diff --git a/scripting/erm/ERMInterpreter.cpp b/scripting/erm/ERMInterpreter.cpp index f6fdaa3a4..f33a0dfbb 100644 --- a/scripting/erm/ERMInterpreter.cpp +++ b/scripting/erm/ERMInterpreter.cpp @@ -7,6 +7,8 @@ #include "../../lib/CCreatureHandler.h" #include "../../lib/VCMIDirs.h" #include "../../lib/IGameCallback.h" +#include "../../lib/mapObjects/CGHeroInstance.h" +#include "../../lib/mapObjects/MiscObjects.h" /* * ERMInterpreter.cpp, part of VCMI engine From f01e30a3b1d6bd8a0ae5754eb6dbfa881776ee98 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 27 Jun 2014 19:08:36 +0300 Subject: [PATCH 21/39] Added random objects to configs. For now as separate "random handlers", should be merged into main handlers later --- config/objects/generic.json | 34 ++++++++++++------------ config/objects/moddables.json | 29 ++++++++++++++++++-- lib/mapObjects/CObjectClassesHandler.cpp | 8 ++++++ 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/config/objects/generic.json b/config/objects/generic.json index f916b5be0..54e6132b1 100644 --- a/config/objects/generic.json +++ b/config/objects/generic.json @@ -64,26 +64,26 @@ }, /// Random objects - "randomResource" : { "index" :76, "handler": "resource" }, - "randomTown" : { "index" :77, "handler": "town" }, - "randomHero" : { "index" :70, "handler": "hero" }, + "randomResource" : { "index" :76, "handler": "randomResource", "types" : { "object" : { "index" : 0} } }, + "randomTown" : { "index" :77, "handler": "randomTown", "types" : { "object" : { "index" : 0} } }, + "randomHero" : { "index" :70, "handler": "randomHero", "types" : { "object" : { "index" : 0} } }, - "randomDwelling" : { "index" :216, "handler": "dwelling" }, + "randomDwelling" : { "index" :216, "handler": "randomDwelling", "types" : { "object" : { "index" : 0} } }, - "randomArtifact" : { "index" :65, "handler": "artifact" }, - "randomArtifactTreasure" : { "index" :66, "handler": "artifact" }, - "randomArtifactMinor" : { "index" :67, "handler": "artifact" }, - "randomArtifactMajor" : { "index" :68, "handler": "artifact" }, - "randomArtifactRelic" : { "index" :69, "handler": "artifact" }, + "randomArtifact" : { "index" :65, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, + "randomArtifactTreasure" : { "index" :66, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, + "randomArtifactMinor" : { "index" :67, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, + "randomArtifactMajor" : { "index" :68, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, + "randomArtifactRelic" : { "index" :69, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, - "randomMonster" : { "index" :71, "handler": "monster" }, - "randomMonsterLevel1" : { "index" :72, "handler": "monster" }, - "randomMonsterLevel2" : { "index" :73, "handler": "monster" }, - "randomMonsterLevel3" : { "index" :74, "handler": "monster" }, - "randomMonsterLevel4" : { "index" :75, "handler": "monster" }, - "randomMonsterLevel5" : { "index" :162, "handler": "monster" }, - "randomMonsterLevel6" : { "index" :163, "handler": "monster" }, - "randomMonsterLevel7" : { "index" :164, "handler": "monster" }, + "randomMonster" : { "index" :71, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomMonsterLevel1" : { "index" :72, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomMonsterLevel2" : { "index" :73, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomMonsterLevel3" : { "index" :74, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomMonsterLevel4" : { "index" :75, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomMonsterLevel5" : { "index" :162, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomMonsterLevel6" : { "index" :163, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomMonsterLevel7" : { "index" :164, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, /// Classes without dedicated object "hillFort" : { "index" :35, "handler": "generic", "types" : { "object" : { "index" : 0} } }, diff --git a/config/objects/moddables.json b/config/objects/moddables.json index 51268b93c..a93481eb5 100644 --- a/config/objects/moddables.json +++ b/config/objects/moddables.json @@ -236,10 +236,35 @@ "seerHut" : { "index" :83, "handler": "seerHut" }, // subtype: level - "randomDwellingLvl" : { "index" :217, "handler": "dwelling" }, + "randomDwellingLvl" : { + "index" :217, "handler": "randomDwelling", + "types" : { + "objectLvl1" : { "index" : 0}, + "objectLvl2" : { "index" : 1}, + "objectLvl3" : { "index" : 2}, + "objectLvl4" : { "index" : 3}, + "objectLvl5" : { "index" : 4}, + "objectLvl6" : { "index" : 5}, + "objectLvl7" : { "index" : 6} + } + }, // subtype: faction ID - "randomDwellingFaction" : { "index" :218, "handler": "dwelling" }, + "randomDwellingFaction" : { + "index" :218, + "handler": "randomDwelling", + "types" : { + "objectCastle" : { "index" : 0}, + "objectRampart" : { "index" : 1}, + "objectTower" : { "index" : 2}, + "objectInferno" : { "index" : 3}, + "objectNecropolis" : { "index" : 4}, + "objectDungeon" : { "index" : 5}, + "objectStronghold" : { "index" : 6}, + "objectFortress" : { "index" : 7}, + "objectCastle" : { "index" : 8}, + } + }, // don't have subtypes (at least now), but closely connected to this objects "spellScroll" : { "index" :93, "handler": "artifact" }, diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index e543a70ee..ed74a8933 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -40,6 +40,13 @@ CObjectClassesHandler::CObjectClassesHandler() SET_HANDLER_CLASS("static", CObstacleConstructor); SET_HANDLER_CLASS("", CObstacleConstructor); + SET_HANDLER("randomArtifact", CGArtifact); + SET_HANDLER("randomHero", CGHeroInstance); + SET_HANDLER("randomResource", CGResource); + SET_HANDLER("randomTown", CGTownInstance); + SET_HANDLER("randomMonster", CGCreature); + SET_HANDLER("randomDwelling", CGDwelling); + SET_HANDLER("generic", CGObjectInstance); SET_HANDLER("market", CGMarket); SET_HANDLER("cartographer", CCartographer); @@ -67,6 +74,7 @@ CObjectClassesHandler::CObjectClassesHandler() SET_HANDLER("pandora", CGPandoraBox); SET_HANDLER("pickable", CGPickable); SET_HANDLER("prison", CGHeroInstance); + SET_HANDLER("prison", CGHeroInstance); SET_HANDLER("questGuard", CGQuestGuard); SET_HANDLER("resource", CGResource); SET_HANDLER("scholar", CGScholar); From 52b17334a0c53f173807017571750d19fcb9f329 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 27 Jun 2014 19:13:43 +0300 Subject: [PATCH 22/39] Added object for scrolls and hero placeholders. Typo fix --- config/objects/moddables.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/objects/moddables.json b/config/objects/moddables.json index a93481eb5..c1c908c7f 100644 --- a/config/objects/moddables.json +++ b/config/objects/moddables.json @@ -262,11 +262,11 @@ "objectDungeon" : { "index" : 5}, "objectStronghold" : { "index" : 6}, "objectFortress" : { "index" : 7}, - "objectCastle" : { "index" : 8}, + "objectConflux" : { "index" : 8}, } }, // don't have subtypes (at least now), but closely connected to this objects - "spellScroll" : { "index" :93, "handler": "artifact" }, - "heroPlaceholder" : { "index" :214, "handler": "heroPlaceholder" } + "spellScroll" : { "index" :93, "handler": "artifact", "types" : { "object" : { "index" : 0 } } }, + "heroPlaceholder" : { "index" :214, "handler": "heroPlaceholder", "types" : { "object" : { "index" : 0 } } } } From 0f5826802d2823aa94eea2dc01737e27842bb022 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 27 Jun 2014 20:36:50 +0300 Subject: [PATCH 23/39] Defined templates for objects with incorrect info in objects.txt: - random arts - random resources - random creatures - spell scroll --- config/objects/generic.json | 184 +++++++++++++++++++++++++++++++--- config/objects/moddables.json | 17 +++- 2 files changed, 185 insertions(+), 16 deletions(-) diff --git a/config/objects/generic.json b/config/objects/generic.json index 54e6132b1..c92a6d97a 100644 --- a/config/objects/generic.json +++ b/config/objects/generic.json @@ -64,26 +64,180 @@ }, /// Random objects - "randomResource" : { "index" :76, "handler": "randomResource", "types" : { "object" : { "index" : 0} } }, "randomTown" : { "index" :77, "handler": "randomTown", "types" : { "object" : { "index" : 0} } }, "randomHero" : { "index" :70, "handler": "randomHero", "types" : { "object" : { "index" : 0} } }, - "randomDwelling" : { "index" :216, "handler": "randomDwelling", "types" : { "object" : { "index" : 0} } }, - "randomArtifact" : { "index" :65, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, - "randomArtifactTreasure" : { "index" :66, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, - "randomArtifactMinor" : { "index" :67, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, - "randomArtifactMajor" : { "index" :68, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, - "randomArtifactRelic" : { "index" :69, "handler": "randomArtifact", "types" : { "object" : { "index" : 0} } }, + "randomResource" : { + "index" :76, + "handler": "randomResource", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVTrndm0", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, - "randomMonster" : { "index" :71, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, - "randomMonsterLevel1" : { "index" :72, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, - "randomMonsterLevel2" : { "index" :73, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, - "randomMonsterLevel3" : { "index" :74, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, - "randomMonsterLevel4" : { "index" :75, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, - "randomMonsterLevel5" : { "index" :162, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, - "randomMonsterLevel6" : { "index" :163, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, - "randomMonsterLevel7" : { "index" :164, "handler": "randomMonster", "types" : { "object" : { "index" : 0} } }, + "randomArtifact" : { + "index" :65, + "handler": "randomArtifact", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVArand", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomArtifactTreasure" : { + "index" :66, + "handler": "randomArtifact", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVArnd1", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomArtifactMinor" : { + "index" :67, + "handler": "randomArtifact", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVArnd2", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomArtifactMajor" : { + "index" :68, + "handler": "randomArtifact", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVArnd3", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomArtifactRelic" : { + "index" :69, + "handler": "randomArtifact", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVArnd4", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + + "randomMonster" : { + "index" :71, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmrnd0", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomMonsterLevel1" : { + "index" :72, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmon1", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomMonsterLevel2" : { + "index" :73, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmon2", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomMonsterLevel3" : { + "index" :74, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmon3", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomMonsterLevel4" : { + "index" :75, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmon4", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomMonsterLevel5" : { + "index" :162, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmon5", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomMonsterLevel6" : { + "index" :163, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmon6", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, + "randomMonsterLevel7" : { + "index" :164, + "handler": "randomMonster", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { "animation" : "AVWmon7", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] } + } + } + } + }, /// Classes without dedicated object "hillFort" : { "index" :35, "handler": "generic", "types" : { "object" : { "index" : 0} } }, diff --git a/config/objects/moddables.json b/config/objects/moddables.json index c1c908c7f..1f460b3c1 100644 --- a/config/objects/moddables.json +++ b/config/objects/moddables.json @@ -267,6 +267,21 @@ }, // don't have subtypes (at least now), but closely connected to this objects - "spellScroll" : { "index" :93, "handler": "artifact", "types" : { "object" : { "index" : 0 } } }, + "spellScroll" : { + "index" :93, + "handler": "artifact", + "types" : { + "object" : { + "index" : 0, + "templates" : { + "normal" : { + "visitableFrom" : [ "+++", "+-+", "+++" ], + "mask" : [ "VA" ], + "animation" : "AVA0001.def" + } + } + } + } + }, "heroPlaceholder" : { "index" :214, "handler": "heroPlaceholder", "types" : { "object" : { "index" : 0 } } } } From 90b72a78566a3703b94b64cdfb9119a6e47a65f1 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Fri, 27 Jun 2014 20:28:21 +0200 Subject: [PATCH 24/39] Workaround with Obelisks. Kill me later. --- lib/rmg/CRmgTemplateZone.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index 7851b7cff..2a12ee9b4 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -973,7 +973,7 @@ void CRmgTemplateZone::createObstacles(CMapGenerator* gen) if (gen->shouldBeBlocked(tile)) //fill tiles that should be blocked with obstacles { auto obj = new CGObjectInstance(); - obj->ID = static_cast(130); + obj->ID = static_cast(57); obj->subID = 0; placeObject(gen, obj, tile); } From 7aa8213cd5f333186dad5e534a4979e82625efc5 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Fri, 27 Jun 2014 21:48:17 +0200 Subject: [PATCH 25/39] Tweaked templates to allow all map sizes. To be released as 0.95c. --- config/rmg.json | 4 ++-- lib/GameConstants.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/rmg.json b/config/rmg.json index 9df21b1b8..8ca2e8845 100644 --- a/config/rmg.json +++ b/config/rmg.json @@ -2,7 +2,7 @@ { "Analogy" : { - "minSize" : "m", "maxSize" : "m", + "minSize" : "s", "maxSize" : "m", "players" : "4", "zones" : { @@ -126,7 +126,7 @@ }, "Golden Ring" : { - "minSize" : "m", "maxSize" : "m", + "minSize" : "m", "maxSize" : "l", "players" : "3", "zones" : { diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 62f483114..e0229431d 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -14,7 +14,7 @@ namespace GameConstants { - const std::string VCMI_VERSION = "VCMI 0.95b"; + const std::string VCMI_VERSION = "VCMI 0.95c"; const int BFIELD_WIDTH = 17; const int BFIELD_HEIGHT = 11; From 920f56969b0501c116779f0f7d345b88a734ca96 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Sat, 28 Jun 2014 09:46:32 +0200 Subject: [PATCH 26/39] Create random obstacles that match terrain. --- ChangeLog | 2 +- lib/mapObjects/CObjectHandler.cpp | 11 +----- lib/mapObjects/ObjectTemplate.cpp | 27 ++++++++++++++ lib/mapObjects/ObjectTemplate.h | 3 ++ lib/rmg/CRmgTemplateZone.cpp | 62 +++++++++++++++++++++++++++---- lib/rmg/CRmgTemplateZone.h | 3 ++ 6 files changed, 89 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 64ba175f1..963c4e4e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ SPELLS: * New configuration format: http://wiki.vcmi.eu/index.php?title=Spell_Format RANDOM MAP GENERATOR -* Towns form mods cna be used +* Towns from mods can be used * Reading connections, terrains, towns and mines from template * Zone placement * Zone borders and connections, fractalized paths inside zones diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index b03980f8c..a08e77bf0 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -178,16 +178,7 @@ std::set CGObjectInstance::getBlockedPos() const std::set CGObjectInstance::getBlockedOffsets() const { - std::set ret; - for(int w=0; w ObjectTemplate::getBlockedOffsets() const +{ + std::set ret; + for(int w = 0; w < getWidth(); ++w) + { + for(int h = 0; h < getHeight(); ++h) + { + if (isBlockedAt(w, h)) + ret.insert(int3(-w, -h, 0)); + } + } + return ret; +} + +int3 ObjectTemplate::getBlockMapOffset() const +{ + for(int w = 0; w < getWidth(); ++w) + { + for(int h = 0; h < getHeight(); ++h) + { + if (isBlockedAt(w, h)) + return int3(-w, -h, 0); + } + } + return int3(-1,-1,-1); +} + bool ObjectTemplate::isVisitableFrom(si8 X, si8 Y) const { // visitDir uses format diff --git a/lib/mapObjects/ObjectTemplate.h b/lib/mapObjects/ObjectTemplate.h index 89353b26c..62320363e 100644 --- a/lib/mapObjects/ObjectTemplate.h +++ b/lib/mapObjects/ObjectTemplate.h @@ -15,6 +15,7 @@ class CBinaryReader; class CLegacyConfigParser; class JsonNode; +class int3; class DLL_LINKAGE ObjectTemplate { @@ -56,6 +57,8 @@ public: bool isVisitableAt(si32 X, si32 Y) const; bool isVisibleAt(si32 X, si32 Y) const; bool isBlockedAt(si32 X, si32 Y) const; + std::set getBlockedOffsets() const; + int3 getBlockMapOffset() const; //bottom-right corner when firts blocked tile is // Checks if object is visitable from certain direction. X and Y must be between -1..+1 bool isVisitableFrom(si8 X, si8 Y) const; diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index 2a12ee9b4..598231ee2 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -962,20 +962,49 @@ void CRmgTemplateZone::createTreasures(CMapGenerator* gen) void CRmgTemplateZone::createObstacles(CMapGenerator* gen) { + //get all possible obstacles for this terrain + for (auto primaryID : VLC->objtypeh->knownObjects()) + { + for (auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID)) + { + auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); + if (handler->isStaticObject()) + { + for (auto temp : handler->getTemplates()) + { + if (temp.canBePlacedAt(terrainType) && temp.getBlockMapOffset().valid()) + possibleObstacles.push_back(temp); + } + } + } + } + auto sel = gen->editManager->getTerrainSelection(); sel.clearSelection(); + + auto tryToPlaceObstacleHere = [this, gen](int3& tile)-> bool + { + auto temp = *RandomGeneratorUtil::nextItem(possibleObstacles, gen->rand); + int3 obstaclePos = tile + temp.getBlockMapOffset(); + if (canObstacleBePlacedHere(gen, temp, obstaclePos)) //can be placed here + { + auto obj = VLC->objtypeh->getHandlerFor(temp.id, temp.subid)->create(temp); + placeObject(gen, obj, obstaclePos); + return true; + } + return false; + }; + for (auto tile : tileinfo) { - //test code - block all the map to show paths clearly - //if (gen->isPossible(tile)) - // gen->setOccupied(tile, ETileType::BLOCKED); - if (gen->shouldBeBlocked(tile)) //fill tiles that should be blocked with obstacles { - auto obj = new CGObjectInstance(); - obj->ID = static_cast(57); - obj->subID = 0; - placeObject(gen, obj, tile); + while (!tryToPlaceObstacleHere(tile)); + } + else if (gen->isPossible(tile)) + { + //try to place random obstacle once - if not possible, leave it clear + tryToPlaceObstacleHere(tile); } } } @@ -1031,6 +1060,23 @@ bool CRmgTemplateZone::findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dis return result; } +bool CRmgTemplateZone::canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos) +{ + auto tilesBlockedByObject = temp.getBlockedOffsets(); + + bool allTilesAvailable = true; + for (auto blockingTile : tilesBlockedByObject) + { + int3 t = pos + blockingTile; + if (!gen->map->isInTheMap(t) || !(gen->isPossible(t) || gen->shouldBeBlocked(t))) + { + allTilesAvailable = false; //if at least one tile is not possible, object can't be placed here + break; + } + } + return allTilesAvailable; +} + bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos) { //we need object apperance to deduce free tiles diff --git a/lib/rmg/CRmgTemplateZone.h b/lib/rmg/CRmgTemplateZone.h index 3eb277b94..03532719d 100644 --- a/lib/rmg/CRmgTemplateZone.h +++ b/lib/rmg/CRmgTemplateZone.h @@ -21,6 +21,7 @@ class CMapGenerator; class CTileInfo; class int3; class CGObjectInstance; +class ObjectTemplate; namespace ETemplateZoneType { @@ -173,6 +174,7 @@ private: ui16 totalDensity; std::vector treasureInfo; std::vector possibleObjects; + std::vector possibleObstacles; //content info std::vector> requiredObjects; @@ -189,6 +191,7 @@ private: void addAllPossibleObjects (CMapGenerator* gen); //add objects, including zone-specific, to possibleObjects bool findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos); bool findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dist, int3 &pos); + bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos); void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos); void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos); bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str); From 917b1ffca876aa3abf474a84f301ffe4f78d61df Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sat, 28 Jun 2014 17:19:53 +0300 Subject: [PATCH 27/39] Bugfixing: - Added missing types for serialization - Fixed possible crash in removable objects (campfire) - Fixed typo in bank config --- config/objects/creatureBanks.json | 8 ++++---- lib/CGameState.cpp | 4 ++-- lib/mapObjects/CGHeroInstance.cpp | 9 ++++++--- lib/mapObjects/CRewardableObject.cpp | 7 ++++++- lib/registerTypes/RegisterTypes.h | 2 ++ 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/config/objects/creatureBanks.json b/config/objects/creatureBanks.json index 6cba397be..e1ad6f6e9 100644 --- a/config/objects/creatureBanks.json +++ b/config/objects/creatureBanks.json @@ -526,7 +526,7 @@ "combat_value": 154, "reward" : { "value": 3200, - "creatures": [ { "amount": 4, "type": "vyvern" } ] + "creatures": [ { "amount": 4, "type": "wyvern" } ] } }, { @@ -541,7 +541,7 @@ "combat_value": 230, "reward" : { "value": 4800, - "creatures": [ { "amount": 6, "type": "vyvern" } ] + "creatures": [ { "amount": 6, "type": "wyvern" } ] } }, { @@ -556,7 +556,7 @@ "combat_value": 307, "reward" : { "value": 6400, - "creatures": [ { "amount": 8, "type": "vyvern" } ] + "creatures": [ { "amount": 8, "type": "wyvern" } ] } }, { @@ -571,7 +571,7 @@ "combat_value": 461, "reward" : { "value": 9600, - "creatures": [ { "amount": 12, "type": "vyvern" } ] + "creatures": [ { "amount": 12, "type": "wyvern" } ] } } ] diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index a5fe9923b..0a41eec3c 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -256,7 +256,7 @@ DLL_LINKAGE void MetaString::toString(std::string &dst) const boost::replace_first(dst, "%+d", '+' + boost::lexical_cast(numbers[nums++])); break; default: - logGlobal->errorStream() << "MetaString processing error!"; + logGlobal->errorStream() << "MetaString processing error! Received message of type " << int(elem); break; } } @@ -313,7 +313,7 @@ DLL_LINKAGE std::string MetaString::buildList () const lista.replace (lista.find("%d"), 2, boost::lexical_cast(numbers[nums++])); break; default: - logGlobal->errorStream() << "MetaString processing error!"; + logGlobal->errorStream() << "MetaString processing error! Received message of type " << int(message[i]); } } diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 10464505b..96a98826c 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -473,9 +473,12 @@ void CGHeroInstance::initObj() skillsInfo.resetMagicSchoolCounter(); skillsInfo.resetWisdomCounter(); - auto customApp = VLC->objtypeh->getHandlerFor(ID, type->heroClass->id)->getOverride(cb->gameState()->getTile(visitablePos())->terType, this); - if (customApp) - appearance = customApp.get(); + if (ID != Obj::PRISON) + { + auto customApp = VLC->objtypeh->getHandlerFor(ID, type->heroClass->id)->getOverride(cb->gameState()->getTile(visitablePos())->terType, this); + if (customApp) + appearance = customApp.get(); + } for(const auto &spec : type->spec) //TODO: unfity with bonus system { diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 4b8561e48..482d82bfa 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -78,6 +78,7 @@ std::vector CRewardableObject::getAvailableRewards(const CGHeroInstance * if (visit.numOfGrants < visit.limiter.numOfGrants && visit.limiter.heroAllowed(hero)) { + logGlobal->debugStream() << "Reward " << i << " is allowed"; ret.push_back(i); } } @@ -88,7 +89,7 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const { auto grantRewardWithMessage = [&](int index) -> void { - grantReward(index, h); + logGlobal->debugStream() << "Granting reward " << index << ". Message says: " << info[index].message.toString(); // show message only if it is not empty if (!info[index].message.toString().empty()) { @@ -99,6 +100,8 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const info[index].reward.loadComponents(iw.components); cb->showInfoDialog(&iw); } + // grant reward afterwards. Note that it may remove object + grantReward(index, h); }; auto selectRewardsMessage = [&](std::vector rewards) -> void { @@ -114,6 +117,7 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const if (!wasVisited(h)) { auto rewards = getAvailableRewards(h); + logGlobal->debugStream() << "Visiting object with " << rewards.size() << " possible rewards"; switch (rewards.size()) { case 0: // no available rewards, e.g. empty flotsam @@ -155,6 +159,7 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const } else { + logGlobal->debugStream() << "Revisiting already visited object"; InfoWindow iw; iw.player = h->tempOwner; iw.soundID = soundID; diff --git a/lib/registerTypes/RegisterTypes.h b/lib/registerTypes/RegisterTypes.h index 8bf37da4d..8f44d5446 100644 --- a/lib/registerTypes/RegisterTypes.h +++ b/lib/registerTypes/RegisterTypes.h @@ -97,6 +97,7 @@ void registerTypesMapObjectTypes(Serializer &s) REGISTER_GENERIC_HANDLER(CGBorderGuard); REGISTER_GENERIC_HANDLER(CGCreature); REGISTER_GENERIC_HANDLER(CGDenOfthieves); + REGISTER_GENERIC_HANDLER(CGDwelling); REGISTER_GENERIC_HANDLER(CGEvent); REGISTER_GENERIC_HANDLER(CGGarrison); REGISTER_GENERIC_HANDLER(CGHeroPlaceholder); @@ -122,6 +123,7 @@ void registerTypesMapObjectTypes(Serializer &s) REGISTER_GENERIC_HANDLER(CGSignBottle); REGISTER_GENERIC_HANDLER(CGSirens); REGISTER_GENERIC_HANDLER(CGTeleport); + REGISTER_GENERIC_HANDLER(CGTownInstance); REGISTER_GENERIC_HANDLER(CGUniversity); REGISTER_GENERIC_HANDLER(CGVisitableOPH); REGISTER_GENERIC_HANDLER(CGVisitableOPW); From 1157111fcf3717cc5bee9809e5c7354ddc375988 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 29 Jun 2014 17:23:06 +0300 Subject: [PATCH 28/39] More bugfixing: - Fixed compile in VCAI (precompiled headers should not include VCMI headers) - Fixed crash on visiting observatories, including shroud of darkness --- AI/VCAI/AIUtility.cpp | 1 + AI/VCAI/StdInc.h | 2 -- AI/VCAI/VCAI.cpp | 2 ++ lib/mapObjects/MiscObjects.cpp | 2 +- server/CGameHandler.cpp | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/AI/VCAI/AIUtility.cpp b/AI/VCAI/AIUtility.cpp index 37ad79386..887f4757a 100644 --- a/AI/VCAI/AIUtility.cpp +++ b/AI/VCAI/AIUtility.cpp @@ -1,6 +1,7 @@ #include "StdInc.h" #include "AIUtility.h" #include "VCAI.h" +#include "Fuzzy.h" #include "../../lib/UnlockGuard.h" #include "../../lib/CConfigHandler.h" diff --git a/AI/VCAI/StdInc.h b/AI/VCAI/StdInc.h index 6448c2288..e0eeaf0aa 100644 --- a/AI/VCAI/StdInc.h +++ b/AI/VCAI/StdInc.h @@ -1,4 +1,2 @@ #pragma once #include "../../Global.h" - -#include "Fuzzy.h" diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index fbf9f1831..b0477fcf8 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -1,6 +1,8 @@ #include "StdInc.h" #include "VCAI.h" #include "Goals.h" +#include "Fuzzy.h" + #include "../../lib/UnlockGuard.h" #include "../../lib/mapObjects/MapObjects.h" #include "../../lib/CConfigHandler.h" diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index d5e9fa2d8..fcd7071db 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -1061,7 +1061,7 @@ void CGObservatory::onHeroVisit( const CGHeroInstance * h ) const case Obj::COVER_OF_DARKNESS: { iw.text.addTxt (MetaString::ADVOB_TXT, 31); - for (auto player : cb->gameState()->players) + for (auto & player : cb->gameState()->players) { if (cb->getPlayerStatus(player.first) == EPlayerStatus::INGAME && cb->getPlayerRelations(player.first, h->tempOwner) == PlayerRelations::ENEMIES) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 93bcbc02b..7684404e4 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1351,7 +1351,7 @@ void CGameHandler::newTurn() } if (t->hasBonusOfType (Bonus::DARKNESS)) { - for (auto player : gameState()->players) + for (auto & player : gameState()->players) { if (getPlayerStatus(player.first) == EPlayerStatus::INGAME && getPlayerRelations(player.first, t->tempOwner) == PlayerRelations::ENEMIES) From f01ab0d48fa146abe6fafb262984cf7f7a98264d Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 29 Jun 2014 20:13:25 +0300 Subject: [PATCH 29/39] Fixed rest of reported on forums bugs in rewardables --- lib/mapObjects/CRewardableObject.cpp | 44 +++++++++++++++++++--------- lib/mapObjects/CRewardableObject.h | 2 +- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 482d82bfa..d0ca8e293 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -76,7 +76,8 @@ std::vector CRewardableObject::getAvailableRewards(const CGHeroInstance * { const CVisitInfo & visit = info[i]; - if (visit.numOfGrants < visit.limiter.numOfGrants && visit.limiter.heroAllowed(hero)) + if ((visit.limiter.numOfGrants == 0 || visit.numOfGrants < visit.limiter.numOfGrants) // reward has unlimited uses or some are still available + && visit.limiter.heroAllowed(hero)) { logGlobal->debugStream() << "Reward " << i << " is allowed"; ret.push_back(i); @@ -270,7 +271,10 @@ void CRewardableObject::grantRewardAfterLevelup(const CVisitInfo & info, const C for (const Bonus & bonus : info.reward.bonuses) { + assert(bonus.source == Bonus::OBJECT); + assert(bonus.sid == ID); GiveBonus gb; + gb.who = GiveBonus::HERO; gb.bonus = bonus; gb.id = hero->id.getNum(); cb->giveHeroBonus(&gb); @@ -306,7 +310,7 @@ bool CRewardableObject::wasVisited (PlayerColor player) const { case VISIT_UNLIMITED: return false; - case VISIT_ONCE: + case VISIT_ONCE: // FIXME: hide this info deeper and return same as player? for (auto & visit : info) { if (visit.numOfGrants != 0) @@ -315,7 +319,7 @@ bool CRewardableObject::wasVisited (PlayerColor player) const case VISIT_HERO: return false; case VISIT_PLAYER: - return vstd::contains(cb->getPlayer(player)->visitedObjects, ObjectInstanceID(ID)); + return vstd::contains(cb->getPlayer(player)->visitedObjects, ObjectInstanceID(id)); default: return false; } @@ -325,8 +329,10 @@ bool CRewardableObject::wasVisited (const CGHeroInstance * h) const { switch (visitMode) { + case VISIT_UNLIMITED: + return h->hasBonusFrom(Bonus::OBJECT, ID); case VISIT_HERO: - return vstd::contains(h->visitedObjects, ObjectInstanceID(ID)) || h->hasBonusFrom(Bonus::OBJECT, ID); + return h->visitedObjects.count(ObjectInstanceID(id)); default: return wasVisited(h->tempOwner); } @@ -337,12 +343,6 @@ void CRewardInfo::loadComponents(std::vector & comps) const for (auto comp : extraComponents) comps.push_back(comp); - for (size_t i=0; i & comps) const for (auto & entry : creatures) comps.push_back(Component(Component::CREATURE, entry.type->idNumber, entry.count, 0)); + + for (size_t i=0; i creatures; CRewardLimiter(): - numOfGrants(1), + numOfGrants(0), dayOfWeek(0), minLevel(0), primary(4, 0) From a1fff864e618ea9d234341307fa92401b3eddf3f Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 30 Jun 2014 00:16:45 +0300 Subject: [PATCH 30/39] Fixed missing names for dwellings and creature banks --- lib/mapObjects/CBank.cpp | 10 ++--- lib/mapObjects/CObjectClassesHandler.cpp | 47 ++++++++++++++++++++++-- lib/mapObjects/CObjectClassesHandler.h | 18 +++++++-- lib/mapObjects/CObjectHandler.cpp | 2 +- lib/mapObjects/CRewardableObject.cpp | 3 +- lib/mapObjects/CommonConstructors.cpp | 7 +++- 6 files changed, 68 insertions(+), 19 deletions(-) diff --git a/lib/mapObjects/CBank.cpp b/lib/mapObjects/CBank.cpp index a653dcbfd..f80d740b9 100644 --- a/lib/mapObjects/CBank.cpp +++ b/lib/mapObjects/CBank.cpp @@ -45,10 +45,8 @@ void CBank::initObj() std::string CBank::getHoverText(PlayerColor player) const { - // TODO: USE BANK_SPECIFIC NAMES // TODO: record visited players - bool visited = (bc == nullptr); - return visitedTxt(visited); + return getObjectName() + " " + visitedTxt(bc == nullptr); } void CBank::setConfig(const BankConfig & config) @@ -128,8 +126,8 @@ void CBank::onHeroVisit (const CGHeroInstance * h) const bd.player = h->getOwner(); bd.soundID = soundID; bd.text.addTxt(MetaString::ADVOB_TXT, banktext); - //if (ID == Obj::CREATURE_BANK) - // bd.text.addReplacement(VLC->objh->creBanksNames[index]); // FIXME: USE BANK SPECIFIC NAMES + if (ID == Obj::CREATURE_BANK) + bd.text.addReplacement(getObjectName()); cb->showBlockingDialog (&bd); } else @@ -149,7 +147,7 @@ void CBank::onHeroVisit (const CGHeroInstance * h) const else { iw.text << VLC->generaltexth->advobtxt[33];// This was X, now is completely empty - //iw.text.addReplacement(VLC->objh->creBanksNames[index]); // FIXME: USE BANK SPECIFIC NAMES + iw.text.addReplacement(getObjectName()); } cb->showInfoDialog(&iw); } diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index 2720226a5..1e1ccc4f5 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -117,6 +117,17 @@ std::vector CObjectClassesHandler::loadLegacyData(size_t dataSize) ret[i]["name"].String() = namesParser.readString(); namesParser.endLine(); } + + CLegacyConfigParser cregen1Parser("data/crgen1"); + do + customNames[Obj::CREATURE_GENERATOR1].push_back(cregen1Parser.readString()); + while(cregen1Parser.endLine()); + + CLegacyConfigParser cregen4Parser("data/crgen4"); + do + customNames[Obj::CREATURE_GENERATOR4].push_back(cregen4Parser.readString()); + while(cregen4Parser.endLine()); + return ret; } @@ -142,12 +153,16 @@ void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContai logGlobal->errorStream() << "Handler with name " << obj->handlerName << " was not found!"; return; } - auto handler = handlerConstructors.at(obj->handlerName)(); - handler->init(entry); - si32 id = selectNextID(entry["index"], obj->objects, 1000); + + auto handler = handlerConstructors.at(obj->handlerName)(); handler->setType(obj->id, id); + if (customNames.count(obj->id) && customNames.at(obj->id).size() > id) + handler->init(entry, customNames.at(obj->id).at(id)); + else + handler->init(entry); + if (handler->getTemplates().empty()) { auto range = legacyTemplates.equal_range(std::make_pair(obj->id, id)); @@ -208,6 +223,7 @@ void CObjectClassesHandler::loadSubObject(std::string name, JsonNode config, si3 std::string oldMeta = config.meta; // FIXME: move into inheritNode? JsonUtils::inherit(config, objects.at(ID)->base); config.setMeta(oldMeta); + loadObjectEntry(config, objects[ID]); } @@ -290,6 +306,17 @@ std::string CObjectClassesHandler::getObjectName(si32 type) const return ""; } +std::string CObjectClassesHandler::getObjectName(si32 type, si32 subtype) const +{ + if (knownSubObjects(type).count(subtype)) + { + auto name = getHandlerFor(type, subtype)->getCustomName(); + if (name) + return name.get(); + } + return getObjectName(type); +} + void AObjectTypeHandler::setType(si32 type, si32 subtype) { this->type = type; @@ -304,7 +331,7 @@ static ui32 loadJsonOrMax(const JsonNode & input) return input.Float(); } -void AObjectTypeHandler::init(const JsonNode & input) +void AObjectTypeHandler::init(const JsonNode & input, boost::optional name) { base = input["base"]; @@ -328,6 +355,12 @@ void AObjectTypeHandler::init(const JsonNode & input) tmpl.readJson(entry.second); templates.push_back(tmpl); } + + if (input["name"].isNull()) + objectName = name; + else + objectName.reset(input["name"].String()); + initTypeData(input); } @@ -338,6 +371,12 @@ bool AObjectTypeHandler::objectFilter(const CGObjectInstance *, const ObjectTemp void AObjectTypeHandler::initTypeData(const JsonNode & input) { + // empty implementation for overrides +} + +boost::optional AObjectTypeHandler::getCustomName() const +{ + return objectName; } void AObjectTypeHandler::addTemplate(ObjectTemplate templ) diff --git a/lib/mapObjects/CObjectClassesHandler.h b/lib/mapObjects/CObjectClassesHandler.h index a16fb0ba4..30a4ef88f 100644 --- a/lib/mapObjects/CObjectClassesHandler.h +++ b/lib/mapObjects/CObjectClassesHandler.h @@ -98,6 +98,9 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable { RandomMapInfo rmgInfo; + /// Human-readable name of this object, used for objects like banks and dwellings, if set + boost::optional objectName; + si32 type; si32 subtype; @@ -116,7 +119,10 @@ public: void setType(si32 type, si32 subtype); /// loads generic data from Json structure and passes it towards type-specific constructors - void init(const JsonNode & input); + void init(const JsonNode & input, boost::optional name = boost::optional()); + + /// Returns object-specific name, if set + boost::optional getCustomName() const; void addTemplate(ObjectTemplate templ); void addTemplate(JsonNode config); @@ -148,7 +154,7 @@ public: template void serialize(Handler &h, const int version) { - h & type & subtype & templates & rmgInfo; + h & type & subtype & templates & rmgInfo & objectName; } }; @@ -174,8 +180,6 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase } }; - typedef std::multimap, ObjectTemplate> TTemplatesContainer; - /// list of object handlers, each of them handles only one type std::map objects; @@ -183,8 +187,13 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase std::map > handlerConstructors; /// container with H3 templates, used only during loading, no need to serialize it + typedef std::multimap, ObjectTemplate> TTemplatesContainer; TTemplatesContainer legacyTemplates; + /// contains list of custom names for H3 objects (e.g. Dwellings), used to load H3 data + /// format: customNames[primaryID][secondaryID] -> name + std::map> customNames; + void loadObjectEntry(const JsonNode & entry, ObjectContainter * obj); ObjectContainter * loadFromJson(const JsonNode & json); public: @@ -211,6 +220,7 @@ public: TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const; std::string getObjectName(si32 type) const; + std::string getObjectName(si32 type, si32 subtype) const; template void serialize(Handler &h, const int version) { diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index b03980f8c..583193216 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -272,7 +272,7 @@ void CGObjectInstance::giveDummyBonus(ObjectInstanceID heroID, ui8 duration) con std::string CGObjectInstance::getObjectName() const { - return VLC->objtypeh->getObjectName(ID); + return VLC->objtypeh->getObjectName(ID, subID); } std::string CGObjectInstance::getHoverText(PlayerColor player) const diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index d0ca8e293..6a4786ced 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -184,7 +184,6 @@ void CRewardableObject::blockingDialogAnswered(const CGHeroInstance *hero, ui32 if (answer > 0 && answer-1 < info.size()) { - //NOTE: this relies on assumption that there won't be any changes in player/hero during blocking dialog auto list = getAvailableRewards(hero); grantReward(list[answer - 1], hero); } @@ -470,7 +469,7 @@ void CGPickable::initObj() blockVisit = true; switch(ID) { - case Obj::CAMPFIRE: //FIXME: campfire is not functioning correctly in game (no visible message) + case Obj::CAMPFIRE: { soundID = soundBase::experience; int givenRes = cb->gameState()->getRandomGenerator().nextInt(5); diff --git a/lib/mapObjects/CommonConstructors.cpp b/lib/mapObjects/CommonConstructors.cpp index af259e564..7fb4ce5ff 100644 --- a/lib/mapObjects/CommonConstructors.cpp +++ b/lib/mapObjects/CommonConstructors.cpp @@ -195,8 +195,11 @@ void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CR if (guards.getType() == JsonNode::DATA_BOOL) { - const CCreature * crea = availableCreatures.at(0).at(0); - dwelling->putStack(SlotID(0), new CStackInstance(crea->idNumber, crea->growth * 3 )); + if (guards.Bool()) + { + const CCreature * crea = availableCreatures.at(0).at(0); + dwelling->putStack(SlotID(0), new CStackInstance(crea->idNumber, crea->growth * 3 )); + } } else for (auto & stack : JsonRandom::loadCreatures(guards, rng)) { From 50dfe05cd1b0899a73e30df96a08c4a6bb53e391 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Fri, 27 Jun 2014 13:04:47 +0400 Subject: [PATCH 31/39] [C::B] Small projects fix --- client/VCMI_client.cbp | 1 - lib/VCMI_lib.cbp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/client/VCMI_client.cbp b/client/VCMI_client.cbp index 36d340ee6..488fd2776 100644 --- a/client/VCMI_client.cbp +++ b/client/VCMI_client.cbp @@ -101,7 +101,6 @@ - diff --git a/lib/VCMI_lib.cbp b/lib/VCMI_lib.cbp index a1cdd70e0..83a15af5b 100644 --- a/lib/VCMI_lib.cbp +++ b/lib/VCMI_lib.cbp @@ -108,6 +108,7 @@ + From db221829aab558ee108ecfbea956168b2c82b9ad Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 30 Jun 2014 17:11:25 +0300 Subject: [PATCH 32/39] Modding-related bugfixes: - hero classes will be loaded correctly - objects without index will have correctly assigned ID's --- lib/CHeroHandler.cpp | 2 +- lib/CModHandler.cpp | 1 + lib/mapObjects/CObjectClassesHandler.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 1a8414dbd..25c43d4a4 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -199,7 +199,7 @@ void CHeroClassHandler::loadObject(std::string scope, std::string name, const Js VLC->modh->identifiers.requestIdentifier(scope, "object", "hero", [=](si32 index) { - JsonNode classConf; + JsonNode classConf = data["mapObject"]; classConf["heroClass"].String() = name; classConf.setMeta(scope); VLC->objtypeh->loadSubObject(name, classConf, index, object->id); diff --git a/lib/CModHandler.cpp b/lib/CModHandler.cpp index 9cd4b8072..9f5422566 100644 --- a/lib/CModHandler.cpp +++ b/lib/CModHandler.cpp @@ -310,6 +310,7 @@ bool CContentHandler::ContentTypeHandler::preloadModData(std::string modName, st if (remoteName == modName) logGlobal->warnStream() << "Redundant namespace definition for " << objectName; + logGlobal->traceStream() << "Patching object " << objectName << " (" << remoteName << ") from " << modName; JsonNode & remoteConf = modData[remoteName].patches[objectName]; JsonUtils::merge(remoteConf, entry.second); diff --git a/lib/mapObjects/CObjectClassesHandler.cpp b/lib/mapObjects/CObjectClassesHandler.cpp index 1e1ccc4f5..8c276e05a 100644 --- a/lib/mapObjects/CObjectClassesHandler.cpp +++ b/lib/mapObjects/CObjectClassesHandler.cpp @@ -140,7 +140,7 @@ si32 selectNextID(const JsonNode & fixedID, const Map & map, si32 defaultID) if (map.empty()) return defaultID; // no objects loaded, keep gap for H3M objects - if (map.rbegin()->first > defaultID) + if (map.rbegin()->first >= defaultID) return map.rbegin()->first + 1; // some modded objects loaded, return next available return defaultID; // some H3M objects loaded, first modded found @@ -172,9 +172,10 @@ void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContai } legacyTemplates.erase(range.first, range.second); } - - obj->objects[id] = handler; + logGlobal->debugStream() << "Loaded object " << obj->id << ":" << id; + assert(!obj->objects.count(id)); // DO NOT override + obj->objects[id] = handler; } CObjectClassesHandler::ObjectContainter * CObjectClassesHandler::loadFromJson(const JsonNode & json) From bda71bed833c83d1464ac7673ccbe6d41558daf7 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Tue, 1 Jul 2014 07:07:40 +0200 Subject: [PATCH 33/39] Uploading misc tweaks. --- ChangeLog | 2 +- config/rmg.json | 4 ++-- lib/NetPacksLib.cpp | 1 + lib/mapObjects/CGTownInstance.cpp | 8 +++++++- lib/mapObjects/CObjectHandler.cpp | 2 +- lib/rmg/CRmgTemplateZone.cpp | 9 ++++++--- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 963c4e4e4..64ba175f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,7 +15,7 @@ SPELLS: * New configuration format: http://wiki.vcmi.eu/index.php?title=Spell_Format RANDOM MAP GENERATOR -* Towns from mods can be used +* Towns form mods cna be used * Reading connections, terrains, towns and mines from template * Zone placement * Zone borders and connections, fractalized paths inside zones diff --git a/config/rmg.json b/config/rmg.json index 8ca2e8845..8ad5fd895 100644 --- a/config/rmg.json +++ b/config/rmg.json @@ -2,7 +2,7 @@ { "Analogy" : { - "minSize" : "s", "maxSize" : "m", + "minSize" : "m", "maxSize" : "m", "players" : "4", "zones" : { @@ -63,7 +63,7 @@ }, "Upgrade" : { - "minSize" : "m", "maxSize" : "m", + "minSize" : "s", "maxSize" : "m", "players" : "2", "zones" : { diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 2c700b101..c2f0ef924 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -163,6 +163,7 @@ DLL_LINKAGE void HeroVisitCastle::applyGs( CGameState *gs ) assert(h); assert(t); + if(start()) t->setVisitingHero(h); else diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 9cb8b05a5..b43e418ab 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -907,7 +907,13 @@ bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, void CGTownInstance::setVisitingHero(CGHeroInstance *h) { - assert(!!visitingHero == !h); + if (!(!!visitingHero == !h)) + { + logGlobal->warnStream() << boost::format("Hero visiting town %s is %s ") % name % (visitingHero.get() ? visitingHero->name : "NULL"); + logGlobal->warnStream() << boost::format("New hero will be %s ") % (h ? h->name : "NULL"); + assert(!!visitingHero == !h); + } + if(h) { PlayerState *p = cb->gameState()->getPlayer(h->tempOwner); diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 5aee86545..eea0b1b5a 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -246,7 +246,7 @@ int3 CGObjectInstance::getVisitableOffset() const if (appearance.isVisitableAt(x, y)) return int3(x,y,0); - logGlobal->warnStream() << "Warning: getVisitableOffset called on non-visitable obj!"; + //logGlobal->warnStream() << "Warning: getVisitableOffset called on non-visitable obj!"; return int3(0,0,0); } diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index 598231ee2..a0fc0dba4 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -761,7 +761,7 @@ void CRmgTemplateZone::initTownType (CMapGenerator* gen) playerInfo.allowedFactions.clear(); playerInfo.allowedFactions.insert (townType); playerInfo.hasMainTown = true; - playerInfo.posOfMainTown = town->pos - int3(2, 0, 0); + playerInfo.posOfMainTown = town->pos - town->getVisitableOffset(); playerInfo.generateHeroAtMainTown = true; //now create actual towns @@ -1264,8 +1264,11 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object, gen->setOccupied (guardTile, ETileType::USED); } - else - gen->setOccupied (guardTile, ETileType::FREE); + else //allow no guard or other object in front of this object + { + for (auto tile : tiles) + gen->setOccupied (tile, ETileType::FREE); + } return true; } From bf567c9e5022678192efe321892cda889ae4fceb Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Tue, 1 Jul 2014 09:13:19 +0200 Subject: [PATCH 34/39] Fixed crash caused by hiding tiles around AI heroes. --- server/CGameHandler.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 7684404e4..fdfb85d2c 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -6254,6 +6254,21 @@ void CGameHandler::changeFogOfWar(int3 center, ui32 radius, PlayerColor player, { std::unordered_set tiles; getTilesInRange(tiles, center, radius, player, hide? -1 : 1); + if (hide) + { + std::unordered_set observedTiles; //do not hide tiles observed by heroes. May lead to disastrous AI problems + auto p = gs->getPlayer(player); + for (auto h : p->heroes) + { + getTilesInRange(observedTiles, h->getSightCenter(), h->getSightRadious(), h->tempOwner, -1); + } + for (auto t : p->towns) + { + getTilesInRange(observedTiles, t->getSightCenter(), t->getSightRadious(), t->tempOwner, -1); + } + for (auto tile : observedTiles) + vstd::erase_if_present (tiles, tile); + } changeFogOfWar(tiles, player, hide); } From bae9f2083f55ec97684d7fe8b9bd0f082109d6bb Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Tue, 1 Jul 2014 12:07:53 +0200 Subject: [PATCH 35/39] Workaround for hero & town issue. Game still crashes elsewhere, though. --- lib/CGameState.cpp | 7 +++++++ lib/mapObjects/CGTownInstance.cpp | 9 ++++++++- lib/rmg/CMapGenerator.cpp | 14 ++++++++------ lib/rmg/CMapGenerator.h | 2 +- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 0a41eec3c..031082994 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -1899,6 +1899,13 @@ void CGameState::initVisitingAndGarrisonedHeroes() } } } + for (auto hero : map->heroesOnMap) + { + if (hero->visitedTown) + { + assert (hero->visitedTown->visitingHero == hero); + } + } } BFieldType CGameState::battleGetBattlefieldType(int3 tile) diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index b43e418ab..3bff6cefa 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -523,7 +523,14 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const { - cb->stopHeroVisitCastle(this, h); + //FIXME: find out why this issue appears on random maps + if (visitingHero == h) + { + cb->stopHeroVisitCastle(this, h); + logGlobal->warnStream() << h->name << " correctly left town " << name; + } + else + logGlobal->warnStream() << "Warning, " << h->name << " tries to leave the town " << name << " but hero is not inside."; } std::string CGTownInstance::getObjectName() const diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 725cea0ae..3ef5e15bf 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -23,8 +23,8 @@ void CMapGenerator::foreach_neighbour(const int3 &pos, std::function mapGenOptions, int randomSeed /*= std::time(nullptr)*/) : - mapGenOptions(mapGenOptions), randomSeed(randomSeed), monolithIndex(0) +CMapGenerator::CMapGenerator(shared_ptr mapGenOptions, int RandomSeed /*= std::time(nullptr)*/) : + mapGenOptions(mapGenOptions), randomSeed(RandomSeed), monolithIndex(0) { rand.setSeed(randomSeed); } @@ -50,12 +50,13 @@ void CMapGenerator::initTiles() CMapGenerator::~CMapGenerator() { - //FIXME: what if map is not present anymore? - if (tiles && map) + if (tiles) { - for (int i=0; i < map->width; i++) + int width = mapGenOptions->getWidth(); + int height = mapGenOptions->getHeight(); + for (int i=0; i < width; i++) { - for(int j=0; j < map->height; j++) + for(int j=0; j < height; j++) { delete [] tiles[i][j]; } @@ -80,6 +81,7 @@ std::unique_ptr CMapGenerator::generate() genZones(); map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded fillZones(); + //updated fuarded tiles will be calculated in CGameState::initMapObjects() } catch (rmgException &e) { diff --git a/lib/rmg/CMapGenerator.h b/lib/rmg/CMapGenerator.h index 9b56c11d2..81586eb78 100644 --- a/lib/rmg/CMapGenerator.h +++ b/lib/rmg/CMapGenerator.h @@ -51,7 +51,7 @@ public: class DLL_LINKAGE CMapGenerator { public: - explicit CMapGenerator(shared_ptr mapGenOptions, int randomSeed = std::time(nullptr)); + explicit CMapGenerator(shared_ptr mapGenOptions, int RandomSeed = std::time(nullptr)); ~CMapGenerator(); // required due to unique_ptr std::unique_ptr generate(); From c956b3f02a3754a2e45fc0558d6e81c95270a404 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 1 Jul 2014 17:19:08 +0300 Subject: [PATCH 36/39] Fixed #1820, better detection of object below cursor that uses same logic as renderer --- client/CAdvmapInterface.cpp | 12 +++++++----- client/CAdvmapInterface.h | 4 ++-- client/GUIClasses.cpp | 7 ++++++- lib/mapObjects/CRewardableObject.cpp | 7 +++++-- lib/mapObjects/CRewardableObject.h | 1 + 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/client/CAdvmapInterface.cpp b/client/CAdvmapInterface.cpp index ea075bcf7..d98364a3d 100644 --- a/client/CAdvmapInterface.cpp +++ b/client/CAdvmapInterface.cpp @@ -1127,17 +1127,19 @@ void CAdvMapInt::endingTurn() LOCPLINT->cb->endTurn(); } -const CGObjectInstance* CAdvMapInt::getBlockingObject(const int3 &mapPos) +const CGObjectInstance* CAdvMapInt::getActiveObject(const int3 &mapPos) { std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mapPos); //blocking objects at tile if (bobjs.empty()) return nullptr; + return *boost::range::max_element(bobjs, &CMapHandler::compareObjectBlitOrder); +/* if (bobjs.back()->ID == Obj::HERO) return bobjs.back(); else - return bobjs.front(); + return bobjs.front();*/ } void CAdvMapInt::tileLClicked(const int3 &mapPos) @@ -1147,7 +1149,7 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos) const TerrainTile *tile = LOCPLINT->cb->getTile(mapPos); - const CGObjectInstance *topBlocking = getBlockingObject(mapPos); + const CGObjectInstance *topBlocking = getActiveObject(mapPos); int3 selPos = selection->getSightCenter(); if(spellBeingCasted && isInScreenRange(selPos, mapPos)) @@ -1232,7 +1234,7 @@ void CAdvMapInt::tileHovered(const int3 &mapPos) statusbar.clear(); return; } - const CGObjectInstance *objAtTile = getBlockingObject(mapPos); + const CGObjectInstance *objAtTile = getActiveObject(mapPos); if (objAtTile) { @@ -1432,7 +1434,7 @@ void CAdvMapInt::tileRClicked(const int3 &mapPos) return; } - const CGObjectInstance * obj = getBlockingObject(mapPos); + const CGObjectInstance * obj = getActiveObject(mapPos); if(!obj) { // Bare or undiscovered terrain diff --git a/client/CAdvmapInterface.h b/client/CAdvmapInterface.h index 793c393ff..cf7f785a9 100644 --- a/client/CAdvmapInterface.h +++ b/client/CAdvmapInterface.h @@ -85,8 +85,8 @@ public: /// can get to the towns and heroes. class CAdvMapInt : public CIntObject { - //get top selectable object at tile - const CGObjectInstance *getBlockingObject(const int3 &tile); + //Return object that must be active at this tile (=clickable) + const CGObjectInstance *getActiveObject(const int3 &tile); public: CAdvMapInt(); diff --git a/client/GUIClasses.cpp b/client/GUIClasses.cpp index b2d824fb6..c17ff1466 100644 --- a/client/GUIClasses.cpp +++ b/client/GUIClasses.cpp @@ -6181,7 +6181,12 @@ void CRClickPopup::createAndPush(const CGObjectInstance *obj, const Point &p, EA if(iWin) GH.pushInt(iWin); else - CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID)); + { + if (adventureInt->curHero()) + CRClickPopup::createAndPush(obj->getHoverText(adventureInt->curHero())); + else + CRClickPopup::createAndPush(obj->getHoverText(LOCPLINT->playerID)); + } } CRClickPopup::CRClickPopup() diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 6a4786ced..55a8d6fcb 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -308,6 +308,7 @@ bool CRewardableObject::wasVisited (PlayerColor player) const switch (visitMode) { case VISIT_UNLIMITED: + case VISIT_BONUS: return false; case VISIT_ONCE: // FIXME: hide this info deeper and return same as player? for (auto & visit : info) @@ -329,6 +330,8 @@ bool CRewardableObject::wasVisited (const CGHeroInstance * h) const switch (visitMode) { case VISIT_UNLIMITED: + return false; + case VISIT_BONUS: return h->hasBonusFrom(Bonus::OBJECT, ID); case VISIT_HERO: return h->visitedObjects.count(ObjectInstanceID(id)); @@ -389,7 +392,7 @@ static std::string & visitedTxt(const bool visited) std::string CRewardableObject::getHoverText(PlayerColor player) const { - if(visitMode != VISIT_UNLIMITED) + if(visitMode == VISIT_PLAYER || visitMode == VISIT_ONCE) return getObjectName() + " " + visitedTxt(wasVisited(player)); return getObjectName(); } @@ -611,7 +614,7 @@ void CGPickable::initObj() CGBonusingObject::CGBonusingObject() { - visitMode = VISIT_UNLIMITED; + visitMode = VISIT_BONUS; selectMode = SELECT_FIRST; } diff --git a/lib/mapObjects/CRewardableObject.h b/lib/mapObjects/CRewardableObject.h index b6924d470..163890e6a 100644 --- a/lib/mapObjects/CRewardableObject.h +++ b/lib/mapObjects/CRewardableObject.h @@ -177,6 +177,7 @@ protected: VISIT_UNLIMITED, // any number of times. Side effect - object hover text won't contain visited/not visited text VISIT_ONCE, // only once, first to visit get all the rewards VISIT_HERO, // every hero can visit object once + VISIT_BONUS, // can be visited by any hero that don't have bonus from this object VISIT_PLAYER // every player can visit object once }; From cc349fa64f14e3a376a1393aa254789fb86578e6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 1 Jul 2014 18:19:51 +0300 Subject: [PATCH 37/39] Fixed Faerie Ring bonus, removed unused code --- lib/mapObjects/CRewardableObject.cpp | 55 +--------------------------- 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 55a8d6fcb..33516a0d9 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -658,7 +658,7 @@ void CGBonusingObject::initObj() break; case Obj::FAERIE_RING: configureMessage(info[0], 49, 50, soundBase::LUCK); - configureBonus(info[0], Bonus::LUCK, 2, 71); + configureBonus(info[0], Bonus::LUCK, 1, 71); break; case Obj::FOUNTAIN_OF_FORTUNE: selectMode = SELECT_RANDOM; @@ -961,59 +961,6 @@ void CGVisitableOPH::initObj() } } -//TODO: re-enable. Probably in some different form but still necessary -/* -const std::string & CGVisitableOPH::getHoverText() const -{ - int pom = -1; - switch(ID) - { - case Obj::ARENA: - pom = -1; - break; - case Obj::MERCENARY_CAMP: - pom = 8; - break; - case Obj::MARLETTO_TOWER: - pom = 7; - break; - case Obj::STAR_AXIS: - pom = 11; - break; - case Obj::GARDEN_OF_REVELATION: - pom = 4; - break; - case Obj::LEARNING_STONE: - pom = 5; - break; - case Obj::TREE_OF_KNOWLEDGE: - pom = 18; - break; - case Obj::LIBRARY_OF_ENLIGHTENMENT: - break; - case Obj::SCHOOL_OF_MAGIC: - pom = 9; - break; - case Obj::SCHOOL_OF_WAR: - pom = 10; - break; - default: - throw std::runtime_error("Wrong CGVisitableOPH object ID!\n"); - } - hoverName = VLC->objtypeh->getObjectName(ID); - if(pom >= 0) - hoverName += ("\n" + VLC->generaltexth->xtrainfo[pom]); - const CGHeroInstance *h = cb->getSelectedHero (cb->getCurrentPlayer()); - if(h) - { - hoverName += "\n\n"; - bool visited = vstd::contains (visitors, h->id); - hoverName += visitedTxt (visited); - } - return hoverName; -} -*/ - /////////////////////////////////////////////////////////////////////////////////////////////////// CGVisitableOPW::CGVisitableOPW() From cc294b3ae74552d33c53a3116038a1aa2c7ceb00 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Tue, 1 Jul 2014 19:30:31 +0200 Subject: [PATCH 38/39] Version 0.96 release. --- lib/Connection.h | 2 +- lib/GameConstants.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Connection.h b/lib/Connection.h index cfb51deb8..2b976d26b 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -27,7 +27,7 @@ #include "mapping/CCampaignHandler.h" //for CCampaignState #include "rmg/CMapGenerator.h" // for CMapGenOptions -const ui32 version = 749; +const ui32 version = 750; const ui32 minSupportedVersion = version; class CConnection; diff --git a/lib/GameConstants.h b/lib/GameConstants.h index e0229431d..386600c89 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -14,7 +14,7 @@ namespace GameConstants { - const std::string VCMI_VERSION = "VCMI 0.95c"; + const std::string VCMI_VERSION = "VCMI 0.96"; const int BFIELD_WIDTH = 17; const int BFIELD_HEIGHT = 11; From 4441bd12db313e35e60cc95876291a00773b5e01 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 1 Jul 2014 21:02:03 +0300 Subject: [PATCH 39/39] (linux) version set to 0.96 --- CMakeLists.txt | 2 +- debian/changelog | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a06161a9..0db0737dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ endif() # VCMI version set(VCMI_VERSION_MAJOR 0) -set(VCMI_VERSION_MINOR 95) +set(VCMI_VERSION_MINOR 96) set(VCMI_VERSION_PATCH 0) option(ENABLE_ERM "Enable compilation of ERM scripting module" OFF) diff --git a/debian/changelog b/debian/changelog index 3dde14aad..0405893dd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +vcmi (0.96) trusty; urgency=low + + * New upstream release + + -- Ivan Savenko Tue, 01 Jul 2014 20:57:29 +0300 + vcmi (0.95) precise; urgency=low * New upstream release