mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-14 02:33:51 +02:00
Merged Warmonger's changes from trunk
This commit is contained in:
commit
31fc8f6db3
@ -17,7 +17,7 @@ void CEmptyAI::heroKilled(const CGHeroInstance *)
|
|||||||
void CEmptyAI::heroCreated(const CGHeroInstance *)
|
void CEmptyAI::heroCreated(const CGHeroInstance *)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void CEmptyAI::heroMoved(const HeroMoveDetails &)
|
void CEmptyAI::heroMoved(const TryMoveHero& TMH)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void CEmptyAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)
|
void CEmptyAI::heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)
|
||||||
|
@ -11,7 +11,7 @@ public:
|
|||||||
void yourTurn();
|
void yourTurn();
|
||||||
void heroKilled(const CGHeroInstance *);
|
void heroKilled(const CGHeroInstance *);
|
||||||
void heroCreated(const CGHeroInstance *);
|
void heroCreated(const CGHeroInstance *);
|
||||||
void heroMoved(const HeroMoveDetails &);
|
void heroMoved(const TryMoveHero&);
|
||||||
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {};
|
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {};
|
||||||
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
||||||
void tileRevealed(int3 pos){};
|
void tileRevealed(int3 pos){};
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
template <typename ruleType, typename facts> template <typename cond> void ExpertSystemShell<ruleType, facts>::DataDrivenReasoning(runType type)
|
template <typename ruleType, typename facts> template <typename cond> void ExpertSystemShell<ruleType, facts>::DataDrivenReasoning(runType type)
|
||||||
{
|
{
|
||||||
std::set<ruleType>::iterator ir;
|
std::vector<ruleType>::iterator ir;
|
||||||
std::list<fact>::iterator iF;
|
std::list<fact>::iterator iF;
|
||||||
std::set<std::pair<cond, input*>>::iterator ic;
|
std::vector<std::pair<cond, input*>>::iterator ic;
|
||||||
bool factWasAdded = false; //carry it over inner loop
|
bool factWasAdded = false; //carry it over inner loop
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -72,7 +72,7 @@ template <typename ruleType, typename facts> template <typename cond> void Exper
|
|||||||
}
|
}
|
||||||
void BonusRule::fireRule()
|
void BonusRule::fireRule()
|
||||||
{
|
{
|
||||||
for (std::set<std::pair<BonusCondition, BonusHolder*>>::iterator it = cons.begin(); it != cons.end(); it++)
|
for (std::vector<std::pair<BonusCondition, BonusHolder*>>::iterator it = cons.begin(); it != cons.end(); it++)
|
||||||
{
|
{
|
||||||
switch (it->first.parameter)
|
switch (it->first.parameter)
|
||||||
{ //compare fact with condition
|
{ //compare fact with condition
|
||||||
@ -109,18 +109,31 @@ void BonusRule::fireRule()
|
|||||||
}
|
}
|
||||||
//TODO: add new fact or modify existing one
|
//TODO: add new fact or modify existing one
|
||||||
}
|
}
|
||||||
//TODO: find out why it does not compile
|
|
||||||
//template <typename input, typename conType> void Rule<input, conType>::refreshRule(std::set<conType> &conditionSet)
|
TLogic operator&&(const TLogic &first, const TLogic &second)
|
||||||
//{
|
{
|
||||||
// cons.clear();
|
return LogicConjunction(first, second);
|
||||||
// for (std::set<conType>::iterator it = conditionSet.begin(); it != conditionSet.end(); it++)
|
}
|
||||||
// cons.insert(std::make_pair<conType,input*>(*it, NULL)); //pointer to condition and null fact
|
TLogic operator||(const TLogic &first, const TLogic &second)
|
||||||
//}
|
{
|
||||||
//template <typename input, typename conType> void Rule<input, conType>::refreshRule()
|
return LogicAlternative(first, second);
|
||||||
//{
|
}
|
||||||
// for (std::set<std::pair<conType, input*>>::iterator it = cons.begin(); it != cons.end(); it++)
|
template <typename input, typename conType> void Rule<input, conType>::refreshRule(std::vector<conType> &conditionSet)
|
||||||
// *it->second = NULL;
|
{//replace conditions with new vector
|
||||||
//}
|
cons.clear();
|
||||||
|
std::pair <conType,input*> para;
|
||||||
|
para.second = NULL;
|
||||||
|
for (std::vector<conType>::iterator it = conditionSet.begin(); it != conditionSet.end(); it++)
|
||||||
|
{
|
||||||
|
para.first = *it;
|
||||||
|
cons.push_back(para); //pointer to condition and null fact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template <typename input, typename conType> void Rule<input, conType>::refreshRule()
|
||||||
|
{//clear matching facts
|
||||||
|
for (std::vector<std::pair<conType, input*>>::iterator it = cons.begin(); it != cons.end(); it++)
|
||||||
|
it->second = NULL;
|
||||||
|
}
|
||||||
bool BonusCondition::matchesFact(Bonus &fact)
|
bool BonusCondition::matchesFact(Bonus &fact)
|
||||||
{
|
{
|
||||||
if (object(fact)) //Bonus(fact) matches local Selector(object)
|
if (object(fact)) //Bonus(fact) matches local Selector(object)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "../vcmi/CCallback.h"
|
#include "../vcmi/CCallback.h"
|
||||||
#include "../vcmi/lib/HeroBonus.h"
|
#include "../vcmi/lib/HeroBonus.h"
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <set>
|
#include <vector>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ExpertSystem.h, part of VCMI engine
|
* ExpertSystem.h, part of VCMI engine
|
||||||
@ -17,21 +17,22 @@ struct Bonus;
|
|||||||
template <typename fact> class AIholder;
|
template <typename fact> class AIholder;
|
||||||
template <typename input, typename output> class Rule;
|
template <typename input, typename output> class Rule;
|
||||||
typedef Rule<Bonus, Bonus> BRule;
|
typedef Rule<Bonus, Bonus> BRule;
|
||||||
|
typedef boost::function<bool(int, si32)> TLogic;
|
||||||
bool greaterThan (int prop, si32 val);
|
bool greaterThan (int prop, si32 val);
|
||||||
|
|
||||||
enum conditionType {LESS_THAN, EQUAL, GREATER_THAN, UNEQUAL, PRESENT};
|
enum conditionType {LESS_THAN, EQUAL, GREATER_THAN, UNEQUAL, PRESENT};
|
||||||
|
|
||||||
template <typename ruleType, typename fact> class ExpertSystemShell
|
template <typename ruleType, typename fact> class ExpertSystemShell
|
||||||
{
|
{
|
||||||
enum runType {ANY_GOAL, TRESHOLD, FULL};
|
enum runType {ANY_GOAL, TRESHOLD, FULL}; //Treshold - stop when received decision has high AI value
|
||||||
private:
|
private:
|
||||||
ICallback* m_cb;
|
ICallback* m_cb;
|
||||||
protected:
|
protected:
|
||||||
std::set<ruleType> knowledge;
|
std::vector<ruleType> knowledge;
|
||||||
std::set<ruleType*> rulesToErase;
|
std::vector<ruleType*> rulesToErase;
|
||||||
std::set<ruleType*> rulesToAdd;
|
std::vector<ruleType*> rulesToAdd;
|
||||||
std::set<fact*> factsToErase;
|
std::vector<fact*> factsToErase;
|
||||||
std::set<fact*> factsToAdd;
|
std::vector<fact*> factsToAdd;
|
||||||
ui16 goalCounter; //count / evaluate achieved goals for runType
|
ui16 goalCounter; //count / evaluate achieved goals for runType
|
||||||
public:
|
public:
|
||||||
ExpertSystemShell(){goalCounter = 0;};
|
ExpertSystemShell(){goalCounter = 0;};
|
||||||
@ -53,12 +54,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename input> class condition
|
template <typename input> class condition
|
||||||
{//compares selected object parameter with value using functor. universal logic handler
|
{//compares selected object parameter with value using functor. universal (?) logic handler
|
||||||
public:
|
public:
|
||||||
input object; //what the fact is, or what it's like (CSelector)
|
input object; //what the fact is, or what it's like (CSelector)
|
||||||
si32 value;
|
si32 value;
|
||||||
ui8 parameter;
|
ui8 parameter;
|
||||||
boost::function<bool(int,si32)> functor; //value of selected parameter, condition value
|
TLogic functor; //value of selected parameter, condition value
|
||||||
|
|
||||||
condition(){object = NULL; value = 0; parameter = 0; functor = greaterThan;};
|
condition(){object = NULL; value = 0; parameter = 0; functor = greaterThan;};
|
||||||
|
|
||||||
@ -72,16 +73,16 @@ public:
|
|||||||
bool fired; //if conditions of rule were met and it produces some output
|
bool fired; //if conditions of rule were met and it produces some output
|
||||||
ui8 conditionCounter;
|
ui8 conditionCounter;
|
||||||
protected:
|
protected:
|
||||||
std::set<std::pair<conType, input*>> cons; //conditions and matching facts
|
std::vector<std::pair<conType, input*>> cons; //conditions and matching facts
|
||||||
input decision;
|
input decision;
|
||||||
virtual void canBeFired(); //if this data makes any sense for rule - type check
|
virtual void canBeFired(); //if this data makes any sense for rule - type check
|
||||||
virtual bool checkCondition(); //if condition is true or false
|
virtual bool checkCondition(); //if condition is true or false
|
||||||
virtual bool checkCondition(std::set<input*> &feed);
|
virtual bool checkCondition(std::vector<input*> &feed);
|
||||||
virtual void fireRule(); //use paired conditions and facts by default
|
virtual void fireRule(); //use paired conditions and facts by default
|
||||||
virtual void fireRule(ExpertSystemShell<input, conType> &system);
|
virtual void fireRule(ExpertSystemShell<input, conType> &system);
|
||||||
virtual void fireRule(std::set<input*> &feed);
|
virtual void fireRule(std::vector<input*> &feed);
|
||||||
virtual void refreshRule();
|
virtual void refreshRule();
|
||||||
virtual void refreshRule(std::set<conType> &conditionSet); //in case conditions were erased
|
virtual void refreshRule(std::vector<conType> &conditionSet); //in case conditions were erased
|
||||||
public:
|
public:
|
||||||
Rule(){fired = false; conditionCounter = 0; decision = NULL;};
|
Rule(){fired = false; conditionCounter = 0; decision = NULL;};
|
||||||
template <typename givenInput> bool matchesInput() //if condition and data match type
|
template <typename givenInput> bool matchesInput() //if condition and data match type
|
||||||
@ -142,7 +143,7 @@ protected:
|
|||||||
void fireRule();
|
void fireRule();
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool greaterThan (int prop, si32 val)
|
inline bool greaterThan (int prop, si32 val) //does it make any sense to keep functors inline?
|
||||||
{
|
{
|
||||||
if ((si32)prop > val)
|
if ((si32)prop > val)
|
||||||
return true;
|
return true;
|
||||||
@ -172,6 +173,36 @@ inline bool present (int prop, si32 val=0)
|
|||||||
return(prop); //unfixable warning :(
|
return(prop); //unfixable warning :(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LogicConjunction
|
||||||
|
{
|
||||||
|
const TLogic first, second; //TODO: universal argument list of functions?
|
||||||
|
public:
|
||||||
|
LogicConjunction(const TLogic First, const TLogic Second)
|
||||||
|
:first(First), second(Second)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool operator()(int prop, si32 val) const
|
||||||
|
{
|
||||||
|
return first(prop,val) && second(prop,val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
TLogic operator&&(const TLogic &first, const TLogic &second);
|
||||||
|
|
||||||
|
class LogicAlternative
|
||||||
|
{
|
||||||
|
const TLogic first, second;
|
||||||
|
public:
|
||||||
|
LogicAlternative(const TLogic First, const TLogic Second)
|
||||||
|
:first(First), second(Second)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool operator()(int prop, si32 val) const
|
||||||
|
{
|
||||||
|
return first(prop,val) || second(prop,val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
TLogic operator||(const TLogic &first, const TLogic &second);
|
||||||
|
|
||||||
class KnowledgeHandler///I'd opt for one omniscent knowledge manager, so no templates here
|
class KnowledgeHandler///I'd opt for one omniscent knowledge manager, so no templates here
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -46,6 +46,7 @@ void CMediaHandler::extract(int index, std::string dstfile) //saves selected fil
|
|||||||
|
|
||||||
void CMediaHandler::extract(std::string srcfile, std::string dstfile, bool caseSens) //saves selected file
|
void CMediaHandler::extract(std::string srcfile, std::string dstfile, bool caseSens) //saves selected file
|
||||||
{
|
{
|
||||||
|
srcfile.erase(srcfile.find_last_of('.'));
|
||||||
if (caseSens)
|
if (caseSens)
|
||||||
{
|
{
|
||||||
for (size_t i=0;i<entries.size();++i)
|
for (size_t i=0;i<entries.size();++i)
|
||||||
|
41
config/bonusnames.txt
Normal file
41
config/bonusnames.txt
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
Bonus Name (24 characters?) Description
|
||||||
|
FLYING Fly Can Fly (ignores obstacles)
|
||||||
|
UNLIMITED_RETALIATIONS Unlimited retaliations May retaliate any number of attacks
|
||||||
|
SHOOTER Ranged Creature can make a Ranged Attack
|
||||||
|
FREE_SHOOTING Shoot Close Can make a Ranged Attack in Close Combat
|
||||||
|
NO_SHOTING_PENALTY ? ???
|
||||||
|
NO_MELEE_PENALTY No melee penalty Creature has no Melee Penalty
|
||||||
|
NO_DISTANCE_PENALTY No distance penalty Does full ranged damage from any distance
|
||||||
|
NO_OBSTACLES_PENALTY No obstacle penalty Creature has no Obstacle Penalty
|
||||||
|
JOUSTING Champion Champion Distance Bonus (+5% damage per square travelled)
|
||||||
|
RETURN_AFTER_STRIKE Attack and Return Returns to starting position after making a melee attack
|
||||||
|
BLOCKS_RETALIATION No retaliation Enemy cannot Retaliate
|
||||||
|
TWO_HEX_ATTACK_BREATH Breath Creature has a Breath Attack (2-hex range)
|
||||||
|
THREE_HEADED_ATTACK Three-headed attack Creature attacks three adjacent units
|
||||||
|
ATTACKS_ALL_ADJACENT Attack all around Creature attacks all adjacent enemies
|
||||||
|
FULL_HP_REGENERATION Regeneration May Regenerate full Health
|
||||||
|
LIFE_DRAIN Drain life Drains life equal to damage dealt
|
||||||
|
SELF_MORALE Positive morale Always has Positive Morale
|
||||||
|
SELF_LUCK Positive luck Always has Positive Luck
|
||||||
|
FEAR Fear Has a chance to cause Fear on an enemy stack
|
||||||
|
FEARLESS Fearless Immune to Fear ability
|
||||||
|
CHARGE_IMMUNITY Immune to Charge Immune to Champion charge bonus
|
||||||
|
HEALER Healer Heals allied units
|
||||||
|
CATAPULT Catapult Attacks siege walls
|
||||||
|
DRAGON_NATURE Dragon Creature has a Dragon Nature
|
||||||
|
NON_LIVING Non living Creature is immune to effects affecting Living units
|
||||||
|
UNDEAD Undead Creature is Undead
|
||||||
|
HATE Hates %s Does more damage to %s
|
||||||
|
DOUBLE_DAMAGE_CHANCE Death Blow Has %d% chance to deal double damage
|
||||||
|
MAGIC_RESISTANCE Magic Resistance Has %d% chance to resist enemy spell
|
||||||
|
SPELL_DAMAGE_REDUCTION Spell Resistance Damage from spells reduced 50%.
|
||||||
|
LEVEL_SPELL_IMMUNITY Spell immunity 1-%d Immune to spells levels 1-%d
|
||||||
|
HP_REGENERATION Regeneration Heals %d hit points every round
|
||||||
|
SPELL_IMMUNITY Immune to %s Immune to %s spell
|
||||||
|
ENEMY_DEFENCE_REDUCTION Reduces Enemy Defense Reduces Enemy Defense by %d% for this attack
|
||||||
|
MAGIC_MIRROR Magic Mirror Has %d% chance to redirect offensive spell back to enemy
|
||||||
|
ADDITIONAL_RETALIATION Additional retaliations May Retaliate %d extra times
|
||||||
|
CHANGES_SPELL_COST_FOR_ALLY Reduce Casting Cost Reduce Casting Cost of allied hero spells by %d
|
||||||
|
CHANGES_SPELL_COST_FOR_ENEMY Magic Damper Increase Casting Cost of enemy hero spells by %d
|
||||||
|
MANA_CHANNELING Magic Channel %d% mana spent by enemy is transfered to your hero
|
||||||
|
SPELL_AFTER_ATTACK Caster - %s %d% chance to cast %s after attack
|
6
global.h
6
global.h
@ -20,7 +20,8 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
|
|||||||
typedef si64 expType;
|
typedef si64 expType;
|
||||||
typedef ui16 spelltype;
|
typedef ui16 spelltype;
|
||||||
typedef std::pair<ui32, ui32> TDmgRange;
|
typedef std::pair<ui32, ui32> TDmgRange;
|
||||||
|
typedef ui8 TBonusType;
|
||||||
|
typedef si32 TBonusSubtype;
|
||||||
#include "int3.h"
|
#include "int3.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -117,11 +118,12 @@ const int NAMES_PER_TOWN=16;
|
|||||||
const int CREATURES_PER_TOWN = 7; //without upgrades
|
const int CREATURES_PER_TOWN = 7; //without upgrades
|
||||||
const int MAX_BUILDING_PER_TURN = 1;
|
const int MAX_BUILDING_PER_TURN = 1;
|
||||||
const int SPELL_LEVELS = 5;
|
const int SPELL_LEVELS = 5;
|
||||||
//const int CREEP_SIZE = 4000; // neutral stacks won't grow beyon this number
|
//const int CREEP_SIZE = 4000; // neutral stacks won't grow beyond this number
|
||||||
const int CREEP_SIZE = 2000000000;
|
const int CREEP_SIZE = 2000000000;
|
||||||
const int WEEKLY_GROWTH = 10; //percent
|
const int WEEKLY_GROWTH = 10; //percent
|
||||||
const int AVAILABLE_HEROES_PER_PLAYER = 2;
|
const int AVAILABLE_HEROES_PER_PLAYER = 2;
|
||||||
const bool DWELLINGS_ACCUMULATE_CREATURES = true;
|
const bool DWELLINGS_ACCUMULATE_CREATURES = true;
|
||||||
|
const bool STACK_EXP = true;
|
||||||
|
|
||||||
const int BFIELD_WIDTH = 17;
|
const int BFIELD_WIDTH = 17;
|
||||||
const int BFIELD_HEIGHT = 11;
|
const int BFIELD_HEIGHT = 11;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
#include "../lib/VCMI_Lib.h"
|
#include "../lib/VCMI_Lib.h"
|
||||||
#include "../lib/CGameState.h"
|
#include "../lib/CGameState.h"
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
using namespace boost::assign;
|
using namespace boost::assign;
|
||||||
extern CLodHandler * bitmaph;
|
extern CLodHandler * bitmaph;
|
||||||
@ -590,6 +591,69 @@ void CCreatureHandler::loadCreatures()
|
|||||||
inp3 >> factionToTurretCreature[g];
|
inp3 >> factionToTurretCreature[g];
|
||||||
}
|
}
|
||||||
inp3.close();
|
inp3.close();
|
||||||
|
|
||||||
|
//reading creature ability names
|
||||||
|
ifs.open(DATA_DIR "/config/bonusnames.txt");
|
||||||
|
{
|
||||||
|
std::string buf2, buf3, line;
|
||||||
|
int i;
|
||||||
|
std::map<std::string,int>::const_iterator it;
|
||||||
|
getline(ifs, line); //skip 1st line
|
||||||
|
while(!ifs.eof())
|
||||||
|
{
|
||||||
|
getline(ifs, buf, '\t');
|
||||||
|
getline(ifs, buf2, '\t');
|
||||||
|
getline(ifs, buf3);
|
||||||
|
it = bonusNameMap.find(buf);
|
||||||
|
if (it != bonusNameMap.end())
|
||||||
|
stackBonuses[it->second] = std::pair<std::string, std::string>(buf2,buf3);
|
||||||
|
else
|
||||||
|
tlog2 << "Bonus " << buf << " not recognized, ingoring\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ifs.close();
|
||||||
|
|
||||||
|
if (STACK_EXP) //reading default stack experience bonuses
|
||||||
|
{
|
||||||
|
buf = bitmaph->getTextFile("CREXPBON.TXT");
|
||||||
|
int it = 0;
|
||||||
|
si32 creid = -1;
|
||||||
|
commonBonuses.resize(8); //8 tiers
|
||||||
|
stackExperience b;
|
||||||
|
b.expBonuses.resize(10);
|
||||||
|
b.source = Bonus::STACK_EXPERIENCE;
|
||||||
|
|
||||||
|
loadToIt (dump2, buf, it, 3); //ignore first line
|
||||||
|
loadToIt (dump2, buf, it, 4); //ignore index
|
||||||
|
loadStackExp(b, buf, it);
|
||||||
|
loadToIt (dump2, buf, it, 4); //crop comment
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
commonBonuses[i].push_back(new stackExperience(b));//health bonus common for all
|
||||||
|
for (int j = 0; j < 4; ++j) //four modifiers common for tiers
|
||||||
|
{
|
||||||
|
loadToIt (dump2, buf, it, 4); //ignore index
|
||||||
|
loadStackExp(b, buf, it);
|
||||||
|
commonBonuses[i].push_back(new stackExperience(b));
|
||||||
|
loadToIt (dump2, buf, it, 3); //crop comment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do //parse everything that's left
|
||||||
|
{
|
||||||
|
loadToIt(creid, buf, it, 4); //get index
|
||||||
|
loadStackExp(b, buf, it);
|
||||||
|
creatures[creid]->bonuses.push_back(new stackExperience(b)); //experience list is common for creatures of that type
|
||||||
|
loadToIt (dump2, buf, it, 3); //crop comment
|
||||||
|
} while (it < buf.size());
|
||||||
|
|
||||||
|
BOOST_FOREACH(CCreature *c, creatures)
|
||||||
|
{
|
||||||
|
if (it = c->level < 7)
|
||||||
|
std::copy(commonBonuses[it-1].begin(), commonBonuses[it-1].end(), c->bonuses.begin());
|
||||||
|
else
|
||||||
|
std::copy(commonBonuses[7].begin(), commonBonuses[7].end(), c->bonuses.begin()); //common for tiers 8+
|
||||||
|
}
|
||||||
|
} //end of stack experience
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreatureHandler::loadAnimationInfo()
|
void CCreatureHandler::loadAnimationInfo()
|
||||||
@ -662,6 +726,40 @@ void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int
|
|||||||
i+=2;
|
i+=2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCreatureHandler::loadStackExp(stackExperience & b, std::string & src, int & it) //help function for parsing CREXPBON.txt, assuming all its details are already defined
|
||||||
|
{
|
||||||
|
std::string buf, mod;
|
||||||
|
loadToIt(buf, src, it, 4);
|
||||||
|
loadToIt(mod, src, it, 4);
|
||||||
|
switch (buf[0])
|
||||||
|
{
|
||||||
|
case 'H':
|
||||||
|
b.type = Bonus::STACK_HEALTH;
|
||||||
|
break;
|
||||||
|
case 'A':
|
||||||
|
b.type = Bonus::PRIMARY_SKILL;
|
||||||
|
b.subtype = PrimarySkill::ATTACK;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
b.type = Bonus::PRIMARY_SKILL;
|
||||||
|
b.subtype = PrimarySkill::DEFENSE;
|
||||||
|
break;
|
||||||
|
case 'M': //Max damage
|
||||||
|
b.type = Bonus::CREATURE_DAMAGE;
|
||||||
|
b.subtype = 2;
|
||||||
|
break;
|
||||||
|
case 'm': //Min damage
|
||||||
|
b.type = Bonus::CREATURE_DAMAGE;
|
||||||
|
b.subtype = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
loadToIt (b.val, src, it, 4); //basic value, not particularly useful but existent
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
loadToIt (b.expBonuses[i], src, it, 4); //vector must have length 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CCreatureHandler::~CCreatureHandler()
|
CCreatureHandler::~CCreatureHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -113,9 +113,13 @@ public:
|
|||||||
std::vector<si8> factionAlignments; //1 for good, 0 for neutral and -1 for evil with faction ID as index
|
std::vector<si8> factionAlignments; //1 for good, 0 for neutral and -1 for evil with faction ID as index
|
||||||
int factionToTurretCreature[F_NUMBER]; //which creature's animation should be used to dispaly creature in turret while siege
|
int factionToTurretCreature[F_NUMBER]; //which creature's animation should be used to dispaly creature in turret while siege
|
||||||
|
|
||||||
|
std::map<TBonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description
|
||||||
|
std::vector<BonusList> commonBonuses; // levels 1-8 from CREXPBON.txt
|
||||||
|
|
||||||
void loadCreatures();
|
void loadCreatures();
|
||||||
void loadAnimationInfo();
|
void loadAnimationInfo();
|
||||||
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
|
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
|
||||||
|
void loadStackExp(stackExperience & b, std::string & src, int & it);
|
||||||
|
|
||||||
bool isGood (si8 faction) const;
|
bool isGood (si8 faction) const;
|
||||||
bool isEvil (si8 faction) const;
|
bool isEvil (si8 faction) const;
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
#include "CGameState.h"
|
#include "CGameState.h"
|
||||||
#include "CGeneralTextHandler.h"
|
#include "CGeneralTextHandler.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include "CSpellHandler.h"
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
|
||||||
const CStackInstance &CCreatureSet::operator[](TSlot slot) const
|
const CStackInstance &CCreatureSet::operator[](TSlot slot) const
|
||||||
{
|
{
|
||||||
@ -441,6 +444,100 @@ void CStackInstance::setType(const CCreature *c)
|
|||||||
|
|
||||||
attachTo(const_cast<CCreature*>(type));
|
attachTo(const_cast<CCreature*>(type));
|
||||||
}
|
}
|
||||||
|
std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
|
||||||
|
{
|
||||||
|
std::map<TBonusType, std::pair<std::string, std::string>>::iterator it = VLC->creh->stackBonuses.find(bonus->type);
|
||||||
|
if (it != VLC->creh->stackBonuses.end())
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
if (description) //long ability description
|
||||||
|
{
|
||||||
|
text = it->second.second;
|
||||||
|
switch (bonus->type)
|
||||||
|
{
|
||||||
|
//no additional modifiers needed
|
||||||
|
case Bonus::FLYING:
|
||||||
|
case Bonus::UNLIMITED_RETALIATIONS:
|
||||||
|
case Bonus::SHOOTER:
|
||||||
|
case Bonus::FREE_SHOOTING:
|
||||||
|
case Bonus::NO_SHOTING_PENALTY:
|
||||||
|
case Bonus::NO_MELEE_PENALTY:
|
||||||
|
case Bonus::NO_DISTANCE_PENALTY:
|
||||||
|
case Bonus::NO_OBSTACLES_PENALTY:
|
||||||
|
case Bonus::JOUSTING: //TODO: percent bonus?
|
||||||
|
case Bonus::RETURN_AFTER_STRIKE:
|
||||||
|
case Bonus::BLOCKS_RETALIATION:
|
||||||
|
case Bonus::TWO_HEX_ATTACK_BREATH:
|
||||||
|
case Bonus::THREE_HEADED_ATTACK:
|
||||||
|
case Bonus::ATTACKS_ALL_ADJACENT:
|
||||||
|
case Bonus::FULL_HP_REGENERATION:
|
||||||
|
case Bonus::LIFE_DRAIN: //TODO: chance, hp percentage?
|
||||||
|
case Bonus::SELF_MORALE:
|
||||||
|
case Bonus::SELF_LUCK:
|
||||||
|
case Bonus::FEAR:
|
||||||
|
case Bonus::FEARLESS:
|
||||||
|
case Bonus::CHARGE_IMMUNITY:
|
||||||
|
case Bonus::HEALER:
|
||||||
|
case Bonus::CATAPULT:
|
||||||
|
case Bonus::DRAGON_NATURE:
|
||||||
|
case Bonus::NON_LIVING:
|
||||||
|
case Bonus::UNDEAD:
|
||||||
|
break;
|
||||||
|
//One numeric value
|
||||||
|
//case Bonus::STACKS_SPEED: //Do we need description for creature stats?
|
||||||
|
//case Bonus::STACK_HEALTH:
|
||||||
|
case Bonus::MAGIC_RESISTANCE:
|
||||||
|
case Bonus::SPELL_DAMAGE_REDUCTION:
|
||||||
|
case Bonus::LEVEL_SPELL_IMMUNITY:
|
||||||
|
case Bonus::CHANGES_SPELL_COST_FOR_ALLY:
|
||||||
|
case Bonus::CHANGES_SPELL_COST_FOR_ENEMY:
|
||||||
|
case Bonus::MANA_CHANNELING:
|
||||||
|
case Bonus::MANA_DRAIN:
|
||||||
|
case Bonus::HP_REGENERATION:
|
||||||
|
case Bonus::ADDITIONAL_RETALIATION:
|
||||||
|
case Bonus::DOUBLE_DAMAGE_CHANCE:
|
||||||
|
case Bonus::ENEMY_DEFENCE_REDUCTION:
|
||||||
|
case Bonus::MAGIC_MIRROR:
|
||||||
|
case Bonus::DARKNESS: //Darkness Dragons any1?
|
||||||
|
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val));
|
||||||
|
break;
|
||||||
|
//Complex descriptions
|
||||||
|
case Bonus::HATE: //TODO: customize damage percent
|
||||||
|
boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl);
|
||||||
|
break;
|
||||||
|
case Bonus::SPELL_IMMUNITY:
|
||||||
|
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
|
||||||
|
break;
|
||||||
|
case Bonus::SPELL_AFTER_ATTACK:
|
||||||
|
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->additionalInfo % 100));
|
||||||
|
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{}//TODO: allow custom bonus types... someday, somehow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //short name
|
||||||
|
{
|
||||||
|
text = it->second.first;
|
||||||
|
switch (bonus->type)
|
||||||
|
{
|
||||||
|
case Bonus::HATE:
|
||||||
|
boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl);
|
||||||
|
break;
|
||||||
|
case Bonus::LEVEL_SPELL_IMMUNITY:
|
||||||
|
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val));
|
||||||
|
break;
|
||||||
|
case Bonus::SPELL_IMMUNITY:
|
||||||
|
case Bonus::SPELL_AFTER_ATTACK:
|
||||||
|
boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
void CStackInstance::setArmyObj(const CArmedInstance *ArmyObj)
|
void CStackInstance::setArmyObj(const CArmedInstance *ArmyObj)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,7 @@ public:
|
|||||||
|
|
||||||
//overrides CBonusSystemNode
|
//overrides CBonusSystemNode
|
||||||
//void getParents(TCNodes &out, const CBonusSystemNode *source = NULL) const; //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
|
//void getParents(TCNodes &out, const CBonusSystemNode *source = NULL) const; //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
|
||||||
|
std::string bonusToString(Bonus *bonus, bool description) const; // how would bonus description look for this particular type of node
|
||||||
|
|
||||||
int getQuantityID() const;
|
int getQuantityID() const;
|
||||||
std::string getQuantityTXT(bool capitalized = true) const;
|
std::string getQuantityTXT(bool capitalized = true) const;
|
||||||
|
@ -16,10 +16,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
typedef ui8 TBonusType;
|
|
||||||
typedef si32 TBonusSubtype;
|
|
||||||
|
|
||||||
class CCreature;
|
class CCreature;
|
||||||
class CSpell;
|
class CSpell;
|
||||||
struct Bonus;
|
struct Bonus;
|
||||||
@ -159,7 +155,7 @@ namespace PrimarySkill
|
|||||||
BONUS_NAME(MAXED_SPELL) /*val = id*/\
|
BONUS_NAME(MAXED_SPELL) /*val = id*/\
|
||||||
BONUS_NAME(SPECIAL_PECULIAR_ENCHANT) /*blesses and curses with id = val dependent on unit's level, subtype = 0 or 1 for Coronius*/\
|
BONUS_NAME(SPECIAL_PECULIAR_ENCHANT) /*blesses and curses with id = val dependent on unit's level, subtype = 0 or 1 for Coronius*/\
|
||||||
BONUS_NAME(SPECIAL_UPGRADE) /*val = base, additionalInfo = target */\
|
BONUS_NAME(SPECIAL_UPGRADE) /*val = base, additionalInfo = target */\
|
||||||
BONUS_NAME(DRAGON_NATURE) /*TODO: implement it!*/\
|
BONUS_NAME(DRAGON_NATURE) \
|
||||||
BONUS_NAME(CREATURE_DAMAGE)/*subtype 0 = both, 1 = min, 2 = max*/
|
BONUS_NAME(CREATURE_DAMAGE)/*subtype 0 = both, 1 = min, 2 = max*/
|
||||||
|
|
||||||
struct DLL_EXPORT Bonus
|
struct DLL_EXPORT Bonus
|
||||||
@ -198,6 +194,7 @@ struct DLL_EXPORT Bonus
|
|||||||
ARMY,
|
ARMY,
|
||||||
CAMPAIGN_BONUS,
|
CAMPAIGN_BONUS,
|
||||||
SPECIAL_WEEK,
|
SPECIAL_WEEK,
|
||||||
|
STACK_EXPERIENCE,
|
||||||
OTHER /*used for defensive stance*/
|
OTHER /*used for defensive stance*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -309,7 +306,7 @@ struct DLL_EXPORT Bonus
|
|||||||
|
|
||||||
struct DLL_EXPORT stackExperience : public Bonus
|
struct DLL_EXPORT stackExperience : public Bonus
|
||||||
{
|
{
|
||||||
std::vector<ui32> expBonuses; // variations for levels 1-10, copied to val field;
|
std::vector<si32> expBonuses; // variations for levels 1-10, copied to val field;
|
||||||
bool enable; //if true - turns ability on / off for zero value
|
bool enable; //if true - turns ability on / off for zero value
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
@ -382,6 +379,7 @@ public:
|
|||||||
void getParents(TCNodes &out) const; //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
|
void getParents(TCNodes &out) const; //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
|
||||||
void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
|
void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
|
||||||
|
|
||||||
|
virtual std::string bonusToString(Bonus *bonus, bool description) const {return "";}; //description or bonus name
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
//interface
|
//interface
|
||||||
|
Loading…
Reference in New Issue
Block a user