Преглед изворни кода

* support for numpad keyboard
* cannot build more than one capitol
* cannot build shipyard if town is not near water

Michał W. Urbańczyk пре 17 година
родитељ
комит
79ae1441ff
7 измењених фајлова са 83 додато и 40 уклоњено
  1. 11 1
      CCallback.cpp
  2. 5 0
      CCallback.h
  3. 1 26
      CCastleInterface.cpp
  4. 48 0
      CGameState.cpp
  5. 2 1
      CGameState.h
  6. 13 1
      CPlayerInterface.cpp
  7. 3 11
      server/CGameHandler.cpp

+ 11 - 1
CCallback.cpp

@@ -703,4 +703,14 @@ std::vector<const CGHeroInstance *> CCallback::getAvailableHeroes(const CGTownIn
 	std::vector<const CGHeroInstance *> ret(gs->players[player].availableHeroes.size());
 	std::copy(gs->players[player].availableHeroes.begin(),gs->players[player].availableHeroes.end(),ret.begin());
 	return ret;
-}	
+}	
+
+const TerrainTile * CCallback::getTileInfo( int3 tile )
+{
+	return &gs->map->getTile(tile);
+}
+
+int CCallback::canBuildStructure( const CGTownInstance *t, int ID )
+{
+	return gs->canBuildStructure(t,ID);
+}

+ 5 - 0
CCallback.h

@@ -25,6 +25,7 @@ struct StartInfo;
 class CStack;
 struct lua_State;
 class CClient;
+struct TerrainTile;
 //structure gathering info about upgrade possibilites
 
 class ICallback
@@ -72,6 +73,8 @@ public:
 	virtual std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const =0;
 	virtual int3 getMapSize() const =0; //returns size of map - z is 1 for one - level map and 2 for two level map
 	virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited
+	virtual const TerrainTile * getTileInfo(int3 tile) = 0;
+	virtual int canBuildStructure(const CGTownInstance *t, int ID) =0;//// 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
 
 //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
@@ -161,6 +164,8 @@ public:
 	std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
 	int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
 	std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const; //heroes that can be recruited
+	const TerrainTile * getTileInfo(int3 tile);
+	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
 
 	//battle
 	int battleGetBattlefieldType(); //   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

+ 1 - 26
CCastleInterface.cpp

@@ -1029,32 +1029,7 @@ CHallInterface::CHallInterface(CCastleInterface * owner)
 						x+=97;
 					boxes[i].push_back(new CBuildingBox(CGI->buildh->hall[owner->town->subID].second[i][j][k],pos.x+x,pos.y+y));
 
-					boxes[i][boxes[i].size()-1]->state = 7; //allowed by default
-
-					//can we build it?
-					if(owner->town->forbiddenBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])!=owner->town->forbiddenBuildings.end())
-						boxes[i][boxes[i].size()-1]->state = 2; //forbidden
-					else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
-						boxes[i][boxes[i].size()-1]->state = 5; //building limit
-
-					//checking resources
-					CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
-					for(int res=0;res<7;res++) //TODO: support custom amount of resources
-					{
-						if(pom->resources[res]>LOCPLINT->cb->getResourceAmount(res))
-							boxes[i][boxes[i].size()-1]->state = 6; //lack of res
-					}
-
-					//checking for requirements
-					for( std::set<int>::iterator ri  =  CGI->townh->requirements[owner->town->subID][ID].begin();
-						 ri != CGI->townh->requirements[owner->town->subID][ID].end();
-						 ri++ )
-					{
-						if(owner->town->builtBuildings.find(*ri)==owner->town->builtBuildings.end())
-							boxes[i][boxes[i].size()-1]->state = 8; //lack of requirements - cannot build
-					}
-
-					//TODO: check if capital is already built, check if there is water for shipyard
+					boxes[i].back()->state = LOCPLINT->cb->canBuildStructure(owner->town,ID);
 					break;
 				}
 			}

+ 48 - 0
CGameState.cpp

@@ -6,6 +6,7 @@
 #include <boost/random/linear_congruential.hpp>
 #include "hch/CDefObjInfoHandler.h"
 #include "hch/CArtHandler.h"
+#include "hch/CBuildingHandler.h"
 #include "hch/CGeneralTextHandler.h"
 #include "hch/CTownHandler.h"
 #include "hch/CSpellHandler.h"
@@ -1885,6 +1886,53 @@ int CGameState::getMovementCost(const CGHeroInstance *h, int3 src, int3 dest, in
 	return ret;
 }
 
