Quellcode durchsuchen

Changes towards Hill fort support.

Michał W. Urbańczyk vor 15 Jahren
Ursprung
Commit
fffef1d740
6 geänderte Dateien mit 80 neuen und 36 gelöschten Zeilen
  1. 1 1
      CCallback.cpp
  2. 22 10
      client/GUIClasses.cpp
  3. 7 1
      client/GUIClasses.h
  4. 45 21
      lib/CGameState.cpp
  5. 4 2
      lib/CGameState.h
  6. 1 1
      server/CGameHandler.cpp

+ 1 - 1
CCallback.cpp

@@ -98,7 +98,7 @@ void CCallback::endTurn()
 UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) const
 {
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
-	return gs->getUpgradeInfo(const_cast<CArmedInstance*>(obj),stackPos);
+	return gs->getUpgradeInfo(obj->getStack(stackPos));
 }
 
 const StartInfo * CCallback::getStartInfo() const

+ 22 - 10
client/GUIClasses.cpp

@@ -616,7 +616,6 @@ CInfoWindow::CInfoWindow(std::string Text, int player, int charperline, const st
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	ID = -1;
-	this->delComps = delComps;
 	for(int i=0;i<Buttons.size();i++)
 	{
 		buttons.push_back(new AdventureMapButton("","",boost::bind(&CInfoWindow::close,this),0,0,Buttons[i].first));
@@ -635,13 +634,14 @@ CInfoWindow::CInfoWindow(std::string Text, int player, int charperline, const st
 		addChild(comps[i]);
 		components.push_back(comps[i]);
 	}
+	setDelComps(delComps);
 	CMessage::drawIWindow(this,Text,player,charperline);
 }
 
 CInfoWindow::CInfoWindow() 
 {
 	ID = -1;
-	delComps = false;
+	setDelComps(false);
 	text = NULL;
 }
 void CInfoWindow::close()
@@ -657,11 +657,11 @@ void CInfoWindow::show(SDL_Surface * to)
 
 CInfoWindow::~CInfoWindow()
 {
-// 	if(delComps)
-// 	{
-// 		for (int i=0;i<components.size();i++)
-// 			delete components[i];
-// 	}
+	if(!delComps)
+	{
+		for (int i=0;i<components.size();i++)
+			removeChild(components[i]);
+	}
 }
 
 void CInfoWindow::showAll( SDL_Surface * to )
@@ -677,7 +677,6 @@ void CInfoWindow::showYesNoDialog(const std::string & text, const std::vector<SC
 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
 	pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",0));
 	CInfoWindow * temp = new CInfoWindow(text, player, 0, components ? *components : std::vector<SComponent*>(), pom, DelComps);
-	temp->delComps = DelComps;
 	for(int i=0;i<onYes.funcs.size();i++)
 		temp->buttons[0]->callback += onYes.funcs[i];
 	for(int i=0;i<onNo.funcs.size();i++)
@@ -694,6 +693,18 @@ CInfoWindow * CInfoWindow::create(const std::string &text, int playerID /*= 1*/,
 	return ret;
 }
 
+void CInfoWindow::setDelComps(bool DelComps)
+{
+	delComps = DelComps;
+	BOOST_FOREACH(SComponent *comp, components)
+	{
+		if(delComps)
+			comp->recActions |= DISPOSE;
+		else
+			comp->recActions &= ~DISPOSE;
+	}
+}
+
 void CRClickPopup::clickRight(tribool down, bool previousState)
 {
 	if(down)
@@ -2214,6 +2225,7 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi
 			bool enough = true;
 			for(std::set<std::pair<int,int> >::iterator i=ui->cost[0].begin(); i!=ui->cost[0].end(); i++) //calculate upgrade cost
 			{
+				BLOCK_CAPTURING;
 				if(LOCPLINT->cb->getResourceAmount(i->first) < i->second*st.count)
 					enough = false;
 				upgResCost.push_back(new SComponent(SComponent::resource,i->first,i->second*st.count)); 
@@ -2362,8 +2374,8 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount)
 CCreInfoWindow::~CCreInfoWindow()
 {
 	delete anim;
-// 	for(int i=0; i<upgResCost.size();i++)
-// 		delete upgResCost[i];
+ 	for(int i=0; i<upgResCost.size();i++)
+ 		delete upgResCost[i];
 }
 
 void CCreInfoWindow::activate()

+ 7 - 1
client/GUIClasses.h

@@ -72,15 +72,21 @@ extern SDL_Color tytulowy, tlo, zwykly ;
 
 class CInfoWindow : public CSimpleWindow //text + comp. + ok button
 { //window able to delete its components when closed
+	bool delComps; //whether comps will be deleted
+
 public:
 	CTextBox *text;
 	std::vector<AdventureMapButton *> buttons;
-	bool delComps; //whether comps will be deleted
 	std::vector<SComponent*> components;
+	CSlider *slider;
 
+	void setDelComps(bool DelComps);
 	virtual void close();
+
 	void show(SDL_Surface * to);
 	void showAll(SDL_Surface * to);
+	void sliderMoved(int to);
+
 	CInfoWindow(std::string Text, int player, int charperline, const std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, bool delComps); //c-tor
 	CInfoWindow(); //c-tor
 	~CInfoWindow(); //d-tor

+ 45 - 21
lib/CGameState.cpp

@@ -1723,37 +1723,61 @@ const CGHeroInstance * CGameState::battleGetOwner(int stackID)
 	return curB->heroes[!curB->getStack(stackID)->attackerOwned];
 }
 
-UpgradeInfo CGameState::getUpgradeInfo(const CArmedInstance *obj, int stackPos)
+std::set<std::pair<int, int> > costDiff(const std::vector<ui32> &a, const std::vector<ui32> &b, const int modifier = 100) //modifer %
+{
+	std::set<std::pair<int, int> > ret;
+	for(int j=0;j<RESOURCE_QUANTITY;j++)
+	{
+		assert(a[j] >= b[j]);
+		if(int dif = modifier * (a[j] - b[j]) / 100)
+			ret.insert(std::make_pair(j,dif));
+	}
+	return ret;
+}
+
+UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
 {
 	UpgradeInfo ret;
-	const CCreature *base = obj->getCreature(stackPos);
-	if((obj->ID == TOWNI_TYPE)  ||  ((obj->ID == HEROI_TYPE) && static_cast<const CGHeroInstance*>(obj)->visitedTown))
+	const CCreature *base = stack.type;
+
+	const CGHeroInstance *h = stack.armyObj->ID == HEROI_TYPE ? static_cast<const CGHeroInstance*>(stack.armyObj) : NULL;
+	const CGTownInstance *t = NULL;
+
+	if(stack.armyObj->ID == TOWNI_TYPE)
+		t = static_cast<const CGTownInstance *>(stack.armyObj);
+	else if(h)
+		t = h->visitedTown;
+
+	if(t)
 	{
-		const CGTownInstance * t;
-		if(obj->ID == TOWNI_TYPE)
-			t = static_cast<const CGTownInstance *>(obj);
-		else
-			t = static_cast<const CGHeroInstance*>(obj)->visitedTown;
-		for(std::set<si32>::const_iterator i=t->builtBuildings.begin();  i!=t->builtBuildings.end(); i++)
+		BOOST_FOREACH(si32 bid, t->builtBuildings)
 		{
-			if( (*i) >= 37   &&   (*i) < 44 ) //upgraded creature dwelling
+			if( bid >= 37   &&   bid < 44 ) //upgraded creature dwelling
 			{
-				int nid = t->town->upgradedCreatures[(*i)-37]; //upgrade offered by that building
-				if(base->upgrades.find(nid) != base->upgrades.end()) //possible upgrade
+				int nid = t->town->upgradedCreatures[bid-37]; //upgrade offered by that building
+				if(vstd::contains(base->upgrades, nid)) //possible upgrade
 				{
 					ret.newID.push_back(nid);
-					ret.cost.push_back(std::set<std::pair<int,int> >());
-					for(int j=0;j<RESOURCE_QUANTITY;j++)
-					{
-						int dif = VLC->creh->creatures[nid]->cost[j] - base->cost[j];
-						if(dif)
-							ret.cost[ret.cost.size()-1].insert(std::make_pair(j,dif));
-					}
+					ret.cost.push_back(costDiff(VLC->creh->creatures[nid]->cost, base->cost));
 				}
 			}
-		}//end for
+		}
+	}
+
+	//hero is visiting Hill Fort
+	if(h && map->getTile(h->visitablePos()).visitableObjects.front()->ID == 35) 
+	{
+		static const int costModifiers[] = {0, 25, 50, 75, 100}; //we get cheaper upgrades depending on level
+		const int costModifier = costModifiers[std::min<int>(std::max((int)base->level - 1, 0), ARRAY_COUNT(costModifiers) - 1)];
+
+		BOOST_FOREACH(si32 nid, base->upgrades)
+		{
+			ret.newID.push_back(nid);
+			ret.cost.push_back(costDiff(VLC->creh->creatures[nid]->cost, base->cost, costModifier));
+		}
 	}
-	//TODO: check if hero ability makes some upgrades possible
+
+	//TODO: check if hero specialty makes some upgrades possible
 
 	if(ret.newID.size())
 		ret.oldID = base->idNumber;

+ 4 - 2
lib/CGameState.h

@@ -90,7 +90,9 @@ public:
 	void initFromHero(const CGHeroInstance *h, bool detailed);
 };
 
-
+// typedef si32 TResourceUnit;
+// typedef std::vector<si32> TResourceVector;
+// typedef std::set<si32> TResourceSet;
 
 struct DLL_EXPORT SThievesGuildInfo
 {
@@ -416,7 +418,7 @@ public:
 	const CGHeroInstance * battleGetOwner(int stackID); //returns hero that owns given stack; NULL if none
 	si8 battleMaxSpellLevel(); //calculates maximum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, SPELL_LEVELS is returned
 	bool battleCanShoot(int ID, int dest); //determines if stack with given ID shoot at the selected destination
-	UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos);
+	UpgradeInfo getUpgradeInfo(const CStackInstance &stack);
 	//float getMarketEfficiency(int player, int mode=0);
 	std::set<int> getBuildingRequiments(const CGTownInstance *t, int ID);
 	int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements

+ 1 - 1
server/CGameHandler.cpp

@@ -2778,7 +2778,7 @@ bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram, si32 from
 bool CGameHandler::upgradeCreature( ui32 objid, ui8 pos, ui32 upgID )
 {
 	CArmedInstance *obj = static_cast<CArmedInstance*>(gs->map->objects[objid]);
-	UpgradeInfo ui = gs->getUpgradeInfo(obj,pos);
+	UpgradeInfo ui = gs->getUpgradeInfo(obj->getStack(pos));
 	int player = obj->tempOwner;
 	int crQuantity = obj->slots[pos].count;