]> git.tdb.fi Git - poefilter.git/blob - source/rangecondition.h
811a1aa48ffba85371d04249ef0ce0eef0f4cb36
[poefilter.git] / source / rangecondition.h
1 #ifndef RANGECONDITION_H_
2 #define RANGECONDITION_H_
3
4 #include "condition.h"
5 #include "filter.h"
6
7 template<typename T>
8 class RangeCondition: public Condition
9 {
10 public:
11         typedef T Traits;
12         typedef typename Traits::Type Type;
13
14 protected:
15         Type min;
16         Type max;
17
18 public:
19         RangeCondition(Type);
20         RangeCondition(Type, Type);
21
22         virtual RangeCondition<T> *clone() const;
23         virtual bool equals(const Condition &) const;
24         virtual bool can_merge(const Condition &, const CompoundCondition &) const;
25         virtual RangeCondition<T> *merge(const std::vector<const Condition *> &, const CompoundCondition &) const;
26         virtual bool is_viable() const { return min<=max; }
27         virtual void add_lines(std::list<FilterStatement> &) const;
28 };
29
30
31 struct RarityTraits
32 {
33         typedef Rarity Type;
34         static Rarity get_min() { return NORMAL; }
35         static Rarity get_max() { return UNIQUE; }
36         static const char *get_keyword() { return "Rarity"; }
37 };
38
39 typedef RangeCondition<RarityTraits> RarityCondition;
40
41
42 struct QualityTraits
43 {
44         typedef unsigned Type;
45         static unsigned get_min() { return 0; }
46         static unsigned get_max() { return 20; }
47         static const char *get_keyword() { return "Quality"; }
48 };
49
50 typedef RangeCondition<QualityTraits> QualityCondition;
51
52
53 struct ItemLevelTraits
54 {
55         typedef unsigned Type;
56         static unsigned get_min() { return 1; }
57         static unsigned get_max() { return 100; }
58         static const char *get_keyword() { return "ItemLevel"; }
59 };
60
61 typedef RangeCondition<ItemLevelTraits> ItemLevelCondition;
62
63
64 struct DropLevelTraits
65 {
66         typedef unsigned Type;
67         static unsigned get_min() { return 1; }
68         static unsigned get_max() { return 100; }
69         static const char *get_keyword() { return "DropLevel"; }
70 };
71
72 typedef RangeCondition<DropLevelTraits> DropLevelCondition;
73
74
75 struct WidthTraits
76 {
77         typedef unsigned Type;
78         static unsigned get_min() { return 1; }
79         static unsigned get_max() { return 2; }
80         static const char *get_keyword() { return "Width"; }
81 };
82
83 typedef RangeCondition<WidthTraits> WidthCondition;
84
85
86 struct HeightTraits
87 {
88         typedef unsigned Type;
89         static unsigned get_min() { return 1; }
90         static unsigned get_max() { return 4; }
91         static const char *get_keyword() { return "Height"; }
92 };
93
94 typedef RangeCondition<HeightTraits> HeightCondition;
95
96
97 struct SocketsTraits
98 {
99         typedef unsigned Type;
100         static unsigned get_min() { return 1; }
101         static unsigned get_max() { return 6; }
102         static const char *get_keyword() { return "Sockets"; }
103 };
104
105 typedef RangeCondition<SocketsTraits> SocketsCondition;
106
107
108 struct LinkedSocketsTraits
109 {
110         typedef unsigned Type;
111         static unsigned get_min() { return 1; }
112         static unsigned get_max() { return 6; }
113         static const char *get_keyword() { return "LinkedSockets"; }
114 };
115
116 typedef RangeCondition<LinkedSocketsTraits> LinkedSocketsCondition;
117
118
119 template<typename T>
120 RangeCondition<T>::RangeCondition(Type v):
121         min(v),
122         max(v)
123 { }
124
125 template<typename T>
126 RangeCondition<T>::RangeCondition(Type n, Type x):
127         min(n),
128         max(x)
129 { }
130
131 template<typename T>
132 RangeCondition<T> *RangeCondition<T>::clone() const
133 {
134         return new RangeCondition<T>(min, max);
135 }
136
137 template<typename T>
138 bool RangeCondition<T>::equals(const Condition &other) const
139 {
140         const RangeCondition<T> *other_range = dynamic_cast<const RangeCondition<T> *>(&other);
141         if(!other_range)
142                 return false;
143
144         return (min==other_range->min && max==other_range->max);
145 }
146
147 template<typename T>
148 bool RangeCondition<T>::can_merge(const Condition &other, const CompoundCondition &parent) const
149 {
150         const RangeCondition<T> *other_range = dynamic_cast<const RangeCondition<T> *>(&other);
151         if(!other_range)
152                 return false;
153
154         if(dynamic_cast<const AndCondition *>(&parent))
155                 return true;
156         else if(dynamic_cast<const OrCondition *>(&parent))
157                 return min<=other_range->max+1 && max+1>=other_range->min;
158         else
159                 return false;
160 }
161
162 template<typename T>
163 RangeCondition<T> *RangeCondition<T>::merge(const std::vector<const Condition *> &conditions, const CompoundCondition &parent) const
164 {
165         if(conditions.empty())
166                 return 0;
167
168         bool intersect = dynamic_cast<const AndCondition *>(&parent);
169         RangeCondition<T> *result;
170         if(intersect)
171                 result = new RangeCondition<T>(Traits::get_min(), Traits::get_max());
172         else
173                 result = new RangeCondition<T>(Traits::get_max(), Traits::get_min());
174         for(std::vector<const Condition *>::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)
175         {
176                 const RangeCondition<T> *c = static_cast<const RangeCondition<T> *>(*i);
177                 if(intersect)
178                 {
179                         result->min = std::max(result->min, c->min);
180                         result->max = std::min(result->max, c->max);
181                 }
182                 else
183                 {
184                         result->min = std::min(result->min, c->min);
185                         result->max = std::max(result->max, c->max);
186                 }
187         }
188         return result;
189 }
190
191 template<typename T>
192 void RangeCondition<T>::add_lines(std::list<FilterStatement> &st) const
193 {
194         const char *keyword = Traits::get_keyword();
195         if(min==max)
196                 FilterStatement::add_line(st, Msp::format("%s %s", keyword, min));
197         else
198         {
199                 if(min!=Traits::get_min())
200                         FilterStatement::add_line(st, Msp::format("%s >= %s", keyword, min));
201                 if(max!=Traits::get_max())
202                         FilterStatement::add_line(st, Msp::format("%s <= %s", keyword, max));
203         }
204 }
205
206 #endif