浏览代码

Merge pull request #1700 from rilian-la-te/resource-array

Modernize resourceSet.
Ivan Savenko 2 年之前
父节点
当前提交
c661419897

+ 2 - 2
AI/VCAI/BuildingManager.cpp

@@ -166,8 +166,8 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t)
 	//below algorithm focuses on economy growth at start of the game, saving money instead of build rushing is handled by Build goal
 	//below algorithm focuses on economy growth at start of the game, saving money instead of build rushing is handled by Build goal
 	//changing code blocks order will alter behavior by changing order of adding elements to immediateBuildings / expensiveBuildings
 	//changing code blocks order will alter behavior by changing order of adding elements to immediateBuildings / expensiveBuildings
 
 
-	TResources currentRes = cb->getResourceAmount();
-	TResources currentIncome = t->dailyIncome();
+	// TResources currentRes = cb->getResourceAmount();
+	// TResources currentIncome = t->dailyIncome();
 
 
 	if(tryBuildAnyStructure(t, essential))
 	if(tryBuildAnyStructure(t, essential))
 		return true;
 		return true;

+ 1 - 1
client/CPlayerInterface.cpp

@@ -1466,7 +1466,7 @@ void CPlayerInterface::showShipyardDialog(const IShipyard *obj)
 {
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	auto state = obj->shipyardStatus();
 	auto state = obj->shipyardStatus();
-	std::vector<si32> cost;
+	TResources cost;
 	obj->getBoatCost(cost);
 	obj->getBoatCost(cost);
 	GH.pushIntT<CShipyardWindow>(cost, state, obj->getBoatType(), [=](){ cb->buildBoat(obj); });
 	GH.pushIntT<CShipyardWindow>(cost, state, obj->getBoatType(), [=](){ cb->buildBoat(obj); });
 }
 }

+ 7 - 11
client/windows/GUIClasses.cpp

@@ -1079,7 +1079,7 @@ void CExchangeWindow::updateWidgets()
 	}
 	}
 }
 }
 
 
