Beispiel #1
0
void CClient::initPlayerInterfaces()
{
	for(auto & elem : gs->scenarioOps->playerInfos)
	{
		PlayerColor color = elem.first;
		if(!vstd::contains(CSH->getAllClientPlayers(CSH->c->connectionID), color))
			continue;

		if(vstd::contains(playerint, color))
			continue;

		logNetwork->trace("Preparing interface for player %s", color.getStr());
		if(elem.second.isControlledByAI())
		{
			auto AiToGive = aiNameForPlayer(elem.second, false);
			logNetwork->info("Player %s will be lead by %s", color, AiToGive);
			installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), color);
		}
		else
		{
			installNewPlayerInterface(std::make_shared<CPlayerInterface>(color), color);
		}
	}

	if(settings["session"]["spectate"].Bool())
	{
		installNewPlayerInterface(std::make_shared<CPlayerInterface>(PlayerColor::SPECTATOR), PlayerColor::SPECTATOR, true);
	}

	if(CSH->getAllClientPlayers(CSH->c->connectionID).count(PlayerColor::NEUTRAL))
		installNewBattleInterface(CDynLibHandler::getNewBattleAI(settings["server"]["neutralAI"].String()), PlayerColor::NEUTRAL);

	logNetwork->trace("Initialized player interfaces %d ms", CSH->th->getDiff());
}
Beispiel #2
0
const SDL_Color & CMinimapInstance::getTileColor(const int3 & pos)
{
    static const SDL_Color fogOfWar = {0, 0, 0, 255};

    const TerrainTile * tile = LOCPLINT->cb->getTile(pos, false);

    // if tile is not visible it will be black on minimap
    if(!tile)
        return fogOfWar;

    // if object at tile is owned - it will be colored as its owner
    for(const CGObjectInstance *obj : tile->blockingObjects)
    {
        //heroes will be blitted later
        if (obj->ID == Obj::HERO)
            continue;

        PlayerColor player = obj->getOwner();
        if(player == PlayerColor::NEUTRAL)
            return *graphics->neutralColor;
        else if (player < PlayerColor::PLAYER_LIMIT)
            return graphics->playerColors[player.getNum()];
    }

    // else - use terrain color (blocked version or normal)
    if (tile->blocked && (!tile->visitable))
        return parent->colors.find(tile->terType)->second.second;
    else
        return parent->colors.find(tile->terType)->second.first;
}
Beispiel #3
0
PlayerColor CMapGenOptions::getNextPlayerColor() const
{
	for(PlayerColor i = PlayerColor(0); i < PlayerColor::PLAYER_LIMIT; i.advance(1))
	{
		if(!players.count(i))
		{
			return i;
		}
	}
	logGlobal->error("Failed to get next player color");
	assert(false);
	return PlayerColor(0);
}
Beispiel #4
0
void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
{
	if(sur->format->palette)
	{
		SDL_Color *palette = nullptr;
		if(player < PlayerColor::PLAYER_LIMIT)
		{
			palette = playerColorPalette + 32*player.getNum();
		}
		else if(player == PlayerColor::NEUTRAL)
		{
			palette = neutralColorPalette;
		}
		else
		{
			logGlobal->errorStream() << "Wrong player id in blueToPlayersAdv (" << player << ")!";
			return;
		}
		SDL_SetColors(sur, palette, 224, 32);
	}
	else
	{
		//TODO: implement. H3 method works only for images with palettes.
		// Add some kind of player-colored overlay?
		// Or keep palette approach here and replace only colors of specific value(s)
		// Or just wait for OpenGL support?
		logGlobal->warnStream() << "Image must have palette to be player-colored!";
	}
}
Beispiel #5
0
void CQuery::addPlayer(PlayerColor color)
{
	if(color.isValidPlayer())
	{
		players.push_back(color);
	}
}
Beispiel #6
0
TeamID LobbyInfo::getPlayerTeamId(PlayerColor color)
{
	if(color < PlayerColor::PLAYER_LIMIT)
		return getPlayerInfo(color.getNum()).team;
	else
		return TeamID::NO_TEAM;
}
Beispiel #7
0
void CSDL_Ext::setPlayerColor(SDL_Surface * sur, PlayerColor player)
{
	if(player==PlayerColor::UNFLAGGABLE)
		return;
	if(sur->format->BitsPerPixel==8)
	{
		SDL_Color *color = (player == PlayerColor::NEUTRAL
							? graphics->neutralColor
							: &graphics->playerColors[player.getNum()]);
		SDL_SetColors(sur, color, 5, 1);
	}
	else
        logGlobal->warnStream() << "Warning, setPlayerColor called on not 8bpp surface!";
}
Beispiel #8
0
void CompImage::playerColored(PlayerColor player)
{
	SDL_Color *pal = nullptr;
	if(player < PlayerColor::PLAYER_LIMIT)
	{
		pal = graphics->playerColorPalette + 32*player.getNum();
	}
	else if(player == PlayerColor::NEUTRAL)
	{
		pal = graphics->neutralColorPalette;
	}
	else
		assert(0);

	for(int i=0; i<32; ++i)
	{
		CSDL_Ext::colorAssign(palette[224+i],pal[i]);
	}
}
Beispiel #9
0
void CInfoBar::CVisibleInfo::loadEnemyTurn(PlayerColor player)
{
    assert(children.empty()); // visible info should be re-created to change type

    OBJ_CONSTRUCTION_CAPTURING_ALL;
    new CPicture("ADSTATNX");
    new CAnimImage("CREST58", player.getNum(), 0, 20, 51);
    new CShowableAnim(99, 51, "HOURSAND");

    // FIXME: currently there is no way to get progress from VCAI
    // if this will change at some point switch this ifdef to enable correct code
#if 0
    //prepare hourglass for updating AI turn
    aiProgress = new CAnimImage("HOURGLAS", 0, 0, 99, 51);
    forceRefresh.push_back(aiProgress);
#else
    //create hourglass that will be always animated ignoring AI status
    new CShowableAnim(99, 51, "HOURGLAS", CShowableAnim::PLAY_ONCE, 40);
#endif
}
void CompImage::playerColored(PlayerColor player)
{
	SDL_Color *pal = nullptr;
	if(player < PlayerColor::PLAYER_LIMIT)
	{
		pal = graphics->playerColorPalette + 32*player.getNum();
	}
	else if(player == PlayerColor::NEUTRAL)
	{
		pal = graphics->neutralColorPalette;
	}
	else
		assert(0);

	for(int i=0; i<32; ++i)
	{
		palette[224+i].r = pal[i].r;
		palette[224+i].g = pal[i].g;
		palette[224+i].b = pal[i].b;
		palette[224+i].unused = pal[i].unused;
	}
}
	void MessageOverlordConnection::sendPlayerColor(PlayerColor playerColor)
	{
		string jsonMessage = "{\"playerColor\": \"" + playerColor.toHexString() +"\"}";
		messageInterface.sendMessage(jsonMessage);
	}
