1 #ifndef CSM_WORLD_INFOSELECTWRAPPER_H
2 #define CSM_WORLD_INFOSELECTWRAPPER_H
3 
4 #include <components/esm/loadinfo.hpp>
5 
6 namespace CSMWorld
7 {
8     // ESM::DialInfo::SelectStruct.mSelectRule
9     // 012345...
10     // ^^^ ^^
11     // ||| ||
12     // ||| |+------------- condition variable string
13     // ||| +-------------- comparison type, ['0'..'5']; e.g. !=, <, >=, etc
14     // ||+---------------- function index (encoded, where function == '1')
15     // |+----------------- function, ['1'..'C']; e.g. Global, Local, Not ID, etc
16     // +------------------ unknown
17     //
18 
19     // Wrapper for DialInfo::SelectStruct
20     class ConstInfoSelectWrapper
21     {
22     public:
23 
24         // Order matters
25         enum FunctionName
26         {
27             Function_RankLow=0,
28             Function_RankHigh,
29             Function_RankRequirement,
30             Function_Reputation,
31             Function_Health_Percent,
32             Function_PcReputation,
33             Function_PcLevel,
34             Function_PcHealthPercent,
35             Function_PcMagicka,
36             Function_PcFatigue,
37             Function_PcStrength,
38             Function_PcBlock,
39             Function_PcArmorer,
40             Function_PcMediumArmor,
41             Function_PcHeavyArmor,
42             Function_PcBluntWeapon,
43             Function_PcLongBlade,
44             Function_PcAxe,
45             Function_PcSpear,
46             Function_PcAthletics,
47             Function_PcEnchant,
48             Function_PcDestruction,
49             Function_PcAlteration,
50             Function_PcIllusion,
51             Function_PcConjuration,
52             Function_PcMysticism,
53             Function_PcRestoration,
54             Function_PcAlchemy,
55             Function_PcUnarmored,
56             Function_PcSecurity,
57             Function_PcSneak,
58             Function_PcAcrobatics,
59             Function_PcLightArmor,
60             Function_PcShortBlade,
61             Function_PcMarksman,
62             Function_PcMerchantile,
63             Function_PcSpeechcraft,
64             Function_PcHandToHand,
65             Function_PcGender,
66             Function_PcExpelled,
67             Function_PcCommonDisease,
68             Function_PcBlightDisease,
69             Function_PcClothingModifier,
70             Function_PcCrimeLevel,
71             Function_SameSex,
72             Function_SameRace,
73             Function_SameFaction,
74             Function_FactionRankDifference,
75             Function_Detected,
76             Function_Alarmed,
77             Function_Choice,
78             Function_PcIntelligence,
79             Function_PcWillpower,
80             Function_PcAgility,
81             Function_PcSpeed,
82             Function_PcEndurance,
83             Function_PcPersonality,
84             Function_PcLuck,
85             Function_PcCorpus,
86             Function_Weather,
87             Function_PcVampire,
88             Function_Level,
89             Function_Attacked,
90             Function_TalkedToPc,
91             Function_PcHealth,
92             Function_CreatureTarget,
93             Function_FriendHit,
94             Function_Fight,
95             Function_Hello,
96             Function_Alarm,
97             Function_Flee,
98             Function_ShouldAttack,
99             Function_Werewolf,
100             Function_PcWerewolfKills=73,
101 
102             Function_Global,
103             Function_Local,
104             Function_Journal,
105             Function_Item,
106             Function_Dead,
107             Function_NotId,
108             Function_NotFaction,
109             Function_NotClass,
110             Function_NotRace,
111             Function_NotCell,
112             Function_NotLocal,
113 
114             Function_None
115         };
116 
117         enum RelationType
118         {
119             Relation_Equal,
120             Relation_NotEqual,
121             Relation_Greater,
122             Relation_GreaterOrEqual,
123             Relation_Less,
124             Relation_LessOrEqual,
125 
126             Relation_None
127         };
128 
129         enum ComparisonType
130         {
131             Comparison_Boolean,
132             Comparison_Integer,
133             Comparison_Numeric,
134 
135             Comparison_None
136         };
137 
138         static const size_t RuleMinSize;
139 
140         static const size_t FunctionPrefixOffset;
141         static const size_t FunctionIndexOffset;
142         static const size_t RelationIndexOffset;
143         static const size_t VarNameOffset;
144 
145         static const char* FunctionEnumStrings[];
146         static const char* RelationEnumStrings[];
147         static const char* ComparisonEnumStrings[];
148 
149         static std::string convertToString(FunctionName name);
150         static std::string convertToString(RelationType type);
151         static std::string convertToString(ComparisonType type);
152 
153         ConstInfoSelectWrapper(const ESM::DialInfo::SelectStruct& select);
154 
155         FunctionName getFunctionName() const;
156         RelationType getRelationType() const;
157         ComparisonType getComparisonType() const;
158 
159         bool hasVariable() const;
160         const std::string& getVariableName() const;
161 
162         bool conditionIsAlwaysTrue() const;
163         bool conditionIsNeverTrue() const;
164         bool variantTypeIsValid() const;
165 
166         const ESM::Variant& getVariant() const;
167 
168         std::string toString() const;
169 
170     protected:
171 
172         void readRule();
173         void readFunctionName();
174         void readRelationType();
175         void readVariableName();
176         void updateHasVariable();
177         void updateComparisonType();
178 
179         std::pair<int, int> getConditionIntRange() const;
180         std::pair<float, float> getConditionFloatRange() const;
181 
182         std::pair<int, int> getValidIntRange() const;
183         std::pair<float, float> getValidFloatRange() const;
184 
185         template <typename Type1, typename Type2>
186         bool rangeContains(Type1 value, std::pair<Type2,Type2> range) const;
187 
188         template <typename Type1, typename Type2>
189         bool rangesOverlap(std::pair<Type1,Type1> range1, std::pair<Type2,Type2> range2) const;
190 
191         template <typename Type1, typename Type2>
192         bool rangeFullyContains(std::pair<Type1,Type1> containing, std::pair<Type2,Type2> test) const;
193 
194         template <typename Type1, typename Type2>
195         bool rangesMatch(std::pair<Type1,Type1> range1, std::pair<Type2,Type2> range2) const;
196 
197         template <typename Type1, typename Type2>
198         bool conditionIsAlwaysTrue(std::pair<Type1,Type1> conditionRange, std::pair<Type2,Type2> validRange) const;
199 
200         template <typename Type1, typename Type2>
201         bool conditionIsNeverTrue(std::pair<Type1,Type1> conditionRange, std::pair<Type2,Type2> validRange) const;
202 
203         FunctionName mFunctionName;
204         RelationType mRelationType;
205         ComparisonType mComparisonType;
206 
207         bool mHasVariable;
208         std::string mVariableName;
209 
210     private:
211 
212         const ESM::DialInfo::SelectStruct& mConstSelect;
213     };
214 
215     // Wrapper for DialInfo::SelectStruct that can modify the wrapped select struct
216     class InfoSelectWrapper : public ConstInfoSelectWrapper
217     {
218     public:
219 
220         InfoSelectWrapper(ESM::DialInfo::SelectStruct& select);
221 
222         // Wrapped SelectStruct will not be modified until update() is called
223         void setFunctionName(FunctionName name);
224         void setRelationType(RelationType type);
225         void setVariableName(const std::string& name);
226 
227         // Modified wrapped SelectStruct
228         void update();
229 
230         // This sets properties based on the function name to its defaults and updates the wrapped object
231         void setDefaults();
232 
233         ESM::Variant& getVariant();
234 
235     private:
236 
237         ESM::DialInfo::SelectStruct& mSelect;
238 
239         void writeRule();
240     };
241 }
242 
243 #endif
244