1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-18 17:40:48 +02:00

New battlegrounds (#758)

This commit is contained in:
Nordsoft91 2022-06-22 11:41:02 +03:00 committed by Andrii Danylchenko
parent 5151da59a7
commit 9241cd1e62
34 changed files with 412 additions and 444 deletions

View File

@ -24,6 +24,7 @@
#include "gui/CAnimation.h"
#include <SDL_ttf.h>
#include "../lib/CThreadHelper.h"
#include "../lib/CModHandler.h"
#include "CGameInfo.h"
#include "../lib/VCMI_Lib.h"
#include "../CCallback.h"
@ -99,28 +100,35 @@ void Graphics::loadPaletteAndColors()
void Graphics::initializeBattleGraphics()
{
const JsonNode config(ResourceID("config/battles_graphics.json"));
auto allConfigs = VLC->modh->getActiveMods();
allConfigs.insert(allConfigs.begin(), "core");
for(auto & mod : allConfigs)
{
if(!CResourceHandler::get(mod)->existsResource(ResourceID("config/battles_graphics.json")))
continue;
const JsonNode config(mod, ResourceID("config/battles_graphics.json"));
// Reserve enough space for the terrains
int idx = static_cast<int>(config["backgrounds"].Vector().size());
battleBacks.resize(idx+1); // 1 to idx, 0 is unused
idx = 1;
for(const JsonNode &t : config["backgrounds"].Vector()) {
battleBacks[idx].push_back(t.String());
idx++;
}
//initialization of AC->def name mapping
for(const JsonNode &ac : config["ac_mapping"].Vector()) {
int ACid = static_cast<int>(ac["id"].Float());
std::vector< std::string > toAdd;
for(const JsonNode &defname : ac["defnames"].Vector()) {
toAdd.push_back(defname.String());
if(!config["backgrounds"].isNull())
for(auto & t : config["backgrounds"].Struct())
{
battleBacks[t.first] = t.second.String();
}
battleACToDef[ACid] = toAdd;
//initialization of AC->def name mapping
if(!config["ac_mapping"].isNull())
for(const JsonNode &ac : config["ac_mapping"].Vector())
{
int ACid = static_cast<int>(ac["id"].Float());
std::vector< std::string > toAdd;
for(const JsonNode &defname : ac["defnames"].Vector())
{
toAdd.push_back(defname.String());
}
battleACToDef[ACid] = toAdd;
}
}
}
Graphics::Graphics()

View File

@ -87,7 +87,7 @@ public:
//towns
std::map<int, std::string> ERMUtoPicture[GameConstants::F_NUMBER]; //maps building ID to it's picture's name for each town type
//for battles
std::vector< std::vector< std::string > > battleBacks; //battleBacks[terType] - vector of possible names for certain terrain type
std::map<std::string, std::string> battleBacks; //maps BattleField to it's picture's name
std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names
//functions

View File

@ -200,15 +200,14 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
}
else
{
auto bfieldType = (int)curInt->cb->battleGetBattlefieldType();
if (graphics->battleBacks.size() <= bfieldType || bfieldType < 0)
logGlobal->error("%d is not valid battlefield type index!", bfieldType);
else if (graphics->battleBacks[bfieldType].empty())
logGlobal->error("%d battlefield type does not have any backgrounds!", bfieldType);
auto bfieldType = curInt->cb->battleGetBattlefieldType();
if(!vstd::contains(graphics->battleBacks, bfieldType))
{
logGlobal->error("%s is not valid battlefield type!", static_cast<std::string>(bfieldType));
}
else
{
const std::string bgName = *RandomGeneratorUtil::nextItem(graphics->battleBacks[bfieldType], CRandomGenerator::getDefault());
background = BitmapHandler::loadBitmap(bgName, false);
background = BitmapHandler::loadBitmap(graphics->battleBacks[bfieldType], false);
}
}

View File

@ -1,32 +1,32 @@
{
// backgrounds of terrains battles can be fought on
"backgrounds": [
"CMBKBCH.BMP",
"CMBKDES.BMP",
"CMBKDRTR.BMP",
"CMBKDRMT.BMP",
"CMBKDRDD.BMP",
"CMBKGRMT.BMP",
"CMBKGRTR.BMP",
"CMBKLAVA.BMP",
"CMBKMAG.BMP",
"CMBKSNMT.BMP",
"CMBKSNTR.BMP",
"CMBKSUB.BMP",
"CMBKSWMP.BMP",
"CMBKFF.BMP",
"CMBKRK.BMP",
"CMBKMC.BMP",
"CMBKLP.BMP",
"CMBKHG.BMP",
"CMBKCF.BMP",
"CMBKEF.BMP",
"CMBKFW.BMP",
"CMBKCUR.BMP",
"CMBKRGH.BMP",
"CMBKBOAT.BMP",
"CMBKDECK.BMP"
],
"backgrounds": {
"sand_shore": "CMBKBCH.BMP",
"sand_mesas": "CMBKDES.BMP",
"dirt_birches": "CMBKDRTR.BMP",
"dirt_hills": "CMBKDRMT.BMP",
"dirt_pines": "CMBKDRDD.BMP",
"grass_hills": "CMBKGRMT.BMP",
"grass_pines": "CMBKGRTR.BMP",
"lava": "CMBKLAVA.BMP",
"magic_plains": "CMBKMAG.BMP",
"snow_mountains": "CMBKSNMT.BMP",
"snow_trees": "CMBKSNTR.BMP",
"subterranean": "CMBKSUB.BMP",
"swamp_trees": "CMBKSWMP.BMP",
"fiery_fields": "CMBKFF.BMP",
"rocklands": "CMBKRK.BMP",
"magic_clouds": "CMBKMC.BMP",
"lucid_pools": "CMBKLP.BMP",
"holy_ground": "CMBKHG.BMP",
"clover_field": "CMBKCF.BMP",
"evil_fog": "CMBKEF.BMP",
"favorable_winds": "CMBKFW.BMP",
"cursed_ground": "CMBKCUR.BMP",
"rough": "CMBKRGH.BMP",
"ship_to_ship": "CMBKBOAT.BMP",
"ship": "CMBKDECK.BMP"
},
// WoG_Ac_format_to_def_names_mapping
"ac_mapping": [

View File

@ -25,7 +25,7 @@
{
"id" : 1,
"allowedTerrain" : ["dirt", "sand", "rough", "subterra"],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 3,
"height" : 2,
"blockedTiles" : [0, 1, 2],
@ -45,7 +45,7 @@
{
"id" : 3,
"allowedTerrain" : ["dirt", "rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 2,
"height" : 1,
"blockedTiles" : [0, 1],
@ -55,7 +55,7 @@
{
"id" : 4,
"allowedTerrain" : ["dirt", "rough", "subterra"],
"specialBattlefields" : [0, 1],
"specialBattlefields" : ["sand_shore", "cursed_ground"],
"width" : 2,
"height" : 1,
"blockedTiles" : [0, 1],
@ -135,7 +135,7 @@
{
"id" : 12,
"allowedTerrain" : ["dirt", "rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 3,
"height" : 3,
"blockedTiles" : [0, 1, 2, 3],
@ -145,7 +145,7 @@
{
"id" : 13,
"allowedTerrain" : ["dirt", "rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 3,
"height" : 2,
"blockedTiles" : [1, 2, -15],
@ -155,7 +155,7 @@
{
"id" : 14,
"allowedTerrain" : ["dirt", "rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 3,
"height" : 2,
"blockedTiles" : [2, -15, -16],
@ -165,7 +165,7 @@
{
"id" : 15,
"allowedTerrain" : ["dirt", "rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 3,
"height" : 3,
"blockedTiles" : [1, -16, -33],
@ -215,7 +215,7 @@
{
"id" : 20,
"allowedTerrain" : ["grass", "swamp"],
"specialBattlefields" : [2],
"specialBattlefields" : ["magic_plains"],
"width" : 2,
"height" : 2,
"blockedTiles" : [0, 1],
@ -235,7 +235,7 @@
{
"id" : 22,
"allowedTerrain" : ["grass"],
"specialBattlefields" : [2],
"specialBattlefields" : ["magic_plains"],
"width" : 6,
"height" : 2,
"blockedTiles" : [1, 2, 3, 4, -13, -14, -15, -16],
@ -415,7 +415,7 @@
{
"id" : 40,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 2,
"height" : 2,
"blockedTiles" : [0, 1, -16],
@ -425,7 +425,7 @@
{
"id" : 41,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 4,
"height" : 3,
"blockedTiles" : [-14, -15, -16, -32, -33],
@ -435,7 +435,7 @@
{
"id" : 42,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 3,
"height" : 2,
"blockedTiles" : [1, 2, -15, -16],
@ -445,7 +445,7 @@
{
"id" : 43,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 3,
"height" : 3,
"blockedTiles" : [-16, -32, -33],
@ -455,7 +455,7 @@
{
"id" : 44,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 3,
"height" : 3,
"blockedTiles" : [-15, -16, -32],
@ -575,7 +575,7 @@
{
"id" : 56,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 3,
"height" : 2,
"blockedTiles" : [1, -15, -16],
@ -585,7 +585,7 @@
{
"id" : 57,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 3,
"height" : 2,
"blockedTiles" : [0, 1, 2],
@ -595,7 +595,7 @@
{
"id" : 58,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 5,
"height" : 2,
"blockedTiles" : [1, 2, 3, -14, -15, -16],
@ -605,7 +605,7 @@
{
"id" : 59,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 4,
"height" : 2,
"blockedTiles" : [1, 2, -14, -15],
@ -615,7 +615,7 @@
{
"id" : 60,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 2,
"height" : 2,
"blockedTiles" : [0, 1, -16],
@ -625,7 +625,7 @@
{
"id" : 61,
"allowedTerrain" : [],
"specialBattlefields" : [3],
"specialBattlefields" : ["holy_ground"],
"width" : 1,
"height" : 1,
"blockedTiles" : [0],
@ -635,7 +635,7 @@
{
"id" : 62,
"allowedTerrain" : [],
"specialBattlefields" : [3],
"specialBattlefields" : ["holy_ground"],
"width" : 2,
"height" : 1,
"blockedTiles" : [0, 1],
@ -645,7 +645,7 @@
{
"id" : 63,
"allowedTerrain" : [],
"specialBattlefields" : [3],
"specialBattlefields" : ["holy_ground"],
"width" : 3,
"height" : 3,
"blockedTiles" : [1],
@ -655,7 +655,7 @@
{
"id" : 64,
"allowedTerrain" : [],
"specialBattlefields" : [3],
"specialBattlefields" : ["holy_ground"],
"width" : 3,
"height" : 2,
"blockedTiles" : [0, 1, 2],
@ -665,7 +665,7 @@
{
"id" : 65,
"allowedTerrain" : [],
"specialBattlefields" : [3],
"specialBattlefields" : ["holy_ground"],
"width" : 4,
"height" : 3,
"blockedTiles" : [0, 1, 2, 3],
@ -675,7 +675,7 @@
{
"id" : 66,
"allowedTerrain" : [],
"specialBattlefields" : [4],
"specialBattlefields" : ["evil_fog"],
"width" : 1,
"height" : 1,
"blockedTiles" : [0],
@ -685,7 +685,7 @@
{
"id" : 67,
"allowedTerrain" : [],
"specialBattlefields" : [4],
"specialBattlefields" : ["evil_fog"],
"width" : 2,
"height" : 1,
"blockedTiles" : [0, 1],
@ -695,7 +695,7 @@
{
"id" : 68,
"allowedTerrain" : [],
"specialBattlefields" : [4],
"specialBattlefields" : ["evil_fog"],
"width" : 3,
"height" : 2,
"blockedTiles" : [0, 1, 2],
@ -705,7 +705,7 @@
{
"id" : 69,
"allowedTerrain" : [],
"specialBattlefields" : [4],
"specialBattlefields" : ["evil_fog"],
"width" : 4,
"height" : 2,
"blockedTiles" : [1, 2],
@ -715,7 +715,7 @@
{
"id" : 70,
"allowedTerrain" : [],
"specialBattlefields" : [4],
"specialBattlefields" : ["evil_fog"],
"width" : 6,
"height" : 2,
"blockedTiles" : [1, 2, 3, -12, -13],
@ -725,7 +725,7 @@
{
"id" : 71,
"allowedTerrain" : [],
"specialBattlefields" : [5],
"specialBattlefields" : ["clover_field"],
"width" : 1,
"height" : 1,
"blockedTiles" : [0],
@ -735,7 +735,7 @@
{
"id" : 72,
"allowedTerrain" : [],
"specialBattlefields" : [5],
"specialBattlefields" : ["clover_field"],
"width" : 3,
"height" : 1,
"blockedTiles" : [0, 1, 2],
@ -745,7 +745,7 @@
{
"id" : 73,
"allowedTerrain" : [],
"specialBattlefields" : [5],
"specialBattlefields" : ["clover_field"],
"width" : 3,
"height" : 2,
"blockedTiles" : [1, 2, -15, -16],
@ -755,7 +755,7 @@
{
"id" : 74,
"allowedTerrain" : [],
"specialBattlefields" : [5],
"specialBattlefields" : ["clover_field"],
"width" : 4,
"height" : 2,
"blockedTiles" : [0, 1, 2, -14, -15, -16],
@ -765,7 +765,7 @@
{
"id" : 75,
"allowedTerrain" : [],
"specialBattlefields" : [6],
"specialBattlefields" : ["lucid_pools"],
"width" : 1,
"height" : 1,
"blockedTiles" : [0],
@ -775,7 +775,7 @@
{
"id" : 76,
"allowedTerrain" : [],
"specialBattlefields" : [6],
"specialBattlefields" : ["lucid_pools"],
"width" : 2,
"height" : 1,
"blockedTiles" : [0, 1],
@ -785,7 +785,7 @@
{
"id" : 77,
"allowedTerrain" : [],
"specialBattlefields" : [6],
"specialBattlefields" : ["lucid_pools"],
"width" : 3,
"height" : 2,
"blockedTiles" : [0, -15, -16],
@ -795,7 +795,7 @@
{
"id" : 78,
"allowedTerrain" : [],
"specialBattlefields" : [6],
"specialBattlefields" : ["lucid_pools"],
"width" : 5,
"height" : 2,
"blockedTiles" : [1, 2, 3, -13, -14, -15, -16],
@ -805,7 +805,7 @@
{
"id" : 79,
"allowedTerrain" : [],
"specialBattlefields" : [7],
"specialBattlefields" : ["fiery_fields"],
"width" : 1,
"height" : 1,
"blockedTiles" : [0],
@ -815,7 +815,7 @@
{
"id" : 80,
"allowedTerrain" : [],
"specialBattlefields" : [7],
"specialBattlefields" : ["fiery_fields"],
"width" : 2,
"height" : 1,
"blockedTiles" : [0, 1],
@ -825,7 +825,7 @@
{
"id" : 81,
"allowedTerrain" : [],
"specialBattlefields" : [7],
"specialBattlefields" : ["fiery_fields"],
"width" : 3,
"height" : 2,
"blockedTiles" : [0, 1, 2, -15],
@ -835,7 +835,7 @@
{
"id" : 82,
"allowedTerrain" : [],
"specialBattlefields" : [7],
"specialBattlefields" : ["fiery_fields"],
"width" : 4,
"height" : 2,
"blockedTiles" : [1, 2, 3, -15, -16],
@ -845,7 +845,7 @@
{
"id" : 83,
"allowedTerrain" : [],
"specialBattlefields" : [7],
"specialBattlefields" : ["fiery_fields"],
"width" : 3,
"height" : 3,
"blockedTiles" : [0, 1, 2, 3, -14, -15, -16],
@ -855,7 +855,7 @@
{
"id" : 84,
"allowedTerrain" : [],
"specialBattlefields" : [8],
"specialBattlefields" : ["rocklands"],
"width" : 1,
"height" : 1,
"blockedTiles" : [0],
@ -865,7 +865,7 @@
{
"id" : 85,
"allowedTerrain" : [],
"specialBattlefields" : [8],
"specialBattlefields" : ["rocklands"],
"width" : 2,
"height" : 1,
"blockedTiles" : [0, 1],
@ -875,7 +875,7 @@
{
"id" : 86,
"allowedTerrain" : [],
"specialBattlefields" : [8],
"specialBattlefields" : ["rocklands"],
"width" : 3,
"height" : 1,
"blockedTiles" : [0, 1, 2],
@ -885,7 +885,7 @@
{
"id" : 87,
"allowedTerrain" : [],
"specialBattlefields" : [8],
"specialBattlefields" : ["rocklands"],
"width" : 4,
"height" : 2,
"blockedTiles" : [1, 2, 3, -15, -16],
@ -895,7 +895,7 @@
{
"id" : 88,
"allowedTerrain" : [],
"specialBattlefields" : [9],
"specialBattlefields" : ["magic_clouds"],
"width" : 1,
"height" : 1,
"blockedTiles" : [0],
@ -905,7 +905,7 @@
{
"id" : 89,
"allowedTerrain" : [],
"specialBattlefields" : [9],
"specialBattlefields" : ["magic_clouds"],
"width" : 2,
"height" : 2,
"blockedTiles" : [1, -16],
@ -915,7 +915,7 @@
{
"id" : 90,
"allowedTerrain" : [],
"specialBattlefields" : [9],
"specialBattlefields" : ["magic_clouds"],
"width" : 4,
"height" : 2,
"blockedTiles" : [0, 1, -14, -15],
@ -1053,7 +1053,7 @@
{
"id" : 14,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 186,
"height" : 212,
"blockedTiles" : [55, 72, 90, 107, 125, 126, 127, 128, 129, 130, 131, 132],
@ -1062,7 +1062,7 @@
{
"id" : 15,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 347,
"height" : 174,
"blockedTiles" : [41, 59, 76, 94, 111, 129, 143, 144, 145],
@ -1071,7 +1071,7 @@
{
"id" : 16,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 294,
"height" : 169,
"blockedTiles" : [40, 41, 42, 43, 58, 75, 93, 110, 128, 145],
@ -1080,7 +1080,7 @@
{
"id" : 17,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 165,
"height" : 257,
"blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 89, 105],
@ -1089,7 +1089,7 @@
{
"id" : 18,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 208,
"height" : 268,
"blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 90, 91, 92, 93, 94, 95, 96, 97],
@ -1098,7 +1098,7 @@
{
"id" : 19,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 252,
"height" : 254,
"blockedTiles" : [73, 74, 75, 76, 77, 78, 91, 92, 93, 94],
@ -1107,7 +1107,7 @@
{
"id" : 20,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 278,
"height" : 128,
"blockedTiles" : [23, 40, 58, 75, 93, 110, 128, 145, 163],
@ -1116,7 +1116,7 @@
{
"id" : 21,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 208,
"height" : 268,
"blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 90, 91, 92, 93, 94, 95, 96, 97],
@ -1125,7 +1125,7 @@
{
"id" : 22,
"allowedTerrain" : ["rough"],
"specialBattlefields" : [1],
"specialBattlefields" : ["cursed_ground"],
"width" : 168,
"height" : 212,
"blockedTiles" : [73, 74, 75, 76, 77, 78, 79, 90, 91, 92, 93, 94, 95, 96, 97, 106, 107, 108, 109, 110, 111, 112],
@ -1134,7 +1134,7 @@
{
"id" : 23,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 147,
"height" : 264,
"blockedTiles" : [72, 73, 74, 75, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98],
@ -1143,7 +1143,7 @@
{
"id" : 24,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 178,
"height" : 262,
"blockedTiles" : [71, 72, 73, 74, 75, 76, 77, 78, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98],
@ -1152,7 +1152,7 @@
{
"id" : 25,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 173,
"height" : 257,
"blockedTiles" : [72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 89, 90, 105, 106],
@ -1161,7 +1161,7 @@
{
"id" : 26,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 241,
"height" : 272,
"blockedTiles" : [73, 91, 108, 109, 110, 111, 112, 113],
@ -1170,7 +1170,7 @@
{
"id" : 27,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 261,
"height" : 129,
"blockedTiles" : [27, 28, 43, 44, 60, 61, 76, 77, 93, 94, 109, 110, 126, 127, 142, 143, 159],
@ -1179,7 +1179,7 @@
{
"id" : 28,
"allowedTerrain" : [],
"specialBattlefields" : [0],
"specialBattlefields" : ["sand_shore"],
"width" : 180,
"height" : 154,
"blockedTiles" : [22, 38, 39, 40, 44, 45, 46, 55, 56, 57, 62, 63, 123, 124, 125, 130, 131, 140, 141, 146, 147, 148],
@ -1188,7 +1188,7 @@
{
"id" : 29,
"allowedTerrain" : [],
"specialBattlefields" : [5],
"specialBattlefields" : ["clover_field"],
"width" : 304,
"height" : 264,
"blockedTiles" : [76, 77, 92, 93, 94, 95, 109, 110, 111],
@ -1197,7 +1197,7 @@
{
"id" : 30,
"allowedTerrain" : [],
"specialBattlefields" : [6],
"specialBattlefields" : ["lucid_pools"],
"width" : 256,
"height" : 257,
"blockedTiles" : [76, 77, 78, 92, 93, 94, 107, 108, 109],
@ -1206,7 +1206,7 @@
{
"id" : 31,
"allowedTerrain" : [],
"specialBattlefields" : [7],
"specialBattlefields" : ["fiery_fields"],
"width" : 257,
"height" : 255,
"blockedTiles" : [76, 77, 91, 92, 93, 94, 95, 108, 109, 110, 111],
@ -1215,7 +1215,7 @@
{
"id" : 32,
"allowedTerrain" : [],
"specialBattlefields" : [8],
"specialBattlefields" : ["rocklands"],
"width" : 277,
"height" : 218,
"blockedTiles" : [60, 61, 75, 76, 77, 91, 92, 93, 94, 95],
@ -1224,7 +1224,7 @@
{
"id" : 33,
"allowedTerrain" : [],
"specialBattlefields" : [9],
"specialBattlefields" : ["magic_clouds"],
"width" : 300,
"height" : 214,
"blockedTiles" : [59, 60, 74, 75, 76, 93, 94, 95, 111, 112],

View File

@ -6,7 +6,9 @@
"minimapBlocked" : [ 57, 40, 8 ],
"music" : "Dirt.mp3",
"tiles" : "DIRTTL",
"code" : "dt"
"code" : "dt",
"battleFields" : ["dirt_birches", "dirt_hills", "dirt_pines"],
"terrainViewPatterns" : "dirt"
},
"sand" :
{
@ -15,7 +17,10 @@
"minimapBlocked" : [ 165, 158, 107 ],
"music" : "Sand.mp3",
"tiles" : "SANDTL",
"code" : "sa"
"code" : "sa",
"battleFields" : ["sand_mesas"],
"transitionRequired" : true,
"terrainViewPatterns" : "sand"
},
"grass" :
{
@ -24,7 +29,8 @@
"minimapBlocked" : [ 0, 48, 0 ],
"music" : "Grass.mp3",
"tiles" : "GRASTL",
"code" : "gr"
"code" : "gr",
"battleFields" : ["grass_hills", "grass_pines"]
},
"snow" :
{
@ -33,7 +39,8 @@
"minimapBlocked" : [ 140, 158, 156 ],
"music" : "Snow.mp3",
"tiles" : "SNOWTL",
"code" : "sn"
"code" : "sn",
"battleFields" : ["snow_mountains", "snow_trees"]
},
"swamp" :
{
@ -42,7 +49,8 @@
"minimapBlocked" : [ 33, 89, 66 ],
"music" : "Swamp.mp3",
"tiles" : "SWMPTL",
"code" : "sw"
"code" : "sw",
"battleFields" : ["swamp_trees"]
},
"rough" :
{
@ -51,7 +59,8 @@
"minimapBlocked" : [ 99, 81, 33 ],
"music" : "Rough.mp3",
"tiles" : "ROUGTL",
"code" : "rg"
"code" : "rg",
"battleFields" : ["rough"]
},
"subterra" :
{
@ -61,7 +70,8 @@
"music" : "Underground.mp3",
"tiles" : "SUBBTL",
"type" : "SUB",
"code" : "sb"
"code" : "sb",
"battleFields" : ["subterranean"]
},
"lava" :
{
@ -70,7 +80,8 @@
"minimapBlocked" : [ 41, 40, 41 ],
"music" : "Lava.mp3",
"tiles" : "LAVATL",
"code" : "lv"
"code" : "lv",
"battleFields" : ["lava"]
},
"water" :
{
@ -80,7 +91,10 @@
"music" : "Water.mp3",
"tiles" : "WATRTL",
"type" : "WATER",
"code" : "wt"
"code" : "wt",
"battleFields" : ["ship"],
"transitionRequired" : true,
"terrainViewPatterns" : "water"
},
"rock" :
{
@ -90,6 +104,9 @@
"music" : "Underground.mp3", // Impossible in H3
"tiles" : "ROCKTL",
"type" : "ROCK",
"code" : "rc"
"code" : "rc",
"battleFields" : ["rocklands"],
"transitionRequired" : true,
"terrainViewPatterns" : "rock"
}
}

View File

@ -1894,17 +1894,17 @@ void CGameState::initVisitingAndGarrisonedHeroes()
}
}
BFieldType CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & rand)
BattleField CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & rand)
{
if(!tile.valid() && curB)
tile = curB->tile;
else if(!tile.valid() && !curB)
return BFieldType::NONE;
return BattleField::NONE;
const TerrainTile &t = map->getTile(tile);
//fight in mine -> subterranean
if(dynamic_cast<const CGMine *>(t.visitableObjects.front()))
return BFieldType::SUBTERRANEAN;
return BattleField("subterranean");
for(auto &obj : map->objects)
{
@ -1915,56 +1915,32 @@ BFieldType CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & ra
switch(obj->ID)
{
case Obj::CLOVER_FIELD:
return BFieldType::CLOVER_FIELD;
return BattleField("clover_field");
case Obj::CURSED_GROUND1: case Obj::CURSED_GROUND2:
return BFieldType::CURSED_GROUND;
return BattleField("cursed_ground");
case Obj::EVIL_FOG:
return BFieldType::EVIL_FOG;
return BattleField("evil_fog");
case Obj::FAVORABLE_WINDS:
return BFieldType::FAVORABLE_WINDS;
return BattleField("favorable_winds");
case Obj::FIERY_FIELDS:
return BFieldType::FIERY_FIELDS;
return BattleField("fiery_fields");
case Obj::HOLY_GROUNDS:
return BFieldType::HOLY_GROUND;
return BattleField("holy_ground");
case Obj::LUCID_POOLS:
return BFieldType::LUCID_POOLS;
return BattleField("lucid_pools");
case Obj::MAGIC_CLOUDS:
return BFieldType::MAGIC_CLOUDS;
return BattleField("magic_clouds");
case Obj::MAGIC_PLAINS1: case Obj::MAGIC_PLAINS2:
return BFieldType::MAGIC_PLAINS;
return BattleField("magic_plains");
case Obj::ROCKLANDS:
return BFieldType::ROCKLANDS;
return BattleField("rocklands");
}
}
if(map->isCoastalTile(tile)) //coastal tile is always ground
return BFieldType::SAND_SHORE;
if(t.terType == Terrain("dirt"))
return BFieldType(rand.nextInt(3, 5));
if(t.terType == Terrain("sand"))
return BFieldType::SAND_MESAS; //TODO: coast support
if(t.terType == Terrain("grass"))
return BFieldType(rand.nextInt(6, 7));
if(t.terType == Terrain("snow"))
return BFieldType(rand.nextInt(10, 11));
if(t.terType == Terrain("swamp"))
return BFieldType::SWAMP_TREES;
if(t.terType == Terrain("rough"))
return BFieldType::ROUGH;
if(t.terType.isUnderground())
return BFieldType::SUBTERRANEAN;
if(t.terType == Terrain("lava"))
return BFieldType::LAVA;
if(t.terType.isWater())
return BFieldType::SHIP;
if(!t.terType.isPassable())
return BFieldType::ROCKLANDS;
return BattleField("sand_shore");
//TODO: STUB, support new battlegrounds
return BFieldType::DIRT_HILLS;
return BFieldType::NONE;
return *RandomGeneratorUtil::nextItem(Terrain::Manager::getInfo(t.terType).battleFields, rand);
}
UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)

View File

@ -179,7 +179,7 @@ public:
void giveHeroArtifact(CGHeroInstance *h, ArtifactID aid);
void apply(CPack *pack);
BFieldType battleGetBattlefieldType(int3 tile, CRandomGenerator & rand);
BattleField battleGetBattlefieldType(int3 tile, CRandomGenerator & rand);
UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile

View File

@ -177,9 +177,9 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
return ret;
}
bool CObstacleInfo::isAppropriate(Terrain terrainType, int specialBattlefield) const
bool CObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & specialBattlefield) const
{
if(specialBattlefield != -1)
if(!allowedSpecialBfields.empty() && specialBattlefield != BattleField::NONE)
return vstd::contains(allowedSpecialBfields, specialBattlefield);
return vstd::contains(allowedTerrains, terrainType);
@ -817,28 +817,35 @@ void CHeroHandler::loadExperience()
void CHeroHandler::loadObstacles()
{
auto loadObstacles = [](const JsonNode &node, bool absolute, std::map<int, CObstacleInfo> &out)
auto loadObstacles = [](const JsonNode & node, bool absolute, std::vector<CObstacleInfo> & out)
{
for(const JsonNode &obs : node.Vector())
{
int ID = static_cast<int>(obs["id"].Float());
CObstacleInfo & obi = out[ID];
obi.ID = ID;
out.emplace_back();
CObstacleInfo & obi = out.back();
obi.defName = obs["defname"].String();
obi.width = static_cast<si32>(obs["width"].Float());
obi.height = static_cast<si32>(obs["height"].Float());
for(auto & t : obs["allowedTerrain"].Vector())
obi.allowedTerrains.emplace_back(t.String());
obi.allowedSpecialBfields = obs["specialBattlefields"].convertTo<std::vector<BFieldType> >();
for(auto & t : obs["specialBattlefields"].Vector())
obi.allowedSpecialBfields.emplace_back(t.String());
obi.blockedTiles = obs["blockedTiles"].convertTo<std::vector<si16> >();
obi.isAbsoluteObstacle = absolute;
}
};
const JsonNode config(ResourceID("config/obstacles.json"));
loadObstacles(config["obstacles"], false, obstacles);
loadObstacles(config["absoluteObstacles"], true, absoluteObstacles);
//loadObstacles(config["moats"], true, moats);
auto allConfigs = VLC->modh->getActiveMods();
allConfigs.insert(allConfigs.begin(), "core");
for(auto & mod : allConfigs)
{
if(!CResourceHandler::get(mod)->existsResource(ResourceID("config/obstacles.json")))
continue;
const JsonNode config(mod, ResourceID("config/obstacles.json"));
loadObstacles(config["obstacles"], false, obstacles);
loadObstacles(config["absoluteObstacles"], true, absoluteObstacles);
}
}
/// convert h3-style ID (e.g. Gobin Wolf Rider) to vcmi (e.g. goblinWolfRider)

View File

@ -27,6 +27,7 @@ class JsonNode;
class CRandomGenerator;
class JsonSerializeFormat;
class Terrain;
class BattleField;
struct SSpecialtyInfo
{ si32 type;
@ -224,10 +225,9 @@ public:
struct DLL_LINKAGE CObstacleInfo
{
si32 ID;
std::string defName;
std::vector<Terrain> allowedTerrains;
std::vector<BFieldType> allowedSpecialBfields;
std::vector<BattleField> allowedSpecialBfields;
ui8 isAbsoluteObstacle; //there may only one such obstacle in battle and its position is always the same
si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm)
@ -235,11 +235,10 @@ 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'
bool isAppropriate(Terrain terrainType, int specialBattlefield = -1) const;
bool isAppropriate(const Terrain & terrainType, const BattleField & specialBattlefield) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ID;
h & defName;
h & allowedTerrains;
h & allowedSpecialBfields;
@ -316,8 +315,8 @@ public:
};
std::vector<SBallisticsLevelInfo> ballistics; //info about ballistics ability per level; [0] - none; [1] - basic; [2] - adv; [3] - expert
std::map<int, CObstacleInfo> obstacles; //info about obstacles that may be placed on battlefield
std::map<int, CObstacleInfo> absoluteObstacles; //info about obstacles that may be placed on battlefield
std::vector<CObstacleInfo> obstacles; //info about obstacles that may be placed on battlefield
std::vector<CObstacleInfo> absoluteObstacles; //info about obstacles that may be placed on battlefield
ui32 level(ui64 experience) const; //calculates level corresponding to given experience amount
ui64 reqExp(ui32 level) const; //calculates experience required for given level

View File

@ -844,26 +844,6 @@ namespace SecSkillLevel
};
}
//follows ERM BI (battle image) format
namespace BattlefieldBI
{
enum BattlefieldBI
{
NONE = -1,
COASTAL,
CURSED_GROUND,
MAGIC_PLAINS,
HOLY_GROUND,
EVIL_FOG,
CLOVER_FIELD,
LUCID_POOLS,
FIERY_FIELDS,
ROCKLANDS,
MAGIC_CLOUDS
};
}
namespace Date
{
enum EDateType
@ -940,29 +920,6 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EPathfindingLayer
ID_LIKE_OPERATORS(EPathfindingLayer, EPathfindingLayer::EEPathfindingLayer)
class BFieldType
{
public:
// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines
//8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields
//15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog
//21. "favorable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
enum EBFieldType {NONE = -1, NONE2, SAND_SHORE, SAND_MESAS, DIRT_BIRCHES, DIRT_HILLS, DIRT_PINES, GRASS_HILLS,
GRASS_PINES, LAVA, MAGIC_PLAINS, SNOW_MOUNTAINS, SNOW_TREES, SUBTERRANEAN, SWAMP_TREES, FIERY_FIELDS,
ROCKLANDS, MAGIC_CLOUDS, LUCID_POOLS, HOLY_GROUND, CLOVER_FIELD, EVIL_FOG, FAVORABLE_WINDS, CURSED_GROUND,
ROUGH, SHIP_TO_SHIP, SHIP
};
BFieldType(EBFieldType _num = NONE) : num(_num)
{}
ID_LIKE_CLASS_COMMON(BFieldType, EBFieldType)
EBFieldType num;
};
ID_LIKE_OPERATORS(BFieldType, BFieldType::EBFieldType)
namespace EPlayerStatus
{
enum EStatus {WRONG = -1, INGAME, LOSER, WINNER};

View File

@ -18,6 +18,8 @@
const Terrain Terrain::ANY("ANY");
const BattleField BattleField::NONE("");
Terrain Terrain::createTerrainTypeH3M(int tId)
{
static std::array<std::string, 10> terrainsH3M
@ -106,6 +108,25 @@ Terrain::Manager::Manager()
assert(info.typeCode.length() == 2);
}
if(!terr.second["battleFields"].isNull())
{
for(auto & t : terr.second["battleFields"].Vector())
{
info.battleFields.emplace_back(t.String());
}
}
info.transitionRequired = false;
if(!terr.second["transitionRequired"].isNull())
{
info.transitionRequired = terr.second["transitionRequired"].Bool();
}
info.terrainViewPatterns = "normal";
if(!terr.second["terrainViewPatterns"].isNull())
{
info.terrainViewPatterns = terr.second["terrainViewPatterns"].String();
}
terrainInfo[Terrain(terr.first)] = info;
}
@ -202,3 +223,31 @@ bool Terrain::isNative() const
{
return name.empty();
}
bool Terrain::isTransitionRequired() const
{
return Terrain::Manager::getInfo(*this).transitionRequired;
}
bool operator==(const BattleField & l, const BattleField & r)
{
return l.name == r.name;
}
bool operator!=(const BattleField & l, const BattleField & r)
{
return l.name != r.name;
}
bool operator<(const BattleField & l, const BattleField & r)
{
return l.name < r.name;
}
BattleField::operator std::string() const
{
return name;
}
int BattleField::hash() const
{
return std::hash<std::string>{}(name);
}

View File

@ -13,6 +13,41 @@
#include "ConstTransitivePtr.h"
#include "JsonNode.h"
class DLL_LINKAGE BattleField
{
public:
// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines
//8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields
//15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog
//21. "favorable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
/*enum EBFieldType {NONE = -1, NONE2, SAND_SHORE, SAND_MESAS, DIRT_BIRCHES, DIRT_HILLS, DIRT_PINES, GRASS_HILLS,
GRASS_PINES, LAVA, MAGIC_PLAINS, SNOW_MOUNTAINS, SNOW_TREES, SUBTERRANEAN, SWAMP_TREES, FIERY_FIELDS,
ROCKLANDS, MAGIC_CLOUDS, LUCID_POOLS, HOLY_GROUND, CLOVER_FIELD, EVIL_FOG, FAVORABLE_WINDS, CURSED_GROUND,
ROUGH, SHIP_TO_SHIP, SHIP
};*/
BattleField(const std::string & type = "") : name(type)
{}
static const BattleField NONE;
DLL_LINKAGE friend bool operator==(const BattleField & l, const BattleField & r);
DLL_LINKAGE friend bool operator!=(const BattleField & l, const BattleField & r);
DLL_LINKAGE friend bool operator<(const BattleField & l, const BattleField & r);
operator std::string() const;
int hash() const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & name;
}
protected:
std::string name;
};
class DLL_LINKAGE Terrain
{
public:
@ -27,14 +62,17 @@ public:
};
int moveCost;
bool transitionRequired;
std::array<int, 3> minimapBlocked;
std::array<int, 3> minimapUnblocked;
std::string musicFilename;
std::string tilesFilename;
std::string terrainText;
std::string typeCode;
std::string terrainViewPatterns;
int horseSoundId;
Type type;
std::vector<BattleField> battleFields;
};
class DLL_LINKAGE Manager
@ -77,6 +115,8 @@ public:
bool isPassable() const; //ROCK
bool isUnderground() const;
bool isNative() const;
bool isTransitionRequired() const;
operator std::string() const;

View File

@ -187,7 +187,7 @@ struct RangeGenerator
std::function<int()> myRand;
};
BattleInfo * BattleInfo::setupBattle(int3 tile, Terrain terrain, BFieldType battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town)
BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain, const BattleField & battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town)
{
CMP_stack cmpst;
auto curB = new BattleInfo();
@ -239,24 +239,24 @@ BattleInfo * BattleInfo::setupBattle(int3 tile, Terrain terrain, BFieldType batt
//randomize obstacles
if (town == nullptr && !creatureBank) //do it only when it's not siege and not creature bank
{
const int ABSOLUTE_OBSTACLES_COUNT = 34, USUAL_OBSTACLES_COUNT = 91; //shouldn't be changes if we want H3-like obstacle placement
const int ABSOLUTE_OBSTACLES_COUNT = VLC->heroh->absoluteObstacles.size();
const int USUAL_OBSTACLES_COUNT = VLC->heroh->obstacles.size(); //shouldn't be changes if we want H3-like obstacle placement
RandGen r;
auto ourRand = [&](){ return r.rand(); };
r.srand(tile);
r.rand(1,8); //battle sound ID to play... can't do anything with it here
int tilesToBlock = r.rand(5,12);
const int specialBattlefield = battlefieldTypeToBI(battlefieldType);
std::vector<BattleHex> blockedTiles;
auto appropriateAbsoluteObstacle = [&](int id)
{
return VLC->heroh->absoluteObstacles[id].isAppropriate(curB->terrainType, specialBattlefield);
return VLC->heroh->absoluteObstacles[id].isAppropriate(curB->terrainType, battlefieldType);
};
auto appropriateUsualObstacle = [&](int id) -> bool
{
return VLC->heroh->obstacles[id].isAppropriate(curB->terrainType, specialBattlefield);
return VLC->heroh->obstacles[id].isAppropriate(curB->terrainType, battlefieldType);
};
if(r.rand(1,100) <= 40) //put cliff-like obstacle
@ -460,71 +460,60 @@ BattleInfo * BattleInfo::setupBattle(int3 tile, Terrain terrain, BFieldType batt
//giving terrain overlay premies
int bonusSubtype = -1;
switch(battlefieldType)
{
case BFieldType::MAGIC_PLAINS:
{
bonusSubtype = 0;
}
FALLTHROUGH
case BFieldType::FIERY_FIELDS:
{
if(bonusSubtype == -1) bonusSubtype = 1;
}
FALLTHROUGH
case BFieldType::ROCKLANDS:
{
if(bonusSubtype == -1) bonusSubtype = 8;
}
FALLTHROUGH
case BFieldType::MAGIC_CLOUDS:
{
if(bonusSubtype == -1) bonusSubtype = 2;
}
FALLTHROUGH
case BFieldType::LUCID_POOLS:
{
if(bonusSubtype == -1) bonusSubtype = 4;
}
{ //common part for cases 9, 14, 15, 16, 17
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MAGIC_SCHOOL_SKILL, Bonus::TERRAIN_OVERLAY, 3, battlefieldType, bonusSubtype));
break;
}
case BFieldType::HOLY_GROUND:
{
std::string goodArmyDesc = VLC->generaltexth->arraytxt[123];
goodArmyDesc.erase(goodArmyDesc.size() - 2, 2); //omitting hardcoded +1 in description
std::string evilArmyDesc = VLC->generaltexth->arraytxt[124];
evilArmyDesc.erase(evilArmyDesc.size() - 2, 2);
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, +1, battlefieldType, goodArmyDesc, 0)->addLimiter(good));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, -1, battlefieldType, evilArmyDesc, 0)->addLimiter(evil));
break;
}
case BFieldType::CLOVER_FIELD:
{ //+2 luck bonus for neutral creatures
std::string desc = VLC->generaltexth->arraytxt[83];
desc.erase(desc.size() - 2, 2);
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::LUCK, Bonus::TERRAIN_OVERLAY, +2, battlefieldType, desc, 0)->addLimiter(neutral));
break;
}
case BFieldType::EVIL_FOG:
{
std::string goodArmyDesc = VLC->generaltexth->arraytxt[126];
goodArmyDesc.erase(goodArmyDesc.size() - 2, 2);
std::string evilArmyDesc = VLC->generaltexth->arraytxt[125];
evilArmyDesc.erase(evilArmyDesc.size() - 2, 2);
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, -1, battlefieldType, goodArmyDesc, 0)->addLimiter(good));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, +1, battlefieldType, evilArmyDesc, 0)->addLimiter(evil));
break;
}
case BFieldType::CURSED_GROUND:
{
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::NO_MORALE, Bonus::TERRAIN_OVERLAY, 0, battlefieldType, VLC->generaltexth->arraytxt[112], 0));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::NO_LUCK, Bonus::TERRAIN_OVERLAY, 0, battlefieldType, VLC->generaltexth->arraytxt[81], 0));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::BLOCK_MAGIC_ABOVE, Bonus::TERRAIN_OVERLAY, 1, battlefieldType, 0, Bonus::INDEPENDENT_MIN));
break;
}
if(battlefieldType == BattleField("magic_plains"))
{
bonusSubtype = 0;
}
if(battlefieldType == BattleField("fiery_fields"))
{
if(bonusSubtype == -1) bonusSubtype = 1;
}
if(battlefieldType == BattleField("rocklands"))
{
if(bonusSubtype == -1) bonusSubtype = 8;
}
if(battlefieldType == BattleField("magic_clouds"))
{
if(bonusSubtype == -1) bonusSubtype = 2;
}
if(battlefieldType == BattleField("lucid_pools"))
{
if(bonusSubtype == -1) bonusSubtype = 4;
}
if(bonusSubtype == -1)
{ //common part for cases 9, 14, 15, 16, 17
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MAGIC_SCHOOL_SKILL,Bonus::TERRAIN_OVERLAY, 3, battlefieldType.hash(), bonusSubtype));
}
else if(battlefieldType == BattleField("holy_ground"))
{
std::string goodArmyDesc = VLC->generaltexth->arraytxt[123];
goodArmyDesc.erase(goodArmyDesc.size() - 2, 2); //omitting hardcoded +1 in description
std::string evilArmyDesc = VLC->generaltexth->arraytxt[124];
evilArmyDesc.erase(evilArmyDesc.size() - 2, 2);
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, +1, battlefieldType.hash(), goodArmyDesc, 0)->addLimiter(good));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, -1, battlefieldType.hash(), evilArmyDesc, 0)->addLimiter(evil));
}
else if(battlefieldType == BattleField("clover_field"))
{ //+2 luck bonus for neutral creatures
std::string desc = VLC->generaltexth->arraytxt[83];
desc.erase(desc.size() - 2, 2);
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::LUCK, Bonus::TERRAIN_OVERLAY, +2, battlefieldType.hash(), desc, 0)->addLimiter(neutral));
}
else if(battlefieldType == BattleField("evil_fog"))
{
std::string goodArmyDesc = VLC->generaltexth->arraytxt[126];
goodArmyDesc.erase(goodArmyDesc.size() - 2, 2);
std::string evilArmyDesc = VLC->generaltexth->arraytxt[125];
evilArmyDesc.erase(evilArmyDesc.size() - 2, 2);
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, -1, battlefieldType.hash(), goodArmyDesc, 0)->addLimiter(good));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::MORALE, Bonus::TERRAIN_OVERLAY, +1, battlefieldType.hash(), evilArmyDesc, 0)->addLimiter(evil));
}
else if(battlefieldType == BattleField("cursed_ground"))
{
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::NO_MORALE, Bonus::TERRAIN_OVERLAY, 0, battlefieldType.hash(), VLC->generaltexth->arraytxt[112], 0));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::NO_LUCK, Bonus::TERRAIN_OVERLAY, 0, battlefieldType.hash(), VLC->generaltexth->arraytxt[81], 0));
curB->addNewBonus(std::make_shared<Bonus>(Bonus::ONE_BATTLE, Bonus::BLOCK_MAGIC_ABOVE, Bonus::TERRAIN_OVERLAY, 1, battlefieldType.hash(), 0, Bonus::INDEPENDENT_MIN));
}
//overlay premies given
@ -580,30 +569,6 @@ ui8 BattleInfo::whatSide(PlayerColor player) const
return -1;
}
BattlefieldBI::BattlefieldBI BattleInfo::battlefieldTypeToBI(BFieldType bfieldType)
{
static const std::map<BFieldType, BattlefieldBI::BattlefieldBI> theMap =
{
{BFieldType::CLOVER_FIELD, BattlefieldBI::CLOVER_FIELD},
{BFieldType::CURSED_GROUND, BattlefieldBI::CURSED_GROUND},
{BFieldType::EVIL_FOG, BattlefieldBI::EVIL_FOG},
{BFieldType::FAVORABLE_WINDS, BattlefieldBI::NONE},
{BFieldType::FIERY_FIELDS, BattlefieldBI::FIERY_FIELDS},
{BFieldType::HOLY_GROUND, BattlefieldBI::HOLY_GROUND},
{BFieldType::LUCID_POOLS, BattlefieldBI::LUCID_POOLS},
{BFieldType::MAGIC_CLOUDS, BattlefieldBI::MAGIC_CLOUDS},
{BFieldType::MAGIC_PLAINS, BattlefieldBI::MAGIC_PLAINS},
{BFieldType::ROCKLANDS, BattlefieldBI::ROCKLANDS},
{BFieldType::SAND_SHORE, BattlefieldBI::COASTAL}
};
auto itr = theMap.find(bfieldType);
if(itr != theMap.end())
return itr->second;
return BattlefieldBI::NONE;
}
CStack * BattleInfo::getStack(int stackID, bool onlyAlive)
{
return const_cast<CStack *>(battleGetStackByID(stackID, onlyAlive));
@ -611,7 +576,7 @@ CStack * BattleInfo::getStack(int stackID, bool onlyAlive)
BattleInfo::BattleInfo()
: round(-1), activeStack(-1), town(nullptr), tile(-1,-1,-1),
battlefieldType(BFieldType::NONE), terrainType(),
battlefieldType(BattleField::NONE), terrainType(),
tacticsSide(0), tacticDistance(0)
{
setBattle(this);
@ -640,7 +605,7 @@ battle::Units BattleInfo::getUnitsIf(battle::UnitFilter predicate) const
}
BFieldType BattleInfo::getBattlefieldType() const
BattleField BattleInfo::getBattlefieldType() const
{
return battlefieldType;
}

View File

@ -19,6 +19,7 @@ class CStack;
class CStackInstance;
class CStackBasicDescriptor;
class Terrain;
class BattleField;
class DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallback, public IBattleState
{
@ -36,7 +37,7 @@ public:
std::vector<std::shared_ptr<CObstacleInstance> > obstacles;
SiegeInfo si;
BFieldType battlefieldType; //like !!BA:B
BattleField battlefieldType; //like !!BA:B
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
@ -72,7 +73,7 @@ public:
battle::Units getUnitsIf(battle::UnitFilter predicate) const override;
BFieldType getBattlefieldType() const override;
BattleField getBattlefieldType() const override;
Terrain getTerrainType() const override;
ObstacleCList getAllObstacles() const override;
@ -138,12 +139,10 @@ public:
const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
void localInit();
static BattleInfo * setupBattle(int3 tile, Terrain terrain, BFieldType battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town);
static BattleInfo * setupBattle(const int3 & tile, const Terrain & terrain, const BattleField & battlefieldType, const CArmedInstance * armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance * town);
ui8 whatSide(PlayerColor player) const;
static BattlefieldBI::BattlefieldBI battlefieldTypeToBI(BFieldType bfieldType); //converts above to ERM BI format
protected:
scripting::Pool * getContextPool() const override;
};

View File

@ -42,7 +42,7 @@ battle::Units BattleProxy::getUnitsIf(battle::UnitFilter predicate) const
return subject->battleGetUnitsIf(predicate);
}
BFieldType BattleProxy::getBattlefieldType() const
BattleField BattleProxy::getBattlefieldType() const
{
return subject->battleGetBattlefieldType();
}

View File

@ -29,7 +29,7 @@ public:
battle::Units getUnitsIf(battle::UnitFilter predicate) const override;
BFieldType getBattlefieldType() const override;
BattleField getBattlefieldType() const override;
Terrain getTerrainType() const override;
ObstacleCList getAllObstacles() const override;

View File

@ -1059,7 +1059,7 @@ AccessibilityInfo CBattleInfoCallback::getAccesibility() const
//special battlefields with logically unavailable tiles
std::vector<BattleHex> impassableHexes;
if(battleGetBattlefieldType().num == BFieldType::SHIP_TO_SHIP)
if(battleGetBattlefieldType() == BattleField("ship_to_ship"))
{
impassableHexes =
{

View File

@ -20,9 +20,9 @@ Terrain CBattleInfoEssentials::battleTerrainType() const
return getBattle()->getTerrainType();
}
BFieldType CBattleInfoEssentials::battleGetBattlefieldType() const
BattleField CBattleInfoEssentials::battleGetBattlefieldType() const
{
RETURN_IF_NOT_BATTLE(BFieldType::NONE);
RETURN_IF_NOT_BATTLE(BattleField::NONE);
return getBattle()->getBattlefieldType();
}

View File

@ -47,7 +47,7 @@ public:
const IBonusBearer * getBattleNode() const;
Terrain battleTerrainType() const override;
BFieldType battleGetBattlefieldType() const override;
BattleField battleGetBattlefieldType() const override;
int32_t battleGetEnchanterCounter(ui8 side) const;
std::vector<std::shared_ptr<const CObstacleInstance> > battleGetAllObstacles(boost::optional<BattlePerspective::BattlePerspective> perspective = boost::none) const; //returns all obstacles on the battlefield

View File

@ -13,7 +13,7 @@
#include "BattleHex.h"
struct CObstacleInstance;
class BFieldType;
class BattleField;
class Terrain;
namespace battle
@ -35,7 +35,7 @@ public:
virtual scripting::Pool * getContextPool() const = 0;
virtual Terrain battleTerrainType() const = 0;
virtual BFieldType battleGetBattlefieldType() const = 0;
virtual BattleField battleGetBattlefieldType() const = 0;
///return none if battle is ongoing; otherwise the victorious side (0/1) or 2 if it is a draw
virtual boost::optional<int> battleIsFinished() const = 0;

View File

@ -16,6 +16,7 @@ class UnitChanges;
struct Bonus;
class JsonNode;
class JsonSerializeFormat;
class BattleField;
namespace vstd
{
@ -40,7 +41,7 @@ public:
virtual battle::Units getUnitsIf(battle::UnitFilter predicate) const = 0;
virtual BFieldType getBattlefieldType() const = 0;
virtual BattleField getBattlefieldType() const = 0;
virtual Terrain getTerrainType() const = 0;
virtual ObstacleCList getAllObstacles() const = 0;

View File

@ -421,7 +421,6 @@ CTerrainViewPatternConfig::CTerrainViewPatternConfig()
}
// Add pattern to the patterns map
const auto & terGroup = getTerrainGroup(mappingPair.first);
std::vector<TerrainViewPattern> terrainViewPatternFlips;
terrainViewPatternFlips.push_back(terGroupPattern);
@ -431,7 +430,8 @@ CTerrainViewPatternConfig::CTerrainViewPatternConfig()
flipPattern(terGroupPattern, i); //FIXME: we flip in place - doesn't make much sense now, but used to work
terrainViewPatternFlips.push_back(terGroupPattern);
}
terrainViewPatterns[terGroup].push_back(terrainViewPatternFlips);
terrainViewPatterns[mappingPair.first].push_back(terrainViewPatternFlips);
}
}
else if(i == 1)
@ -453,29 +453,17 @@ CTerrainViewPatternConfig::~CTerrainViewPatternConfig()
}
ETerrainGroup::ETerrainGroup CTerrainViewPatternConfig::getTerrainGroup(const std::string & terGroup) const
const std::vector<CTerrainViewPatternConfig::TVPVector> & CTerrainViewPatternConfig::getTerrainViewPatterns(const Terrain & terrain) const
{
static const std::map<std::string, ETerrainGroup::ETerrainGroup> terGroups =
{
{"normal", ETerrainGroup::NORMAL},
{"dirt", ETerrainGroup::DIRT},
{"sand", ETerrainGroup::SAND},
{"water", ETerrainGroup::WATER},
{"rock", ETerrainGroup::ROCK},
};
auto it = terGroups.find(terGroup);
if(it == terGroups.end()) throw std::runtime_error(boost::str(boost::format("Terrain group '%s' does not exist.") % terGroup));
return it->second;
auto iter = terrainViewPatterns.find(Terrain::Manager::getInfo(terrain).terrainViewPatterns);
if(iter == terrainViewPatterns.end())
return terrainViewPatterns.at("normal");
return iter->second;
}
const std::vector<CTerrainViewPatternConfig::TVPVector> & CTerrainViewPatternConfig::getTerrainViewPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const
boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrainViewPatternById(const Terrain & terrain, const std::string & id) const
{
return terrainViewPatterns.find(terGroup)->second;
}
boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrainViewPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const
{
const std::vector<TVPVector> & groupPatterns = getTerrainViewPatternsForGroup(terGroup);
const std::vector<TVPVector> & groupPatterns = getTerrainViewPatterns(terrain);
for (const TVPVector & patternFlips : groupPatterns)
{
const TerrainViewPattern & pattern = patternFlips.front();
@ -486,9 +474,10 @@ boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrai
}
return boost::optional<const TerrainViewPattern &>();
}
boost::optional<const CTerrainViewPatternConfig::TVPVector &> CTerrainViewPatternConfig::getTerrainViewPatternsById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const
boost::optional<const CTerrainViewPatternConfig::TVPVector &> CTerrainViewPatternConfig::getTerrainViewPatternsById(const Terrain & terrain, const std::string & id) const
{
const std::vector<TVPVector> & groupPatterns = getTerrainViewPatternsForGroup(terGroup);
const std::vector<TVPVector> & groupPatterns = getTerrainViewPatterns(terrain);
for (const TVPVector & patternFlips : groupPatterns)
{
const TerrainViewPattern & pattern = patternFlips.front();
@ -705,7 +694,7 @@ void CDrawTerrainOperation::updateTerrainViews()
{
for(const auto & pos : invalidatedTerViews)
{
const auto & patterns = VLC->terviewh->getTerrainViewPatternsForGroup(getTerrainGroup(map->getTile(pos).terType));
const auto & patterns = VLC->terviewh->getTerrainViewPatterns(map->getTile(pos).terType);
// Detect a pattern which fits best
int bestPattern = -1;
@ -760,19 +749,6 @@ void CDrawTerrainOperation::updateTerrainViews()
}
}
ETerrainGroup::ETerrainGroup CDrawTerrainOperation::getTerrainGroup(Terrain terType) const
{
if(terType == Terrain("dirt"))
return ETerrainGroup::DIRT;
if(terType == Terrain("sand"))
return ETerrainGroup::SAND;
if(terType.isWater())
return ETerrainGroup::WATER;
if(!terType.isPassable())
return ETerrainGroup::ROCK;
return ETerrainGroup::NORMAL;
}
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainView(const int3 & pos, const std::vector<TerrainViewPattern> * pattern, int recDepth) const
{
for(int flip = 0; flip < 4; ++flip)
@ -790,7 +766,6 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainViewInner(const int3 & pos, const TerrainViewPattern & pattern, int recDepth) const
{
auto centerTerType = map->getTile(pos).terType;
auto centerTerGroup = getTerrainGroup(centerTerType);
int totalPoints = 0;
std::string transitionReplacement;
@ -857,8 +832,7 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
{
if(terType == centerTerType)
{
const auto & group = getTerrainGroup(centerTerType);
const auto & patternForRule = VLC->terviewh->getTerrainViewPatternsById(group, rule.name);
const auto & patternForRule = VLC->terviewh->getTerrainViewPatternsById(centerTerType, rule.name);
if(auto p = patternForRule)
{
auto rslt = validateTerrainView(currentPos, &(*p), 1);
@ -884,12 +858,30 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
// Validate cell with the ruleset of the pattern
bool nativeTestOk, nativeTestStrongOk;
nativeTestOk = nativeTestStrongOk = (rule.isNativeStrong() || rule.isNativeRule()) && !isAlien;
if(centerTerGroup == ETerrainGroup::NORMAL)
if(centerTerType == Terrain("dirt"))
{
nativeTestOk = rule.isNativeRule() && !terType.isTransitionRequired();
bool sandTestOk = (rule.isSandRule() || rule.isTransition())
&& terType.isTransitionRequired();
applyValidationRslt(rule.isAnyRule() || sandTestOk || nativeTestOk || nativeTestStrongOk);
}
else if(centerTerType == Terrain("sand"))
{
applyValidationRslt(true);
}
else if(centerTerType.isTransitionRequired()) //water, rock and some special terrains require sand transition
{
bool sandTestOk = (rule.isSandRule() || rule.isTransition())
&& isAlien;
applyValidationRslt(rule.isAnyRule() || sandTestOk || nativeTestOk);
}
else
{
bool dirtTestOk = (rule.isDirtRule() || rule.isTransition())
&& isAlien && !isSandType(terType);
&& isAlien && !terType.isTransitionRequired();
bool sandTestOk = (rule.isSandRule() || rule.isTransition())
&& isSandType(terType);
&& terType.isTransitionRequired();
if (transitionReplacement.empty() && rule.isTransition()
&& (dirtTestOk || sandTestOk))
@ -906,23 +898,6 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
applyValidationRslt(rule.isAnyRule() || dirtTestOk || sandTestOk || nativeTestOk);
}
}
else if(centerTerGroup == ETerrainGroup::DIRT)
{
nativeTestOk = rule.isNativeRule() && !isSandType(terType);
bool sandTestOk = (rule.isSandRule() || rule.isTransition())
&& isSandType(terType);
applyValidationRslt(rule.isAnyRule() || sandTestOk || nativeTestOk || nativeTestStrongOk);
}
else if(centerTerGroup == ETerrainGroup::SAND)
{
applyValidationRslt(true);
}
else if(centerTerGroup == ETerrainGroup::WATER || centerTerGroup == ETerrainGroup::ROCK)
{
bool sandTestOk = (rule.isSandRule() || rule.isTransition())
&& isAlien;
applyValidationRslt(rule.isAnyRule() || sandTestOk || nativeTestOk);
}
}
if(topPoints == -1)
@ -945,13 +920,6 @@ CDrawTerrainOperation::ValidationResult CDrawTerrainOperation::validateTerrainVi
}
}
bool CDrawTerrainOperation::isSandType(Terrain terType) const
{
if(terType.isWater() || terType == Terrain("sand") || !terType.isPassable())
return true;
return false;
}
void CDrawTerrainOperation::invalidateTerrainViews(const int3 & centerPos)
{
auto rect = extendTileAroundSafely(centerPos);

View File

@ -211,18 +211,6 @@ private:
std::list<std::unique_ptr<CMapOperation> > operations;
};
namespace ETerrainGroup
{
enum ETerrainGroup
{
NORMAL,
DIRT,
SAND,
WATER,
ROCK
};
}
/// The terrain view pattern describes a specific composition of terrain tiles
/// in a 3x3 matrix and notes which terrain view frame numbers can be used.
struct DLL_LINKAGE TerrainViewPattern
@ -338,15 +326,14 @@ public:
CTerrainViewPatternConfig();
~CTerrainViewPatternConfig();
const std::vector<TVPVector> & getTerrainViewPatternsForGroup(ETerrainGroup::ETerrainGroup terGroup) const;
boost::optional<const TerrainViewPattern &> getTerrainViewPatternById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const;
boost::optional<const TVPVector &> getTerrainViewPatternsById(ETerrainGroup::ETerrainGroup terGroup, const std::string & id) const;
const std::vector<TVPVector> & getTerrainViewPatterns(const Terrain & terrain) const;
boost::optional<const TerrainViewPattern &> getTerrainViewPatternById(const Terrain & terrain, const std::string & id) const;
boost::optional<const TVPVector &> getTerrainViewPatternsById(const Terrain & terrain, const std::string & id) const;
const TVPVector * getTerrainTypePatternById(const std::string & id) const;
ETerrainGroup::ETerrainGroup getTerrainGroup(const std::string & terGroup) const;
void flipPattern(TerrainViewPattern & pattern, int flip) const;
private:
std::map<ETerrainGroup::ETerrainGroup, std::vector<TVPVector> > terrainViewPatterns;
std::map<std::string, std::vector<TVPVector> > terrainViewPatterns;
std::map<std::string, TVPVector> terrainTypePatterns;
};
@ -385,13 +372,10 @@ private:
InvalidTiles getInvalidTiles(const int3 & centerPos) const;
void updateTerrainViews();
ETerrainGroup::ETerrainGroup getTerrainGroup(Terrain terType) const;
/// 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).
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;
/// Tests whether the given terrain type is a sand type. Sand types are: Water, Sand and Rock
bool isSandType(Terrain terType) const;
CTerrainSelection terrainSel;
Terrain terType;

View File

@ -12,8 +12,8 @@
#include "../ConstTransitivePtr.h"
#include "../GameConstants.h"
const ui32 SERIALIZATION_VERSION = 802;
const ui32 MINIMAL_SERIALIZATION_VERSION = 802;
const ui32 SERIALIZATION_VERSION = 803;
const ui32 MINIMAL_SERIALIZATION_VERSION = 803;
const std::string SAVEGAME_MAGIC = "VCMISVG";
class CHero;

View File

@ -520,7 +520,7 @@ bool BaseMechanics::adaptProblem(ESpellCastProblem::ESpellCastProblem source, Pr
caster->getCasterName(text);
target.add(std::move(text), spells::Problem::NORMAL);
}
else if(b && b->source == Bonus::TERRAIN_OVERLAY && b->sid == BFieldType::CURSED_GROUND)
else if(b && b->source == Bonus::TERRAIN_OVERLAY && b->sid == BattleField("cursed_ground").hash())
{
text.addTxt(MetaString::GENERAL_TXT, 537);
target.add(std::move(text), spells::Problem::NORMAL);

View File

@ -73,7 +73,7 @@ int BattleCbProxy::getBattlefieldType(lua_State * L)
auto ret = object->battleGetBattlefieldType();
return LuaStack::quickRetInt(L, static_cast<si32>(ret.num));
return LuaStack::quickRetStr(L, ret);
}
int BattleCbProxy::getTerrainType(lua_State * L)

View File

@ -2219,9 +2219,9 @@ void CGameHandler::setupBattle(int3 tile, const CArmedInstance *armies[2], const
if (gs->map->isCoastalTile(tile)) //coastal tile is always ground
terrain = Terrain("sand");
BFieldType terType = gs->battleGetBattlefieldType(tile, getRandomGenerator());
BattleField terType = gs->battleGetBattlefieldType(tile, getRandomGenerator());
if (heroes[0] && heroes[0]->boat && heroes[1] && heroes[1]->boat)
terType = BFieldType::SHIP_TO_SHIP;
terType = BattleField("ship_to_ship");
//send info about battles
BattleStart bs;

View File

@ -155,7 +155,7 @@ TEST_F(ERM_BU_G, Get)
source << "!?PI;" << std::endl;
source << "!!BU:G?v1;" << std::endl;
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BFieldType::SNOW_TREES));
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField("snow_trees")));
loadScript(VLC->scriptHandler->erm, source.str());
@ -174,7 +174,7 @@ TEST_F(ERM_BU_G, Get2)
source << "!?PI;" << std::endl;
source << "!!BU:G?v1;" << std::endl;
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BFieldType::EVIL_FOG));
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField("evil_fog")));
loadScript(VLC->scriptHandler->erm, source.str());
runServer();

View File

@ -194,7 +194,7 @@ public:
const auto t = gameCallback->getTile(tile);
Terrain terrain = t->terType;
BFieldType terType = BFieldType::GRASS_HILLS;
BattleField terType = BattleField("grass_hills");
//send info about battles

View File

@ -130,10 +130,9 @@ TEST(MapManager, DrawTerrain_View)
if(patternParts.size() != 2) throw std::runtime_error("A pattern should consist of two parts, the group and the id. Continue with next pattern.");
const auto & groupStr = patternParts[0];
const auto & id = patternParts[1];
auto terGroup = VLC->terviewh->getTerrainGroup(groupStr);
// Get mapping range
const auto & pattern = VLC->terviewh->getTerrainViewPatternById(terGroup, id);
const auto & pattern = VLC->terviewh->getTerrainViewPatternById(groupStr, id);
const auto & mapping = (*pattern).mapping;
const auto & positionsNode = node["pos"].Vector();

View File

@ -92,7 +92,7 @@ void BattleFake::setupEmptyBattlefield()
{
EXPECT_CALL(*this, getDefendedTown()).WillRepeatedly(Return(nullptr));
EXPECT_CALL(*this, getAllObstacles()).WillRepeatedly(Return(IBattleInfo::ObstacleCList()));
EXPECT_CALL(*this, getBattlefieldType()).WillRepeatedly(Return(BFieldType::NONE2));
EXPECT_CALL(*this, getBattlefieldType()).WillRepeatedly(Return(BattleField::NONE));
}

View File

@ -18,7 +18,7 @@ class IBattleInfoCallbackMock : public IBattleInfoCallback
public:
MOCK_CONST_METHOD0(getContextPool, scripting::Pool *());
MOCK_CONST_METHOD0(battleTerrainType, Terrain());
MOCK_CONST_METHOD0(battleGetBattlefieldType, BFieldType());
MOCK_CONST_METHOD0(battleGetBattlefieldType, BattleField());
MOCK_CONST_METHOD0(battleIsFinished, boost::optional<int>());

View File

@ -18,7 +18,7 @@ public:
MOCK_CONST_METHOD0(getActiveStackID, int32_t());
MOCK_CONST_METHOD1(getStacksIf, TStacks(TStackFilter));
MOCK_CONST_METHOD1(getUnitsIf, battle::Units(battle::UnitFilter));
MOCK_CONST_METHOD0(getBattlefieldType, BFieldType());
MOCK_CONST_METHOD0(getBattlefieldType, BattleField());
MOCK_CONST_METHOD0(getTerrainType, Terrain());
MOCK_CONST_METHOD0(getAllObstacles, IBattleInfo::ObstacleCList());
MOCK_CONST_METHOD0(getDefendedTown, const CGTownInstance *());