⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 te_territory_editor.cpp

📁 空战游戏flacon源码
💻 CPP
字号:
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// Tactical Engagement - Robin Heydon
//
// Implements the user interface for the tactical engagement section
// of falcon 4.0
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

#include "falclib.h"
#include "vu2.h"
#include "chandler.h"
#include "ui95_ext.h"
#include "uicomms.h"
#include "userids.h"
#include "textids.h"
#include "cmpclass.h"
#include "division.h"
#include "cmap.h"
#include "tac_class.h"
#include "te_defs.h"
#include "find.h"
#include "camplist.h"
#include "gps.h"

extern GlobalPositioningSystem *gGps;

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

enum{
	SMFLGS_USA 		=52012,
	SMFLGS_NKOREA 	=52013,
	SMFLGS_CHINA 	=52014,
	SMFLGS_FRANCE 	=52015,
	SMFLGS_CIS 		=52016,
	SMFLGS_SKOREA  	=52017,
	SMFLGS_JAPAN 	=52018,
	SMFLGS_GERMAN 	=52019,
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

extern IMAGE_RSC *gOccupationMap;
extern int MRX;
extern int MRY;
extern uchar gSelectedTeam;
extern long gDrawTeam;
long OwnershipChanged=0;

uchar *te_restore_map = NULL;

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void tactical_territory_editor_clear (long ID, short hittype, C_Base *control);
void tactical_territory_editor_restore (long ID, short hittype, C_Base *control);
void tactical_territory_map_edit (long ID, short hittype, C_Base *control);
void UpdateOwners();

// Run the list of campaign things and change ownership as required
void UpdateObjectiveOwnership (void);
void UpdateUnitOwnership(void);

void tactical_team_selection(long ID,short hittype,C_Base *control);

void MakeOccupationMap(IMAGE_RSC *Map);
IMAGE_RSC *CreateOccupationMap(long ID,long w,long h,long palsize);
static void SetupMapWindow (void);
void CampaignListCB(void);
void UpdateOccupationMap(void);

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void tactical_territory_editor_clear (long, short hittype, C_Base *)
{
	if(hittype != C_TYPE_LMOUSEUP)
		return;

	if (TheCampaign.CampMapData)
	{
		memset (TheCampaign.CampMapData, 0, TheCampaign.CampMapSize);
		UpdateOccupationMap();
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void tactical_territory_editor_restore (long, short hittype, C_Base *)
{
	if(hittype != C_TYPE_LMOUSEUP)
		return;

	if ((TheCampaign.CampMapData) && (te_restore_map))
	{
		memcpy (TheCampaign.CampMapData, te_restore_map, TheCampaign.CampMapSize);
		UpdateOccupationMap();
	}
}

void tactical_set_drawmode (long, short hittype, C_Base *)
{
	if(hittype == C_TYPE_LMOUSEUP)
		return;

	gDrawTeam=gSelectedTeam;
}

void tactical_set_erasemode (long, short hittype, C_Base *)
{
	if(hittype == C_TYPE_LMOUSEUP)
		return;

	gDrawTeam=0;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static int get_group_cover (int x, int y)
{
	int
		dx,
		dy,
		cover;

	for (dx = 0; dx < MAP_RATIO; dx ++)
	{
		for (dy = 0; dy < MAP_RATIO; dy ++)
		{
			cover = GetCover (static_cast<short>(x + dx), static_cast<short>(y + dy));

			if (cover != Water)
			{
				return cover;
			}
		}
	}

	return Water;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static int
	fill_width,
	fill_height,
	fill_team;

static unsigned char
	*fill_src;

static void flood_fill_team (int x, int y)
{
	int
		old_team;

	unsigned char
		cover;

	if(x < 0 || y < 0 || x >= fill_width || y >= fill_height)
		return;

	if (x & 1)
	{
		old_team = (fill_src[(y * fill_width + x) / 2] & 0xf0) >> 4;
	}
	else
	{
		old_team = fill_src[(y * fill_width + x) / 2] & 0x0f;
	}

	if ((old_team == gDrawTeam) || (old_team != fill_team))
	{
		return;
	}

	cover = static_cast<uchar>(get_group_cover (x * MAP_RATIO, y * MAP_RATIO));

	if (cover != Water)
	{
		
		if (x & 1)
		{
			fill_src[(y * fill_width + x) / 2] &= 0x0f;
			fill_src[(y * fill_width + x) / 2] |= gDrawTeam  << 4;
			
			flood_fill_team (x + 0, y - 1);
			flood_fill_team (x - 1, y + 0);
			flood_fill_team (x + 1, y + 0);
			flood_fill_team (x + 0, y + 1);
		}
		else
		{
			fill_src[(y * fill_width + x) / 2] &= 0xf0;
			fill_src[(y * fill_width + x) / 2] |= gDrawTeam ;

			flood_fill_team (x + 0, y - 1);
			flood_fill_team (x - 1, y + 0);
			flood_fill_team (x + 1, y + 0);
			flood_fill_team (x + 0, y + 1);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void tactical_territory_map_edit (long, short hittype, C_Base *control)
{
	long
		width,
		height,
		px,
		py,
		lx,
		ly,
		x,
		y;

	uchar
		cover,
		*src;

	if (hittype == C_TYPE_RMOUSEDOWN)
	{
		save_territory_editor();
		OwnershipChanged=1;

		x = control->GetRelX ();
		y = control->GetRelY ();

		y = TheCampaign.TheaterSizeY / MAP_RATIO - y;

		x -= 3;
		y -= 4;

		width = TheCampaign.TheaterSizeX / MAP_RATIO;
		height = TheCampaign.TheaterSizeY / MAP_RATIO;

		src=TheCampaign.CampMapData;

		if (src)
		{
			fill_width = width;
			fill_height = height;
			fill_src = src;
			
			if (x & 1)
			{
				fill_team = (fill_src[(y * fill_width + x) / 2] & 0xf0) >> 4;
			}
			else
			{
				fill_team = fill_src[(y * fill_width + x) / 2] & 0x0f;
			}
			
			flood_fill_team (x, y);

			MakeOccupationMap(gOccupationMap);
			control->Refresh();
		}
	}
	else if ((hittype == C_TYPE_LMOUSEDOWN) || (hittype == C_TYPE_DRAGXY))
	{
		if(hittype == C_TYPE_LMOUSEDOWN)
			save_territory_editor();

		OwnershipChanged=1;

		x = control->GetRelX ();
		y = control->GetRelY ();

		y = TheCampaign.TheaterSizeY / MAP_RATIO - y;

		x -= 3;
		y -= 4;

		width = TheCampaign.TheaterSizeX / MAP_RATIO;
		height = TheCampaign.TheaterSizeY / MAP_RATIO;

		src=TheCampaign.CampMapData;

		if (src)
		{
			for (lx = 0; lx < MAP_RATIO; lx ++)
			{
				px = x + lx;
				for (ly = 0; ly < MAP_RATIO; ly ++)
				{
					py = y + ly;

					if ((px >= 0) && (px < width) && (py >= 0) && (py < height))
					{
						cover = static_cast<uchar>(get_group_cover (px * MAP_RATIO, py * MAP_RATIO));

						if (cover != Water)
						{
							// Update the ownership for all objectives/squadrons/battalions in the area
							

							if (px & 1)
							{
								src[(py * width + px) / 2] &= 0x0f;
								src[(py * width + px) / 2] |= gDrawTeam << 4;
							}
							else
							{
								src[(py * width + px) / 2] &= 0xf0;
								src[(py * width + px) / 2] |= gDrawTeam;
							}
						}
					}
				}
			}
			MakeOccupationMap(gOccupationMap);
			control->Refresh();
		}
	}
	else if (hittype == C_TYPE_LMOUSEUP)
	{
		OwnershipChanged=1;
		MakeOccupationMap(gOccupationMap);
		control->Refresh();
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void SetupOccupationMap (void)
{
	C_Window *win;
	C_Button *but;
	C_Bitmap *bmp;

	if(gOccupationMap == NULL && (TheCampaign.TheaterSizeX && TheCampaign.TheaterSizeY && TheCampaign.CampMapData))
	{
		// Create Occupation map...
		gOccupationMap=CreateOccupationMap(1,TheCampaign.TheaterSizeX/MAP_RATIO,TheCampaign.TheaterSizeY/MAP_RATIO,16);
	}
	if(gOccupationMap )
		MakeOccupationMap(gOccupationMap);

	win = gMainHandler->FindWindow(TAC_TEAM_WIN);
	if (win != NULL)
	{
		but=(C_Button *)win->FindControl(TAC_MAP_TE);
		if(but)
		{
			but->SetImage(0,gOccupationMap);
			but->SetSubParents(win);
			but->Refresh();
		}
	}
	win=gMainHandler->FindWindow(TAC_MISSION_SUA);
	if(win)
	{
		bmp=(C_Bitmap*)win->FindControl(TAC_OVERLAY);
		if(bmp)
		{
			bmp->SetImage(gOccupationMap);
			bmp->SetSubParents(win);
			bmp->Refresh();
		}
	}
	win=gMainHandler->FindWindow(TAC_SUA_WIN);
	if(win)
	{
		bmp=(C_Bitmap*)win->FindControl(TAC_OVERLAY);
		if(bmp)
		{
			bmp->SetImage(gOccupationMap);
			bmp->SetSubParents(win);
			bmp->Refresh();
		}
	}
}

void UpdateOccupationMap(void)
{
	C_Window *win;
	C_Button *but;
	C_Bitmap *bmp;

	if(!gOccupationMap)
		return;

	MakeOccupationMap(gOccupationMap);

	win = gMainHandler->FindWindow(TAC_TEAM_WIN);
	if (win != NULL)
	{
		but=(C_Button *)win->FindControl(TAC_MAP_TE);
		if(but)
		{
			but->Refresh();
		}
	}
	win=gMainHandler->FindWindow(TAC_MISSION_SUA);
	if(win)
	{
		bmp=(C_Bitmap*)win->FindControl(TAC_OVERLAY);
		if(bmp)
		{
			bmp->Refresh();
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void save_territory_editor (void)
{
	if (TheCampaign.CampMapData)
	{
		if (!te_restore_map)
			te_restore_map=new uchar[TheCampaign.CampMapSize];

		if (te_restore_map)
		{
			memcpy (te_restore_map, TheCampaign.CampMapData, TheCampaign.CampMapSize);
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

int tryx[20] = { 1, -1, 0, 0, 1, 1, -1, -1,		2, -2, 0, 0, 2, 2, -2, -2, 1, -1, 1, -1 };
int tryy[20] = { 0, 0, 1, -1, 1, -1, 1, -1,		0, 0, 2, -2, 1, -1, 1, -1, 2, 2, -2, -2 };

short GetMapTeam(short x,short y)
{
	int bit,indx;
	uchar pixel;
	int width;

	if(!TheCampaign.CampMapData)
		return(0);

	width=MRX >> 1;
	x=static_cast<short>(x/MAP_RATIO);
	y=static_cast<short>(y/MAP_RATIO);
	bit=x&1;
	x>>=1;
	pixel=TheCampaign.CampMapData[y*width+x];
	pixel = static_cast<uchar>((pixel >> (bit * 4)) & 0x0f);
	if(pixel > 0 && pixel < NUM_TEAMS)
		return(pixel);
	// KCK: Added this to try and avoid accidental painting of team 0 stuff
	// Basically, I'm going to look around until I find a non-water area
	for (int i=0; i<20; i++)
		{
		indx = (y+tryy[i])*width + x+tryx[i];
		if (indx >= 0 && indx < TheCampaign.CampMapSize)
			{
			pixel=TheCampaign.CampMapData[indx];
			pixel = static_cast<uchar>((pixel >> (bit * 4)) & 0x0f);
			if(pixel > 0 && pixel < NUM_TEAMS)
				return(pixel);
			}
		}
	return(0);
}

void UpdateObjectiveOwnership ()
{
	VuListIterator myit(AllObjList);
	Objective	obj;
	GridIndex   x,y;
	Team team;
	
	obj = (Objective) myit.GetFirst();
	while (obj != NULL)
	{
		obj->GetLocation(&x, &y);
				
		team = static_cast<uchar>(GetMapTeam(x,y));

		if ((team < NUM_TEAMS) && (TeamInfo[team]))
		{
			if (obj->GetOwner() != team)
				obj->SetOwner (team);
			if (obj->GetObjectiveOldown() != team)
				obj->SetObjectiveOldown(team);
		}
		else
		{
			if (obj->GetOwner() != 0)
				obj->SetOwner (0);
			if (obj->GetObjectiveOldown() != 0)
				obj->SetObjectiveOldown (0);
		}
		obj = (Objective) myit.GetNext();
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

void UpdateUnitOwnership(void)
{
#if 0
	int team;
	short unitX, unitY;
	VuListIterator	myit(AllUnitList);
	UnitClass* theUnit;


	theUnit = GetFirstUnit(&myit);
	while (theUnit != NULL)
	{
		theUnit->GetLocation(&unitX, &unitY);
		team = GetOwner(TheCampaign.CampMapData,unitX,unitY);
		ShiAssert(team < NUM_TEAMS && TeamInfo[team]);
		theUnit->SetOwner (team);
		
		theUnit = GetNextUnit(&myit);
	}
#endif
}

void UpdateOwners()
{
	if(OwnershipChanged)
	{
		UpdateObjectiveOwnership ();
		UpdateUnitOwnership();
		gGps->Update();
		OwnershipChanged=0;
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -