📄 cmap.cpp
字号:
/***************************************************************************\
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 + -