1
0
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:
Michał W. Urbańczyk 2011-02-06 08:32:05 +00:00
commit 31fc8f6db3
12 changed files with 325 additions and 39 deletions

View File

@ -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)

View File

@ -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){};

View File

@ -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)

View File

@ -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:

View File

@ -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
View 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

View File

@ -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;

View File

@ -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()
{ {
} }

View File

@ -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;

View File

@ -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)
{ {

View File

@ -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;

View File

@ -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