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

📄 cmap.cpp

📁 空战游戏flacon源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************\
    Cmap.cpp
    Peter Ward
	July 15, 1996

    This code handles drawing the Campaign Map with/without units (user selectable)
\***************************************************************************/
#include <windows.h>
#include "unit.h"
#include "team.h"
#include "CmpGlobl.h"
#include "CampCell.h"
#include "CampTerr.h"
#include "find.h"
#include "division.h"
#include "flight.h"
#include "campwp.h"
#include "cmpclass.h"
#include "campstr.h"
#include "Listadt.h"
#include "objectiv.h"
#include "Campaign.h"
#include "chandler.h"
#include "ui95_ext.h"
#include "filters.h"
#include "cmap.h" // header file for this class
#include "userids.h"
#include "textids.h"
#include "classtbl.h"
#include "falcsess.h"
#include "gps.h"
#include "urefresh.h"
#include "battalion.h"

enum
{
	PLANNER_RESOURCE=200110,
};

extern VU_ID gSelectedPackage,gActiveFlightID;;
extern int gMoveBattalion;

extern GlobalPositioningSystem *gGps;

extern C_Handler *gMainHandler;
void WaypointCB (long ID, short hittype, C_Base *ctrl);
void UnitCB (long ID,short hittype,C_Base *ctrl);
int IsValidWP (WayPointClass *wp, Flight flt);
void Uni_Float(_TCHAR *buffer);

#define FEET_PER_PIXEL (FEET_PER_KM / 2.0f)

C_Map::C_Map()
{
	CenterX_=0;
	CenterY_=0;
	ZoomLevel_=_MAX_ZOOM_LEVEL_;
	scale_=1.0f;
	flags_=I_NEED_TO_DRAW|I_NEED_TO_DRAW_MAP;

	MapID=0;
	Map_=NULL;
	memset(&MapRect_,0,sizeof(UI95_RECT));

	memset(&TeamFlags_[0],0,sizeof(long)*_MAX_TEAMS_);
	memset(&Team_[0],0,sizeof(MAPICONS)*_MAX_TEAMS_);
	memset(&TeamColor_[0],0,sizeof(COLORREF)*_MAX_TEAMS_);
	CurWP_=NULL;
	CurWPZ_=NULL;
	WPUnitID_=FalconNullId;
	CurIcons_=NULL;
	CurWPArea_.left=-1;
	CurWPArea_.top=-1;
	CurWPArea_.right=-1;
	CurWPArea_.bottom=-1;

	BullsEye_=NULL;
	Circles_=0;

	ObjectiveMask_=0;
	UnitMask_=0;
	NavalUnitMask_=0;
	AirUnitMask_=0;
	ThreatMask_=0;

	SmallMapCtrl_=NULL;
	DrawWindow_=NULL;
	WPZWindow_=NULL;
	memset(&DrawRect_,0,sizeof(UI95_RECT));
}

C_Map::~C_Map()
{
	if(Map_ || DrawWindow_ || SmallMapCtrl_)
		Cleanup();
}