-CShipyardWindow::CShipyardWindow(const std::vector<si32> & cost, int state, int boatType, const std::function<void()> & onBuy)
+CShipyardWindow::CShipyardWindow(const TResources & cost, int state, int boatType, const std::function<void()> & onBuy)
 	: CStatusbarWindow(PLAYER_COLORED, "TPSHIP")
 	: CStatusbarWindow(PLAYER_COLORED, "TPSHIP")
 {
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
@@ -1456,15 +1456,11 @@ void CHillFortWindow::updateGarrisons()
 {
 {
 	std::array<TResources, slotsCount> costs;// costs [slot ID] [resource ID] = resource count for upgrade
 	std::array<TResources, slotsCount> costs;// costs [slot ID] [resource ID] = resource count for upgrade
 
 
-	TResources totalSumm; // totalSum[resource ID] = value
-	totalSumm.resize(GameConstants::RESOURCE_QUANTITY);
-
-	for(int i=0; i<GameConstants::RESOURCE_QUANTITY; i++)
-		totalSumm[i]=0;
+	TResources totalSum; // totalSum[resource ID] = value
 
 
 	for(int i=0; i<slotsCount; i++)
 	for(int i=0; i<slotsCount; i++)
 	{
 	{
-		costs[i].clear();
+		std::fill(costs[i].begin(), costs[i].end(), 0);
 		int newState = getState(SlotID(i));
 		int newState = getState(SlotID(i));
 		if(newState != -1)
 		if(newState != -1)
 		{
 		{
@@ -1473,7 +1469,7 @@ void CHillFortWindow::updateGarrisons()
 			if(info.newID.size())//we have upgrades here - update costs
 			if(info.newID.size())//we have upgrades here - update costs
 			{
 			{
 				costs[i] = info.cost[0] * hero->getStackCount(SlotID(i));
 				costs[i] = info.cost[0] * hero->getStackCount(SlotID(i));
-				totalSumm += costs[i];
+				totalSum += costs[i];
 			}
 			}
 		}
 		}
 
 
@@ -1495,7 +1491,7 @@ void CHillFortWindow::updateGarrisons()
 		if(allUpgraded)
 		if(allUpgraded)
 			newState = 1;
 			newState = 1;
 
 
-		if(!totalSumm.canBeAfforded(myRes))
+		if(!totalSum.canBeAfforded(myRes))
 			newState = 0;
 			newState = 0;
 	}
 	}
 
 
@@ -1543,7 +1539,7 @@ void CHillFortWindow::updateGarrisons()
 
 
 	for(int i = 0; i < resCount; i++)
 	for(int i = 0; i < resCount; i++)
 	{
 	{
-		if(totalSumm[i] == 0)
+		if(totalSum[i] == 0)
 		{
 		{
 			totalIcons[i]->visible = false;
 			totalIcons[i]->visible = false;
 			totalLabels[i]->setText("");
 			totalLabels[i]->setText("");
@@ -1551,7 +1547,7 @@ void CHillFortWindow::updateGarrisons()
 		else
 		else
 		{
 		{
 			totalIcons[i]->visible = true;
 			totalIcons[i]->visible = true;
-			totalLabels[i]->setText(std::to_string(totalSumm[i]));
+			totalLabels[i]->setText(std::to_string(totalSum[i]));
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
client/windows/GUIClasses.h

@@ -358,7 +358,7 @@ class CShipyardWindow : public CStatusbarWindow
 	std::shared_ptr<CButton> quit;
 	std::shared_ptr<CButton> quit;
 
 
 public:
 public:
-	CShipyardWindow(const std::vector<si32> & cost, int state, int boatType, const std::function<void()> & onBuy);
+	CShipyardWindow(const TResources & cost, int state, int boatType, const std::function<void()> & onBuy);
 };
 };
 
 
 /// Creature transformer window
 /// Creature transformer window

+ 2 - 1
lib/CCreatureHandler.cpp

@@ -11,6 +11,7 @@
 #include "CCreatureHandler.h"
 #include "CCreatureHandler.h"
 
 
 #include "CGeneralTextHandler.h"
 #include "CGeneralTextHandler.h"
+#include "ResourceSet.h"
 #include "filesystem/Filesystem.h"
 #include "filesystem/Filesystem.h"
 #include "VCMI_Lib.h"
 #include "VCMI_Lib.h"
 #include "CGameState.h"
 #include "CGameState.h"
@@ -267,7 +268,7 @@ bool CCreature::isEvil () const
 	return (*VLC->townh)[faction]->alignment == EAlignment::EVIL;
 	return (*VLC->townh)[faction]->alignment == EAlignment::EVIL;
 }
 }
 
 
-si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatures can be bought
+si32 CCreature::maxAmount(const TResources &res) const //how many creatures can be bought
 {
 {
 	int ret = 2147483645;
 	int ret = 2147483645;
 	int resAmnt = static_cast<int>(std::min(res.size(),cost.size()));
 	int resAmnt = static_cast<int>(std::min(res.size(),cost.size()));

+ 1 - 1
lib/CCreatureHandler.h

@@ -194,7 +194,7 @@ public:
 
 
 	bool isGood () const;
 	bool isGood () const;
 	bool isEvil () const;
 	bool isEvil () const;
-	si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought
+	si32 maxAmount(const TResources &res) const; //how many creatures can be bought
 	static CCreature::CreatureQuantityId getQuantityID(const int & quantity);
 	static CCreature::CreatureQuantityId getQuantityID(const int & quantity);
 	static std::string getQuantityRangeStringForId(const CCreature::CreatureQuantityId & quantityId);
 	static std::string getQuantityRangeStringForId(const CCreature::CreatureQuantityId & quantityId);
 	static int estimateCreatureCount(ui32 countID); //reverse version of above function, returns middle of range
 	static int estimateCreatureCount(ui32 countID); //reverse version of above function, returns middle of range

+ 11 - 20
lib/ResourceSet.cpp

@@ -9,6 +9,7 @@
  */
  */
 
 
 #include "StdInc.h"
 #include "StdInc.h"
+#include "GameConstants.h"
 #include "ResourceSet.h"
 #include "ResourceSet.h"
 #include "StringConstants.h"
 #include "StringConstants.h"
 #include "JsonNode.h"
 #include "JsonNode.h"
@@ -18,37 +19,27 @@
 
 
 VCMI_LIB_NAMESPACE_BEGIN
 VCMI_LIB_NAMESPACE_BEGIN
 
 
-Res::ResourceSet::ResourceSet()
-{
-	resize(GameConstants::RESOURCE_QUANTITY, 0);
-}
-
 Res::ResourceSet::ResourceSet(const JsonNode & node)
 Res::ResourceSet::ResourceSet(const JsonNode & node)
 {
 {
-	reserve(GameConstants::RESOURCE_QUANTITY);
-	for(const std::string & name : GameConstants::RESOURCE_NAMES)
-		push_back(static_cast<int>(node[name].Float()));
+	for(auto i = 0; i < GameConstants::RESOURCE_QUANTITY; i++)
+		this[i] = static_cast<int>(node[GameConstants::RESOURCE_NAMES[i]].Float());
 }
 }
 
 
 Res::ResourceSet::ResourceSet(TResource wood, TResource mercury, TResource ore, TResource sulfur, TResource crystal,
 Res::ResourceSet::ResourceSet(TResource wood, TResource mercury, TResource ore, TResource sulfur, TResource crystal,
 							TResource gems, TResource gold, TResource mithril)
 							TResource gems, TResource gold, TResource mithril)
 {
 {
-	resize(GameConstants::RESOURCE_QUANTITY);
-	auto * d = data();
-	d[Res::WOOD] = wood;
-	d[Res::MERCURY] = mercury;
-	d[Res::ORE] = ore;
-	d[Res::SULFUR] = sulfur;
-	d[Res::CRYSTAL] = crystal;
-	d[Res::GEMS] = gems;
-	d[Res::GOLD] = gold;
-	d[Res::MITHRIL] = mithril;
+	this[Res::WOOD] = wood;
+	this[Res::MERCURY] = mercury;
+	this[Res::ORE] = ore;
+	this[Res::SULFUR] = sulfur;
+	this[Res::CRYSTAL] = crystal;
+	this[Res::GEMS] = gems;
+	this[Res::GOLD] = gold;
+	this[Res::MITHRIL] = mithril;
 }
 }
 
 
 void Res::ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::string & fieldName)
 void Res::ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::string & fieldName)
 {
 {
-	if(!handler.saving)
-		resize(GameConstants::RESOURCE_QUANTITY, 0);
 	if(handler.saving && !nonZero())
 	if(handler.saving && !nonZero())
 		return;
 		return;
 	auto s = handler.enterStruct(fieldName);
 	auto s = handler.enterStruct(fieldName);

+ 103 - 37
lib/ResourceSet.h

@@ -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

+ 1 - 2
lib/mapObjects/CObjectHandler.cpp

@@ -492,9 +492,8 @@ void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visit
 	}
 	}
 }
 }
 
 
-void IShipyard::getBoatCost( std::vector<si32> &cost ) const
+void IShipyard::getBoatCost(TResources & cost) const
 {
 {
-	cost.resize(GameConstants::RESOURCE_QUANTITY);
 	cost[Res::WOOD] = 10;
 	cost[Res::WOOD] = 10;
 	cost[Res::GOLD] = 1000;
 	cost[Res::GOLD] = 1000;
 }
 }

+ 2 - 1
lib/mapObjects/CObjectHandler.h

@@ -14,6 +14,7 @@
 #include "../int3.h"
 #include "../int3.h"
 #include "../HeroBonus.h"
 #include "../HeroBonus.h"
 #include "../NetPacksBase.h"
 #include "../NetPacksBase.h"
+#include "../ResourceSet.h"
 
 
 VCMI_LIB_NAMESPACE_BEGIN
 VCMI_LIB_NAMESPACE_BEGIN
 
 
@@ -104,7 +105,7 @@ class DLL_LINKAGE IShipyard : public IBoatGenerator
 public:
 public:
 	IShipyard(const CGObjectInstance *O);
 	IShipyard(const CGObjectInstance *O);
 
 
-	virtual void getBoatCost(std::vector<si32> &cost) const;
+	virtual void getBoatCost(TResources & cost) const;
 
 
 	static const IShipyard *castFrom(const CGObjectInstance *obj);
 	static const IShipyard *castFrom(const CGObjectInstance *obj);
 	static IShipyard *castFrom(CGObjectInstance *obj);
 	static IShipyard *castFrom(CGObjectInstance *obj);

+ 0 - 3
lib/mapObjects/CQuest.cpp

@@ -521,9 +521,6 @@ void CQuest::serializeJson(JsonSerializeFormat & handler, const std::string & fi
         {
         {
         	auto r = handler.enterStruct("resources");
         	auto r = handler.enterStruct("resources");
 
 
-        	if(!handler.saving)
-				m7resources.resize(GameConstants::RESOURCE_QUANTITY-1);
-
 			for(size_t idx = 0; idx < (GameConstants::RESOURCE_QUANTITY - 1); idx++)
 			for(size_t idx = 0; idx < (GameConstants::RESOURCE_QUANTITY - 1); idx++)
 			{
 			{
 				handler.serializeInt(GameConstants::RESOURCE_NAMES[idx], m7resources[idx], 0);
 				handler.serializeInt(GameConstants::RESOURCE_NAMES[idx], m7resources[idx], 0);

+ 0 - 1
lib/mapping/MapFormatH3M.cpp

@@ -2195,7 +2195,6 @@ void CMapLoaderH3M::readSpells(std::set<SpellID>& dest)
 
 
 void CMapLoaderH3M::readResourses(TResources& resources)
 void CMapLoaderH3M::readResourses(TResources& resources)
 {
 {
-	resources.resize(GameConstants::RESOURCE_QUANTITY); //needed?
 	for(int x = 0; x < 7; ++x)
 	for(int x = 0; x < 7; ++x)
 	{
 	{
 		resources[x] = reader->readUInt32();
 		resources[x] = reader->readUInt32();

+ 1 - 1
mapeditor/inspector/rewardswidget.cpp

@@ -248,7 +248,7 @@ bool RewardsWidget::commitChanges()
 					break;
 					break;
 					
 					
 				case RewardType::RESOURCE:
 				case RewardType::RESOURCE:
-					pandora->resources.at(listId) = amount;
+					pandora->resources[listId] = amount;
 					break;
 					break;
 					
 					
 				case RewardType::PRIMARY_SKILL:
 				case RewardType::PRIMARY_SKILL:

+ 1 - 1
scripting/lua/api/netpacks/SetResources.cpp

@@ -137,7 +137,7 @@ int SetResourcesProxy::setAmount(lua_State * L)
 	if(!S.tryGet(3, amount))
 	if(!S.tryGet(3, amount))
 		return S.retVoid();
 		return S.retVoid();
 
 
-	object->res.at(typeIdx) = amount;
+	object->res[typeIdx] = amount;
 
 
 	return S.retVoid();
 	return S.retVoid();
 }
 }

+ 10 - 10
server/CGameHandler.cpp

@@ -1784,7 +1784,7 @@ void CGameHandler::newTurn()
 		else if (elem.first >= PlayerColor::PLAYER_LIMIT)
 		else if (elem.first >= PlayerColor::PLAYER_LIMIT)
 			assert(0); //illegal player number!
 			assert(0); //illegal player number!
 
 
-		std::pair<PlayerColor, si32> playerGold(elem.first, elem.second.resources.at(Res::GOLD));
+		std::pair<PlayerColor, si32> playerGold(elem.first, elem.second.resources[Res::GOLD]);
 		hadGold.insert(playerGold);
 		hadGold.insert(playerGold);
 
 
 		if (newWeek) //new heroes in tavern
 		if (newWeek) //new heroes in tavern
@@ -2516,7 +2516,7 @@ void CGameHandler::giveResource(PlayerColor player, Res::ERes which, int val) //
 	if (!val) return; //don't waste time on empty call
 	if (!val) return; //don't waste time on empty call
 
 
 	TResources resources;
 	TResources resources;
-	resources.at(which) = val;
+	resources[which] = val;
 	giveResources(player, resources);
 	giveResources(player, resources);
 }
 }
 
 
@@ -4078,7 +4078,7 @@ bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid)
 		COMPLAIN_RET_FALSE_IF(art->warMachine == CreatureID::NONE, "War machine artifact required");
 		COMPLAIN_RET_FALSE_IF(art->warMachine == CreatureID::NONE, "War machine artifact required");
 		COMPLAIN_RET_FALSE_IF(hero->hasArt(aid),"Hero already has this machine!");
 		COMPLAIN_RET_FALSE_IF(hero->hasArt(aid),"Hero already has this machine!");
 		const int price = art->price;
 		const int price = art->price;
-		COMPLAIN_RET_FALSE_IF(getPlayerState(hero->getOwner())->resources.at(Res::GOLD) < price, "Not enough gold!");
+		COMPLAIN_RET_FALSE_IF(getPlayerState(hero->getOwner())->resources[Res::GOLD] < price, "Not enough gold!");
 
 
 		if ((town->hasBuilt(BuildingID::BLACKSMITH) && town->town->warMachine == aid)
 		if ((town->hasBuilt(BuildingID::BLACKSMITH) && town->town->warMachine == aid)
 		 || (town->hasBuilt(BuildingSubID::BALLISTA_YARD) && aid == ArtifactID::BALLISTA))
 		 || (town->hasBuilt(BuildingSubID::BALLISTA_YARD) && aid == ArtifactID::BALLISTA))
@@ -4183,7 +4183,7 @@ bool CGameHandler::buySecSkill(const IMarket *m, const CGHeroInstance *h, Second
 
 
 bool CGameHandler::tradeResources(const IMarket *market, ui32 val, PlayerColor player, ui32 id1, ui32 id2)
 bool CGameHandler::tradeResources(const IMarket *market, ui32 val, PlayerColor player, ui32 id1, ui32 id2)
 {
 {
-	TResourceCap r1 = getPlayerState(player)->resources.at(id1);
+	TResourceCap r1 = getPlayerState(player)->resources[id1];
 
 
 	vstd::amin(val, r1); //can't trade more resources than have
 	vstd::amin(val, r1); //can't trade more resources than have
 
 
@@ -4271,7 +4271,7 @@ bool CGameHandler::sendResources(ui32 val, PlayerColor player, Res::ERes r1, Pla
 		return false;
 		return false;
 	}
 	}
 
 
-	TResourceCap curRes1 = getPlayerState(player)->resources.at(r1);
+	TResourceCap curRes1 = getPlayerState(player)->resources[r1];
 
 
 	vstd::amin(val, curRes1);
 	vstd::amin(val, curRes1);
 
 
@@ -4306,7 +4306,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor pl
 	//common preconditions
 	//common preconditions
 //	if ((p->resources.at(Res::GOLD)<GOLD_NEEDED  && complain("Not enough gold for buying hero!"))
 //	if ((p->resources.at(Res::GOLD)<GOLD_NEEDED  && complain("Not enough gold for buying hero!"))
 //		|| (getHeroCount(player, false) >= GameConstants::MAX_HEROES_PER_PLAYER && complain("Cannot hire hero, only 8 wandering heroes are allowed!")))
 //		|| (getHeroCount(player, false) >= GameConstants::MAX_HEROES_PER_PLAYER && complain("Cannot hire hero, only 8 wandering heroes are allowed!")))
-	if ((p->resources.at(Res::GOLD) < GameConstants::HERO_GOLD_COST && complain("Not enough gold for buying hero!"))
+	if ((p->resources[Res::GOLD] < GameConstants::HERO_GOLD_COST && complain("Not enough gold for buying hero!"))
 		|| ((getHeroCount(player, false) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP) && complain("Cannot hire hero, too many wandering heroes already!")))
 		|| ((getHeroCount(player, false) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP) && complain("Cannot hire hero, too many wandering heroes already!")))
 		|| ((getHeroCount(player, true) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP) && complain("Cannot hire hero, too many heroes garrizoned and wandering already!"))))
 		|| ((getHeroCount(player, true) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP) && complain("Cannot hire hero, too many heroes garrizoned and wandering already!"))))
 	{
 	{
@@ -5324,8 +5324,8 @@ void CGameHandler::handleTimeEvents()
 
 
 				for (int i=0; i<ev.resources.size(); i++)
 				for (int i=0; i<ev.resources.size(); i++)
 				{
 				{
-					if (ev.resources.at(i)) //if resource is changed, we add it to the dialog
-						iw.components.emplace_back(Component::EComponentType::RESOURCE,i,ev.resources.at(i),0);
+					if (ev.resources[i]) //if resource is changed, we add it to the dialog
+						iw.components.emplace_back(Component::EComponentType::RESOURCE,i,ev.resources[i],0);
 				}
 				}
 
 
 				sendAndApply(&iw); //show dialog
 				sendAndApply(&iw); //show dialog
@@ -5382,8 +5382,8 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n)
 				n.res[player].amax(0);
 				n.res[player].amax(0);
 
 
 				for (int i=0; i<ev.resources.size(); i++)
 				for (int i=0; i<ev.resources.size(); i++)
-					if (ev.resources.at(i) && pinfo->resources.at(i) != n.res.at(player).at(i)) //if resource had changed, we add it to the dialog
-						iw.components.emplace_back(Component::EComponentType::RESOURCE,i,n.res.at(player).at(i)-was.at(i),0);
+					if (ev.resources[i] && pinfo->resources[i] != n.res.at(player)[i]) //if resource had changed, we add it to the dialog
+						iw.components.emplace_back(Component::EComponentType::RESOURCE,i,n.res.at(player)[i]-was[i],0);
 
 
 			}
 			}