mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
battlefields in VLC and custom bonuses for terrain patches
This commit is contained in:
parent
8b8e837495
commit
232010c5de
@ -37,6 +37,7 @@ void CGameInfo::setFromLib()
|
|||||||
spellh = VLC->spellh;
|
spellh = VLC->spellh;
|
||||||
skillh = VLC->skillh;
|
skillh = VLC->skillh;
|
||||||
objtypeh = VLC->objtypeh;
|
objtypeh = VLC->objtypeh;
|
||||||
|
battleFieldHandler = VLC->battlefieldsHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ArtifactService * CGameInfo::artifacts() const
|
const ArtifactService * CGameInfo::artifacts() const
|
||||||
@ -44,6 +45,11 @@ const ArtifactService * CGameInfo::artifacts() const
|
|||||||
return globalServices->artifacts();
|
return globalServices->artifacts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BattleFieldService * CGameInfo::battlefields() const
|
||||||
|
{
|
||||||
|
return globalServices->battlefields();
|
||||||
|
}
|
||||||
|
|
||||||
const CreatureService * CGameInfo::creatures() const
|
const CreatureService * CGameInfo::creatures() const
|
||||||
{
|
{
|
||||||
return globalServices->creatures();
|
return globalServices->creatures();
|
||||||
|
@ -31,6 +31,7 @@ class CCursorHandler;
|
|||||||
class CGameState;
|
class CGameState;
|
||||||
class IMainVideoPlayer;
|
class IMainVideoPlayer;
|
||||||
class CServerHandler;
|
class CServerHandler;
|
||||||
|
class BattleFieldHandler;
|
||||||
|
|
||||||
class CMap;
|
class CMap;
|
||||||
|
|
||||||
@ -60,6 +61,7 @@ public:
|
|||||||
const scripting::Service * scripts() const override;
|
const scripting::Service * scripts() const override;
|
||||||
const spells::Service * spells() const override;
|
const spells::Service * spells() const override;
|
||||||
const SkillService * skills() const override;
|
const SkillService * skills() const override;
|
||||||
|
const BattleFieldService * battlefields() const override;
|
||||||
|
|
||||||
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
ConstTransitivePtr<CModHandler> modh; //public?
|
ConstTransitivePtr<CModHandler> modh; //public?
|
||||||
|
ConstTransitivePtr<BattleFieldHandler> battleFieldHandler;
|
||||||
ConstTransitivePtr<CHeroHandler> heroh;
|
ConstTransitivePtr<CHeroHandler> heroh;
|
||||||
ConstTransitivePtr<CCreatureHandler> creh;
|
ConstTransitivePtr<CCreatureHandler> creh;
|
||||||
ConstTransitivePtr<CSpellHandler> spellh;
|
ConstTransitivePtr<CSpellHandler> spellh;
|
||||||
|
@ -109,12 +109,6 @@ void Graphics::initializeBattleGraphics()
|
|||||||
|
|
||||||
const JsonNode config(mod, ResourceID("config/battles_graphics.json"));
|
const JsonNode config(mod, ResourceID("config/battles_graphics.json"));
|
||||||
|
|
||||||
if(!config["backgrounds"].isNull())
|
|
||||||
for(auto & t : config["backgrounds"].Struct())
|
|
||||||
{
|
|
||||||
battleBacks[t.first] = t.second.String();
|
|
||||||
}
|
|
||||||
|
|
||||||
//initialization of AC->def name mapping
|
//initialization of AC->def name mapping
|
||||||
if(!config["ac_mapping"].isNull())
|
if(!config["ac_mapping"].isNull())
|
||||||
for(const JsonNode &ac : config["ac_mapping"].Vector())
|
for(const JsonNode &ac : config["ac_mapping"].Vector())
|
||||||
|
@ -87,7 +87,6 @@ public:
|
|||||||
//towns
|
//towns
|
||||||
std::map<int, std::string> ERMUtoPicture[GameConstants::F_NUMBER]; //maps building ID to it's picture's name for each town type
|
std::map<int, std::string> ERMUtoPicture[GameConstants::F_NUMBER]; //maps building ID to it's picture's name for each town type
|
||||||
//for battles
|
//for battles
|
||||||
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
|
std::map< int, std::vector < std::string > > battleACToDef; //maps AC format to vector of appropriate def names
|
||||||
|
|
||||||
//functions
|
//functions
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "../../lib/spells/ISpellMechanics.h"
|
#include "../../lib/spells/ISpellMechanics.h"
|
||||||
#include "../../lib/spells/Problem.h"
|
#include "../../lib/spells/Problem.h"
|
||||||
#include "../../lib/CTownHandler.h"
|
#include "../../lib/CTownHandler.h"
|
||||||
|
#include "../../lib/BattleFieldHandler.h"
|
||||||
#include "../../lib/CGameState.h"
|
#include "../../lib/CGameState.h"
|
||||||
#include "../../lib/mapping/CMap.h"
|
#include "../../lib/mapping/CMap.h"
|
||||||
#include "../../lib/NetPacks.h"
|
#include "../../lib/NetPacks.h"
|
||||||
@ -201,13 +202,14 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto bfieldType = curInt->cb->battleGetBattlefieldType();
|
auto bfieldType = curInt->cb->battleGetBattlefieldType();
|
||||||
if(!vstd::contains(graphics->battleBacks, bfieldType))
|
|
||||||
|
if(bfieldType == BattleField::NONE)
|
||||||
{
|
{
|
||||||
logGlobal->error("%s is not valid battlefield type!", static_cast<std::string>(bfieldType));
|
logGlobal->error("Invalid battlefield returned for current battle");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
background = BitmapHandler::loadBitmap(graphics->battleBacks[bfieldType], false);
|
background = BitmapHandler::loadBitmap(bfieldType.getInfo()->graphics, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
173
config/battlefields.json
Normal file
173
config/battlefields.json
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
{
|
||||||
|
"sand_shore": { "graphics" : "CMBKBCH.BMP" },
|
||||||
|
"sand_mesas": { "graphics" : "CMBKDES.BMP" },
|
||||||
|
"dirt_birches": { "graphics" : "CMBKDRTR.BMP" },
|
||||||
|
"dirt_hills": { "graphics" : "CMBKDRMT.BMP" },
|
||||||
|
"dirt_pines": { "graphics" : "CMBKDRDD.BMP" },
|
||||||
|
"grass_hills": { "graphics" : "CMBKGRMT.BMP" },
|
||||||
|
"grass_pines": { "graphics" : "CMBKGRTR.BMP" },
|
||||||
|
"lava": { "graphics" :"CMBKLAVA.BMP" },
|
||||||
|
"magic_plains": {
|
||||||
|
"graphics": "CMBKMAG.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "MAGIC_SCHOOL_SKILL",
|
||||||
|
"subtype" : 0,
|
||||||
|
"val" : 3,
|
||||||
|
"valueType" : "BASE_NUMBER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"snow_mountains": { "graphics" : "CMBKSNMT.BMP" },
|
||||||
|
"snow_trees": { "graphics" : "CMBKSNTR.BMP" },
|
||||||
|
"subterranean": { "graphics" : "CMBKSUB.BMP", "isSpecial" : true },
|
||||||
|
"swamp_trees": { "graphics" : "CMBKSWMP.BMP" },
|
||||||
|
"fiery_fields": {
|
||||||
|
"graphics": "CMBKFF.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "MAGIC_SCHOOL_SKILL",
|
||||||
|
"subtype" : 2,
|
||||||
|
"val" : 3,
|
||||||
|
"valueType" : "BASE_NUMBER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rocklands": {
|
||||||
|
"graphics": "CMBKRK.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "MAGIC_SCHOOL_SKILL",
|
||||||
|
"subtype" : 8,
|
||||||
|
"val" : 3,
|
||||||
|
"valueType" : "BASE_NUMBER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"magic_clouds": {
|
||||||
|
"graphics": "CMBKMC.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "MAGIC_SCHOOL_SKILL",
|
||||||
|
"subtype" : 1,
|
||||||
|
"val" : 3,
|
||||||
|
"valueType" : "BASE_NUMBER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lucid_pools": {
|
||||||
|
"graphics": "CMBKLP.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "MAGIC_SCHOOL_SKILL",
|
||||||
|
"subtype" : 4,
|
||||||
|
"val" : 3,
|
||||||
|
"valueType" : "BASE_NUMBER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"holy_ground": {
|
||||||
|
"graphics": "CMBKHG.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "MORALE",
|
||||||
|
"val" : 1,
|
||||||
|
"valueType" : "BASE_NUMBER",
|
||||||
|
"description" : "Creatures of good town alignment on Holly Ground",
|
||||||
|
"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["good"] }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "MORALE",
|
||||||
|
"val" : -1,
|
||||||
|
"valueType" : "BASE_NUMBER",
|
||||||
|
"description" : "Creatures of evil town alignment on Holly Ground",
|
||||||
|
"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["evil"] }]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"clover_field": {
|
||||||
|
"graphics": "CMBKCF.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "LUCK",
|
||||||
|
"val" : 2,
|
||||||
|
"valueType" : "BASE_NUMBER",
|
||||||
|
"description" : "Creatures of neutral town alignment on Clover Field",
|
||||||
|
"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["neutral"] }]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"evil_fog": {
|
||||||
|
"graphics": "CMBKEF.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "MORALE",
|
||||||
|
"val" : -1,
|
||||||
|
"valueType" : "BASE_NUMBER",
|
||||||
|
"description" : "Creatures of good town alignment on Evil Fog",
|
||||||
|
"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["good"] }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "MORALE",
|
||||||
|
"val" : 1,
|
||||||
|
"valueType" : "BASE_NUMBER",
|
||||||
|
"description" : "Creatures of evil town alignment on Evil Fog",
|
||||||
|
"limiters": [{ "type" : "CREATURE_ALIGNMENT_LIMITER", "parameters" : ["evil"] }]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"favorable_winds": {
|
||||||
|
"graphics": "CMBKFW.BMP",
|
||||||
|
"isSpecial" : true
|
||||||
|
},
|
||||||
|
"cursed_ground": {
|
||||||
|
"graphics": "CMBKCUR.BMP",
|
||||||
|
"isSpecial" : true,
|
||||||
|
"bonuses": [
|
||||||
|
{
|
||||||
|
"type" : "NO_MORALE",
|
||||||
|
"subtype" : 0,
|
||||||
|
"val" : 0,
|
||||||
|
"valueType" : "INDEPENDENT_MIN",
|
||||||
|
"description" : "Creatures on Cursed Ground"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "NO_LUCK",
|
||||||
|
"subtype" : 0,
|
||||||
|
"val" : 0,
|
||||||
|
"valueType" : "INDEPENDENT_MIN",
|
||||||
|
"description" : "Creatures on Cursed Ground"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "BLOCK_MAGIC_ABOVE",
|
||||||
|
"subtype" : 0,
|
||||||
|
"val" : 1,
|
||||||
|
"valueType" : "INDEPENDENT_MIN"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rough": { "graphics" : "CMBKRGH.BMP" },
|
||||||
|
"ship_to_ship":
|
||||||
|
{
|
||||||
|
"graphics" : "CMBKBOAT.BMP"
|
||||||
|
"impassableHexes" : [
|
||||||
|
6, 7, 8, 9,
|
||||||
|
24, 25, 26,
|
||||||
|
58, 59, 60,
|
||||||
|
75, 76, 77,
|
||||||
|
92, 93, 94,
|
||||||
|
109, 110, 111,
|
||||||
|
126, 127, 128,
|
||||||
|
159, 160, 161, 162, 163,
|
||||||
|
176, 177, 178, 179, 180]
|
||||||
|
},
|
||||||
|
"ship": { "graphics" : "CMBKDECK.BMP" }
|
||||||
|
}
|
@ -1,33 +1,4 @@
|
|||||||
{
|
{
|
||||||
// backgrounds of terrains battles can be fought on
|
|
||||||
"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
|
// WoG_Ac_format_to_def_names_mapping
|
||||||
"ac_mapping": [
|
"ac_mapping": [
|
||||||
{ "id": 0, "defnames": [ "C10SPW.DEF" ] },//merged
|
{ "id": 0, "defnames": [ "C10SPW.DEF" ] },//merged
|
||||||
|
@ -84,5 +84,9 @@
|
|||||||
"terrains":
|
"terrains":
|
||||||
[
|
[
|
||||||
"config/terrains.json"
|
"config/terrains.json"
|
||||||
|
],
|
||||||
|
"battlefields":
|
||||||
|
[
|
||||||
|
"config/battlefields.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
35
config/schemas/battlefield.json
Normal file
35
config/schemas/battlefield.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"type":"object",
|
||||||
|
"$schema": "http://json-schema.org/draft-04/schema",
|
||||||
|
"title" : "VCMI battlefield format",
|
||||||
|
"description" : "Format used to define new artifacts in VCMI",
|
||||||
|
"required" : [ "graphics" ],
|
||||||
|
|
||||||
|
"additionalProperties" : false,
|
||||||
|
"properties":{
|
||||||
|
"bonuses": {
|
||||||
|
"type":"array",
|
||||||
|
"description": "Bonuses provided by this battleground using bonus system",
|
||||||
|
"items": { "$ref" : "bonus.json" }
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type":"string",
|
||||||
|
"description": "Name of the battleground"
|
||||||
|
},
|
||||||
|
"graphics": {
|
||||||
|
"type":"string",
|
||||||
|
"description": "BMP battleground resource"
|
||||||
|
},
|
||||||
|
"isSpecial": {
|
||||||
|
"type":"boolean",
|
||||||
|
"description": "Shows if this battleground has own obstacles"
|
||||||
|
},
|
||||||
|
"impassableHexes": {
|
||||||
|
"type":"array",
|
||||||
|
"description": "Battle hexes always impassable for this type of battlefield (ship to ship for instance)",
|
||||||
|
"items": {
|
||||||
|
"type":"number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -112,6 +112,12 @@
|
|||||||
"description": "List of configuration files for RMG templates",
|
"description": "List of configuration files for RMG templates",
|
||||||
"items": { "type":"string", "format" : "textFile" }
|
"items": { "type":"string", "format" : "textFile" }
|
||||||
|
|
||||||
|
},
|
||||||
|
"battlefields":{
|
||||||
|
"type":"array",
|
||||||
|
"description": "List of configuration files for battlefields",
|
||||||
|
"items": { "type":"string", "format" : "textFile" }
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"changelog" : {
|
"changelog" : {
|
||||||
|
@ -19,6 +19,7 @@ class HeroClassService;
|
|||||||
class HeroTypeService;
|
class HeroTypeService;
|
||||||
class SkillService;
|
class SkillService;
|
||||||
class JsonNode;
|
class JsonNode;
|
||||||
|
class BattleFieldService;
|
||||||
|
|
||||||
namespace spells
|
namespace spells
|
||||||
{
|
{
|
||||||
@ -48,6 +49,7 @@ public:
|
|||||||
virtual const scripting::Service * scripts() const = 0;
|
virtual const scripting::Service * scripts() const = 0;
|
||||||
virtual const spells::Service * spells() const = 0;
|
virtual const spells::Service * spells() const = 0;
|
||||||
virtual const SkillService * skills() const = 0;
|
virtual const SkillService * skills() const = 0;
|
||||||
|
virtual const BattleFieldService * battlefields() const = 0;
|
||||||
|
|
||||||
virtual void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) = 0;
|
virtual void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) = 0;
|
||||||
|
|
||||||
|
108
lib/BattleFieldHandler.cpp
Normal file
108
lib/BattleFieldHandler.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* BattleFieldHandler.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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "StdInc.h"
|
||||||
|
|
||||||
|
#include <vcmi/Entity.h>
|
||||||
|
#include "BattleFieldHandler.h"
|
||||||
|
|
||||||
|
BattleFieldInfo * BattleFieldHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & identifier, size_t index)
|
||||||
|
{
|
||||||
|
BattleFieldInfo * info = new BattleFieldInfo(BattleField(index), identifier);
|
||||||
|
|
||||||
|
if(json["graphics"].getType() == JsonNode::JsonType::DATA_STRING)
|
||||||
|
{
|
||||||
|
info->graphics = json["graphics"].String();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json["icon"].getType() == JsonNode::JsonType::DATA_STRING)
|
||||||
|
{
|
||||||
|
info->icon = json["icon"].String();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json["name"].getType() == JsonNode::JsonType::DATA_STRING)
|
||||||
|
{
|
||||||
|
info->name = json["name"].String();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json["bonuses"].getType() == JsonNode::JsonType::DATA_VECTOR)
|
||||||
|
{
|
||||||
|
for(auto b : json["bonuses"].Vector())
|
||||||
|
{
|
||||||
|
auto bonus = JsonUtils::parseBonus(b);
|
||||||
|
|
||||||
|
bonus->source = Bonus::TERRAIN_OVERLAY;
|
||||||
|
bonus->sid = info->getIndex();
|
||||||
|
bonus->duration = Bonus::ONE_BATTLE;
|
||||||
|
|
||||||
|
info->bonuses.push_back(bonus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json["isSpecial"].getType() == JsonNode::JsonType::DATA_BOOL)
|
||||||
|
{
|
||||||
|
info->isSpecial = json["isSpecial"].Bool();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json["impassableHexes"].getType() == JsonNode::JsonType::DATA_VECTOR)
|
||||||
|
{
|
||||||
|
for(auto node : json["impassableHexes"].Vector())
|
||||||
|
info->impassableHexes.push_back(BattleHex(node.Integer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<JsonNode> BattleFieldHandler::loadLegacyData(size_t dataSize)
|
||||||
|
{
|
||||||
|
return std::vector<JsonNode>();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> & BattleFieldHandler::getTypeNames() const
|
||||||
|
{
|
||||||
|
static const std::vector<std::string> types = std::vector<std::string> { "battlefield" };
|
||||||
|
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bool> BattleFieldHandler::getDefaultAllowed() const
|
||||||
|
{
|
||||||
|
return std::vector<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BattleFieldInfo::getIndex() const
|
||||||
|
{
|
||||||
|
return battlefield.getNum();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BattleFieldInfo::getIconIndex() const
|
||||||
|
{
|
||||||
|
return iconIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & BattleFieldInfo::getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & BattleFieldInfo::getJsonKey() const
|
||||||
|
{
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BattleFieldInfo::registerIcons(const IconRegistar & cb) const
|
||||||
|
{
|
||||||
|
//cb(getIconIndex(), "BATTLEFIELD", icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleField BattleFieldInfo::getId() const
|
||||||
|
{
|
||||||
|
return battlefield;
|
||||||
|
}
|
85
lib/BattleFieldHandler.h
Normal file
85
lib/BattleFieldHandler.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* BattleFieldHandler.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 <vcmi/EntityService.h>
|
||||||
|
#include "HeroBonus.h"
|
||||||
|
#include "GameConstants.h"
|
||||||
|
#include "IHandlerBase.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
#include "battle/BattleHex.h"
|
||||||
|
|
||||||
|
class BattleFieldInfo : public EntityT<BattleField>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BattleField battlefield;
|
||||||
|
std::vector<std::shared_ptr<Bonus>> bonuses;
|
||||||
|
bool isSpecial;
|
||||||
|
std::string graphics;
|
||||||
|
std::string name;
|
||||||
|
std::string identifier;
|
||||||
|
std::string icon;
|
||||||
|
si32 iconIndex;
|
||||||
|
std::vector<BattleHex> impassableHexes;
|
||||||
|
|
||||||
|
BattleFieldInfo()
|
||||||
|
: BattleFieldInfo(BattleField::NONE, "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleFieldInfo(BattleField battlefield, std::string identifier)
|
||||||
|
:bonuses(), isSpecial(false), battlefield(battlefield), identifier(identifier), graphics(), icon(), iconIndex(battlefield.getNum()), impassableHexes(), name(identifier)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getIndex() const override;
|
||||||
|
int32_t getIconIndex() const override;
|
||||||
|
const std::string & getName() const override;
|
||||||
|
const std::string & getJsonKey() const override;
|
||||||
|
void registerIcons(const IconRegistar & cb) const override;
|
||||||
|
BattleField getId() const override;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler & h, const int version)
|
||||||
|
{
|
||||||
|
h & name;
|
||||||
|
h & identifier;
|
||||||
|
h & isSpecial;
|
||||||
|
h & graphics;
|
||||||
|
h & icon;
|
||||||
|
h & iconIndex;
|
||||||
|
h & battlefield;
|
||||||
|
h & impassableHexes;
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DLL_LINKAGE BattleFieldService : public EntityServiceT<BattleField, BattleFieldInfo>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
class BattleFieldHandler : public CHandlerBase<BattleField, BattleFieldInfo, BattleFieldInfo, BattleFieldService>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual BattleFieldInfo * loadFromJson(
|
||||||
|
const std::string & scope,
|
||||||
|
const JsonNode & json,
|
||||||
|
const std::string & identifier,
|
||||||
|
size_t index) override;
|
||||||
|
|
||||||
|
virtual const std::vector<std::string> & getTypeNames() const override;
|
||||||
|
virtual std::vector<JsonNode> loadLegacyData(size_t dataSize) override;
|
||||||
|
virtual std::vector<bool> getDefaultAllowed() const override;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler & h, const int version)
|
||||||
|
{
|
||||||
|
h & objects;
|
||||||
|
}
|
||||||
|
};
|
@ -1922,9 +1922,10 @@ BattleField CGameState::battleGetBattlefieldType(int3 tile, CRandomGenerator & r
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(map->isCoastalTile(tile)) //coastal tile is always ground
|
if(map->isCoastalTile(tile)) //coastal tile is always ground
|
||||||
return BattleField("sand_shore");
|
return BattleField::fromString("sand_shore");
|
||||||
|
|
||||||
return *RandomGeneratorUtil::nextItem(Terrain::Manager::getInfo(t.terType).battleFields, rand);
|
return BattleField::fromString(
|
||||||
|
*RandomGeneratorUtil::nextItem(Terrain::Manager::getInfo(t.terType).battleFields, rand));
|
||||||
}
|
}
|
||||||
|
|
||||||
UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
|
UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "mapObjects/CObjectClassesHandler.h"
|
#include "mapObjects/CObjectClassesHandler.h"
|
||||||
|
#include "BattleFieldHandler.h"
|
||||||
|
|
||||||
CHero::CHero() = default;
|
CHero::CHero() = default;
|
||||||
CHero::~CHero() = default;
|
CHero::~CHero() = default;
|
||||||
@ -179,8 +180,10 @@ std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
|
|||||||
|
|
||||||
bool CObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & battlefield) const
|
bool CObstacleInfo::isAppropriate(const Terrain & terrainType, const BattleField & battlefield) const
|
||||||
{
|
{
|
||||||
if(battlefield.isSpecial())
|
auto bgInfo = battlefield.getInfo();
|
||||||
return vstd::contains(allowedSpecialBfields, battlefield);
|
|
||||||
|
if(bgInfo->isSpecial)
|
||||||
|
return vstd::contains(allowedSpecialBfields, bgInfo->identifier);
|
||||||
|
|
||||||
return vstd::contains(allowedTerrains, terrainType);
|
return vstd::contains(allowedTerrains, terrainType);
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ struct DLL_LINKAGE CObstacleInfo
|
|||||||
{
|
{
|
||||||
std::string defName;
|
std::string defName;
|
||||||
std::vector<Terrain> allowedTerrains;
|
std::vector<Terrain> allowedTerrains;
|
||||||
std::vector<BattleField> allowedSpecialBfields;
|
std::vector<std::string> 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
|
||||||
si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm)
|
si32 width, height; //how much space to the right and up is needed to place obstacle (affects only placement algorithm)
|
||||||
|
@ -130,6 +130,7 @@ set(lib_SRCS
|
|||||||
|
|
||||||
vstd/StringUtils.cpp
|
vstd/StringUtils.cpp
|
||||||
|
|
||||||
|
BattleFieldHandler.cpp
|
||||||
CAndroidVMHelper.cpp
|
CAndroidVMHelper.cpp
|
||||||
CArtHandler.cpp
|
CArtHandler.cpp
|
||||||
CBonusTypeHandler.cpp
|
CBonusTypeHandler.cpp
|
||||||
@ -338,6 +339,7 @@ set(lib_HEADERS
|
|||||||
spells/effects/Sacrifice.h
|
spells/effects/Sacrifice.h
|
||||||
|
|
||||||
AI_Base.h
|
AI_Base.h
|
||||||
|
BattleFieldHandler.h
|
||||||
CAndroidVMHelper.h
|
CAndroidVMHelper.h
|
||||||
CArtHandler.h
|
CArtHandler.h
|
||||||
CBonusTypeHandler.h
|
CBonusTypeHandler.h
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "spells/CSpellHandler.h"
|
#include "spells/CSpellHandler.h"
|
||||||
#include "CSkillHandler.h"
|
#include "CSkillHandler.h"
|
||||||
#include "ScriptHandler.h"
|
#include "ScriptHandler.h"
|
||||||
|
#include "BattleFieldHandler.h"
|
||||||
|
|
||||||
#include <vstd/StringUtils.h>
|
#include <vstd/StringUtils.h>
|
||||||
|
|
||||||
@ -433,6 +434,7 @@ void CContentHandler::init()
|
|||||||
handlers.insert(std::make_pair("skills", ContentTypeHandler(VLC->skillh, "skill")));
|
handlers.insert(std::make_pair("skills", ContentTypeHandler(VLC->skillh, "skill")));
|
||||||
handlers.insert(std::make_pair("templates", ContentTypeHandler((IHandlerBase *)VLC->tplh, "template")));
|
handlers.insert(std::make_pair("templates", ContentTypeHandler((IHandlerBase *)VLC->tplh, "template")));
|
||||||
handlers.insert(std::make_pair("scripts", ContentTypeHandler(VLC->scriptHandler, "script")));
|
handlers.insert(std::make_pair("scripts", ContentTypeHandler(VLC->scriptHandler, "script")));
|
||||||
|
handlers.insert(std::make_pair("battlefields", ContentTypeHandler(VLC->battlefieldsHandler, "battlefield")));
|
||||||
//TODO: any other types of moddables?
|
//TODO: any other types of moddables?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "StringConstants.h"
|
#include "StringConstants.h"
|
||||||
#include "CGeneralTextHandler.h"
|
#include "CGeneralTextHandler.h"
|
||||||
#include "CModHandler.h"//todo: remove
|
#include "CModHandler.h"//todo: remove
|
||||||
|
#include "BattleFieldHandler.h"
|
||||||
|
|
||||||
const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
|
const SlotID SlotID::COMMANDER_SLOT_PLACEHOLDER = SlotID(-2);
|
||||||
const SlotID SlotID::SUMMONED_SLOT_PLACEHOLDER = SlotID(-3);
|
const SlotID SlotID::SUMMONED_SLOT_PLACEHOLDER = SlotID(-3);
|
||||||
@ -255,3 +256,40 @@ std::ostream & operator<<(std::ostream & os, const EPathfindingLayer pathfinding
|
|||||||
if (it == pathfinderLayerToString.end()) return os << "<Unknown type>";
|
if (it == pathfinderLayerToString.end()) return os << "<Unknown type>";
|
||||||
else return os << it->second;
|
else return os << it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BattleField BattleField::NONE;
|
||||||
|
|
||||||
|
bool operator==(const BattleField & l, const BattleField & r)
|
||||||
|
{
|
||||||
|
return l.num == r.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const BattleField & l, const BattleField & r)
|
||||||
|
{
|
||||||
|
return l.num != r.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const BattleField & l, const BattleField & r)
|
||||||
|
{
|
||||||
|
return l.num < r.num;
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleField::operator std::string() const
|
||||||
|
{
|
||||||
|
return getInfo()->identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BattleFieldInfo * BattleField::getInfo() const
|
||||||
|
{
|
||||||
|
return VLC->battlefields()->getById(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
BattleField BattleField::fromString(std::string identifier)
|
||||||
|
{
|
||||||
|
auto rawId = VLC->modh->identifiers.getIdentifier("core", "battlefield", identifier);
|
||||||
|
|
||||||
|
if(rawId)
|
||||||
|
return BattleField(rawId.get());
|
||||||
|
else
|
||||||
|
return BattleField::NONE;
|
||||||
|
}
|
@ -1109,6 +1109,23 @@ public:
|
|||||||
|
|
||||||
ID_LIKE_OPERATORS(SpellID, SpellID::ESpellID)
|
ID_LIKE_OPERATORS(SpellID, SpellID::ESpellID)
|
||||||
|
|
||||||
|
class BattleFieldInfo;
|
||||||
|
class BattleField : public BaseForID<BattleField, si32>
|
||||||
|
{
|
||||||
|
INSTID_LIKE_CLASS_COMMON(BattleField, si32)
|
||||||
|
|
||||||
|
DLL_LINKAGE 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);
|
||||||
|
|
||||||
|
DLL_LINKAGE operator std::string() const;
|
||||||
|
DLL_LINKAGE const BattleFieldInfo * getInfo() const;
|
||||||
|
|
||||||
|
DLL_LINKAGE static BattleField fromString(std::string identifier);
|
||||||
|
};
|
||||||
|
|
||||||
enum class ESpellSchool: ui8
|
enum class ESpellSchool: ui8
|
||||||
{
|
{
|
||||||
AIR = 0,
|
AIR = 0,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "NetPacks.h"
|
#include "NetPacks.h"
|
||||||
#include "CBonusTypeHandler.h"
|
#include "CBonusTypeHandler.h"
|
||||||
#include "CModHandler.h"
|
#include "CModHandler.h"
|
||||||
|
#include "BattleFieldHandler.h"
|
||||||
|
|
||||||
#include "serializer/CSerializer.h" // for SAVEGAME_MAGIC
|
#include "serializer/CSerializer.h" // for SAVEGAME_MAGIC
|
||||||
#include "serializer/BinaryDeserializer.h"
|
#include "serializer/BinaryDeserializer.h"
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
const Terrain Terrain::ANY("ANY");
|
const Terrain Terrain::ANY("ANY");
|
||||||
|
|
||||||
const BattleField BattleField::NONE("");
|
|
||||||
|
|
||||||
Terrain Terrain::createTerrainTypeH3M(int tId)
|
Terrain Terrain::createTerrainTypeH3M(int tId)
|
||||||
{
|
{
|
||||||
static std::array<std::string, 10> terrainsH3M
|
static std::array<std::string, 10> terrainsH3M
|
||||||
@ -227,27 +225,3 @@ bool Terrain::isTransitionRequired() const
|
|||||||
{
|
{
|
||||||
return Terrain::Manager::getInfo(*this).transitionRequired;
|
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);
|
|
||||||
}
|
|
||||||
|
@ -11,47 +11,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ConstTransitivePtr.h"
|
#include "ConstTransitivePtr.h"
|
||||||
|
#include "GameConstants.h"
|
||||||
#include "JsonNode.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSpecial() const
|
|
||||||
{
|
|
||||||
return name.find('_') >= 0; // hack for special battlefields, move to JSON
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::string name;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DLL_LINKAGE Terrain
|
class DLL_LINKAGE Terrain
|
||||||
{
|
{
|
||||||
@ -77,7 +39,7 @@ public:
|
|||||||
std::string terrainViewPatterns;
|
std::string terrainViewPatterns;
|
||||||
int horseSoundId;
|
int horseSoundId;
|
||||||
Type type;
|
Type type;
|
||||||
std::vector<BattleField> battleFields;
|
std::vector<std::string> battleFields;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE Manager
|
class DLL_LINKAGE Manager
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "rmg/CRmgTemplateStorage.h"
|
#include "rmg/CRmgTemplateStorage.h"
|
||||||
#include "mapping/CMapEditManager.h"
|
#include "mapping/CMapEditManager.h"
|
||||||
#include "ScriptHandler.h"
|
#include "ScriptHandler.h"
|
||||||
|
#include "BattleFieldHandler.h"
|
||||||
|
|
||||||
LibClasses * VLC = nullptr;
|
LibClasses * VLC = nullptr;
|
||||||
|
|
||||||
@ -110,6 +111,11 @@ spells::effects::Registry * LibClasses::spellEffects()
|
|||||||
return spells::effects::GlobalRegistry::get();
|
return spells::effects::GlobalRegistry::get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BattleFieldService * LibClasses::battlefields() const
|
||||||
|
{
|
||||||
|
return battlefieldsHandler;
|
||||||
|
}
|
||||||
|
|
||||||
void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & data)
|
void LibClasses::updateEntity(Metatype metatype, int32_t index, const JsonNode & data)
|
||||||
{
|
{
|
||||||
switch(metatype)
|
switch(metatype)
|
||||||
@ -205,6 +211,8 @@ void LibClasses::init(bool onlyEssential)
|
|||||||
|
|
||||||
createHandler(scriptHandler, "Script", pomtime);
|
createHandler(scriptHandler, "Script", pomtime);
|
||||||
|
|
||||||
|
createHandler(battlefieldsHandler, "Battlefields", pomtime);
|
||||||
|
|
||||||
logGlobal->info("\tInitializing handlers: %d ms", totalTime.getDiff());
|
logGlobal->info("\tInitializing handlers: %d ms", totalTime.getDiff());
|
||||||
|
|
||||||
modh->load();
|
modh->load();
|
||||||
@ -231,6 +239,7 @@ void LibClasses::clear()
|
|||||||
delete tplh;
|
delete tplh;
|
||||||
delete terviewh;
|
delete terviewh;
|
||||||
delete scriptHandler;
|
delete scriptHandler;
|
||||||
|
delete battlefieldsHandler;
|
||||||
makeNull();
|
makeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +259,7 @@ void LibClasses::makeNull()
|
|||||||
tplh = nullptr;
|
tplh = nullptr;
|
||||||
terviewh = nullptr;
|
terviewh = nullptr;
|
||||||
scriptHandler = nullptr;
|
scriptHandler = nullptr;
|
||||||
|
battlefieldsHandler = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LibClasses::LibClasses()
|
LibClasses::LibClasses()
|
||||||
|
@ -24,6 +24,7 @@ class CTownHandler;
|
|||||||
class CGeneralTextHandler;
|
class CGeneralTextHandler;
|
||||||
class CModHandler;
|
class CModHandler;
|
||||||
class CContentHandler;
|
class CContentHandler;
|
||||||
|
class BattleFieldHandler;
|
||||||
class IBonusTypeHandler;
|
class IBonusTypeHandler;
|
||||||
class CBonusTypeHandler;
|
class CBonusTypeHandler;
|
||||||
class CTerrainViewPatternConfig;
|
class CTerrainViewPatternConfig;
|
||||||
@ -56,6 +57,7 @@ public:
|
|||||||
const scripting::Service * scripts() const override;
|
const scripting::Service * scripts() const override;
|
||||||
const spells::Service * spells() const override;
|
const spells::Service * spells() const override;
|
||||||
const SkillService * skills() const override;
|
const SkillService * skills() const override;
|
||||||
|
const BattleFieldService * battlefields() const override;
|
||||||
|
|
||||||
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
void updateEntity(Metatype metatype, int32_t index, const JsonNode & data) override;
|
||||||
|
|
||||||
@ -76,6 +78,7 @@ public:
|
|||||||
CModHandler * modh;
|
CModHandler * modh;
|
||||||
CTerrainViewPatternConfig * terviewh;
|
CTerrainViewPatternConfig * terviewh;
|
||||||
CRmgTemplateStorage * tplh;
|
CRmgTemplateStorage * tplh;
|
||||||
|
BattleFieldHandler * battlefieldsHandler;
|
||||||
scripting::ScriptHandler * scriptHandler;
|
scripting::ScriptHandler * scriptHandler;
|
||||||
|
|
||||||
LibClasses(); //c-tor, loads .lods and NULLs handlers
|
LibClasses(); //c-tor, loads .lods and NULLs handlers
|
||||||
@ -104,6 +107,8 @@ public:
|
|||||||
h & objtypeh;
|
h & objtypeh;
|
||||||
h & spellh;
|
h & spellh;
|
||||||
h & skillh;
|
h & skillh;
|
||||||
|
h & battlefieldsHandler;
|
||||||
|
|
||||||
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
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "../mapObjects/CGTownInstance.h"
|
#include "../mapObjects/CGTownInstance.h"
|
||||||
#include "../CGeneralTextHandler.h"
|
#include "../CGeneralTextHandler.h"
|
||||||
#include "../Terrain.h"
|
#include "../Terrain.h"
|
||||||
|
#include "../BattleFieldHandler.h"
|
||||||
|
|
||||||
//TODO: remove
|
//TODO: remove
|
||||||
#include "../IGameCallback.h"
|
#include "../IGameCallback.h"
|
||||||
@ -458,64 +459,12 @@ BattleInfo * BattleInfo::setupBattle(const int3 & tile, const Terrain & terrain,
|
|||||||
auto good = std::make_shared<CreatureAlignmentLimiter>(EAlignment::GOOD);
|
auto good = std::make_shared<CreatureAlignmentLimiter>(EAlignment::GOOD);
|
||||||
auto evil = std::make_shared<CreatureAlignmentLimiter>(EAlignment::EVIL);
|
auto evil = std::make_shared<CreatureAlignmentLimiter>(EAlignment::EVIL);
|
||||||
|
|
||||||
//giving terrain overlay premies
|
auto bgInfo = VLC->battlefields()->getById(battlefieldType);
|
||||||
int bonusSubtype = -1;
|
|
||||||
|
|
||||||
if(battlefieldType == BattleField("magic_plains"))
|
for(const std::shared_ptr<Bonus> & bonus : bgInfo->bonuses)
|
||||||
{
|
{
|
||||||
bonusSubtype = 0;
|
curB->addNewBonus(bonus);
|
||||||
}
|
}
|
||||||
if(battlefieldType == BattleField("fiery_fields"))
|
|
||||||
{
|
|
||||||
if(bonusSubtype == -1) bonusSubtype = 2;
|
|
||||||
}
|
|
||||||
if(battlefieldType == BattleField("rocklands"))
|
|
||||||
{
|
|
||||||
if(bonusSubtype == -1) bonusSubtype = 8;
|
|
||||||
}
|
|
||||||
if(battlefieldType == BattleField("magic_clouds"))
|
|
||||||
{
|
|
||||||
if(bonusSubtype == -1) bonusSubtype = 1;
|
|
||||||
}
|
|
||||||
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
|
|
||||||
|
|
||||||
//native terrain bonuses
|
//native terrain bonuses
|
||||||
static auto nativeTerrain = std::make_shared<CreatureTerrainLimiter>();
|
static auto nativeTerrain = std::make_shared<CreatureTerrainLimiter>();
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "../NetPacks.h"
|
#include "../NetPacks.h"
|
||||||
#include "../spells/CSpellHandler.h"
|
#include "../spells/CSpellHandler.h"
|
||||||
#include "../mapObjects/CGTownInstance.h"
|
#include "../mapObjects/CGTownInstance.h"
|
||||||
|
#include "../BattleFieldHandler.h"
|
||||||
|
|
||||||
namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO
|
namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO
|
||||||
{
|
{
|
||||||
@ -1058,24 +1059,15 @@ AccessibilityInfo CBattleInfoCallback::getAccesibility() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
//special battlefields with logically unavailable tiles
|
//special battlefields with logically unavailable tiles
|
||||||
std::vector<BattleHex> impassableHexes;
|
auto bFieldType = battleGetBattlefieldType();
|
||||||
if(battleGetBattlefieldType() == BattleField("ship_to_ship"))
|
|
||||||
|
if(bFieldType != BattleField::NONE)
|
||||||
{
|
{
|
||||||
impassableHexes =
|
std::vector<BattleHex> impassableHexes = bFieldType.getInfo()->impassableHexes;
|
||||||
{
|
|
||||||
6, 7, 8, 9,
|
for(auto hex : impassableHexes)
|
||||||
24, 25, 26,
|
ret[hex] = EAccessibility::UNAVAILABLE;
|
||||||
58, 59, 60,
|
|
||||||
75, 76, 77,
|
|
||||||
92, 93, 94,
|
|
||||||
109, 110, 111,
|
|
||||||
126, 127, 128,
|
|
||||||
159, 160, 161, 162, 163,
|
|
||||||
176, 177, 178, 179, 180
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
for(auto hex : impassableHexes)
|
|
||||||
ret[hex] = EAccessibility::UNAVAILABLE;
|
|
||||||
|
|
||||||
//gate -> should be before stacks
|
//gate -> should be before stacks
|
||||||
if(battleGetSiegeLevel() > 0)
|
if(battleGetSiegeLevel() > 0)
|
||||||
|
@ -515,10 +515,10 @@ void AObjectTypeHandler::init(const JsonNode & input, boost::optional<std::strin
|
|||||||
else
|
else
|
||||||
aiValue = static_cast<boost::optional<si32>>(input["aiValue"].Integer());
|
aiValue = static_cast<boost::optional<si32>>(input["aiValue"].Integer());
|
||||||
|
|
||||||
if(input["battleground"].isNull())
|
if(input["battleground"].getType() == JsonNode::JsonType::DATA_STRING)
|
||||||
battlefield = BattleField::NONE;
|
battlefield = input["battleground"].String();
|
||||||
else
|
else
|
||||||
battlefield = BattleField(input["battleground"].String());
|
battlefield = boost::none;
|
||||||
|
|
||||||
initTypeData(input);
|
initTypeData(input);
|
||||||
}
|
}
|
||||||
@ -577,7 +577,7 @@ std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates() const
|
|||||||
|
|
||||||
BattleField AObjectTypeHandler::getBattlefield() const
|
BattleField AObjectTypeHandler::getBattlefield() const
|
||||||
{
|
{
|
||||||
return battlefield;
|
return battlefield ? BattleField::fromString(battlefield.get()) : BattleField::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates(const Terrain & terrainType) const
|
std::vector<ObjectTemplate> AObjectTypeHandler::getTemplates(const Terrain & terrainType) const
|
||||||
|
@ -150,7 +150,7 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
|
|||||||
|
|
||||||
boost::optional<si32> aiValue;
|
boost::optional<si32> aiValue;
|
||||||
|
|
||||||
BattleField battlefield;
|
boost::optional<std::string> battlefield;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void preInitObject(CGObjectInstance * obj) const;
|
void preInitObject(CGObjectInstance * obj) const;
|
||||||
@ -219,6 +219,7 @@ public:
|
|||||||
h & subTypeName;
|
h & subTypeName;
|
||||||
h & sounds;
|
h & sounds;
|
||||||
h & aiValue;
|
h & aiValue;
|
||||||
|
h & battlefield;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -461,12 +461,15 @@ const std::vector<CTerrainViewPatternConfig::TVPVector> & CTerrainViewPatternCon
|
|||||||
return iter->second;
|
return iter->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrainViewPatternById(const Terrain & terrain, const std::string & id) const
|
boost::optional<const TerrainViewPattern &> CTerrainViewPatternConfig::getTerrainViewPatternById(std::string patternId, const std::string & id) const
|
||||||
{
|
{
|
||||||
const std::vector<TVPVector> & groupPatterns = getTerrainViewPatterns(terrain);
|
auto iter = terrainViewPatterns.find(patternId);
|
||||||
|
const std::vector<TVPVector> & groupPatterns = (iter == terrainViewPatterns.end()) ? terrainViewPatterns.at("normal") : iter->second;
|
||||||
|
|
||||||
for (const TVPVector & patternFlips : groupPatterns)
|
for (const TVPVector & patternFlips : groupPatterns)
|
||||||
{
|
{
|
||||||
const TerrainViewPattern & pattern = patternFlips.front();
|
const TerrainViewPattern & pattern = patternFlips.front();
|
||||||
|
|
||||||
if(id == pattern.id)
|
if(id == pattern.id)
|
||||||
{
|
{
|
||||||
return boost::optional<const TerrainViewPattern &>(pattern);
|
return boost::optional<const TerrainViewPattern &>(pattern);
|
||||||
|
@ -327,7 +327,7 @@ public:
|
|||||||
~CTerrainViewPatternConfig();
|
~CTerrainViewPatternConfig();
|
||||||
|
|
||||||
const std::vector<TVPVector> & getTerrainViewPatterns(const Terrain & terrain) 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 TerrainViewPattern &> getTerrainViewPatternById(std::string patternId, const std::string & id) const;
|
||||||
boost::optional<const TVPVector &> getTerrainViewPatternsById(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;
|
const TVPVector * getTerrainTypePatternById(const std::string & id) const;
|
||||||
void flipPattern(TerrainViewPattern & pattern, int flip) const;
|
void flipPattern(TerrainViewPattern & pattern, int flip) const;
|
||||||
|
@ -55,6 +55,7 @@ void registerTypesMapObjects1(Serializer &s)
|
|||||||
s.template registerType<CGObjectInstance, CGShipyard>(); s.template registerType<IShipyard, CGShipyard>();
|
s.template registerType<CGObjectInstance, CGShipyard>(); s.template registerType<IShipyard, CGShipyard>();
|
||||||
s.template registerType<CGObjectInstance, CGDenOfthieves>();
|
s.template registerType<CGObjectInstance, CGDenOfthieves>();
|
||||||
s.template registerType<CGObjectInstance, CGLighthouse>();
|
s.template registerType<CGObjectInstance, CGLighthouse>();
|
||||||
|
s.template registerType<CGObjectInstance, CGTerrainPatch>();
|
||||||
s.template registerType<CGObjectInstance, CGMarket>(); s.template registerType<IMarket, CGMarket>();
|
s.template registerType<CGObjectInstance, CGMarket>(); s.template registerType<IMarket, CGMarket>();
|
||||||
s.template registerType<CGMarket, CGBlackMarket>();
|
s.template registerType<CGMarket, CGBlackMarket>();
|
||||||
s.template registerType<CGMarket, CGUniversity>();
|
s.template registerType<CGMarket, CGUniversity>();
|
||||||
@ -108,6 +109,7 @@ void registerTypesMapObjectTypes(Serializer &s)
|
|||||||
REGISTER_GENERIC_HANDLER(CGHeroInstance);
|
REGISTER_GENERIC_HANDLER(CGHeroInstance);
|
||||||
REGISTER_GENERIC_HANDLER(CGKeymasterTent);
|
REGISTER_GENERIC_HANDLER(CGKeymasterTent);
|
||||||
REGISTER_GENERIC_HANDLER(CGLighthouse);
|
REGISTER_GENERIC_HANDLER(CGLighthouse);
|
||||||
|
REGISTER_GENERIC_HANDLER(CGTerrainPatch);
|
||||||
REGISTER_GENERIC_HANDLER(CGMagi);
|
REGISTER_GENERIC_HANDLER(CGMagi);
|
||||||
REGISTER_GENERIC_HANDLER(CGMagicSpring);
|
REGISTER_GENERIC_HANDLER(CGMagicSpring);
|
||||||
REGISTER_GENERIC_HANDLER(CGMagicWell);
|
REGISTER_GENERIC_HANDLER(CGMagicWell);
|
||||||
|
@ -246,8 +246,18 @@ void CMapGenOptions::finalize(CRandomGenerator & rand)
|
|||||||
|
|
||||||
if(waterContent == EWaterContent::RANDOM)
|
if(waterContent == EWaterContent::RANDOM)
|
||||||
{
|
{
|
||||||
waterContent = *RandomGeneratorUtil::nextItem(mapTemplate->getWaterContentAllowed(), rand);
|
auto allowedContent = mapTemplate->getWaterContentAllowed();
|
||||||
|
|
||||||
|
if(allowedContent.size())
|
||||||
|
{
|
||||||
|
waterContent = *RandomGeneratorUtil::nextItem(mapTemplate->getWaterContentAllowed(), rand);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
waterContent = EWaterContent::NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(monsterStrength == EMonsterStrength::RANDOM)
|
if(monsterStrength == EMonsterStrength::RANDOM)
|
||||||
{
|
{
|
||||||
monsterStrength = static_cast<EMonsterStrength::EMonsterStrength>(rand.nextInt(EMonsterStrength::GLOBAL_WEAK, EMonsterStrength::GLOBAL_STRONG));
|
monsterStrength = static_cast<EMonsterStrength::EMonsterStrength>(rand.nextInt(EMonsterStrength::GLOBAL_WEAK, EMonsterStrength::GLOBAL_STRONG));
|
||||||
|
@ -2019,6 +2019,10 @@ int3 CRmgTemplateZone::makeBoat(TRmgTemplateZoneId land, const std::set<int3> &
|
|||||||
{
|
{
|
||||||
std::set<int3> lakeCoast;
|
std::set<int3> lakeCoast;
|
||||||
std::set_intersection(gen->getZones()[land]->getCoastTiles().begin(), gen->getZones()[land]->getCoastTiles().end(), lake.begin(), lake.end(), std::inserter(lakeCoast, lakeCoast.begin()));
|
std::set_intersection(gen->getZones()[land]->getCoastTiles().begin(), gen->getZones()[land]->getCoastTiles().end(), lake.begin(), lake.end(), std::inserter(lakeCoast, lakeCoast.begin()));
|
||||||
|
|
||||||
|
if(lakeCoast.empty())
|
||||||
|
return int3(-1, -1, -1);
|
||||||
|
|
||||||
for(int randomAttempts = 0; randomAttempts<5; ++randomAttempts)
|
for(int randomAttempts = 0; randomAttempts<5; ++randomAttempts)
|
||||||
{
|
{
|
||||||
auto coastTile = *RandomGeneratorUtil::nextItem(lakeCoast, gen->rand);
|
auto coastTile = *RandomGeneratorUtil::nextItem(lakeCoast, gen->rand);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "ISpellMechanics.h"
|
#include "ISpellMechanics.h"
|
||||||
|
|
||||||
#include "../CRandomGenerator.h"
|
#include "../CRandomGenerator.h"
|
||||||
|
#include "../VCMI_Lib.h"
|
||||||
|
|
||||||
#include "../HeroBonus.h"
|
#include "../HeroBonus.h"
|
||||||
#include "../battle/CBattleInfoCallback.h"
|
#include "../battle/CBattleInfoCallback.h"
|
||||||
@ -39,6 +40,7 @@
|
|||||||
|
|
||||||
#include "../CHeroHandler.h"//todo: remove
|
#include "../CHeroHandler.h"//todo: remove
|
||||||
#include "../IGameCallback.h"//todo: remove
|
#include "../IGameCallback.h"//todo: remove
|
||||||
|
#include "../BattleFieldHandler.h"
|
||||||
|
|
||||||
namespace spells
|
namespace spells
|
||||||
{
|
{
|
||||||
@ -520,7 +522,7 @@ bool BaseMechanics::adaptProblem(ESpellCastProblem::ESpellCastProblem source, Pr
|
|||||||
caster->getCasterName(text);
|
caster->getCasterName(text);
|
||||||
target.add(std::move(text), spells::Problem::NORMAL);
|
target.add(std::move(text), spells::Problem::NORMAL);
|
||||||
}
|
}
|
||||||
else if(b && b->source == Bonus::TERRAIN_OVERLAY && b->sid == BattleField("cursed_ground").hash())
|
else if(b && b->source == Bonus::TERRAIN_OVERLAY && VLC->battlefields()->getByIndex(b->sid)->identifier == "cursed_ground")
|
||||||
{
|
{
|
||||||
text.addTxt(MetaString::GENERAL_TXT, 537);
|
text.addTxt(MetaString::GENERAL_TXT, 537);
|
||||||
target.add(std::move(text), spells::Problem::NORMAL);
|
target.add(std::move(text), spells::Problem::NORMAL);
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
|
|
||||||
#include "BattleCb.h"
|
#include "BattleCb.h"
|
||||||
|
#include <vcmi/Entity.h>
|
||||||
|
|
||||||
#include "../LuaStack.h"
|
#include "../LuaStack.h"
|
||||||
#include "../LuaCallWrapper.h"
|
#include "../LuaCallWrapper.h"
|
||||||
|
|
||||||
#include "../../../lib/GameConstants.h"
|
#include "../../../lib/GameConstants.h"
|
||||||
#include "../../../lib/battle/Unit.h"
|
#include "../../../lib/battle/Unit.h"
|
||||||
|
#include "../../../lib/BattleFieldHandler.h"
|
||||||
|
|
||||||
namespace scripting
|
namespace scripting
|
||||||
{
|
{
|
||||||
@ -73,7 +75,7 @@ int BattleCbProxy::getBattlefieldType(lua_State * L)
|
|||||||
|
|
||||||
auto ret = object->battleGetBattlefieldType();
|
auto ret = object->battleGetBattlefieldType();
|
||||||
|
|
||||||
return LuaStack::quickRetStr(L, ret);
|
return LuaStack::quickRetStr(L, ret.getInfo()->identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
int BattleCbProxy::getTerrainType(lua_State * L)
|
int BattleCbProxy::getTerrainType(lua_State * L)
|
||||||
|
@ -55,16 +55,16 @@ end
|
|||||||
|
|
||||||
local SPECIAL_FIELDS = {}
|
local SPECIAL_FIELDS = {}
|
||||||
|
|
||||||
SPECIAL_FIELDS[0] = 0
|
SPECIAL_FIELDS['sand_shore'] = 0
|
||||||
SPECIAL_FIELDS[22] = 1
|
SPECIAL_FIELDS['cursed_ground'] = 1
|
||||||
SPECIAL_FIELDS[9] = 2
|
SPECIAL_FIELDS['magic_plains'] = 2
|
||||||
SPECIAL_FIELDS[18] = 3
|
SPECIAL_FIELDS['holy_ground'] = 3
|
||||||
SPECIAL_FIELDS[20] = 4
|
SPECIAL_FIELDS['evil_fog'] = 4
|
||||||
SPECIAL_FIELDS[19] = 5
|
SPECIAL_FIELDS['clover_field'] = 5
|
||||||
SPECIAL_FIELDS[17] = 6
|
SPECIAL_FIELDS['lucid_pools'] = 6
|
||||||
SPECIAL_FIELDS[14] = 7
|
SPECIAL_FIELDS['fiery_fields'] = 7
|
||||||
SPECIAL_FIELDS[15] = 8
|
SPECIAL_FIELDS['rocklands'] = 8
|
||||||
SPECIAL_FIELDS[16] = 9
|
SPECIAL_FIELDS['magic_clouds'] = 9
|
||||||
|
|
||||||
|
|
||||||
function BU:G(x, p1)
|
function BU:G(x, p1)
|
||||||
|
@ -2221,7 +2221,7 @@ void CGameHandler::setupBattle(int3 tile, const CArmedInstance *armies[2], const
|
|||||||
|
|
||||||
BattleField terType = gs->battleGetBattlefieldType(tile, getRandomGenerator());
|
BattleField 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)
|
||||||
terType = BattleField("ship_to_ship");
|
terType = BattleField::fromString("ship_to_ship");
|
||||||
|
|
||||||
//send info about battles
|
//send info about battles
|
||||||
BattleStart bs;
|
BattleStart bs;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
|
|
||||||
#include "../../lib/battle/CBattleInfoCallback.h"
|
#include "../../lib/battle/CBattleInfoCallback.h"
|
||||||
|
#include "../../lib/battle/CUnitState.h"
|
||||||
|
|
||||||
#include <vstd/RNG.h>
|
#include <vstd/RNG.h>
|
||||||
|
|
||||||
@ -25,7 +26,15 @@ using namespace testing;
|
|||||||
|
|
||||||
class UnitFake : public UnitMock
|
class UnitFake : public UnitMock
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
std::shared_ptr<CUnitState> state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
UnitFake()
|
||||||
|
{
|
||||||
|
state.reset(new CUnitStateDetached(this, this));
|
||||||
|
}
|
||||||
|
|
||||||
void addNewBonus(const std::shared_ptr<Bonus> & b)
|
void addNewBonus(const std::shared_ptr<Bonus> & b)
|
||||||
{
|
{
|
||||||
bonusFake.addNewBonus(b);
|
bonusFake.addNewBonus(b);
|
||||||
@ -58,6 +67,13 @@ public:
|
|||||||
EXPECT_CALL(*this, unitSlot()).WillRepeatedly(Return(SlotID(0)));
|
EXPECT_CALL(*this, unitSlot()).WillRepeatedly(Return(SlotID(0)));
|
||||||
EXPECT_CALL(*this, creatureIndex()).WillRepeatedly(Return(0));
|
EXPECT_CALL(*this, creatureIndex()).WillRepeatedly(Return(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDefaultState()
|
||||||
|
{
|
||||||
|
EXPECT_CALL(*this, isClone()).WillRepeatedly(Return(false));
|
||||||
|
EXPECT_CALL(*this, isCaster()).WillRepeatedly(Return(false));
|
||||||
|
EXPECT_CALL(*this, acquireState()).WillRepeatedly(Return(state));
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
BonusBearerMock bonusFake;
|
BonusBearerMock bonusFake;
|
||||||
};
|
};
|
||||||
@ -207,6 +223,7 @@ TEST_F(BattleFinishedTest, LastAliveUnitWins)
|
|||||||
{
|
{
|
||||||
UnitFake & unit = unitsFake.add(1);
|
UnitFake & unit = unitsFake.add(1);
|
||||||
unit.makeAlive();
|
unit.makeAlive();
|
||||||
|
unit.setDefaultState();
|
||||||
|
|
||||||
setDefaultExpectations();
|
setDefaultExpectations();
|
||||||
startBattle();
|
startBattle();
|
||||||
@ -232,6 +249,7 @@ TEST_F(BattleFinishedTest, LastWarMachineNotWins)
|
|||||||
UnitFake & unit = unitsFake.add(0);
|
UnitFake & unit = unitsFake.add(0);
|
||||||
unit.makeAlive();
|
unit.makeAlive();
|
||||||
unit.makeWarMachine();
|
unit.makeWarMachine();
|
||||||
|
unit.setDefaultState();
|
||||||
|
|
||||||
setDefaultExpectations();
|
setDefaultExpectations();
|
||||||
startBattle();
|
startBattle();
|
||||||
@ -241,17 +259,26 @@ TEST_F(BattleFinishedTest, LastWarMachineNotWins)
|
|||||||
|
|
||||||
TEST_F(BattleFinishedTest, LastWarMachineLoose)
|
TEST_F(BattleFinishedTest, LastWarMachineLoose)
|
||||||
{
|
{
|
||||||
UnitFake & unit1 = unitsFake.add(0);
|
try
|
||||||
unit1.makeAlive();
|
{
|
||||||
|
UnitFake & unit1 = unitsFake.add(0);
|
||||||
|
unit1.makeAlive();
|
||||||
|
unit1.setDefaultState();
|
||||||
|
|
||||||
UnitFake & unit2 = unitsFake.add(1);
|
UnitFake & unit2 = unitsFake.add(1);
|
||||||
unit2.makeAlive();
|
unit2.makeAlive();
|
||||||
unit2.makeWarMachine();
|
unit2.makeWarMachine();
|
||||||
|
unit2.setDefaultState();
|
||||||
|
|
||||||
setDefaultExpectations();
|
setDefaultExpectations();
|
||||||
startBattle();
|
startBattle();
|
||||||
|
|
||||||
expectBattleWinner(0);
|
expectBattleWinner(0);
|
||||||
|
}
|
||||||
|
catch(std::exception e)
|
||||||
|
{
|
||||||
|
logGlobal->error(e.what());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BattleMatchOwnerTest : public CBattleInfoCallbackTest
|
class BattleMatchOwnerTest : public CBattleInfoCallbackTest
|
||||||
|
@ -155,7 +155,7 @@ TEST_F(ERM_BU_G, Get)
|
|||||||
source << "!?PI;" << std::endl;
|
source << "!?PI;" << std::endl;
|
||||||
source << "!!BU:G?v1;" << std::endl;
|
source << "!!BU:G?v1;" << std::endl;
|
||||||
|
|
||||||
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField("snow_trees")));
|
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField::fromString("snow_trees")));
|
||||||
|
|
||||||
|
|
||||||
loadScript(VLC->scriptHandler->erm, source.str());
|
loadScript(VLC->scriptHandler->erm, source.str());
|
||||||
@ -169,12 +169,14 @@ TEST_F(ERM_BU_G, Get)
|
|||||||
|
|
||||||
TEST_F(ERM_BU_G, Get2)
|
TEST_F(ERM_BU_G, Get2)
|
||||||
{
|
{
|
||||||
|
const int EXPECTED_ERM_FOG_CODE = 4;
|
||||||
|
|
||||||
std::stringstream source;
|
std::stringstream source;
|
||||||
source << "VERM" << std::endl;
|
source << "VERM" << std::endl;
|
||||||
source << "!?PI;" << std::endl;
|
source << "!?PI;" << std::endl;
|
||||||
source << "!!BU:G?v1;" << std::endl;
|
source << "!!BU:G?v1;" << std::endl;
|
||||||
|
|
||||||
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField("evil_fog")));
|
EXPECT_CALL(binfoMock, battleGetBattlefieldType()).WillOnce(Return(BattleField::fromString("evil_fog")));
|
||||||
|
|
||||||
loadScript(VLC->scriptHandler->erm, source.str());
|
loadScript(VLC->scriptHandler->erm, source.str());
|
||||||
runServer();
|
runServer();
|
||||||
@ -182,7 +184,7 @@ TEST_F(ERM_BU_G, Get2)
|
|||||||
JsonNode actualState = context->saveState();
|
JsonNode actualState = context->saveState();
|
||||||
|
|
||||||
|
|
||||||
EXPECT_EQ(actualState["ERM"]["v"]["1"], JsonUtils::floatNode(4)) << actualState.toJson(true);
|
EXPECT_EQ(actualState["ERM"]["v"]["1"], JsonUtils::floatNode(EXPECTED_ERM_FOG_CODE)) << actualState.toJson(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: ERM_BU_G Set
|
//TODO: ERM_BU_G Set
|
||||||
|
@ -194,7 +194,7 @@ public:
|
|||||||
const auto t = gameCallback->getTile(tile);
|
const auto t = gameCallback->getTile(tile);
|
||||||
|
|
||||||
Terrain terrain = t->terType;
|
Terrain terrain = t->terType;
|
||||||
BattleField terType = BattleField("grass_hills");
|
BattleField terType = BattleField::fromString("grass_hills");
|
||||||
|
|
||||||
//send info about battles
|
//send info about battles
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "MapComparer.h"
|
#include "MapComparer.h"
|
||||||
#include "../JsonComparer.h"
|
#include "../JsonComparer.h"
|
||||||
|
#include "mock/ZoneOptionsFake.h"
|
||||||
|
|
||||||
static const int TEST_RANDOM_SEED = 1337;
|
static const int TEST_RANDOM_SEED = 1337;
|
||||||
|
|
||||||
@ -43,10 +44,12 @@ TEST(MapFormat, Random)
|
|||||||
|
|
||||||
CMapGenOptions opt;
|
CMapGenOptions opt;
|
||||||
CRmgTemplate tmpl;
|
CRmgTemplate tmpl;
|
||||||
|
std::shared_ptr<ZoneOptionsFake> zoneOptions = std::make_shared<ZoneOptionsFake>();
|
||||||
|
|
||||||
const_cast<CRmgTemplate::CPlayerCountRange &>(tmpl.getCpuPlayers()).addRange(1, 4);
|
const_cast<CRmgTemplate::CPlayerCountRange &>(tmpl.getCpuPlayers()).addRange(1, 4);
|
||||||
const_cast<CRmgTemplate::Zones &>(tmpl.getZones())[0] = std::make_shared<rmg::ZoneOptions>();
|
const_cast<CRmgTemplate::Zones &>(tmpl.getZones())[0] = zoneOptions;
|
||||||
|
|
||||||
|
zoneOptions->setOwner(1);
|
||||||
opt.setMapTemplate(&tmpl);
|
opt.setMapTemplate(&tmpl);
|
||||||
|
|
||||||
opt.setHeight(CMapHeader::MAP_SIZE_MIDDLE);
|
opt.setHeight(CMapHeader::MAP_SIZE_MIDDLE);
|
||||||
|
@ -92,7 +92,7 @@ void BattleFake::setupEmptyBattlefield()
|
|||||||
{
|
{
|
||||||
EXPECT_CALL(*this, getDefendedTown()).WillRepeatedly(Return(nullptr));
|
EXPECT_CALL(*this, getDefendedTown()).WillRepeatedly(Return(nullptr));
|
||||||
EXPECT_CALL(*this, getAllObstacles()).WillRepeatedly(Return(IBattleInfo::ObstacleCList()));
|
EXPECT_CALL(*this, getAllObstacles()).WillRepeatedly(Return(IBattleInfo::ObstacleCList()));
|
||||||
EXPECT_CALL(*this, getBattlefieldType()).WillRepeatedly(Return(BattleField::NONE));
|
EXPECT_CALL(*this, getBattlefieldType()).WillRepeatedly(Return(BattleField::fromString("grass_hills")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
23
test/mock/ZoneOptionsFake.h
Normal file
23
test/mock/ZoneOptionsFake.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* BattleFake.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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../lib/rmg/CMapGenOptions.h"
|
||||||
|
#include "../../../lib/rmg/CMapGenerator.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class ZoneOptionsFake : public rmg::ZoneOptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void setOwner(int ow)
|
||||||
|
{
|
||||||
|
this->owner = ow;
|
||||||
|
}
|
||||||
|
};
|
@ -23,7 +23,8 @@ public:
|
|||||||
MOCK_CONST_METHOD0(heroTypes, const HeroTypeService *());
|
MOCK_CONST_METHOD0(heroTypes, const HeroTypeService *());
|
||||||
MOCK_CONST_METHOD0(scripts, const scripting::Service *());
|
MOCK_CONST_METHOD0(scripts, const scripting::Service *());
|
||||||
MOCK_CONST_METHOD0(spells, const spells::Service *());
|
MOCK_CONST_METHOD0(spells, const spells::Service *());
|
||||||
MOCK_CONST_METHOD0(skills, const SkillService *());
|
MOCK_CONST_METHOD0(skills, const SkillService * ());
|
||||||
|
MOCK_CONST_METHOD0(battlefields, const BattleFieldService *());
|
||||||
|
|
||||||
MOCK_METHOD3(updateEntity, void(Metatype, int32_t, const JsonNode &));
|
MOCK_METHOD3(updateEntity, void(Metatype, int32_t, const JsonNode &));
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ TEST_F(CloneApplyTest, SetsLifetimeMarker)
|
|||||||
{
|
{
|
||||||
setDefaultExpectations();
|
setDefaultExpectations();
|
||||||
|
|
||||||
EXPECT_CALL(*battleFake, addUnitBonus(_,_)).WillOnce(Invoke(this, &CloneApplyTest::checkCloneLifetimeMarker));
|
EXPECT_CALL(*battleFake, addUnitBonus(_, _)).WillOnce(Invoke(this, &CloneApplyTest::checkCloneLifetimeMarker));
|
||||||
|
|
||||||
subject->apply(&serverMock, &mechanicsMock, target);
|
subject->apply(&serverMock, &mechanicsMock, target);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user