فهرست منبع

- University fix for #594
- Ally support:
- - fix for non-continuous players (notes to rev 1736)
- - objects visiting and shared puzzle map

Ivan Savenko 15 سال پیش
والد
کامیت
bdcdc89991
8فایلهای تغییر یافته به همراه76 افزوده شده و 39 حذف شده
  1. 1 1
      CCallback.cpp
  2. 11 9
      client/GUIClasses.cpp
  3. 1 3
      client/GUIClasses.h
  4. 58 23
      hch/CObjectHandler.cpp
  5. 1 1
      hch/CObjectHandler.h
  6. 2 1
      lib/CGameState.cpp
  7. 1 0
      lib/CGameState.h
  8. 1 1
      server/CGameHandler.cpp

+ 1 - 1
CCallback.cpp

@@ -923,7 +923,7 @@ int3 CCallback::getGrailPos( float &outKnownRatio )
 	}
 	else
 	{
-		outKnownRatio = (float)CGObelisk::visited[player] / CGObelisk::obeliskCount;
+		outKnownRatio = (float)CGObelisk::visited[gs->getPlayerTeam(player)->id] / CGObelisk::obeliskCount;
 	}
 	return gs->map->grailPos;
 }

+ 11 - 9
client/GUIClasses.cpp

@@ -5978,7 +5978,7 @@ int CUniversityWindow::CItem::state()
 
 void CUniversityWindow::CItem::showAll(SDL_Surface * to)
 {
-	SDL_Surface * bar;
+	CPicture * bar;
 	switch (state())
 	{
 		case 0: bar = parent->red;
@@ -5989,8 +5989,8 @@ void CUniversityWindow::CItem::showAll(SDL_Surface * to)
 		        break;
 	}
 	
-	blitAtLoc(bar, -28, -22, to);
-	blitAtLoc(bar, -28,  48, to);
+	blitAtLoc(bar->bg, -28, -22, to);
+	blitAtLoc(bar->bg, -28,  48, to);
 	printAtMiddleLoc  (CGI->generaltexth->skillName[ID], 22, -13, FONT_SMALL, zwykly,to);//Name
 	printAtMiddleLoc  (CGI->generaltexth->levels[0], 22, 57, FONT_SMALL, zwykly,to);//Level(always basic)
 	
@@ -6009,9 +6009,13 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
 	bg = new CPicture("UNIVERS1.PCX");
 	bg->colorizeAndConvert(LOCPLINT->playerID);
 	
-	yellow = BitmapHandler::loadBitmap("UNIVGOLD.PCX");
-	green  = BitmapHandler::loadBitmap("UNIVGREN.PCX");//bars
-	red    = BitmapHandler::loadBitmap("UNIVRED.PCX");
+	green  = new CPicture("UNIVGREN.PCX");
+	yellow = new CPicture("UNIVGOLD.PCX");//bars
+	red    = new CPicture("UNIVRED.PCX");
+
+	green->recActions  =
+	yellow->recActions =
+	red->recActions    = DISPOSE;
 
 	if ( market->o->ID == 104 ) // this is adventure map university
 	{
@@ -6045,9 +6049,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
 
 CUniversityWindow::~CUniversityWindow()
 {
-	delete red;
-	delete yellow;
-	delete green;
+	
 }
 
 CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * PARENT, int SKILL, bool available ):parent(PARENT)

+ 1 - 3
client/GUIClasses.h

@@ -1103,9 +1103,7 @@ public:
 	const CGHeroInstance *hero;
 	const IMarket * market;
 	
-	SDL_Surface * red, 
-	            * green,//colored bars near skills
-	            * yellow;
+	CPicture * green, * yellow, * red;//colored bars near skills
 	CPicture *bg; //background
 	std::vector<CItem*> items;
 

+ 58 - 23
hch/CObjectHandler.cpp

@@ -437,13 +437,18 @@ void CGObjectInstance::hideTiles(int ourplayer, int radius) const
 {
 	for (std::map<ui8, TeamState>::iterator i = cb->gameState()->teams.begin(); i != cb->gameState()->teams.end(); i++)
 	{
-		if ( !vstd::contains(i->second.players, ourplayer )/* && i->second.status == PlayerState::INGAME*/)
+		if ( !vstd::contains(i->second.players, ourplayer ))//another team
 		{
-			FoWChange fw;
-			fw.mode = 0;
-			fw.player = i->first;
-			cb->getTilesInRange (fw.tiles, pos, radius, i->first, -1);
-			cb->sendAndApply (&fw);
+			for (std::set<ui8>::iterator j = i->second.players.begin(); j != i->second.players.end(); j++)
+				if ( cb->getPlayerState(*j)->status == PlayerState::INGAME )//seek for living player (if any)
+				{
+					FoWChange fw;
+					fw.mode = 0;
+					fw.player = i->first;
+					cb->getTilesInRange (fw.tiles, pos, radius, (*j), -1);
+					cb->sendAndApply (&fw);
+					break;
+				}
 		}
 	}
 }
@@ -1659,7 +1664,12 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
 		return;
 	}
 
