Browse Source

Workaround for serializer allowing sending CStackInstance* pointing to commander. (and only CStackInstance*)

Michał W. Urbańczyk 13 years ago
parent
commit
401d6816d1
2 changed files with 32 additions and 4 deletions
  1. 9 1
      lib/CArtHandler.cpp
  2. 23 3
      lib/Connection.h

+ 9 - 1
lib/CArtHandler.cpp

@@ -1030,7 +1030,15 @@ bool CArtifactInstance::canBePutAt(const CArtifactSet *artSet, int slot, bool as
 		return true;
 	}
 
-	if(!vstd::contains(artType->possibleSlots[artSet->bearerType()], slot))
+ 	auto possibleSlots = artType->possibleSlots.find(artSet->bearerType());
+ 	if(possibleSlots == artType->possibleSlots.end())
+ 	{
+		tlog3 << "Warning: arrtifact " << artType->Name() << " doesn't have defined allowed slots for bearer of type "
+			<< artSet->bearerType() << std::endl;
+		return false;
+	}
+
+	if(!vstd::contains(possibleSlots->second, slot))
 		return false;
 
 	return artSet->isPositionFree(slot, assumeDestRemoved);

+ 23 - 3
lib/Connection.h

@@ -24,6 +24,8 @@
 #include "CObjectHandler.h" //fo CArmedInstance
 
 const ui32 version = 732;
+const TSlot COMMANDER_SLOT_PLACEHOLDER = -2;
+
 class CConnection;
 class CGObjectInstance;
 class CStackInstance;
@@ -378,7 +380,14 @@ struct SaveIfStackInstance<Ser, CStackInstance *>
 	static bool invoke(Ser &s, const CStackInstance* const &data)
 	{
 		assert(data->armyObj);
-		TSlot slot = data->armyObj->findStack(data);
+		TSlot slot = -1;
+
+		if(data->getNodeType() == Bonus::COMMANDER)
+			slot = COMMANDER_SLOT_PLACEHOLDER;
+		else
+			slot = data->armyObj->findStack(data);
+
+		assert(slot != -1);
 		s << data->armyObj << slot;
 		return true;
 	}
@@ -391,6 +400,7 @@ struct LoadIfStackInstance
 		return false;
 	}
 };
+
 template<typename Ser>
 struct LoadIfStackInstance<Ser, CStackInstance *>
 {
@@ -399,8 +409,18 @@ struct LoadIfStackInstance<Ser, CStackInstance *>
 		CArmedInstance *armedObj;
 		TSlot slot;
 		s >> armedObj >> slot;
-		assert(armedObj->hasStackAtSlot(slot));
-		data = armedObj->stacks[slot];
+		if(slot != COMMANDER_SLOT_PLACEHOLDER)
+		{
+			assert(armedObj->hasStackAtSlot(slot));
+			data = armedObj->stacks[slot];
+		}
+		else
+		{
+			auto hero = dynamic_cast<CGHeroInstance *>(armedObj);
+			assert(hero);
+			assert(hero->commander);
+			data = hero->commander;
+		}
 		return true;
 	}
 };