diff --git a/AI/GeniusAI/ExpertSystem.cpp b/AI/GeniusAI/ExpertSystem.cpp index 76c962310..2bff9171a 100644 --- a/AI/GeniusAI/ExpertSystem.cpp +++ b/AI/GeniusAI/ExpertSystem.cpp @@ -109,6 +109,11 @@ void BonusRule::fireRule() } //TODO: add new fact or modify existing one } + +TLogic operator&&(const TLogic &first, const TLogic &second) +{ + return LogicConjunction(first, second); +} //TODO: find out why it does not compile //template void Rule::refreshRule(std::set &conditionSet) //{ diff --git a/AI/GeniusAI/ExpertSystem.h b/AI/GeniusAI/ExpertSystem.h index b58053168..8a60909a7 100644 --- a/AI/GeniusAI/ExpertSystem.h +++ b/AI/GeniusAI/ExpertSystem.h @@ -17,13 +17,14 @@ struct Bonus; template class AIholder; template class Rule; typedef Rule BRule; +typedef boost::function TLogic; bool greaterThan (int prop, si32 val); enum conditionType {LESS_THAN, EQUAL, GREATER_THAN, UNEQUAL, PRESENT}; template 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: @@ -53,12 +54,12 @@ public: }; template 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 functor; //value of selected parameter, condition value + TLogic functor; //value of selected parameter, condition value condition(){object = NULL; value = 0; parameter = 0; functor = greaterThan;}; @@ -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,21 @@ 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); //TODO: + } +}; +TLogic operator&&(const TLogic &first, const TLogic &second); + class KnowledgeHandler///I'd opt for one omniscent knowledge manager, so no templates here { public: diff --git a/config/bonusnames.txt b/config/bonusnames.txt new file mode 100644 index 000000000..00ed7150e --- /dev/null +++ b/config/bonusnames.txt @@ -0,0 +1,27 @@ +"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" diff --git a/global.h b/global.h index e4821ffb7..bfe0aebad 100644 --- a/global.h +++ b/global.h @@ -16,6 +16,8 @@ typedef boost::int16_t si16; //signed int 16 bits (2 bytes) typedef boost::int8_t si8; //signed int 8 bits (1 byte) typedef si64 expType; typedef ui16 spelltype; +typedef ui8 TBonusType; +typedef si32 TBonusSubtype; #include "int3.h" #include #include diff --git a/hch/CGeneralTextHandler.h b/hch/CGeneralTextHandler.h index e0a33b8dd..11cc19a34 100644 --- a/hch/CGeneralTextHandler.h +++ b/hch/CGeneralTextHandler.h @@ -74,6 +74,9 @@ public: std::vector > skillInfoTexts; //[id][level] : level 0 - basic; 2 - advanced std::vector levels; + //bonuses + std::map> stackBonuses; // bonus => name, description + //campaigns std::vector campaignMapNames; std::vector < std::vector > campaignRegionNames; diff --git a/hch/CSndHandler.cpp b/hch/CSndHandler.cpp index 79705fb48..1ed429368 100644 --- a/hch/CSndHandler.cpp +++ b/hch/CSndHandler.cpp @@ -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;igameState()->globalEffects); } +std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const +{ + std::map>::iterator it = VLC->generaltexth->stackBonuses.find(bonus->type); + if (it != VLC->generaltexth->stackBonuses.end()) + { + std::string text; + if (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; + } + } + else + { + text = it->second.first; + } + return text; + } + else + return ""; +} std::string CStackInstance::getQuantityTXT(bool capitalized /*= true*/) const { diff --git a/lib/CCreatureSet.h b/lib/CCreatureSet.h index be3ce8dd7..b7d3d2ec4 100644 --- a/lib/CCreatureSet.h +++ b/lib/CCreatureSet.h @@ -36,6 +36,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; diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index 1ad73148c..38f0a9b03 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -15,10 +15,6 @@ * */ - -typedef ui8 TBonusType; -typedef si32 TBonusSubtype; - class CCreature; class CSpell; struct Bonus; @@ -363,7 +359,8 @@ public: int getBonusesCount(const CSelector &selector, const CBonusSystemNode *root = NULL) const; int valOfBonuses(const CSelector &selector, const CBonusSystemNode *root = NULL) const; bool hasBonus(const CSelector &selector, const CBonusSystemNode *root = NULL) const; - void getModifiersWDescr(TModDescr &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; //out: pairs + void getModifiersWDescr(TModDescr &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; //out: pairs* + virtual std::string bonusToString(Bonus *bonus, bool description) const {return "";}; //description or bonus name ////////////////////////////////////////////////////////////////////////// //legacy interface