void C_Map::Cleanup()
{
	short i,j,k;

	if(DrawWindow_)
	{
		RemoveListsFromWindow();
		DrawWindow_=NULL;
	}
	if(WPZWindow_)
		WPZWindow_=NULL;
	if(Map_)
	{
		Map_->Cleanup();
		delete Map_;
		Map_=NULL;
	}

	if(BullsEye_)
	{
		BullsEye_->Cleanup();
		delete BullsEye_;
		BullsEye_=NULL;
	}

	for(i=0;i<_MAX_TEAMS_;i++)
	{
		if(Team_[i].Threats)
		{
			for(j=0;j<_MAP_NUM_THREAT_TYPES_;j++)
				if(Team_[i].Threats->Type[j])
				{
					Team_[i].Threats->Type[j]->Cleanup();
					delete Team_[i].Threats->Type[j];
				}
			delete Team_[i].Threats;
			Team_[i].Threats=NULL;
		}
		if(Team_[i].Objectives)
		{
			for(j=0;j<_MAP_NUM_OBJ_TYPES_;j++)
				if(Team_[i].Objectives->Type[j])
				{
					Team_[i].Objectives->Type[j]->Cleanup();
					delete Team_[i].Objectives->Type[j];
				}
			delete Team_[i].Objectives;
			Team_[i].Objectives=NULL;
		}
		if(Team_[i].NavalUnits)
		{
			for(j=0;j<_MAP_NUM_NAV_TYPES_;j++)
				if(Team_[i].NavalUnits->Type[j])
				{
					Team_[i].NavalUnits->Type[j]->Cleanup();
					delete Team_[i].NavalUnits->Type[j];
				}
			delete Team_[i].NavalUnits;
			Team_[i].NavalUnits=NULL;
		}
		if(Team_[i].Units)
		{
			for(j=0;j<_MAP_NUM_GND_TYPES_;j++)
				if(Team_[i].Units->Type[j])
				{
					if(Team_[i].Units->Type[j])
					{
						for(k=0;k<_MAP_NUM_GND_LEVELS_;k++)
							if(Team_[i].Units->Type[j]->Levels[k])
							{
								Team_[i].Units->Type[j]->Levels[k]->Cleanup();
								delete Team_[i].Units->Type[j]->Levels[k];
							}
						delete Team_[i].Units->Type[j];
					}
				}
			delete Team_[i].Units;
			Team_[i].Units=NULL;
		}
		if(Team_[i].AirUnits)
		{
			for(j=0;j<_MAP_NUM_AIR_TYPES_;j++)
				if(Team_[i].AirUnits->Type[j])
				{
					Team_[i].AirUnits->Type[j]->Cleanup();
					delete Team_[i].AirUnits->Type[j];
				}
			delete Team_[i].AirUnits;
			Team_[i].AirUnits=NULL;
		}
		if(Team_[i].Waypoints)
		{
			Team_[i].Waypoints->Cleanup();
			delete Team_[i].Waypoints;
			Team_[i].Waypoints=NULL;
		}
	}
	if(CurIcons_)
	{
		CurIcons_->Cleanup();
		delete CurIcons_;
		CurIcons_=NULL;
	}
	if(CurWP_)
	{
		CurWP_->Cleanup();
		delete CurWP_;
		CurWP_=NULL;
	}
	if(CurWPZ_)
	{
		CurWPZ_->Cleanup();
		delete CurWPZ_;
		CurWPZ_=NULL;
	}
	SmallMapCtrl_=NULL;
}

void C_Map::RemoveAllEntities()
{
	short i,j,k;

	for(i=0;i<_MAX_TEAMS_;i++)
	{
		if(Team_[i].Threats)
		{
			for(j=0;j<_MAP_NUM_THREAT_TYPES_;j++)
				if(Team_[i].Threats->Type[j])
				{
					Team_[i].Threats->Type[j]->Cleanup();
				}
		}
		if(Team_[i].Objectives)
		{
			for(j=0;j<_MAP_NUM_OBJ_TYPES_;j++)
				if(Team_[i].Objectives->Type[j])
				{
					Team_[i].Objectives->Type[j]->Cleanup();
				}
		}
		if(Team_[i].NavalUnits)
		{
			for(j=0;j<_MAP_NUM_NAV_TYPES_;j++)
				if(Team_[i].NavalUnits->Type[j])
				{
					Team_[i].NavalUnits->Type[j]->Cleanup();
				}
		}
		if(Team_[i].Units)
		{
			for(j=0;j<_MAP_NUM_GND_TYPES_;j++)
				if(Team_[i].Units->Type[j])
				{
					if(Team_[i].Units->Type[j])
					{
						for(k=0;k<_MAP_NUM_GND_LEVELS_;k++)
							if(Team_[i].Units->Type[j]->Levels[k])
							{
								Team_[i].Units->Type[j]->Levels[k]->Cleanup();
							}
					}
				}
		}
		if(Team_[i].AirUnits)
		{
			for(j=0;j<_MAP_NUM_AIR_TYPES_;j++)
				if(Team_[i].AirUnits->Type[j])
				{
					Team_[i].AirUnits->Type[j]->Cleanup();
				}
		}
		if(Team_[i].Waypoints)
		{
			Team_[i].Waypoints->Cleanup();
		}
	}
	if(CurIcons_)
	{
		CurIcons_->Cleanup();
	}
	if(CurWP_)
	{
		CurWP_->Cleanup();
	}
	if(CurWPZ_)
	{
		CurWPZ_->Cleanup();
	}
}

