Jelajahi Sumber

- fix for #283
- ally support: adventure map

Ivan Savenko 15 tahun lalu
induk
melakukan
fd45cd0a6d

+ 3 - 3
CCallback.cpp

@@ -184,7 +184,7 @@ bool CCallback::getTownInfo( const CGObjectInstance *town, InfoAboutTown &dest )
 
 	bool detailed = hasAccess(town->tempOwner);
 
-	//TODO vision support, info about allies
+	//TODO vision support
 	if(town->ID == TOWNI_TYPE)
 		dest.initFromTown(static_cast<const CGTownInstance *>(town), detailed);
 	else if(town->ID == 33 || town->ID == 219)
@@ -249,7 +249,7 @@ bool CCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest )
 	if(!h || !isVisible(h->getPosition(false))) //it's not a hero or it's not visible for layer
 		return false;
 	
-	//TODO vision support, info about allies
+	//TODO vision support
 	dest.initFromHero(h, hasAccess(h->tempOwner));
 	return true;
 }
@@ -956,7 +956,7 @@ void CCallback::castSpell(const CGHeroInstance *hero, int spellID, const int3 &p
 
 bool CCallback::hasAccess(int playerId) const
 {
-	return playerId == player  ||  player < 0;
+	return gs->getPlayerRelations( playerId, player ) ||  player < 0;
 }
 
 si8 CCallback::battleHasDistancePenalty( int stackID, int destHex )

+ 15 - 12
client/CAdvmapInterface.cpp

@@ -1771,14 +1771,17 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 		}
 		return;
 	}
+	//check if we can select this object
+	bool canSelect = topBlocking && topBlocking->ID == HEROI_TYPE && topBlocking->tempOwner == LOCPLINT->playerID;
+	canSelect |= topBlocking && topBlocking->ID == TOWNI_TYPE && CGI->state->getPlayerRelations(topBlocking->tempOwner, LOCPLINT->playerID);
 
 	if (selection->ID != HEROI_TYPE) //hero is not selected (presumably town)
 	{
 		assert(!terrain.currentPath); //path can be active only when hero is selected
 		if(selection == topBlocking) //selected town clicked
 			LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(topBlocking));
-		else if(topBlocking && (topBlocking->ID == TOWNI_TYPE || topBlocking->ID == HEROI_TYPE) && topBlocking->tempOwner == LOCPLINT->playerID) //our town/hero clicked
-			select(static_cast<const CArmedInstance*>(topBlocking), false);
+		else if ( canSelect )
+				select(static_cast<const CArmedInstance*>(topBlocking), false);
 		return;
 	}
 	else if(const CGHeroInstance * currentHero = curHero()) //hero is selected
@@ -1789,8 +1792,7 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
 			LOCPLINT->openHeroWindow(currentHero);
 			return;
 		}