+int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
+{
+	int ret = 7; //allowed by default
+
+	//can we build it?
+	if(t->forbiddenBuildings.find(ID)!=t->forbiddenBuildings.end())
+		ret = 2; //forbidden
+	else if(t->builded >= MAX_BUILDING_PER_TURN)
+		ret = 5; //building limit
+
+	//checking resources
+	CBuilding * pom = VLC->buildh->buildings[t->subID][ID];
+	for(int res=0;res<7;res++) //TODO: support custom amount of resources
+	{
+		if(pom->resources[res] > players[t->tempOwner].resources[res])
+			ret = 6; //lack of res
+	}
+
+	//checking for requirements
+	for( std::set<int>::iterator ri  =  VLC->townh->requirements[t->subID][ID].begin();
+		ri != VLC->townh->requirements[t->subID][ID].end();
+		ri++ )
+	{
+		if(t->builtBuildings.find(*ri)==t->builtBuildings.end())
+			ret = 8; //lack of requirements - cannot build
+	}
+
+	if(ID == 13) //capitol
+	{
+		for(int in = 0; in < map->towns.size(); in++)
+		{
+			if(map->towns[in]->tempOwner==t->tempOwner  &&  vstd::contains(map->towns[in]->builtBuildings,13))
+			{
+				ret = 0; //no more than one capitol
+				break;
+			}
+		}
+	}
+	else if(ID == 6) //shipyard
+	{
+		if(map->getTile(t->pos + int3(-1,3,0)).tertype != water  &&  map->getTile(t->pos + int3(-3,3,0)).tertype != water)
+			ret = 1; //lack of water
+	}
+
+	return ret;
+}
+
 int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting)
 {
 	int attackerAttackBonus = attacker->creature->attack + (attackerHero ? attackerHero->getPrimSkillLevel(0) : 0);

+ 2 - 1
CGameState.h

@@ -241,7 +241,8 @@ private:
 	int battleGetBattlefieldType(int3 tile = int3());//   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
 	UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
 	float getMarketEfficiency(int player, int mode=0);
-	std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
+	std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious
+	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
 public:
 	CGameState();
 	~CGameState();

+ 13 - 1
CPlayerInterface.cpp

@@ -1818,10 +1818,22 @@ void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 
 	if (sEvent->type==SDL_KEYDOWN || sEvent->type==SDL_KEYUP)
 	{
+		SDL_KeyboardEvent key = sEvent->key;
+
+		//translate numpad keys
+		if (key.keysym.sym >= SDLK_KP0  && key.keysym.sym <= SDLK_KP9)
+		{
+			key.keysym.sym = (SDLKey) (key.keysym.sym - SDLK_KP0 + SDLK_0);
+		}
+		else if(key.keysym.sym == SDLK_KP_ENTER)
+		{
+			key.keysym.sym = (SDLKey)SDLK_RETURN;
+		}
+
 		std::list<KeyInterested*> miCopy = keyinterested;
 		for(std::list<KeyInterested*>::iterator i=miCopy.begin(); i != miCopy.end();i++)
 			if(vstd::contains(keyinterested,*i))
-				(**i).keyPressed(sEvent->key);
+				(**i).keyPressed(key);
 	}
 	else if(sEvent->type==SDL_MOUSEMOTION)
 	{

+ 3 - 11
server/CGameHandler.cpp

@@ -662,21 +662,13 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 					c >> tid >> bid;
 					CGTownInstance * t = static_cast<CGTownInstance*>(gs->map->objects[tid]);
 					CBuilding * b = VLC->buildh->buildings[t->subID][bid];
-					for(int i=0;i<RESOURCE_QUANTITY;i++)
-						if(b->resources[i] > gs->players[t->tempOwner].resources[i])
-							break; //no res
 
-					for( std::set<int>::iterator ri  =  VLC->townh->requirements[t->subID][bid].begin();
-						 ri != VLC->townh->requirements[t->subID][bid].end();
-						 ri++ )
+					if(gs->canBuildStructure(t,bid) != 7)
 					{
-						if(!vstd::contains(t->builtBuildings,*ri))
-							break; //lack of requirements - cannot build
+						sendMessageTo(c,"Cannot build that building!");
+						break;
 					}
 
-					if(vstd::contains(t->forbiddenBuildings,bid))
-						break; //this building is forbidden
-
 					NewStructures ns;
 					ns.tid = tid;
 					if(bid>36) //upg dwelling