// Private
void C_Map::CalculateDrawingParams()
{
	float ratio;
	long pixels;

	if(Map_ == NULL || DrawWindow_ == NULL)
		return;

	ratio=(float)(DrawRect_.bottom-DrawRect_.top) / (float)(DrawRect_.right-DrawRect_.left);
	pixels=ZoomLevel_;

	MapRect_.left=FloatToInt32(CenterX_) - pixels/2;
	if(MapRect_.left < 0)
	{
		MapRect_.left=0;
		CenterX_=static_cast<float>(MapRect_.left+pixels/2);
	}
	MapRect_.right=MapRect_.left+pixels;
	if(MapRect_.right > Map_->GetW())
	{
		MapRect_.right=Map_->GetW();
		MapRect_.left=MapRect_.right-pixels;
		CenterX_=static_cast<float>(MapRect_.right-pixels/2);
	}

	MapRect_.top=FloatToInt32(CenterY_) - (long)((float)pixels*ratio)/2;

	if(MapRect_.top < 0)
	{
		MapRect_.top=0;
		CenterY_=static_cast<float>(MapRect_.top+(long)((float)pixels*ratio)/2);
	}
	MapRect_.bottom=MapRect_.top+(long)((float)pixels*ratio);
	if(MapRect_.bottom > Map_->GetH())
	{
		MapRect_.bottom=Map_->GetH();
		MapRect_.top=MapRect_.bottom-(long)((float)pixels*ratio);
		CenterY_=static_cast<float>(MapRect_.bottom-(long)((float)pixels*ratio)/2);
	}

	Map_->SetSrcRect(&MapRect_);
	Map_->SetDestRect(&DrawRect_);
	Map_->SetScaleInfo(((MapRect_.right-MapRect_.left)*1000)/(DrawRect_.right-DrawRect_.left));

	scale_=(float)(DrawRect_.right-DrawRect_.left) / ((float)(MapRect_.right-MapRect_.left)*FEET_PER_PIXEL);

	DrawWindow_->VX_[0]=-(short)((float)MapRect_.left*FEET_PER_PIXEL*scale_)+DrawWindow_->ClientArea_[0].left;
	DrawWindow_->VY_[0]=-(short)((float)MapRect_.top*FEET_PER_PIXEL*scale_)+DrawWindow_->ClientArea_[0].top;
	SetTeamScales();

	flags_ |= I_NEED_TO_DRAW|I_NEED_TO_DRAW_MAP;
}

THREAT_LIST *C_Map::AddThreat(CampEntity ent)
{
	THREAT_LIST *threat;
	long radar_short;
	long radar_long;
	long sam_short;
	long sam_long;
	short i;
	GridIndex x,y;

	threat=NULL;
	if(ent->IsObjective() && ent->IsEmitting())
	{
		ent->GetLocation(&x,&y);
		y=static_cast<short>(1024-y);

		radar_short=ent->GetElectronicDetectionRange(LowAir);
		radar_long=ent->GetElectronicDetectionRange(Air);
		if(radar_short || radar_long)
		{
			#ifdef USE_SH_POOLS
			threat = (THREAT_LIST *)MemAllocPtr(UI_Pools[UI_GENERAL_POOL],sizeof(THREAT_LIST),FALSE);
			#else
			threat=new THREAT_LIST;
			#endif
			memset(threat,0,sizeof(THREAT_LIST));

			if(Team_[ent->GetTeam()].Threats)
			{
				if(Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_HIGH_])
				{
					Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_HIGH_]->AddCircle(ent->GetCampID(),C_Threat::THR_CIRCLE,x,y,radar_long);
					threat->RadarHigh=Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_HIGH_]->GetThreat(ent->GetCampID());
				}
				if(Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_] && radar_short)
				{
					Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_]->AddCircle(ent->GetCampID(),C_Threat::THR_SLICE,x,y,radar_short);
					for(i=0;i<8;i++)
						Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_]->SetRadius(ent->GetCampID(),i,static_cast<long>(min(ent->GetArcRange(i)*FT_TO_KM,radar_short)));
					threat->RadarLow=Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_]->GetThreat(ent->GetCampID());
				}
			}

		}
	}
	if(ent->IsUnit() && ent->IsEmitting())
	{
		ent->GetLocation(&x,&y);
		y=static_cast<short>(1024-y);

		radar_short=ent->GetElectronicDetectionRange(LowAir);
		radar_long=ent->GetElectronicDetectionRange(Air);
		sam_short=ent->GetAproxWeaponRange(LowAir);
		sam_long=ent->GetAproxWeaponRange(Air);
		if(radar_short || radar_long || sam_long || sam_short)
		{
			#ifdef USE_SH_POOLS
			threat = (THREAT_LIST *)MemAllocPtr(UI_Pools[UI_GENERAL_POOL],sizeof(THREAT_LIST),FALSE);
			#else
			threat=new THREAT_LIST;
			#endif
			memset(threat,0,sizeof(THREAT_LIST));

			if(Team_[ent->GetTeam()].Threats)
			{
				if(Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_HIGH_] && radar_long)
				{
					Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_HIGH_]->AddCircle(ent->GetCampID(),C_Threat::THR_CIRCLE,x,y,radar_long);
					threat->RadarHigh=Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_HIGH_]->GetThreat(ent->GetCampID());
				}
				if(Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_] && radar_short)
				{
					Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_]->AddCircle(ent->GetCampID(),C_Threat::THR_SLICE,x,y,radar_short);
					for(i=0;i<8;i++)
						Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_]->SetRadius(ent->GetCampID(),i,static_cast<short>(min(ent->GetArcRange(i)*FT_TO_KM,radar_short)));
					threat->RadarLow=Team_[ent->GetTeam()].Threats->Type[_THREAT_RADAR_LOW_]->GetThreat(ent->GetCampID());
				}
				if(Team_[ent->GetTeam()].Threats->Type[_THREAT_SAM_HIGH_] && sam_long)
				{
					Team_[ent->GetTeam()].Threats->Type[_THREAT_SAM_HIGH_]->AddCircle(ent->GetCampID(),C_Threat::THR_CIRCLE,x,y,sam_long);
					threat->SamHigh=Team_[ent->GetTeam()].Threats->Type[_THREAT_SAM_HIGH_]->GetThreat(ent->GetCampID());
				}
				if(Team_[ent->GetTeam()].Threats->Type[_THREAT_SAM_LOW_] && sam_short)
				{
					Team_[ent->GetTeam()].Threats->Type[_THREAT_SAM_LOW_]->AddCircle(ent->GetCampID(),C_Threat::THR_SLICE,x,y,sam_short);
					for(i=0;i<8;i++)
						Team_[ent->GetTeam()].Threats->Type[_THREAT_SAM_LOW_]->SetRadius(ent->GetCampID(),i,static_cast<short>(min(ent->GetArcRange(i)*FT_TO_KM,sam_short)));
					threat->SamLow=Team_[ent->GetTeam()].Threats->Type[_THREAT_SAM_LOW_]->GetThreat(ent->GetCampID());
				}
			}
		}
	}

	return(NULL);
}

