mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
parent
205bb09880
commit
aaa07e4d2e
@ -88,24 +88,22 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
|||||||
for(pos.z = 0; pos.z < sizes.z; ++pos.z)
|
for(pos.z = 0; pos.z < sizes.z; ++pos.z)
|
||||||
{
|
{
|
||||||
const TerrainTile * tile = &gs->map->getTile(pos);
|
const TerrainTile * tile = &gs->map->getTile(pos);
|
||||||
switch(tile->terType)
|
if(!tile->terType.isPassable())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(tile->terType.isWater())
|
||||||
{
|
{
|
||||||
case ETerrainType::ROCK:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETerrainType::WATER:
|
|
||||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||||
if(useFlying)
|
if(useFlying)
|
||||||
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
||||||
if(useWaterWalking)
|
if(useWaterWalking)
|
||||||
resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs));
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
default:
|
{
|
||||||
resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs));
|
||||||
if(useFlying)
|
if(useFlying)
|
||||||
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1428,4 +1426,4 @@ std::string AIPath::toString() const
|
|||||||
str << node.targetHero->name << "[" << std::hex << node.chainMask << std::dec << "]" << "->" << node.coord.toString() << "; ";
|
str << node.targetHero->name << "[" << std::hex << node.chainMask << std::dec << "]" << "->" << node.coord.toString() << "; ";
|
||||||
|
|
||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ int ChainActor::maxMovePoints(CGPathNode::ELayer layer)
|
|||||||
{
|
{
|
||||||
#if AI_TRACE_LEVEL > 0
|
#if AI_TRACE_LEVEL > 0
|
||||||
if(!hero)
|
if(!hero)
|
||||||
throw std::exception("Asking movement points for static actor");
|
throw std::logic_error("Asking movement points for static actor");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return hero->maxMovePointsCached(layer, tiCache.get());
|
return hero->maxMovePointsCached(layer, tiCache.get());
|
||||||
|
@ -46,24 +46,22 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
|||||||
for(pos.z=0; pos.z < sizes.z; ++pos.z)
|
for(pos.z=0; pos.z < sizes.z; ++pos.z)
|
||||||
{
|
{
|
||||||
const TerrainTile * tile = &gs->map->getTile(pos);
|
const TerrainTile * tile = &gs->map->getTile(pos);
|
||||||
switch(tile->terType)
|
if(!tile->terType.isPassable())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(tile->terType.isWater())
|
||||||
{
|
{
|
||||||
case ETerrainType::ROCK:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETerrainType::WATER:
|
|
||||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||||
if(useFlying)
|
if(useFlying)
|
||||||
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
||||||
if(useWaterWalking)
|
if(useWaterWalking)
|
||||||
resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs));
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
default:
|
{
|
||||||
resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs));
|
||||||
if(useFlying)
|
if(useFlying)
|
||||||
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,11 +347,6 @@ public:
|
|||||||
h & visitableObjs;
|
h & visitableObjs;
|
||||||
h & alreadyVisited;
|
h & alreadyVisited;
|
||||||
h & reservedObjs;
|
h & reservedObjs;
|
||||||
if (version < 788 && !h.saving)
|
|
||||||
{
|
|
||||||
TResources saving;
|
|
||||||
h & saving; //mind the ambiguity
|
|
||||||
}
|
|
||||||
h & status;
|
h & status;
|
||||||
h & battlename;
|
h & battlename;
|
||||||
h & heroesUnableToExplore;
|
h & heroesUnableToExplore;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "../lib/StringConstants.h"
|
#include "../lib/StringConstants.h"
|
||||||
#include "../lib/CRandomGenerator.h"
|
#include "../lib/CRandomGenerator.h"
|
||||||
#include "../lib/VCMIDirs.h"
|
#include "../lib/VCMIDirs.h"
|
||||||
|
#include "../lib/Terrain.h"
|
||||||
|
|
||||||
#define VCMI_SOUND_NAME(x)
|
#define VCMI_SOUND_NAME(x)
|
||||||
#define VCMI_SOUND_FILE(y) #y,
|
#define VCMI_SOUND_FILE(y) #y,
|
||||||
@ -92,20 +93,34 @@ CSoundHandler::CSoundHandler():
|
|||||||
soundBase::pickup04, soundBase::pickup05, soundBase::pickup06, soundBase::pickup07
|
soundBase::pickup04, soundBase::pickup05, soundBase::pickup06, soundBase::pickup07
|
||||||
};
|
};
|
||||||
|
|
||||||
horseSounds = // must be the same order as terrains (see ETerrainType);
|
|
||||||
{
|
|
||||||
soundBase::horseDirt, soundBase::horseSand, soundBase::horseGrass,
|
|
||||||
soundBase::horseSnow, soundBase::horseSwamp, soundBase::horseRough,
|
|
||||||
soundBase::horseSubterranean, soundBase::horseLava,
|
|
||||||
soundBase::horseWater, soundBase::horseRock
|
|
||||||
};
|
|
||||||
|
|
||||||
battleIntroSounds =
|
battleIntroSounds =
|
||||||
{
|
{
|
||||||
soundBase::battle00, soundBase::battle01,
|
soundBase::battle00, soundBase::battle01,
|
||||||
soundBase::battle02, soundBase::battle03, soundBase::battle04,
|
soundBase::battle02, soundBase::battle03, soundBase::battle04,
|
||||||
soundBase::battle05, soundBase::battle06, soundBase::battle07
|
soundBase::battle05, soundBase::battle06, soundBase::battle07
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//predefine terrain set
|
||||||
|
//TODO: need refactoring - support custom sounds for new terrains and load from json
|
||||||
|
int h3mTerrId = 0;
|
||||||
|
for(auto snd :
|
||||||
|
{
|
||||||
|
soundBase::horseDirt, soundBase::horseSand, soundBase::horseGrass,
|
||||||
|
soundBase::horseSnow, soundBase::horseSwamp, soundBase::horseRough,
|
||||||
|
soundBase::horseSubterranean, soundBase::horseLava,
|
||||||
|
soundBase::horseWater, soundBase::horseRock
|
||||||
|
})
|
||||||
|
{
|
||||||
|
horseSounds[Terrain::createTerrainTypeH3M(h3mTerrId++)] = snd;
|
||||||
|
}
|
||||||
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
{
|
||||||
|
//since all sounds are hardcoded, let's keep it
|
||||||
|
if(vstd::contains(horseSounds, terrain))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
horseSounds[terrain] = horseSounds.at(Terrain::createTerrainTypeH3M(Terrain::Manager::getInfo(terrain).horseSoundId));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void CSoundHandler::init()
|
void CSoundHandler::init()
|
||||||
@ -341,26 +356,22 @@ CMusicHandler::CMusicHandler():
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
int battleMusicID = 0;
|
|
||||||
int AIThemeID = 0;
|
|
||||||
|
|
||||||
for(const ResourceID & file : mp3files)
|
for(const ResourceID & file : mp3files)
|
||||||
{
|
{
|
||||||
if(boost::algorithm::istarts_with(file.getName(), "MUSIC/Combat"))
|
if(boost::algorithm::istarts_with(file.getName(), "MUSIC/Combat"))
|
||||||
addEntryToSet("battle", battleMusicID++, file.getName());
|
addEntryToSet("battle", file.getName(), file.getName());
|
||||||
else if(boost::algorithm::istarts_with(file.getName(), "MUSIC/AITheme"))
|
else if(boost::algorithm::istarts_with(file.getName(), "MUSIC/AITheme"))
|
||||||
addEntryToSet("enemy-turn", AIThemeID++, file.getName());
|
addEntryToSet("enemy-turn", file.getName(), file.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonNode terrains(ResourceID("config/terrains.json"));
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
for (auto entry : terrains.Struct())
|
|
||||||
{
|
{
|
||||||
int terrIndex = vstd::find_pos(GameConstants::TERRAIN_NAMES, entry.first);
|
auto & entry = Terrain::Manager::getInfo(terrain);
|
||||||
addEntryToSet("terrain", terrIndex, "Music/" + entry.second["music"].String());
|
addEntryToSet("terrain", terrain, "Music/" + entry.musicFilename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMusicHandler::addEntryToSet(std::string set, int musicID, std::string musicURI)
|
void CMusicHandler::addEntryToSet(const std::string & set, const std::string & musicID, const std::string & musicURI)
|
||||||
{
|
{
|
||||||
musicsSet[set][musicID] = musicURI;
|
musicsSet[set][musicID] = musicURI;
|
||||||
}
|
}
|
||||||
@ -388,7 +399,7 @@ void CMusicHandler::release()
|
|||||||
CAudioBase::release();
|
CAudioBase::release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMusicHandler::playMusic(std::string musicURI, bool loop)
|
void CMusicHandler::playMusic(const std::string & musicURI, bool loop)
|
||||||
{
|
{
|
||||||
if (current && current->isTrack(musicURI))
|
if (current && current->isTrack(musicURI))
|
||||||
return;
|
return;
|
||||||
@ -396,7 +407,7 @@ void CMusicHandler::playMusic(std::string musicURI, bool loop)
|
|||||||
queueNext(this, "", musicURI, loop);
|
queueNext(this, "", musicURI, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMusicHandler::playMusicFromSet(std::string whichSet, bool loop)
|
void CMusicHandler::playMusicFromSet(const std::string & whichSet, bool loop)
|
||||||
{
|
{
|
||||||
auto selectedSet = musicsSet.find(whichSet);
|
auto selectedSet = musicsSet.find(whichSet);
|
||||||
if (selectedSet == musicsSet.end())
|
if (selectedSet == musicsSet.end())
|
||||||
@ -412,8 +423,7 @@ void CMusicHandler::playMusicFromSet(std::string whichSet, bool loop)
|
|||||||
queueNext(this, whichSet, "", loop);
|
queueNext(this, whichSet, "", loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMusicHandler::playMusicFromSet(const std::string & whichSet, const std::string & entryID, bool loop)
|
||||||
void CMusicHandler::playMusicFromSet(std::string whichSet, int entryID, bool loop)
|
|
||||||
{
|
{
|
||||||
auto selectedSet = musicsSet.find(whichSet);
|
auto selectedSet = musicsSet.find(whichSet);
|
||||||
if (selectedSet == musicsSet.end())
|
if (selectedSet == musicsSet.end())
|
||||||
@ -425,7 +435,7 @@ void CMusicHandler::playMusicFromSet(std::string whichSet, int entryID, bool loo
|
|||||||
auto selectedEntry = selectedSet->second.find(entryID);
|
auto selectedEntry = selectedSet->second.find(entryID);
|
||||||
if (selectedEntry == selectedSet->second.end())
|
if (selectedEntry == selectedSet->second.end())
|
||||||
{
|
{
|
||||||
logGlobal->error("Error: playing non-existing entry %d from set: %s", entryID, whichSet);
|
logGlobal->error("Error: playing non-existing entry %s from set: %s", entryID, whichSet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +462,7 @@ void CMusicHandler::queueNext(std::unique_ptr<MusicEntry> queued)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMusicHandler::queueNext(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped)
|
void CMusicHandler::queueNext(CMusicHandler *owner, const std::string & setName, const std::string & musicURI, bool looped)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -552,7 +562,7 @@ bool MusicEntry::play()
|
|||||||
|
|
||||||
if (!setName.empty())
|
if (!setName.empty())
|
||||||
{
|
{
|
||||||
auto set = owner->musicsSet[setName];
|
const auto & set = owner->musicsSet[setName];
|
||||||
load(RandomGeneratorUtil::nextItem(set, CRandomGenerator::getDefault())->second);
|
load(RandomGeneratorUtil::nextItem(set, CRandomGenerator::getDefault())->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ struct _Mix_Music;
|
|||||||
struct SDL_RWops;
|
struct SDL_RWops;
|
||||||
typedef struct _Mix_Music Mix_Music;
|
typedef struct _Mix_Music Mix_Music;
|
||||||
struct Mix_Chunk;
|
struct Mix_Chunk;
|
||||||
|
class Terrain;
|
||||||
|
|
||||||
class CAudioBase {
|
class CAudioBase {
|
||||||
protected:
|
protected:
|
||||||
@ -81,8 +82,8 @@ public:
|
|||||||
|
|
||||||
// Sets
|
// Sets
|
||||||
std::vector<soundBase::soundID> pickupSounds;
|
std::vector<soundBase::soundID> pickupSounds;
|
||||||
std::vector<soundBase::soundID> horseSounds;
|
|
||||||
std::vector<soundBase::soundID> battleIntroSounds;
|
std::vector<soundBase::soundID> battleIntroSounds;
|
||||||
|
std::map<Terrain, soundBase::soundID> horseSounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper //now it looks somewhat useless
|
// Helper //now it looks somewhat useless
|
||||||
@ -118,6 +119,7 @@ public:
|
|||||||
class CMusicHandler: public CAudioBase
|
class CMusicHandler: public CAudioBase
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//update volume on configuration change
|
//update volume on configuration change
|
||||||
SettingsListener listener;
|
SettingsListener listener;
|
||||||
void onVolumeChange(const JsonNode &volumeNode);
|
void onVolumeChange(const JsonNode &volumeNode);
|
||||||
@ -125,26 +127,27 @@ private:
|
|||||||
std::unique_ptr<MusicEntry> current;
|
std::unique_ptr<MusicEntry> current;
|
||||||
std::unique_ptr<MusicEntry> next;
|
std::unique_ptr<MusicEntry> next;
|
||||||
|
|
||||||
void queueNext(CMusicHandler *owner, std::string setName, std::string musicURI, bool looped);
|
void queueNext(CMusicHandler *owner, const std::string & setName, const std::string & musicURI, bool looped);
|
||||||
void queueNext(std::unique_ptr<MusicEntry> queued);
|
void queueNext(std::unique_ptr<MusicEntry> queued);
|
||||||
|
|
||||||
std::map<std::string, std::map<int, std::string> > musicsSet;
|
std::map<std::string, std::map<std::string, std::string>> musicsSet;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CMusicHandler();
|
CMusicHandler();
|
||||||
|
|
||||||
/// add entry with URI musicURI in set. Track will have ID musicID
|
/// add entry with URI musicURI in set. Track will have ID musicID
|
||||||
void addEntryToSet(std::string set, int musicID, std::string musicURI);
|
void addEntryToSet(const std::string & set, const std::string & entryID, const std::string & musicURI);
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
void release() override;
|
void release() override;
|
||||||
void setVolume(ui32 percent) override;
|
void setVolume(ui32 percent) override;
|
||||||
|
|
||||||
/// play track by URI, if loop = true music will be looped
|
/// play track by URI, if loop = true music will be looped
|
||||||
void playMusic(std::string musicURI, bool loop);
|
void playMusic(const std::string & musicURI, bool loop);
|
||||||
/// play random track from this set
|
/// play random track from this set
|
||||||
void playMusicFromSet(std::string musicSet, bool loop);
|
void playMusicFromSet(const std::string & musicSet, bool loop);
|
||||||
/// play specific track from set
|
/// play specific track from set
|
||||||
void playMusicFromSet(std::string musicSet, int entryID, bool loop);
|
void playMusicFromSet(const std::string & musicSet, const std::string & entryID, bool loop);
|
||||||
void stopMusic(int fade_ms=1000);
|
void stopMusic(int fade_ms=1000);
|
||||||
void musicFinishedCallback();
|
void musicFinishedCallback();
|
||||||
|
|
||||||
|
@ -1351,12 +1351,6 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
|
|||||||
|
|
||||||
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
||||||
{
|
{
|
||||||
if(version < 774 && !h.saving)
|
|
||||||
{
|
|
||||||
bool observerInDuelMode = false;
|
|
||||||
h & observerInDuelMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
h & wanderingHeroes;
|
h & wanderingHeroes;
|
||||||
h & towns;
|
h & towns;
|
||||||
h & sleepingHeroes;
|
h & sleepingHeroes;
|
||||||
@ -2742,8 +2736,8 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
|
|
||||||
{
|
{
|
||||||
path.convert(0);
|
path.convert(0);
|
||||||
ETerrainType currentTerrain = ETerrainType::BORDER; // not init yet
|
Terrain currentTerrain = Terrain("BORDER"); // not init yet
|
||||||
ETerrainType newTerrain;
|
Terrain newTerrain;
|
||||||
int sh = -1;
|
int sh = -1;
|
||||||
|
|
||||||
auto canStop = [&](CGPathNode * node) -> bool
|
auto canStop = [&](CGPathNode * node) -> bool
|
||||||
@ -2779,7 +2773,9 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
destinationTeleportPos = int3(-1);
|
destinationTeleportPos = int3(-1);
|
||||||
}
|
}
|
||||||
if(i != path.nodes.size() - 1)
|
if(i != path.nodes.size() - 1)
|
||||||
|
{
|
||||||
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[currentTerrain], -1);
|
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[currentTerrain], -1);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2797,7 +2793,7 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
newTerrain = cb->getTile(CGHeroInstance::convertPosition(currentCoord, false))->terType;
|
newTerrain = cb->getTile(CGHeroInstance::convertPosition(currentCoord, false))->terType;
|
||||||
if (newTerrain != currentTerrain)
|
if(newTerrain != currentTerrain)
|
||||||
{
|
{
|
||||||
CCS->soundh->stopSound(sh);
|
CCS->soundh->stopSound(sh);
|
||||||
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[newTerrain], -1);
|
sh = CCS->soundh->playSound(CCS->soundh->horseSounds[newTerrain], -1);
|
||||||
|
@ -274,12 +274,6 @@ void CClient::serialize(BinarySerializer & h, const int version)
|
|||||||
void CClient::serialize(BinaryDeserializer & h, const int version)
|
void CClient::serialize(BinaryDeserializer & h, const int version)
|
||||||
{
|
{
|
||||||
assert(!h.saving);
|
assert(!h.saving);
|
||||||
if(version < 787)
|
|
||||||
{
|
|
||||||
bool hotSeat = false;
|
|
||||||
h & hotSeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui8 players = 0;
|
ui8 players = 0;
|
||||||
h & players;
|
h & players;
|
||||||
|
|
||||||
@ -337,11 +331,7 @@ void CClient::serialize(BinaryDeserializer & h, const int version)
|
|||||||
|
|
||||||
{
|
{
|
||||||
JsonNode scriptsState;
|
JsonNode scriptsState;
|
||||||
if(version >= 800)
|
h & scriptsState;
|
||||||
{
|
|
||||||
h & scriptsState;
|
|
||||||
}
|
|
||||||
|
|
||||||
clientScripts->serializeState(h.saving, scriptsState);
|
clientScripts->serializeState(h.saving, scriptsState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,7 +454,7 @@ CBattleInterface::~CBattleInterface()
|
|||||||
|
|
||||||
if (adventureInt && adventureInt->selection)
|
if (adventureInt && adventureInt->selection)
|
||||||
{
|
{
|
||||||
int terrain = LOCPLINT->cb->getTile(adventureInt->selection->visitablePos())->terType;
|
auto & terrain = LOCPLINT->cb->getTile(adventureInt->selection->visitablePos())->terType;
|
||||||
CCS->musich->playMusicFromSet("terrain", terrain, true);
|
CCS->musich->playMusicFromSet("terrain", terrain, true);
|
||||||
}
|
}
|
||||||
animsAreDisplayed.setn(false);
|
animsAreDisplayed.setn(false);
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "../lib/CGameState.h"
|
#include "../lib/CGameState.h"
|
||||||
#include "../lib/CHeroHandler.h"
|
#include "../lib/CHeroHandler.h"
|
||||||
#include "../lib/CTownHandler.h"
|
#include "../lib/CTownHandler.h"
|
||||||
|
#include "../lib/CModHandler.h"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "../lib/mapping/CMap.h"
|
#include "../lib/mapping/CMap.h"
|
||||||
#include "../lib/CConfigHandler.h"
|
#include "../lib/CConfigHandler.h"
|
||||||
@ -29,6 +30,9 @@
|
|||||||
#include "CMT.h"
|
#include "CMT.h"
|
||||||
#include "CMusicHandler.h"
|
#include "CMusicHandler.h"
|
||||||
#include "../lib/CRandomGenerator.h"
|
#include "../lib/CRandomGenerator.h"
|
||||||
|
#include "../lib/Terrain.h"
|
||||||
|
#include "../lib/filesystem/ResourceID.h"
|
||||||
|
#include "../lib/JsonDetail.h"
|
||||||
|
|
||||||
#define ADVOPT (conf.go()->ac)
|
#define ADVOPT (conf.go()->ac)
|
||||||
|
|
||||||
@ -142,79 +146,68 @@ EMapAnimRedrawStatus CMapHandler::drawTerrainRectNew(SDL_Surface * targetSurface
|
|||||||
|
|
||||||
void CMapHandler::initTerrainGraphics()
|
void CMapHandler::initTerrainGraphics()
|
||||||
{
|
{
|
||||||
static const std::vector<std::string> TERRAIN_FILES =
|
static const std::map<std::string, std::string> ROAD_FILES =
|
||||||
{
|
{
|
||||||
"DIRTTL",
|
{ROAD_NAMES[1], "dirtrd"},
|
||||||
"SANDTL",
|
{ROAD_NAMES[2], "gravrd"},
|
||||||
"GRASTL",
|
{ROAD_NAMES[3], "cobbrd"}
|
||||||
"SNOWTL",
|
|
||||||
"SWMPTL",
|
|
||||||
|
|
||||||
"ROUGTL",
|
|
||||||
"SUBBTL",
|
|
||||||
"LAVATL",
|
|
||||||
"WATRTL",
|
|
||||||
"ROCKTL"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::vector<std::string> ROAD_FILES =
|
static const std::map<std::string, std::string> RIVER_FILES =
|
||||||
{
|
{
|
||||||
"dirtrd",
|
{RIVER_NAMES[1], "clrrvr"},
|
||||||
"gravrd",
|
{RIVER_NAMES[2], "icyrvr"},
|
||||||
"cobbrd"
|
{RIVER_NAMES[3], "mudrvr"},
|
||||||
|
{RIVER_NAMES[4], "lavrvr"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const std::vector<std::string> RIVER_FILES =
|
auto loadFlipped = [](TFlippedAnimations & animation, TFlippedCache & cache, const std::map<std::string, std::string> & files)
|
||||||
{
|
{
|
||||||
"clrrvr",
|
|
||||||
"icyrvr",
|
|
||||||
"mudrvr",
|
|
||||||
"lavrvr"
|
|
||||||
};
|
|
||||||
|
|
||||||
auto loadFlipped = [](int types, TFlippedAnimations & animation, TFlippedCache & cache, const std::vector<std::string> & files)
|
|
||||||
{
|
|
||||||
animation.resize(types);
|
|
||||||
cache.resize(types);
|
|
||||||
|
|
||||||
//no rotation and basic setup
|
//no rotation and basic setup
|
||||||
for(int i = 0; i < types; i++)
|
for(auto & type : files)
|
||||||
{
|
{
|
||||||
animation[i][0] = make_unique<CAnimation>(files[i]);
|
animation[type.first][0] = make_unique<CAnimation>(type.second);
|
||||||
animation[i][0]->preload();
|
animation[type.first][0]->preload();
|
||||||
const size_t views = animation[i][0]->size(0);
|
const size_t views = animation[type.first][0]->size(0);
|
||||||
cache[i].resize(views);
|
cache[type.first].resize(views);
|
||||||
|
|
||||||
for(int j = 0; j < views; j++)
|
for(int j = 0; j < views; j++)
|
||||||
cache[i][j][0] = animation[i][0]->getImage(j);
|
cache[type.first][j][0] = animation[type.first][0]->getImage(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int rotation = 1; rotation < 4; rotation++)
|
for(int rotation = 1; rotation < 4; rotation++)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < types; i++)
|
for(auto & type : files)
|
||||||
{
|
{
|
||||||
animation[i][rotation] = make_unique<CAnimation>(files[i]);
|
animation[type.first][rotation] = make_unique<CAnimation>(type.second);
|
||||||
animation[i][rotation]->preload();
|
animation[type.first][rotation]->preload();
|
||||||
const size_t views = animation[i][rotation]->size(0);
|
const size_t views = animation[type.first][rotation]->size(0);
|
||||||
|
|
||||||
for(int j = 0; j < views; j++)
|
for(int j = 0; j < views; j++)
|
||||||
{
|
{
|
||||||
auto image = animation[i][rotation]->getImage(j);
|
auto image = animation[type.first][rotation]->getImage(j);
|
||||||
|
|
||||||
if(rotation == 2 || rotation == 3)
|
if(rotation == 2 || rotation == 3)
|
||||||
image->horizontalFlip();
|
image->horizontalFlip();
|
||||||
if(rotation == 1 || rotation == 3)
|
if(rotation == 1 || rotation == 3)
|
||||||
image->verticalFlip();
|
image->verticalFlip();
|
||||||
|
|
||||||
cache[i][j][rotation] = image;
|
cache[type.first][j][rotation] = image;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadFlipped(GameConstants::TERRAIN_TYPES, terrainAnimations, terrainImages, TERRAIN_FILES);
|
std::map<std::string, std::string> terrainFiles;
|
||||||
loadFlipped(3, roadAnimations, roadImages, ROAD_FILES);
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
loadFlipped(4, riverAnimations, riverImages, RIVER_FILES);
|
{
|
||||||
|
terrainFiles[terrain] = Terrain::Manager::getInfo(terrain).tilesFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadFlipped(terrainAnimations, terrainImages, terrainFiles);
|
||||||
|
loadFlipped(roadAnimations, roadImages, ROAD_FILES);
|
||||||
|
loadFlipped(riverAnimations, riverImages, RIVER_FILES);
|
||||||
|
|
||||||
// Create enough room for the whole map and its frame
|
// Create enough room for the whole map and its frame
|
||||||
|
|
||||||
@ -626,6 +619,9 @@ void CMapHandler::CMapBlitter::drawTileTerrain(SDL_Surface * targetSurf, const T
|
|||||||
Rect destRect(realTileRect);
|
Rect destRect(realTileRect);
|
||||||
|
|
||||||
ui8 rotation = tinfo.extTileFlags % 4;
|
ui8 rotation = tinfo.extTileFlags % 4;
|
||||||
|
|
||||||
|
if(parent->terrainImages[tinfo.terType].size()<=tinfo.terView)
|
||||||
|
return;
|
||||||
|
|
||||||
drawElement(EMapCacheType::TERRAIN, parent->terrainImages[tinfo.terType][tinfo.terView][rotation], nullptr, targetSurf, &destRect);
|
drawElement(EMapCacheType::TERRAIN, parent->terrainImages[tinfo.terType][tinfo.terView][rotation], nullptr, targetSurf, &destRect);
|
||||||
}
|
}
|
||||||
@ -802,21 +798,21 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra
|
|||||||
|
|
||||||
void CMapHandler::CMapBlitter::drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const
|
void CMapHandler::CMapBlitter::drawRoad(SDL_Surface * targetSurf, const TerrainTile & tinfo, const TerrainTile * tinfoUpper) const
|
||||||
{
|
{
|
||||||
if (tinfoUpper && tinfoUpper->roadType != ERoadType::NO_ROAD)
|
if (tinfoUpper && tinfoUpper->roadType != ROAD_NAMES[0])
|
||||||
{
|
{
|
||||||
ui8 rotation = (tinfoUpper->extTileFlags >> 4) % 4;
|
ui8 rotation = (tinfoUpper->extTileFlags >> 4) % 4;
|
||||||
Rect source(0, tileSize / 2, tileSize, tileSize / 2);
|
Rect source(0, tileSize / 2, tileSize, tileSize / 2);
|
||||||
Rect dest(realPos.x, realPos.y, tileSize, tileSize / 2);
|
Rect dest(realPos.x, realPos.y, tileSize, tileSize / 2);
|
||||||
drawElement(EMapCacheType::ROADS, parent->roadImages[tinfoUpper->roadType - 1][tinfoUpper->roadDir][rotation],
|
drawElement(EMapCacheType::ROADS, parent->roadImages[tinfoUpper->roadType][tinfoUpper->roadDir][rotation],
|
||||||
&source, targetSurf, &dest);
|
&source, targetSurf, &dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tinfo.roadType != ERoadType::NO_ROAD) //print road from this tile
|
if(tinfo.roadType != ROAD_NAMES[0]) //print road from this tile
|
||||||
{
|
{
|
||||||
ui8 rotation = (tinfo.extTileFlags >> 4) % 4;
|
ui8 rotation = (tinfo.extTileFlags >> 4) % 4;
|
||||||
Rect source(0, 0, tileSize, halfTileSizeCeil);
|
Rect source(0, 0, tileSize, halfTileSizeCeil);
|
||||||
Rect dest(realPos.x, realPos.y + tileSize / 2, tileSize, tileSize / 2);
|
Rect dest(realPos.x, realPos.y + tileSize / 2, tileSize, tileSize / 2);
|
||||||
drawElement(EMapCacheType::ROADS, parent->roadImages[tinfo.roadType - 1][tinfo.roadDir][rotation],
|
drawElement(EMapCacheType::ROADS, parent->roadImages[tinfo.roadType][tinfo.roadDir][rotation],
|
||||||
&source, targetSurf, &dest);
|
&source, targetSurf, &dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -825,7 +821,7 @@ void CMapHandler::CMapBlitter::drawRiver(SDL_Surface * targetSurf, const Terrain
|
|||||||
{
|
{
|
||||||
Rect destRect(realTileRect);
|
Rect destRect(realTileRect);
|
||||||
ui8 rotation = (tinfo.extTileFlags >> 2) % 4;
|
ui8 rotation = (tinfo.extTileFlags >> 2) % 4;
|
||||||
drawElement(EMapCacheType::RIVERS, parent->riverImages[tinfo.riverType-1][tinfo.riverDir][rotation], nullptr, targetSurf, &destRect);
|
drawElement(EMapCacheType::RIVERS, parent->riverImages[tinfo.riverType][tinfo.riverDir][rotation], nullptr, targetSurf, &destRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
|
void CMapHandler::CMapBlitter::drawFow(SDL_Surface * targetSurf) const
|
||||||
@ -876,7 +872,7 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn
|
|||||||
if(isVisible || info->showAllTerrain)
|
if(isVisible || info->showAllTerrain)
|
||||||
{
|
{
|
||||||
drawTileTerrain(targetSurf, tinfo, tile);
|
drawTileTerrain(targetSurf, tinfo, tile);
|
||||||
if (tinfo.riverType)
|
if(tinfo.riverType != RIVER_NAMES[0])
|
||||||
drawRiver(targetSurf, tinfo);
|
drawRiver(targetSurf, tinfo);
|
||||||
drawRoad(targetSurf, tinfo, tinfoUpper);
|
drawRoad(targetSurf, tinfo, tinfoUpper);
|
||||||
}
|
}
|
||||||
@ -1326,13 +1322,13 @@ bool CMapHandler::canStartHeroMovement()
|
|||||||
|
|
||||||
void CMapHandler::updateWater() //shift colors in palettes of water tiles
|
void CMapHandler::updateWater() //shift colors in palettes of water tiles
|
||||||
{
|
{
|
||||||
for(auto & elem : terrainImages[7])
|
for(auto & elem : terrainImages["lava"])
|
||||||
{
|
{
|
||||||
for(auto img : elem)
|
for(auto img : elem)
|
||||||
img->shiftPalette(246, 9);
|
img->shiftPalette(246, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & elem : terrainImages[8])
|
for(auto & elem : terrainImages["water"])
|
||||||
{
|
{
|
||||||
for(auto img : elem)
|
for(auto img : elem)
|
||||||
{
|
{
|
||||||
@ -1341,7 +1337,7 @@ void CMapHandler::updateWater() //shift colors in palettes of water tiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & elem : riverImages[0])
|
for(auto & elem : riverImages["clrrvr"])
|
||||||
{
|
{
|
||||||
for(auto img : elem)
|
for(auto img : elem)
|
||||||
{
|
{
|
||||||
@ -1350,7 +1346,7 @@ void CMapHandler::updateWater() //shift colors in palettes of water tiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & elem : riverImages[2])
|
for(auto & elem : riverImages["mudrvr"])
|
||||||
{
|
{
|
||||||
for(auto img : elem)
|
for(auto img : elem)
|
||||||
{
|
{
|
||||||
@ -1360,7 +1356,7 @@ void CMapHandler::updateWater() //shift colors in palettes of water tiles
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto & elem : riverImages[3])
|
for(auto & elem : riverImages["lavrvr"])
|
||||||
{
|
{
|
||||||
for(auto img : elem)
|
for(auto img : elem)
|
||||||
img->shiftPalette(240, 9);
|
img->shiftPalette(240, 9);
|
||||||
|
@ -354,8 +354,8 @@ public:
|
|||||||
//terrain graphics
|
//terrain graphics
|
||||||
|
|
||||||
//FIXME: unique_ptr should be enough, but fails to compile in MSVS 2013
|
//FIXME: unique_ptr should be enough, but fails to compile in MSVS 2013
|
||||||
typedef std::vector<std::array<std::shared_ptr<CAnimation>, 4>> TFlippedAnimations; //[type, rotation]
|
typedef std::map<std::string, std::array<std::shared_ptr<CAnimation>, 4>> TFlippedAnimations; //[type, rotation]
|
||||||
typedef std::vector<std::vector<std::array<std::shared_ptr<IImage>, 4>>> TFlippedCache;//[type, view type, rotation]
|
typedef std::map<std::string, std::vector<std::array<std::shared_ptr<IImage>, 4>>> TFlippedCache;//[type, view type, rotation]
|
||||||
|
|
||||||
TFlippedAnimations terrainAnimations;//[terrain type, rotation]
|
TFlippedAnimations terrainAnimations;//[terrain type, rotation]
|
||||||
TFlippedCache terrainImages;//[terrain type, view type, rotation]
|
TFlippedCache terrainImages;//[terrain type, view type, rotation]
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "../../lib/CHeroHandler.h"
|
#include "../../lib/CHeroHandler.h"
|
||||||
#include "../../lib/CModHandler.h"
|
#include "../../lib/CModHandler.h"
|
||||||
#include "../../lib/CTownHandler.h"
|
#include "../../lib/CTownHandler.h"
|
||||||
|
#include "../../lib/Terrain.h"
|
||||||
#include "../../lib/filesystem/Filesystem.h"
|
#include "../../lib/filesystem/Filesystem.h"
|
||||||
#include "../../lib/JsonNode.h"
|
#include "../../lib/JsonNode.h"
|
||||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||||
@ -494,41 +495,30 @@ void CMinimapInstance::showAll(SDL_Surface * to)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string from)
|
std::map<Terrain, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors()
|
||||||
{
|
{
|
||||||
std::map<int, std::pair<SDL_Color, SDL_Color> > ret;
|
std::map<Terrain, std::pair<SDL_Color, SDL_Color> > ret;
|
||||||
|
|
||||||
const JsonNode config(ResourceID(from, EResType::TEXT));
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
|
||||||
for(auto &m : config.Struct())
|
|
||||||
{
|
{
|
||||||
auto index = boost::find(GameConstants::TERRAIN_NAMES, m.first);
|
auto & m = Terrain::Manager::getInfo(terrain);
|
||||||
if (index == std::end(GameConstants::TERRAIN_NAMES))
|
|
||||||
{
|
|
||||||
logGlobal->error("Error: unknown terrain in terrains.json: %s", m.first);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int terrainID = static_cast<int>(index - std::begin(GameConstants::TERRAIN_NAMES));
|
|
||||||
|
|
||||||
const JsonVector &unblockedVec = m.second["minimapUnblocked"].Vector();
|
|
||||||
SDL_Color normal =
|
SDL_Color normal =
|
||||||
{
|
{
|
||||||
ui8(unblockedVec[0].Float()),
|
ui8(m.minimapUnblocked[0]),
|
||||||
ui8(unblockedVec[1].Float()),
|
ui8(m.minimapUnblocked[1]),
|
||||||
ui8(unblockedVec[2].Float()),
|
ui8(m.minimapUnblocked[2]),
|
||||||
ui8(255)
|
ui8(255)
|
||||||
};
|
};
|
||||||
|
|
||||||
const JsonVector &blockedVec = m.second["minimapBlocked"].Vector();
|
|
||||||
SDL_Color blocked =
|
SDL_Color blocked =
|
||||||
{
|
{
|
||||||
ui8(blockedVec[0].Float()),
|
ui8(m.minimapBlocked[0]),
|
||||||
ui8(blockedVec[1].Float()),
|
ui8(m.minimapBlocked[1]),
|
||||||
ui8(blockedVec[2].Float()),
|
ui8(m.minimapBlocked[2]),
|
||||||
ui8(255)
|
ui8(255)
|
||||||
};
|
};
|
||||||
|
|
||||||
ret.insert(std::make_pair(terrainID, std::make_pair(normal, blocked)));
|
ret[terrain] = std::make_pair(normal, blocked);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -536,7 +526,7 @@ std::map<int, std::pair<SDL_Color, SDL_Color> > CMinimap::loadColors(std::string
|
|||||||
CMinimap::CMinimap(const Rect & position)
|
CMinimap::CMinimap(const Rect & position)
|
||||||
: CIntObject(LCLICK | RCLICK | HOVER | MOVE, position.topLeft()),
|
: CIntObject(LCLICK | RCLICK | HOVER | MOVE, position.topLeft()),
|
||||||
level(0),
|
level(0),
|
||||||
colors(loadColors("config/terrains.json"))
|
colors(loadColors())
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||||
pos.w = position.w;
|
pos.w = position.w;
|
||||||
|
@ -30,6 +30,7 @@ struct InfoAboutTown;
|
|||||||
class CHeroTooltip;
|
class CHeroTooltip;
|
||||||
class CTownTooltip;
|
class CTownTooltip;
|
||||||
class CTextBox;
|
class CTextBox;
|
||||||
|
class Terrain;
|
||||||
|
|
||||||
/// Base UI Element for hero\town lists
|
/// Base UI Element for hero\town lists
|
||||||
class CList : public CIntObject
|
class CList : public CIntObject
|
||||||
@ -216,7 +217,7 @@ protected:
|
|||||||
int level;
|
int level;
|
||||||
|
|
||||||
//to initialize colors
|
//to initialize colors
|
||||||
std::map<int, std::pair<SDL_Color, SDL_Color> > loadColors(std::string from);
|
std::map<Terrain, std::pair<SDL_Color, SDL_Color> > loadColors();
|
||||||
|
|
||||||
void clickLeft(tribool down, bool previousState) override;
|
void clickLeft(tribool down, bool previousState) override;
|
||||||
void clickRight(tribool down, bool previousState) override;
|
void clickRight(tribool down, bool previousState) override;
|
||||||
@ -227,7 +228,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// terrainID -> (normal color, blocked color)
|
// terrainID -> (normal color, blocked color)
|
||||||
const std::map<int, std::pair<SDL_Color, SDL_Color> > colors;
|
const std::map<Terrain, std::pair<SDL_Color, SDL_Color> > colors;
|
||||||
|
|
||||||
CMinimap(const Rect & position);
|
CMinimap(const Rect & position);
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ void CTerrainRect::showPath(const SDL_Rect * extRect, SDL_Surface * to)
|
|||||||
{-1, 1, 2, 23, -1, 3, 22, 21, 12}
|
{-1, 1, 2, 23, -1, 3, 22, 21, 12}
|
||||||
}; //table of magic values TODO meaning, change variable name
|
}; //table of magic values TODO meaning, change variable name
|
||||||
|
|
||||||
for (int i=0; i < (int)currentPath->nodes.size()-1; ++i)
|
for (int i = 0; i < -1 + (int)currentPath->nodes.size(); ++i)
|
||||||
{
|
{
|
||||||
const int3 &curPos = currentPath->nodes[i].coord, &nextPos = currentPath->nodes[i+1].coord;
|
const int3 &curPos = currentPath->nodes[i].coord, &nextPos = currentPath->nodes[i+1].coord;
|
||||||
if(curPos.z != adventureInt->position.z)
|
if(curPos.z != adventureInt->position.z)
|
||||||
|
@ -80,5 +80,9 @@
|
|||||||
"skills" :
|
"skills" :
|
||||||
[
|
[
|
||||||
"config/skills.json"
|
"config/skills.json"
|
||||||
|
],
|
||||||
|
"terrains":
|
||||||
|
[
|
||||||
|
"config/terrains.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
"obstacles" : [
|
"obstacles" : [
|
||||||
{
|
{
|
||||||
"id" : 0,
|
"id" : 0,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 1,
|
"id" : 1,
|
||||||
"allowedTerrain" : [0, 1, 5, 6],
|
"allowedTerrain" : ["dirt", "sand", "rough", "subterra"],
|
||||||
"specialBattlefields" : [0],
|
"specialBattlefields" : [0],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -34,7 +34,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 2,
|
"id" : 2,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -44,7 +44,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 3,
|
"id" : 3,
|
||||||
"allowedTerrain" : [0, 5],
|
"allowedTerrain" : ["dirt", "rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -54,7 +54,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 4,
|
"id" : 4,
|
||||||
"allowedTerrain" : [0, 5, 6],
|
"allowedTerrain" : ["dirt", "rough", "subterra"],
|
||||||
"specialBattlefields" : [0, 1],
|
"specialBattlefields" : [0, 1],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -64,7 +64,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 5,
|
"id" : 5,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -74,7 +74,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 6,
|
"id" : 6,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -84,7 +84,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 7,
|
"id" : 7,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -94,7 +94,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 8,
|
"id" : 8,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -104,7 +104,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 9,
|
"id" : 9,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -114,7 +114,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 10,
|
"id" : 10,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -124,7 +124,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 11,
|
"id" : 11,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -134,7 +134,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 12,
|
"id" : 12,
|
||||||
"allowedTerrain" : [0, 5],
|
"allowedTerrain" : ["dirt", "rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -144,7 +144,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 13,
|
"id" : 13,
|
||||||
"allowedTerrain" : [0, 5],
|
"allowedTerrain" : ["dirt", "rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -154,7 +154,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 14,
|
"id" : 14,
|
||||||
"allowedTerrain" : [0, 5],
|
"allowedTerrain" : ["dirt", "rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -164,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 15,
|
"id" : 15,
|
||||||
"allowedTerrain" : [0, 5],
|
"allowedTerrain" : ["dirt", "rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -174,7 +174,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 16,
|
"id" : 16,
|
||||||
"allowedTerrain" : [1],
|
"allowedTerrain" : ["sand"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 4,
|
"height" : 4,
|
||||||
@ -184,7 +184,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 17,
|
"id" : 17,
|
||||||
"allowedTerrain" : [1],
|
"allowedTerrain" : ["sand"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -194,7 +194,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 18,
|
"id" : 18,
|
||||||
"allowedTerrain" : [1],
|
"allowedTerrain" : ["sand"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -204,7 +204,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 19,
|
"id" : 19,
|
||||||
"allowedTerrain" : [2, 4],
|
"allowedTerrain" : ["grass", "swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -214,7 +214,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 20,
|
"id" : 20,
|
||||||
"allowedTerrain" : [2, 4],
|
"allowedTerrain" : ["grass", "swamp"],
|
||||||
"specialBattlefields" : [2],
|
"specialBattlefields" : [2],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -224,7 +224,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 21,
|
"id" : 21,
|
||||||
"allowedTerrain" : [2, 4],
|
"allowedTerrain" : ["grass", "swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 1,
|
"width" : 1,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -234,7 +234,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 22,
|
"id" : 22,
|
||||||
"allowedTerrain" : [2],
|
"allowedTerrain" : ["grass"],
|
||||||
"specialBattlefields" : [2],
|
"specialBattlefields" : [2],
|
||||||
"width" : 6,
|
"width" : 6,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -244,7 +244,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 23,
|
"id" : 23,
|
||||||
"allowedTerrain" : [2],
|
"allowedTerrain" : ["grass"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 7,
|
"width" : 7,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -254,7 +254,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 24,
|
"id" : 24,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -264,7 +264,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 25,
|
"id" : 25,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 5,
|
"width" : 5,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -274,7 +274,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 26,
|
"id" : 26,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -284,7 +284,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 27,
|
"id" : 27,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -294,7 +294,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 28,
|
"id" : 28,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -304,7 +304,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 29,
|
"id" : 29,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -314,7 +314,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 30,
|
"id" : 30,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -324,7 +324,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 31,
|
"id" : 31,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -334,7 +334,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 32,
|
"id" : 32,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 7,
|
"width" : 7,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -344,7 +344,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 33,
|
"id" : 33,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 5,
|
"width" : 5,
|
||||||
"height" : 5,
|
"height" : 5,
|
||||||
@ -354,7 +354,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 34,
|
"id" : 34,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -364,7 +364,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 35,
|
"id" : 35,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 8,
|
"width" : 8,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -374,7 +374,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 36,
|
"id" : 36,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -384,7 +384,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 37,
|
"id" : 37,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 1,
|
"height" : 1,
|
||||||
@ -394,7 +394,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 38,
|
"id" : 38,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 5,
|
"width" : 5,
|
||||||
"height" : 4,
|
"height" : 4,
|
||||||
@ -404,7 +404,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 39,
|
"id" : 39,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -414,7 +414,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 40,
|
"id" : 40,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 2,
|
"width" : 2,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -424,7 +424,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 41,
|
"id" : 41,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -434,7 +434,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 42,
|
"id" : 42,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -444,7 +444,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 43,
|
"id" : 43,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -454,7 +454,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 44,
|
"id" : 44,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -464,7 +464,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 45,
|
"id" : 45,
|
||||||
"allowedTerrain" : [6],
|
"allowedTerrain" : ["subterra"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -474,7 +474,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 46,
|
"id" : 46,
|
||||||
"allowedTerrain" : [6],
|
"allowedTerrain" : ["subterra"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -484,7 +484,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 47,
|
"id" : 47,
|
||||||
"allowedTerrain" : [6],
|
"allowedTerrain" : ["subterra"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -494,7 +494,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 48,
|
"id" : 48,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -504,7 +504,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 49,
|
"id" : 49,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -514,7 +514,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 50,
|
"id" : 50,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 5,
|
"width" : 5,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -524,7 +524,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 51,
|
"id" : 51,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 2,
|
"height" : 2,
|
||||||
@ -534,7 +534,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 52,
|
"id" : 52,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 4,
|
"width" : 4,
|
||||||
"height" : 4,
|
"height" : 4,
|
||||||
@ -544,7 +544,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 53,
|
"id" : 53,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 5,
|
"width" : 5,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -554,7 +554,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 54,
|
"id" : 54,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 5,
|
"width" : 5,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -564,7 +564,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 55,
|
"id" : 55,
|
||||||
"allowedTerrain" : [8],
|
"allowedTerrain" : ["water"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 3,
|
"width" : 3,
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
@ -926,7 +926,7 @@
|
|||||||
"absoluteObstacles" : [
|
"absoluteObstacles" : [
|
||||||
{
|
{
|
||||||
"id" : 0,
|
"id" : 0,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 124,
|
"width" : 124,
|
||||||
"height" : 254,
|
"height" : 254,
|
||||||
@ -935,7 +935,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 1,
|
"id" : 1,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 256,
|
"width" : 256,
|
||||||
"height" : 254,
|
"height" : 254,
|
||||||
@ -944,7 +944,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 2,
|
"id" : 2,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 168,
|
"width" : 168,
|
||||||
"height" : 212,
|
"height" : 212,
|
||||||
@ -953,7 +953,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 3,
|
"id" : 3,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 124,
|
"width" : 124,
|
||||||
"height" : 254,
|
"height" : 254,
|
||||||
@ -962,7 +962,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 4,
|
"id" : 4,
|
||||||
"allowedTerrain" : [0],
|
"allowedTerrain" : ["dirt"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 146,
|
"width" : 146,
|
||||||
"height" : 254,
|
"height" : 254,
|
||||||
@ -971,7 +971,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 5,
|
"id" : 5,
|
||||||
"allowedTerrain" : [2],
|
"allowedTerrain" : ["grass"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 173,
|
"width" : 173,
|
||||||
"height" : 221,
|
"height" : 221,
|
||||||
@ -980,7 +980,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 6,
|
"id" : 6,
|
||||||
"allowedTerrain" : [2],
|
"allowedTerrain" : ["grass"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 180,
|
"width" : 180,
|
||||||
"height" : 264,
|
"height" : 264,
|
||||||
@ -989,7 +989,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 7,
|
"id" : 7,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 166,
|
"width" : 166,
|
||||||
"height" : 255,
|
"height" : 255,
|
||||||
@ -998,7 +998,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 8,
|
"id" : 8,
|
||||||
"allowedTerrain" : [3],
|
"allowedTerrain" : ["snow"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 302,
|
"width" : 302,
|
||||||
"height" : 172,
|
"height" : 172,
|
||||||
@ -1007,7 +1007,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 9,
|
"id" : 9,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 300,
|
"width" : 300,
|
||||||
"height" : 170,
|
"height" : 170,
|
||||||
@ -1016,7 +1016,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 10,
|
"id" : 10,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 278,
|
"width" : 278,
|
||||||
"height" : 171,
|
"height" : 171,
|
||||||
@ -1025,7 +1025,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 11,
|
"id" : 11,
|
||||||
"allowedTerrain" : [4],
|
"allowedTerrain" : ["swamp"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 256,
|
"width" : 256,
|
||||||
"height" : 254,
|
"height" : 254,
|
||||||
@ -1034,7 +1034,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 12,
|
"id" : 12,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 124,
|
"width" : 124,
|
||||||
"height" : 254,
|
"height" : 254,
|
||||||
@ -1043,7 +1043,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 13,
|
"id" : 13,
|
||||||
"allowedTerrain" : [7],
|
"allowedTerrain" : ["lava"],
|
||||||
"specialBattlefields" : [],
|
"specialBattlefields" : [],
|
||||||
"width" : 256,
|
"width" : 256,
|
||||||
"height" : 128,
|
"height" : 128,
|
||||||
@ -1052,7 +1052,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 14,
|
"id" : 14,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 186,
|
"width" : 186,
|
||||||
"height" : 212,
|
"height" : 212,
|
||||||
@ -1061,7 +1061,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 15,
|
"id" : 15,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 347,
|
"width" : 347,
|
||||||
"height" : 174,
|
"height" : 174,
|
||||||
@ -1070,7 +1070,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 16,
|
"id" : 16,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 294,
|
"width" : 294,
|
||||||
"height" : 169,
|
"height" : 169,
|
||||||
@ -1079,7 +1079,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 17,
|
"id" : 17,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 165,
|
"width" : 165,
|
||||||
"height" : 257,
|
"height" : 257,
|
||||||
@ -1088,7 +1088,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 18,
|
"id" : 18,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 208,
|
"width" : 208,
|
||||||
"height" : 268,
|
"height" : 268,
|
||||||
@ -1097,7 +1097,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 19,
|
"id" : 19,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 252,
|
"width" : 252,
|
||||||
"height" : 254,
|
"height" : 254,
|
||||||
@ -1106,7 +1106,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 20,
|
"id" : 20,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 278,
|
"width" : 278,
|
||||||
"height" : 128,
|
"height" : 128,
|
||||||
@ -1115,7 +1115,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 21,
|
"id" : 21,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 208,
|
"width" : 208,
|
||||||
"height" : 268,
|
"height" : 268,
|
||||||
@ -1124,7 +1124,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 22,
|
"id" : 22,
|
||||||
"allowedTerrain" : [5],
|
"allowedTerrain" : ["rough"],
|
||||||
"specialBattlefields" : [1],
|
"specialBattlefields" : [1],
|
||||||
"width" : 168,
|
"width" : 168,
|
||||||
"height" : 212,
|
"height" : 212,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"terrain" :
|
"terrain" :
|
||||||
{
|
{
|
||||||
"undergroundAllow" : ["lava"], //others to be replaced by subterranena
|
"undergroundAllow" : ["lava"], //others to be replaced by subterranena
|
||||||
"groundProhibit" : ["subterranean"] //to be replaced by dirt
|
"groundProhibit" : ["subterra"] //to be replaced by dirt
|
||||||
},
|
},
|
||||||
"waterZone" :
|
"waterZone" :
|
||||||
{
|
{
|
||||||
@ -31,7 +31,7 @@
|
|||||||
"extraResourcesLimit" : 3
|
"extraResourcesLimit" : 3
|
||||||
},
|
},
|
||||||
"minGuardStrength" : 2000,
|
"minGuardStrength" : 2000,
|
||||||
"defaultRoadType" : "cobblestone_road",
|
"defaultRoadType" : "pc", //pd - dirt, pg - gravel, pc - cobblestone
|
||||||
"treasureValueLimit" : 20000, //generate pandora with gold for treasure above this limit
|
"treasureValueLimit" : 20000, //generate pandora with gold for treasure above this limit
|
||||||
"prisons" :
|
"prisons" :
|
||||||
{
|
{
|
||||||
|
@ -4,69 +4,92 @@
|
|||||||
"moveCost" : 100,
|
"moveCost" : 100,
|
||||||
"minimapUnblocked" : [ 82, 56, 8 ],
|
"minimapUnblocked" : [ 82, 56, 8 ],
|
||||||
"minimapBlocked" : [ 57, 40, 8 ],
|
"minimapBlocked" : [ 57, 40, 8 ],
|
||||||
"music" : "Dirt.mp3"
|
"music" : "Dirt.mp3",
|
||||||
|
"tiles" : "DIRTTL",
|
||||||
|
"code" : "dt"
|
||||||
},
|
},
|
||||||
"sand" :
|
"sand" :
|
||||||
{
|
{
|
||||||
"moveCost" : 150,
|
"moveCost" : 150,
|
||||||
"minimapUnblocked" : [ 222, 207, 140 ],
|
"minimapUnblocked" : [ 222, 207, 140 ],
|
||||||
"minimapBlocked" : [ 165, 158, 107 ],
|
"minimapBlocked" : [ 165, 158, 107 ],
|
||||||
"music" : "Sand.mp3"
|
"music" : "Sand.mp3",
|
||||||
|
"tiles" : "SANDTL",
|
||||||
|
"code" : "sa"
|
||||||
},
|
},
|
||||||
"grass" :
|
"grass" :
|
||||||
{
|
{
|
||||||
"moveCost" : 100,
|
"moveCost" : 100,
|
||||||
"minimapUnblocked" : [ 0, 65, 0 ],
|
"minimapUnblocked" : [ 0, 65, 0 ],
|
||||||
"minimapBlocked" : [ 0, 48, 0 ],
|
"minimapBlocked" : [ 0, 48, 0 ],
|
||||||
"music" : "Grass.mp3"
|
"music" : "Grass.mp3",
|
||||||
|
"tiles" : "GRASTL",
|
||||||
|
"code" : "gr"
|
||||||
},
|
},
|
||||||
"snow" :
|
"snow" :
|
||||||
{
|
{
|
||||||
"moveCost" : 150,
|
"moveCost" : 150,
|
||||||
"minimapUnblocked" : [ 181, 199, 198 ],
|
"minimapUnblocked" : [ 181, 199, 198 ],
|
||||||
"minimapBlocked" : [ 140, 158, 156 ],
|
"minimapBlocked" : [ 140, 158, 156 ],
|
||||||
"music" : "Snow.mp3"
|
"music" : "Snow.mp3",
|
||||||
|
"tiles" : "SNOWTL",
|
||||||
|
"code" : "sn"
|
||||||
},
|
},
|
||||||
"swamp" :
|
"swamp" :
|
||||||
{
|
{
|
||||||
"moveCost" : 175,
|
"moveCost" : 175,
|
||||||
"minimapUnblocked" : [ 74, 134, 107 ],
|
"minimapUnblocked" : [ 74, 134, 107 ],
|
||||||
"minimapBlocked" : [ 33, 89, 66 ],
|
"minimapBlocked" : [ 33, 89, 66 ],
|
||||||
"music" : "Swamp.mp3"
|
"music" : "Swamp.mp3",
|
||||||
|
"tiles" : "SWMPTL",
|
||||||
|
"code" : "sw"
|
||||||
},
|
},
|
||||||
"rough" :
|
"rough" :
|
||||||
{
|
{
|
||||||
"moveCost" : 125,
|
"moveCost" : 125,
|
||||||
"minimapUnblocked" : [ 132, 113, 49 ],
|
"minimapUnblocked" : [ 132, 113, 49 ],
|
||||||
"minimapBlocked" : [ 99, 81, 33 ],
|
"minimapBlocked" : [ 99, 81, 33 ],
|
||||||
"music" : "Rough.mp3"
|
"music" : "Rough.mp3",
|
||||||
|
"tiles" : "ROUGTL",
|
||||||
|
"code" : "rg"
|
||||||
},
|
},
|
||||||
"subterra" :
|
"subterra" :
|
||||||
{
|
{
|
||||||
"moveCost" : 100,
|
"moveCost" : 100,
|
||||||
"minimapUnblocked" : [ 132, 48, 0 ],
|
"minimapUnblocked" : [ 132, 48, 0 ],
|
||||||
"minimapBlocked" : [ 90, 8, 0 ],
|
"minimapBlocked" : [ 90, 8, 0 ],
|
||||||
"music" : "Underground.mp3"
|
"music" : "Underground.mp3",
|
||||||
|
"tiles" : "SUBBTL",
|
||||||
|
"type" : "SUB",
|
||||||
|
"code" : "sb"
|
||||||
},
|
},
|
||||||
"lava" :
|
"lava" :
|
||||||
{
|
{
|
||||||
"moveCost" : 100,
|
"moveCost" : 100,
|
||||||
"minimapUnblocked" : [ 74, 73, 74 ],
|
"minimapUnblocked" : [ 74, 73, 74 ],
|
||||||
"minimapBlocked" : [ 41, 40, 41 ],
|
"minimapBlocked" : [ 41, 40, 41 ],
|
||||||
"music" : "Lava.mp3"
|
"music" : "Lava.mp3",
|
||||||
|
"tiles" : "LAVATL",
|
||||||
|
"code" : "lv"
|
||||||
},
|
},
|
||||||
"water" :
|
"water" :
|
||||||
{
|
{
|
||||||
"moveCost" : 100,
|
"moveCost" : 100,
|
||||||
"minimapUnblocked" : [ 8, 81, 148 ],
|
"minimapUnblocked" : [ 8, 81, 148 ],
|
||||||
"minimapBlocked" : [ 8, 81, 148 ],
|
"minimapBlocked" : [ 8, 81, 148 ],
|
||||||
"music" : "Water.mp3"
|
"music" : "Water.mp3",
|
||||||
|
"tiles" : "WATRTL",
|
||||||
|
"type" : "WATER",
|
||||||
|
"code" : "wt"
|
||||||
},
|
},
|
||||||
"rock" :
|
"rock" :
|
||||||
{
|
{
|
||||||
"moveCost" : -1,
|
"moveCost" : -1,
|
||||||
"minimapUnblocked" : [ 0, 0, 0 ],
|
"minimapUnblocked" : [ 0, 0, 0 ],
|
||||||
"minimapBlocked" : [ 0, 0, 0 ],
|
"minimapBlocked" : [ 0, 0, 0 ],
|
||||||
"music" : "Underground.mp3" // Impossible in H3
|
"music" : "Underground.mp3", // Impossible in H3
|
||||||
|
"tiles" : "ROCKTL",
|
||||||
|
"type" : "ROCK",
|
||||||
|
"code" : "rc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,19 +102,8 @@ public:
|
|||||||
h & constituentOf;
|
h & constituentOf;
|
||||||
h & aClass;
|
h & aClass;
|
||||||
h & id;
|
h & id;
|
||||||
if(version >= 759)
|
h & identifier;
|
||||||
{
|
h & warMachine;
|
||||||
h & identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(version >= 771)
|
|
||||||
{
|
|
||||||
h & warMachine;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
fillWarMachine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CArtifact();
|
CArtifact();
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "CGameState.h"
|
#include "CGameState.h"
|
||||||
#include "CTownHandler.h"
|
#include "CTownHandler.h"
|
||||||
#include "CModHandler.h"
|
#include "CModHandler.h"
|
||||||
|
#include "Terrain.h"
|
||||||
#include "StringConstants.h"
|
#include "StringConstants.h"
|
||||||
#include "serializer/JsonDeserializer.h"
|
#include "serializer/JsonDeserializer.h"
|
||||||
#include "serializer/JsonUpdater.h"
|
#include "serializer/JsonUpdater.h"
|
||||||
@ -282,13 +283,13 @@ std::string CCreature::nodeName() const
|
|||||||
return "\"" + namePl + "\"";
|
return "\"" + namePl + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCreature::isItNativeTerrain(ETerrainType::EETerrainType terrain) const
|
bool CCreature::isItNativeTerrain(const Terrain & terrain) const
|
||||||
{
|
{
|
||||||
auto native = getNativeTerrain();
|
auto native = getNativeTerrain();
|
||||||
return native == terrain || native == ETerrainType::ANY_TERRAIN;
|
return native == terrain || native == Terrain::ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ETerrainType::EETerrainType CCreature::getNativeTerrain() const
|
Terrain CCreature::getNativeTerrain() const
|
||||||
{
|
{
|
||||||
const std::string cachingStringBlocksRetaliation = "type_NO_TERRAIN_PENALTY";
|
const std::string cachingStringBlocksRetaliation = "type_NO_TERRAIN_PENALTY";
|
||||||
static const auto selectorBlocksRetaliation = Selector::type()(Bonus::NO_TERRAIN_PENALTY);
|
static const auto selectorBlocksRetaliation = Selector::type()(Bonus::NO_TERRAIN_PENALTY);
|
||||||
@ -296,8 +297,8 @@ ETerrainType::EETerrainType CCreature::getNativeTerrain() const
|
|||||||
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
|
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
|
||||||
//and in the CGHeroInstance::getNativeTerrain() to setup mevement bonuses or/and penalties.
|
//and in the CGHeroInstance::getNativeTerrain() to setup mevement bonuses or/and penalties.
|
||||||
return hasBonus(selectorBlocksRetaliation, selectorBlocksRetaliation)
|
return hasBonus(selectorBlocksRetaliation, selectorBlocksRetaliation)
|
||||||
? ETerrainType::ANY_TERRAIN
|
? Terrain::ANY
|
||||||
: (ETerrainType::EETerrainType)(*VLC->townh)[faction]->nativeTerrain;
|
: (Terrain)(*VLC->townh)[faction]->nativeTerrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreature::updateFrom(const JsonNode & data)
|
void CCreature::updateFrom(const JsonNode & data)
|
||||||
@ -1340,11 +1341,6 @@ void CCreatureHandler::removeBonusesFromAllCreatures()
|
|||||||
allCreatures.removeBonuses(Selector::all);
|
allCreatures.removeBonuses(Selector::all);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureHandler::restoreAllCreaturesNodeType794()
|
|
||||||
{
|
|
||||||
allCreatures.setNodeType(CBonusSystemNode::ENodeTypes::ALL_CREATURES);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCreatureHandler::buildBonusTreeForTiers()
|
void CCreatureHandler::buildBonusTreeForTiers()
|
||||||
{
|
{
|
||||||
for(CCreature * c : objects)
|
for(CCreature * c : objects)
|
||||||
|
@ -24,6 +24,7 @@ class CLegacyConfigParser;
|
|||||||
class CCreatureHandler;
|
class CCreatureHandler;
|
||||||
class CCreature;
|
class CCreature;
|
||||||
class JsonSerializeFormat;
|
class JsonSerializeFormat;
|
||||||
|
class Terrain;
|
||||||
|
|
||||||
class DLL_LINKAGE CCreature : public Creature, public CBonusSystemNode
|
class DLL_LINKAGE CCreature : public Creature, public CBonusSystemNode
|
||||||
{
|
{
|
||||||
@ -118,14 +119,14 @@ public:
|
|||||||
|
|
||||||
ArtifactID warMachine;
|
ArtifactID warMachine;
|
||||||
|
|
||||||
bool isItNativeTerrain(ETerrainType::EETerrainType terrain) const;
|
bool isItNativeTerrain(const Terrain & terrain) const;
|
||||||
/**
|
/**
|
||||||
Returns creature native terrain considering some terrain bonuses.
|
Returns creature native terrain considering some terrain bonuses.
|
||||||
@param considerBonus is used to avoid Dead Lock when this method is called inside getAllBonuses
|
@param considerBonus is used to avoid Dead Lock when this method is called inside getAllBonuses
|
||||||
considerBonus = true is called from Pathfinder and fills actual nativeTerrain considering bonus(es).
|
considerBonus = true is called from Pathfinder and fills actual nativeTerrain considering bonus(es).
|
||||||
considerBonus = false is called on Battle init and returns already prepared nativeTerrain without Bonus system calling.
|
considerBonus = false is called on Battle init and returns already prepared nativeTerrain without Bonus system calling.
|
||||||
*/
|
*/
|
||||||
ETerrainType::EETerrainType getNativeTerrain() const;
|
Terrain getNativeTerrain() const;
|
||||||
int32_t getIndex() const override;
|
int32_t getIndex() const override;
|
||||||
int32_t getIconIndex() const override;
|
int32_t getIconIndex() const override;
|
||||||
const std::string & getName() const override;
|
const std::string & getName() const override;
|
||||||
@ -211,18 +212,8 @@ public:
|
|||||||
|
|
||||||
h & doubleWide;
|
h & doubleWide;
|
||||||
h & special;
|
h & special;
|
||||||
if(version>=759)
|
h & identifier;
|
||||||
{
|
h & warMachine;
|
||||||
h & identifier;
|
|
||||||
}
|
|
||||||
if(version >= 771)
|
|
||||||
{
|
|
||||||
h & warMachine;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
fillWarMachine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CCreature();
|
CCreature();
|
||||||
@ -281,7 +272,6 @@ public:
|
|||||||
void addBonusForTier(int tier, const std::shared_ptr<Bonus> & b); //tier must be <1-7>
|
void addBonusForTier(int tier, const std::shared_ptr<Bonus> & b); //tier must be <1-7>
|
||||||
void addBonusForAllCreatures(const std::shared_ptr<Bonus> & b); //due to CBonusSystem::addNewBonus(const std::shared_ptr<Bonus>& b);
|
void addBonusForAllCreatures(const std::shared_ptr<Bonus> & b); //due to CBonusSystem::addNewBonus(const std::shared_ptr<Bonus>& b);
|
||||||
void removeBonusesFromAllCreatures();
|
void removeBonusesFromAllCreatures();
|
||||||
void restoreAllCreaturesNodeType794(); //restore ALL_CREATURES node type for old saves
|
|
||||||
|
|
||||||
CCreatureHandler();
|
CCreatureHandler();
|
||||||
~CCreatureHandler();
|
~CCreatureHandler();
|
||||||
|
@ -574,7 +574,7 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow
|
|||||||
{
|
{
|
||||||
const TerrainTile *tile = getTile(t->bestLocation(), false);
|
const TerrainTile *tile = getTile(t->bestLocation(), false);
|
||||||
|
|
||||||
if(!tile || tile->terType != ETerrainType::WATER)
|
if(!tile || tile->terType.isLand())
|
||||||
return EBuildingState::NO_WATER; //lack of water
|
return EBuildingState::NO_WATER; //lack of water
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -963,8 +963,8 @@ void CGameState::initGrailPosition()
|
|||||||
const TerrainTile &t = map->getTile(int3(i, j, k));
|
const TerrainTile &t = map->getTile(int3(i, j, k));
|
||||||
if(!t.blocked
|
if(!t.blocked
|
||||||
&& !t.visitable
|
&& !t.visitable
|
||||||
&& t.terType != ETerrainType::WATER
|
&& t.terType.isLand()
|
||||||
&& t.terType != ETerrainType::ROCK
|
&& t.terType.isPassable()
|
||||||
&& (int)map->grailPos.dist2dSQ(int3(i, j, k)) <= (map->grailRadius * map->grailRadius))
|
&& (int)map->grailPos.dist2dSQ(int3(i, j, k)) <= (map->grailRadius * map->grailRadius))
|
||||||
allowedPos.push_back(int3(i,j,k));
|
allowedPos.push_back(int3(i,j,k));
|
||||||
}
|
}
|
||||||
@ -1940,31 +1940,31 @@ BFieldType CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & ra
|
|||||||
if(map->isCoastalTile(tile)) //coastal tile is always ground
|
if(map->isCoastalTile(tile)) //coastal tile is always ground
|
||||||
return BFieldType::SAND_SHORE;
|
return BFieldType::SAND_SHORE;
|
||||||
|
|
||||||
switch(t.terType)
|
if(t.terType == Terrain("dirt"))
|
||||||
{
|
|
||||||
case ETerrainType::DIRT:
|
|
||||||
return BFieldType(rand.nextInt(3, 5));
|
return BFieldType(rand.nextInt(3, 5));
|
||||||
case ETerrainType::SAND:
|
if(t.terType == Terrain("sand"))
|
||||||
return BFieldType::SAND_MESAS; //TODO: coast support
|
return BFieldType::SAND_MESAS; //TODO: coast support
|
||||||
case ETerrainType::GRASS:
|
if(t.terType == Terrain("grass"))
|
||||||
return BFieldType(rand.nextInt(6, 7));
|
return BFieldType(rand.nextInt(6, 7));
|
||||||
case ETerrainType::SNOW:
|
if(t.terType == Terrain("snow"))
|
||||||
return BFieldType(rand.nextInt(10, 11));
|
return BFieldType(rand.nextInt(10, 11));
|
||||||
case ETerrainType::SWAMP:
|
if(t.terType == Terrain("swamp"))
|
||||||
return BFieldType::SWAMP_TREES;
|
return BFieldType::SWAMP_TREES;
|
||||||
case ETerrainType::ROUGH:
|
if(t.terType == Terrain("rough"))
|
||||||
return BFieldType::ROUGH;
|
return BFieldType::ROUGH;
|
||||||
case ETerrainType::SUBTERRANEAN:
|
if(t.terType.isUnderground())
|
||||||
return BFieldType::SUBTERRANEAN;
|
return BFieldType::SUBTERRANEAN;
|
||||||
case ETerrainType::LAVA:
|
if(t.terType == Terrain("lava"))
|
||||||
return BFieldType::LAVA;
|
return BFieldType::LAVA;
|
||||||
case ETerrainType::WATER:
|
if(t.terType.isWater())
|
||||||
return BFieldType::SHIP;
|
return BFieldType::SHIP;
|
||||||
case ETerrainType::ROCK:
|
if(!t.terType.isPassable())
|
||||||
return BFieldType::ROCKLANDS;
|
return BFieldType::ROCKLANDS;
|
||||||
default:
|
|
||||||
return BFieldType::NONE;
|
//TODO: STUB, support new battlegrounds
|
||||||
}
|
return BFieldType::DIRT_HILLS;
|
||||||
|
|
||||||
|
return BFieldType::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
|
UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
|
||||||
@ -2145,7 +2145,7 @@ void CGameState::updateRumor()
|
|||||||
rumorId = *RandomGeneratorUtil::nextItem(sRumorTypes, rand);
|
rumorId = *RandomGeneratorUtil::nextItem(sRumorTypes, rand);
|
||||||
if(rumorId == RumorState::RUMOR_GRAIL)
|
if(rumorId == RumorState::RUMOR_GRAIL)
|
||||||
{
|
{
|
||||||
rumorExtra = getTile(map->grailPos)->terType;
|
rumorExtra = getTile(map->grailPos)->terType.id();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,14 +227,7 @@ public:
|
|||||||
h & hpool;
|
h & hpool;
|
||||||
h & globalEffects;
|
h & globalEffects;
|
||||||
h & rand;
|
h & rand;
|
||||||
if(version >= 755) //save format backward compatibility
|
h & rumor;
|
||||||
{
|
|
||||||
h & rumor;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
rumor = RumorState();
|
|
||||||
}
|
|
||||||
|
|
||||||
BONUS_TREE_DESERIALIZATION_FIX
|
BONUS_TREE_DESERIALIZATION_FIX
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "CModHandler.h"
|
#include "CModHandler.h"
|
||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
#include "VCMI_Lib.h"
|
#include "VCMI_Lib.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
size_t Unicode::getCharacterSize(char firstByte)
|
size_t Unicode::getCharacterSize(char firstByte)
|
||||||
{
|
{
|
||||||
@ -309,6 +310,7 @@ void CGeneralTextHandler::readToVector(std::string sourceName, std::vector<std::
|
|||||||
|
|
||||||
CGeneralTextHandler::CGeneralTextHandler()
|
CGeneralTextHandler::CGeneralTextHandler()
|
||||||
{
|
{
|
||||||
|
std::vector<std::string> h3mTerrainNames;
|
||||||
readToVector("DATA/VCDESC.TXT", victoryConditions);
|
readToVector("DATA/VCDESC.TXT", victoryConditions);
|
||||||
readToVector("DATA/LCDESC.TXT", lossCondtions);
|
readToVector("DATA/LCDESC.TXT", lossCondtions);
|
||||||
readToVector("DATA/TCOMMAND.TXT", tcommands);
|
readToVector("DATA/TCOMMAND.TXT", tcommands);
|
||||||
@ -317,7 +319,7 @@ CGeneralTextHandler::CGeneralTextHandler()
|
|||||||
readToVector("DATA/ADVEVENT.TXT", advobtxt);
|
readToVector("DATA/ADVEVENT.TXT", advobtxt);
|
||||||
readToVector("DATA/XTRAINFO.TXT", xtrainfo);
|
readToVector("DATA/XTRAINFO.TXT", xtrainfo);
|
||||||
readToVector("DATA/RESTYPES.TXT", restypes);
|
readToVector("DATA/RESTYPES.TXT", restypes);
|
||||||
readToVector("DATA/TERRNAME.TXT", terrainNames);
|
readToVector("DATA/TERRNAME.TXT", h3mTerrainNames);
|
||||||
readToVector("DATA/RANDSIGN.TXT", randsign);
|
readToVector("DATA/RANDSIGN.TXT", randsign);
|
||||||
readToVector("DATA/CRGEN1.TXT", creGens);
|
readToVector("DATA/CRGEN1.TXT", creGens);
|
||||||
readToVector("DATA/CRGEN4.TXT", creGens4);
|
readToVector("DATA/CRGEN4.TXT", creGens4);
|
||||||
@ -331,6 +333,17 @@ CGeneralTextHandler::CGeneralTextHandler()
|
|||||||
readToVector("DATA/HEROSCRN.TXT", heroscrn);
|
readToVector("DATA/HEROSCRN.TXT", heroscrn);
|
||||||
readToVector("DATA/TENTCOLR.TXT", tentColors);
|
readToVector("DATA/TENTCOLR.TXT", tentColors);
|
||||||
readToVector("DATA/SKILLLEV.TXT", levels);
|
readToVector("DATA/SKILLLEV.TXT", levels);
|
||||||
|
|
||||||
|
for(int i = 0; i < h3mTerrainNames.size(); ++i)
|
||||||
|
{
|
||||||
|
terrainNames[Terrain::createTerrainTypeH3M(i)] = h3mTerrainNames[i];
|
||||||
|
}
|
||||||
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
{
|
||||||
|
if(!Terrain::Manager::getInfo(terrain).terrainText.empty())
|
||||||
|
terrainNames[terrain] = Terrain::Manager::getInfo(terrain).terrainText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char * QE_MOD_COMMANDS = "DATA/QECOMMANDS.TXT";
|
static const char * QE_MOD_COMMANDS = "DATA/QECOMMANDS.TXT";
|
||||||
if (CResourceHandler::get()->existsResource(ResourceID(QE_MOD_COMMANDS, EResType::TEXT)))
|
if (CResourceHandler::get()->existsResource(ResourceID(QE_MOD_COMMANDS, EResType::TEXT)))
|
||||||
|
@ -122,7 +122,7 @@ public:
|
|||||||
std::vector<std::string> advobtxt;
|
std::vector<std::string> advobtxt;
|
||||||
std::vector<std::string> xtrainfo;
|
std::vector<std::string> xtrainfo;
|
||||||
std::vector<std::string> restypes; //names of resources
|
std::vector<std::string> restypes; //names of resources
|
||||||
std::vector<std::string> terrainNames;
|
std::map<std::string, std::string> terrainNames;
|
||||||
std::vector<std::string> randsign;
|
std::vector<std::string> randsign;
|
||||||
std::vector<std::pair<std::string,std::string>> mines; //first - name; second - event description
|
std::vector<std::pair<std::string,std::string>> mines; //first - name; second - event description
|
||||||
std::vector<std::string> seerEmpty;
|
std::vector<std::string> seerEmpty;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "CCreatureHandler.h"
|
#include "CCreatureHandler.h"
|
||||||
#include "CModHandler.h"
|
#include "CModHandler.h"
|
||||||
#include "CTownHandler.h"
|
#include "CTownHandler.h"
|
||||||
|
#include "Terrain.h"
|
||||||
#include "mapObjects/CObjectHandler.h" //for hero specialty
|
#include "mapObjects/CObjectHandler.h" //for hero specialty
|
||||||
#include "CSkillHandler.h"
|
#include "CSkillHandler.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -176,7 +177,7 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CObstacleInfo::isAppropriate(ETerrainType terrainType, int specialBattlefield) const
|
bool CObstacleInfo::isAppropriate(Terrain terrainType, int specialBattlefield) const
|
||||||
{
|
{
|
||||||
if(specialBattlefield != -1)
|
if(specialBattlefield != -1)
|
||||||
return vstd::contains(allowedSpecialBfields, specialBattlefield);
|
return vstd::contains(allowedSpecialBfields, specialBattlefield);
|
||||||
@ -376,9 +377,9 @@ CHeroHandler::CHeroHandler()
|
|||||||
{
|
{
|
||||||
loadObstacles();
|
loadObstacles();
|
||||||
loadTerrains();
|
loadTerrains();
|
||||||
for (int i = 0; i < GameConstants::TERRAIN_TYPES; ++i)
|
for(int i = 0; i < Terrain::Manager::terrains().size(); ++i)
|
||||||
{
|
{
|
||||||
VLC->modh->identifiers.registerObject("core", "terrain", GameConstants::TERRAIN_NAMES[i], i);
|
VLC->modh->identifiers.registerObject("core", "terrain", Terrain::Manager::terrains()[i], i);
|
||||||
}
|
}
|
||||||
loadBallistics();
|
loadBallistics();
|
||||||
loadExperience();
|
loadExperience();
|
||||||
@ -826,7 +827,8 @@ void CHeroHandler::loadObstacles()
|
|||||||
obi.defName = obs["defname"].String();
|
obi.defName = obs["defname"].String();
|
||||||
obi.width = static_cast<si32>(obs["width"].Float());
|
obi.width = static_cast<si32>(obs["width"].Float());
|
||||||
obi.height = static_cast<si32>(obs["height"].Float());
|
obi.height = static_cast<si32>(obs["height"].Float());
|
||||||
obi.allowedTerrains = obs["allowedTerrain"].convertTo<std::vector<ETerrainType> >();
|
for(auto & t : obs["allowedTerrain"].Vector())
|
||||||
|
obi.allowedTerrains.emplace_back(t.String());
|
||||||
obi.allowedSpecialBfields = obs["specialBattlefields"].convertTo<std::vector<BFieldType> >();
|
obi.allowedSpecialBfields = obs["specialBattlefields"].convertTo<std::vector<BFieldType> >();
|
||||||
obi.blockedTiles = obs["blockedTiles"].convertTo<std::vector<si16> >();
|
obi.blockedTiles = obs["blockedTiles"].convertTo<std::vector<si16> >();
|
||||||
obi.isAbsoluteObstacle = absolute;
|
obi.isAbsoluteObstacle = absolute;
|
||||||
@ -1029,11 +1031,10 @@ ui64 CHeroHandler::reqExp (ui32 level) const
|
|||||||
|
|
||||||
void CHeroHandler::loadTerrains()
|
void CHeroHandler::loadTerrains()
|
||||||
{
|
{
|
||||||
const JsonNode config(ResourceID("config/terrains.json"));
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
{
|
||||||
terrCosts.reserve(GameConstants::TERRAIN_TYPES);
|
terrCosts[terrain] = Terrain::Manager::getInfo(terrain).moveCost;
|
||||||
for(const std::string & name : GameConstants::TERRAIN_NAMES)
|
}
|
||||||
terrCosts.push_back((int)config[name]["moveCost"].Float());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<bool> CHeroHandler::getDefaultAllowed() const
|
std::vector<bool> CHeroHandler::getDefaultAllowed() const
|
||||||
|
@ -26,6 +26,7 @@ struct BattleHex;
|
|||||||
class JsonNode;
|
class JsonNode;
|
||||||
class CRandomGenerator;
|
class CRandomGenerator;
|
||||||
class JsonSerializeFormat;
|
class JsonSerializeFormat;
|
||||||
|
class Terrain;
|
||||||
|
|
||||||
struct SSpecialtyInfo
|
struct SSpecialtyInfo
|
||||||
{ si32 type;
|
{ si32 type;
|
||||||
@ -119,15 +120,7 @@ public:
|
|||||||
h & initialArmy;
|
h & initialArmy;
|
||||||
h & heroClass;
|
h & heroClass;
|
||||||
h & secSkillsInit;
|
h & secSkillsInit;
|
||||||
if(version >= 781)
|
h & specialty;
|
||||||
{
|
|
||||||
h & specialty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h & specDeprecated;
|
|
||||||
h & specialtyDeprecated;
|
|
||||||
}
|
|
||||||
h & spells;
|
h & spells;
|
||||||
h & haveSpellBook;
|
h & haveSpellBook;
|
||||||
h & sex;
|
h & sex;
|
||||||
@ -141,14 +134,8 @@ public:
|
|||||||
h & iconSpecLarge;
|
h & iconSpecLarge;
|
||||||
h & portraitSmall;
|
h & portraitSmall;
|
||||||
h & portraitLarge;
|
h & portraitLarge;
|
||||||
if(version >= 759)
|
h & identifier;
|
||||||
{
|
h & battleImage;
|
||||||
h & identifier;
|
|
||||||
}
|
|
||||||
if(version >= 790)
|
|
||||||
{
|
|
||||||
h & battleImage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -211,16 +198,7 @@ public:
|
|||||||
h & identifier;
|
h & identifier;
|
||||||
h & name;
|
h & name;
|
||||||
h & faction;
|
h & faction;
|
||||||
if(version >= 800)
|
h & id;
|
||||||
{
|
|
||||||
h & id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui8 old_id = 0;
|
|
||||||
h & old_id;
|
|
||||||
id = HeroClassID(old_id);
|
|
||||||
}
|
|
||||||
h & defaultTavernChance;
|
h & defaultTavernChance;
|
||||||
h & primarySkillInitial;
|
h & primarySkillInitial;
|
||||||
h & primarySkillLowLevel;
|
h & primarySkillLowLevel;
|
||||||
@ -248,7 +226,7 @@ struct DLL_LINKAGE CObstacleInfo
|
|||||||
{
|
{
|
||||||
si32 ID;
|
si32 ID;
|
||||||
std::string defName;
|
std::string defName;
|
||||||
std::vector<ETerrainType> allowedTerrains;
|
std::vector<Terrain> allowedTerrains;
|
||||||
std::vector<BFieldType> allowedSpecialBfields;
|
std::vector<BFieldType> allowedSpecialBfields;
|
||||||
|
|
||||||
ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
|
ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
|
||||||
@ -257,7 +235,7 @@ struct DLL_LINKAGE CObstacleInfo
|
|||||||
|
|
||||||
std::vector<BattleHex> getBlocked(BattleHex hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
|
std::vector<BattleHex> getBlocked(BattleHex hex) const; //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
|
||||||
|
|
||||||
bool isAppropriate(ETerrainType terrainType, int specialBattlefield = -1) const;
|
bool isAppropriate(Terrain terrainType, int specialBattlefield = -1) const;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
@ -315,7 +293,7 @@ public:
|
|||||||
CHeroClassHandler classes;
|
CHeroClassHandler classes;
|
||||||
|
|
||||||
//default costs of going through terrains. -1 means terrain is impassable
|
//default costs of going through terrains. -1 means terrain is impassable
|
||||||
std::vector<int> terrCosts;
|
std::map<Terrain, int> terrCosts;
|
||||||
|
|
||||||
struct SBallisticsLevelInfo
|
struct SBallisticsLevelInfo
|
||||||
{
|
{
|
||||||
|
@ -163,6 +163,7 @@ set(lib_SRCS
|
|||||||
StartInfo.cpp
|
StartInfo.cpp
|
||||||
ResourceSet.cpp
|
ResourceSet.cpp
|
||||||
ScriptHandler.cpp
|
ScriptHandler.cpp
|
||||||
|
Terrain.cpp
|
||||||
VCMIDirs.cpp
|
VCMIDirs.cpp
|
||||||
VCMI_Lib.cpp
|
VCMI_Lib.cpp
|
||||||
|
|
||||||
@ -385,6 +386,7 @@ set(lib_HEADERS
|
|||||||
ScopeGuard.h
|
ScopeGuard.h
|
||||||
StartInfo.h
|
StartInfo.h
|
||||||
StringConstants.h
|
StringConstants.h
|
||||||
|
Terrain.h
|
||||||
UnlockGuard.h
|
UnlockGuard.h
|
||||||
VCMIDirs.h
|
VCMIDirs.h
|
||||||
vcmi_endian.h
|
vcmi_endian.h
|
||||||
|
@ -303,32 +303,9 @@ public:
|
|||||||
h & ALL_CREATURES_GET_DOUBLE_MONTHS;
|
h & ALL_CREATURES_GET_DOUBLE_MONTHS;
|
||||||
h & MAX_HEROES_AVAILABLE_PER_PLAYER;
|
h & MAX_HEROES_AVAILABLE_PER_PLAYER;
|
||||||
h & MAX_HEROES_ON_MAP_PER_PLAYER;
|
h & MAX_HEROES_ON_MAP_PER_PLAYER;
|
||||||
if(version >= 756)
|
h & WINNING_HERO_WITH_NO_TROOPS_RETREATS;
|
||||||
{
|
h & BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE;
|
||||||
h & WINNING_HERO_WITH_NO_TROOPS_RETREATS;
|
h & NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS;
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
WINNING_HERO_WITH_NO_TROOPS_RETREATS = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(version >= 776)
|
|
||||||
{
|
|
||||||
h & BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
BLACK_MARKET_MONTHLY_ARTIFACTS_CHANGE = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(version >= 791)
|
|
||||||
{
|
|
||||||
h & NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
NO_RANDOM_SPECIAL_WEEKS_AND_MONTHS = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} settings;
|
} settings;
|
||||||
|
|
||||||
|
@ -46,24 +46,19 @@ void NodeStorage::initialize(const PathfinderOptions & options, const CGameState
|
|||||||
for(pos.z=0; pos.z < sizes.z; ++pos.z)
|
for(pos.z=0; pos.z < sizes.z; ++pos.z)
|
||||||
{
|
{
|
||||||
const TerrainTile * tile = &gs->map->getTile(pos);
|
const TerrainTile * tile = &gs->map->getTile(pos);
|
||||||
switch(tile->terType)
|
if(tile->terType.isWater())
|
||||||
{
|
{
|
||||||
case ETerrainType::ROCK:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETerrainType::WATER:
|
|
||||||
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::SAIL, PathfinderUtil::evaluateAccessibility<ELayer::SAIL>(pos, tile, fow, player, gs));
|
||||||
if(useFlying)
|
if(useFlying)
|
||||||
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
||||||
if(useWaterWalking)
|
if(useWaterWalking)
|
||||||
resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::WATER, PathfinderUtil::evaluateAccessibility<ELayer::WATER>(pos, tile, fow, player, gs));
|
||||||
break;
|
}
|
||||||
|
if(tile->terType.isLand())
|
||||||
default:
|
{
|
||||||
resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::LAND, PathfinderUtil::evaluateAccessibility<ELayer::LAND>(pos, tile, fow, player, gs));
|
||||||
if(useFlying)
|
if(useFlying)
|
||||||
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
resetTile(pos, ELayer::AIR, PathfinderUtil::evaluateAccessibility<ELayer::AIR>(pos, tile, fow, player, gs));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1012,8 +1007,7 @@ bool CPathfinderHelper::passOneTurnLimitCheck(const PathNodeInfo & source) const
|
|||||||
|
|
||||||
TurnInfo::BonusCache::BonusCache(TConstBonusListPtr bl)
|
TurnInfo::BonusCache::BonusCache(TConstBonusListPtr bl)
|
||||||
{
|
{
|
||||||
noTerrainPenalty.reserve(ETerrainType::ROCK);
|
for(int i = 0; i < Terrain::Manager::terrains().size(); ++i)
|
||||||
for(int i = 0; i < ETerrainType::ROCK; i++)
|
|
||||||
{
|
{
|
||||||
noTerrainPenalty.push_back(static_cast<bool>(
|
noTerrainPenalty.push_back(static_cast<bool>(
|
||||||
bl->getFirst(Selector::type()(Bonus::NO_TERRAIN_PENALTY).And(Selector::subtype()(i)))));
|
bl->getFirst(Selector::type()(Bonus::NO_TERRAIN_PENALTY).And(Selector::subtype()(i)))));
|
||||||
@ -1179,7 +1173,7 @@ void CPathfinderHelper::getNeighbours(
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const TerrainTile & hlpt = map->getTile(hlp);
|
const TerrainTile & hlpt = map->getTile(hlp);
|
||||||
if(hlpt.terType == ETerrainType::ROCK)
|
if(!hlpt.terType.isPassable())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// //we cannot visit things from blocked tiles
|
// //we cannot visit things from blocked tiles
|
||||||
@ -1189,18 +1183,18 @@ void CPathfinderHelper::getNeighbours(
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
/// Following condition let us avoid diagonal movement over coast when sailing
|
/// Following condition let us avoid diagonal movement over coast when sailing
|
||||||
if(srct.terType == ETerrainType::WATER && limitCoastSailing && hlpt.terType == ETerrainType::WATER && dir.x && dir.y) //diagonal move through water
|
if(srct.terType.isWater() && limitCoastSailing && hlpt.terType.isWater() && dir.x && dir.y) //diagonal move through water
|
||||||
{
|
{
|
||||||
int3 hlp1 = tile,
|
int3 hlp1 = tile,
|
||||||
hlp2 = tile;
|
hlp2 = tile;
|
||||||
hlp1.x += dir.x;
|
hlp1.x += dir.x;
|
||||||
hlp2.y += dir.y;
|
hlp2.y += dir.y;
|
||||||
|
|
||||||
if(map->getTile(hlp1).terType != ETerrainType::WATER || map->getTile(hlp2).terType != ETerrainType::WATER)
|
if(map->getTile(hlp1).terType.isLand() || map->getTile(hlp2).terType.isLand())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(indeterminate(onLand) || onLand == (hlpt.terType != ETerrainType::WATER))
|
if(indeterminate(onLand) || onLand == hlpt.terType.isLand())
|
||||||
{
|
{
|
||||||
vec.push_back(hlp);
|
vec.push_back(hlp);
|
||||||
}
|
}
|
||||||
@ -1238,7 +1232,7 @@ int CPathfinderHelper::getMovementCost(
|
|||||||
{
|
{
|
||||||
ret = static_cast<int>(ret * (100.0 + ti->valOfBonuses(Bonus::FLYING_MOVEMENT)) / 100.0);
|
ret = static_cast<int>(ret * (100.0 + ti->valOfBonuses(Bonus::FLYING_MOVEMENT)) / 100.0);
|
||||||
}
|
}
|
||||||
else if(dt->terType == ETerrainType::WATER)
|
else if(dt->terType.isWater())
|
||||||
{
|
{
|
||||||
if(hero->boat && ct->hasFavorableWinds() && dt->hasFavorableWinds())
|
if(hero->boat && ct->hasFavorableWinds() && dt->hasFavorableWinds())
|
||||||
ret = static_cast<int>(ret * 0.666);
|
ret = static_cast<int>(ret * 0.666);
|
||||||
@ -1266,7 +1260,7 @@ int CPathfinderHelper::getMovementCost(
|
|||||||
{
|
{
|
||||||
std::vector<int3> vec;
|
std::vector<int3> vec;
|
||||||
vec.reserve(8); //optimization
|
vec.reserve(8); //optimization
|
||||||
getNeighbours(*dt, dst, vec, ct->terType != ETerrainType::WATER, true);
|
getNeighbours(*dt, dst, vec, ct->terType.isLand(), true);
|
||||||
for(auto & elem : vec)
|
for(auto & elem : vec)
|
||||||
{
|
{
|
||||||
int fcost = getMovementCost(dst, elem, nullptr, nullptr, left, false);
|
int fcost = getMovementCost(dst, elem, nullptr, nullptr, left, false);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "IGameCallback.h"
|
#include "IGameCallback.h"
|
||||||
#include "HeroBonus.h"
|
#include "HeroBonus.h"
|
||||||
#include "int3.h"
|
#include "int3.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
#include <boost/heap/fibonacci_heap.hpp>
|
#include <boost/heap/fibonacci_heap.hpp>
|
||||||
|
|
||||||
@ -521,7 +522,7 @@ struct DLL_LINKAGE TurnInfo
|
|||||||
TConstBonusListPtr bonuses;
|
TConstBonusListPtr bonuses;
|
||||||
mutable int maxMovePointsLand;
|
mutable int maxMovePointsLand;
|
||||||
mutable int maxMovePointsWater;
|
mutable int maxMovePointsWater;
|
||||||
ETerrainType::EETerrainType nativeTerrain;
|
Terrain nativeTerrain;
|
||||||
|
|
||||||
TurnInfo(const CGHeroInstance * Hero, const int Turn = 0);
|
TurnInfo(const CGHeroInstance * Hero, const int Turn = 0);
|
||||||
bool isLayerAvailable(const EPathfindingLayer layer) const;
|
bool isLayerAvailable(const EPathfindingLayer layer) const;
|
||||||
|
@ -67,14 +67,6 @@ public:
|
|||||||
h & dwellings;
|
h & dwellings;
|
||||||
h & quests;
|
h & quests;
|
||||||
h & visitedObjects;
|
h & visitedObjects;
|
||||||
|
|
||||||
if(version < 760)
|
|
||||||
{
|
|
||||||
//was: h & getBonusList();
|
|
||||||
BonusList junk;
|
|
||||||
h & junk;
|
|
||||||
}
|
|
||||||
|
|
||||||
h & status;
|
h & status;
|
||||||
h & daysWithoutCastle;
|
h & daysWithoutCastle;
|
||||||
h & enteredLosingCheatCode;
|
h & enteredLosingCheatCode;
|
||||||
|
@ -35,12 +35,9 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler & h, const int version)
|
template <typename Handler> void serialize(Handler & h, const int version)
|
||||||
{
|
{
|
||||||
h & description;
|
h & description;
|
||||||
if(version >= 785)
|
h & iconSmall;
|
||||||
{
|
h & iconMedium;
|
||||||
h & iconSmall;
|
h & iconLarge;
|
||||||
h & iconMedium;
|
|
||||||
h & iconLarge;
|
|
||||||
}
|
|
||||||
h & effects;
|
h & effects;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -78,10 +75,7 @@ public:
|
|||||||
h & id;
|
h & id;
|
||||||
h & identifier;
|
h & identifier;
|
||||||
h & name;
|
h & name;
|
||||||
if(version >= 785)
|
h & gainChance;
|
||||||
{
|
|
||||||
h & gainChance;
|
|
||||||
}
|
|
||||||
h & levels;
|
h & levels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ CStack::CStack(const CStackInstance * Base, PlayerColor O, int I, ui8 Side, Slot
|
|||||||
slot(S),
|
slot(S),
|
||||||
side(Side),
|
side(Side),
|
||||||
initialPosition(),
|
initialPosition(),
|
||||||
nativeTerrain(ETerrainType::WRONG)
|
nativeTerrain()
|
||||||
{
|
{
|
||||||
health.init(); //???
|
health.init(); //???
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ CStack::CStack(const CStackInstance * Base, PlayerColor O, int I, ui8 Side, Slot
|
|||||||
CStack::CStack()
|
CStack::CStack()
|
||||||
: CBonusSystemNode(STACK_BATTLE),
|
: CBonusSystemNode(STACK_BATTLE),
|
||||||
CUnitState(),
|
CUnitState(),
|
||||||
nativeTerrain(ETerrainType::WRONG)
|
nativeTerrain()
|
||||||
{
|
{
|
||||||
base = nullptr;
|
base = nullptr;
|
||||||
type = nullptr;
|
type = nullptr;
|
||||||
@ -328,11 +328,11 @@ bool CStack::canBeHealed() const
|
|||||||
bool CStack::isOnNativeTerrain() const
|
bool CStack::isOnNativeTerrain() const
|
||||||
{
|
{
|
||||||
//this code is called from CreatureTerrainLimiter::limit on battle start
|
//this code is called from CreatureTerrainLimiter::limit on battle start
|
||||||
auto res = nativeTerrain == ETerrainType::ANY_TERRAIN || nativeTerrain == battle->getTerrainType();
|
auto res = nativeTerrain == Terrain::ANY || nativeTerrain == battle->getTerrainType();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStack::isOnTerrain(int terrain) const
|
bool CStack::isOnTerrain(const Terrain & terrain) const
|
||||||
{
|
{
|
||||||
return battle->getTerrainType() == terrain;
|
return battle->getTerrainType() == terrain;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "CCreatureHandler.h" //todo: remove
|
#include "CCreatureHandler.h" //todo: remove
|
||||||
#include "battle/BattleHex.h"
|
#include "battle/BattleHex.h"
|
||||||
#include "mapObjects/CGHeroInstance.h" // for commander serialization
|
#include "mapObjects/CGHeroInstance.h" // for commander serialization
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
#include "battle/CUnitState.h"
|
#include "battle/CUnitState.h"
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ public:
|
|||||||
|
|
||||||
ui32 ID; //unique ID of stack
|
ui32 ID; //unique ID of stack
|
||||||
const CCreature * type;
|
const CCreature * type;
|
||||||
ETerrainType::EETerrainType nativeTerrain; //tmp variable to save native terrain value on battle init
|
Terrain nativeTerrain; //tmp variable to save native terrain value on battle init
|
||||||
ui32 baseAmount;
|
ui32 baseAmount;
|
||||||
|
|
||||||
PlayerColor owner; //owner - player color (255 for neutrals)
|
PlayerColor owner; //owner - player color (255 for neutrals)
|
||||||
@ -50,7 +51,7 @@ public:
|
|||||||
|
|
||||||
bool canBeHealed() const; //for first aid tent - only harmed stacks that are not war machines
|
bool canBeHealed() const; //for first aid tent - only harmed stacks that are not war machines
|
||||||
bool isOnNativeTerrain() const;
|
bool isOnNativeTerrain() const;
|
||||||
bool isOnTerrain(int terrain) const;
|
bool isOnTerrain(const Terrain & terrain) const;
|
||||||
|
|
||||||
ui32 level() const;
|
ui32 level() const;
|
||||||
si32 magicResistance() const override; //include aura of resistance
|
si32 magicResistance() const override; //include aura of resistance
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
|
|
||||||
const int NAMES_PER_TOWN=16; // number of town names per faction in H3 files. Json can define any number
|
const int NAMES_PER_TOWN=16; // number of town names per faction in H3 files. Json can define any number
|
||||||
|
|
||||||
|
const Terrain CTownHandler::defaultGoodTerrain{"grass"};
|
||||||
|
const Terrain CTownHandler::defaultEvilTerrain{"lava"};
|
||||||
|
const Terrain CTownHandler::defaultNeutralTerrain{"rough"};
|
||||||
|
|
||||||
const std::map<std::string, CBuilding::EBuildMode> CBuilding::MODES =
|
const std::map<std::string, CBuilding::EBuildMode> CBuilding::MODES =
|
||||||
{
|
{
|
||||||
{ "normal", CBuilding::BUILD_NORMAL },
|
{ "normal", CBuilding::BUILD_NORMAL },
|
||||||
@ -77,135 +81,11 @@ si32 CBuilding::getDistance(BuildingID buildID) const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBuilding::deserializeFix()
|
|
||||||
{
|
|
||||||
//default value for mode was broken, have to fix it here for old saves (v777 and older)
|
|
||||||
switch(mode)
|
|
||||||
{
|
|
||||||
case BUILD_NORMAL:
|
|
||||||
case BUILD_AUTO:
|
|
||||||
case BUILD_SPECIAL:
|
|
||||||
case BUILD_GRAIL:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
mode = BUILD_NORMAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CBuilding::addNewBonus(std::shared_ptr<Bonus> b, BonusList & bonusList)
|
void CBuilding::addNewBonus(std::shared_ptr<Bonus> b, BonusList & bonusList)
|
||||||
{
|
{
|
||||||
bonusList.push_back(b);
|
bonusList.push_back(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
const JsonNode & CBuilding::getCurrentFactionForUpdateRoutine() const
|
|
||||||
{
|
|
||||||
const auto & faction = town->faction->identifier;
|
|
||||||
const auto & factionsContent = (*VLC->modh->content)["factions"];
|
|
||||||
const auto & coreData = factionsContent.modData.at("core");
|
|
||||||
const auto & coreFactions = coreData.modData;
|
|
||||||
const auto & currentFaction = coreFactions[faction];
|
|
||||||
|
|
||||||
if(currentFaction.isNull())
|
|
||||||
{
|
|
||||||
const auto index = faction.find(':');
|
|
||||||
const std::string factionDir = index == std::string::npos ? faction : faction.substr(0, index);
|
|
||||||
const auto it = factionsContent.modData.find(factionDir);
|
|
||||||
|
|
||||||
if(it == factionsContent.modData.end())
|
|
||||||
{
|
|
||||||
logMod->warn("Warning: Update old save failed: Faction: '%s' is not found.", factionDir);
|
|
||||||
return currentFaction;
|
|
||||||
}
|
|
||||||
const std::string modFaction = index == std::string::npos ? faction : faction.substr(index + 1);
|
|
||||||
return it->second.modData[modFaction];
|
|
||||||
}
|
|
||||||
return currentFaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CBuilding::update792()
|
|
||||||
{
|
|
||||||
subId = BuildingSubID::NONE;
|
|
||||||
height = ETowerHeight::HEIGHT_NO_TOWER;
|
|
||||||
|
|
||||||
if(!bid.IsSpecialOrGrail() || town == nullptr || town->faction == nullptr || town->faction->identifier.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto buildingName = CTownHandler::getMappedValue<std::string, BuildingID>(bid, std::string(), MappedKeys::BUILDING_TYPES_TO_NAMES);
|
|
||||||
|
|
||||||
if(buildingName.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto & currentFaction = getCurrentFactionForUpdateRoutine();
|
|
||||||
|
|
||||||
if(!currentFaction.isNull() && currentFaction.getType() == JsonNode::JsonType::DATA_STRUCT)
|
|
||||||
{
|
|
||||||
const auto & buildings = currentFaction["town"]["buildings"];
|
|
||||||
const auto & currentBuilding = buildings[buildingName];
|
|
||||||
|
|
||||||
subId = CTownHandler::getMappedValue<BuildingSubID::EBuildingSubID>(currentBuilding["type"], BuildingSubID::NONE, MappedKeys::SPECIAL_BUILDINGS);
|
|
||||||
height = subId == BuildingSubID::LOOKOUT_TOWER || bid == BuildingID::GRAIL
|
|
||||||
? CTownHandler::getMappedValue<CBuilding::ETowerHeight>(currentBuilding["height"], CBuilding::HEIGHT_NO_TOWER, CBuilding::TOWER_TYPES)
|
|
||||||
: height = CBuilding::HEIGHT_NO_TOWER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CBuilding::update794()
|
|
||||||
{
|
|
||||||
if(bid == BuildingID::TAVERN || subId == BuildingSubID::BROTHERHOOD_OF_SWORD)
|
|
||||||
{
|
|
||||||
VLC->townh->addBonusesForVanilaBuilding(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(!bid.IsSpecialOrGrail())
|
|
||||||
return;
|
|
||||||
|
|
||||||
VLC->townh->addBonusesForVanilaBuilding(this);
|
|
||||||
|
|
||||||
if(!buildingBonuses.empty() //addBonusesForVanilaBuilding has done all work
|
|
||||||
|| town->faction == nullptr //or faction data is not valid
|
|
||||||
|| town->faction->identifier.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto buildingName = CTownHandler::getMappedValue<std::string, BuildingID>(bid, std::string(), MappedKeys::BUILDING_TYPES_TO_NAMES, false);
|
|
||||||
|
|
||||||
if(buildingName.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto & currentFaction = getCurrentFactionForUpdateRoutine();
|
|
||||||
|
|
||||||
if(currentFaction.isNull() || currentFaction.getType() != JsonNode::JsonType::DATA_STRUCT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto & buildings = currentFaction["town"]["buildings"];
|
|
||||||
const auto & currentBuilding = buildings[buildingName];
|
|
||||||
|
|
||||||
CTownHandler::loadSpecialBuildingBonuses(currentBuilding["bonuses"], buildingBonuses, this);
|
|
||||||
CTownHandler::loadSpecialBuildingBonuses(currentBuilding["onVisitBonuses"], onVisitBonuses, this);
|
|
||||||
|
|
||||||
if(!onVisitBonuses.empty())
|
|
||||||
{
|
|
||||||
if(subId == BuildingSubID::NONE)
|
|
||||||
subId = BuildingSubID::CUSTOM_VISITING_BONUS;
|
|
||||||
|
|
||||||
for(auto & bonus : onVisitBonuses)
|
|
||||||
bonus->sid = Bonus::getSid32(town->faction->index, bid);
|
|
||||||
}
|
|
||||||
const auto & overriddenBids = currentBuilding["overrides"];
|
|
||||||
|
|
||||||
if(overriddenBids.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto scope = town->getBuildingScope();
|
|
||||||
|
|
||||||
for(auto b : overriddenBids.Vector())
|
|
||||||
{
|
|
||||||
auto bid = BuildingID(VLC->modh->identifiers.getIdentifier(scope, b).get());
|
|
||||||
overrideBids.insert(bid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CFaction::CFaction()
|
CFaction::CFaction()
|
||||||
{
|
{
|
||||||
town = nullptr;
|
town = nullptr;
|
||||||
@ -1062,9 +942,9 @@ void CTownHandler::loadPuzzle(CFaction &faction, const JsonNode &source)
|
|||||||
assert(faction.puzzleMap.size() == GameConstants::PUZZLE_MAP_PIECES);
|
assert(faction.puzzleMap.size() == GameConstants::PUZZLE_MAP_PIECES);
|
||||||
}
|
}
|
||||||
|
|
||||||
ETerrainType::EETerrainType CTownHandler::getDefaultTerrainForAlignment(EAlignment::EAlignment alignment) const
|
Terrain CTownHandler::getDefaultTerrainForAlignment(EAlignment::EAlignment alignment) const
|
||||||
{
|
{
|
||||||
ETerrainType::EETerrainType terrain = defaultGoodTerrain;
|
Terrain terrain = defaultGoodTerrain;
|
||||||
|
|
||||||
switch(alignment)
|
switch(alignment)
|
||||||
{
|
{
|
||||||
@ -1095,19 +975,15 @@ CFaction * CTownHandler::loadFromJson(const std::string & scope, const JsonNode
|
|||||||
faction->alignment = EAlignment::NEUTRAL;
|
faction->alignment = EAlignment::NEUTRAL;
|
||||||
else
|
else
|
||||||
faction->alignment = static_cast<EAlignment::EAlignment>(alignment);
|
faction->alignment = static_cast<EAlignment::EAlignment>(alignment);
|
||||||
|
|
||||||
auto nativeTerrain = source["nativeTerrain"];
|
|
||||||
int terrainNum = nativeTerrain.isNull()
|
|
||||||
? -1
|
|
||||||
: vstd::find_pos(GameConstants::TERRAIN_NAMES, nativeTerrain.String());
|
|
||||||
|
|
||||||
auto preferUndergound = source["preferUndergroundPlacement"];
|
auto preferUndergound = source["preferUndergroundPlacement"];
|
||||||
faction->preferUndergroundPlacement = preferUndergound.isNull() ? false : preferUndergound.Bool();
|
faction->preferUndergroundPlacement = preferUndergound.isNull() ? false : preferUndergound.Bool();
|
||||||
|
|
||||||
//Contructor is not called here, but operator=
|
//Contructor is not called here, but operator=
|
||||||
faction->nativeTerrain = terrainNum < 0
|
auto nativeTerrain = source["nativeTerrain"];
|
||||||
|
faction->nativeTerrain = nativeTerrain.isNull()
|
||||||
? getDefaultTerrainForAlignment(faction->alignment)
|
? getDefaultTerrainForAlignment(faction->alignment)
|
||||||
: static_cast<ETerrainType::EETerrainType>(terrainNum);
|
: Terrain(nativeTerrain.String());
|
||||||
|
|
||||||
if (!source["town"].isNull())
|
if (!source["town"].isNull())
|
||||||
{
|
{
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "LogicalExpression.h"
|
#include "LogicalExpression.h"
|
||||||
#include "battle/BattleHex.h"
|
#include "battle/BattleHex.h"
|
||||||
#include "HeroBonus.h"
|
#include "HeroBonus.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
class CLegacyConfigParser;
|
class CLegacyConfigParser;
|
||||||
class JsonNode;
|
class JsonNode;
|
||||||
@ -111,8 +112,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addNewBonus(std::shared_ptr<Bonus> b, BonusList & bonusList);
|
void addNewBonus(std::shared_ptr<Bonus> b, BonusList & bonusList);
|
||||||
void update792();
|
|
||||||
void update794();
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
@ -126,33 +125,14 @@ public:
|
|||||||
h & requirements;
|
h & requirements;
|
||||||
h & upgrade;
|
h & upgrade;
|
||||||
h & mode;
|
h & mode;
|
||||||
|
h & subId;
|
||||||
if(version >= 792)
|
h & height;
|
||||||
{
|
h & overrideBids;
|
||||||
h & subId;
|
h & buildingBonuses;
|
||||||
h & height;
|
h & onVisitBonuses;
|
||||||
}
|
|
||||||
if(!h.saving && version < 793)
|
|
||||||
update792(); //adjust height, subId
|
|
||||||
|
|
||||||
if(version >= 794)
|
|
||||||
{
|
|
||||||
h & overrideBids;
|
|
||||||
h & buildingBonuses;
|
|
||||||
h & onVisitBonuses;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
update794(); //populate overrideBids, buildingBonuses, onVisitBonuses
|
|
||||||
|
|
||||||
if(!h.saving)
|
|
||||||
deserializeFix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class CTownHandler;
|
friend class CTownHandler;
|
||||||
|
|
||||||
private:
|
|
||||||
void deserializeFix();
|
|
||||||
const JsonNode & getCurrentFactionForUpdateRoutine() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This is structure used only by client
|
/// This is structure used only by client
|
||||||
@ -205,7 +185,7 @@ public:
|
|||||||
|
|
||||||
TFaction index;
|
TFaction index;
|
||||||
|
|
||||||
ETerrainType nativeTerrain;
|
Terrain nativeTerrain;
|
||||||
EAlignment::EAlignment alignment;
|
EAlignment::EAlignment alignment;
|
||||||
bool preferUndergroundPlacement;
|
bool preferUndergroundPlacement;
|
||||||
|
|
||||||
@ -356,14 +336,7 @@ public:
|
|||||||
h & warMachine;
|
h & warMachine;
|
||||||
h & clientInfo;
|
h & clientInfo;
|
||||||
h & moatDamage;
|
h & moatDamage;
|
||||||
if(version >= 758)
|
h & moatHexes;
|
||||||
{
|
|
||||||
h & moatHexes;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
moatHexes = defaultMoatHexes();
|
|
||||||
}
|
|
||||||
h & defaultTavernChance;
|
h & defaultTavernChance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,9 +358,9 @@ class DLL_LINKAGE CTownHandler : public CHandlerBase<FactionID, Faction, CFactio
|
|||||||
std::vector<BuildingRequirementsHelper> requirementsToLoad;
|
std::vector<BuildingRequirementsHelper> requirementsToLoad;
|
||||||
std::vector<BuildingRequirementsHelper> overriddenBidsToLoad; //list of buildings, which bonuses should be overridden.
|
std::vector<BuildingRequirementsHelper> overriddenBidsToLoad; //list of buildings, which bonuses should be overridden.
|
||||||
|
|
||||||
const static ETerrainType::EETerrainType defaultGoodTerrain = ETerrainType::EETerrainType::GRASS;
|
const static Terrain defaultGoodTerrain;
|
||||||
const static ETerrainType::EETerrainType defaultEvilTerrain = ETerrainType::EETerrainType::LAVA;
|
const static Terrain defaultEvilTerrain;
|
||||||
const static ETerrainType::EETerrainType defaultNeutralTerrain = ETerrainType::EETerrainType::ROUGH;
|
const static Terrain defaultNeutralTerrain;
|
||||||
|
|
||||||
static TPropagatorPtr & emptyPropagator();
|
static TPropagatorPtr & emptyPropagator();
|
||||||
|
|
||||||
@ -418,7 +391,7 @@ class DLL_LINKAGE CTownHandler : public CHandlerBase<FactionID, Faction, CFactio
|
|||||||
|
|
||||||
void loadPuzzle(CFaction & faction, const JsonNode & source);
|
void loadPuzzle(CFaction & faction, const JsonNode & source);
|
||||||
|
|
||||||
ETerrainType::EETerrainType getDefaultTerrainForAlignment(EAlignment::EAlignment aligment) const;
|
Terrain getDefaultTerrainForAlignment(EAlignment::EAlignment aligment) const;
|
||||||
void loadRandomFaction();
|
void loadRandomFaction();
|
||||||
|
|
||||||
|
|
||||||
@ -450,15 +423,7 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & objects;
|
h & objects;
|
||||||
|
h & randomTown;
|
||||||
if(version >= 770)
|
|
||||||
{
|
|
||||||
h & randomTown;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
loadRandomFaction();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -236,38 +236,6 @@ std::ostream & operator<<(std::ostream & os, const EActionType actionType)
|
|||||||
else return os << it->second;
|
else return os << it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & os, const ETerrainType terrainType)
|
|
||||||
{
|
|
||||||
static const std::map<ETerrainType::EETerrainType, std::string> terrainTypeToString =
|
|
||||||
{
|
|
||||||
#define DEFINE_ELEMENT(element) {ETerrainType::element, #element}
|
|
||||||
DEFINE_ELEMENT(WRONG),
|
|
||||||
DEFINE_ELEMENT(BORDER),
|
|
||||||
DEFINE_ELEMENT(DIRT),
|
|
||||||
DEFINE_ELEMENT(SAND),
|
|
||||||
DEFINE_ELEMENT(GRASS),
|
|
||||||
DEFINE_ELEMENT(SNOW),
|
|
||||||
DEFINE_ELEMENT(SWAMP),
|
|
||||||
DEFINE_ELEMENT(ROUGH),
|
|
||||||
DEFINE_ELEMENT(SUBTERRANEAN),
|
|
||||||
DEFINE_ELEMENT(LAVA),
|
|
||||||
DEFINE_ELEMENT(WATER),
|
|
||||||
DEFINE_ELEMENT(ROCK)
|
|
||||||
#undef DEFINE_ELEMENT
|
|
||||||
};
|
|
||||||
|
|
||||||
auto it = terrainTypeToString.find(terrainType.num);
|
|
||||||
if (it == terrainTypeToString.end()) return os << "<Unknown type>";
|
|
||||||
else return os << it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ETerrainType::toString() const
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << *this;
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & os, const EPathfindingLayer pathfindingLayer)
|
std::ostream & operator<<(std::ostream & os, const EPathfindingLayer pathfindingLayer)
|
||||||
{
|
{
|
||||||
static const std::map<EPathfindingLayer::EEPathfindingLayer, std::string> pathfinderLayerToString
|
static const std::map<EPathfindingLayer::EEPathfindingLayer, std::string> pathfinderLayerToString
|
||||||
|
@ -61,7 +61,6 @@ namespace GameConstants
|
|||||||
|
|
||||||
const int SKILL_QUANTITY=28;
|
const int SKILL_QUANTITY=28;
|
||||||
const int PRIMARY_SKILLS=4;
|
const int PRIMARY_SKILLS=4;
|
||||||
const int TERRAIN_TYPES=10;
|
|
||||||
const int RESOURCE_QUANTITY=8;
|
const int RESOURCE_QUANTITY=8;
|
||||||
const int HEROES_PER_TYPE=8; //amount of heroes of each type
|
const int HEROES_PER_TYPE=8; //amount of heroes of each type
|
||||||
|
|
||||||
@ -678,21 +677,8 @@ enum class ETeleportChannelType
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace ERiverType
|
static std::vector<std::string> RIVER_NAMES {"", "rw", "ri", "rm", "rl"};
|
||||||
{
|
static std::vector<std::string> ROAD_NAMES {"", "pd", "pg", "pc"};
|
||||||
enum ERiverType
|
|
||||||
{
|
|
||||||
NO_RIVER, CLEAR_RIVER, ICY_RIVER, MUDDY_RIVER, LAVA_RIVER
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ERoadType
|
|
||||||
{
|
|
||||||
enum ERoadType
|
|
||||||
{
|
|
||||||
NO_ROAD, DIRT_ROAD, GRAVEL_ROAD, COBBLESTONE_ROAD
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class Obj
|
class Obj
|
||||||
{
|
{
|
||||||
@ -912,36 +898,6 @@ enum class EActionType : int32_t
|
|||||||
|
|
||||||
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EActionType actionType);
|
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EActionType actionType);
|
||||||
|
|
||||||
class DLL_LINKAGE ETerrainType
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum EETerrainType
|
|
||||||
{
|
|
||||||
ANY_TERRAIN = -3,
|
|
||||||
WRONG = -2, BORDER = -1, DIRT, SAND, GRASS, SNOW, SWAMP,
|
|
||||||
ROUGH, SUBTERRANEAN, LAVA, WATER, ROCK // ROCK is also intended to be max value.
|
|
||||||
};
|
|
||||||
|
|
||||||
ETerrainType(EETerrainType _num = WRONG) : num(_num)
|
|
||||||
{}
|
|
||||||
|
|
||||||
ETerrainType& operator=(EETerrainType _num)
|
|
||||||
{
|
|
||||||
num = _num;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID_LIKE_CLASS_COMMON(ETerrainType, EETerrainType)
|
|
||||||
|
|
||||||
EETerrainType num;
|
|
||||||
|
|
||||||
std::string toString() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const ETerrainType terrainType);
|
|
||||||
|
|
||||||
ID_LIKE_OPERATORS(ETerrainType, ETerrainType::EETerrainType)
|
|
||||||
|
|
||||||
class DLL_LINKAGE EDiggingStatus
|
class DLL_LINKAGE EDiggingStatus
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -2078,13 +2078,8 @@ bool CPropagatorNodeType::shouldBeAttached(CBonusSystemNode *dest)
|
|||||||
return nodeType == dest->getNodeType();
|
return nodeType == dest->getNodeType();
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureTerrainLimiter::CreatureTerrainLimiter(int TerrainType)
|
|
||||||
: terrainType(TerrainType)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CreatureTerrainLimiter::CreatureTerrainLimiter()
|
CreatureTerrainLimiter::CreatureTerrainLimiter()
|
||||||
: terrainType(-1)
|
: terrainType()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2094,7 +2089,7 @@ int CreatureTerrainLimiter::limit(const BonusLimitationContext &context) const
|
|||||||
const CStack *stack = retrieveStackBattle(&context.node);
|
const CStack *stack = retrieveStackBattle(&context.node);
|
||||||
if(stack)
|
if(stack)
|
||||||
{
|
{
|
||||||
if(terrainType == -1)//terrainType not specified = native
|
if(terrainType.isNative())//terrainType not specified = native
|
||||||
return !stack->isOnNativeTerrain();
|
return !stack->isOnNativeTerrain();
|
||||||
return !stack->isOnTerrain(terrainType);
|
return !stack->isOnTerrain(terrainType);
|
||||||
}
|
}
|
||||||
@ -2105,7 +2100,7 @@ int CreatureTerrainLimiter::limit(const BonusLimitationContext &context) const
|
|||||||
std::string CreatureTerrainLimiter::toString() const
|
std::string CreatureTerrainLimiter::toString() const
|
||||||
{
|
{
|
||||||
boost::format fmt("CreatureTerrainLimiter(terrainType=%s)");
|
boost::format fmt("CreatureTerrainLimiter(terrainType=%s)");
|
||||||
fmt % (terrainType >= 0 ? GameConstants::TERRAIN_NAMES[terrainType] : "native");
|
fmt % (terrainType.isNative() ? "native" : static_cast<std::string>(terrainType));
|
||||||
return fmt.str();
|
return fmt.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2114,8 +2109,8 @@ JsonNode CreatureTerrainLimiter::toJsonNode() const
|
|||||||
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
|
JsonNode root(JsonNode::JsonType::DATA_STRUCT);
|
||||||
|
|
||||||
root["type"].String() = "CREATURE_TERRAIN_LIMITER";
|
root["type"].String() = "CREATURE_TERRAIN_LIMITER";
|
||||||
if(terrainType >= 0)
|
if(!terrainType.isNative())
|
||||||
root["parameters"].Vector().push_back(JsonUtils::stringNode(GameConstants::TERRAIN_NAMES[terrainType]));
|
root["parameters"].Vector().push_back(JsonUtils::stringNode(terrainType));
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "GameConstants.h"
|
#include "GameConstants.h"
|
||||||
#include "JsonNode.h"
|
#include "JsonNode.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
class CCreature;
|
class CCreature;
|
||||||
struct Bonus;
|
struct Bonus;
|
||||||
@ -438,36 +439,15 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
|
|||||||
h & val;
|
h & val;
|
||||||
h & sid;
|
h & sid;
|
||||||
h & description;
|
h & description;
|
||||||
if(version >= 783)
|
h & additionalInfo;
|
||||||
{
|
|
||||||
h & additionalInfo;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
additionalInfo.resize(1, -1);
|
|
||||||
h & additionalInfo[0];
|
|
||||||
}
|
|
||||||
h & turnsRemain;
|
h & turnsRemain;
|
||||||
h & valType;
|
h & valType;
|
||||||
if(version >= 784)
|
h & stacking;
|
||||||
{
|
|
||||||
h & stacking;
|
|
||||||
}
|
|
||||||
h & effectRange;
|
h & effectRange;
|
||||||
h & limiter;
|
h & limiter;
|
||||||
h & propagator;
|
h & propagator;
|
||||||
if(version >= 781)
|
h & updater;
|
||||||
{
|
h & propagationUpdater;
|
||||||
h & updater;
|
|
||||||
}
|
|
||||||
if(version >= 801)
|
|
||||||
{
|
|
||||||
h & propagationUpdater;
|
|
||||||
}
|
|
||||||
if(version < 801 && !h.saving) //Opposite Side bonuses are introduced
|
|
||||||
{
|
|
||||||
updateOppositeBonuses();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Ptr>
|
template <typename Ptr>
|
||||||
@ -999,10 +979,7 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler & h, const int version)
|
template <typename Handler> void serialize(Handler & h, const int version)
|
||||||
{
|
{
|
||||||
h & static_cast<ILimiter&>(*this);
|
h & static_cast<ILimiter&>(*this);
|
||||||
if(version >= 786)
|
h & limiters;
|
||||||
{
|
|
||||||
h & limiters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1081,9 +1058,9 @@ public:
|
|||||||
class DLL_LINKAGE CreatureTerrainLimiter : public ILimiter //applies only to creatures that are on specified terrain, default native terrain
|
class DLL_LINKAGE CreatureTerrainLimiter : public ILimiter //applies only to creatures that are on specified terrain, default native terrain
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int terrainType;
|
Terrain terrainType;
|
||||||
CreatureTerrainLimiter();
|
CreatureTerrainLimiter();
|
||||||
CreatureTerrainLimiter(int TerrainType);
|
CreatureTerrainLimiter(const Terrain& terrain);
|
||||||
|
|
||||||
int limit(const BonusLimitationContext &context) const override;
|
int limit(const BonusLimitationContext &context) const override;
|
||||||
virtual std::string toString() const override;
|
virtual std::string toString() const override;
|
||||||
|
@ -49,7 +49,7 @@ void CPrivilegedInfoCallback::getFreeTiles(std::vector<int3> & tiles) const
|
|||||||
for (int yd = 0; yd < gs->map->height; yd++)
|
for (int yd = 0; yd < gs->map->height; yd++)
|
||||||
{
|
{
|
||||||
tinfo = getTile(int3 (xd,yd,zd));
|
tinfo = getTile(int3 (xd,yd,zd));
|
||||||
if (tinfo->terType != ETerrainType::WATER && tinfo->terType != ETerrainType::ROCK && !tinfo->blocked) //land and free
|
if (tinfo->terType.isLand() && tinfo->terType.isPassable() && !tinfo->blocked) //land and free
|
||||||
tiles.push_back (int3 (xd,yd,zd));
|
tiles.push_back (int3 (xd,yd,zd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,8 +116,8 @@ void CPrivilegedInfoCallback::getAllTiles(std::unordered_set<int3, ShashInt3> &
|
|||||||
{
|
{
|
||||||
for (int yd = 0; yd < gs->map->height; yd++)
|
for (int yd = 0; yd < gs->map->height; yd++)
|
||||||
{
|
{
|
||||||
if ((getTile (int3 (xd,yd,zd))->terType == ETerrainType::WATER && water)
|
if ((getTile (int3 (xd,yd,zd))->terType.isWater() && water)
|
||||||
|| (getTile (int3 (xd,yd,zd))->terType != ETerrainType::WATER && land))
|
|| (getTile (int3 (xd,yd,zd))->terType.isLand() && land))
|
||||||
tiles.insert(int3(xd,yd,zd));
|
tiles.insert(int3(xd,yd,zd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//Internal class for string -> JsonNode conversion
|
//Internal class for string -> JsonNode conversion
|
||||||
class JsonParser
|
class DLL_LINKAGE JsonParser
|
||||||
{
|
{
|
||||||
std::string errors; // Contains description of all encountered errors
|
std::string errors; // Contains description of all encountered errors
|
||||||
constString input; // Input data
|
constString input; // Input data
|
||||||
|
@ -59,6 +59,15 @@ JsonNode::JsonNode(const ResourceID & fileURI):
|
|||||||
*this = parser.parse(fileURI.getName());
|
*this = parser.parse(fileURI.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JsonNode::JsonNode(const std::string & idx, const ResourceID & fileURI):
|
||||||
|
type(JsonType::DATA_NULL)
|
||||||
|
{
|
||||||
|
auto file = CResourceHandler::get(idx)->load(fileURI)->readAll();
|
||||||
|
|
||||||
|
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second);
|
||||||
|
*this = parser.parse(fileURI.getName());
|
||||||
|
}
|
||||||
|
|
||||||
JsonNode::JsonNode(ResourceID && fileURI, bool &isValidSyntax):
|
JsonNode::JsonNode(ResourceID && fileURI, bool &isValidSyntax):
|
||||||
type(JsonType::DATA_NULL)
|
type(JsonType::DATA_NULL)
|
||||||
{
|
{
|
||||||
@ -711,7 +720,8 @@ std::shared_ptr<ILimiter> JsonUtils::parseLimiter(const JsonNode & limiter)
|
|||||||
{
|
{
|
||||||
VLC->modh->identifiers.requestIdentifier("terrain", parameters[0], [=](si32 terrain)
|
VLC->modh->identifiers.requestIdentifier("terrain", parameters[0], [=](si32 terrain)
|
||||||
{
|
{
|
||||||
terrainLimiter->terrainType = terrain;
|
//TODO: support limiters
|
||||||
|
//terrainLimiter->terrainType = terrain;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return terrainLimiter;
|
return terrainLimiter;
|
||||||
|
@ -60,6 +60,7 @@ public:
|
|||||||
//Create tree from JSON file
|
//Create tree from JSON file
|
||||||
explicit JsonNode(ResourceID && fileURI);
|
explicit JsonNode(ResourceID && fileURI);
|
||||||
explicit JsonNode(const ResourceID & fileURI);
|
explicit JsonNode(const ResourceID & fileURI);
|
||||||
|
explicit JsonNode(const std::string& idx, const ResourceID & fileURI);
|
||||||
explicit JsonNode(ResourceID && fileURI, bool & isValidSyntax);
|
explicit JsonNode(ResourceID && fileURI, bool & isValidSyntax);
|
||||||
//Copy c-tor
|
//Copy c-tor
|
||||||
JsonNode(const JsonNode ©);
|
JsonNode(const JsonNode ©);
|
||||||
@ -127,10 +128,7 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & meta;
|
h & meta;
|
||||||
if(version >= 782)
|
h & flags;
|
||||||
{
|
|
||||||
h & flags;
|
|
||||||
}
|
|
||||||
h & type;
|
h & type;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
@ -152,10 +150,7 @@ public:
|
|||||||
h & data.Struct;
|
h & data.Struct;
|
||||||
break;
|
break;
|
||||||
case JsonType::DATA_INTEGER:
|
case JsonType::DATA_INTEGER:
|
||||||
if(version >= 770)
|
h & data.Integer;
|
||||||
{
|
|
||||||
h & data.Integer;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,13 +699,13 @@ DLL_LINKAGE void GiveHero::applyGs(CGameState *gs)
|
|||||||
|
|
||||||
DLL_LINKAGE void NewObject::applyGs(CGameState *gs)
|
DLL_LINKAGE void NewObject::applyGs(CGameState *gs)
|
||||||
{
|
{
|
||||||
ETerrainType terrainType;
|
Terrain terrainType;
|
||||||
|
|
||||||
if(ID == Obj::BOAT && !gs->isInTheMap(pos)) //special handling for bug #3060 - pos outside map but visitablePos is not
|
if(ID == Obj::BOAT && !gs->isInTheMap(pos)) //special handling for bug #3060 - pos outside map but visitablePos is not
|
||||||
{
|
{
|
||||||
CGObjectInstance testObject = CGObjectInstance();
|
CGObjectInstance testObject = CGObjectInstance();
|
||||||
testObject.pos = pos;
|
testObject.pos = pos;
|
||||||
testObject.appearance = VLC->objtypeh->getHandlerFor(ID, subID)->getTemplates(ETerrainType::WATER).front();
|
testObject.appearance = VLC->objtypeh->getHandlerFor(ID, subID)->getTemplates(Terrain("water")).front();
|
||||||
|
|
||||||
const int3 previousXAxisTile = int3(pos.x - 1, pos.y, pos.z);
|
const int3 previousXAxisTile = int3(pos.x - 1, pos.y, pos.z);
|
||||||
assert(gs->isInTheMap(previousXAxisTile) && (testObject.visitablePos() == previousXAxisTile));
|
assert(gs->isInTheMap(previousXAxisTile) && (testObject.visitablePos() == previousXAxisTile));
|
||||||
@ -722,7 +722,7 @@ DLL_LINKAGE void NewObject::applyGs(CGameState *gs)
|
|||||||
{
|
{
|
||||||
case Obj::BOAT:
|
case Obj::BOAT:
|
||||||
o = new CGBoat();
|
o = new CGBoat();
|
||||||
terrainType = ETerrainType::WATER; //TODO: either boat should only spawn on water, or all water objects should be handled this way
|
terrainType = Terrain("water"); //TODO: either boat should only spawn on water, or all water objects should be handled this way
|
||||||
break;
|
break;
|
||||||
case Obj::MONSTER: //probably more options will be needed
|
case Obj::MONSTER: //probably more options will be needed
|
||||||
o = new CGCreature();
|
o = new CGCreature();
|
||||||
|
@ -59,13 +59,13 @@ namespace PathfinderUtil
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ELayer::WATER:
|
case ELayer::WATER:
|
||||||
if(tinfo->blocked || tinfo->terType != ETerrainType::WATER)
|
if(tinfo->blocked || tinfo->terType.isLand())
|
||||||
return CGPathNode::BLOCKED;
|
return CGPathNode::BLOCKED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELayer::AIR:
|
case ELayer::AIR:
|
||||||
if(tinfo->blocked || tinfo->terType == ETerrainType::WATER)
|
if(tinfo->blocked || tinfo->terType.isLand())
|
||||||
return CGPathNode::FLYABLE;
|
return CGPathNode::FLYABLE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -56,19 +56,7 @@ struct DLL_LINKAGE PlayerSettings
|
|||||||
h & color;
|
h & color;
|
||||||
h & handicap;
|
h & handicap;
|
||||||
h & name;
|
h & name;
|
||||||
if(version < 787)
|
h & connectedPlayerIDs;
|
||||||
{
|
|
||||||
ui8 oldConnectedId = 0;
|
|
||||||
h & oldConnectedId;
|
|
||||||
if(oldConnectedId)
|
|
||||||
{
|
|
||||||
connectedPlayerIDs.insert(oldConnectedId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h & connectedPlayerIDs;
|
|
||||||
}
|
|
||||||
h & team;
|
h & team;
|
||||||
h & compOnly;
|
h & compOnly;
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,6 @@
|
|||||||
///
|
///
|
||||||
namespace GameConstants
|
namespace GameConstants
|
||||||
{
|
{
|
||||||
const std::string TERRAIN_NAMES [TERRAIN_TYPES] = {
|
|
||||||
"dirt", "sand", "grass", "snow", "swamp", "rough", "subterra", "lava", "water", "rock"
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::string RESOURCE_NAMES [RESOURCE_QUANTITY] = {
|
const std::string RESOURCE_NAMES [RESOURCE_QUANTITY] = {
|
||||||
"wood", "mercury", "ore", "sulfur", "crystal", "gems", "gold", "mithril"
|
"wood", "mercury", "ore", "sulfur", "crystal", "gems", "gold", "mithril"
|
||||||
};
|
};
|
||||||
|
204
lib/Terrain.cpp
Normal file
204
lib/Terrain.cpp
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*
|
||||||
|
* Terrain.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 "Terrain.h"
|
||||||
|
#include "VCMI_Lib.h"
|
||||||
|
#include "CModHandler.h"
|
||||||
|
|
||||||
|
//regular expression to change id for string at config
|
||||||
|
//("allowedTerrain"\s*:\s*\[.*)9(.*\],\n)
|
||||||
|
//\1"rock"\2
|
||||||
|
|
||||||
|
const Terrain Terrain::ANY("ANY");
|
||||||
|
|
||||||
|
Terrain Terrain::createTerrainTypeH3M(int tId)
|
||||||
|
{
|
||||||
|
static std::array<std::string, 10> terrainsH3M
|
||||||
|
{
|
||||||
|
"dirt", "sand", "grass", "snow", "swamp", "rough", "subterra", "lava", "water", "rock"
|
||||||
|
};
|
||||||
|
return Terrain(terrainsH3M.at(tId));
|
||||||
|
}
|
||||||
|
|
||||||
|
Terrain Terrain::createTerrainByCode(const std::string & typeCode)
|
||||||
|
{
|
||||||
|
for(const auto & terrain : Manager::terrains())
|
||||||
|
{
|
||||||
|
if(Manager::getInfo(terrain).typeCode == typeCode)
|
||||||
|
return terrain;
|
||||||
|
}
|
||||||
|
return Terrain::ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
Terrain::Manager::Manager()
|
||||||
|
{
|
||||||
|
auto allConfigs = VLC->modh->getActiveMods();
|
||||||
|
allConfigs.insert(allConfigs.begin(), "core");
|
||||||
|
for(auto & mod : allConfigs)
|
||||||
|
{
|
||||||
|
if(!CResourceHandler::get(mod)->existsResource(ResourceID("config/terrains.json")))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
JsonNode terrs(mod, ResourceID("config/terrains.json"));
|
||||||
|
for(auto & terr : terrs.Struct())
|
||||||
|
{
|
||||||
|
Terrain::Info info;
|
||||||
|
info.moveCost = terr.second["moveCost"].Integer();
|
||||||
|
const JsonVector &unblockedVec = terr.second["minimapUnblocked"].Vector();
|
||||||
|
info.minimapUnblocked =
|
||||||
|
{
|
||||||
|
ui8(unblockedVec[0].Float()),
|
||||||
|
ui8(unblockedVec[1].Float()),
|
||||||
|
ui8(unblockedVec[2].Float())
|
||||||
|
};
|
||||||
|
|
||||||
|
const JsonVector &blockedVec = terr.second["minimapBlocked"].Vector();
|
||||||
|
info.minimapBlocked =
|
||||||
|
{
|
||||||
|
ui8(blockedVec[0].Float()),
|
||||||
|
ui8(blockedVec[1].Float()),
|
||||||
|
ui8(blockedVec[2].Float())
|
||||||
|
};
|
||||||
|
info.musicFilename = terr.second["music"].String();
|
||||||
|
info.tilesFilename = terr.second["tiles"].String();
|
||||||
|
|
||||||
|
if(terr.second["type"].isNull())
|
||||||
|
{
|
||||||
|
info.type = Terrain::Info::Type::Land;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto s = terr.second["type"].String();
|
||||||
|
if(s == "LAND") info.type = Terrain::Info::Type::Land;
|
||||||
|
if(s == "WATER") info.type = Terrain::Info::Type::Water;
|
||||||
|
if(s == "SUB") info.type = Terrain::Info::Type::Subterranean;
|
||||||
|
if(s == "ROCK") info.type = Terrain::Info::Type::Rock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(terr.second["horseSoundId"].isNull())
|
||||||
|
{
|
||||||
|
info.horseSoundId = 9; //rock sound as default
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.horseSoundId = terr.second["horseSoundId"].Integer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!terr.second["text"].isNull())
|
||||||
|
{
|
||||||
|
info.terrainText = terr.second["text"].String();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(terr.second["code"].isNull())
|
||||||
|
{
|
||||||
|
info.typeCode = terr.first.substr(0, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.typeCode = terr.second["code"].String();
|
||||||
|
assert(info.typeCode.length() == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
terrainInfo[Terrain(terr.first)] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Terrain::Manager & Terrain::Manager::get()
|
||||||
|
{
|
||||||
|
static Terrain::Manager manager;
|
||||||
|
return manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Terrain> Terrain::Manager::terrains()
|
||||||
|
{
|
||||||
|
std::vector<Terrain> _terrains;
|
||||||
|
for(const auto & info : Terrain::Manager::get().terrainInfo)
|
||||||
|
_terrains.push_back(info.first);
|
||||||
|
return _terrains;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Terrain::Info & Terrain::Manager::getInfo(const Terrain & terrain)
|
||||||
|
{
|
||||||
|
return Terrain::Manager::get().terrainInfo.at(terrain);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream & operator<<(std::ostream & os, const Terrain terrainType)
|
||||||
|
{
|
||||||
|
return os << static_cast<const std::string &>(terrainType);
|
||||||
|
}
|
||||||
|
|
||||||
|
Terrain::operator std::string() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
Terrain::Terrain(const std::string & _name) : name(_name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Terrain& Terrain::operator=(const Terrain & _name)
|
||||||
|
{
|
||||||
|
name = _name.name;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Terrain& Terrain::operator=(const std::string & _name)
|
||||||
|
{
|
||||||
|
name = _name;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const Terrain & l, const Terrain & r)
|
||||||
|
{
|
||||||
|
return l.name == r.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Terrain & l, const Terrain & r)
|
||||||
|
{
|
||||||
|
return l.name != r.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const Terrain & l, const Terrain & r)
|
||||||
|
{
|
||||||
|
return l.name < r.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Terrain::id() const
|
||||||
|
{
|
||||||
|
if(name == "ANY") return -3;
|
||||||
|
if(name == "WRONG") return -2;
|
||||||
|
if(name == "BORDER") return -1;
|
||||||
|
|
||||||
|
auto _terrains = Terrain::Manager::terrains();
|
||||||
|
auto iter = std::find(_terrains.begin(), _terrains.end(), *this);
|
||||||
|
return iter - _terrains.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Terrain::isLand() const
|
||||||
|
{
|
||||||
|
return !isWater();
|
||||||
|
}
|
||||||
|
bool Terrain::isWater() const
|
||||||
|
{
|
||||||
|
return Terrain::Manager::getInfo(*this).type == Terrain::Info::Type::Water;
|
||||||
|
}
|
||||||
|
bool Terrain::isPassable() const
|
||||||
|
{
|
||||||
|
return Terrain::Manager::getInfo(*this).type != Terrain::Info::Type::Rock;
|
||||||
|
}
|
||||||
|
bool Terrain::isUnderground() const
|
||||||
|
{
|
||||||
|
return Terrain::Manager::getInfo(*this).type == Terrain::Info::Type::Subterranean;
|
||||||
|
}
|
||||||
|
bool Terrain::isNative() const
|
||||||
|
{
|
||||||
|
return name.empty();
|
||||||
|
}
|
93
lib/Terrain.h
Normal file
93
lib/Terrain.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Terrain.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ConstTransitivePtr.h"
|
||||||
|
#include "JsonNode.h"
|
||||||
|
|
||||||
|
class DLL_LINKAGE Terrain
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
friend class Manager;
|
||||||
|
|
||||||
|
struct Info
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Land, Water, Subterranean, Rock
|
||||||
|
};
|
||||||
|
|
||||||
|
int moveCost;
|
||||||
|
std::array<int, 3> minimapBlocked;
|
||||||
|
std::array<int, 3> minimapUnblocked;
|
||||||
|
std::string musicFilename;
|
||||||
|
std::string tilesFilename;
|
||||||
|
std::string terrainText;
|
||||||
|
std::string typeCode;
|
||||||
|
int horseSoundId;
|
||||||
|
Type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DLL_LINKAGE Manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::vector<Terrain> terrains();
|
||||||
|
static const Info & getInfo(const Terrain &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Manager & get();
|
||||||
|
Manager();
|
||||||
|
|
||||||
|
std::map<Terrain, Info> terrainInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*enum EETerrainType
|
||||||
|
{
|
||||||
|
ANY_TERRAIN = -3,
|
||||||
|
WRONG = -2, BORDER = -1, DIRT, SAND, GRASS, SNOW, SWAMP,
|
||||||
|
ROUGH, SUBTERRANEAN, LAVA, WATER, ROCK // ROCK is also intended to be max value.
|
||||||
|
};*/
|
||||||
|
|
||||||
|
Terrain(const std::string & _type = "");
|
||||||
|
static Terrain createTerrainTypeH3M(int tId);
|
||||||
|
static Terrain createTerrainByCode(const std::string & typeCode);
|
||||||
|
|
||||||
|
int id() const; //TODO: has to be completely removed
|
||||||
|
|
||||||
|
Terrain& operator=(const Terrain & _type);
|
||||||
|
Terrain& operator=(const std::string & _type);
|
||||||
|
|
||||||
|
DLL_LINKAGE friend bool operator==(const Terrain & l, const Terrain & r);
|
||||||
|
DLL_LINKAGE friend bool operator!=(const Terrain & l, const Terrain & r);
|
||||||
|
DLL_LINKAGE friend bool operator<(const Terrain & l, const Terrain & r);
|
||||||
|
|
||||||
|
static const Terrain ANY;
|
||||||
|
|
||||||
|
bool isLand() const;
|
||||||
|
bool isWater() const;
|
||||||
|
bool isPassable() const; //ROCK
|
||||||
|
bool isUnderground() const;
|
||||||
|
bool isNative() const;
|
||||||
|
|
||||||
|
operator std::string() const;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const Terrain terrainType);
|
@ -288,15 +288,3 @@ void LibClasses::setContent(std::shared_ptr<CContentHandler> content)
|
|||||||
{
|
{
|
||||||
modh->content = content;
|
modh->content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibClasses::restoreAllCreaturesNodeType794()
|
|
||||||
{
|
|
||||||
creh->restoreAllCreaturesNodeType794();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LibClasses::update800()
|
|
||||||
{
|
|
||||||
vstd::clear_pointer(scriptHandler);
|
|
||||||
scriptHandler = new scripting::ScriptHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ class DLL_LINKAGE LibClasses : public Services
|
|||||||
void makeNull(); //sets all handler pointers to null
|
void makeNull(); //sets all handler pointers to null
|
||||||
std::shared_ptr<CContentHandler> getContent() const;
|
std::shared_ptr<CContentHandler> getContent() const;
|
||||||
void setContent(std::shared_ptr<CContentHandler> content);
|
void setContent(std::shared_ptr<CContentHandler> content);
|
||||||
void restoreAllCreaturesNodeType794();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool IS_AI_ENABLED; //unused?
|
bool IS_AI_ENABLED; //unused?
|
||||||
@ -91,33 +90,20 @@ public:
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
if(version >= 800)
|
h & scriptHandler;//must be first (or second after modh), it can modify factories other handlers depends on
|
||||||
|
if(!h.saving)
|
||||||
{
|
{
|
||||||
h & scriptHandler;//must be first (or second after modh), it can modify factories other handlers depends on
|
scriptsLoaded();
|
||||||
if(!h.saving)
|
|
||||||
{
|
|
||||||
scriptsLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
update800();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h & heroh;
|
h & heroh;
|
||||||
h & arth;
|
h & arth;
|
||||||
h & creh;
|
h & creh;
|
||||||
if(!h.saving && version < 794)
|
|
||||||
restoreAllCreaturesNodeType794();
|
|
||||||
|
|
||||||
h & townh;
|
h & townh;
|
||||||
h & objh;
|
h & objh;
|
||||||
h & objtypeh;
|
h & objtypeh;
|
||||||
h & spellh;
|
h & spellh;
|
||||||
if(version >= 777)
|
h & skillh;
|
||||||
{
|
|
||||||
h & skillh;
|
|
||||||
}
|
|
||||||
if(!h.saving)
|
if(!h.saving)
|
||||||
{
|
{
|
||||||
//modh will be changed and modh->content will be empty after deserialization
|
//modh will be changed and modh->content will be empty after deserialization
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "../filesystem/Filesystem.h"
|
#include "../filesystem/Filesystem.h"
|
||||||
#include "../mapObjects/CGTownInstance.h"
|
#include "../mapObjects/CGTownInstance.h"
|
||||||
#include "../CGeneralTextHandler.h"
|
#include "../CGeneralTextHandler.h"
|
||||||
|
#include "../Terrain.h"
|
||||||
|
|
||||||
//TODO: remove
|
//TODO: remove
|
||||||
#include "../IGameCallback.h"
|
#include "../IGameCallback.h"
|
||||||
@ -186,7 +187,7 @@ struct RangeGenerator
|
|||||||
std::function<int()> myRand;
|
std::function<int()> myRand;
|
||||||
};
|
};
|
||||||
|
|
||||||
BattleInfo * BattleInfo::setupBattle(int3 tile, ETerrainType terrain, BFieldType battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town)
|
BattleInfo * BattleInfo::setupBattle(int3 tile, Terrain terrain, BFieldType battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town)
|
||||||
{
|
{
|
||||||
CMP_stack cmpst;
|
CMP_stack cmpst;
|
||||||
auto curB = new BattleInfo();
|
auto curB = new BattleInfo();
|
||||||
@ -610,7 +611,7 @@ CStack * BattleInfo::getStack(int stackID, bool onlyAlive)
|
|||||||
|
|
||||||
BattleInfo::BattleInfo()
|
BattleInfo::BattleInfo()
|
||||||
: round(-1), activeStack(-1), town(nullptr), tile(-1,-1,-1),
|
: round(-1), activeStack(-1), town(nullptr), tile(-1,-1,-1),
|
||||||
battlefieldType(BFieldType::NONE), terrainType(ETerrainType::WRONG),
|
battlefieldType(BFieldType::NONE), terrainType(),
|
||||||
tacticsSide(0), tacticDistance(0)
|
tacticsSide(0), tacticDistance(0)
|
||||||
{
|
{
|
||||||
setBattle(this);
|
setBattle(this);
|
||||||
@ -644,7 +645,7 @@ BFieldType BattleInfo::getBattlefieldType() const
|
|||||||
return battlefieldType;
|
return battlefieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
ETerrainType BattleInfo::getTerrainType() const
|
Terrain BattleInfo::getTerrainType() const
|
||||||
{
|
{
|
||||||
return terrainType;
|
return terrainType;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
class CStack;
|
class CStack;
|
||||||
class CStackInstance;
|
class CStackInstance;
|
||||||
class CStackBasicDescriptor;
|
class CStackBasicDescriptor;
|
||||||
|
class Terrain;
|
||||||
|
|
||||||
class DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallback, public IBattleState
|
class DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallback, public IBattleState
|
||||||
{
|
{
|
||||||
@ -36,7 +37,7 @@ public:
|
|||||||
SiegeInfo si;
|
SiegeInfo si;
|
||||||
|
|
||||||
BFieldType battlefieldType; //like !!BA:B
|
BFieldType battlefieldType; //like !!BA:B
|
||||||
ETerrainType terrainType; //used for some stack nativity checks (not the bonus limiters though that have their own copy)
|
Terrain terrainType; //used for some stack nativity checks (not the bonus limiters though that have their own copy)
|
||||||
|
|
||||||
ui8 tacticsSide; //which side is requested to play tactics phase
|
ui8 tacticsSide; //which side is requested to play tactics phase
|
||||||
ui8 tacticDistance; //how many hexes we can go forward (1 = only hexes adjacent to margin line)
|
ui8 tacticDistance; //how many hexes we can go forward (1 = only hexes adjacent to margin line)
|
||||||
@ -72,7 +73,7 @@ public:
|
|||||||
battle::Units getUnitsIf(battle::UnitFilter predicate) const override;
|
battle::Units getUnitsIf(battle::UnitFilter predicate) const override;
|
||||||
|
|
||||||
BFieldType getBattlefieldType() const override;
|
BFieldType getBattlefieldType() const override;
|
||||||
ETerrainType getTerrainType() const override;
|
Terrain getTerrainType() const override;
|
||||||
|
|
||||||
ObstacleCList getAllObstacles() const override;
|
ObstacleCList getAllObstacles() const override;
|
||||||
|
|
||||||
@ -137,7 +138,7 @@ public:
|
|||||||
const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
|
const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
|
||||||
|
|
||||||
void localInit();
|
void localInit();
|
||||||
static BattleInfo * setupBattle(int3 tile, ETerrainType terrain, BFieldType battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town);
|
static BattleInfo * setupBattle(int3 tile, Terrain terrain, BFieldType battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town);
|
||||||
|
|
||||||
ui8 whatSide(PlayerColor player) const;
|
ui8 whatSide(PlayerColor player) const;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "BattleProxy.h"
|
#include "BattleProxy.h"
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
///BattleProxy
|
///BattleProxy
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ BFieldType BattleProxy::getBattlefieldType() const
|
|||||||
return subject->battleGetBattlefieldType();
|
return subject->battleGetBattlefieldType();
|
||||||
}
|
}
|
||||||
|
|
||||||
ETerrainType BattleProxy::getTerrainType() const
|
Terrain BattleProxy::getTerrainType() const
|
||||||
{
|
{
|
||||||
return subject->battleTerrainType();
|
return subject->battleTerrainType();
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
battle::Units getUnitsIf(battle::UnitFilter predicate) const override;
|
battle::Units getUnitsIf(battle::UnitFilter predicate) const override;
|
||||||
|
|
||||||
BFieldType getBattlefieldType() const override;
|
BFieldType getBattlefieldType() const override;
|
||||||
ETerrainType getTerrainType() const override;
|
Terrain getTerrainType() const override;
|
||||||
|
|
||||||
ObstacleCList getAllObstacles() const override;
|
ObstacleCList getAllObstacles() const override;
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
#include "../NetPacks.h"
|
#include "../NetPacks.h"
|
||||||
#include "../mapObjects/CGTownInstance.h"
|
#include "../mapObjects/CGTownInstance.h"
|
||||||
|
|
||||||
ETerrainType CBattleInfoEssentials::battleTerrainType() const
|
Terrain CBattleInfoEssentials::battleTerrainType() const
|
||||||
{
|
{
|
||||||
RETURN_IF_NOT_BATTLE(ETerrainType::WRONG);
|
RETURN_IF_NOT_BATTLE(Terrain());
|
||||||
return getBattle()->getTerrainType();
|
return getBattle()->getTerrainType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
BattlePerspective::BattlePerspective battleGetMySide() const;
|
BattlePerspective::BattlePerspective battleGetMySide() const;
|
||||||
const IBonusBearer * getBattleNode() const;
|
const IBonusBearer * getBattleNode() const;
|
||||||
|
|
||||||
ETerrainType battleTerrainType() const override;
|
Terrain battleTerrainType() const override;
|
||||||
BFieldType battleGetBattlefieldType() const override;
|
BFieldType battleGetBattlefieldType() const override;
|
||||||
int32_t battleGetEnchanterCounter(ui8 side) const;
|
int32_t battleGetEnchanterCounter(ui8 side) const;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
struct CObstacleInstance;
|
struct CObstacleInstance;
|
||||||
class BFieldType;
|
class BFieldType;
|
||||||
class ETerrainType;
|
class Terrain;
|
||||||
|
|
||||||
namespace battle
|
namespace battle
|
||||||
{
|
{
|
||||||
@ -34,7 +34,7 @@ class DLL_LINKAGE IBattleInfoCallback
|
|||||||
public:
|
public:
|
||||||
virtual scripting::Pool * getContextPool() const = 0;
|
virtual scripting::Pool * getContextPool() const = 0;
|
||||||
|
|
||||||
virtual ETerrainType battleTerrainType() const = 0;
|
virtual Terrain battleTerrainType() const = 0;
|
||||||
virtual BFieldType battleGetBattlefieldType() const = 0;
|
virtual BFieldType battleGetBattlefieldType() const = 0;
|
||||||
|
|
||||||
///return none if battle is ongoing; otherwise the victorious side (0/1) or 2 if it is a draw
|
///return none if battle is ongoing; otherwise the victorious side (0/1) or 2 if it is a draw
|
||||||
|
@ -41,7 +41,7 @@ public:
|
|||||||
virtual battle::Units getUnitsIf(battle::UnitFilter predicate) const = 0;
|
virtual battle::Units getUnitsIf(battle::UnitFilter predicate) const = 0;
|
||||||
|
|
||||||
virtual BFieldType getBattlefieldType() const = 0;
|
virtual BFieldType getBattlefieldType() const = 0;
|
||||||
virtual ETerrainType getTerrainType() const = 0;
|
virtual Terrain getTerrainType() const = 0;
|
||||||
|
|
||||||
virtual ObstacleCList getAllObstacles() const = 0;
|
virtual ObstacleCList getAllObstacles() const = 0;
|
||||||
|
|
||||||
|
@ -79,28 +79,28 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile & dest, const TerrainTile & f
|
|||||||
int64_t ret = GameConstants::BASE_MOVEMENT_COST;
|
int64_t ret = GameConstants::BASE_MOVEMENT_COST;
|
||||||
|
|
||||||
//if there is road both on dest and src tiles - use road movement cost
|
//if there is road both on dest and src tiles - use road movement cost
|
||||||
if(dest.roadType != ERoadType::NO_ROAD && from.roadType != ERoadType::NO_ROAD)
|
if(dest.roadType != ROAD_NAMES[0] && from.roadType != ROAD_NAMES[0])
|
||||||
{
|
{
|
||||||
int road = std::min(dest.roadType,from.roadType); //used road ID
|
int roadPos = std::min(vstd::find_pos(ROAD_NAMES, dest.roadType), vstd::find_pos(ROAD_NAMES, from.roadType)); //used road ID
|
||||||
switch(road)
|
switch(roadPos)
|
||||||
{
|
{
|
||||||
case ERoadType::DIRT_ROAD:
|
case 1:
|
||||||
ret = 75;
|
ret = 75;
|
||||||
break;
|
break;
|
||||||
case ERoadType::GRAVEL_ROAD:
|
case 2:
|
||||||
ret = 65;
|
ret = 65;
|
||||||
break;
|
break;
|
||||||
case ERoadType::COBBLESTONE_ROAD:
|
case 3:
|
||||||
ret = 50;
|
ret = 50;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logGlobal->error("Unknown road type: %d", road);
|
logGlobal->error("Unknown road type: %d", roadPos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ti->nativeTerrain != from.terType //the terrain is not native
|
else if(ti->nativeTerrain != from.terType //the terrain is not native
|
||||||
&& ti->nativeTerrain != ETerrainType::ANY_TERRAIN //no special creature bonus
|
&& ti->nativeTerrain != Terrain::ANY //no special creature bonus
|
||||||
&& !ti->hasBonusOfType(Bonus::NO_TERRAIN_PENALTY, from.terType) //no special movement bonus
|
&& !ti->hasBonusOfType(Bonus::NO_TERRAIN_PENALTY, from.terType.id()) //no special movement bonus
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static const CSelector selectorPATHFINDING = Selector::typeSubtype(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::PATHFINDING);
|
static const CSelector selectorPATHFINDING = Selector::typeSubtype(Bonus::SECONDARY_SKILL_PREMY, SecondarySkill::PATHFINDING);
|
||||||
@ -114,7 +114,7 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile & dest, const TerrainTile & f
|
|||||||
return (ui32)ret;
|
return (ui32)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ETerrainType::EETerrainType CGHeroInstance::getNativeTerrain() const
|
Terrain CGHeroInstance::getNativeTerrain() const
|
||||||
{
|
{
|
||||||
// NOTE: in H3 neutral stacks will ignore terrain penalty only if placed as topmost stack(s) in hero army.
|
// NOTE: in H3 neutral stacks will ignore terrain penalty only if placed as topmost stack(s) in hero army.
|
||||||
// This is clearly bug in H3 however intended behaviour is not clear.
|
// This is clearly bug in H3 however intended behaviour is not clear.
|
||||||
@ -122,18 +122,18 @@ ETerrainType::EETerrainType CGHeroInstance::getNativeTerrain() const
|
|||||||
// will always have best penalty without any influence from player-defined stacks order
|
// will always have best penalty without any influence from player-defined stacks order
|
||||||
|
|
||||||
// TODO: What should we do if all hero stacks are neutral creatures?
|
// TODO: What should we do if all hero stacks are neutral creatures?
|
||||||
ETerrainType::EETerrainType nativeTerrain = ETerrainType::BORDER;
|
Terrain nativeTerrain("BORDER");
|
||||||
|
|
||||||
for(auto stack : stacks)
|
for(auto stack : stacks)
|
||||||
{
|
{
|
||||||
ETerrainType::EETerrainType stackNativeTerrain = stack.second->type->getNativeTerrain(); //consider terrain bonuses e.g. Lodestar.
|
Terrain stackNativeTerrain = stack.second->type->getNativeTerrain(); //consider terrain bonuses e.g. Lodestar.
|
||||||
|
|
||||||
if(stackNativeTerrain == ETerrainType::BORDER)
|
if(stackNativeTerrain == Terrain("BORDER"))
|
||||||
continue;
|
continue;
|
||||||
if(nativeTerrain == ETerrainType::BORDER)
|
if(nativeTerrain == Terrain("BORDER"))
|
||||||
nativeTerrain = stackNativeTerrain;
|
nativeTerrain = stackNativeTerrain;
|
||||||
else if(nativeTerrain != stackNativeTerrain)
|
else if(nativeTerrain != stackNativeTerrain)
|
||||||
return ETerrainType::BORDER;
|
return Terrain("BORDER");
|
||||||
}
|
}
|
||||||
return nativeTerrain;
|
return nativeTerrain;
|
||||||
}
|
}
|
||||||
@ -560,23 +560,6 @@ void CGHeroInstance::recreateSecondarySkillsBonuses()
|
|||||||
updateSkillBonus(SecondarySkill(skill_info.first), skill_info.second);
|
updateSkillBonus(SecondarySkill(skill_info.first), skill_info.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGHeroInstance::recreateSpecialtyBonuses(std::vector<HeroSpecial *> & specialtyDeprecated)
|
|
||||||
{
|
|
||||||
auto HeroSpecialToSpecialtyBonus = [](HeroSpecial & hs) -> SSpecialtyBonus
|
|
||||||
{
|
|
||||||
SSpecialtyBonus sb;
|
|
||||||
sb.growsWithLevel = hs.growsWithLevel;
|
|
||||||
sb.bonuses = hs.getBonusList();
|
|
||||||
return sb;
|
|
||||||
};
|
|
||||||
|
|
||||||
for(HeroSpecial * hs : specialtyDeprecated)
|
|
||||||
{
|
|
||||||
for(std::shared_ptr<Bonus> b : SpecialtyBonusToBonuses(HeroSpecialToSpecialtyBonus(*hs), type->ID.getNum()))
|
|
||||||
addNewBonus(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGHeroInstance::updateSkillBonus(SecondarySkill which, int val)
|
void CGHeroInstance::updateSkillBonus(SecondarySkill which, int val)
|
||||||
{
|
{
|
||||||
removeBonuses(Selector::source(Bonus::SECONDARY_SKILL, which));
|
removeBonuses(Selector::source(Bonus::SECONDARY_SKILL, which));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* CGHeroInstance.h, part of VCMI engine
|
* CGHeroInstance.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
@ -89,15 +89,7 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & patrolling;
|
h & patrolling;
|
||||||
if(version >= 755) //save format backward compatibility
|
h & initialPos;
|
||||||
{
|
|
||||||
h & initialPos;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
patrolling = false;
|
|
||||||
initialPos = int3();
|
|
||||||
}
|
|
||||||
h & patrolRadius;
|
h & patrolRadius;
|
||||||
}
|
}
|
||||||
} patrol;
|
} patrol;
|
||||||
@ -163,7 +155,7 @@ public:
|
|||||||
bool needsLastStack()const override;
|
bool needsLastStack()const override;
|
||||||
|
|
||||||
ui32 getTileCost(const TerrainTile &dest, const TerrainTile &from, const TurnInfo * ti) const; //move cost - applying pathfinding skill, road and terrain modifiers. NOT includes diagonal move penalty, last move levelling
|
ui32 getTileCost(const TerrainTile &dest, const TerrainTile &from, const TurnInfo * ti) const; //move cost - applying pathfinding skill, road and terrain modifiers. NOT includes diagonal move penalty, last move levelling
|
||||||
ETerrainType::EETerrainType getNativeTerrain() const;
|
Terrain getNativeTerrain() const;
|
||||||
ui32 getLowestCreatureSpeed() const;
|
ui32 getLowestCreatureSpeed() const;
|
||||||
int3 getPosition(bool h3m = false) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
|
int3 getPosition(bool h3m = false) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
|
||||||
si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
|
si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
|
||||||
@ -287,7 +279,6 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void levelUpAutomatically(CRandomGenerator & rand);
|
void levelUpAutomatically(CRandomGenerator & rand);
|
||||||
void recreateSpecialtyBonuses(std::vector<HeroSpecial*> & specialtyDeprecated);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string getHeroTypeName() const;
|
std::string getHeroTypeName() const;
|
||||||
@ -316,18 +307,8 @@ public:
|
|||||||
h & visitedTown;
|
h & visitedTown;
|
||||||
h & boat;
|
h & boat;
|
||||||
h & type;
|
h & type;
|
||||||
if(version < 781)
|
|
||||||
{
|
|
||||||
std::vector<HeroSpecial*> specialtyDeprecated;
|
|
||||||
h & specialtyDeprecated;
|
|
||||||
if(!h.saving)
|
|
||||||
recreateSpecialtyBonuses(specialtyDeprecated);
|
|
||||||
}
|
|
||||||
h & commander;
|
h & commander;
|
||||||
h & visitedObjects;
|
h & visitedObjects;
|
||||||
BONUS_TREE_DESERIALIZATION_FIX
|
BONUS_TREE_DESERIALIZATION_FIX
|
||||||
//visitied town pointer will be restored by map serialization method
|
|
||||||
if(version < 777 && !h.saving)
|
|
||||||
recreateSecondarySkillsBonuses();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -796,28 +796,6 @@ void CGTownInstance::addTownBonuses()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::fixBonusingDuplicates() //For versions 794-800
|
|
||||||
{
|
|
||||||
std::map<BuildingID::EBuildingID, int> bids;
|
|
||||||
|
|
||||||
for(auto i = 0; i != bonusingBuildings.size(); i++)
|
|
||||||
{
|
|
||||||
auto bid = bonusingBuildings[i]->getBuildingType();
|
|
||||||
if(!bids.count(bid))
|
|
||||||
bids.insert({ bid, 0 });
|
|
||||||
else
|
|
||||||
bids[bid]++;
|
|
||||||
}
|
|
||||||
for(auto & pair : bids)
|
|
||||||
{
|
|
||||||
if(!pair.second)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for(auto i = 0; i < pair.second; i++)
|
|
||||||
deleteTownBonus(pair.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGTownInstance::deleteTownBonus(BuildingID::EBuildingID bid)
|
void CGTownInstance::deleteTownBonus(BuildingID::EBuildingID bid)
|
||||||
{
|
{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -875,90 +853,6 @@ void CGTownInstance::initObj(CRandomGenerator & rand) ///initialize town structu
|
|||||||
updateAppearance();
|
updateAppearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::updateBonusingBuildings() //update to version 792
|
|
||||||
{
|
|
||||||
if(this->town->faction != nullptr)
|
|
||||||
{
|
|
||||||
//firstly, update subtype for the Bonusing objects, which are already stored in the bonusing list
|
|
||||||
for(auto building : bonusingBuildings) //no garrison bonuses here, only week and visiting bonuses
|
|
||||||
{
|
|
||||||
switch(this->town->faction->index)
|
|
||||||
{
|
|
||||||
case ETownType::CASTLE:
|
|
||||||
building->setBuildingSubtype(BuildingSubID::STABLES);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETownType::DUNGEON:
|
|
||||||
if(building->getBuildingType() == BuildingID::SPECIAL_2)
|
|
||||||
building->setBuildingSubtype(BuildingSubID::MANA_VORTEX);
|
|
||||||
else if(building->getBuildingType() == BuildingID::SPECIAL_4)
|
|
||||||
building->setBuildingSubtype(BuildingSubID::EXPERIENCE_VISITING_BONUS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETownType::TOWER:
|
|
||||||
building->setBuildingSubtype(BuildingSubID::KNOWLEDGE_VISITING_BONUS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETownType::STRONGHOLD:
|
|
||||||
building->setBuildingSubtype(BuildingSubID::ATTACK_VISITING_BONUS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETownType::INFERNO:
|
|
||||||
building->setBuildingSubtype(BuildingSubID::SPELL_POWER_VISITING_BONUS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ETownType::FORTRESS:
|
|
||||||
building->setBuildingSubtype(BuildingSubID::DEFENSE_VISITING_BONUS);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//secondly, supplement bonusing buildings list and active bonuses; subtypes for these objects are already set in update792
|
|
||||||
for(auto & kvp : town->buildings)
|
|
||||||
{
|
|
||||||
auto & building = kvp.second;
|
|
||||||
|
|
||||||
if(building->subId == BuildingSubID::PORTAL_OF_SUMMONING)
|
|
||||||
{
|
|
||||||
if(!hasBuiltInOldWay(ETownType::DUNGEON, BuildingID::PORTAL_OF_SUMMON))
|
|
||||||
creatures.resize(GameConstants::CREATURES_PER_TOWN + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(!building->IsVisitingBonus() && !building->IsWeekBonus()) //it's not bonusing => nothing to handle
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(getBonusingBuilding(building->subId) != nullptr) //it's already added => already handled
|
|
||||||
continue;
|
|
||||||
|
|
||||||
///'hasBuilt' checking for bonuses is in the onHeroVisit handler
|
|
||||||
if(building->IsWeekBonus())
|
|
||||||
tryAddOnePerWeekBonus(building->subId);
|
|
||||||
|
|
||||||
if(building->IsVisitingBonus())
|
|
||||||
tryAddVisitingBonus(building->subId);
|
|
||||||
}
|
|
||||||
recreateBuildingsBonuses(); ///Clear all bonuses and recreate
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGTownInstance::updateTown794()
|
|
||||||
{
|
|
||||||
for(auto builtBuilding : builtBuildings)
|
|
||||||
{
|
|
||||||
auto building = town->buildings.at(builtBuilding);
|
|
||||||
|
|
||||||
for(auto overriddenBid : building->overrideBids)
|
|
||||||
overriddenBuildings.insert(overriddenBid);
|
|
||||||
}
|
|
||||||
for(auto & kvp : town->buildings)
|
|
||||||
{
|
|
||||||
auto & building = kvp.second;
|
|
||||||
//The building acts as a visiting bonus and it has not been overridden.
|
|
||||||
if(building->IsVisitingBonus() && overriddenBuildings.find(kvp.first) == overriddenBuildings.end())
|
|
||||||
tryAddVisitingBonus(building->subId);
|
|
||||||
}
|
|
||||||
recreateBuildingsBonuses();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CGTownInstance::hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const
|
bool CGTownInstance::hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const
|
||||||
{
|
{
|
||||||
return (this->town->faction != nullptr && this->town->faction->index == type && hasBuilt(bid));
|
return (this->town->faction != nullptr && this->town->faction->index == type && hasBuilt(bid));
|
||||||
|
@ -130,9 +130,7 @@ public:
|
|||||||
{
|
{
|
||||||
h & bID;
|
h & bID;
|
||||||
h & indexOnTV;
|
h & indexOnTV;
|
||||||
|
h & bType;
|
||||||
if(version >= 792)
|
|
||||||
h & bType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -267,16 +265,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!h.saving && version < 793)
|
h & overriddenBuildings;
|
||||||
updateBonusingBuildings();
|
|
||||||
|
|
||||||
if(version >= 794)
|
|
||||||
h & overriddenBuildings;
|
|
||||||
else if(!h.saving)
|
|
||||||
updateTown794();
|
|
||||||
|
|
||||||
if(!h.saving && (version >= 794 && version < 801))
|
|
||||||
fixBonusingDuplicates();
|
|
||||||
|
|
||||||
if(!h.saving)
|
if(!h.saving)
|
||||||
this->setNodeType(CBonusSystemNode::TOWN);
|
this->setNodeType(CBonusSystemNode::TOWN);
|
||||||
@ -367,7 +356,6 @@ private:
|
|||||||
void setOwner(const PlayerColor owner) const;
|
void setOwner(const PlayerColor owner) const;
|
||||||
void onTownCaptured(const PlayerColor winner) const;
|
void onTownCaptured(const PlayerColor winner) const;
|
||||||
int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<ConstTransitivePtr<CGDwelling> >& dwellings) const;
|
int getDwellingBonus(const std::vector<CreatureID>& creatureIds, const std::vector<ConstTransitivePtr<CGDwelling> >& dwellings) const;
|
||||||
void updateBonusingBuildings();
|
|
||||||
bool hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const;
|
bool hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const;
|
||||||
bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const;
|
bool townEnvisagesBuilding(BuildingSubID::EBuildingSubID bid) const;
|
||||||
bool isBonusingBuildingAdded(BuildingID::EBuildingID bid) const;
|
bool isBonusingBuildingAdded(BuildingID::EBuildingID bid) const;
|
||||||
@ -375,6 +363,4 @@ private:
|
|||||||
void tryAddVisitingBonus(BuildingSubID::EBuildingSubID subID);
|
void tryAddVisitingBonus(BuildingSubID::EBuildingSubID subID);
|
||||||
void initOverriddenBids();
|
void initOverriddenBids();
|
||||||
void addTownBonuses();
|
void addTownBonuses();
|
||||||
void updateTown794(); //populate overriddenBuildings and vanila bonuses for old saves
|
|
||||||
void fixBonusingDuplicates(); //For versions 794-800.
|
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* CObjectClassesHandler.cpp, part of VCMI engine
|
* CObjectClassesHandler.cpp, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
@ -195,7 +195,7 @@ void CObjectClassesHandler::loadObjectEntry(const std::string & identifier, cons
|
|||||||
else
|
else
|
||||||
handler->init(entry);
|
handler->init(entry);
|
||||||
|
|
||||||
if (handler->getTemplates().empty())
|
//if (handler->getTemplates().empty())
|
||||||
{
|
{
|
||||||
auto range = legacyTemplates.equal_range(std::make_pair(obj->id, id));
|
auto range = legacyTemplates.equal_range(std::make_pair(obj->id, id));
|
||||||
for (auto & templ : boost::make_iterator_range(range.first, range.second))
|
for (auto & templ : boost::make_iterator_range(range.first, range.second))
|
||||||
@ -569,14 +569,14 @@ std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates() const
|
|||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates(si32 terrainType) const// FIXME: replace with ETerrainType
|
std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates(const Terrain & terrainType) const
|
||||||
{
|
{
|
||||||
std::vector<ObjectTemplate> templates = getTemplates();
|
std::vector<ObjectTemplate> templates = getTemplates();
|
||||||
std::vector<ObjectTemplate> filtered;
|
std::vector<ObjectTemplate> filtered;
|
||||||
|
|
||||||
std::copy_if(templates.begin(), templates.end(), std::back_inserter(filtered), [&](const ObjectTemplate & obj)
|
std::copy_if(templates.begin(), templates.end(), std::back_inserter(filtered), [&](const ObjectTemplate & obj)
|
||||||
{
|
{
|
||||||
return obj.canBePlacedAt(ETerrainType(terrainType));
|
return obj.canBePlacedAt(terrainType);
|
||||||
});
|
});
|
||||||
// H3 defines allowed terrains in a weird way - artifacts, monsters and resources have faulty masks here
|
// H3 defines allowed terrains in a weird way - artifacts, monsters and resources have faulty masks here
|
||||||
// Perhaps we should re-define faulty templates and remove this workaround (already done for resources)
|
// Perhaps we should re-define faulty templates and remove this workaround (already done for resources)
|
||||||
@ -586,7 +586,7 @@ std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates(si32 terrainType) c
|
|||||||
return filtered;
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<ObjectTemplate> AObjectTypeHandler::getOverride(si32 terrainType, const CGObjectInstance * object) const
|
boost::optional<ObjectTemplate> AObjectTypeHandler::getOverride(const Terrain & terrainType, const CGObjectInstance * object) const
|
||||||
{
|
{
|
||||||
std::vector<ObjectTemplate> ret = getTemplates(terrainType);
|
std::vector<ObjectTemplate> ret = getTemplates(terrainType);
|
||||||
for (auto & tmpl : ret)
|
for (auto & tmpl : ret)
|
||||||
|
@ -178,11 +178,11 @@ public:
|
|||||||
|
|
||||||
/// returns all templates matching parameters
|
/// returns all templates matching parameters
|
||||||
std::vector<ObjectTemplate> getTemplates() const;
|
std::vector<ObjectTemplate> getTemplates() const;
|
||||||
std::vector<ObjectTemplate> getTemplates(si32 terrainType) const;
|
std::vector<ObjectTemplate> getTemplates(const Terrain & terrainType) const;
|
||||||
|
|
||||||
/// returns preferred template for this object, if present (e.g. one of 3 possible templates for town - village, fort and castle)
|
/// returns preferred template for this object, if present (e.g. one of 3 possible templates for town - village, fort and castle)
|
||||||
/// note that appearance will not be changed - this must be done separately (either by assignment or via pack from server)
|
/// note that appearance will not be changed - this must be done separately (either by assignment or via pack from server)
|
||||||
boost::optional<ObjectTemplate> getOverride(si32 terrainType, const CGObjectInstance * object) const;
|
boost::optional<ObjectTemplate> getOverride(const Terrain & terrainType, const CGObjectInstance * object) const;
|
||||||
|
|
||||||
const RandomMapInfo & getRMGInfo();
|
const RandomMapInfo & getRMGInfo();
|
||||||
|
|
||||||
@ -210,19 +210,10 @@ public:
|
|||||||
h & templates;
|
h & templates;
|
||||||
h & rmgInfo;
|
h & rmgInfo;
|
||||||
h & objectName;
|
h & objectName;
|
||||||
if(version >= 759)
|
h & typeName;
|
||||||
{
|
h & subTypeName;
|
||||||
h & typeName;
|
h & sounds;
|
||||||
h & subTypeName;
|
h & aiValue;
|
||||||
}
|
|
||||||
if(version >= 778)
|
|
||||||
{
|
|
||||||
h & sounds;
|
|
||||||
}
|
|
||||||
if(version >= 789)
|
|
||||||
{
|
|
||||||
h & aiValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -253,19 +244,10 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
|
|||||||
h & handlerName;
|
h & handlerName;
|
||||||
h & base;
|
h & base;
|
||||||
h & subObjects;
|
h & subObjects;
|
||||||
if(version >= 759)
|
h & identifier;
|
||||||
{
|
h & subIds;
|
||||||
h & identifier;
|
h & sounds;
|
||||||
h & subIds;
|
h & groupDefaultAiValue;
|
||||||
}
|
|
||||||
if(version >= 778)
|
|
||||||
{
|
|
||||||
h & sounds;
|
|
||||||
}
|
|
||||||
if(version >= 789)
|
|
||||||
{
|
|
||||||
h & groupDefaultAiValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ int3 IBoatGenerator::bestLocation() const
|
|||||||
{
|
{
|
||||||
if(const TerrainTile *tile = IObjectInterface::cb->getTile(o->pos + offset, false)) //tile is in the map
|
if(const TerrainTile *tile = IObjectInterface::cb->getTile(o->pos + offset, false)) //tile is in the map
|
||||||
{
|
{
|
||||||
if(tile->terType == ETerrainType::WATER && (!tile->blocked || tile->blockingObjects.front()->ID == Obj::BOAT)) //and is water and is not blocked or is blocked by boat
|
if(tile->terType.isWater() && (!tile->blocked || tile->blockingObjects.front()->ID == Obj::BOAT)) //and is water and is not blocked or is blocked by boat
|
||||||
return o->pos + offset;
|
return o->pos + offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,13 +213,9 @@ public:
|
|||||||
///Entry point of binary (de-)serialization
|
///Entry point of binary (de-)serialization
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
if(version >= 759)
|
h & instanceName;
|
||||||
{
|
h & typeName;
|
||||||
h & instanceName;
|
h & subTypeName;
|
||||||
h & typeName;
|
|
||||||
h & subTypeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
h & pos;
|
h & pos;
|
||||||
h & ID;
|
h & ID;
|
||||||
h & subID;
|
h & subID;
|
||||||
|
@ -87,14 +87,7 @@ public:
|
|||||||
h & isCustomFirst;
|
h & isCustomFirst;
|
||||||
h & isCustomNext;
|
h & isCustomNext;
|
||||||
h & isCustomComplete;
|
h & isCustomComplete;
|
||||||
if(version >= 757)
|
h & completedOption;
|
||||||
{
|
|
||||||
h & completedOption;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
completedOption = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName);
|
void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName);
|
||||||
|
@ -269,11 +269,6 @@ public:
|
|||||||
h & onVisited;
|
h & onVisited;
|
||||||
h & onEmpty;
|
h & onEmpty;
|
||||||
h & visitMode;
|
h & visitMode;
|
||||||
if(version < 778)
|
|
||||||
{
|
|
||||||
ui16 soundID = 0;
|
|
||||||
h & soundID;
|
|
||||||
}
|
|
||||||
h & selectMode;
|
h & selectMode;
|
||||||
h & selectedReward;
|
h & selectedReward;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "CObjectHandler.h"
|
#include "CObjectHandler.h"
|
||||||
#include "../CModHandler.h"
|
#include "../CModHandler.h"
|
||||||
#include "../JsonNode.h"
|
#include "../JsonNode.h"
|
||||||
|
#include "../Terrain.h"
|
||||||
|
|
||||||
#include "CRewardableConstructor.h"
|
#include "CRewardableConstructor.h"
|
||||||
|
|
||||||
@ -143,7 +144,17 @@ void ObjectTemplate::readTxt(CLegacyConfigParser & parser)
|
|||||||
for (size_t i=0; i<9; i++)
|
for (size_t i=0; i<9; i++)
|
||||||
{
|
{
|
||||||
if (terrStr[8-i] == '1')
|
if (terrStr[8-i] == '1')
|
||||||
allowedTerrains.insert(ETerrainType((si32)i));
|
allowedTerrains.insert(Terrain::createTerrainTypeH3M(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
//assuming that object can be placed on other land terrains
|
||||||
|
if(allowedTerrains.size() >= 8 && !allowedTerrains.count(Terrain("water")))
|
||||||
|
{
|
||||||
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
{
|
||||||
|
if(terrain.isLand() && terrain.isPassable())
|
||||||
|
allowedTerrains.insert(terrain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id = Obj(boost::lexical_cast<int>(strings[5]));
|
id = Obj(boost::lexical_cast<int>(strings[5]));
|
||||||
@ -205,7 +216,17 @@ void ObjectTemplate::readMap(CBinaryReader & reader)
|
|||||||
for (size_t i=0; i<9; i++)
|
for (size_t i=0; i<9; i++)
|
||||||
{
|
{
|
||||||
if (((terrMask >> i) & 1 ) != 0)
|
if (((terrMask >> i) & 1 ) != 0)
|
||||||
allowedTerrains.insert(ETerrainType((si32)i));
|
allowedTerrains.insert(Terrain::createTerrainTypeH3M(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
//assuming that object can be placed on other land terrains
|
||||||
|
if(allowedTerrains.size() >= 8 && !allowedTerrains.count(Terrain("water")))
|
||||||
|
{
|
||||||
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
{
|
||||||
|
if(terrain.isLand() && terrain.isPassable())
|
||||||
|
allowedTerrains.insert(terrain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id = Obj(reader.readUInt32());
|
id = Obj(reader.readUInt32());
|
||||||
@ -247,15 +268,16 @@ void ObjectTemplate::readJson(const JsonNode &node, const bool withTerrain)
|
|||||||
if(withTerrain && !node["allowedTerrains"].isNull())
|
if(withTerrain && !node["allowedTerrains"].isNull())
|
||||||
{
|
{
|
||||||
for (auto & entry : node["allowedTerrains"].Vector())
|
for (auto & entry : node["allowedTerrains"].Vector())
|
||||||
allowedTerrains.insert(ETerrainType(vstd::find_pos(GameConstants::TERRAIN_NAMES, entry.String())));
|
allowedTerrains.insert(entry.String());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (size_t i=0; i< GameConstants::TERRAIN_TYPES; i++)
|
for(auto & i : Terrain::Manager::terrains())
|
||||||
allowedTerrains.insert(ETerrainType((si32)i));
|
{
|
||||||
|
if(!i.isPassable() || i.isWater())
|
||||||
allowedTerrains.erase(ETerrainType::ROCK);
|
continue;
|
||||||
allowedTerrains.erase(ETerrainType::WATER);
|
allowedTerrains.insert(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(withTerrain && allowedTerrains.empty())
|
if(withTerrain && allowedTerrains.empty())
|
||||||
@ -329,14 +351,14 @@ void ObjectTemplate::writeJson(JsonNode & node, const bool withTerrain) const
|
|||||||
if(withTerrain)
|
if(withTerrain)
|
||||||
{
|
{
|
||||||
//assumed that ROCK and WATER terrains are not included
|
//assumed that ROCK and WATER terrains are not included
|
||||||
if(allowedTerrains.size() < (GameConstants::TERRAIN_TYPES - 2))
|
if(allowedTerrains.size() < (Terrain::Manager::terrains().size() - 2))
|
||||||
{
|
{
|
||||||
JsonVector & data = node["allowedTerrains"].Vector();
|
JsonVector & data = node["allowedTerrains"].Vector();
|
||||||
|
|
||||||
for(auto type : allowedTerrains)
|
for(auto type : allowedTerrains)
|
||||||
{
|
{
|
||||||
JsonNode value(JsonNode::JsonType::DATA_STRING);
|
JsonNode value(JsonNode::JsonType::DATA_STRING);
|
||||||
value.String() = GameConstants::TERRAIN_NAMES[type.num];
|
value.String() = type;
|
||||||
data.push_back(value);
|
data.push_back(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -511,7 +533,7 @@ bool ObjectTemplate::isVisitableFromTop() const
|
|||||||
//return isVisitableFrom (0, 1);
|
//return isVisitableFrom (0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectTemplate::canBePlacedAt(ETerrainType terrain) const
|
bool ObjectTemplate::canBePlacedAt(Terrain terrain) const
|
||||||
{
|
{
|
||||||
return allowedTerrains.count(terrain) != 0;
|
return allowedTerrains.count(terrain) != 0;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ class CBinaryReader;
|
|||||||
class CLegacyConfigParser;
|
class CLegacyConfigParser;
|
||||||
class JsonNode;
|
class JsonNode;
|
||||||
class int3;
|
class int3;
|
||||||
|
class Terrain;
|
||||||
|
|
||||||
class DLL_LINKAGE ObjectTemplate
|
class DLL_LINKAGE ObjectTemplate
|
||||||
{
|
{
|
||||||
@ -30,7 +31,7 @@ class DLL_LINKAGE ObjectTemplate
|
|||||||
/// directions from which object can be entered, format same as for moveDir in CGHeroInstance(but 0 - 7)
|
/// directions from which object can be entered, format same as for moveDir in CGHeroInstance(but 0 - 7)
|
||||||
ui8 visitDir;
|
ui8 visitDir;
|
||||||
/// list of terrains on which this object can be placed
|
/// list of terrains on which this object can be placed
|
||||||
std::set<ETerrainType> allowedTerrains;
|
std::set<Terrain> allowedTerrains;
|
||||||
|
|
||||||
void afterLoadFixup();
|
void afterLoadFixup();
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ public:
|
|||||||
bool isVisitableFromTop() const;
|
bool isVisitableFromTop() const;
|
||||||
|
|
||||||
// Checks if object can be placed on specific terrain
|
// Checks if object can be placed on specific terrain
|
||||||
bool canBePlacedAt(ETerrainType terrain) const;
|
bool canBePlacedAt(Terrain terrain) const;
|
||||||
|
|
||||||
ObjectTemplate();
|
ObjectTemplate();
|
||||||
//custom copy constructor is required
|
//custom copy constructor is required
|
||||||
@ -96,10 +97,7 @@ public:
|
|||||||
h & subid;
|
h & subid;
|
||||||
h & printPriority;
|
h & printPriority;
|
||||||
h & visitDir;
|
h & visitDir;
|
||||||
if(version >= 770)
|
h & editorAnimationFile;
|
||||||
{
|
|
||||||
h & editorAnimationFile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -422,17 +422,6 @@ std::vector<CGHeroInstance *> CCampaignScenario::getLostCrossoverHeroes()
|
|||||||
return lostCrossoverHeroes;
|
return lostCrossoverHeroes;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<JsonNode> CCampaignScenario::update787(std::vector<CGHeroInstance *> & heroes)
|
|
||||||
{
|
|
||||||
static_assert(MINIMAL_SERIALIZATION_VERSION < 787, "No longer needed CCampaignScenario::update787");
|
|
||||||
std::vector<JsonNode> heroesNew;
|
|
||||||
for(auto hero : heroes)
|
|
||||||
{
|
|
||||||
heroesNew.push_back(CCampaignState::crossoverSerialize(hero));
|
|
||||||
}
|
|
||||||
return heroesNew;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCampaignState::setCurrentMapAsConquered(const std::vector<CGHeroInstance *> & heroes)
|
void CCampaignState::setCurrentMapAsConquered(const std::vector<CGHeroInstance *> & heroes)
|
||||||
{
|
{
|
||||||
camp->scenarios[*currentMap].crossoverHeroes.clear();
|
camp->scenarios[*currentMap].crossoverHeroes.clear();
|
||||||
|
@ -146,8 +146,7 @@ public:
|
|||||||
// FIXME: due to usage of JsonNode I can't make these methods const
|
// FIXME: due to usage of JsonNode I can't make these methods const
|
||||||
const CGHeroInstance * strongestHero(PlayerColor owner);
|
const CGHeroInstance * strongestHero(PlayerColor owner);
|
||||||
std::vector<CGHeroInstance *> getLostCrossoverHeroes(); /// returns a list of crossover heroes which started the scenario, but didn't complete it
|
std::vector<CGHeroInstance *> getLostCrossoverHeroes(); /// returns a list of crossover heroes which started the scenario, but didn't complete it
|
||||||
std::vector<JsonNode> update787(std::vector<CGHeroInstance *> & heroes);
|
|
||||||
|
|
||||||
CCampaignScenario();
|
CCampaignScenario();
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||||
@ -163,19 +162,8 @@ public:
|
|||||||
h & prolog;
|
h & prolog;
|
||||||
h & epilog;
|
h & epilog;
|
||||||
h & travelOptions;
|
h & travelOptions;
|
||||||
if(formatVersion < 787)
|
h & crossoverHeroes;
|
||||||
{
|
h & placedCrossoverHeroes;
|
||||||
std::vector<CGHeroInstance *> crossoverHeroesOld, placedCrossoverHeroesOld;
|
|
||||||
h & crossoverHeroesOld;
|
|
||||||
h & placedCrossoverHeroesOld;
|
|
||||||
crossoverHeroes = update787(crossoverHeroesOld);
|
|
||||||
placedCrossoverHeroes = update787(placedCrossoverHeroesOld);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h & crossoverHeroes;
|
|
||||||
h & placedCrossoverHeroes;
|
|
||||||
}
|
|
||||||
h & keepHeroes;
|
h & keepHeroes;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -148,7 +148,7 @@ static bool ruleIsAny(const std::string & rule)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
///CDrawRoadsOperation
|
///CDrawRoadsOperation
|
||||||
CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, ERoadType::ERoadType roadType, CRandomGenerator * gen):
|
CDrawRoadsOperation::CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, const std::string & roadType, CRandomGenerator * gen):
|
||||||
CMapOperation(map),terrainSel(terrainSel), roadType(roadType), gen(gen)
|
CMapOperation(map),terrainSel(terrainSel), roadType(roadType), gen(gen)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ void CDrawRoadsOperation::flipPattern(RoadPattern& pattern, int flip) const
|
|||||||
|
|
||||||
bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const
|
bool CDrawRoadsOperation::needUpdateTile(const TerrainTile & tile) const
|
||||||
{
|
{
|
||||||
return tile.roadType != ERoadType::NO_ROAD; //TODO: this method should be virtual for river support
|
return tile.roadType != ROAD_NAMES[0]; //TODO: this method should be virtual for river support
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDrawRoadsOperation::updateTiles(std::set<int3> & invalidated)
|
void CDrawRoadsOperation::updateTiles(std::set<int3> & invalidated)
|
||||||
@ -263,7 +263,7 @@ bool CDrawRoadsOperation::tileHasSomething(const int3& pos) const
|
|||||||
{
|
{
|
||||||
//TODO: this method should be virtual for river support
|
//TODO: this method should be virtual for river support
|
||||||
|
|
||||||
return map->getTile(pos).roadType != ERoadType::NO_ROAD;
|
return map->getTile(pos).roadType != ROAD_NAMES[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ struct TerrainTile;
|
|||||||
class CDrawRoadsOperation : public CMapOperation
|
class CDrawRoadsOperation : public CMapOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, ERoadType::ERoadType roadType, CRandomGenerator * gen);
|
CDrawRoadsOperation(CMap * map, const CTerrainSelection & terrainSel, const std::string & roadType, CRandomGenerator * gen);
|
||||||
void execute() override;
|
void execute() override;
|
||||||
void undo() override;
|
void undo() override;
|
||||||
void redo() override;
|
void redo() override;
|
||||||
@ -53,6 +53,6 @@ private:
|
|||||||
bool tileHasSomething(const int3 & pos) const;
|
bool tileHasSomething(const int3 & pos) const;
|
||||||
|
|
||||||
CTerrainSelection terrainSel;
|
CTerrainSelection terrainSel;
|
||||||
ERoadType::ERoadType roadType;
|
std::string roadType;
|
||||||
CRandomGenerator * gen;
|
CRandomGenerator * gen;
|
||||||
};
|
};
|
||||||
|
@ -123,8 +123,8 @@ CCastleEvent::CCastleEvent() : town(nullptr)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainTile::TerrainTile() : terType(ETerrainType::BORDER), terView(0), riverType(ERiverType::NO_RIVER),
|
TerrainTile::TerrainTile() : terType("BORDER"), terView(0), riverType(RIVER_NAMES[0]),
|
||||||
riverDir(0), roadType(ERoadType::NO_ROAD), roadDir(0), extTileFlags(0), visitable(false),
|
riverDir(0), roadType(ROAD_NAMES[0]), roadDir(0), extTileFlags(0), visitable(false),
|
||||||
blocked(false)
|
blocked(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -132,13 +132,13 @@ TerrainTile::TerrainTile() : terType(ETerrainType::BORDER), terView(0), riverTyp
|
|||||||
|
|
||||||
bool TerrainTile::entrableTerrain(const TerrainTile * from) const
|
bool TerrainTile::entrableTerrain(const TerrainTile * from) const
|
||||||
{
|
{
|
||||||
return entrableTerrain(from ? from->terType != ETerrainType::WATER : true, from ? from->terType == ETerrainType::WATER : true);
|
return entrableTerrain(from ? from->terType.isLand() : true, from ? from->terType.isWater() : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const
|
bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const
|
||||||
{
|
{
|
||||||
return terType != ETerrainType::ROCK
|
return terType.isPassable()
|
||||||
&& ((allowSea && terType == ETerrainType::WATER) || (allowLand && terType != ETerrainType::WATER));
|
&& ((allowSea && terType.isWater()) || (allowLand && terType.isLand()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TerrainTile::isClear(const TerrainTile * from) const
|
bool TerrainTile::isClear(const TerrainTile * from) const
|
||||||
@ -164,7 +164,7 @@ CGObjectInstance * TerrainTile::topVisitableObj(bool excludeTop) const
|
|||||||
|
|
||||||
EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const
|
EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const
|
||||||
{
|
{
|
||||||
if(terType == ETerrainType::WATER || terType == ETerrainType::ROCK)
|
if(terType.isWater() || !terType.isPassable())
|
||||||
return EDiggingStatus::WRONG_TERRAIN;
|
return EDiggingStatus::WRONG_TERRAIN;
|
||||||
|
|
||||||
int allowedBlocked = excludeTop ? 1 : 0;
|
int allowedBlocked = excludeTop ? 1 : 0;
|
||||||
@ -181,7 +181,7 @@ bool TerrainTile::hasFavorableWinds() const
|
|||||||
|
|
||||||
bool TerrainTile::isWater() const
|
bool TerrainTile::isWater() const
|
||||||
{
|
{
|
||||||
return terType == ETerrainType::WATER;
|
return terType.isWater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapHeader::setupEvents()
|
void CMapHeader::setupEvents()
|
||||||
|
@ -110,11 +110,7 @@ struct DLL_LINKAGE PlayerInfo
|
|||||||
h & posOfMainTown;
|
h & posOfMainTown;
|
||||||
h & team;
|
h & team;
|
||||||
h & generateHero;
|
h & generateHero;
|
||||||
|
h & mainHeroInstance;
|
||||||
if(version >= 770)
|
|
||||||
{
|
|
||||||
h & mainHeroInstance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,16 +160,9 @@ struct DLL_LINKAGE EventCondition
|
|||||||
h & objectType;
|
h & objectType;
|
||||||
h & position;
|
h & position;
|
||||||
h & condition;
|
h & condition;
|
||||||
//(!!!) should be `version >= 759` here, but do not try to "fix" it
|
h & objectSubtype;
|
||||||
if(version > 759)
|
h & objectInstanceName;
|
||||||
{
|
h & metaType;
|
||||||
h & objectSubtype;
|
|
||||||
h & objectInstanceName;
|
|
||||||
}
|
|
||||||
if(version >= 770)
|
|
||||||
{
|
|
||||||
h & metaType;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -495,9 +484,6 @@ public:
|
|||||||
h & CGTownInstance::merchantArtifacts;
|
h & CGTownInstance::merchantArtifacts;
|
||||||
h & CGTownInstance::universitySkills;
|
h & CGTownInstance::universitySkills;
|
||||||
|
|
||||||
if(formatVersion >= 759)
|
h & instanceNames;
|
||||||
{
|
|
||||||
h & instanceNames;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -80,11 +80,11 @@ struct DLL_LINKAGE TerrainTile
|
|||||||
EDiggingStatus getDiggingStatus(const bool excludeTop = true) const;
|
EDiggingStatus getDiggingStatus(const bool excludeTop = true) const;
|
||||||
bool hasFavorableWinds() const;
|
bool hasFavorableWinds() const;
|
||||||
|
|
||||||
ETerrainType terType;
|
Terrain terType;
|
||||||
ui8 terView;
|
ui8 terView;
|
||||||
ERiverType::ERiverType riverType;
|
std::string riverType;
|
||||||
ui8 riverDir;
|
ui8 riverDir;
|
||||||
ERoadType::ERoadType roadType;
|
std::string roadType;
|
||||||
ui8 roadDir;
|
ui8 roadDir;
|
||||||
/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
|
/// first two bits - how to rotate terrain graphic (next two - river graphic, next two - road);
|
||||||
/// 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favorable Winds effect
|
/// 7th bit - whether tile is coastal (allows disembarking if land or block movement if water); 8th bit - Favorable Winds effect
|
||||||
|
@ -243,13 +243,13 @@ void CMapEditManager::clearTerrain(CRandomGenerator * gen)
|
|||||||
execute(make_unique<CClearTerrainOperation>(map, gen ? gen : &(this->gen)));
|
execute(make_unique<CClearTerrainOperation>(map, gen ? gen : &(this->gen)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapEditManager::drawTerrain(ETerrainType terType, CRandomGenerator * gen)
|
void CMapEditManager::drawTerrain(Terrain terType, CRandomGenerator * gen)
|
||||||
{
|
{
|
||||||
execute(make_unique<CDrawTerrainOperation>(map, terrainSel, terType, gen ? gen : &(this->gen)));
|
execute(make_unique<CDrawTerrainOperation>(map, terrainSel, terType, gen ? gen : &(this->gen)));
|
||||||
terrainSel.clearSelection();
|
terrainSel.clearSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapEditManager::drawRoad(ERoadType::ERoadType roadType, CRandomGenerator* gen)
|
void CMapEditManager::drawRoad(const std::string & roadType, CRandomGenerator* gen)
|
||||||
{
|
{
|
||||||
execute(make_unique<CDrawRoadsOperation>(map, terrainSel, roadType, gen ? gen : &(this->gen)));
|
execute(make_unique<CDrawRoadsOperation>(map, terrainSel, roadType, gen ? gen : &(this->gen)));
|
||||||
terrainSel.clearSelection();
|
terrainSel.clearSelection();
|
||||||
@ -534,7 +534,7 @@ void CTerrainViewPatternConfig::flipPattern(TerrainViewPattern & pattern, int fl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CDrawTerrainOperation::CDrawTerrainOperation(CMap * map, const CTerrainSelection & terrainSel, ETerrainType terType, CRandomGenerator * gen)
|
CDrawTerrainOperation::CDrawTerrainOperation(CMap * map, const CTerrainSelection & terrainSel, Terrain terType, CRandomGenerator * gen)
|
||||||
: CMapOperation(map), terrainSel(terrainSel), terType(terType), gen(gen)
|
: CMapOperation(map), terrainSel(terrainSel), terType(terType), gen(gen)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -760,21 +760,17 @@ void CDrawTerrainOperation::updateTerrainViews()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ETerrainGroup::ETerrainGroup CDrawTerrainOperation::getTerrainGroup(ETerrainType terType) const
|
ETerrainGroup::ETerrainGroup CDrawTerrainOperation::getTerrainGroup(Terrain terType) const
|
||||||
{
|
{
|
||||||
switch(terType)
|
if(terType == Terrain("dirt"))
|
||||||
{
|
|
||||||
case ETerrainType::DIRT:
|
|
||||||
return ETerrainGroup::DIRT;
|
return ETerrainGroup::DIRT;
|
||||||
case ETerrainType::SAND:
|
if(terType == Terrain("sand"))
|
||||||
return ETerrainGroup::SAND;
|
return ETerrainGroup::SAND;
|
||||||
case ETerrainType::WATER:
|
if(terType.isWater())
|
||||||
return ETerrainGroup::WATER;
|
return ETerrainGroup::WATER;
|
||||||
case ETerrainType::ROCK:
|
if(!terType.isPassable())
|
||||||
return ETerrainGroup::ROCK;
|
return ETerrainGroup::ROCK;
|
||||||
default:
|
return ETerrainGroup::NORMAL;
|
||||||
return ETerrainGroup::NORMAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainView(const int3 & pos, const std::vector<TerrainViewPattern> * pattern, int recDepth) const
|
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainView(const int3 & pos, const std::vector<TerrainViewPattern> * pattern, int recDepth) const
|
||||||
@ -811,7 +807,7 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
|||||||
int cy = pos.y + (i / 3) - 1;
|
int cy = pos.y + (i / 3) - 1;
|
||||||
int3 currentPos(cx, cy, pos.z);
|
int3 currentPos(cx, cy, pos.z);
|
||||||
bool isAlien = false;
|
bool isAlien = false;
|
||||||
ETerrainType terType;
|
Terrain terType;
|
||||||
if(!map->isInTheMap(currentPos))
|
if(!map->isInTheMap(currentPos))
|
||||||
{
|
{
|
||||||
// position is not in the map, so take the ter type from the neighbor tile
|
// position is not in the map, so take the ter type from the neighbor tile
|
||||||
@ -949,17 +945,11 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDrawTerrainOperation::isSandType(ETerrainType terType) const
|
bool CDrawTerrainOperation::isSandType(Terrain terType) const
|
||||||
{
|
{
|
||||||
switch(terType)
|
if(terType.isWater() || terType == Terrain("sand") || !terType.isPassable())
|
||||||
{
|
|
||||||
case ETerrainType::WATER:
|
|
||||||
case ETerrainType::SAND:
|
|
||||||
case ETerrainType::ROCK:
|
|
||||||
return true;
|
return true;
|
||||||
default:
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDrawTerrainOperation::invalidateTerrainViews(const int3 & centerPos)
|
void CDrawTerrainOperation::invalidateTerrainViews(const int3 & centerPos)
|
||||||
@ -986,7 +976,7 @@ CDrawTerrainOperation::InvalidTiles CDrawTerrainOperation::getInvalidTiles(const
|
|||||||
auto valid = validateTerrainView(pos, ptrConfig->getTerrainTypePatternById("n1")).result;
|
auto valid = validateTerrainView(pos, ptrConfig->getTerrainTypePatternById("n1")).result;
|
||||||
|
|
||||||
// Special validity check for rock & water
|
// Special validity check for rock & water
|
||||||
if(valid && (terType == ETerrainType::WATER || terType == ETerrainType::ROCK))
|
if(valid && (terType.isWater() || !terType.isPassable()))
|
||||||
{
|
{
|
||||||
static const std::string patternIds[] = { "s1", "s2" };
|
static const std::string patternIds[] = { "s1", "s2" };
|
||||||
for(auto & patternId : patternIds)
|
for(auto & patternId : patternIds)
|
||||||
@ -996,7 +986,7 @@ CDrawTerrainOperation::InvalidTiles CDrawTerrainOperation::getInvalidTiles(const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Additional validity check for non rock OR water
|
// Additional validity check for non rock OR water
|
||||||
else if(!valid && (terType != ETerrainType::WATER && terType != ETerrainType::ROCK))
|
else if(!valid && (terType.isLand() && terType.isPassable()))
|
||||||
{
|
{
|
||||||
static const std::string patternIds[] = { "n2", "n3" };
|
static const std::string patternIds[] = { "n2", "n3" };
|
||||||
for(auto & patternId : patternIds)
|
for(auto & patternId : patternIds)
|
||||||
@ -1040,7 +1030,7 @@ void CTerrainViewPatternUtils::printDebuggingInfoAboutTile(const CMap * map, int
|
|||||||
{
|
{
|
||||||
auto debugTile = map->getTile(debugPos);
|
auto debugTile = map->getTile(debugPos);
|
||||||
|
|
||||||
std::string terType = debugTile.terType.toString().substr(0, 6);
|
std::string terType = static_cast<std::string>(debugTile.terType).substr(0, 6);
|
||||||
line += terType;
|
line += terType;
|
||||||
line.insert(line.end(), PADDED_LENGTH - terType.size(), ' ');
|
line.insert(line.end(), PADDED_LENGTH - terType.size(), ' ');
|
||||||
}
|
}
|
||||||
@ -1059,12 +1049,12 @@ CClearTerrainOperation::CClearTerrainOperation(CMap * map, CRandomGenerator * ge
|
|||||||
{
|
{
|
||||||
CTerrainSelection terrainSel(map);
|
CTerrainSelection terrainSel(map);
|
||||||
terrainSel.selectRange(MapRect(int3(0, 0, 0), map->width, map->height));
|
terrainSel.selectRange(MapRect(int3(0, 0, 0), map->width, map->height));
|
||||||
addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::WATER, gen));
|
addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, Terrain("water"), gen));
|
||||||
if(map->twoLevel)
|
if(map->twoLevel)
|
||||||
{
|
{
|
||||||
terrainSel.clearSelection();
|
terrainSel.clearSelection();
|
||||||
terrainSel.selectRange(MapRect(int3(0, 0, 1), map->width, map->height));
|
terrainSel.selectRange(MapRect(int3(0, 0, 1), map->width, map->height));
|
||||||
addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, ETerrainType::ROCK, gen));
|
addOperation(make_unique<CDrawTerrainOperation>(map, terrainSel, Terrain("rock"), gen));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "../CRandomGenerator.h"
|
#include "../CRandomGenerator.h"
|
||||||
#include "../int3.h"
|
#include "../int3.h"
|
||||||
#include "../GameConstants.h"
|
#include "../GameConstants.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
class CTerrainViewPatternConfig;
|
class CTerrainViewPatternConfig;
|
||||||
@ -168,10 +169,10 @@ public:
|
|||||||
void clearTerrain(CRandomGenerator * gen = nullptr);
|
void clearTerrain(CRandomGenerator * gen = nullptr);
|
||||||
|
|
||||||
/// Draws terrain at the current terrain selection. The selection will be cleared automatically.
|
/// Draws terrain at the current terrain selection. The selection will be cleared automatically.
|
||||||
void drawTerrain(ETerrainType terType, CRandomGenerator * gen = nullptr);
|
void drawTerrain(Terrain terType, CRandomGenerator * gen = nullptr);
|
||||||
|
|
||||||
/// Draws roads at the current terrain selection. The selection will be cleared automatically.
|
/// Draws roads at the current terrain selection. The selection will be cleared automatically.
|
||||||
void drawRoad(ERoadType::ERoadType roadType, CRandomGenerator * gen = nullptr);
|
void drawRoad(const std::string & roadType, CRandomGenerator * gen = nullptr);
|
||||||
|
|
||||||
void insertObject(CGObjectInstance * obj);
|
void insertObject(CGObjectInstance * obj);
|
||||||
|
|
||||||
@ -353,7 +354,7 @@ private:
|
|||||||
class CDrawTerrainOperation : public CMapOperation
|
class CDrawTerrainOperation : public CMapOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDrawTerrainOperation(CMap * map, const CTerrainSelection & terrainSel, ETerrainType terType, CRandomGenerator * gen);
|
CDrawTerrainOperation(CMap * map, const CTerrainSelection & terrainSel, Terrain terType, CRandomGenerator * gen);
|
||||||
|
|
||||||
void execute() override;
|
void execute() override;
|
||||||
void undo() override;
|
void undo() override;
|
||||||
@ -384,16 +385,16 @@ private:
|
|||||||
InvalidTiles getInvalidTiles(const int3 & centerPos) const;
|
InvalidTiles getInvalidTiles(const int3 & centerPos) const;
|
||||||
|
|
||||||
void updateTerrainViews();
|
void updateTerrainViews();
|
||||||
ETerrainGroup::ETerrainGroup getTerrainGroup(ETerrainType terType) const;
|
ETerrainGroup::ETerrainGroup getTerrainGroup(Terrain terType) const;
|
||||||
/// Validates the terrain view of the given position and with the given pattern. The first method wraps the
|
/// Validates the terrain view of the given position and with the given pattern. The first method wraps the
|
||||||
/// second method to validate the terrain view with the given pattern in all four flip directions(horizontal, vertical).
|
/// second method to validate the terrain view with the given pattern in all four flip directions(horizontal, vertical).
|
||||||
ValidationResult validateTerrainView(const int3 & pos, const std::vector<TerrainViewPattern> * pattern, int recDepth = 0) const;
|
ValidationResult validateTerrainView(const int3 & pos, const std::vector<TerrainViewPattern> * pattern, int recDepth = 0) const;
|
||||||
ValidationResult validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth = 0) const;
|
ValidationResult validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth = 0) const;
|
||||||
/// Tests whether the given terrain type is a sand type. Sand types are: Water, Sand and Rock
|
/// Tests whether the given terrain type is a sand type. Sand types are: Water, Sand and Rock
|
||||||
bool isSandType(ETerrainType terType) const;
|
bool isSandType(Terrain terType) const;
|
||||||
|
|
||||||
CTerrainSelection terrainSel;
|
CTerrainSelection terrainSel;
|
||||||
ETerrainType terType;
|
Terrain terType;
|
||||||
CRandomGenerator * gen;
|
CRandomGenerator * gen;
|
||||||
std::set<int3> invalidatedTerViews;
|
std::set<int3> invalidatedTerViews;
|
||||||
};
|
};
|
||||||
|
@ -935,14 +935,14 @@ void CMapLoaderH3M::readTerrain()
|
|||||||
for(int z = 0; z < map->height; z++)
|
for(int z = 0; z < map->height; z++)
|
||||||
{
|
{
|
||||||
auto & tile = map->getTile(int3(z, c, a));
|
auto & tile = map->getTile(int3(z, c, a));
|
||||||
tile.terType = ETerrainType(reader.readUInt8());
|
tile.terType = Terrain::createTerrainTypeH3M(reader.readUInt8());
|
||||||
tile.terView = reader.readUInt8();
|
tile.terView = reader.readUInt8();
|
||||||
tile.riverType = static_cast<ERiverType::ERiverType>(reader.readUInt8());
|
tile.riverType = RIVER_NAMES[reader.readUInt8()];
|
||||||
tile.riverDir = reader.readUInt8();
|
tile.riverDir = reader.readUInt8();
|
||||||
tile.roadType = static_cast<ERoadType::ERoadType>(reader.readUInt8());
|
tile.roadType = ROAD_NAMES[reader.readUInt8()];
|
||||||
tile.roadDir = reader.readUInt8();
|
tile.roadDir = reader.readUInt8();
|
||||||
tile.extTileFlags = reader.readUInt8();
|
tile.extTileFlags = reader.readUInt8();
|
||||||
tile.blocked = ((tile.terType == ETerrainType::ROCK || tile.terType == ETerrainType::BORDER ) ? true : false); //underground tiles are always blocked
|
tile.blocked = ((!tile.terType.isPassable() || tile.terType == Terrain("BORDER") ) ? true : false); //underground tiles are always blocked
|
||||||
tile.visitable = 0;
|
tile.visitable = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,20 +323,6 @@ namespace TriggeredEventsDetail
|
|||||||
|
|
||||||
namespace TerrainDetail
|
namespace TerrainDetail
|
||||||
{
|
{
|
||||||
static const std::array<std::string, 10> terrainCodes =
|
|
||||||
{
|
|
||||||
"dt", "sa", "gr", "sn", "sw", "rg", "sb", "lv", "wt", "rc"
|
|
||||||
};
|
|
||||||
static const std::array<std::string, 4> roadCodes =
|
|
||||||
{
|
|
||||||
"", "pd", "pg", "pc"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::array<std::string, 5> riverCodes =
|
|
||||||
{
|
|
||||||
"", "rw", "ri", "rm", "rl"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::array<char, 4> flipCodes =
|
static const std::array<char, 4> flipCodes =
|
||||||
{
|
{
|
||||||
'_', '-', '|', '+'
|
'_', '-', '|', '+'
|
||||||
@ -959,13 +945,7 @@ void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile
|
|||||||
using namespace TerrainDetail;
|
using namespace TerrainDetail;
|
||||||
{//terrain type
|
{//terrain type
|
||||||
const std::string typeCode = src.substr(0, 2);
|
const std::string typeCode = src.substr(0, 2);
|
||||||
|
tile.terType = Terrain::createTerrainByCode(typeCode);
|
||||||
int rawType = vstd::find_pos(terrainCodes, typeCode);
|
|
||||||
|
|
||||||
if(rawType < 0)
|
|
||||||
throw std::runtime_error("Invalid terrain type code in "+src);
|
|
||||||
|
|
||||||
tile.terType = ETerrainType(rawType);
|
|
||||||
}
|
}
|
||||||
int startPos = 2; //0+typeCode fixed length
|
int startPos = 2; //0+typeCode fixed length
|
||||||
{//terrain view
|
{//terrain view
|
||||||
@ -992,20 +972,18 @@ void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile
|
|||||||
{//road type
|
{//road type
|
||||||
const std::string typeCode = src.substr(startPos, 2);
|
const std::string typeCode = src.substr(startPos, 2);
|
||||||
startPos+=2;
|
startPos+=2;
|
||||||
int rawType = vstd::find_pos(roadCodes, typeCode);
|
if(vstd::find_pos(ROAD_NAMES, typeCode) < 0)
|
||||||
if(rawType < 0)
|
|
||||||
{
|
{
|
||||||
rawType = vstd::find_pos(riverCodes, typeCode);
|
if(vstd::find_pos(RIVER_NAMES, typeCode) < 0)
|
||||||
if(rawType < 0)
|
|
||||||
throw std::runtime_error("Invalid river type in "+src);
|
throw std::runtime_error("Invalid river type in "+src);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tile.riverType = ERiverType::ERiverType(rawType);
|
tile.riverType = typeCode;
|
||||||
hasRoad = false;
|
hasRoad = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tile.roadType = ERoadType::ERoadType(rawType);
|
tile.roadType = typeCode;
|
||||||
}
|
}
|
||||||
if(hasRoad)
|
if(hasRoad)
|
||||||
{//road dir
|
{//road dir
|
||||||
@ -1033,10 +1011,9 @@ void CMapLoaderJson::readTerrainTile(const std::string & src, TerrainTile & tile
|
|||||||
{//river type
|
{//river type
|
||||||
const std::string typeCode = src.substr(startPos, 2);
|
const std::string typeCode = src.substr(startPos, 2);
|
||||||
startPos+=2;
|
startPos+=2;
|
||||||
int rawType = vstd::find_pos(riverCodes, typeCode);
|
if(vstd::find_pos(RIVER_NAMES, typeCode) < 0)
|
||||||
if(rawType < 0)
|
|
||||||
throw std::runtime_error("Invalid river type in "+src);
|
throw std::runtime_error("Invalid river type in "+src);
|
||||||
tile.riverType = ERiverType::ERiverType(rawType);
|
tile.riverType = typeCode;
|
||||||
}
|
}
|
||||||
{//river dir
|
{//river dir
|
||||||
int pos = startPos;
|
int pos = startPos;
|
||||||
@ -1298,13 +1275,13 @@ std::string CMapSaverJson::writeTerrainTile(const TerrainTile & tile)
|
|||||||
out.setf(std::ios::dec, std::ios::basefield);
|
out.setf(std::ios::dec, std::ios::basefield);
|
||||||
out.unsetf(std::ios::showbase);
|
out.unsetf(std::ios::showbase);
|
||||||
|
|
||||||
out << terrainCodes.at(int(tile.terType)) << (int)tile.terView << flipCodes[tile.extTileFlags % 4];
|
out << Terrain::Manager::getInfo(tile.terType).typeCode << (int)tile.terView << flipCodes[tile.extTileFlags % 4];
|
||||||
|
|
||||||
if(tile.roadType != ERoadType::NO_ROAD)
|
if(tile.roadType != ROAD_NAMES[0])
|
||||||
out << roadCodes.at(int(tile.roadType)) << (int)tile.roadDir << flipCodes[(tile.extTileFlags >> 4) % 4];
|
out << tile.roadType << (int)tile.roadDir << flipCodes[(tile.extTileFlags >> 4) % 4];
|
||||||
|
|
||||||
if(tile.riverType != ERiverType::NO_RIVER)
|
if(tile.riverType != RIVER_NAMES[0])
|
||||||
out << riverCodes.at(int(tile.riverType)) << (int)tile.riverDir << flipCodes[(tile.extTileFlags >> 2) % 4];
|
out << tile.riverType << (int)tile.riverDir << flipCodes[(tile.extTileFlags >> 2) % 4];
|
||||||
|
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
@ -69,17 +69,6 @@ CMapGenerator::CMapGenerator(CMapGenOptions& mapGenOptions, int RandomSeed) :
|
|||||||
|
|
||||||
void CMapGenerator::loadConfig()
|
void CMapGenerator::loadConfig()
|
||||||
{
|
{
|
||||||
static std::map<std::string, ETerrainType> terrainMap
|
|
||||||
{
|
|
||||||
{"dirt", ETerrainType::DIRT},
|
|
||||||
{"sand", ETerrainType::SAND},
|
|
||||||
{"grass", ETerrainType::GRASS},
|
|
||||||
{"snow", ETerrainType::SNOW},
|
|
||||||
{"swamp", ETerrainType::SWAMP},
|
|
||||||
{"subterranean", ETerrainType::SUBTERRANEAN},
|
|
||||||
{"lava", ETerrainType::LAVA},
|
|
||||||
{"rough", ETerrainType::ROUGH}
|
|
||||||
};
|
|
||||||
static const std::map<std::string, Res::ERes> resMap
|
static const std::map<std::string, Res::ERes> resMap
|
||||||
{
|
{
|
||||||
{"wood", Res::ERes::WOOD},
|
{"wood", Res::ERes::WOOD},
|
||||||
@ -90,23 +79,17 @@ void CMapGenerator::loadConfig()
|
|||||||
{"sulfur", Res::ERes::SULFUR},
|
{"sulfur", Res::ERes::SULFUR},
|
||||||
{"gold", Res::ERes::GOLD},
|
{"gold", Res::ERes::GOLD},
|
||||||
};
|
};
|
||||||
static std::map<std::string, ERoadType::ERoadType> roadTypeMap
|
|
||||||
{
|
|
||||||
{"dirt_road", ERoadType::DIRT_ROAD},
|
|
||||||
{"gravel_road", ERoadType::GRAVEL_ROAD},
|
|
||||||
{"cobblestone_road", ERoadType::COBBLESTONE_ROAD}
|
|
||||||
};
|
|
||||||
static const ResourceID path("config/randomMap.json");
|
static const ResourceID path("config/randomMap.json");
|
||||||
JsonNode randomMapJson(path);
|
JsonNode randomMapJson(path);
|
||||||
for(auto& s : randomMapJson["terrain"]["undergroundAllow"].Vector())
|
for(auto& s : randomMapJson["terrain"]["undergroundAllow"].Vector())
|
||||||
{
|
{
|
||||||
if(!s.isNull())
|
if(!s.isNull())
|
||||||
config.terrainUndergroundAllowed.push_back(terrainMap[s.String()]);
|
config.terrainUndergroundAllowed.emplace_back(s.String());
|
||||||
}
|
}
|
||||||
for(auto& s : randomMapJson["terrain"]["groundProhibit"].Vector())
|
for(auto& s : randomMapJson["terrain"]["groundProhibit"].Vector())
|
||||||
{
|
{
|
||||||
if(!s.isNull())
|
if(!s.isNull())
|
||||||
config.terrainGroundProhibit.push_back(terrainMap[s.String()]);
|
config.terrainGroundProhibit.emplace_back(s.String());
|
||||||
}
|
}
|
||||||
config.shipyardGuard = randomMapJson["waterZone"]["shipyard"]["value"].Integer();
|
config.shipyardGuard = randomMapJson["waterZone"]["shipyard"]["value"].Integer();
|
||||||
for(auto & treasure : randomMapJson["waterZone"]["treasure"].Vector())
|
for(auto & treasure : randomMapJson["waterZone"]["treasure"].Vector())
|
||||||
@ -119,7 +102,7 @@ void CMapGenerator::loadConfig()
|
|||||||
}
|
}
|
||||||
config.mineExtraResources = randomMapJson["mines"]["extraResourcesLimit"].Integer();
|
config.mineExtraResources = randomMapJson["mines"]["extraResourcesLimit"].Integer();
|
||||||
config.minGuardStrength = randomMapJson["minGuardStrength"].Integer();
|
config.minGuardStrength = randomMapJson["minGuardStrength"].Integer();
|
||||||
config.defaultRoadType = roadTypeMap[randomMapJson["defaultRoadType"].String()];
|
config.defaultRoadType = randomMapJson["defaultRoadType"].String();
|
||||||
config.treasureValueLimit = randomMapJson["treasureValueLimit"].Integer();
|
config.treasureValueLimit = randomMapJson["treasureValueLimit"].Integer();
|
||||||
for(auto & i : randomMapJson["prisons"]["experience"].Vector())
|
for(auto & i : randomMapJson["prisons"]["experience"].Vector())
|
||||||
config.prisonExperience.push_back(i.Integer());
|
config.prisonExperience.push_back(i.Integer());
|
||||||
@ -357,7 +340,7 @@ void CMapGenerator::genZones()
|
|||||||
{
|
{
|
||||||
getEditManager()->clearTerrain(&rand);
|
getEditManager()->clearTerrain(&rand);
|
||||||
getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions.getWidth(), mapGenOptions.getHeight()));
|
getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions.getWidth(), mapGenOptions.getHeight()));
|
||||||
getEditManager()->drawTerrain(ETerrainType::GRASS, &rand);
|
getEditManager()->drawTerrain(Terrain("grass"), &rand);
|
||||||
|
|
||||||
auto tmpl = mapGenOptions.getMapTemplate();
|
auto tmpl = mapGenOptions.getMapTemplate();
|
||||||
zones.clear();
|
zones.clear();
|
||||||
@ -530,14 +513,14 @@ void CMapGenerator::fillZones()
|
|||||||
|
|
||||||
void CMapGenerator::createObstaclesCommon1()
|
void CMapGenerator::createObstaclesCommon1()
|
||||||
{
|
{
|
||||||
if (map->twoLevel) //underground
|
if(map->twoLevel) //underground
|
||||||
{
|
{
|
||||||
//negative approach - create rock tiles first, then make sure all accessible tiles have no rock
|
//negative approach - create rock tiles first, then make sure all accessible tiles have no rock
|
||||||
std::vector<int3> rockTiles;
|
std::vector<int3> rockTiles;
|
||||||
|
|
||||||
for (int x = 0; x < map->width; x++)
|
for(int x = 0; x < map->width; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < map->height; y++)
|
for(int y = 0; y < map->height; y++)
|
||||||
{
|
{
|
||||||
int3 tile(x, y, 1);
|
int3 tile(x, y, 1);
|
||||||
if (shouldBeBlocked(tile))
|
if (shouldBeBlocked(tile))
|
||||||
@ -547,21 +530,29 @@ void CMapGenerator::createObstaclesCommon1()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getEditManager()->getTerrainSelection().setSelection(rockTiles);
|
getEditManager()->getTerrainSelection().setSelection(rockTiles);
|
||||||
getEditManager()->drawTerrain(ETerrainType::ROCK, &rand);
|
|
||||||
|
//collect all rock terrain types
|
||||||
|
std::vector<Terrain> rockTerrains;
|
||||||
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
if(!terrain.isPassable())
|
||||||
|
rockTerrains.push_back(terrain);
|
||||||
|
auto rockTerrain = *RandomGeneratorUtil::nextItem(rockTerrains, rand);
|
||||||
|
|
||||||
|
getEditManager()->drawTerrain(rockTerrain, &rand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenerator::createObstaclesCommon2()
|
void CMapGenerator::createObstaclesCommon2()
|
||||||
{
|
{
|
||||||
if (map->twoLevel)
|
if(map->twoLevel)
|
||||||
{
|
{
|
||||||
//finally mark rock tiles as occupied, spawn no obstacles there
|
//finally mark rock tiles as occupied, spawn no obstacles there
|
||||||
for (int x = 0; x < map->width; x++)
|
for(int x = 0; x < map->width; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < map->height; y++)
|
for(int y = 0; y < map->height; y++)
|
||||||
{
|
{
|
||||||
int3 tile(x, y, 1);
|
int3 tile(x, y, 1);
|
||||||
if (map->getTile(tile).terType == ETerrainType::ROCK)
|
if(!map->getTile(tile).terType.isPassable())
|
||||||
{
|
{
|
||||||
setOccupied(tile, ETileType::USED);
|
setOccupied(tile, ETileType::USED);
|
||||||
}
|
}
|
||||||
@ -904,7 +895,7 @@ void CMapGenerator::setOccupied(const int3 &tile, ETileType::ETileType state)
|
|||||||
tiles[tile.x][tile.y][tile.z].setOccupied(state);
|
tiles[tile.x][tile.y][tile.z].setOccupied(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenerator::setRoad(const int3& tile, ERoadType::ERoadType roadType)
|
void CMapGenerator::setRoad(const int3& tile, const std::string & roadType)
|
||||||
{
|
{
|
||||||
checkIsOnMap(tile);
|
checkIsOnMap(tile);
|
||||||
|
|
||||||
|
@ -26,8 +26,6 @@ class JsonNode;
|
|||||||
class CMapGenerator;
|
class CMapGenerator;
|
||||||
class CTileInfo;
|
class CTileInfo;
|
||||||
|
|
||||||
//#define _BETA
|
|
||||||
|
|
||||||
typedef std::vector<JsonNode> JsonVector;
|
typedef std::vector<JsonNode> JsonVector;
|
||||||
|
|
||||||
class rmgException : public std::exception
|
class rmgException : public std::exception
|
||||||
@ -54,14 +52,14 @@ class DLL_LINKAGE CMapGenerator
|
|||||||
public:
|
public:
|
||||||
struct Config
|
struct Config
|
||||||
{
|
{
|
||||||
std::vector<ETerrainType> terrainUndergroundAllowed;
|
std::vector<Terrain> terrainUndergroundAllowed;
|
||||||
std::vector<ETerrainType> terrainGroundProhibit;
|
std::vector<Terrain> terrainGroundProhibit;
|
||||||
std::vector<CTreasureInfo> waterTreasure;
|
std::vector<CTreasureInfo> waterTreasure;
|
||||||
int shipyardGuard;
|
int shipyardGuard;
|
||||||
int mineExtraResources;
|
int mineExtraResources;
|
||||||
std::map<Res::ERes, int> mineValues;
|
std::map<Res::ERes, int> mineValues;
|
||||||
int minGuardStrength;
|
int minGuardStrength;
|
||||||
ERoadType::ERoadType defaultRoadType;
|
std::string defaultRoadType;
|
||||||
int treasureValueLimit;
|
int treasureValueLimit;
|
||||||
std::vector<int> prisonExperience, prisonValues;
|
std::vector<int> prisonExperience, prisonValues;
|
||||||
std::vector<int> scrollValues;
|
std::vector<int> scrollValues;
|
||||||
@ -101,7 +99,7 @@ public:
|
|||||||
bool isRoad(const int3 &tile) const;
|
bool isRoad(const int3 &tile) const;
|
||||||
|
|
||||||
void setOccupied(const int3 &tile, ETileType::ETileType state);
|
void setOccupied(const int3 &tile, ETileType::ETileType state);
|
||||||
void setRoad(const int3 &tile, ERoadType::ERoadType roadType);
|
void setRoad(const int3 &tile, const std::string & roadType);
|
||||||
|
|
||||||
CTileInfo getTile(const int3 & tile) const;
|
CTileInfo getTile(const int3 & tile) const;
|
||||||
bool isAllowedSpell(SpellID sid) const;
|
bool isAllowedSpell(SpellID sid) const;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "../mapping/CMap.h"
|
#include "../mapping/CMap.h"
|
||||||
#include "../VCMI_Lib.h"
|
#include "../VCMI_Lib.h"
|
||||||
#include "../CTownHandler.h"
|
#include "../CTownHandler.h"
|
||||||
|
#include "../Terrain.h"
|
||||||
#include "../serializer/JsonSerializeFormat.h"
|
#include "../serializer/JsonSerializeFormat.h"
|
||||||
#include "../StringConstants.h"
|
#include "../StringConstants.h"
|
||||||
|
|
||||||
@ -66,12 +67,12 @@ class TerrainEncoder
|
|||||||
public:
|
public:
|
||||||
static si32 decode(const std::string & identifier)
|
static si32 decode(const std::string & identifier)
|
||||||
{
|
{
|
||||||
return vstd::find_pos(GameConstants::TERRAIN_NAMES, identifier);
|
return vstd::find_pos(Terrain::Manager::terrains(), identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string encode(const si32 index)
|
static std::string encode(const si32 index)
|
||||||
{
|
{
|
||||||
return (index >=0 && index < GameConstants::TERRAIN_TYPES) ? GameConstants::TERRAIN_NAMES[index] : "<INVALID TERRAIN>";
|
return (index >=0 && index < Terrain::Manager::terrains().size()) ? static_cast<std::string>(Terrain::Manager::terrains()[index]) : "<INVALID TERRAIN>";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -89,18 +90,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::set<ETerrainType> ZoneOptions::DEFAULT_TERRAIN_TYPES =
|
|
||||||
{
|
|
||||||
ETerrainType::DIRT,
|
|
||||||
ETerrainType::SAND,
|
|
||||||
ETerrainType::GRASS,
|
|
||||||
ETerrainType::SNOW,
|
|
||||||
ETerrainType::SWAMP,
|
|
||||||
ETerrainType::ROUGH,
|
|
||||||
ETerrainType::SUBTERRANEAN,
|
|
||||||
ETerrainType::LAVA
|
|
||||||
};
|
|
||||||
|
|
||||||
const TRmgTemplateZoneId ZoneOptions::NO_ZONE = -1;
|
const TRmgTemplateZoneId ZoneOptions::NO_ZONE = -1;
|
||||||
|
|
||||||
ZoneOptions::CTownInfo::CTownInfo()
|
ZoneOptions::CTownInfo::CTownInfo()
|
||||||
@ -149,7 +138,6 @@ ZoneOptions::ZoneOptions()
|
|||||||
playerTowns(),
|
playerTowns(),
|
||||||
neutralTowns(),
|
neutralTowns(),
|
||||||
matchTerrainToTown(true),
|
matchTerrainToTown(true),
|
||||||
terrainTypes(DEFAULT_TERRAIN_TYPES),
|
|
||||||
townsAreSameType(false),
|
townsAreSameType(false),
|
||||||
townTypes(),
|
townTypes(),
|
||||||
monsterTypes(),
|
monsterTypes(),
|
||||||
@ -161,7 +149,9 @@ ZoneOptions::ZoneOptions()
|
|||||||
terrainTypeLikeZone(NO_ZONE),
|
terrainTypeLikeZone(NO_ZONE),
|
||||||
treasureLikeZone(NO_ZONE)
|
treasureLikeZone(NO_ZONE)
|
||||||
{
|
{
|
||||||
|
for(auto & terr : Terrain::Manager::terrains())
|
||||||
|
if(terr.isLand() && terr.isPassable())
|
||||||
|
terrainTypes.insert(terr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneOptions & ZoneOptions::operator=(const ZoneOptions & other)
|
ZoneOptions & ZoneOptions::operator=(const ZoneOptions & other)
|
||||||
@ -224,15 +214,15 @@ boost::optional<int> ZoneOptions::getOwner() const
|
|||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::set<ETerrainType> & ZoneOptions::getTerrainTypes() const
|
const std::set<Terrain> & ZoneOptions::getTerrainTypes() const
|
||||||
{
|
{
|
||||||
return terrainTypes;
|
return terrainTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneOptions::setTerrainTypes(const std::set<ETerrainType> & value)
|
void ZoneOptions::setTerrainTypes(const std::set<Terrain> & value)
|
||||||
{
|
{
|
||||||
assert(value.find(ETerrainType::WRONG) == value.end() && value.find(ETerrainType::BORDER) == value.end() &&
|
//assert(value.find(ETerrainType::WRONG) == value.end() && value.find(ETerrainType::BORDER) == value.end() &&
|
||||||
value.find(ETerrainType::WATER) == value.end() && value.find(ETerrainType::ROCK) == value.end());
|
// value.find(ETerrainType::WATER) == value.end() && value.find(ETerrainType::ROCK) == value.end());
|
||||||
terrainTypes = value;
|
terrainTypes = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +329,31 @@ void ZoneOptions::serializeJson(JsonSerializeFormat & handler)
|
|||||||
#undef SERIALIZE_ZONE_LINK
|
#undef SERIALIZE_ZONE_LINK
|
||||||
|
|
||||||
if(terrainTypeLikeZone == NO_ZONE)
|
if(terrainTypeLikeZone == NO_ZONE)
|
||||||
handler.serializeIdArray<ETerrainType, TerrainEncoder>("terrainTypes", terrainTypes, DEFAULT_TERRAIN_TYPES);
|
{
|
||||||
|
JsonNode node;
|
||||||
|
if(handler.saving)
|
||||||
|
{
|
||||||
|
node.setType(JsonNode::JsonType::DATA_VECTOR);
|
||||||
|
for(auto & ttype : terrainTypes)
|
||||||
|
{
|
||||||
|
JsonNode n;
|
||||||
|
n.String() = ttype;
|
||||||
|
node.Vector().push_back(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handler.serializeRaw("terrainTypes", node, boost::none);
|
||||||
|
if(!handler.saving)
|
||||||
|
{
|
||||||
|
if(!node.Vector().empty())
|
||||||
|
{
|
||||||
|
terrainTypes.clear();
|
||||||
|
for(auto ttype : node.Vector())
|
||||||
|
{
|
||||||
|
terrainTypes.emplace(ttype.String());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handler.serializeBool("townsAreSameType", townsAreSameType, false);
|
handler.serializeBool("townsAreSameType", townsAreSameType, false);
|
||||||
handler.serializeIdArray<TFaction, FactionID>("allowedMonsters", monsterTypes, VLC->townh->getAllowedFactions(false));
|
handler.serializeIdArray<TFaction, FactionID>("allowedMonsters", monsterTypes, VLC->townh->getAllowedFactions(false));
|
||||||
|
@ -13,9 +13,11 @@
|
|||||||
#include "../int3.h"
|
#include "../int3.h"
|
||||||
#include "../GameConstants.h"
|
#include "../GameConstants.h"
|
||||||
#include "../ResourceSet.h"
|
#include "../ResourceSet.h"
|
||||||
|
#include "../Terrain.h"
|
||||||
#include "CMapGenOptions.h"
|
#include "CMapGenOptions.h"
|
||||||
|
|
||||||
class JsonSerializeFormat;
|
class JsonSerializeFormat;
|
||||||
|
class Terrain;
|
||||||
|
|
||||||
namespace ETemplateZoneType
|
namespace ETemplateZoneType
|
||||||
{
|
{
|
||||||
@ -65,7 +67,6 @@ private:
|
|||||||
class DLL_LINKAGE ZoneOptions
|
class DLL_LINKAGE ZoneOptions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const std::set<ETerrainType> DEFAULT_TERRAIN_TYPES;
|
|
||||||
static const TRmgTemplateZoneId NO_ZONE;
|
static const TRmgTemplateZoneId NO_ZONE;
|
||||||
|
|
||||||
class DLL_LINKAGE CTownInfo
|
class DLL_LINKAGE CTownInfo
|
||||||
@ -101,8 +102,8 @@ public:
|
|||||||
void setSize(int value);
|
void setSize(int value);
|
||||||
boost::optional<int> getOwner() const;
|
boost::optional<int> getOwner() const;
|
||||||
|
|
||||||
const std::set<ETerrainType> & getTerrainTypes() const;
|
const std::set<Terrain> & getTerrainTypes() const;
|
||||||
void setTerrainTypes(const std::set<ETerrainType> & value);
|
void setTerrainTypes(const std::set<Terrain> & value);
|
||||||
|
|
||||||
std::set<TFaction> getDefaultTownTypes() const;
|
std::set<TFaction> getDefaultTownTypes() const;
|
||||||
const std::set<TFaction> & getTownTypes() const;
|
const std::set<TFaction> & getTownTypes() const;
|
||||||
@ -134,7 +135,7 @@ protected:
|
|||||||
CTownInfo playerTowns;
|
CTownInfo playerTowns;
|
||||||
CTownInfo neutralTowns;
|
CTownInfo neutralTowns;
|
||||||
bool matchTerrainToTown;
|
bool matchTerrainToTown;
|
||||||
std::set<ETerrainType> terrainTypes;
|
std::set<Terrain> terrainTypes;
|
||||||
bool townsAreSameType;
|
bool townsAreSameType;
|
||||||
|
|
||||||
std::set<TFaction> townTypes;
|
std::set<TFaction> townTypes;
|
||||||
|
@ -36,7 +36,7 @@ void CRmgTemplateZone::addRoadNode(const int3& node)
|
|||||||
roadNodes.insert(node);
|
roadNodes.insert(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTileInfo::CTileInfo():nearestObjectDistance(float(INT_MAX)), terrain(ETerrainType::WRONG),roadType(ERoadType::NO_ROAD)
|
CTileInfo::CTileInfo():nearestObjectDistance(float(INT_MAX)), terrain()
|
||||||
{
|
{
|
||||||
occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
|
occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ bool CTileInfo::isFree() const
|
|||||||
|
|
||||||
bool CTileInfo::isRoad() const
|
bool CTileInfo::isRoad() const
|
||||||
{
|
{
|
||||||
return roadType != ERoadType::NO_ROAD;
|
return roadType != ROAD_NAMES[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTileInfo::isUsed() const
|
bool CTileInfo::isUsed() const
|
||||||
@ -86,17 +86,17 @@ ETileType::ETileType CTileInfo::getTileType() const
|
|||||||
return occupied;
|
return occupied;
|
||||||
}
|
}
|
||||||
|
|
||||||
ETerrainType CTileInfo::getTerrainType() const
|
Terrain CTileInfo::getTerrainType() const
|
||||||
{
|
{
|
||||||
return terrain;
|
return terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTileInfo::setTerrainType(ETerrainType value)
|
void CTileInfo::setTerrainType(Terrain value)
|
||||||
{
|
{
|
||||||
terrain = value;
|
terrain = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTileInfo::setRoadType(ERoadType::ERoadType value)
|
void CTileInfo::setRoadType(const std::string & value)
|
||||||
{
|
{
|
||||||
roadType = value;
|
roadType = value;
|
||||||
// setOccupied(ETileType::FREE);
|
// setOccupied(ETileType::FREE);
|
||||||
@ -106,7 +106,7 @@ void CTileInfo::setRoadType(ERoadType::ERoadType value)
|
|||||||
CRmgTemplateZone::CRmgTemplateZone(CMapGenerator * Gen)
|
CRmgTemplateZone::CRmgTemplateZone(CMapGenerator * Gen)
|
||||||
: ZoneOptions(),
|
: ZoneOptions(),
|
||||||
townType(ETownType::NEUTRAL),
|
townType(ETownType::NEUTRAL),
|
||||||
terrainType (ETerrainType::GRASS),
|
terrainType (Terrain("grass")),
|
||||||
minGuardedValue(0),
|
minGuardedValue(0),
|
||||||
questArtZone(),
|
questArtZone(),
|
||||||
gen(Gen)
|
gen(Gen)
|
||||||
@ -989,7 +989,7 @@ bool CRmgTemplateZone::createRoad(const int3& src, const int3& dst)
|
|||||||
std::map<int3, int3> cameFrom; // The map of navigated nodes.
|
std::map<int3, int3> cameFrom; // The map of navigated nodes.
|
||||||
std::map<int3, float> distances;
|
std::map<int3, float> distances;
|
||||||
|
|
||||||
gen->setRoad (src, ERoadType::NO_ROAD); //just in case zone guard already has road under it. Road under nodes will be added at very end
|
gen->setRoad (src, ROAD_NAMES[0]); //just in case zone guard already has road under it. Road under nodes will be added at very end
|
||||||
|
|
||||||
cameFrom[src] = int3(-1, -1, -1); //first node points to finish condition
|
cameFrom[src] = int3(-1, -1, -1); //first node points to finish condition
|
||||||
pq.push(std::make_pair(src, 0.f));
|
pq.push(std::make_pair(src, 0.f));
|
||||||
@ -1012,8 +1012,8 @@ bool CRmgTemplateZone::createRoad(const int3& src, const int3& dst)
|
|||||||
while (cameFrom[backTracking].valid())
|
while (cameFrom[backTracking].valid())
|
||||||
{
|
{
|
||||||
// add node to path
|
// add node to path
|
||||||
roads.insert (backTracking);
|
roads.insert(backTracking);
|
||||||
gen->setRoad (backTracking, ERoadType::COBBLESTONE_ROAD);
|
gen->setRoad(backTracking, gen->getConfig().defaultRoadType);
|
||||||
//logGlobal->trace("Setting road at tile %s", backTracking);
|
//logGlobal->trace("Setting road at tile %s", backTracking);
|
||||||
// do the same for the predecessor
|
// do the same for the predecessor
|
||||||
backTracking = cameFrom[backTracking];
|
backTracking = cameFrom[backTracking];
|
||||||
@ -1250,6 +1250,17 @@ void CRmgTemplateZone::addToConnectLater(const int3& src)
|
|||||||
tilesToConnectLater.insert(src);
|
tilesToConnectLater.insert(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CRmgTemplateZone::chooseRandomAppearance(si32 ObjID) const
|
||||||
|
{
|
||||||
|
auto factories = VLC->objtypeh->knownSubObjects(ObjID);
|
||||||
|
vstd::erase_if(factories, [this, ObjID](si32 f)
|
||||||
|
{
|
||||||
|
return VLC->objtypeh->getHandlerFor(ObjID, f)->getTemplates(terrainType).empty();
|
||||||
|
});
|
||||||
|
|
||||||
|
return *RandomGeneratorUtil::nextItem(factories, gen->rand);
|
||||||
|
}
|
||||||
|
|
||||||
bool CRmgTemplateZone::addMonster(int3 &pos, si32 strength, bool clearSurroundingTiles, bool zoneGuard)
|
bool CRmgTemplateZone::addMonster(int3 &pos, si32 strength, bool clearSurroundingTiles, bool zoneGuard)
|
||||||
{
|
{
|
||||||
//precalculate actual (randomized) monster strength based on this post
|
//precalculate actual (randomized) monster strength based on this post
|
||||||
@ -1731,33 +1742,51 @@ void CRmgTemplateZone::initTerrainType ()
|
|||||||
{
|
{
|
||||||
if (type==ETemplateZoneType::WATER)
|
if (type==ETemplateZoneType::WATER)
|
||||||
{
|
{
|
||||||
terrainType = ETerrainType::WATER;
|
//collect all water terrain types
|
||||||
|
std::vector<Terrain> waterTerrains;
|
||||||
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
if(terrain.isWater())
|
||||||
|
waterTerrains.push_back(terrain);
|
||||||
|
|
||||||
|
terrainType = *RandomGeneratorUtil::nextItem(waterTerrains, gen->rand);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (matchTerrainToTown && townType != ETownType::NEUTRAL)
|
if (matchTerrainToTown && townType != ETownType::NEUTRAL)
|
||||||
|
{
|
||||||
terrainType = (*VLC->townh)[townType]->nativeTerrain;
|
terrainType = (*VLC->townh)[townType]->nativeTerrain;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
terrainType = *RandomGeneratorUtil::nextItem(terrainTypes, gen->rand);
|
terrainType = *RandomGeneratorUtil::nextItem(terrainTypes, gen->rand);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: allow new types of terrain?
|
//TODO: allow new types of terrain?
|
||||||
{
|
{
|
||||||
if(isUnderground())
|
if(isUnderground())
|
||||||
{
|
{
|
||||||
if(!vstd::contains(gen->getConfig().terrainUndergroundAllowed, terrainType))
|
if(!vstd::contains(gen->getConfig().terrainUndergroundAllowed, terrainType))
|
||||||
terrainType = ETerrainType::SUBTERRANEAN;
|
{
|
||||||
|
//collect all underground terrain types
|
||||||
|
std::vector<Terrain> undegroundTerrains;
|
||||||
|
for(auto & terrain : Terrain::Manager::terrains())
|
||||||
|
if(terrain.isUnderground())
|
||||||
|
undegroundTerrains.push_back(terrain);
|
||||||
|
|
||||||
|
terrainType = *RandomGeneratorUtil::nextItem(undegroundTerrains, gen->rand);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(vstd::contains(gen->getConfig().terrainGroundProhibit, terrainType))
|
if(vstd::contains(gen->getConfig().terrainGroundProhibit, terrainType) || terrainType.isUnderground())
|
||||||
terrainType = ETerrainType::DIRT;
|
terrainType = Terrain("dirt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
paintZoneTerrain (terrainType);
|
paintZoneTerrain (terrainType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRmgTemplateZone::paintZoneTerrain (ETerrainType terrainType)
|
void CRmgTemplateZone::paintZoneTerrain (Terrain terrainType)
|
||||||
{
|
{
|
||||||
std::vector<int3> tiles(tileinfo.begin(), tileinfo.end());
|
std::vector<int3> tiles(tileinfo.begin(), tileinfo.end());
|
||||||
gen->getEditManager()->getTerrainSelection().setSelection(tiles);
|
gen->getEditManager()->getTerrainSelection().setSelection(tiles);
|
||||||
@ -1837,6 +1866,9 @@ bool CRmgTemplateZone::createRequiredObjects()
|
|||||||
for(const auto &object : requiredObjects)
|
for(const auto &object : requiredObjects)
|
||||||
{
|
{
|
||||||
auto obj = object.first;
|
auto obj = object.first;
|
||||||
|
if (!obj->appearance.canBePlacedAt(terrainType))
|
||||||
|
continue;
|
||||||
|
|
||||||
int3 pos;
|
int3 pos;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -1845,6 +1877,7 @@ bool CRmgTemplateZone::createRequiredObjects()
|
|||||||
logGlobal->error("Failed to fill zone %d due to lack of space", id);
|
logGlobal->error("Failed to fill zone %d due to lack of space", id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tryToPlaceObjectAndConnectToPath(obj, pos) == EObjectPlacingResult::SUCCESS)
|
if (tryToPlaceObjectAndConnectToPath(obj, pos) == EObjectPlacingResult::SUCCESS)
|
||||||
{
|
{
|
||||||
//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones
|
//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones
|
||||||
@ -1858,6 +1891,9 @@ bool CRmgTemplateZone::createRequiredObjects()
|
|||||||
for (const auto &obj : closeObjects)
|
for (const auto &obj : closeObjects)
|
||||||
{
|
{
|
||||||
setTemplateForObject(obj.first);
|
setTemplateForObject(obj.first);
|
||||||
|
if (!obj.first->appearance.canBePlacedAt(terrainType))
|
||||||
|
continue;
|
||||||
|
|
||||||
auto tilesBlockedByObject = obj.first->getBlockedOffsets();
|
auto tilesBlockedByObject = obj.first->getBlockedOffsets();
|
||||||
|
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
@ -2069,8 +2105,8 @@ int3 CRmgTemplateZone::createShipyard(const std::set<int3> & lake, si32 guardStr
|
|||||||
|
|
||||||
bool CRmgTemplateZone::createShipyard(const int3 & position, si32 guardStrength)
|
bool CRmgTemplateZone::createShipyard(const int3 & position, si32 guardStrength)
|
||||||
{
|
{
|
||||||
auto subObjects = VLC->objtypeh->knownSubObjects(Obj::SHIPYARD);
|
int subtype = chooseRandomAppearance(Obj::SHIPYARD);
|
||||||
auto shipyard = (CGShipyard*) VLC->objtypeh->getHandlerFor(Obj::SHIPYARD, *RandomGeneratorUtil::nextItem(subObjects, gen->rand))->create(ObjectTemplate());
|
auto shipyard = (CGShipyard*) VLC->objtypeh->getHandlerFor(Obj::SHIPYARD, subtype)->create(ObjectTemplate());
|
||||||
shipyard->tempOwner = PlayerColor::NEUTRAL;
|
shipyard->tempOwner = PlayerColor::NEUTRAL;
|
||||||
|
|
||||||
setTemplateForObject(shipyard);
|
setTemplateForObject(shipyard);
|
||||||
@ -2569,7 +2605,8 @@ void CRmgTemplateZone::checkAndPlaceObject(CGObjectInstance* object, const int3
|
|||||||
if (object->appearance.id == Obj::NO_OBJ)
|
if (object->appearance.id == Obj::NO_OBJ)
|
||||||
{
|
{
|
||||||
auto terrainType = gen->map->getTile(pos).terType;
|
auto terrainType = gen->map->getTile(pos).terType;
|
||||||
auto templates = VLC->objtypeh->getHandlerFor(object->ID, object->subID)->getTemplates(terrainType);
|
auto h = VLC->objtypeh->getHandlerFor(object->ID, object->subID);
|
||||||
|
auto templates = h->getTemplates(terrainType);
|
||||||
if (templates.empty())
|
if (templates.empty())
|
||||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % object->ID % object->subID % pos.toString() % terrainType));
|
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % object->ID % object->subID % pos.toString() % terrainType));
|
||||||
|
|
||||||
@ -3239,7 +3276,7 @@ void CRmgTemplateZone::addAllPossibleObjects()
|
|||||||
if (!creaturesAmount)
|
if (!creaturesAmount)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand);
|
int randomAppearance = chooseRandomAppearance(Obj::SEER_HUT);
|
||||||
|
|
||||||
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
oi.generateObject = [creature, creaturesAmount, randomAppearance, this, generateArtInfo]() -> CGObjectInstance *
|
||||||
{
|
{
|
||||||
@ -3270,7 +3307,7 @@ void CRmgTemplateZone::addAllPossibleObjects()
|
|||||||
static int seerLevels = std::min(gen->getConfig().questValues.size(), gen->getConfig().questRewardValues.size());
|
static int seerLevels = std::min(gen->getConfig().questValues.size(), gen->getConfig().questRewardValues.size());
|
||||||
for(int i = 0; i < seerLevels; i++) //seems that code for exp and gold reward is similiar
|
for(int i = 0; i < seerLevels; i++) //seems that code for exp and gold reward is similiar
|
||||||
{
|
{
|
||||||
int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand);
|
int randomAppearance = chooseRandomAppearance(Obj::SEER_HUT);
|
||||||
|
|
||||||
oi.setTemplate(Obj::SEER_HUT, randomAppearance, terrainType);
|
oi.setTemplate(Obj::SEER_HUT, randomAppearance, terrainType);
|
||||||
oi.value = gen->getConfig().questValues[i];
|
oi.value = gen->getConfig().questValues[i];
|
||||||
@ -3332,7 +3369,7 @@ ObjectInfo::ObjectInfo()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectInfo::setTemplate (si32 type, si32 subtype, ETerrainType terrainType)
|
void ObjectInfo::setTemplate (si32 type, si32 subtype, Terrain terrainType)
|
||||||
{
|
{
|
||||||
auto templHandler = VLC->objtypeh->getHandlerFor(type, subtype);
|
auto templHandler = VLC->objtypeh->getHandlerFor(type, subtype);
|
||||||
if(!templHandler)
|
if(!templHandler)
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "CRmgTemplate.h"
|
#include "CRmgTemplate.h"
|
||||||
#include "../mapObjects/ObjectTemplate.h"
|
#include "../mapObjects/ObjectTemplate.h"
|
||||||
#include <boost/heap/priority_queue.hpp> //A*
|
#include <boost/heap/priority_queue.hpp> //A*
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
class CMapGenerator;
|
class CMapGenerator;
|
||||||
class CTileInfo;
|
class CTileInfo;
|
||||||
@ -48,16 +49,16 @@ public:
|
|||||||
bool isUsed() const;
|
bool isUsed() const;
|
||||||
bool isRoad() const;
|
bool isRoad() const;
|
||||||
void setOccupied(ETileType::ETileType value);
|
void setOccupied(ETileType::ETileType value);
|
||||||
ETerrainType getTerrainType() const;
|
Terrain getTerrainType() const;
|
||||||
ETileType::ETileType getTileType() const;
|
ETileType::ETileType getTileType() const;
|
||||||
void setTerrainType(ETerrainType value);
|
void setTerrainType(Terrain value);
|
||||||
|
|
||||||
void setRoadType(ERoadType::ERoadType value);
|
void setRoadType(const std::string & value);
|
||||||
private:
|
private:
|
||||||
float nearestObjectDistance;
|
float nearestObjectDistance;
|
||||||
ETileType::ETileType occupied;
|
ETileType::ETileType occupied;
|
||||||
ETerrainType terrain;
|
Terrain terrain;
|
||||||
ERoadType::ERoadType roadType;
|
std::string roadType;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DLL_LINKAGE ObjectInfo
|
struct DLL_LINKAGE ObjectInfo
|
||||||
@ -69,7 +70,7 @@ struct DLL_LINKAGE ObjectInfo
|
|||||||
//ui32 maxPerMap; //unused
|
//ui32 maxPerMap; //unused
|
||||||
std::function<CGObjectInstance *()> generateObject;
|
std::function<CGObjectInstance *()> generateObject;
|
||||||
|
|
||||||
void setTemplate (si32 type, si32 subtype, ETerrainType terrain);
|
void setTemplate (si32 type, si32 subtype, Terrain terrain);
|
||||||
|
|
||||||
ObjectInfo();
|
ObjectInfo();
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ public:
|
|||||||
bool fill ();
|
bool fill ();
|
||||||
bool placeMines ();
|
bool placeMines ();
|
||||||
void initTownType ();
|
void initTownType ();
|
||||||
void paintZoneTerrain (ETerrainType terrainType);
|
void paintZoneTerrain (Terrain terrainType);
|
||||||
void randomizeTownType(bool matchUndergroundType = false); //helper function
|
void randomizeTownType(bool matchUndergroundType = false); //helper function
|
||||||
void initTerrainType ();
|
void initTerrainType ();
|
||||||
void createBorder();
|
void createBorder();
|
||||||
@ -192,7 +193,7 @@ private:
|
|||||||
|
|
||||||
//template info
|
//template info
|
||||||
si32 townType;
|
si32 townType;
|
||||||
ETerrainType terrainType;
|
Terrain terrainType;
|
||||||
std::weak_ptr<CRmgTemplateZone> questArtZone; //artifacts required for Seer Huts will be placed here - or not if null
|
std::weak_ptr<CRmgTemplateZone> questArtZone; //artifacts required for Seer Huts will be placed here - or not if null
|
||||||
|
|
||||||
std::vector<ObjectInfo> possibleObjects;
|
std::vector<ObjectInfo> possibleObjects;
|
||||||
@ -230,6 +231,7 @@ private:
|
|||||||
bool canObstacleBePlacedHere(ObjectTemplate &temp, int3 &pos);
|
bool canObstacleBePlacedHere(ObjectTemplate &temp, int3 &pos);
|
||||||
void setTemplateForObject(CGObjectInstance* obj);
|
void setTemplateForObject(CGObjectInstance* obj);
|
||||||
void checkAndPlaceObject(CGObjectInstance* object, const int3 &pos);
|
void checkAndPlaceObject(CGObjectInstance* object, const int3 &pos);
|
||||||
|
int chooseRandomAppearance(si32 ObjID) const;
|
||||||
|
|
||||||
bool isGuardNeededForTreasure(int value);
|
bool isGuardNeededForTreasure(int value);
|
||||||
};
|
};
|
||||||
|
@ -184,28 +184,26 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
|
|||||||
zonesToPlace.push_back(zone);
|
zonesToPlace.push_back(zone);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch ((*VLC->townh)[faction]->nativeTerrain)
|
auto & tt = (*VLC->townh)[faction]->nativeTerrain;
|
||||||
|
if(tt == Terrain("dirt"))
|
||||||
{
|
{
|
||||||
case ETerrainType::GRASS:
|
|
||||||
case ETerrainType::SWAMP:
|
|
||||||
case ETerrainType::SNOW:
|
|
||||||
case ETerrainType::SAND:
|
|
||||||
case ETerrainType::ROUGH:
|
|
||||||
//surface
|
|
||||||
zonesOnLevel[0]++;
|
|
||||||
levels[zone.first] = 0;
|
|
||||||
break;
|
|
||||||
case ETerrainType::LAVA:
|
|
||||||
case ETerrainType::SUBTERRANEAN:
|
|
||||||
//underground
|
|
||||||
zonesOnLevel[1]++;
|
|
||||||
levels[zone.first] = 1;
|
|
||||||
break;
|
|
||||||
case ETerrainType::DIRT:
|
|
||||||
default:
|
|
||||||
//any / random
|
//any / random
|
||||||
zonesToPlace.push_back(zone);
|
zonesToPlace.push_back(zone);
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(tt.isUnderground())
|
||||||
|
{
|
||||||
|
//underground
|
||||||
|
zonesOnLevel[1]++;
|
||||||
|
levels[zone.first] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//surface
|
||||||
|
zonesOnLevel[0]++;
|
||||||
|
levels[zone.first] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,7 +562,7 @@ void CZonePlacer::assignZones()
|
|||||||
|
|
||||||
//make sure that terrain inside zone is not a rock
|
//make sure that terrain inside zone is not a rock
|
||||||
//FIXME: reorder actions?
|
//FIXME: reorder actions?
|
||||||
zone.second->paintZoneTerrain (ETerrainType::SUBTERRANEAN);
|
zone.second->paintZoneTerrain (Terrain("subterra"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logGlobal->info("Finished zone colouring");
|
logGlobal->info("Finished zone colouring");
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
#include "../ConstTransitivePtr.h"
|
#include "../ConstTransitivePtr.h"
|
||||||
#include "../GameConstants.h"
|
#include "../GameConstants.h"
|
||||||
|
|
||||||
const ui32 SERIALIZATION_VERSION = 801;
|
const ui32 SERIALIZATION_VERSION = 802;
|
||||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
const ui32 MINIMAL_SERIALIZATION_VERSION = 802;
|
||||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||||
|
|
||||||
class CHero;
|
class CHero;
|
||||||
|
@ -1018,54 +1018,3 @@ std::vector<bool> CSpellHandler::getDefaultAllowed() const
|
|||||||
|
|
||||||
return allowedSpells;
|
return allowedSpells;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSpellHandler::update780()
|
|
||||||
{
|
|
||||||
static_assert(MINIMAL_SERIALIZATION_VERSION < 780, "No longer needed CSpellHandler::update780");
|
|
||||||
|
|
||||||
auto spellsContent = (*VLC->modh->content)["spells"];
|
|
||||||
|
|
||||||
const ContentTypeHandler::ModInfo & coreData = spellsContent.modData.at("core");
|
|
||||||
|
|
||||||
const JsonNode & coreSpells = coreData.modData;
|
|
||||||
|
|
||||||
const int levelsCount = GameConstants::SPELL_SCHOOL_LEVELS;
|
|
||||||
|
|
||||||
for(CSpell * spell : objects)
|
|
||||||
{
|
|
||||||
auto identifier = spell->identifier;
|
|
||||||
size_t colonPos = identifier.find(':');
|
|
||||||
if(colonPos != std::string::npos)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const JsonNode & actualConfig = coreSpells[spell->identifier];
|
|
||||||
|
|
||||||
if(actualConfig.getType() != JsonNode::JsonType::DATA_STRUCT)
|
|
||||||
{
|
|
||||||
logGlobal->error("Spell not found %s", spell->identifier);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(actualConfig["targetCondition"].getType() == JsonNode::JsonType::DATA_STRUCT && !actualConfig["targetCondition"].Struct().empty())
|
|
||||||
{
|
|
||||||
spell->targetCondition = actualConfig["targetCondition"];
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int levelIndex = 0; levelIndex < levelsCount; levelIndex++)
|
|
||||||
{
|
|
||||||
const JsonNode & levelNode = actualConfig["levels"][SpellConfig::LEVEL_NAMES[levelIndex]];
|
|
||||||
|
|
||||||
logGlobal->debug(levelNode.toJson());
|
|
||||||
|
|
||||||
CSpell::LevelInfo & levelObject = spell->levels[levelIndex];
|
|
||||||
|
|
||||||
if(levelNode["battleEffects"].getType() == JsonNode::JsonType::DATA_STRUCT && !levelNode["battleEffects"].Struct().empty())
|
|
||||||
{
|
|
||||||
levelObject.battleEffects = levelNode["battleEffects"];
|
|
||||||
|
|
||||||
logGlobal->trace("Updated special effects for level %d of spell %s", levelIndex, spell->identifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -83,14 +83,7 @@ public:
|
|||||||
{
|
{
|
||||||
h & resourceName;
|
h & resourceName;
|
||||||
h & verticalPosition;
|
h & verticalPosition;
|
||||||
if(version >= 754)
|
h & pause;
|
||||||
{
|
|
||||||
h & pause;
|
|
||||||
}
|
|
||||||
else if(!h.saving)
|
|
||||||
{
|
|
||||||
pause = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,10 +113,7 @@ public:
|
|||||||
h & projectile;
|
h & projectile;
|
||||||
h & hit;
|
h & hit;
|
||||||
h & cast;
|
h & cast;
|
||||||
if(version >= 762)
|
h & affect;
|
||||||
{
|
|
||||||
h & affect;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string selectProjectile(const double angle) const;
|
std::string selectProjectile(const double angle) const;
|
||||||
@ -158,32 +148,11 @@ public:
|
|||||||
h & AIValue;
|
h & AIValue;
|
||||||
h & smartTarget;
|
h & smartTarget;
|
||||||
h & range;
|
h & range;
|
||||||
|
h & effects;
|
||||||
if(version >= 773)
|
h & cumulativeEffects;
|
||||||
{
|
|
||||||
h & effects;
|
|
||||||
h & cumulativeEffects;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//all old effects treated as not cumulative, special cases handled by CSpell::serialize
|
|
||||||
std::vector<Bonus> old;
|
|
||||||
h & old;
|
|
||||||
|
|
||||||
if(!h.saving)
|
|
||||||
{
|
|
||||||
effects.clear();
|
|
||||||
cumulativeEffects.clear();
|
|
||||||
for(const Bonus & oldBonus : old)
|
|
||||||
effects.push_back(std::make_shared<Bonus>(oldBonus));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h & clearTarget;
|
h & clearTarget;
|
||||||
h & clearAffected;
|
h & clearAffected;
|
||||||
|
h & battleEffects;
|
||||||
if(version >= 780)
|
|
||||||
h & battleEffects;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -316,27 +285,7 @@ public:
|
|||||||
h & damage;
|
h & damage;
|
||||||
h & offensive;
|
h & offensive;
|
||||||
h & targetType;
|
h & targetType;
|
||||||
|
h & targetCondition;
|
||||||
if(version >= 780)
|
|
||||||
{
|
|
||||||
h & targetCondition;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BTVector immunities;
|
|
||||||
BTVector absoluteImmunities;
|
|
||||||
BTVector limiters;
|
|
||||||
BTVector absoluteLimiters;
|
|
||||||
|
|
||||||
h & immunities;
|
|
||||||
h & limiters;
|
|
||||||
h & absoluteImmunities;
|
|
||||||
h & absoluteLimiters;
|
|
||||||
|
|
||||||
if(!h.saving)
|
|
||||||
targetCondition = convertTargetCondition(immunities, absoluteImmunities, limiters, absoluteLimiters);
|
|
||||||
}
|
|
||||||
|
|
||||||
h & iconImmune;
|
h & iconImmune;
|
||||||
h & defaultProbability;
|
h & defaultProbability;
|
||||||
h & special;
|
h & special;
|
||||||
@ -348,16 +297,6 @@ public:
|
|||||||
h & levels;
|
h & levels;
|
||||||
h & school;
|
h & school;
|
||||||
h & animationInfo;
|
h & animationInfo;
|
||||||
|
|
||||||
//backward compatibility
|
|
||||||
//can not be added to level structure as level structure does not know spell id
|
|
||||||
if(!h.saving && version < 773)
|
|
||||||
{
|
|
||||||
if(id == SpellID::DISRUPTING_RAY || id == SpellID::ACID_BREATH_DEFENSE)
|
|
||||||
for(auto & level : levels)
|
|
||||||
std::swap(level.effects, level.cumulativeEffects);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
friend class CSpellHandler;
|
friend class CSpellHandler;
|
||||||
friend class Graphics;
|
friend class Graphics;
|
||||||
@ -442,11 +381,6 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler & h, const int version)
|
template <typename Handler> void serialize(Handler & h, const int version)
|
||||||
{
|
{
|
||||||
h & objects;
|
h & objects;
|
||||||
if(!h.saving && version < 780)
|
|
||||||
{
|
|
||||||
update780();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!h.saving)
|
if(!h.saving)
|
||||||
{
|
{
|
||||||
afterLoadFinalization();
|
afterLoadFinalization();
|
||||||
@ -456,6 +390,4 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
const std::vector<std::string> & getTypeNames() const override;
|
const std::vector<std::string> & getTypeNames() const override;
|
||||||
CSpell * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;
|
CSpell * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index) override;
|
||||||
private:
|
|
||||||
void update780();
|
|
||||||
};
|
};
|
||||||
|
@ -84,9 +84,7 @@ int BattleCbProxy::getTerrainType(lua_State * L)
|
|||||||
if(!S.tryGet(1, object))
|
if(!S.tryGet(1, object))
|
||||||
return S.retVoid();
|
return S.retVoid();
|
||||||
|
|
||||||
auto ret = object->battleTerrainType();
|
return LuaStack::quickRetStr(L, object->battleTerrainType());
|
||||||
|
|
||||||
return LuaStack::quickRetInt(L, static_cast<si32>(ret.num));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int BattleCbProxy::getUnitByPos(lua_State * L)
|
int BattleCbProxy::getUnitByPos(lua_State * L)
|
||||||
|
@ -1911,7 +1911,7 @@ void CGameHandler::newTurn()
|
|||||||
hth.id = h->id;
|
hth.id = h->id;
|
||||||
auto ti = make_unique<TurnInfo>(h, 1);
|
auto ti = make_unique<TurnInfo>(h, 1);
|
||||||
// TODO: this code executed when bonuses of previous day not yet updated (this happen in NewTurn::applyGs). See issue 2356
|
// TODO: this code executed when bonuses of previous day not yet updated (this happen in NewTurn::applyGs). See issue 2356
|
||||||
hth.move = h->maxMovePointsCached(gs->map->getTile(h->getPosition(false)).terType != ETerrainType::WATER, ti.get());
|
hth.move = h->maxMovePointsCached(gs->map->getTile(h->getPosition(false)).terType.isLand(), ti.get());
|
||||||
hth.mana = h->getManaNewTurn();
|
hth.mana = h->getManaNewTurn();
|
||||||
|
|
||||||
n.heroes.insert(hth);
|
n.heroes.insert(hth);
|
||||||
@ -2215,9 +2215,9 @@ void CGameHandler::setupBattle(int3 tile, const CArmedInstance *armies[2], const
|
|||||||
battleResult.set(nullptr);
|
battleResult.set(nullptr);
|
||||||
|
|
||||||
const auto t = getTile(tile);
|
const auto t = getTile(tile);
|
||||||
ETerrainType terrain = t->terType;
|
Terrain terrain = t->terType;
|
||||||
if (gs->map->isCoastalTile(tile)) //coastal tile is always ground
|
if (gs->map->isCoastalTile(tile)) //coastal tile is always ground
|
||||||
terrain = ETerrainType::SAND;
|
terrain = Terrain("sand");
|
||||||
|
|
||||||
BFieldType terType = gs->battleGetBattlefieldType(tile, getRandomGenerator());
|
BFieldType terType = gs->battleGetBattlefieldType(tile, getRandomGenerator());
|
||||||
if (heroes[0] && heroes[0]->boat && heroes[1] && heroes[1]->boat)
|
if (heroes[0] && heroes[0]->boat && heroes[1] && heroes[1]->boat)
|
||||||
@ -2314,7 +2314,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
const int3 guardPos = gs->guardingCreaturePosition(hmpos);
|
const int3 guardPos = gs->guardingCreaturePosition(hmpos);
|
||||||
|
|
||||||
const bool embarking = !h->boat && !t.visitableObjects.empty() && t.visitableObjects.back()->ID == Obj::BOAT;
|
const bool embarking = !h->boat && !t.visitableObjects.empty() && t.visitableObjects.back()->ID == Obj::BOAT;
|
||||||
const bool disembarking = h->boat && t.terType != ETerrainType::WATER && !t.blocked;
|
const bool disembarking = h->boat && t.terType.isLand() && !t.blocked;
|
||||||
|
|
||||||
//result structure for start - movement failed, no move points used
|
//result structure for start - movement failed, no move points used
|
||||||
TryMoveHero tmh;
|
TryMoveHero tmh;
|
||||||
@ -2336,11 +2336,11 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
|
|
||||||
//it's a rock or blocked and not visitable tile
|
//it's a rock or blocked and not visitable tile
|
||||||
//OR hero is on land and dest is water and (there is not present only one object - boat)
|
//OR hero is on land and dest is water and (there is not present only one object - boat)
|
||||||
if (((t.terType == ETerrainType::ROCK || (t.blocked && !t.visitable && !canFly))
|
if (((!t.terType.isPassable() || (t.blocked && !t.visitable && !canFly))
|
||||||
&& complain("Cannot move hero, destination tile is blocked!"))
|
&& complain("Cannot move hero, destination tile is blocked!"))
|
||||||
|| ((!h->boat && !canWalkOnSea && !canFly && t.terType == ETerrainType::WATER && (t.visitableObjects.size() < 1 || (t.visitableObjects.back()->ID != Obj::BOAT && t.visitableObjects.back()->ID != Obj::HERO))) //hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276)
|
|| ((!h->boat && !canWalkOnSea && !canFly && t.terType.isWater() && (t.visitableObjects.size() < 1 || (t.visitableObjects.back()->ID != Obj::BOAT && t.visitableObjects.back()->ID != Obj::HERO))) //hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276)
|
||||||
&& complain("Cannot move hero, destination tile is on water!"))
|
&& complain("Cannot move hero, destination tile is on water!"))
|
||||||
|| ((h->boat && t.terType != ETerrainType::WATER && t.blocked)
|
|| ((h->boat && t.terType.isLand() && t.blocked)
|
||||||
&& complain("Cannot disembark hero, tile is blocked!"))
|
&& complain("Cannot disembark hero, tile is blocked!"))
|
||||||
|| ((distance(h->pos, dst) >= 1.5 && !teleporting)
|
|| ((distance(h->pos, dst) >= 1.5 && !teleporting)
|
||||||
&& complain("Tiles are not neighboring!"))
|
&& complain("Tiles are not neighboring!"))
|
||||||
|
@ -272,21 +272,14 @@ public:
|
|||||||
h & QID;
|
h & QID;
|
||||||
h & states;
|
h & states;
|
||||||
h & finishingBattle;
|
h & finishingBattle;
|
||||||
|
h & getRandomGenerator();
|
||||||
|
|
||||||
if(version >= 761)
|
JsonNode scriptsState;
|
||||||
{
|
if(h.saving)
|
||||||
h & getRandomGenerator();
|
serverScripts->serializeState(h.saving, scriptsState);
|
||||||
}
|
h & scriptsState;
|
||||||
|
if(!h.saving)
|
||||||
if(version >= 800)
|
serverScripts->serializeState(h.saving, scriptsState);
|
||||||
{
|
|
||||||
JsonNode scriptsState;
|
|
||||||
if(h.saving)
|
|
||||||
serverScripts->serializeState(h.saving, scriptsState);
|
|
||||||
h & scriptsState;
|
|
||||||
if(!h.saving)
|
|
||||||
serverScripts->serializeState(h.saving, scriptsState);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMessageToAll(const std::string &message);
|
void sendMessageToAll(const std::string &message);
|
||||||
@ -314,11 +307,6 @@ public:
|
|||||||
h & loserHero;
|
h & loserHero;
|
||||||
h & victor;
|
h & victor;
|
||||||
h & loser;
|
h & loser;
|
||||||
if(version < 774 && !h.saving)
|
|
||||||
{
|
|
||||||
bool duel;
|
|
||||||
h & duel;
|
|
||||||
}
|
|
||||||
h & remainingBattleQueriesCount;
|
h & remainingBattleQueriesCount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -193,7 +193,7 @@ public:
|
|||||||
|
|
||||||
const auto t = gameCallback->getTile(tile);
|
const auto t = gameCallback->getTile(tile);
|
||||||
|
|
||||||
ETerrainType terrain = t->terType;
|
Terrain terrain = t->terType;
|
||||||
BFieldType terType = BFieldType::GRASS_HILLS;
|
BFieldType terType = BFieldType::GRASS_HILLS;
|
||||||
|
|
||||||
//send info about battles
|
//send info about battles
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit e2239ee6043f73722e7aa812a459f54a28552929
|
Subproject commit 4bab34d2084259cba67f3bfb51217c10d606e175
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user