Browse Source

New files / project files for VC9.

Michał W. Urbańczyk 15 years ago
parent
commit
b52707f0ae
3 changed files with 253 additions and 0 deletions
  1. 175 0
      lib/CCreatureSet.cpp
  2. 70 0
      lib/CCreatureSet.h
  3. 8 0
      lib/VCMI_lib.vcproj

+ 175 - 0
lib/CCreatureSet.cpp

@@ -0,0 +1,175 @@
+#define VCMI_DLL
+#include "CCreatureSet.h"
+#include "../hch/CCreatureHandler.h"
+#include "VCMI_Lib.h"
+#include <assert.h>
+
+const CStackInstance CCreatureSet::operator[](TSlot slot) const
+{
+	TSlots::const_iterator i = slots.find(slot);
+	if (i != slots.end())
+		return i->second;
+	else
+		throw std::string("That slot is empty!");
+}
+
+const CCreature* CCreatureSet::getCreature(TSlot slot) const /*workaround of map issue */
+{
+	TSlots::const_iterator i = slots.find(slot);
+	if (i != slots.end())
+		return i->second.type;
+	else
+		return NULL;
+}
+
+bool CCreatureSet::setCreature(TSlot slot, TCreature type, TQuantity quantity) /*slots 0 to 6 */
+{
+	slots[slot] = CStackInstance(type, quantity);  //brutal force
+	if (quantity == 0)
+		slots.erase(slot);
+
+	if (slots.size() > 7) 
+		return false;
+	else 
+		return true;
+}
+
+TSlot CCreatureSet::getSlotFor(TCreature creature, ui32 slotsAmount/*=7*/) const /*returns -1 if no slot available */
+{
+	for(TSlots::const_iterator i=slots.begin(); i!=slots.end(); ++i)
+	{
+		if(i->second.type->idNumber == creature)
+		{
+			return i->first; //if there is already such creature we return its slot id
+		}
+	}
+	for(ui32 i=0; i<slotsAmount; i++)
+	{
+		if(slots.find(i) == slots.end())
+		{
+			return i; //return first free slot
+		}
+	}
+	return -1; //no slot available
+}
+
+int CCreatureSet::getAmount(TSlot slot) const
+{
+	TSlots::const_iterator i = slots.find(slot);
+	if (i != slots.end())
+		return i->second.count;
+	else
+		return 0; //TODO? consider issuing a warning
+}
+
+bool CCreatureSet::mergableStacks(std::pair<TSlot, TSlot> &out, TSlot preferable /*= -1*/) /*looks for two same stacks, returns slot positions */
+{
+	//try to match creature to our preferred stack
+	if(preferable >= 0  &&  vstd::contains(slots, preferable))
+	{
+		const CCreature *cr = slots[preferable].type;
+		for(TSlots::const_iterator j=slots.begin(); j!=slots.end(); ++j)
+		{
+			if(cr == j->second.type && j->first != preferable)
+			{
+				out.first = preferable;
+				out.second = j->first;
+				return true;
+			}
+		}
+	}
+
+	for(TSlots::const_iterator i=slots.begin(); i!=slots.end(); ++i)
+	{
+		for(TSlots::const_iterator j=slots.begin(); j!=slots.end(); ++j)
+		{
+			if(i->second.type == j->second.type  &&  i->first != j->first)
+			{
+				out.first = i->first;
+				out.second = j->first;
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+void CCreatureSet::sweep()
+{
+	for(TSlots::iterator i=slots.begin(); i!=slots.end(); ++i)
+	{
+		if(!i->second.count)
+		{
+			slots.erase(i);
+			sweep();
+			break;
+		}
+	}
+}
+
+void CCreatureSet::addToSlot(TSlot slot, TCreature cre, TQuantity count)
+{
+	assert(slot >= 0);
+	const CCreature *c = &VLC->creh->creatures[cre];
+	assert(!vstd::contains(slots, slot) || slots[slot].type == c); //that slot was empty or contained same type creature
+	slots[slot].type = c;
+	slots[slot].count += count;
+}
+
+void CCreatureSet::addToSlot(TSlot slot, const CStackInstance &stack)
+{
+	addToSlot(slot, stack.type->idNumber, stack.count);
+}
+
+bool CCreatureSet::validTypes(bool allowUnrandomized /*= false*/) const
+{
+	for(TSlots::const_iterator i=slots.begin(); i!=slots.end(); ++i)
+	{
+		bool isRand = (i->second.idRand != -1);
+		if(!isRand)
+		{
+			assert(i->second.type);
+			assert(i->second.type == &VLC->creh->creatures[i->second.type->idNumber]);
+		}
+		else
+			assert(allowUnrandomized);
+	}
+	return true;
+}
+
+CStackInstance::CStackInstance()
+{
+	init();
+}
+
+CStackInstance::CStackInstance(TCreature id, TQuantity Count)
+{
+	init();
+	setType(id);
+	count = Count;
+}
+
+CStackInstance::CStackInstance(const CCreature *cre, TQuantity Count)
+{
+	init();
+	type = cre;
+	count = Count;
+}
+
+void CStackInstance::init()
+{
+	experience = 0;
+	count = 0;
+	type = NULL;
+	idRand = -1;
+}
+
+int CStackInstance::getQuantityID() const 
+{
+	return CCreature::getQuantityID(count);
+}
+
+void CStackInstance::setType(int creID)
+{
+	type = &VLC->creh->creatures[creID];
+}

+ 70 - 0
lib/CCreatureSet.h

@@ -0,0 +1,70 @@
+#ifndef __CCREATURESET_H__
+#define __CCREATURESET_H__
+
+#include "../global.h"
+#include <map>
+
+class CCreature;
+class CGHeroInstance;
+
+//a few typedefs for CCreatureSet
+typedef si32 TSlot;
+typedef si32 TQuantity; 
+typedef ui32 TCreature; //creature id
+
+
+class DLL_EXPORT CStackInstance
+{
+public:
+	int idRand; //hlp variable used during loading game -> "id" placeholder for randomization
+	const CCreature *type;
+	TQuantity count;
+	ui32 experience; //TODO: handle
+	//TODO: stack artifacts
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h/* & owner*/ & type & count & experience;
+	}
+
+	int getQuantityID() const;
+	void init();
+	CStackInstance();
+	CStackInstance(TCreature id, TQuantity count);
+	CStackInstance(const CCreature *cre, TQuantity count);
+	void setType(int creID);
+};
+
+
+typedef std::map<TSlot, CStackInstance> TSlots;
+
+class DLL_EXPORT CCreatureSet //seven combined creatures
+{
+public:
+	TSlots slots; //slots[slot_id]=> pair(creature_id,creature_quantity)
+	ui8 formation; //false - wide, true - tight
+
+	const CStackInstance operator[](TSlot slot) const; 
+
+	void addToSlot(TSlot slot, TCreature cre, TQuantity count); //Adds stack to slot. Slot must be empty or with same type creature
+	void addToSlot(TSlot slot, const CStackInstance &stack); //Adds stack to slot. Slot must be empty or with same type creature
+
+	const CCreature* getCreature(TSlot slot) const; //workaround of map issue;
+	int getAmount (TSlot slot) const;
+	bool setCreature (TSlot slot, TCreature type, TQuantity quantity); //slots 0 to 6
+	TSlot getSlotFor(TCreature creature, ui32 slotsAmount=7) const; //returns -1 if no slot available
+	bool mergableStacks(std::pair<TSlot, TSlot> &out, TSlot preferable = -1); //looks for two same stacks, returns slot positions;
+	bool validTypes(bool allowUnrandomized = false) const; //checks if all types of creatures are set properly
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & slots & formation;
+	}
+	operator bool() const
+	{
+		return slots.size() > 0;
+	}
+	void sweep();
+};
+
+#endif // __CCREATURESET_H__

+ 8 - 0
lib/VCMI_lib.vcproj

@@ -376,6 +376,10 @@
 				RelativePath="..\hch\CCreatureHandler.h"
 				>
 			</File>
+			<File
+				RelativePath=".\CCreatureSet.h"
+				>
+			</File>
 			<File
 				RelativePath="..\hch\CDefObjInfoHandler.h"
 				>
@@ -453,6 +457,10 @@
 				>
 			</File>
 		</Filter>
+		<File
+			RelativePath=".\CCreatureSet.cpp"
+			>
+		</File>
 	</Files>
 	<Globals>
 	</Globals>