MAPICONLIST *C_Map::AddObjective(Objective Obj)
{
	long ObjType,TypeID;
	short numarcs;
	float radar_short,radar_long;
	ObjClassDataType *ObjPtr;
	_TCHAR Buffer[40];
	DETECTOR *detect;

	ObjType=GetObjectiveType(Obj);
	TypeID=FindTypeIndex(ObjType,OBJ_TypeList,_MAP_NUM_OBJ_TYPES_);
	if(TypeID != -1)
	{
		if(ObjType)
		{
			ObjPtr=Obj->GetObjectiveClassData();
			if(ObjPtr)
			{
				Obj->GetName(Buffer,39,TRUE);
				detect=NULL;
				radar_short=static_cast<float>(Obj->GetElectronicDetectionRange(LowAir));
				radar_long=static_cast<float>(Obj->GetElectronicDetectionRange(Air));
				if(radar_short || radar_long)
				{
					#ifdef USE_SH_POOLS
					detect = (DETECTOR *)MemAllocPtr(UI_Pools[UI_GENERAL_POOL],sizeof(DETECTOR),FALSE);
					#else
					detect=new DETECTOR;
					#endif
					detect->HighSam=0.0f;
					detect->HighRadar=radar_long * KM_TO_FT;
					detect->LowSam=0.0f;

					if(radar_short)
					{
						numarcs=static_cast<short>(Obj->GetNumberOfArcs());
						numarcs=1; // TEMP kludge
						#ifdef USE_SH_POOLS
						detect->LowRadar = (ARC_LIST *)MemAllocPtr(UI_Pools[UI_GENERAL_POOL],sizeof(ARC_LIST),FALSE);
						#else
						detect->LowRadar=new ARC_LIST;
						#endif
						detect->LowRadar->numarcs=numarcs;
						#ifdef USE_SH_POOLS
						detect->LowRadar->arcs = (ARC_REC *)MemAllocPtr(UI_Pools[UI_GENERAL_POOL],sizeof(ARC_REC)*numarcs,FALSE);
						#else
						detect->LowRadar->arcs=new ARC_REC[numarcs];
						#endif
						// after getting rid of kludges...
						// figure out how to do arcs right
						// kludge
						detect->LowRadar->arcs[0].arc=0;
						detect->LowRadar->arcs[0].range=radar_short;

⌨️ 快捷键说明

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