-		else if(topBlocking && (topBlocking->ID == HEROI_TYPE || topBlocking->ID == TOWNI_TYPE) //clicked our town or hero
-			&& pn->turns == 255 && topBlocking->tempOwner == LOCPLINT->playerID) //at inaccessible tile
+		else if(canSelect && pn->turns == 255 ) //selectable object at inaccessible tile
 		{
 			select(static_cast<const CArmedInstance*>(topBlocking), false);
 			return;
@@ -1877,11 +1879,11 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 
 	if(selection->ID == TOWNI_TYPE)
 	{
-		if(objAtTile && objAtTile->tempOwner == LOCPLINT->playerID)
+		if(objAtTile)
 		{
-			if(objAtTile->ID == TOWNI_TYPE)
+			if(objAtTile->ID == TOWNI_TYPE && CGI->state->getPlayerRelations(objAtTile->tempOwner, LOCPLINT->playerID))
 				CGI->curh->changeGraphic(0, 3);
-			else if(objAtTile->ID == HEROI_TYPE)
+			else if(objAtTile->ID == HEROI_TYPE && objAtTile->tempOwner == LOCPLINT->playerID)
 				CGI->curh->changeGraphic(0, 2);
 		}
 		else
@@ -1893,14 +1895,14 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 		{
 			if(objAtTile->ID == HEROI_TYPE)
 			{
-				if(objAtTile->tempOwner != LOCPLINT->playerID) //enemy hero TODO: allies
+				if(!CGI->state->getPlayerRelations( objAtTile->tempOwner, LOCPLINT->playerID)) //enemy hero
 				{
 					if(accessible)
 						CGI->curh->changeGraphic(0, 5 + turns*6);
 					else
 						CGI->curh->changeGraphic(0, 0);
 				}
-				else //our hero
+				else //our or ally hero
 				{
 					if(selection == objAtTile)
 						CGI->curh->changeGraphic(0, 2);
@@ -1912,7 +1914,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 			}
 			else if(objAtTile->ID == TOWNI_TYPE)
 			{
-				if(objAtTile->tempOwner != LOCPLINT->playerID) //enemy town TODO: allies
+				if(!CGI->state->getPlayerRelations( objAtTile->tempOwner, LOCPLINT->playerID)) //enemy town
 				{
 					if(accessible) 
 					{
@@ -1930,7 +1932,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 						CGI->curh->changeGraphic(0, 0);
 					}
 				}
-				else //our town
+				else //our or ally town
 				{
 					if(accessible)
 						CGI->curh->changeGraphic(0, 9 + turns*6);
@@ -1952,7 +1954,8 @@ void CAdvMapInt::tileHovered(const int3 &tile)
 					const CGGarrison* garrObj = dynamic_cast<const CGGarrison*>(objAtTile); //TODO evil evil cast!
 
 					// Show battle cursor for guarded enemy garrisons, otherwise movement cursor.
-					if (garrObj  &&  garrObj->tempOwner != LOCPLINT->playerID  &&  garrObj->stacksCount())
+					if (garrObj&&  garrObj->stacksCount() 
+						&& !CGI->state->getPlayerRelations( garrObj->tempOwner, LOCPLINT->playerID) )
 						CGI->curh->changeGraphic(0, 5 + turns*6);
 					else
 						CGI->curh->changeGraphic(0, 9 + turns*6);

+ 1 - 1
client/CKingdomInterface.cpp

@@ -782,7 +782,7 @@ void CKingdomInterface::CHeroItem::setHero(const CGHeroInstance * newHero)
 	artLeft->block(hero->artifacts.size() <= 8);
 	artRight->block(hero->artifacts.size() <= 8);
 	garr = new CGarrisonInt(pos.x+6, pos.y+78, 4, Point(), parent->slots->ourImages[parent->PicCount].bitmap,
-		Point(6,78), hero, NULL, true, false, true);
+		Point(6,78), hero, NULL, true, true, true);
 
 	for (int i=0; i<artifacts.size(); i++)
 	{

+ 4 - 0
client/GUIClasses.cpp

@@ -1207,6 +1207,7 @@ void CList::fixPos()
 
 	amin(from, size() - SIZE);
 	amax(from, 0);
+	draw(screen);
 }
 
 CHeroList::CHeroList(int Size)
@@ -1270,6 +1271,8 @@ void CHeroList::select(int which)
 
 	selected = which;
 	adventureInt->select(LOCPLINT->wanderingHeroes[which]);
+	fixPos();
+	draw(screen);
 }
 
 void CHeroList::clickLeft(tribool down, bool previousState)
@@ -1551,6 +1554,7 @@ void CTownList::select(int which)
 	selected = which;
 	if(!fun.empty())
 		fun();
+	fixPos();
 }
 
 void CTownList::mouseMoved (const SDL_MouseMotionEvent & sEvent)

+ 6 - 6
hch/CObjectHandler.cpp

@@ -928,7 +928,7 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
 
 	if (ID == HEROI_TYPE) //hero
 	{
-		if( cb->getPlayerRelations(tempOwner, h->tempOwner)) //our or ally hero
+		if( cb->gameState()->getPlayerRelations(tempOwner, h->tempOwner)) //our or ally hero
 		{
 			//exchange
 			cb->heroExchange(h->id, id);
@@ -1664,7 +1664,7 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
 		return;
 	}
 
-	int relations = cb->getPlayerRelations( h->tempOwner, tempOwner );
+	int relations = cb->gameState()->getPlayerRelations( h->tempOwner, tempOwner );
 	
 	if ( relations == 1 )//ally
 		return;//do not allow recruiting or capturing
@@ -2047,7 +2047,7 @@ bool CGTownInstance::needsLastStack() const
 
 void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
 {
-	if( !cb->getPlayerRelations( getOwner(), h->getOwner() ))//if this is enemy
+	if( !cb->gameState()->getPlayerRelations( getOwner(), h->getOwner() ))//if this is enemy
 	{
 		if(stacksCount() > 0 || visitingHero)
 		{
@@ -3118,7 +3118,7 @@ void CGCreature::flee( const CGHeroInstance * h ) const
 
 void CGMine::onHeroVisit( const CGHeroInstance * h ) const
 {
-	int relations = cb->getPlayerRelations(h->tempOwner, tempOwner);
+	int relations = cb->gameState()->getPlayerRelations(h->tempOwner, tempOwner);
 	
 	if(relations == 2) //we're visiting our mine
 	{
@@ -5260,7 +5260,7 @@ void CGScholar::initObj()
 
 void CGGarrison::onHeroVisit (const CGHeroInstance *h) const
 {
-	int ally = cb->getPlayerRelations(h->tempOwner, tempOwner);
+	int ally = cb->gameState()->getPlayerRelations(h->tempOwner, tempOwner);
 	if (!ally && stacksCount() > 0) {
 		//TODO: Find a way to apply magic garrison effects in battle.
 		cb->startBattleI(h, this, boost::bind(&CGGarrison::fightOver, this, h, _1));
@@ -6279,7 +6279,7 @@ void CGShipyard::getOutOffsets( std::vector<int3> &offsets ) const
 
 void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const
 {
-	if(!cb->getPlayerRelations(tempOwner, h->tempOwner))
+	if(!cb->gameState()->getPlayerRelations(tempOwner, h->tempOwner))
 		cb->setOwner(id, h->tempOwner);
 
 	int s = state();

+ 10 - 0
lib/CGameState.cpp

@@ -2008,6 +2008,16 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
 	return ret;
 }
 
+int CGameState::getPlayerRelations( ui8 color1, ui8 color2 )
+{
+	if ( color1 == color2 )
+		return 2;
+	const TeamState * ts = getPlayerTeam(color1);
+	if (ts && vstd::contains(ts->players, color2))
+		return 1;
+	return 0;
+}
+
 void CGameState::loadTownDInfos()
 {
 	for(int i=0;i<F_NUMBER;i++)

+ 1 - 0
lib/CGameState.h

@@ -428,6 +428,7 @@ public:
 	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 CStackInstance &stack);
+	int getPlayerRelations(ui8 color1, ui8 color2);// 0 = enemy, 1 = ally, 2 = same player
 	//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

+ 0 - 12
lib/IGameCallback.cpp

@@ -239,18 +239,6 @@ const PlayerState * IGameCallback::getPlayerState( int color )
 	return gs->getPlayer(color, false);
 }
 
-int IGameCallback::getPlayerRelations( ui8 color1, ui8 color2 )
-{
-	if ( color1 == color2 )
-		return 2;
-	if ( color1 == 255 || color2 == 255)
-		return 0;
-	const TeamState * ts = gs->getPlayerTeam(color1);
-	if (ts && vstd::contains(ts->players, color2))
-		return 1;
-	return 0;
-}
-
 const CTown * IGameCallback::getNativeTown(int color)
 {
 	return &VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(color).castle];

+ 0 - 1
lib/IGameCallback.h

@@ -68,7 +68,6 @@ public:
 	virtual int3 getMapSize(); //returns size of the map
 	virtual TerrainTile * getTile(int3 pos);
 	virtual const PlayerState * getPlayerState(int color);
-	virtual int getPlayerRelations(ui8 color1, ui8 color2);// -1 = enemy, 0 = neutral, 1 = ally, 2 = same player
 	virtual const CTown *getNativeTown(int color);
 
 	//do sth

+ 3 - 3
server/CGameHandler.cpp

@@ -1888,7 +1888,7 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
 			{
 				CGHeroInstance *dh = static_cast<CGHeroInstance *>(obj);
 
-				if( getPlayerRelations(dh->tempOwner, h->tempOwner)) 
+				if( gameState()->getPlayerRelations(dh->tempOwner, h->tempOwner)) 
 				{
 					heroExchange(h->id, dh->id);
 					return true;
@@ -2355,7 +2355,7 @@ void CGameHandler::heroExchange(si32 hero1, si32 hero2)
 	ui8 player1 = getHero(hero1)->tempOwner;
 	ui8 player2 = getHero(hero2)->tempOwner;
 
-	if( getPlayerRelations( player1, player2))
+	if( gameState()->getPlayerRelations( player1, player2))
 	{
 		OpenWindow hex;
 		hex.window = OpenWindow::EXCHANGE_WINDOW;
@@ -4553,7 +4553,7 @@ void CGameHandler::checkLossVictory( ui8 player )
 				sendAndApply(&iw);
 
 				peg.player = i->first;
-				peg.victory = getPlayerRelations(player, i->first) == 1; // ally of winner
+				peg.victory = gameState()->getPlayerRelations(player, i->first) == 1; // ally of winner
 				sendAndApply(&peg);
 			}
 		}