2
0
Michał W. Urbańczyk 15 жил өмнө
parent
commit
a981dfd1fd

+ 16 - 0
hch/CCreatureHandler.cpp

@@ -656,3 +656,19 @@ void CCreatureHandler::loadUnitAnimInfo(CCreature & unit, std::string & src, int
 CCreatureHandler::~CCreatureHandler()
 {
 }
+
+int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen) const
+{
+	int r = 0;
+	do 
+	{
+		if(randGen)
+			r = randGen();
+		else
+			r = rand();
+
+		r %= 197;
+	} while (vstd::contains(VLC->creh->notUsedMonsters,r));
+
+	return r;
+}

+ 3 - 0
hch/CCreatureHandler.h

@@ -113,6 +113,9 @@ public:
 	bool isGood (si8 faction) const;
 	bool isEvil (si8 faction) const;
 
+	int pickRandomMonster(const boost::function<int()> &randGen = 0) const;
+
+
 	CCreatureHandler();
 	~CCreatureHandler();
 

+ 34 - 38
hch/CObjectHandler.cpp

@@ -1568,6 +1568,10 @@ void CGDwelling::initObj()
 		hoverName = VLC->generaltexth->creGens4[subID];
 		break;
 
+	case 78: //Refugee Camp
+		//is handled within newturn func
+		break; 
+
 	case 106: //War Machine Factory
 		creatures.resize(3);
 		creatures[0].second.push_back(146); //Ballista 
@@ -1597,11 +1601,26 @@ void CGDwelling::setProperty(ui8 what, ui32 val)
 					cb->gameState()->players[val].dwellings.push_back (this);
 			}
 			break;
+		case ObjProperty::AVAILABLE_CREATURE:
+			creatures.resize(1);
+			creatures[0].second.resize(1);
+			creatures[0].second[0] = val;
+			break;
 	}
-	 CGObjectInstance::setProperty(what,val);
+	CGObjectInstance::setProperty(what,val);
 }
 void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
 {
+	if(ID == 78 && !creatures[0].first) //Refugee Camp, no available cres
+	{
+		InfoWindow iw;
+		iw.player = h->tempOwner;
+		iw.text.addTxt(MetaString::ADVOB_TXT, 44); //{%s} \n\n The camp is deserted.  Perhaps you should try next week.
+		iw.text.addReplacement(MetaString::OBJ_NAMES, ID);
+		cb->sendAndApply(&iw);
+		return;
+	}
+
 	if(h->tempOwner != tempOwner  &&  stacksCount() > 0) //object is guarded
 	{
 		BlockingDialog bd;
@@ -1630,6 +1649,13 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
 		for(size_t i = 0; i < creatures.size(); i++)
 			bd.text.addReplacement(MetaString::CRE_PL_NAMES, creatures[i].second[0]);
 	}
+	else if(ID == 78)
+	{
+		bd.text.addTxt(MetaString::ADVOB_TXT, 35); //{%s} Would you like to recruit %s?
+		bd.text.addReplacement(MetaString::OBJ_NAMES, ID);
+		for(size_t i = 0; i < creatures.size(); i++)
+			bd.text.addReplacement(MetaString::CRE_PL_NAMES, creatures[i].second[0]);
+	}
 	else if(ID == 106)
 		bd.text.addTxt(MetaString::ADVOB_TXT, 157); //{War Machine Factory} Would you like to purchase War Machines?
 	else
@@ -1647,6 +1673,11 @@ void CGDwelling::newTurn() const
 	if(ID == TOWNI_TYPE  ||  ID == 106)
 		return;
 
+	if(ID == 78) //if it's a refugee camp, we need to pick an available creature
+	{
+		cb->setObjProperty(id, ObjProperty::AVAILABLE_CREATURE, VLC->creh->pickRandomMonster());
+	}
+
 	bool change = false;
 
 	SetAvailableCreatures sac;
@@ -1676,7 +1707,7 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co
 	int crid = creatures[0].second[0];
 	CCreature *crs = VLC->creh->creatures[crid];
 
-	if(crs->level == 1) //first level - creatures are for free
+	if(crs->level == 1  &&  ID != 78) //first level - creatures are for free
 	{
 		if(creatures[0].first) //there are available creatures
 		{
@@ -1737,7 +1768,7 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co
 		OpenWindow ow;
 		ow.id1 = id;
 		ow.id2 = h->id;
-		ow.window = ID == 17 
+		ow.window = (ID == 17 || ID == 78)
 			? OpenWindow::RECRUITMENT_FIRST 
 			: OpenWindow::RECRUITMENT_ALL;
 		cb->sendAndApply(&ow);
@@ -6175,41 +6206,6 @@ void CCartographer::buyMap (const CGHeroInstance *h, ui32 accept) const
 	}
 }
 
-void CShop::newTurn() const 
-{ 
-	switch (ID)
-	{
-		case 7: //ArtMerchant aka. Black Market
-			if (cb->getDate(0)%28 == 1)
-			{
-				cb->setObjProperty (id, 13, 0);
-				cb->setObjProperty (id, 14, rand());
-			}
-			break;
-		case 78: //Refugee Camp
-		case 95: //Tavern -- global hero pool?
-			if (cb->getDate(0)%7 == 1)
-				cb->setObjProperty (id, 14, rand());
-			break;
-	}
-}
-
-void CShop::setPropertyDer (ui8 what, ui32 val)
-{
-	switch (what)
-	{
-		case 14: //reset - get new items
-			reset(val);
-			break;
-	}
-}
-
-void CGRefugeeCamp::reset(ui32 val)
-{
-	creatureID = VLC->creh->creatures[val%VLC->creh->creatures.size()]->idNumber;
-}
-
-
 void CGDenOfthieves::onHeroVisit (const CGHeroInstance * h) const
 {
 	cb->showThievesGuildWindow(id);

+ 0 - 31
hch/CObjectHandler.h

@@ -1089,37 +1089,6 @@ public:
 		h & static_cast<CPlayersVisited&>(*this);
 		h & players;
 	}
-
-};
-
-class DLL_EXPORT CShop : public CGObjectInstance
-{
-///base class for university, art merchant, slave market etc.
-public:
-	void initObj() {};
-	void setPropertyDer (ui8 what, ui32 val);
-	void newTurn() const;
-	virtual void reset (ui32 val) {}; //get new items for Black Market, Tavern, Refugee Camp 
-	virtual void onHeroVisit (const CGHeroInstance * h) const {};
-	virtual void trade (const CGHeroInstance * h) const {};
-	
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & static_cast<CGObjectInstance&>(*this);
-	}
-};
-
-class DLL_EXPORT CGRefugeeCamp : public CShop
-{
-public:
-	ui16 creatureID;
-	void reset (ui32 val);
-	void onHeroVisit (const CGHeroInstance * h) const {};
-
-	template <typename Handler> void serialize(Handler &h, const int version)
-	{
-		h & creatureID & static_cast<CShop&>(*this);
-	}
 };
 
 class DLL_EXPORT CGDenOfthieves : public CGObjectInstance