Beispiel #12
0
// Update map window screen
// top_tile top left tile to draw. Not necessarily visible.
// extRect, extRect = map window on screen
// moveX, moveY: when a hero is in movement indicates how to shift the map. Range is -31 to + 31.
void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std::vector< std::vector<ui8> > > * visibilityMap, bool otherHeroAnim, ui8 heroAnim, SDL_Surface * extSurf, const SDL_Rect * extRect, int moveX, int moveY, bool puzzleMode, int3 grailPosRel ) const
{
	// Width and height of the portion of the map to process. Units in tiles.
	ui32 dx = tilesW;
	ui32 dy = tilesH;

	// Basic rectangle for a tile. Should be a const but conflicts with SDL headers
	SDL_Rect rtile = { 0, 0, 32, 32 };

	// Absolute coords of the first pixel in the top left corner
	int srx_init = offsetX + extRect->x;
	int sry_init = offsetY + extRect->y;

	int srx, sry;	// absolute screen coordinates in pixels

	// If moving, we need to add an extra column/line
	if (moveX != 0) 
	{
		dx++;
		srx_init += moveX;
		if (moveX > 0) 
		{
			// Moving right. We still need to draw the old tile on the
			// left, so adjust our referential
			top_tile.x --;
			srx_init -= 32;
		}
	}

	if (moveY != 0) 
	{
		dy++;
		sry_init += moveY;
		if (moveY > 0) 
		{
			// Moving down. We still need to draw the tile on the top,
			// so adjust our referential.
			top_tile.y --;
			sry_init -= 32;
		}
	}

	// Reduce sizes if we go out of the full map.
	if (top_tile.x < -frameW)
		top_tile.x = -frameW;
	if (top_tile.y < -frameH)
		top_tile.y = -frameH;
	if (top_tile.x + dx > sizes.x + frameW)
		dx = sizes.x + frameW - top_tile.x;
	if (top_tile.y + dy > sizes.y + frameH)
		dy = sizes.y + frameH - top_tile.y;
	
	if(!otherHeroAnim)
		heroAnim = anim; //the same, as it should be

	SDL_Rect prevClip;
	SDL_GetClipRect(extSurf, &prevClip);
	SDL_SetClipRect(extSurf, extRect); //preventing blitting outside of that rect

	const BlitterWithRotationVal blitterWithRotation = CSDL_Ext::getBlitterWithRotation(extSurf);
	const BlitterWithRotationVal blitterWithRotationAndAlpha = CSDL_Ext::getBlitterWithRotationAndAlpha(extSurf);
	//const BlitterWithRotationAndAlphaVal blitterWithRotation = CSDL_Ext::getBlitterWithRotation(extSurf);

	// printing terrain
	srx = srx_init;

	for (int bx = 0; bx < dx; bx++, srx+=32)
	{
		// Skip column if not in map
		if (top_tile.x+bx < 0 || top_tile.x+bx >= sizes.x)
			continue;

		sry = sry_init;

		for (int by=0; by < dy; by++, sry+=32)
		{
			int3 pos(top_tile.x+bx, top_tile.y+by, top_tile.z); //blitted tile position

			// Skip tile if not in map
			if (pos.y < 0 || pos.y >= sizes.y)
				continue;

			const TerrainTile2 & tile = ttiles[pos.x][pos.y][pos.z];
			const TerrainTile &tinfo = map->getTile(int3(pos.x, pos.y, pos.z));

			SDL_Rect sr;
			sr.x=srx;
			sr.y=sry;
			sr.h=sr.w=32;

			//blit terrain with river/road
			if(tile.terbitmap)
			{ //if custom terrain graphic - use it
				SDL_Rect temp_rect = genRect(sr.h, sr.w, 0, 0);
				CSDL_Ext::blitSurface(tile.terbitmap, &temp_rect, extSurf, &sr);
			}
			else //use default terrain graphic
			{
                blitterWithRotation(terrainGraphics[tinfo.terType][tinfo.terView],rtile, extSurf, sr, tinfo.extTileFlags%4);
			}
            if(tinfo.riverType) //print river if present
			{
                blitterWithRotationAndAlpha(staticRiverDefs[tinfo.riverType-1]->ourImages[tinfo.riverDir].bitmap,rtile, extSurf, sr, (tinfo.extTileFlags>>2)%4);
			}

			//Roads are shifted by 16 pixels to bottom. We have to draw both parts separately
			if (pos.y > 0 && map->getTile(int3(pos.x, pos.y-1, pos.z)).roadType != ERoadType::NO_ROAD)
			{ //part from top tile
				const TerrainTile &topTile = map->getTile(int3(pos.x, pos.y-1, pos.z));
				Rect source(0, 16, 32, 16);
				Rect dest(sr.x, sr.y, sr.w, sr.h/2);
                blitterWithRotationAndAlpha(roadDefs[topTile.roadType - 1]->ourImages[topTile.roadDir].bitmap, source, extSurf, dest, (topTile.extTileFlags>>4)%4);
			}

            if(tinfo.roadType != ERoadType::NO_ROAD) //print road from this tile
			{
				Rect source(0, 0, 32, 32);
				Rect dest(sr.x, sr.y+16, sr.w, sr.h/2);
                blitterWithRotationAndAlpha(roadDefs[tinfo.roadType-1]->ourImages[tinfo.roadDir].bitmap, source, extSurf, dest, (tinfo.extTileFlags>>4)%4);
			}

			//blit objects
			const std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > &objects = tile.objects;
			for(int h=0; h < objects.size(); ++h)
			{
				const CGObjectInstance *obj = objects[h].first;
				if (!graphics->getDef(obj))
					processDef(obj->defInfo);

				PlayerColor color = obj->tempOwner;

				//checking if object has non-empty graphic on this tile
				if(obj->ID != Obj::HERO && !obj->coveringAt(top_tile.x + bx - obj->pos.x, top_tile.y + by - obj->pos.y))
					continue;

				static const int notBlittedInPuzzleMode[] = {124};

				//don't print flaggable objects in puzzle mode
				if(puzzleMode && (obj->isVisitable() || std::find(notBlittedInPuzzleMode, notBlittedInPuzzleMode+1, obj->ID) != notBlittedInPuzzleMode+1)) //?
					continue;

 				SDL_Rect sr2(sr); 

				SDL_Rect pp = objects[h].second;
				pp.h = sr.h;
				pp.w = sr.w;

				const CGHeroInstance * themp = (obj->ID != Obj::HERO
					? NULL  
					: static_cast<const CGHeroInstance*>(obj));

				//print hero / boat and flag
				if((themp && themp->moveDir && themp->type) || (obj->ID == Obj::BOAT)) //it's hero or boat
				{
					const int IMGVAL = 8; //frames per group of movement animation
					ui8 dir;
					std::vector<Cimage> * iv = NULL;
					std::vector<CDefEssential *> Graphics::*flg = NULL;
					SDL_Surface * tb = nullptr; //surface to blitted

					if(themp) //hero
					{
						if(themp->tempOwner >= PlayerColor::PLAYER_LIMIT) //Neutral hero?
						{
                            logGlobal->errorStream() << "A neutral hero (" << themp->name << ") at " << themp->pos << ". Should not happen!";
							continue;
						}

						dir = themp->moveDir;

						//pick graphics of hero (or boat if hero is sailing)
						if (themp->boat)
							iv = &graphics->boatAnims[themp->boat->subID]->ourImages;
						else if (themp->sex)
							iv = &graphics->heroAnims[themp->type->heroClass->imageMapFemale]->ourImages;
						else
							iv = &graphics->heroAnims[themp->type->heroClass->imageMapMale]->ourImages;

						//pick appropriate flag set
						if(themp->boat)
						{
							switch (themp->boat->subID)
							{
							case 0: flg = &Graphics::flags1; break;
							case 1: flg = &Graphics::flags2; break;
							case 2: flg = &Graphics::flags3; break;
                            default: logGlobal->errorStream() << "Not supported boat subtype: " << themp->boat->subID;
							}
						}
						else
						{
							flg = &Graphics::flags4;
						}
					}
					else //boat
					{
						const CGBoat *boat = static_cast<const CGBoat*>(obj);
						dir = boat->direction;
						iv = &graphics->boatAnims[boat->subID]->ourImages;
					}


					if(themp && !themp->isStanding) //hero is moving
					{
						size_t gg;
						for(gg=0; gg<iv->size(); ++gg)
						{
							if((*iv)[gg].groupNumber==getHeroFrameNum(dir, true))
							{
								tb = (*iv)[gg+heroAnim%IMGVAL].bitmap;
								break;
							}
						}
						CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr2);

						//printing flag
						pp.y+=IMGVAL*2-32;
						sr2.y-=16;
						CSDL_Ext::blitSurface((graphics->*flg)[color.getNum()]->ourImages[gg+heroAnim%IMGVAL+35].bitmap, &pp, extSurf, &sr2);
					}
					else //hero / boat stands still
					{
						size_t gg;
						for(gg=0; gg < iv->size(); ++gg)
						{
							if((*iv)[gg].groupNumber==getHeroFrameNum(dir, false))
							{
								tb = (*iv)[gg].bitmap;
								break;
							}
						}
						CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr2);

						//printing flag
						if(flg  
							&&  obj->pos.x == top_tile.x + bx  
							&&  obj->pos.y == top_tile.y + by)
						{
							SDL_Rect bufr = sr2;
							bufr.x-=2*32;
							bufr.y-=1*32;
							bufr.h = 64;
							bufr.w = 96;
							if(bufr.x-extRect->x>-64)
								CSDL_Ext::blitSurface((graphics->*flg)[color.getNum()]->ourImages[getHeroFrameNum(dir, false) *8+(heroAnim/4)%IMGVAL].bitmap, NULL, extSurf, &bufr);
						}
					}
				}
				else //blit normal object
				{
					const std::vector<Cimage> &ourImages = graphics->getDef(obj)->ourImages;
					SDL_Surface *bitmap = ourImages[(anim+getPhaseShift(obj))%ourImages.size()].bitmap;

					//setting appropriate flag color
					if(color < PlayerColor::PLAYER_LIMIT || color==PlayerColor::NEUTRAL)
						CSDL_Ext::setPlayerColor(bitmap, color);

					if( obj->hasShadowAt(top_tile.x + bx - obj->pos.x, top_tile.y + by - obj->pos.y) )
						CSDL_Ext::blit8bppAlphaTo24bpp(bitmap,&pp,extSurf,&sr2);
					else
						CSDL_Ext::blitSurface(bitmap,&pp,extSurf,&sr2);
				}
			}
			//objects blitted

			//X sign
			if(puzzleMode)
			{
				if(bx == grailPosRel.x && by == grailPosRel.y)
				{
					CSDL_Ext::blit8bppAlphaTo24bpp(graphics->heroMoveArrows->ourImages[0].bitmap, NULL, extSurf, &sr);
				}
			}
		}
