📄 waypoint.cpp
字号:
{
ent = GetObjectiveByXY(x,y);
if (ent)
wp->SetWPTarget(ent->Id());
else
wp->SetWPTarget(FalconNullId);
}
break;
default:
break;
}
wp->UnSetWPFlag(WPF_CRITICAL_MASK);
wp->SetWPFlag(flags);
wp->SetWPAction(action);
if (action != oldaction && flags != oldflags)
gMapMgr->SetCurrentWaypointList(gActiveFlightID);
}
void set_waypoint_action(long,short hittype,C_Base *control)
{
C_ListBox *lbox;
WayPointClass *wp;
C_Window *win;
int action;
if(hittype != C_TYPE_SELECT)
return;
win=control->Parent_;
if(!win)
return;
lbox = (C_ListBox *) control;
if(!lbox)
return;
action=lbox->GetTextID()-1;
RefreshActionClusters(action, control->Parent_);
control->Refresh();
wp = get_current_waypoint ();
set_waypoint_action(wp,action);
SetSteerPointValues(control->Parent_,wp,gActiveWPNum);
refresh_waypoint(wp);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void set_waypoint_formation(long,short hittype,C_Base *control)
{
C_ListBox
*lbox;
WayPointClass
*wp;
C_Window
*win;
if(hittype != C_TYPE_SELECT)
return;
win=control->Parent_;
if(!win)
return;
lbox = (C_ListBox *) control;
wp = get_current_waypoint ();
if ((lbox) && (wp))
wp->SetWPFormation(lbox->GetTextID()-1);
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Takes speed in nm/hr and altitude in ft
float get_ground_speed (float speed, int altitude)
{
float
vcas,
vtas,
error;
vtas = speed;
error = speed / 2.0F;
while (error > 0.1F)
{
vcas = get_air_speed (vtas, altitude);
if (vcas < speed)
{
vtas += error;
}
else
{
vtas -= error;
}
error /= 2.0F;
}
return vtas;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Takes speed in nm/hr and altitude in ft
float get_air_speed (float speed, int altitude)
{
float
rsigma,
pa,
mach,
qc,
qpasl1,
vcas,
oper,
ttheta;
if (altitude <= 36089)
{
ttheta = 1.0F - 0.000006875F * altitude;
rsigma = static_cast<float>(pow (ttheta, 4.256F));
}
else
{
ttheta = 0.7519F;
rsigma = static_cast<float>(0.2971F * pow (2.718F, 0.00004806F * (36089.0F - altitude)));
}
mach = static_cast<float>(speed / (sqrt (ttheta) * AASLK));
pa = ttheta * rsigma * PASL;
if (mach <= 1.0F)
{
qc = ((float)pow((1.0F + 0.2F * mach * mach), 3.5F) - 1.0F)*pa;
}
else
{
qc = static_cast<float>(((166.9*mach*mach)/(float)(pow((7.0F - 1.0F/(mach*mach)), 2.5F)) - 1.0F)*pa);
}
qpasl1 = qc / PASL + 1.0F;
vcas = static_cast<float>(1479.12F * sqrt (pow (qpasl1, 0.285714F) - 1.0F));
if (qc > 1889.64F)
{
oper = static_cast<float>(qpasl1 * pow ((7.0F - AASLK * AASLK / (vcas * vcas)), 2.5F));
if (oper < 0.0F) oper = 0.1F;
{
vcas = static_cast<float>(51.1987F * sqrt(oper));
}
}
return vcas;
}
void RebuildCurrentWPList()
{
if(gMapMgr)
gMapMgr->SetCurrentWaypointList(gMapMgr->GetCurWPID());
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Find a new target/airbase etc if this waypoint requires it
void DropWayPoint (WayPoint wp)
{
GridIndex x,y;
CampBaseClass *ent;
int action;
Unit unit;
if (!wp)
return;
unit=(Unit)vuDatabase->Find(gActiveFlightID);
action = wp->GetWPAction();
wp->GetWPLocation(&x, &y);
if (action == WP_TAKEOFF || action == WP_LAND)
{
ent = GetObjectiveByXY(x,y);
if (ent && (ent->GetType() == TYPE_AIRBASE || ent->GetType() == TYPE_AIRSTRIP))
wp->SetWPTarget(ent->Id());
else
wp->SetWPTarget(FalconNullId);
}
else if (action == WP_STRIKE || action == WP_BOMB || action == WP_RECON)
{
ent = GetObjectiveByXY(x,y);
if (ent)
wp->SetWPTarget(ent->Id());
else
wp->SetWPTarget(FalconNullId);
}
else if (action == WP_INTERCEPT || action == WP_NAVSTRIKE || action == WP_GNDSTRIKE)
{
ent = GetUnitByXY(x,y);
if (ent)
wp->SetWPTarget(ent->Id());
else
wp->SetWPTarget(FalconNullId);
}
if (unit->IsFlight())
{
((Flight)unit)->SetUnitMissionTarget(wp->GetWPTargetID());
}
}
/*
void GotoWaypoint ()
{
C_Window *win;
WayPoint wp,prevwp=NULL;
int i;
Unit un;
Flight flt;
VU_ID *tmpID;
if(hittype != C_TYPE_LMOUSEUP)
return;
win=gMainHandler->FindWindow(FLIGHT_PLAN_WIN);
if(win)
{
tmpID=(VU_ID *)control->GetUserPtr(C_STATE_0);
if (!tmpID) return;
un = FindUnit (*tmpID);
if ((un) && (un->IsFlight ()))
{
flt=(Flight)un;
if (gActiveFlightID != *tmpID)
gActiveFlightID=*tmpID;
wp=flt->GetFirstUnitWP();
prevwp=wp;
i=1;
while(i < control->GetUserNumber(C_STATE_1) && wp)
{
prevwp=wp;
wp=wp->GetNextWP();
i++;
}
if(wp)
{
UpdateWaypointWindowInfo(win,wp,i);
win->RefreshWindow();
gMainHandler->ShowWindow(win);
gMainHandler->WindowToFront(win);
gActiveWPNum=control->GetUserNumber(C_STATE_1);
}
}
}
}
*/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void WaypointCB (long ID, short hittype, class C_Base *ctrl)
{
C_Window *win=NULL;
Unit un=NULL;
float wx=0.0F,wy=0.0F,wz=0.0F;
GridIndex gx=0,gy=0;
C_Waypoint *cwp=NULL;
WAYPOINTLIST *wpicon=NULL;
WayPointClass *wp=NULL;//,*lwp=NULL;
cwp = (C_Waypoint *) ctrl;
if(cwp)
wpicon=cwp->GetLast();
if(!cwp || !wpicon)
return;
// The reason I changed this routine... (And it didn't screw up the waypoints)... is because you guys took out
// the altitude part of this routine (probably Robin)...
// This routine is used for both XY draging AND Z dragging, and you guys just assumed it was used for
// XY only, which screwed everything else up.
// Therefore, the Check for DragXY & DragY (where DragY is for altitude)
// beyond that, there has been NO logic changes to this routine
if (hittype == C_TYPE_LDROP)
{
MonoPrint("TYPE_LDROP in WaypointCB\n");
// Drop and recalculate a waypoint if we're dropping a nub, otherwise
// Just relocate and recalculate the waypoint
un = (Unit)vuDatabase->Find(gMapMgr->GetCurWPID());
if (un)
{
gActiveFlightID = un->Id();
if (wpicon->Icon->GetUserNumber(C_STATE_1) < 0)
{
// KCK: Peter, this is pointless, as the campaign will just replan it,
// And will not do what you think it will.
// This MAY be pointless, however, if the user drags this... it might as well let them do it
// besides, it is used for the SIM CAS waypoint as well as the Alternate Landing strip
// If the Alternate landing (or tanker) can't be changed (ever) the dragging should be disabled,
// NOT the call saying to move it
// Divert WP in Flight
if(un->IsFlight())
{
wp=((Flight)un)->GetOverrideWP();
if(wp)
{
if(cwp->GetType() == C_TYPE_DRAGXY)
{
float x,y,z;
wx = wpicon->worldx;
wy = wpicon->worldy;
x = (float) cwp->GetUserNumber (C_STATE_0) - wy;
y = wx;
z = wp->GetWPAltitude() * -1.0F;
wp->SetLocation (x, y, z);
}
else if(cwp->GetType() == C_TYPE_DRAGY)
{
wp->SetWPAltitude(-1*FloatToInt32(wpicon->worldy));
}
}
}
}
else
{
if(cwp->GetType() == C_TYPE_DRAGXY)
{
// Standard WP or WP nub
wx = wpicon->worldx;
wy = gMapMgr->GetMaxY() - wpicon->worldy;
gx = SimToGrid(wx);
gy = SimToGrid(wy);
if (un->IsBattalion())
{
CampEnterCriticalSection();
tactical_set_orders((Battalion)un, FalconNullId, gx, gy);
CampLeaveCriticalSection();
return;
}
else if (un->IsFlight())
{
gActiveWPNum = static_cast<short>(ID & 0xff);
wp = get_current_waypoint();
if (wp)
{
if (ID & 0x40000000)
{
int alt = wp->GetWPAltitude();
WayPoint pw = wp->GetPrevWP();
if (pw)
{
if (pw->GetWPFlags() & WPF_HOLDCURRENT)
alt = pw->GetWPAltitude();
wp = un->AddWPAfter(pw,gx,gy,alt,FloatToInt32(wp->GetWPSpeed()),0,wp->GetWPRouteAction(),WP_NOTHING);
}
}
wp->SetWPLocation(gx,gy);
recalculate_waypoints(wp);
if (!(ID & 0x60000000))
{
DropWayPoint(wp);
// Look for the Triangle OR square... and move to this spot also
if(cwp->UpdateInfo(0x20000000 + ID,wpicon->worldx,wpicon->worldy))
cwp->Refresh();
}
}
}
}
else if(cwp->GetType() == C_TYPE_DRAGY)
{
// Standard WP or WP nub
wz = wpicon->worldy; // scale it
gActiveWPNum = static_cast<short>(ID & 0xff);
wp = get_current_waypoint();
if (wp)
{
wp->SetWPAltitude(-1*FloatToInt32(wpicon->worldy));
recalculate_waypoints(wp);
DropWayPoint(wp);
}
}
if(ID & 0x40000000)
PostMessage(gMainHandler->GetAppWnd(),FM_REBUILD_WP_LIST,0,0); // Have to do this because we can't delete the caller of this CB
}
if (TheCampaign.Flags & CAMP_TACTICAL_EDIT)
{
UI_Refresher *cur;
fixup_unit(un);
cur = (UI_Refresher*)gGps->Find(un->GetCampID());
if (cur)
cur->Update(un,0);
gMapMgr->GetCurWP()->Refresh();
}
un->MakeWaypointsDirty();
}
}
else if(hittype == C_TYPE_LMOUSEUP)
{
// Just activate this unit and waypoint
un = (Unit)vuDatabase->Find(gMapMgr->GetCurWPID());
if(!un)
return;
MonoPrint("TYPE_LMOUSEUP in WaypointCB\n");
if(un->IsFlight())
{
gActiveFlightID = un->Id();
if(!(ID & 0x40000000))
{
gActiveWPNum = static_cast<short>(ID & 0xff);
// gActiveWPNum=control->GetUserNumber(C_STATE_1);
wp = get_current_waypoint();
}
win=gMainHandler->FindWindow(FLIGHT_PLAN_WIN);
if(win && wp)
{
UpdateWaypointWindowInfo(win,wp,gActiveWPNum);
win->RefreshWindow();
gMainHandler->ShowWindow(win);
gMainHandler->WindowToFront(win);
}
}
}
else if(hittype == C_TYPE_LMOUSEDOWN)
{
// Just activate this unit and record the waypoint's current speed
if(!(ID & 0x40000000))
{
un = (Unit)vuDatabase->Find(gMapMgr->GetCurWPID());
if(!un)
return;
gActiveFlightID = un->Id();
gActiveWPNum = static_cast<short>(ID & 0xff);
wp = get_current_waypoint();
if (wp)
SetWPSpeed(wp);
}
}
else if (hittype == C_TYPE_MOUSEMOVE)
{
// Check for Waypoints vs distance boxes
if(!(ID & 0x40000000))
{
// Just update the waypoint's location and check for validity
un = (Unit)vuDatabase->Find(gMapMgr->GetCurWPID());
if(!un || !un->IsFlight())
return;
gActiveFlightID = un->Id();
gActiveWPNum = static_cast<short>(ID & 0xff);
wp = get_current_waypoint();
if (wp)
{
if(cwp->GetType() == C_TYPE_DRAGXY)
{
wx = wpicon->worldx;
wy = gMapMgr->GetMaxY() - wpicon->worldy;
gx = SimToGrid(wx);
gy = SimToGrid(wy);
wp->SetWPLocation(gx,gy);
}
else if(cwp->GetType() == C_TYPE_DRAGY)
{
wp->SetWPAltitude(-1*FloatToInt32(wpicon->worldy));
}
recalculate_waypoints(wp);
}
if (TheCampaign.Flags & CAMP_TACTICAL_EDIT)
{
UI_Refresher *cur;
fixup_unit (un);
cur = (UI_Refresher*)gGps->Find(un->GetCampID());
if (cur)
cur->Update(un,0);
gMapMgr->GetCurWP()->Refresh();
gMapMgr->GetCurWPZ()->Refresh();
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void update_active_flight (UnitClass *un)
{
if (gMapMgr && vuDatabase->Find(gActiveFlightID) == un)
{
gMapMgr->SetCurrentWaypointList(un->Id());
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -