| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 | 
							- /*
 
-  * ResourceSet.h, part of VCMI engine
 
-  *
 
-  * Authors: listed in file AUTHORS in main folder
 
-  *
 
-  * License: GNU General Public License v2.0 or later
 
-  * Full text of license available in license.txt file, in main folder
 
-  *
 
-  */
 
- #pragma once
 
- #include "GameConstants.h"
 
- VCMI_LIB_NAMESPACE_BEGIN
 
- using TResource = int32_t;
 
- using TResourceCap = int64_t; //to avoid overflow when adding integers. Signed values are easier to control.
 
- class JsonNode;
 
- class JsonSerializeFormat;
 
- class ResourceSet;
 
- //class to be representing a vector of resource
 
- class ResourceSet
 
- {
 
- private:
 
- 	std::array<TResource, GameConstants::RESOURCE_QUANTITY> container;
 
- public:
 
- 	// read resources set from json. Format example: { "gold": 500, "wood":5 }
 
- 	DLL_LINKAGE ResourceSet(const JsonNode & node);
 
- 	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)									\
 
- 	ResourceSet& operator OPSIGN ## =(const TResource &rhs) \
 
- 	{														\
 
- 		for(auto i = 0; i < container.size(); i++)						\
 
- 			container.at(i) OPSIGN ## = rhs;						\
 
- 															\
 
- 		return *this;											\
 
- 	}
 
- #define vectorOperator(OPSIGN)										\
 
- 	ResourceSet& operator OPSIGN ## =(const ResourceSet &rhs)	\
 
- 	{															\
 
- 		for(auto i = 0; i < container.size(); i++)							\
 
- 			container.at(i) OPSIGN ## = rhs[i];						\
 
- 																\
 
- 		return *this;												\
 
- 	}
 
- #define twoOperands(OPSIGN, RHS_TYPE) \
 
- 	friend ResourceSet operator OPSIGN(ResourceSet lhs, const RHS_TYPE &rhs) \
 
- 	{ \
 
- 		lhs OPSIGN ## = rhs; \
 
- 		return lhs; \
 
- 	}
 
- 	scalarOperator(+)
 
- 	scalarOperator(-)
 
- 	scalarOperator(*)
 
- 	scalarOperator(/)
 
- 	vectorOperator(+)
 
- 	vectorOperator(-)
 
- 	twoOperands(+, TResource)
 
- 	twoOperands(-, TResource)
 
- 	twoOperands(*, TResource)
 
- 	twoOperands(/, TResource)
 
- 	twoOperands(+, ResourceSet)
 
- 	twoOperands(-, ResourceSet)
 
- #undef scalarOperator
 
- #undef vectorOperator
 
- #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[](GameResID index)
 
- 	{
 
- 		return operator[](index.getNum());
 
- 	}
 
- 	const TResource & operator[](GameResID index) const 
 
- 	{
 
- 		return operator[](index.getNum());
 
- 	}
 
- 	TResource & operator[](size_t index)
 
- 	{
 
- 		return container.at(index);
 
- 	}
 
- 	const TResource & operator[](size_t index) const 
 
- 	{
 
- 		return container.at(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?"
 
- 	int operator/(const ResourceSet &rhs)
 
- 	{
 
- 		int ret = INT_MAX;
 
- 		for(int i = 0; i < container.size(); i++)
 
- 			if(rhs[i])
 
- 				vstd::amin(ret, container.at(i) / rhs[i]);
 
- 		return ret;
 
- 	}
 
- 	ResourceSet & operator=(const TResource &rhs)
 
- 	{
 
- 		for(int & i : container)
 
- 			i = rhs;
 
- 		return *this;
 
- 	}
 
- 	ResourceSet operator-() const
 
- 	{
 
- 		ResourceSet ret;
 
- 		for(int i = 0; i < container.size(); i++)
 
- 			ret[i] = -container.at(i);
 
- 		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]
 
- // 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)
 
- // 		{
 
- // 			for(int i = 0; i < size(); i++)
 
- // 				if(at(i) >= rhs[i])
 
- // 					return false;
 
- //
 
- // 			return true;
 
- // 		}
 
- 	template <typename Handler> void serialize(Handler &h, const int version)
 
- 	{
 
- 		h & container;
 
- 	}
 
- 	DLL_LINKAGE void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName);
 
- 	DLL_LINKAGE void amax(const TResourceCap &val); //performs vstd::amax on each element
 
- 	DLL_LINKAGE void amin(const TResourceCap &val); //performs vstd::amin on each element
 
- 	DLL_LINKAGE void positive(); //values below 0 are set to 0 - upgrade cost can't be negative, for example
 
- 	DLL_LINKAGE bool nonZero() const; //returns true if at least one value is non-zero;
 
- 	DLL_LINKAGE bool canAfford(const ResourceSet &price) const;
 
- 	DLL_LINKAGE bool canBeAfforded(const ResourceSet &res) const;
 
- 	DLL_LINKAGE TResourceCap marketValue() const;
 
- 	DLL_LINKAGE std::string toString() const;
 
- 	//special iterator of iterating over non-zero resources in set
 
- 	class DLL_LINKAGE nziterator
 
- 	{
 
- 		struct ResEntry
 
- 		{
 
- 			GameResID resType;
 
- 			TResourceCap resVal;
 
- 		} cur;
 
- 		const ResourceSet &rs;
 
- 		void advance();
 
- 	public:
 
- 		nziterator(const ResourceSet &RS);
 
- 		bool valid() const;
 
- 		nziterator operator++();
 
- 		nziterator operator++(int);
 
- 		const ResEntry& operator*() const;
 
- 		const ResEntry* operator->() const;
 
- 	};
 
- };
 
- using TResources = ResourceSet;
 
- VCMI_LIB_NAMESPACE_END
 
 
  |