+ 1 - 6
lib/CGameState.cpp

@@ -933,12 +933,7 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
 		}
 	case 71: //random monster
 		{
-			int r;
-			do 
-			{
-				r = ran()%197;
-			} while (vstd::contains(VLC->creh->notUsedMonsters,r));
-			return std::pair<int,int>(54,r); 
+			return std::pair<int,int>(54,VLC->creh->pickRandomMonster(boost::ref(ran))); 
 		}
 	case 72: //random monster lvl1
 		return std::pair<int,int>(54,VLC->creh->levelCreatures[1][ran()%VLC->creh->levelCreatures[1].size()]->idNumber); 

+ 1 - 1
lib/NetPacks.h

@@ -747,7 +747,7 @@ struct InfoWindow : public CPackForClient //103  - displays simple info window
 namespace ObjProperty
 {
 	//TODO: move non general properties out to the appropriate objs classes
-	enum {OWNER = 1, BLOCKVIS = 2, PRIMARY_STACK_COUNT = 3, VISITORS = 4, VISITED = 5, ID = 6};
+	enum {OWNER = 1, BLOCKVIS = 2, PRIMARY_STACK_COUNT = 3, VISITORS = 4, VISITED = 5, ID = 6, AVAILABLE_CREATURE = 7};
 }
 
 struct SetObjectProperty : public CPackForClient//1001

+ 1 - 0
lib/map.cpp

@@ -1678,6 +1678,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
 				i+=3;
 				break;
 			}
+		case 78: //Refugee Camp
 		case 106: //War Machine Factory
 			{
 				nobj = new CGDwelling();

+ 1 - 1
server/CGameHandler.cpp

@@ -2703,7 +2703,7 @@ bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram, si32 from
 
 	if(dw->ID == TOWNI_TYPE)
 		dst = dw;
-	else if(dw->ID == 17  ||  dw->ID == 20) //advmap dwelling
+	else if(dw->ID == 17  ||  dw->ID == 20  ||  dw->ID == 78) //advmap dwelling
 		dst = getHero(gs->getPlayer(dw->tempOwner)->currentSelection); //TODO: check if current hero is really visiting dwelling
 	else if(dw->ID == 106)
 		dst = dynamic_cast<const CGHeroInstance *>(getTile(dw->visitablePos())->visitableObjects.back());