Ver Fonte

* battle funcs added to ICallback
* initing visiting heroes
* merging stacks in town screen
* available creature amount handled

Michał W. Urbańczyk há 17 anos atrás
pai
commit
a729484dde
5 ficheiros alterados com 136 adições e 42 exclusões
  1. 1 1
      AI/EmptyAI/CEmptyAI.h
  2. 74 35
      CCallback.cpp
  3. 14 1
      CCallback.h
  4. 15 0
      CMT.cpp
  5. 32 5
      CPlayerInterface.cpp

+ 1 - 1
AI/EmptyAI/CEmptyAI.h

@@ -1,5 +1,5 @@
 #include "../../AI_Base.h"
-
+#include "../../CCallback.h"
 class CEmptyAI : public CGlobalAI
 {
 	ICallback * cb;

+ 74 - 35
CCallback.cpp

@@ -251,6 +251,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount
 	if(amount<=0) return;
 	if(obj->ID==98)
 	{
+		int ser=-1;
 		CGTownInstance *t = const_cast<CGTownInstance*>(static_cast<const CGTownInstance*>(obj));
 
 		//verify
@@ -262,6 +263,7 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount
 				|| (found  = (ID == t->town->upgradedCreatures[av->first]))			)
 			{
 				amount = std::min(amount,av->second);
+				ser = av->first;
 				break;
 			}
 		}
@@ -292,6 +294,8 @@ void CCallback::recruitCreatures(const CGObjectInstance *obj, int ID, int amount
 
 		for(int i=0;i<RESOURCE_QUANTITY;i++)
 			gs->players[player].resources[i]  -=  (CGI->creh->creatures[ID].cost[i] * amount);
+
+		t->strInfo.creatures[ser] -= amount;
 		
 		t->army.slots[slot].first = &CGI->creh->creatures[ID];
 		t->army.slots[slot].second = amount;
@@ -496,52 +500,82 @@ int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance
 		//TODO: check if we are allowed to swap these creatures
 		return -1;
 	}
-	//if(S1->slots[p1].first)
+
+	CCreature * pom = S2->slots[p2].first;
+	S2->slots[p2].first = S1->slots[p1].first;
+	S1->slots[p1].first = pom;
+	int pom2 = S2->slots[p2].second;
+	S2->slots[p2].second = S1->slots[p1].second;
+	S1->slots[p1].second = pom2;
+
+	if(!S1->slots[p1].first)
+		S1->slots.erase(p1);
+	if(!S2->slots[p2].first)
+		S2->slots.erase(p2);
+
+	if(s1->tempOwner<PLAYER_LIMIT)
 	{
-		//if(s2->slots[p2].first)
+		for(int b=0; b<CGI->playerint.size(); ++b)
 		{
-			CCreature * pom = S2->slots[p2].first;
-			S2->slots[p2].first = S1->slots[p1].first;
-			S1->slots[p1].first = pom;
-			int pom2 = S2->slots[p2].second;
-			S2->slots[p2].second = S1->slots[p1].second;
-			S1->slots[p1].second = pom2;
-
-			if(!S1->slots[p1].first)
-				S1->slots.erase(p1);
-			if(!S2->slots[p2].first)
-				S2->slots.erase(p2);
-			if(s1->tempOwner<PLAYER_LIMIT)
+			if(CGI->playerint[b]->playerID == s1->tempOwner)
 			{
-				for(int b=0; b<CGI->playerint.size(); ++b)
-				{
-					if(CGI->playerint[b]->playerID == s1->tempOwner)
-					{
-						CGI->playerint[b]->garrisonChanged(s1);
-						break;
-					}
-				}
+				CGI->playerint[b]->garrisonChanged(s1);
+				break;
 			}
-			if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
+		}
+	}
+	if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
+	{
+		for(int b=0; b<CGI->playerint.size(); ++b)
+		{
+			if(CGI->playerint[b]->playerID == s2->tempOwner)
 			{
-				for(int b=0; b<CGI->playerint.size(); ++b)
-				{
-					if(CGI->playerint[b]->playerID == s2->tempOwner)
-					{
-						CGI->playerint[b]->garrisonChanged(s2);
-						break;
-					}
-				}
+				CGI->playerint[b]->garrisonChanged(s2);
+				break;
 			}
-			return 0;
 		}
 	}
-	return -1;
+	return 0;
 }
 
 int CCallback::mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)
-{
-	return -1;
+{	
+	CCreatureSet *S1 = const_cast<CCreatureSet*>(getGarrison(s1)), *S2 = const_cast<CCreatureSet*>(getGarrison(s2));
+	if ((S1->slots[p1].first != S2->slots[p2].first) && (true /*we are allowed to*/))
+	{
+		return -1;
+	}
+
+
+	S2->slots[p2].second += S1->slots[p1].second;
+	S1->slots[p1].first = NULL;
+	S1->slots[p1].second = 0;
+
+	S1->slots.erase(p1);
+
+	if(s1->tempOwner<PLAYER_LIMIT)
+	{
+		for(int b=0; b<CGI->playerint.size(); ++b)
+		{
+			if(CGI->playerint[b]->playerID == s1->tempOwner)
+			{
+				CGI->playerint[b]->garrisonChanged(s1);
+				break;
+			}
+		}
+	}
+	if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
+	{
+		for(int b=0; b<CGI->playerint.size(); ++b)
+		{
+			if(CGI->playerint[b]->playerID == s2->tempOwner)
+			{
+				CGI->playerint[b]->garrisonChanged(s2);
+				break;
+			}
+		}
+	}
+	return 0;
 }
 int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)
 {
@@ -611,6 +645,11 @@ int CCallback::battleGetBattlefieldType()
 	return CGI->mh->ttiles[CGI->state->curB->tile.x][CGI->state->curB->tile.y][CGI->state->curB->tile.z].terType;
 }
 
