mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +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::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)
|
||||
|
@ -11,7 +11,7 @@ public:
|
||||
void yourTurn();
|
||||
void heroKilled(const CGHeroInstance *);
|
||||
void heroCreated(const CGHeroInstance *);
|
||||
void heroMoved(const HeroMoveDetails &);
|
||||
void heroMoved(const TryMoveHero&);
|
||||
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) {};
|
||||
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID){};
|
||||
void tileRevealed(int3 pos){};
|
||||
|
@ -14,9 +14,9 @@
|
||||
|
||||
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::set<std::pair<cond, input*>>::iterator ic;
|
||||
std::vector<std::pair<cond, input*>>::iterator ic;
|
||||
bool factWasAdded = false; //carry it over inner loop
|
||||
switch (type)
|
||||
{
|
||||
@ -72,7 +72,7 @@ template <typename ruleType, typename facts> template <typename cond> void Exper
|
||||
}
|
||||
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)
|
||||
{ //compare fact with condition
|
||||
@ -109,18 +109,31 @@ void BonusRule::fireRule()
|
||||
}
|
||||
//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)
|
||||
//{
|
||||
// cons.clear();
|
||||
// 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
|
||||
//}
|
||||
//template <typename input, typename conType> void Rule<input, conType>::refreshRule()
|
||||
//{
|
||||
// for (std::set<std::pair<conType, input*>>::iterator it = cons.begin(); it != cons.end(); it++)
|
||||
// *it->second = NULL;
|
||||
//}
|
||||
|
||||
TLogic operator&&(const TLogic &first, const TLogic &second)
|
||||
{
|
||||
return LogicConjunction(first, second);
|
||||
}
|
||||
TLogic operator||(const TLogic &first, const TLogic &second)
|
||||
{
|
||||
return LogicAlternative(first, second);
|
||||
}
|
||||
template <typename input, typename conType> void Rule<input, conType>::refreshRule(std::vector<conType> &conditionSet)
|
||||
{//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)
|
||||
{
|
||||
if (object(fact)) //Bonus(fact) matches local Selector(object)
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "../vcmi/CCallback.h"
|
||||
#include "../vcmi/lib/HeroBonus.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
* ExpertSystem.h, part of VCMI engine
|
||||
@ -17,21 +17,22 @@ struct Bonus;
|
||||
template <typename fact> class AIholder;
|
||||
template <typename input, typename output> class Rule;
|
||||
typedef Rule<Bonus, Bonus> BRule;
|
||||
typedef boost::function<bool(int, si32)> TLogic;
|
||||
bool greaterThan (int prop, si32 val);
|
||||
|
||||
enum conditionType {LESS_THAN, EQUAL, GREATER_THAN, UNEQUAL, PRESENT};
|
||||
|
||||
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:
|
||||
ICallback* m_cb;
|
||||
protected:
|
||||
std::set<ruleType> knowledge;
|
||||
std::set<ruleType*> rulesToErase;
|
||||
std::set<ruleType*> rulesToAdd;
|
||||
std::set<fact*> factsToErase;
|
||||
std::set<fact*> factsToAdd;
|
||||
std::vector<ruleType> knowledge;
|
||||
std::vector<ruleType*> rulesToErase;
|
||||
std::vector<ruleType*> rulesToAdd;
|
||||
std::vector<fact*> factsToErase;
|
||||
std::vector<fact*> factsToAdd;
|
||||
ui16 goalCounter; //count / evaluate achieved goals for runType
|
||||
public:
|
||||
ExpertSystemShell(){goalCounter = 0;};
|
||||
@ -53,12 +54,12 @@ public:
|
||||
};
|
||||
|
||||
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:
|
||||
input object; //what the fact is, or what it's like (CSelector)
|
||||
si32 value;
|
||||
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;};
|
||||
|
||||
@ -72,16 +73,16 @@ public:
|
||||
bool fired; //if conditions of rule were met and it produces some output
|
||||
ui8 conditionCounter;
|
||||
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;
|
||||
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(std::set<input*> &feed);
|
||||
virtual bool checkCondition(std::vector<input*> &feed);
|
||||
virtual void fireRule(); //use paired conditions and facts by default
|
||||
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(std::set<conType> &conditionSet); //in case conditions were erased
|
||||
virtual void refreshRule(std::vector<conType> &conditionSet); //in case conditions were erased
|
||||
public:
|
||||
Rule(){fired = false; conditionCounter = 0; decision = NULL;};
|
||||
template <typename givenInput> bool matchesInput() //if condition and data match type
|
||||
@ -142,7 +143,7 @@ protected:
|
||||
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)
|
||||
return true;
|
||||
@ -172,6 +173,36 @@ inline bool present (int prop, si32 val=0)
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
srcfile.erase(srcfile.find_last_of('.'));
|
||||
if (caseSens)
|
||||
{
|
||||
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 ui16 spelltype;
|
||||
typedef std::pair<ui32, ui32> TDmgRange;
|
||||
|
||||
typedef ui8 TBonusType;
|
||||
typedef si32 TBonusSubtype;
|
||||
#include "int3.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
@ -117,11 +118,12 @@ const int NAMES_PER_TOWN=16;
|
||||
const int CREATURES_PER_TOWN = 7; //without upgrades
|
||||
const int MAX_BUILDING_PER_TURN = 1;
|
||||
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 WEEKLY_GROWTH = 10; //percent
|
||||
const int AVAILABLE_HEROES_PER_PLAYER = 2;
|
||||
const bool DWELLINGS_ACCUMULATE_CREATURES = true;
|
||||
const bool STACK_EXP = true;
|
||||
|
||||
const int BFIELD_WIDTH = 17;
|
||||
const int BFIELD_HEIGHT = 11;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../lib/CGameState.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace boost::assign;
|
||||
extern CLodHandler * bitmaph;
|
||||
@ -590,6 +591,69 @@ void CCreatureHandler::loadCreatures()
|
||||
inp3 >> factionToTurretCreature[g];
|
||||
}
|
||||
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()
|
||||
@ -662,6 +726,40 @@ void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
@ -113,9 +113,13 @@ public:
|
||||
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
|
||||
|
||||
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 loadAnimationInfo();
|
||||
void loadUnitAnimInfo(CCreature & unit, std::string & src, int & i);
|
||||
void loadStackExp(stackExperience & b, std::string & src, int & it);
|
||||
|
||||
bool isGood (si8 faction) const;
|
||||
bool isEvil (si8 faction) const;
|
||||
|
@ -8,6 +8,9 @@
|
||||
#include "CGameState.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include <sstream>
|
||||
#include "CSpellHandler.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
const CStackInstance &CCreatureSet::operator[](TSlot slot) const
|
||||
{
|
||||
@ -441,6 +444,100 @@ void CStackInstance::setType(const CCreature *c)
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
|
||||
//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
|
||||
std::string bonusToString(Bonus *bonus, bool description) const; // how would bonus description look for this particular type of node
|
||||
|
||||
int getQuantityID() const;
|
||||
std::string getQuantityTXT(bool capitalized = true) const;
|
||||
|
@ -16,10 +16,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
typedef ui8 TBonusType;
|
||||
typedef si32 TBonusSubtype;
|
||||
|
||||
class CCreature;
|
||||
class CSpell;
|
||||
struct Bonus;
|
||||
@ -159,7 +155,7 @@ namespace PrimarySkill
|
||||
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_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*/
|
||||
|
||||
struct DLL_EXPORT Bonus
|
||||
@ -198,6 +194,7 @@ struct DLL_EXPORT Bonus
|
||||
ARMY,
|
||||
CAMPAIGN_BONUS,
|
||||
SPECIAL_WEEK,
|
||||
STACK_EXPERIENCE,
|
||||
OTHER /*used for defensive stance*/
|
||||
};
|
||||
|
||||
@ -309,7 +306,7 @@ struct DLL_EXPORT 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
|
||||
|
||||
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 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
|
||||
|
Loading…
Reference in New Issue
Block a user