mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Fixed #1035.
Support for commander artifacts that accumulate bonus after battle.
This commit is contained in:
parent
69de38bf1d
commit
cf45239332
@ -542,7 +542,7 @@ void CCreatureWindow::showAll(SDL_Surface * to)
|
||||
skillPictures[i]->showAll (to);
|
||||
}
|
||||
|
||||
if (upgradeOptions[selectedOption] >= 100) //add frame to selected skill
|
||||
if (type == COMMANDER_LEVEL_UP && upgradeOptions[selectedOption] >= 100) //add frame to selected skill
|
||||
{
|
||||
int index = selectedOption - selectableSkills.size(); //this is screwed
|
||||
CSDL_Ext::drawBorder(to, Rect::around(selectableBonuses[index]->pos), int3(Colors::MetallicGold.r, Colors::MetallicGold.g, Colors::MetallicGold.b));
|
||||
|
@ -51,5 +51,86 @@
|
||||
{"ability": ["JOUSTING", 0, 0, 0 ], "skills": [3, 4]},
|
||||
{"ability": ["DEATH_STARE", 1, 1, 0 ], "skills": [3,5]},
|
||||
{"ability": ["FLYING", 0, 0, 0 ], "skills": [4,5]}
|
||||
],
|
||||
"artifacts":
|
||||
[
|
||||
{
|
||||
"id": 146, //axe of smashing
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 6,
|
||||
"bonus": ["PRIMARY_SKILL", 1, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 147, //mithril mail
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 1,
|
||||
"bonus": ["STACK_HEALTH", 1, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 148, //sword of sharpness
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 1,
|
||||
"bonus": ["CREATURE_DAMAGE", 1, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 150, //pendant of sorcery
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 10,
|
||||
"bonus": ["CREATURE_ENCHANT_POWER", 1, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 151, //boots of haste
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 10,
|
||||
"bonus": ["STACKS_SPEED", 1, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 152, //bow of seeking
|
||||
"thresholdBonuses":
|
||||
[
|
||||
{
|
||||
"level": 5,
|
||||
"bonus": ["SHOOTER", 0, 0, 0]
|
||||
},
|
||||
{
|
||||
"level": 25,
|
||||
"bonus": ["NO_WALL_PENALTY", 0, 0, 0]
|
||||
},
|
||||
{
|
||||
"level": 50,
|
||||
"bonus": ["NO_DISTANCE_PENALTY", 0, 0, 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 153, //hardened shield
|
||||
"bonusesPerLevel":
|
||||
[
|
||||
{
|
||||
"level": 6,
|
||||
"bonus": ["PRIMARY_SKILL", 1, 1, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -8,6 +8,7 @@
|
||||
#include "CSpellHandler.h"
|
||||
#include "CObjectHandler.h"
|
||||
#include "NetPacks.h"
|
||||
#include "../lib/JsonNode.h"
|
||||
|
||||
extern CLodHandler *bitmaph;
|
||||
using namespace boost::assign;
|
||||
@ -23,6 +24,7 @@ using namespace boost::assign;
|
||||
*/
|
||||
|
||||
extern boost::rand48 ran;
|
||||
extern Bonus * ParseBonus (const JsonVector &ability_vec);
|
||||
|
||||
const std::string & CArtifact::Name() const
|
||||
{
|
||||
@ -44,11 +46,6 @@ bool CArtifact::isBig () const
|
||||
{
|
||||
return VLC->arth->isBigArtifact(id);
|
||||
}
|
||||
//
|
||||
// bool CArtifact::isModable () const
|
||||
// {
|
||||
// return (bool)dynamic_cast<const IModableArt *>(this);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Checks whether the artifact fits at a given slot.
|
||||
@ -193,6 +190,30 @@ void CArtifact::setDescription (std::string desc)
|
||||
description = desc;
|
||||
}
|
||||
|
||||
void CGrowingArtifact::levelUpArtifact (CArtifactInstance * art)
|
||||
{
|
||||
Bonus b;
|
||||
b.type = Bonus::LEVEL_COUNTER;
|
||||
b.val = 1;
|
||||
b.duration = Bonus::COMMANDER_KILLED;
|
||||
art->accumulateBonus (b);
|
||||
|
||||
BOOST_FOREACH (auto bonus, bonusesPerLevel)
|
||||
{
|
||||
if (art->valOfBonuses(Bonus::LEVEL_COUNTER) % bonus.first == 0) //every n levels
|
||||
{
|
||||
art->accumulateBonus (bonus.second);
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH (auto bonus, thresholdBonuses)
|
||||
{
|
||||
if (art->valOfBonuses(Bonus::LEVEL_COUNTER) == bonus.first) //every n levels
|
||||
{
|
||||
art->addNewBonus (&bonus.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CArtHandler::CArtHandler()
|
||||
{
|
||||
VLC->arth = this;
|
||||
@ -215,6 +236,7 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
{
|
||||
std::vector<ui16> slots;
|
||||
slots += 17, 16, 15, 14, 13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
|
||||
growingArtifacts += 146, 147, 148, 150, 151, 152, 153;
|
||||
static std::map<char, CArtifact::EartClass> classes =
|
||||
map_list_of('S',CArtifact::ART_SPECIAL)('T',CArtifact::ART_TREASURE)('N',CArtifact::ART_MINOR)('J',CArtifact::ART_MAJOR)('R',CArtifact::ART_RELIC);
|
||||
std::string buf = bitmaph->getTextFile("ARTRAITS.TXT"), dump, pom;
|
||||
@ -226,10 +248,18 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
VLC->generaltexth->artifNames.resize(GameConstants::ARTIFACTS_QUANTITY);
|
||||
VLC->generaltexth->artifDescriptions.resize(GameConstants::ARTIFACTS_QUANTITY);
|
||||
std::map<ui32,ui8>::iterator itr;
|
||||
|
||||
for (int i=0; i<GameConstants::ARTIFACTS_QUANTITY; i++)
|
||||
{
|
||||
CArtifact *art = new CArtifact();
|
||||
|
||||
CArtifact *art;
|
||||
if (vstd::contains (growingArtifacts, i))
|
||||
{
|
||||
art = new CGrowingArtifact();
|
||||
}
|
||||
else
|
||||
{
|
||||
art = new CArtifact();
|
||||
}
|
||||
CArtifact &nart = *art;
|
||||
nart.id=i;
|
||||
loadToIt(VLC->generaltexth->artifNames[i],buf,it,4);
|
||||
@ -329,6 +359,23 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
|
||||
artifacts.push_back(&nart);
|
||||
}
|
||||
if (GameConstants::COMMANDERS)
|
||||
{ //TODO: move all artifacts config to separate json file
|
||||
const JsonNode config(GameConstants::DATA_DIR + "/config/commanders.json");
|
||||
BOOST_FOREACH(const JsonNode &artifact, config["artifacts"].Vector())
|
||||
{
|
||||
auto ga = dynamic_cast <CGrowingArtifact *>(artifacts[artifact["id"].Float()].get());
|
||||
BOOST_FOREACH (auto b, artifact["bonusesPerLevel"].Vector())
|
||||
{
|
||||
ga->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *ParseBonus (b["bonus"].Vector())));
|
||||
}
|
||||
BOOST_FOREACH (auto b, artifact["thresholdBonuses"].Vector())
|
||||
{
|
||||
ga->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *ParseBonus (b["bonus"].Vector())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sortArts();
|
||||
if(onlyTxt)
|
||||
return;
|
||||
@ -1112,7 +1159,17 @@ void CArtifactInstance::move(ArtifactLocation src, ArtifactLocation dst)
|
||||
CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
|
||||
{
|
||||
if(!Art->constituents)
|
||||
return new CArtifactInstance(Art);
|
||||
{
|
||||
auto ret = new CArtifactInstance(Art);
|
||||
if (dynamic_cast<CGrowingArtifact *>(Art))
|
||||
{
|
||||
Bonus * bonus = new Bonus;
|
||||
bonus->type = Bonus::LEVEL_COUNTER;
|
||||
bonus->val = 0;
|
||||
ret->addNewBonus (bonus);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCombinedArtifactInstance * ret = new CCombinedArtifactInstance(Art);
|
||||
|
@ -18,6 +18,7 @@ class CArtifact;
|
||||
class CGHeroInstance;
|
||||
struct ArtifactLocation;
|
||||
class CArtifactSet;
|
||||
class CArtifactInstance;
|
||||
|
||||
namespace ArtifactPosition
|
||||
{
|
||||
@ -55,6 +56,8 @@ public:
|
||||
int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other
|
||||
std::string nodeName() const OVERRIDE;
|
||||
|
||||
virtual void levelUpArtifact (CArtifactInstance * art){};
|
||||
|
||||
ui32 price;
|
||||
bmap<ui8, std::vector<ui16> > possibleSlots; //Bearer Type => ids of slots where artifact can be placed
|
||||
std::vector<ui32> * constituents; // Artifacts IDs a combined artifact consists of, or NULL.
|
||||
@ -75,6 +78,21 @@ public:
|
||||
//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CGrowingArtifact : public CArtifact //for example commander artifacts getting bonuses after battle
|
||||
{
|
||||
public:
|
||||
std::vector <std::pair <ui16, Bonus> > bonusesPerLevel; //bonus given each n levels
|
||||
std::vector <std::pair <ui16, Bonus> > thresholdBonuses; //after certain level they will be added once
|
||||
|
||||
void levelUpArtifact (CArtifactInstance * art);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArtifact&>(*this);
|
||||
h & bonusesPerLevel & thresholdBonuses;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CArtifactInstance : public CBonusSystemNode
|
||||
{
|
||||
protected:
|
||||
@ -170,7 +188,7 @@ public:
|
||||
std::vector< ConstTransitivePtr<CArtifact> > artifacts;
|
||||
std::vector<CArtifact *> allowedArtifacts;
|
||||
std::set<ui32> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines.
|
||||
//std::map<ui32, ui8> modableArtifacts; //1-scroll, 2-banner, 3-commander art with progressive bonus
|
||||
std::set<ui32> growingArtifacts;
|
||||
|
||||
void loadArtifacts(bool onlyTxt);
|
||||
void sortArts();
|
||||
@ -194,7 +212,8 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & artifacts & allowedArtifacts & treasures & minors & majors & relics;
|
||||
h & artifacts & allowedArtifacts & treasures & minors & majors & relics
|
||||
& growingArtifacts;
|
||||
//if(!h.saving) sortArts();
|
||||
}
|
||||
};
|
||||
|
@ -202,24 +202,6 @@ bool CCreatureHandler::isEvil (si8 faction) const
|
||||
{
|
||||
return faction != -1 && factionAlignments[faction] == -1;
|
||||
}
|
||||
static Bonus * ParseBonus (const JsonVector &ability_vec) //TODO: merge with AddAbility, create universal parser for all bonus properties
|
||||
{
|
||||
Bonus * b = new Bonus();
|
||||
std::string type = ability_vec[0].String();
|
||||
auto it = bonusNameMap.find(type);
|
||||
if (it == bonusNameMap.end())
|
||||
{
|
||||
tlog1 << "Error: invalid ability type " << type << " in creatures.txt" << std::endl;
|
||||
return b;
|
||||
}
|
||||
b->type = it->second;
|
||||
b->val = ability_vec[1].Float();
|
||||
b->subtype = ability_vec[2].Float();
|
||||
b->additionalInfo = ability_vec[3].Float();
|
||||
b->duration = Bonus::PERMANENT;
|
||||
b->turnsRemain = 0;
|
||||
return b;
|
||||
}
|
||||
|
||||
static void AddAbility(CCreature *cre, const JsonVector &ability_vec)
|
||||
{
|
||||
|
@ -1010,7 +1010,7 @@ void CCommanderInstance::setAlive (bool Alive)
|
||||
alive = Alive;
|
||||
if (!alive)
|
||||
{
|
||||
//remove all bonuses from artifacts
|
||||
getBonusList().remove_if (Bonus::UntilCommanderKilled);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ typedef boost::function<bool(const Bonus*)> CSelector;
|
||||
|
||||
#define BONUS_LIST \
|
||||
BONUS_NAME(NONE) \
|
||||
BONUS_NAME(LEVEL_COUNTER) /* for commander artifacts*/ \
|
||||
BONUS_NAME(MOVEMENT) /*both water/land*/ \
|
||||
BONUS_NAME(LAND_MOVEMENT) \
|
||||
BONUS_NAME(SEA_MOVEMENT) \
|
||||
@ -194,7 +195,8 @@ struct DLL_LINKAGE Bonus
|
||||
N_DAYS = 32,
|
||||
UNITL_BEING_ATTACKED = 64,/*removed after attack and counterattacks are performed*/
|
||||
UNTIL_ATTACK = 128, /*removed after attack and counterattacks are performed*/
|
||||
STACK_GETS_TURN = 256 /*removed when stack gets its turn - used for defensive stance*/
|
||||
STACK_GETS_TURN = 256, /*removed when stack gets its turn - used for defensive stance*/
|
||||
COMMANDER_KILLED = 512
|
||||
};
|
||||
enum BonusSource
|
||||
{
|
||||
@ -303,6 +305,10 @@ struct DLL_LINKAGE Bonus
|
||||
{
|
||||
return hb->duration & Bonus::UNITL_BEING_ATTACKED;
|
||||
}
|
||||
static bool UntilCommanderKilled(const Bonus *hb)
|
||||
{
|
||||
return hb->duration & Bonus::COMMANDER_KILLED;
|
||||
}
|
||||
static bool IsFrom(const Bonus &hb, ui8 source, ui32 id) //if id==0xffffff then id doesn't matter
|
||||
{
|
||||
return hb.source==source && (id==0xffffff || hb.sid==id);
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "StdInc.h"
|
||||
#include "JsonNode.h"
|
||||
|
||||
|
||||
class Bonus;
|
||||
|
||||
const JsonNode JsonNode::nullNode;
|
||||
|
||||
JsonNode::JsonNode(JsonType Type):
|
||||
@ -869,4 +872,4 @@ JsonValidator::JsonValidator(JsonNode &root, const JsonNode &schema, bool Minimi
|
||||
if (schema.isNull())
|
||||
addMessage("Schema not found!");
|
||||
tlog3<<errors;
|
||||
}
|
||||
}
|
413
lib/JsonNode.h
413
lib/JsonNode.h
@ -1,200 +1,221 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
class JsonNode;
|
||||
typedef std::map <std::string, JsonNode> JsonMap;
|
||||
typedef std::vector <JsonNode> JsonVector;
|
||||
|
||||
class DLL_LINKAGE JsonNode
|
||||
{
|
||||
public:
|
||||
enum JsonType
|
||||
{
|
||||
DATA_NULL,
|
||||
DATA_BOOL,
|
||||
DATA_FLOAT,
|
||||
DATA_STRING,
|
||||
DATA_VECTOR,
|
||||
DATA_STRUCT
|
||||
};
|
||||
|
||||
private:
|
||||
union JsonData
|
||||
{
|
||||
bool Bool;
|
||||
double Float;
|
||||
std::string* String;
|
||||
JsonVector* Vector;
|
||||
JsonMap* Struct;
|
||||
};
|
||||
|
||||
JsonType type;
|
||||
JsonData data;
|
||||
|
||||
public:
|
||||
//Create empty node
|
||||
JsonNode(JsonType Type = DATA_NULL);
|
||||
//Create tree from Json-formatted input
|
||||
explicit JsonNode(const char * data, size_t datasize);
|
||||
//Create tree from JSON file
|
||||
explicit JsonNode(std::string filename);
|
||||
//Copy c-tor
|
||||
JsonNode(const JsonNode ©);
|
||||
|
||||
~JsonNode();
|
||||
|
||||
void swap(JsonNode &b);
|
||||
JsonNode& operator =(JsonNode node);
|
||||
|
||||
bool operator == (const JsonNode &other) const;
|
||||
bool operator != (const JsonNode &other) const;
|
||||
|
||||
//removes all nodes that are identical to default entry in schema
|
||||
void minimize(const JsonNode& schema);
|
||||
//check schema
|
||||
void validate(const JsonNode& schema);
|
||||
|
||||
//Convert node to another type. Converting to NULL will clear all data
|
||||
void setType(JsonType Type);
|
||||
JsonType getType() const;
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
//non-const accessors, node will change type on type mismatch
|
||||
bool & Bool();
|
||||
double & Float();
|
||||
std::string & String();
|
||||
JsonVector & Vector();
|
||||
JsonMap & Struct();
|
||||
|
||||
//const accessors, will cause assertion failure on type mismatch
|
||||
const bool & Bool() const;
|
||||
const double & Float() const;
|
||||
const std::string & String() const;
|
||||
const JsonVector & Vector() const;
|
||||
const JsonMap & Struct() const;
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> StdVector() const
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "This works with numbers only.");
|
||||
#pragma once
|
||||
|
||||
#include "HeroBonus.h"
|
||||
|
||||
class JsonNode;
|
||||
typedef std::map <std::string, JsonNode> JsonMap;
|
||||
typedef std::vector <JsonNode> JsonVector;
|
||||
|
||||
class Bonus;
|
||||
|
||||
class DLL_LINKAGE JsonNode
|
||||
{
|
||||
public:
|
||||
enum JsonType
|
||||
{
|
||||
DATA_NULL,
|
||||
DATA_BOOL,
|
||||
DATA_FLOAT,
|
||||
DATA_STRING,
|
||||
DATA_VECTOR,
|
||||
DATA_STRUCT
|
||||
};
|
||||
|
||||
private:
|
||||
union JsonData
|
||||
{
|
||||
bool Bool;
|
||||
double Float;
|
||||
std::string* String;
|
||||
JsonVector* Vector;
|
||||
JsonMap* Struct;
|
||||
};
|
||||
|
||||
JsonType type;
|
||||
JsonData data;
|
||||
|
||||
public:
|
||||
//Create empty node
|
||||
JsonNode(JsonType Type = DATA_NULL);
|
||||
//Create tree from Json-formatted input
|
||||
explicit JsonNode(const char * data, size_t datasize);
|
||||
//Create tree from JSON file
|
||||
explicit JsonNode(std::string filename);
|
||||
//Copy c-tor
|
||||
JsonNode(const JsonNode ©);
|
||||
|
||||
~JsonNode();
|
||||
|
||||
void swap(JsonNode &b);
|
||||
JsonNode& operator =(JsonNode node);
|
||||
|
||||
bool operator == (const JsonNode &other) const;
|
||||
bool operator != (const JsonNode &other) const;
|
||||
|
||||
//removes all nodes that are identical to default entry in schema
|
||||
void minimize(const JsonNode& schema);
|
||||
//check schema
|
||||
void validate(const JsonNode& schema);
|
||||
|
||||
//Convert node to another type. Converting to NULL will clear all data
|
||||
void setType(JsonType Type);
|
||||
JsonType getType() const;
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
//non-const accessors, node will change type on type mismatch
|
||||
bool & Bool();
|
||||
double & Float();
|
||||
std::string & String();
|
||||
JsonVector & Vector();
|
||||
JsonMap & Struct();
|
||||
|
||||
//const accessors, will cause assertion failure on type mismatch
|
||||
const bool & Bool() const;
|
||||
const double & Float() const;
|
||||
const std::string & String() const;
|
||||
const JsonVector & Vector() const;
|
||||
const JsonMap & Struct() const;
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> StdVector() const
|
||||
{
|
||||
static_assert(std::is_arithmetic<T>::value, "This works with numbers only.");
|
||||
std::vector<T> ret;
|
||||
BOOST_FOREACH(const JsonNode &node, Vector())
|
||||
{
|
||||
ret.push_back(node.Float());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//operator [], for structs only - get child node by name
|
||||
JsonNode & operator[](std::string child);
|
||||
const JsonNode & operator[](std::string child) const;
|
||||
|
||||
//error value for const operator[]
|
||||
static const JsonNode nullNode;
|
||||
};
|
||||
|
||||
class JsonWriter
|
||||
{
|
||||
//prefix for each line (tabulation)
|
||||
std::string prefix;
|
||||
std::ostream &out;
|
||||
public:
|
||||
template<typename Iterator>
|
||||
void writeContainer(Iterator begin, Iterator end);
|
||||
void writeEntry(JsonMap::const_iterator entry);
|
||||
void writeEntry(JsonVector::const_iterator entry);
|
||||
void writeString(const std::string &string);
|
||||
void writeNode(const JsonNode &node);
|
||||
JsonWriter(std::ostream &output, const JsonNode &node);
|
||||
};
|
||||
|
||||
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const JsonNode &node);
|
||||
|
||||
//Tiny string class that uses const char* as data for speed, members are private
|
||||
//for ease of debugging and some compatibility with std::string
|
||||
class constString
|
||||
{
|
||||
const char *data;
|
||||
const size_t datasize;
|
||||
|
||||
public:
|
||||
constString(const char * inputString, size_t stringSize):
|
||||
data(inputString),
|
||||
datasize(stringSize)
|
||||
{
|
||||
}
|
||||
|
||||
inline size_t size() const
|
||||
{
|
||||
return datasize;
|
||||
};
|
||||
|
||||
inline const char& operator[] (size_t position)
|
||||
{
|
||||
assert (position < datasize);
|
||||
return data[position];
|
||||
}
|
||||
};
|
||||
|
||||
//Internal class for string -> JsonNode conversion
|
||||
class JsonParser
|
||||
{
|
||||
std::string errors; // Contains description of all encountered errors
|
||||
constString input; // Input data
|
||||
ui32 lineCount; // Currently parsed line, starting from 1
|
||||
size_t lineStart; // Position of current line start
|
||||
size_t pos; // Current position of parser
|
||||
|
||||
//Helpers
|
||||
bool extractEscaping(std::string &str);
|
||||
bool extractLiteral(const std::string &literal);
|
||||
bool extractString(std::string &string);
|
||||
bool extractWhitespace(bool verbose = true);
|
||||
bool extractSeparator();
|
||||
bool extractElement(JsonNode &node, char terminator);
|
||||
|
||||
//Methods for extracting JSON data
|
||||
bool extractArray(JsonNode &node);
|
||||
bool extractFalse(JsonNode &node);
|
||||
bool extractFloat(JsonNode &node);
|
||||
bool extractNull(JsonNode &node);
|
||||
bool extractString(JsonNode &node);
|
||||
bool extractStruct(JsonNode &node);
|
||||
bool extractTrue(JsonNode &node);
|
||||
bool extractValue(JsonNode &node);
|
||||
|
||||
//Add error\warning message to list
|
||||
bool error(const std::string &message, bool warning=false);
|
||||
|
||||
public:
|
||||
JsonParser(const char * inputString, size_t stringSize, JsonNode &root);
|
||||
};
|
||||
|
||||
//Internal class for Json validation, used automaticaly in JsonNode constructor. Behaviour:
|
||||
// - "schema" entry from root node is used for validation and will be removed
|
||||
// - any missing entries will be replaced with default value from schema (if present)
|
||||
// - if entry uses different type than defined in schema it will be removed
|
||||
// - entries nod described in schema will be kept unchanged
|
||||
class JsonValidator
|
||||
{
|
||||
std::string errors; // Contains description of all encountered errors
|
||||
std::list<std::string> currentPath; // path from root node to current one
|
||||
bool minimize;
|
||||
|
||||
bool validateType(JsonNode &node, const JsonNode &schema, JsonNode::JsonType type);
|
||||
bool validateSchema(JsonNode::JsonType &type, const JsonNode &schema);
|
||||
bool validateNode(JsonNode &node, const JsonNode &schema, const std::string &name);
|
||||
bool validateItems(JsonNode &node, const JsonNode &schema);
|
||||
bool validateProperties(JsonNode &node, const JsonNode &schema);
|
||||
|
||||
bool addMessage(const std::string &message);
|
||||
public:
|
||||
// validate node with "schema" entry
|
||||
JsonValidator(JsonNode &root, bool minimize=false);
|
||||
// validate with external schema
|
||||
JsonValidator(JsonNode &root, const JsonNode &schema, bool minimize=false);
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//operator [], for structs only - get child node by name
|
||||
JsonNode & operator[](std::string child);
|
||||
const JsonNode & operator[](std::string child) const;
|
||||
|
||||
//error value for const operator[]
|
||||
static const JsonNode nullNode;
|
||||
};
|
||||
|
||||
class JsonWriter
|
||||
{
|
||||
//prefix for each line (tabulation)
|
||||
std::string prefix;
|
||||
std::ostream &out;
|
||||
public:
|
||||
template<typename Iterator>
|
||||
void writeContainer(Iterator begin, Iterator end);
|
||||
void writeEntry(JsonMap::const_iterator entry);
|
||||
void writeEntry(JsonVector::const_iterator entry);
|
||||
void writeString(const std::string &string);
|
||||
void writeNode(const JsonNode &node);
|
||||
JsonWriter(std::ostream &output, const JsonNode &node);
|
||||
};
|
||||
|
||||
DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const JsonNode &node);
|
||||
|
||||
//Tiny string class that uses const char* as data for speed, members are private
|
||||
//for ease of debugging and some compatibility with std::string
|
||||
class constString
|
||||
{
|
||||
const char *data;
|
||||
const size_t datasize;
|
||||
|
||||
public:
|
||||
constString(const char * inputString, size_t stringSize):
|
||||
data(inputString),
|
||||
datasize(stringSize)
|
||||
{
|
||||
}
|
||||
|
||||
inline size_t size() const
|
||||
{
|
||||
return datasize;
|
||||
};
|
||||
|
||||
inline const char& operator[] (size_t position)
|
||||
{
|
||||
assert (position < datasize);
|
||||
return data[position];
|
||||
}
|
||||
};
|
||||
|
||||
//Internal class for string -> JsonNode conversion
|
||||
class JsonParser
|
||||
{
|
||||
std::string errors; // Contains description of all encountered errors
|
||||
constString input; // Input data
|
||||
ui32 lineCount; // Currently parsed line, starting from 1
|
||||
size_t lineStart; // Position of current line start
|
||||
size_t pos; // Current position of parser
|
||||
|
||||
//Helpers
|
||||
bool extractEscaping(std::string &str);
|
||||
bool extractLiteral(const std::string &literal);
|
||||
bool extractString(std::string &string);
|
||||
bool extractWhitespace(bool verbose = true);
|
||||
bool extractSeparator();
|
||||
bool extractElement(JsonNode &node, char terminator);
|
||||
|
||||
//Methods for extracting JSON data
|
||||
bool extractArray(JsonNode &node);
|
||||
bool extractFalse(JsonNode &node);
|
||||
bool extractFloat(JsonNode &node);
|
||||
bool extractNull(JsonNode &node);
|
||||
bool extractString(JsonNode &node);
|
||||
bool extractStruct(JsonNode &node);
|
||||
bool extractTrue(JsonNode &node);
|
||||
bool extractValue(JsonNode &node);
|
||||
|
||||
//Add error\warning message to list
|
||||
bool error(const std::string &message, bool warning=false);
|
||||
|
||||
public:
|
||||
JsonParser(const char * inputString, size_t stringSize, JsonNode &root);
|
||||
};
|
||||
|
||||
//Internal class for Json validation, used automaticaly in JsonNode constructor. Behaviour:
|
||||
// - "schema" entry from root node is used for validation and will be removed
|
||||
// - any missing entries will be replaced with default value from schema (if present)
|
||||
// - if entry uses different type than defined in schema it will be removed
|
||||
// - entries nod described in schema will be kept unchanged
|
||||
class JsonValidator
|
||||
{
|
||||
std::string errors; // Contains description of all encountered errors
|
||||
std::list<std::string> currentPath; // path from root node to current one
|
||||
bool minimize;
|
||||
|
||||
bool validateType(JsonNode &node, const JsonNode &schema, JsonNode::JsonType type);
|
||||
bool validateSchema(JsonNode::JsonType &type, const JsonNode &schema);
|
||||
bool validateNode(JsonNode &node, const JsonNode &schema, const std::string &name);
|
||||
bool validateItems(JsonNode &node, const JsonNode &schema);
|
||||
bool validateProperties(JsonNode &node, const JsonNode &schema);
|
||||
|
||||
bool addMessage(const std::string &message);
|
||||
public:
|
||||
// validate node with "schema" entry
|
||||
JsonValidator(JsonNode &root, bool minimize=false);
|
||||
// validate with external schema
|
||||
JsonValidator(JsonNode &root, const JsonNode &schema, bool minimize=false);
|
||||
};
|
||||
|
||||
//Bonus * ParseBonus (const JsonVector &ability_vec);
|
||||
|
||||
static Bonus * ParseBonus (const JsonVector &ability_vec) //TODO: merge with AddAbility, create universal parser for all bonus properties
|
||||
{
|
||||
Bonus * b = new Bonus();
|
||||
std::string type = ability_vec[0].String();
|
||||
auto it = bonusNameMap.find(type);
|
||||
if (it == bonusNameMap.end())
|
||||
{
|
||||
tlog1 << "Error: invalid ability type " << type << " in creatures.txt" << std::endl;
|
||||
return b;
|
||||
}
|
||||
b->type = it->second;
|
||||
b->val = ability_vec[1].Float();
|
||||
b->subtype = ability_vec[2].Float();
|
||||
b->additionalInfo = ability_vec[3].Float();
|
||||
b->duration = Bonus::PERMANENT;
|
||||
b->turnsRemain = 0;
|
||||
return b;
|
||||
}
|
@ -1032,6 +1032,8 @@ DLL_LINKAGE void BattleObstaclePlaced::applyGs( CGameState *gs )
|
||||
void BattleResult::applyGs( CGameState *gs )
|
||||
{
|
||||
//stack with SUMMONED flag but coming from garrison -> most likely resurrected, needs to be removed
|
||||
|
||||
//TODO: switch commander status to dead
|
||||
BOOST_FOREACH(CStack *s, gs->curB->stacks)
|
||||
{
|
||||
if(s->base && s->base->armyObj && vstd::contains(s->state, EBattleStackState::SUMMONED))
|
||||
@ -1043,14 +1045,20 @@ void BattleResult::applyGs( CGameState *gs )
|
||||
for (unsigned i = 0; i < gs->curB->stacks.size(); i++)
|
||||
delete gs->curB->stacks[i];
|
||||
|
||||
//remove any "until next battle" bonuses
|
||||
CGHeroInstance *h;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
h = gs->curB->heroes[i];
|
||||
h = gs->curB->heroes[i];
|
||||
if (h)
|
||||
{
|
||||
h->getBonusList().remove_if(Bonus::OneBattle);
|
||||
h->getBonusList().remove_if(Bonus::OneBattle); //remove any "until next battle" bonuses
|
||||
if (h->commander && h->commander->alive)
|
||||
{
|
||||
BOOST_FOREACH (auto art, h->commander->artifactsWorn) //increment bonuses for commander artifacts
|
||||
{
|
||||
art.second.artifact->artType->levelUpArtifact (art.second.artifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user