|
@@ -10,10 +10,11 @@
|
|
|
|
|
|
#pragma once
|
|
#pragma once
|
|
|
|
|
|
|
|
+#include "GameConstants.h"
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
|
-typedef si32 TResource;
|
|
|
|
-typedef si64 TResourceCap; //to avoid overflow when adding integers. Signed values are easier to control.
|
|
|
|
|
|
+using TResource = int32_t;
|
|
|
|
+using TResourceCap = int64_t; //to avoid overflow when adding integers. Signed values are easier to control.
|
|
|
|
|
|
class JsonNode;
|
|
class JsonNode;
|
|
class JsonSerializeFormat;
|
|
class JsonSerializeFormat;
|
|
@@ -32,76 +33,136 @@ namespace Res
|
|
};
|
|
};
|
|
|
|
|
|
//class to be representing a vector of resource
|
|
//class to be representing a vector of resource
|
|
- class ResourceSet : public std::vector<int>
|
|
|
|
|
|
+ class ResourceSet
|
|
{
|
|
{
|
|
|
|
+ private:
|
|
|
|
+ std::array<int, GameConstants::RESOURCE_QUANTITY> container;
|
|
public:
|
|
public:
|
|
- DLL_LINKAGE ResourceSet();
|
|
|
|
// read resources set from json. Format example: { "gold": 500, "wood":5 }
|
|
// read resources set from json. Format example: { "gold": 500, "wood":5 }
|
|
DLL_LINKAGE ResourceSet(const JsonNode & node);
|
|
DLL_LINKAGE ResourceSet(const JsonNode & node);
|
|
- DLL_LINKAGE ResourceSet(TResource wood, TResource mercury, TResource ore, TResource sulfur, TResource crystal,
|
|
|
|
- TResource gems, TResource gold, TResource mithril = 0);
|
|
|
|
|
|
+ DLL_LINKAGE ResourceSet(TResource wood = 0, TResource mercury = 0, TResource ore = 0, TResource sulfur = 0, TResource crystal = 0,
|
|
|
|
+ TResource gems = 0, TResource gold = 0, TResource mithril = 0);
|
|
|
|
|
|
|
|
|
|
#define scalarOperator(OPSIGN) \
|
|
#define scalarOperator(OPSIGN) \
|
|
- ResourceSet operator OPSIGN(const TResource &rhs) const \
|
|
|
|
|
|
+ ResourceSet& operator OPSIGN ## =(const TResource &rhs) \
|
|
{ \
|
|
{ \
|
|
- ResourceSet ret = *this; \
|
|
|
|
- for(int i = 0; i < (int)size(); i++) \
|
|
|
|
- ret[i] = at(i) OPSIGN rhs; \
|
|
|
|
|
|
+ for(auto i = 0; i < container.size(); i++) \
|
|
|
|
+ container.at(i) OPSIGN ## = rhs; \
|
|
\
|
|
\
|
|
- return ret; \
|
|
|
|
|
|
+ return *this; \
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
#define vectorOperator(OPSIGN) \
|
|
#define vectorOperator(OPSIGN) \
|
|
- ResourceSet operator OPSIGN(const ResourceSet &rhs) const \
|
|
|
|
|
|
+ ResourceSet& operator OPSIGN ## =(const ResourceSet &rhs) \
|
|
{ \
|
|
{ \
|
|
- ResourceSet ret = *this; \
|
|
|
|
- for(int i = 0; i < (int)size(); i++) \
|
|
|
|
- ret[i] = at(i) OPSIGN rhs[i]; \
|
|
|
|
|
|
+ for(auto i = 0; i < container.size(); i++) \
|
|
|
|
+ container.at(i) OPSIGN ## = rhs[i]; \
|
|
\
|
|
\
|
|
- return ret; \
|
|
|
|
|
|
+ return *this; \
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-#define opEqOperator(OPSIGN, RHS_TYPE) \
|
|
|
|
- ResourceSet& operator OPSIGN ## =(const RHS_TYPE &rhs) \
|
|
|
|
- { \
|
|
|
|
- return *this = *this OPSIGN rhs; \
|
|
|
|
|
|
+#define twoOperands(OPSIGN, RHS_TYPE) \
|
|
|
|
+ friend ResourceSet operator OPSIGN(ResourceSet lhs, const RHS_TYPE &rhs) \
|
|
|
|
+ { \
|
|
|
|
+ lhs OPSIGN ## = rhs; \
|
|
|
|
+ return lhs; \
|
|
}
|
|
}
|
|
|
|
|
|
scalarOperator(+)
|
|
scalarOperator(+)
|
|
scalarOperator(-)
|
|
scalarOperator(-)
|
|
scalarOperator(*)
|
|
scalarOperator(*)
|
|
scalarOperator(/)
|
|
scalarOperator(/)
|
|
- opEqOperator(+, TResource)
|
|
|
|
- opEqOperator(-, TResource)
|
|
|
|
- opEqOperator(*, TResource)
|
|
|
|
vectorOperator(+)
|
|
vectorOperator(+)
|
|
vectorOperator(-)
|
|
vectorOperator(-)
|
|
- opEqOperator(+, ResourceSet)
|
|
|
|
- opEqOperator(-, ResourceSet)
|
|
|
|
|
|
+ twoOperands(+, TResource)
|
|
|
|
+ twoOperands(-, TResource)
|
|
|
|
+ twoOperands(*, TResource)
|
|
|
|
+ twoOperands(/, TResource)
|
|
|
|
+ twoOperands(+, ResourceSet)
|
|
|
|
+ twoOperands(-, ResourceSet)
|
|
|
|
+
|
|
|
|
|
|
#undef scalarOperator
|
|
#undef scalarOperator
|
|
#undef vectorOperator
|
|
#undef vectorOperator
|
|
-#undef opEqOperator
|
|
|
|
|
|
+#undef twoOperands
|
|
|
|
+
|
|
|
|
+ using const_reference = decltype(container)::const_reference;
|
|
|
|
+ using value_type = decltype(container)::value_type;
|
|
|
|
+ using const_iterator = decltype(container)::const_iterator;
|
|
|
|
+ using iterator = decltype(container)::iterator;
|
|
|
|
+
|
|
|
|
+ // Array-like interface
|
|
|
|
+ TResource & operator[](Res::ERes index)
|
|
|
|
+ {
|
|
|
|
+ return operator[](static_cast<size_t>(index));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const TResource & operator[](Res::ERes index) const
|
|
|
|
+ {
|
|
|
|
+ return operator[](static_cast<size_t>(index));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TResource & operator[](size_t index)
|
|
|
|
+ {
|
|
|
|
+ return container[index];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const TResource & operator[](size_t index) const
|
|
|
|
+ {
|
|
|
|
+ return container[index];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bool empty () const
|
|
|
|
+ {
|
|
|
|
+ for(const auto & res : *this)
|
|
|
|
+ if(res)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // C++ range-based for support
|
|
|
|
+ auto begin () -> decltype (container.begin())
|
|
|
|
+ {
|
|
|
|
+ return container.begin();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ auto end () -> decltype (container.end())
|
|
|
|
+ {
|
|
|
|
+ return container.end();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ auto begin () const -> decltype (container.cbegin())
|
|
|
|
+ {
|
|
|
|
+ return container.cbegin();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ auto end () const -> decltype (container.cend())
|
|
|
|
+ {
|
|
|
|
+ return container.cend();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ auto size () const -> decltype (container.size())
|
|
|
|
+ {
|
|
|
|
+ return container.size();
|
|
|
|
+ }
|
|
|
|
|
|
//to be used for calculations of type "how many units of sth can I afford?"
|
|
//to be used for calculations of type "how many units of sth can I afford?"
|
|
int operator/(const ResourceSet &rhs)
|
|
int operator/(const ResourceSet &rhs)
|
|
{
|
|
{
|
|
int ret = INT_MAX;
|
|
int ret = INT_MAX;
|
|
- for(int i = 0; i < (int)size(); i++)
|
|
|
|
|
|
+ for(int i = 0; i < container.size(); i++)
|
|
if(rhs[i])
|
|
if(rhs[i])
|
|
- vstd::amin(ret, at(i) / rhs[i]);
|
|
|
|
|
|
+ vstd::amin(ret, container.at(i) / rhs[i]);
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
ResourceSet & operator=(const TResource &rhs)
|
|
ResourceSet & operator=(const TResource &rhs)
|
|
{
|
|
{
|
|
- for(int i = 0; i < (int)size(); i++)
|
|
|
|
- at(i) = rhs;
|
|
|
|
|
|
+ for(int i = 0; i < container.size(); i++)
|
|
|
|
+ container.at(i) = rhs;
|
|
|
|
|
|
return *this;
|
|
return *this;
|
|
}
|
|
}
|
|
@@ -109,11 +170,16 @@ namespace Res
|
|
ResourceSet operator-() const
|
|
ResourceSet operator-() const
|
|
{
|
|
{
|
|
ResourceSet ret;
|
|
ResourceSet ret;
|
|
- for(int i = 0; i < (int)size(); i++)
|
|
|
|
- ret[i] = -at(i);
|
|
|
|
|
|
+ for(int i = 0; i < container.size(); i++)
|
|
|
|
+ ret[i] = -container.at(i);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ bool operator==(const ResourceSet &rhs) const
|
|
|
|
+ {
|
|
|
|
+ return this->container == rhs.container;
|
|
|
|
+ }
|
|
|
|
+
|
|
// WARNING: comparison operators are used for "can afford" relation: a <= b means that foreach i a[i] <= b[i]
|
|
// WARNING: comparison operators are used for "can afford" relation: a <= b means that foreach i a[i] <= b[i]
|
|
// that doesn't work the other way: a > b doesn't mean that a cannot be afforded with b, it's still b can afford a
|
|
// that doesn't work the other way: a > b doesn't mean that a cannot be afforded with b, it's still b can afford a
|
|
// bool operator<(const ResourceSet &rhs)
|
|
// bool operator<(const ResourceSet &rhs)
|
|
@@ -127,7 +193,7 @@ namespace Res
|
|
|
|
|
|
template <typename Handler> void serialize(Handler &h, const int version)
|
|
template <typename Handler> void serialize(Handler &h, const int version)
|
|
{
|
|
{
|
|
- h & static_cast<std::vector<int>&>(*this);
|
|
|
|
|
|
+ h & container;
|
|
}
|
|
}
|
|
|
|
|
|
DLL_LINKAGE void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName);
|
|
DLL_LINKAGE void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName);
|
|
@@ -167,7 +233,7 @@ namespace Res
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
-typedef Res::ResourceSet TResources;
|
|
|
|
|
|
+using TResources = Res::ResourceSet;
|
|
|
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|
|
VCMI_LIB_NAMESPACE_END
|