-	if(h->tempOwner != tempOwner  &&  stacksCount() > 0) //object is guarded
+	int relations = cb->getPlayerRelations( h->tempOwner, tempOwner );
+	
+	if ( relations == 1 )//ally
+		return;//do not allow recruiting or capturing
+		
+	if( !relations  &&  stacksCount() > 0) //object is guarded, owned by enemy
 	{
 		BlockingDialog bd;
 		bd.player = h->tempOwner;
@@ -1672,7 +1682,7 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
 		return;
 	}
 
-	if(h->tempOwner != tempOwner  &&  ID != 106)
+	if(!relations  &&  ID != 106)
 	{
 		cb->setOwner(id, h->tempOwner);
 	}
@@ -2037,9 +2047,8 @@ bool CGTownInstance::needsLastStack() const
 
 void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
 {
-	if(getOwner() != h->getOwner())
+	if( !cb->getPlayerRelations( getOwner(), h->getOwner() ))//if this is enemy
 	{
-		//TODO ally check
 		if(stacksCount() > 0 || visitingHero)
 		{
 			const CGHeroInstance *defendingHero = NULL;
@@ -2188,7 +2197,17 @@ int3 CGTownInstance::getSightCenter() const
 
 ui8 CGTownInstance::getPassableness() const
 {
-	return stacksCount() ? 1<<tempOwner : ALL_PLAYERS; //if there is garrison army, castle be entered only by owner //TODO: allies
+	if ( !stacksCount() )//empty castle - anyone can visit
+		return ALL_PLAYERS;
+	if ( tempOwner == 255 )//neutral guarded - noone can visit
+		return 0;
+		
+	ui8 mask;
+	TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
+	BOOST_FOREACH(ui8 it, ts->players)
+		mask |= 1<<it;//allies - add to possible visitors
+	
+	return mask;
 }
 
 void CGTownInstance::getOutOffsets( std::vector<int3> &offsets ) const
@@ -3099,23 +3118,25 @@ void CGCreature::flee( const CGHeroInstance * h ) const
 
 void CGMine::onHeroVisit( const CGHeroInstance * h ) const
 {
-	if(h->tempOwner == tempOwner) //we're visiting our mine
+	int relations = cb->getPlayerRelations(h->tempOwner, tempOwner);
+	
+	if(relations == 2) //we're visiting our mine
 	{
 		cb->showGarrisonDialog(id,h->id,true,0);
 		return; 
 	}
+	else if (relations == 1)//ally
+		return;
 
-	if(subID >= 7) //Abandoned mine
+	if(stacksCount()) //Mine is guarded
 	{
 		BlockingDialog ynd(true,false);
 		ynd.player = h->tempOwner;
-		ynd.text << std::pair<ui8,ui32>(MetaString::ADVOB_TXT, 84); 
+		ynd.text << std::pair<ui8,ui32>(MetaString::ADVOB_TXT, subID == 7 ? 84 : 187); 
 		cb->showBlockingDialog(&ynd,boost::bind(&CGMine::fight, this, _1, h));
 		return;
 	}
 
-	//TODO: check if mine is guarded
-
 	flagMine(h->tempOwner);
 
 }
@@ -5239,14 +5260,15 @@ void CGScholar::initObj()
 
 void CGGarrison::onHeroVisit (const CGHeroInstance *h) const
 {
-	if (h->tempOwner != tempOwner && stacksCount() > 0) {
+	int ally = cb->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));
 		return;
 	}
 
 	//New owner.
-	if (h->tempOwner != tempOwner)
+	if (!ally)
 		cb->setOwner(id, h->tempOwner);
 
 	cb->showGarrisonDialog(id, h->id, removableUnits, 0);
@@ -5260,7 +5282,17 @@ void CGGarrison::fightOver (const CGHeroInstance *h, BattleResult *result) const
 
 ui8 CGGarrison::getPassableness() const
 {
-	return 1<<tempOwner;
+	if ( !stacksCount() )//empty - anyone can visit
+		return ALL_PLAYERS;
+	if ( tempOwner == 255 )//neutral guarded - noone can visit
+		return 0;
+		
+	ui8 mask;
+	TeamState * ts = cb->gameState()->getPlayerTeam(tempOwner);
+	BOOST_FOREACH(ui8 it, ts->players)
+		mask |= 1<<it;//allies - add to possible visitors
+	
+	return mask;
 }
 
 void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
@@ -6247,7 +6279,7 @@ void CGShipyard::getOutOffsets( std::vector<int3> &offsets ) const
 
 void CGShipyard::onHeroVisit( const CGHeroInstance * h ) const
 {
-	if(tempOwner != h->tempOwner)
+	if(!cb->getPlayerRelations(tempOwner, h->tempOwner))
 		cb->setOwner(id, h->tempOwner);
 
 	int s = state();
@@ -6341,20 +6373,23 @@ void CGObelisk::onHeroVisit( const CGHeroInstance * h ) const
 {
 	InfoWindow iw;
 	iw.player = h->tempOwner;
+	TeamState *ts = cb->gameState()->getPlayerTeam(h->tempOwner);
+	assert(ts);
+	int team = ts->id;
 	
-	if(!hasVisited(h->tempOwner))
+	if(!hasVisited(team))
 	{
 		iw.text.addTxt(MetaString::ADVOB_TXT, 96);
 		cb->sendAndApply(&iw);
 
-		cb->setObjProperty(id,20,h->tempOwner); //increment general visited obelisks counter
+		cb->setObjProperty(id,20,team); //increment general visited obelisks counter
 
 		OpenWindow ow;
 		ow.id1 = h->tempOwner;
 		ow.window = OpenWindow::PUZZLE_MAP;
 		cb->sendAndApply(&ow);
 
-		cb->setObjProperty(id,10,h->tempOwner); //mark that particular obelisk as visited
+		cb->setObjProperty(id,10,team); //mark that particular obelisk as visited
 	}
 	else
 	{

+ 1 - 1
hch/CObjectHandler.h

@@ -1112,7 +1112,7 @@ class DLL_EXPORT CGObelisk : public CPlayersVisited
 {
 public:
 	static ui8 obeliskCount; //how many obelisks are on map
-	static std::map<ui8, ui8> visited; //map: color_id => how many obelisks has been visited
+	static std::map<ui8, ui8> visited; //map: team_id => how many obelisks has been visited
 
 	void setPropertyDer (ui8 what, ui32 val);
 	void onHeroVisit(const CGHeroInstance * h) const;

+ 2 - 1
lib/CGameState.cpp

@@ -1395,7 +1395,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
 		ins.second.color=ins.first;
 		ins.second.human = it->second.human;
 		ins.second.team = map->players[ins.first].team;
-		teams[ins.second.team].players.insert(ins.first);
+		teams[ins.second.team].id = ins.second.team;//init team
+		teams[ins.second.team].players.insert(ins.first);//add player to team
 		players.insert(ins);
 	}
 

+ 1 - 0
lib/CGameState.h

@@ -151,6 +151,7 @@ public:
 struct DLL_EXPORT TeamState : public CBonusSystemNode
 {
 public:
+	ui8 id; //position in gameState::teams
 	std::set<ui8> players; // members of this team
 	std::vector<std::vector<std::vector<ui8> > >  fogOfWarMap; //true - visible, false - hidden
 	

+ 1 - 1
server/CGameHandler.cpp

@@ -3361,7 +3361,7 @@ bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance
 	const CStackInstance &s = army->getStack(slot);
 	int resCreature;//resulting creature - bone dragons or skeletons
 	
-	if	(s.hasBonusOfType(Bonus::KING1))
+	if	(s.hasBonusOfType(Bonus::DRAGON_NATURE))
 		resCreature = 68;
 	else
 		resCreature = 56;