+int CCallback::battleGetObstaclesAtTile(int tile) //returns bitfield 
+{
+	//TODO - write
+	return -1;
+}
 int CCallback::battleGetStack(int pos)
 {
 	for(int g=0; g<CGI->state->curB->stacks.size(); ++g)

+ 14 - 1
CCallback.h

@@ -42,6 +42,19 @@ public:
 	virtual int getMySerial()=0;
 	virtual int getHeroSerial(const CGHeroInstance * hero)=0;
 	virtual const CCreatureSet* getGarrison(const CGObjectInstance *obj)=0;
+
+//battle
+	virtual int battleGetBattlefieldType()=0; //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
+	virtual int battleGetObstaclesAtTile(int tile)=0; //returns bitfield 
+	virtual int battleGetStack(int pos)=0; //returns ID of stack on the tile
+	virtual CStack battleGetStackByID(int ID)=0; //returns stack info by given ID
+	virtual int battleGetPos(int stack)=0; //returns position (tile ID) of stack
+	virtual int battleMakeAction(BattleAction* action)=0;//perform action with an active stack (or custom action)
+	virtual std::map<int, CStack> battleGetStacks()=0; //returns stacks on battlefield
+	virtual CCreature battleGetCreature(int number)=0; //returns type of creature by given number of stack
+	virtual bool battleMoveCreature(int ID, int dest)=0; //moves creature with id ID to dest if possible
+	virtual std::vector<int> battleGetAvailableHexes(int ID)=0; //reutrns numbers of hexes reachable by creature with id ID
+	virtual bool battleIsStackMine(int ID)=0; //returns true if stack with id ID belongs to caller
 };
 
 struct HeroMoveDetails
@@ -90,7 +103,7 @@ public:
 	int getHeroSerial(const CGHeroInstance * hero);
 	int getMySerial();
 	int swapCreatures(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2);
-	int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2);
+	int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2); //first goes to the second
 	int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val);
 	bool dismissHero(const CGHeroInstance * hero);
 	const CCreatureSet* getGarrison(const CGObjectInstance *obj);

+ 15 - 0
CMT.cpp

@@ -237,7 +237,22 @@ void initGameState(CGameInfo * cgi)
 				}
 			}
 		}
+
+		//init visiting heroes
+		for(int l=0; l<k->second.heroes.size();l++)
+		{ 
+			for(int m=0; m<k->second.towns.size();m++)
+			{
+				int3 vistile = k->second.towns[m]->pos; vistile.x--; //tile next to the entrance
+				if(vistile == k->second.heroes[l]->pos)
+				{
+					k->second.towns[m]->visitingHero = k->second.heroes[l];
+					break;
+				}
+			}
+		}
 	}
+
 	/****************************SCRIPTS************************************************/
 	std::map<int, std::map<std::string, CObjectScript*> > * skrypty = &cgi->state->objscr; //alias for easier access
 	/****************************C++ OBJECT SCRIPTS************************************************/

+ 32 - 5
CPlayerInterface.cpp

@@ -56,12 +56,18 @@ void CGarrisonSlot::hover (bool on)
 					temp = CGI->townh->tcommands[2];
 					boost::algorithm::replace_first(temp,"%s",creature->nameSing);
 				}
-				else
+				else if (owner->highlighted->creature)
 				{
 					temp = CGI->townh->tcommands[7];
 					boost::algorithm::replace_first(temp,"%s",owner->highlighted->creature->nameSing);
 					boost::algorithm::replace_first(temp,"%s",creature->nameSing);
 				}
+				else
+				{
+					std::cout << "Warning - shouldn't be - highlighted void slot "<<owner->highlighted<<std::endl;
+					std::cout << "Highlighted set to NULL"<<std::endl;
+					owner->highlighted = NULL;
+				}
 			}
 			else
 			{
@@ -109,10 +115,26 @@ void CGarrisonSlot::clickLeft(tribool down)
 	{
 		if(owner->highlighted)
 		{
-			LOCPLINT->cb->swapCreatures(
-				(!upg)?(owner->oup):(owner->odown),
-				(!owner->highlighted->upg)?(owner->oup):(owner->odown),
-				ID,owner->highlighted->ID);
+			if(owner->highlighted == this)
+			{
+				//TODO: view creature info
+				owner->highlighted = NULL;
+				show();
+			}
+			else if(creature != owner->highlighted->creature) //swap
+			{
+				LOCPLINT->cb->swapCreatures(
+					(!upg)?(owner->oup):(owner->odown),
+					(!owner->highlighted->upg)?(owner->oup):(owner->odown),
+					ID,owner->highlighted->ID);
+			}
+			else
+			{
+				LOCPLINT->cb->mergeStacks(
+					(!owner->highlighted->upg)?(owner->oup):(owner->odown),
+					(!upg)?(owner->oup):(owner->odown),
+					owner->highlighted->ID,ID);
+			}
 		}
 		else
 		{
@@ -1861,6 +1883,11 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
 			SDL_FreeSurface(heroWins[hh->subID]);
 			heroWins[hh->subID] = infoWin(hh);
 		}
+		if(castleInt == curint) //opened town window - redraw town garrsion slots (change is within hero garr) 
+		{
+			castleInt->garr->highlighted = NULL;
+			castleInt->garr->recreateSlots();
+		}
 	}
 	else if (obj->ID == 98) //town
 	{