Beispiel #13
0
void CMessage::drawBorder(PlayerColor playerColor, SDL_Surface * ret, int w, int h, int x, int y)
{	
	std::vector<SDL_Surface *> &box = piecesOfBox[playerColor.getNum()];

	// Note: this code assumes that the corner dimensions are all the same.

	// Horizontal borders
	int start_x = x + box[0]->w;
	const int stop_x = x + w - box[1]->w;
	const int bottom_y = y+h-box[7]->h+1;
	while (start_x < stop_x) {
		int cur_w = stop_x - start_x;
		if (cur_w > box[6]->w)
			cur_w = box[6]->w;

		// Top border
		Rect srcR(0, 0, cur_w, box[6]->h);
		Rect dstR(start_x, y, 0, 0);
		CSDL_Ext::blitSurface(box[6], &srcR, ret, &dstR);
		
		// Bottom border
		dstR.y = bottom_y;
		CSDL_Ext::blitSurface(box[7], &srcR, ret, &dstR);

		start_x += cur_w;
	}

	// Vertical borders
	int start_y = y + box[0]->h;
	const int stop_y = y + h - box[2]->h+1;
	const int right_x = x+w-box[5]->w;
	while (start_y < stop_y) {
		int cur_h = stop_y - start_y;
		if (cur_h > box[4]->h)
			cur_h = box[4]->h;

		// Left border
		Rect srcR(0, 0, box[4]->w, cur_h);
		Rect dstR(x, start_y, 0, 0);
		CSDL_Ext::blitSurface(box[4], &srcR, ret, &dstR);

		// Right border
		dstR.x = right_x;
		CSDL_Ext::blitSurface(box[5], &srcR, ret, &dstR);

		start_y += cur_h;
	}

	//corners
	Rect dstR(x, y, box[0]->w, box[0]->h);
	CSDL_Ext::blitSurface(box[0], nullptr, ret, &dstR);

	dstR=Rect(x+w-box[1]->w, y,   box[1]->w, box[1]->h);
	CSDL_Ext::blitSurface(box[1], nullptr, ret, &dstR);

	dstR=Rect(x, y+h-box[2]->h+1, box[2]->w, box[2]->h);
	CSDL_Ext::blitSurface(box[2], nullptr, ret, &dstR);

	dstR=Rect(x+w-box[3]->w, y+h-box[3]->h+1, box[3]->w, box[3]->h);
	CSDL_Ext::blitSurface(box[3], nullptr, ret, &dstR);
}
Beispiel #14
0
void Graphics::blueToPlayersAdv(SDL_Surface * sur, PlayerColor player)
{
// 	if(player==1) //it is actually blue...
// 		return;
	if(sur->format->BitsPerPixel == 8)
	{
		SDL_Color *palette = nullptr;
		if(player < PlayerColor::PLAYER_LIMIT)
		{
			palette = playerColorPalette + 32*player.getNum();
		}
		else if(player == PlayerColor::NEUTRAL)
		{
			palette = neutralColorPalette;
		}
		else
		{
            logGlobal->errorStream() << "Wrong player id in blueToPlayersAdv (" << player << ")!";
			return;
		}

		SDL_SetColors(sur, palette, 224, 32);
		//for(int i=0; i<32; ++i)
		//{
		//	sur->format->palette->colors[224+i] = palette[i];
		//}
	}
	else if(sur->format->BitsPerPixel == 24) //should never happen in general
	{
		for(int y=0; y<sur->h; ++y)
		{
			for(int x=0; x<sur->w; ++x)
			{
				Uint8* cp = (Uint8*)sur->pixels + y*sur->pitch + x*3;
				if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
				{
					if(cp[2]>cp[1] && cp[2]>cp[0])
					{
						std::vector<long long int> sort1;
						sort1.push_back(cp[0]);
						sort1.push_back(cp[1]);
						sort1.push_back(cp[2]);
						std::vector< std::pair<long long int, Uint8*> > sort2;
						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].r, &(cp[0])));
						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].g, &(cp[1])));
						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].b, &(cp[2])));
						std::sort(sort1.begin(), sort1.end());
						if(sort2[0].first>sort2[1].first)
							std::swap(sort2[0], sort2[1]);
						if(sort2[1].first>sort2[2].first)
							std::swap(sort2[1], sort2[2]);
						if(sort2[0].first>sort2[1].first)
							std::swap(sort2[0], sort2[1]);
						for(int hh=0; hh<3; ++hh)
						{
							(*sort2[hh].second) = (sort1[hh] + sort2[hh].first)/2.2;
						}
					}
				}
				else
				{
					if(
						(/*(mode==0) && (cp[0]>cp[1]) && (cp[0]>cp[2])) ||
						((mode==1) &&*/ (cp[2]<45) && (cp[0]>80) && (cp[1]<70) && ((cp[0]-cp[1])>40))
					  )
					{
						std::vector<long long int> sort1;
						sort1.push_back(cp[2]);
						sort1.push_back(cp[1]);
						sort1.push_back(cp[0]);
						std::vector< std::pair<long long int, Uint8*> > sort2;
						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].r, &(cp[2])));
						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].g, &(cp[1])));
						sort2.push_back(std::make_pair(graphics->playerColors[player.getNum()].b, &(cp[0])));
						std::sort(sort1.begin(), sort1.end());
						if(sort2[0].first>sort2[1].first)
							std::swap(sort2[0], sort2[1]);
						if(sort2[1].first>sort2[2].first)
							std::swap(sort2[1], sort2[2]);
						if(sort2[0].first>sort2[1].first)
							std::swap(sort2[0], sort2[1]);
						for(int hh=0; hh<3; ++hh)
						{
							(*sort2[hh].second) = (sort1[hh]*0.8 + sort2[hh].first)/2;
						}
					}
				}
			}
		}
	}
}