// SHD.cpp : Defines the exported functions for the DLL application.
//
#define STRICT
#define ORBITER_MODULE
#include "D9base.h"
#include "UCGOCargoSDK.h"
#include "orbitersdk.h"
#include <math.h>
#include <stdio.h>
#include "OrbiterSoundSDK35.h"
#include "VesselAPI.h"
#define MY500METERSOUND 1 // those are definition so all function will be more clear to read..
#define MYRADARSOUND 2 // because we will know wich sound is concerned by function instead
#define MYEXTERNAL_UFO_FADEDSOUND 3 // of having simple number.
#define GEARUP 4
#define GEARDOWN 5
#define PLBAYAOPEN 6
#define PLBAYACLOSE 7
#define PLBAYBOPEN 8
#define PLBAYBCLOSE 9
HINSTANCE g_hDLL;
VISHANDLE MainExternalMeshVisual = 0;
// ==============================================================
// Airfoil definition
// ==============================================================
void Shuttle_MomentCoeff (double aoa,double M,double Re,double *cl,double *cm,double *cd)
{
int i;
const int nabsc = 7;
static const double AOA[nabsc] = {-180*RAD, -90*RAD,-30*RAD, 0*RAD, 60*RAD,90*RAD,180*RAD};
static const double CL[nabsc] = { 0, -0.0005, -0.001, 0, 0.0071, 0.0011, 0.00001};
static const double CM[nabsc] = { 0, 0, 0.0007, 0,-0.0010, 0, 0};
for (i = 0; i < nabsc-1 && AOA[i+1] < aoa; i++);
double f = (aoa-AOA[i]) / (AOA[i+1]-AOA[i]);
*cl = CL[i] + (CL[i+1]-CL[i]) * f; // aoa-dependent lift coefficient
*cm = CM[i] + (CM[i+1]-CM[i]) * f; // aoa-dependent moment coefficient
double saoa = sin(aoa);
double pd = 0.045 + 0.4*saoa*saoa; // profile drag
*cd = pd + oapiGetInducedDrag (*cl, 0.1,0.7) + oapiGetWaveDrag (M, 0.75, 1.0, 1.1, 0.04);
// profile drag + (lift-)induced drag + transonic/supersonic wave (compressibility) drag
}
ShuttleD::ShuttleD (OBJHANDLE hObj, int fmodel)
: VESSEL3 (hObj, fmodel)
{
GEAR_status = GEAR_UP;
GEAR_proc = 0.0;
PLBAYA_status = PLBAYA_UP;
PLBAYA_proc = 0.0;
PLBAYB_status = PLBAYB_UP;
PLBAYB_proc = 0.0;
O2Tank = 1000;
DefineAnimations();
}
//=========================================================
// Vessel Animations
//=========================================================
void ShuttleD::DefineAnimations()
{
//ANIMATIONCOMPONENT_HANDLE parent;
static UINT gearback[1] = {38};
static MGROUP_ROTATE gear (
0,
gearback,
1,
_V(0,-2.4,-27.97),
_V(1,0,0),
(float)(-90*RAD)
);
static UINT gearfront[1] = {39};
static MGROUP_ROTATE gearf (
0,
gearfront,
1,
_V(0,-2.4,24.73),
_V(1,0,0),
(float)(90*RAD)
);
anim_gear = CreateAnimation (0);
AddAnimationComponent (anim_gear, 0, 1, &gear);
AddAnimationComponent (anim_gear, 0, 1, &gearf);
static UINT PLBAYA[1] = {33};
static MGROUP_ROTATE PLBAYA1 (
0,
PLBAYA,
1,
_V(0.858,-1.821666,-5.07),
_V(0,0,1),
(float)(90*RAD)
);
anim_PLBAYA = CreateAnimation (0);
AddAnimationComponent (anim_PLBAYA, 0, 1, &PLBAYA1);
static UINT PLBAYB[1] = {29};
static MGROUP_ROTATE PLBAYB1 (
0,
PLBAYB,
1,
_V(0,4.413,-28.79),
_V(1,0,0),
(float)(-90*RAD)
);
anim_PLBAYB = CreateAnimation (0);
AddAnimationComponent (anim_PLBAYB, 0, 1, &PLBAYB1);
}
void ShuttleD::RevertGEAR (void)
{
GEAR_status = ((GEAR_status == GEAR_UP || GEAR_status == GEAR_RAISING) ?
GEAR_LOWERING : GEAR_RAISING);
}
void ShuttleD::RevertPLBAYA (void)
{
PLBAYA_status = ((PLBAYA_status == PLBAYA_UP || PLBAYA_status == PLBAYA_CLOSING) ?
PLBAYA_OPENING : PLBAYA_CLOSING);
}
void ShuttleD::RevertPLBAYB (void)
{
PLBAYB_status = ((PLBAYB_status == PLBAYB_UP || PLBAYB_status == PLBAYB_CLOSING) ?
PLBAYB_OPENING : PLBAYB_CLOSING);
}
void ShuttleD::SetUMMUAirlockPos(void)
{
int AirlockStatus=Crew.GetAirlockDoorState();
Crew.SetActiveDockForTransfer(iActiveDockNumber);
switch(iActiveDockNumber)
{
case 0:
Crew.DefineAirLockShape(TRUE,-1,1,-3.04,2.84, 23.93,26.93);
Crew.SetMembersPosRotOnEVA(_V(0,-0.937,25.935),_V(0,-225,0));
break;
case 1:
Crew.DefineAirLockShape(AirlockStatus, -1,1,2,4,-23,-21.6);
Crew.SetMembersPosRotOnEVA(_V(0,3.9,-22.568),_V(0,0,0));
break;
}
}
//=========================================================
// Vessel Capabilities
//=========================================================
void ShuttleD::clbkSetClassCaps (FILEHANDLE cfg)
{
Crew.InitUmmu(GetHandle());
float UMmuVersion=Crew.GetUserUMmuVersion();
// double UMmuVersion=Crew.GetUserUMmuVersion();
Crew.SetMaxSeatAvailableInShip(4);
Crew.DeclareActionArea(0,_V(2,-3.05,12.63),2.9,TRUE,"Sound\\ShuttleD\\ActionCommand.wav","Payload Bay A Activated");
Crew.DeclareActionArea(1,_V(0,3.120,-22.568),2.9,TRUE, "Sound\\ShuttleD\\ActionCommand.wav","Payload Bay B Activated");
Crew.DeclareActionArea(2,_V(0,-0.937,26.2),4.5,TRUE,"Sound\\ShuttleD\\ActionCommand.wav","Airlock Activated");
iActionAreaDemoStep=0; // this is just to show a feature of action area, see below "DetectActionAreaActivated"
SelectedUmmuMember =0; // our current selected member
// The HUD display method variables, see PDF doc
cUmmuHudDisplay[0] =0; // Initialisation of UMmu hud char variable
dHudMessageDelay =0; // Initialisation of UMmu delay variable
strcpy(SendHudMessage(),"Welcome aboard ! E=EVA 1,2=select UMmu\n A=Open/Close airlock S=info M=add crew");
// The Add mmu without scenery editor variable see PDF doc
cAddUMmuToVessel[0]=0;
//UCGO 2.0 Initialisation, cargo slot pos, rot declaration
hUcgo.Init(GetHandle());
// in contrary of the PDF code we declare 6 slots
// because it's fun :)
hUcgo.DeclareCargoSlot(0,_V(-0.65,-3.3,11.53),_V(0,0,270)); // slot 0
hUcgo.DeclareCargoSlot(1,_V(-0.65,-3.3,10.23),_V(0,0,270)); // slot 1
hUcgo.DeclareCargoSlot(2,_V(-0.65,-3.3,8.93),_V(0,0,270)); // slot 2
hUcgo.DeclareCargoSlot(3,_V(-0.65,-3.3,7.63),_V(0,0,270)); // slot 3
hUcgo.DeclareCargoSlot(4,_V(-0.65,-3.3,6.33),_V(0,0,270)); // slot 4
hUcgo.DeclareCargoSlot(5,_V(-0.65,-3.3,5.03),_V(0,0,270)); // slot 5
hUcgo.DeclareCargoSlot(6,_V(-0.65,-3.3,3.73),_V(0,0,270)); // slot 6
hUcgo.DeclareCargoSlot(7,_V(-0.65,-3.3,2.43),_V(0,0,270)); // slot 7
hUcgo.DeclareCargoSlot(8,_V(-0.65,-3.3,1.13),_V(0,0,270)); // slot 8
hUcgo.DeclareCargoSlot(9,_V(-0.65,-3.3,-0.17),_V(0,0,270)); // slot 9
hUcgo.DeclareCargoSlot(10,_V(-0.65,-3.3,-1.47),_V(0,0,270)); // slot 10
hUcgo.DeclareCargoSlot(11,_V(-0.65,-3.3,-2.77),_V(0,0,270)); // slot 11
hUcgo.DeclareCargoSlot(12,_V(-0.65,-3.3,-4.07),_V(0,0,270)); // slot 12
hUcgo.DeclareCargoSlot(13,_V(-0.65,-3.3,-5.37),_V(0,0,270)); // slot 13
hUcgo.DeclareCargoSlot(14,_V(-0.65,-3.3,-6.67),_V(0,0,270)); // slot 14
hUcgo.DeclareCargoSlot(15,_V(-0.65,-3.3,-7.97),_V(0,0,270)); // slot 15
hUcgo.DeclareCargoSlot(16,_V(-0.65,-3.3,-9.27),_V(0,0,270)); // slot 16
hUcgo.DeclareCargoSlot(17,_V(-0.65,-3.3,-10.57),_V(0,0,270)); // slot 17
hUcgo.SetSlotGroundReleasePos(0,_V(2,-3.6,11.53)); // slot 0
hUcgo.SetSlotGroundReleasePos(1,_V(2,-3.6,10.23)); // slot 1
hUcgo.SetSlotGroundReleasePos(2,_V(2,-3.6,8.93)); // slot 2
hUcgo.SetSlotGroundReleasePos(3,_V(2,-3.6,7.63)); // slot 3
hUcgo.SetSlotGroundReleasePos(4,_V(2,-3.6,6.33)); // slot 4
hUcgo.SetSlotGroundReleasePos(5,_V(2,-3.6,5.03)); // slot 5
hUcgo.SetSlotGroundReleasePos(6,_V(2,-3.6,3.73)); // slot 6
hUcgo.SetSlotGroundReleasePos(7,_V(2,-3.6,2.43)); // slot 7
hUcgo.SetSlotGroundReleasePos(8,_V(2,-3.6,1.13)); // slot 8
hUcgo.SetSlotGroundReleasePos(9,_V(2,-3.6,-0.17)); // slot 9
hUcgo.SetSlotGroundReleasePos(10,_V(2,-3.6,-1.47)); // slot 10
hUcgo.SetSlotGroundReleasePos(11,_V(2,-3.6,-2.77)); // slot 11
hUcgo.SetSlotGroundReleasePos(12,_V(2,-3.6,-4.07)); // slot 12
hUcgo.SetSlotGroundReleasePos(13,_V(2,-3.6,-5.37)); // slot 13
hUcgo.SetSlotGroundReleasePos(14,_V(2,-3.6,-6.67)); // slot 14
hUcgo.SetSlotGroundReleasePos(15,_V(2,-3.6,-7.97)); // slot 15
hUcgo.SetSlotGroundReleasePos(16,_V(2,-3.6,-9.27)); // slot 16
hUcgo.SetSlotGroundReleasePos(17,_V(2,-3.6,-10.57)); // slot 17
// UCGO 2.0 Parameters settings
hUcgo.SetReleaseSpeedInSpace(0.001f); // release speed of cargo in space in m/s
hUcgo.SetMaxCargoMassAcceptable(50000.0); // max cargo mass in kg that your vessel can carry
hUcgo.SetGrappleDistance(60); // grapple distance radius in meter from center of ship
// UCGO Variables initialisation
cCargoHudDisplay[0]=0; // Cargo hud display char variable
dCargHudMessageDelay=0; // Cargo hud display delay
iSelectedCargo=-1; // for the selection of cargos (-1 mean "default" see header)
// welcome message with keys for users
strcpy(SendCargHudMessage(),"Cargo key: C/SHF+C = grapple/release, 9/SHF+9 = snc editor add cargo, 8=infos on cargos");
THRUSTER_HANDLE th_main, th_hover, th_rcs[14], th_group[4];
DOCKHANDLE Dock0, Dock1;
iActiveDockNumber = 0;
SetUMMUAirlockPos();
// ************************ Airfoil ****************************
ClearAirfoilDefinitions();
CreateAirfoil (LIFT_VERTICAL, _V(0,0,0), Shuttle_MomentCoeff, 8, 140, 0.1);
// vessel caps definitions
AddMesh ("Shuttle-D");
SetMeshVisibilityMode (AddMesh (DVCInterior = oapiLoadMeshGlobal ("ShuttleDVC")), MESHVIS_VC);
SetCameraOffset (_V(0,0.14,24.13));
SetAlbedoRGB (_V(0.77,0.20,0.73));
SetSize (EXP_SIZE);
SetEmptyMass (EXP_EMPTYMASS + O2Tank);
void UpdateEmptyMass(void);
SetPMI (EXP_PMI);
SetCrossSections (EXP_CS);
SetSurfaceFrictionCoeff (0.55, 0.79);
SetRotDrag (_V(0.9, 0.76, 0.2));
EnableTransponder (true);
InitNavRadios (4);
// propellant resources
PROPELLANT_HANDLE MainFuel = CreatePropellantResource (EXP_FUELMASS);
PROPELLANT_HANDLE RCS1 = CreatePropellantResource (EXP_RCS1FUELMASS);
PROPELLANT_HANDLE RCS2 = CreatePropellantResource (EXP_RCS2FUELMASS);
PROPELLANT_HANDLE RCS3 = CreatePropellantResource (EXP_RCS3FUELMASS);
PROPELLANT_HANDLE RCS4 = CreatePropellantResource (EXP_RCS4FUELMASS);
PROPELLANT_HANDLE RCS5 = CreatePropellantResource (EXP_RCS5FUELMASS);
PROPELLANT_HANDLE RCS6 = CreatePropellantResource (EXP_RCS6FUELMASS);
PROPELLANT_HANDLE RCS7 = CreatePropellantResource (EXP_RCS7FUELMASS);
PROPELLANT_HANDLE RCS8 = CreatePropellantResource (EXP_RCS8FUELMASS);
PROPELLANT_HANDLE RCS9 = CreatePropellantResource (EXP_RCS9FUELMASS);
PROPELLANT_HANDLE RCS10 = CreatePropellantResource (EXP_RCS10FUELMASS);
PROPELLANT_HANDLE RCS11 = CreatePropellantResource (EXP_RCS11FUELMASS);
PROPELLANT_HANDLE RCS12 = CreatePropellantResource (EXP_RCS12FUELMASS);
PROPELLANT_HANDLE RCSRES = CreatePropellantResource (EXP_RCSRESFUELMASS);
// main engine
th_main = CreateThruster (_V(0,0,-36.52), _V(0,0,1), EXP_MAXMAINTH, MainFuel, VACSHD_ISP, NMLSHD_ISP, P_NML);
CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
AddExhaust (th_main, 18, 5, _V(0,0.13,-36.52), _V(0,0,-1));
PARTICLESTREAMSPEC contrail_main = {
0, 5.0, 16, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
};
PARTICLESTREAMSPEC exhaust_main = {
0, 2.0, 20, 200, 0.05, 0.1, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
};
AddExhaustStream (th_main, _V(0,0.13,-36.52), &contrail_main);
AddExhaustStream (th_main, _V(0,0.13,-36.52), &exhaust_main);
// hover engine
th_hover = CreateThruster (_V(0,-2.94,0), _V(0,1,0), EXP_MAXHOVERTH, MainFuel, VACSHD_ISP, NMLSHD_ISP, P_NML);
CreateThrusterGroup (&th_hover, 1, THGROUP_HOVER);
AddExhaust (th_hover, 8, 1, _V(0.0,-3.04,-22.16), _V(0,-1,0));
AddExhaust (th_hover, 11.05675834, 1, _V(0.0,-3.04,18.55), _V(0,-1,0));
PARTICLESTREAMSPEC contrail_hover = {
0, 5.0, 8, 200, 0.15, 1.0, 5, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
};
PARTICLESTREAMSPEC exhaust_hover = {
0, 2.0, 10, 200, 0.05, 0.05, 8, 1.0, PARTICLESTREAMSPEC::EMISSIVE,
PARTICLESTREAMSPEC::LVL_SQRT, 0, 1,
PARTICLESTREAMSPEC::ATM_PLOG, 1e-5, 0.1
};
AddExhaustStream (th_hover, _V(0,-3.04, 18.55), &contrail_hover);
AddExhaustStream (th_hover, _V(0,-3.04,-22.16), &contrail_hover);
AddExhaustStream (th_hover, _V(0,-3.04, 18.55), &exhaust_hover);
AddExhaustStream (th_hover, _V(0,-3.04,-22.16), &exhaust_hover);
// RCS engines
th_rcs[0] = CreateThruster (_V( 1.601,0, 24.707), _V(0,0,1), RCSTH0, RCS1, VACSHD_ISP, NMLSHD_ISP, P_NML);//CM FRONT RIGHT SIDE FORWARD
th_rcs[1] = CreateThruster (_V( -1.601,0, 24.707), _V(0,0,1), RCSTH1, RCS2, VACSHD_ISP, NMLSHD_ISP, P_NML);//CM FRONT LEFT SIDE FORWARD
th_rcs[2] = CreateThruster (_V(1.8505,0, 24.299), _V(-1, 0,0), RCSTH2, RCS1, VACSHD_ISP, NMLSHD_ISP, P_NML);//CM FRONT RIGHT SIDE RIGHT
th_rcs[3] = CreateThruster (_V(-1.8505,0, 24.299), _V(1,0,0), RCSTH3, RCS2, VACSHD_ISP, NMLSHD_ISP, P_NML);//CM FRONT LEFT SIDE LEFT
th_rcs[4] = CreateThruster (_V( 1.171,1.94,16.182), _V(0, 1,0), RCSTH4, RCS3, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS FORWARD RIGHT SIDE UP
th_rcs[5] = CreateThruster (_V( -1.171,1.94,16.182), _V(0,1,0), RCSTH5, RCS4, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS FORWARD LEFT SIDE UP
th_rcs[6] = CreateThruster (_V(1.171,-1.836,16.182), _V(0,-1,0), RCSTH6, RCS5, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS FORWARD RIGHT SIDE DOWN
th_rcs[7] = CreateThruster (_V(-1.171,-1.836,16.182), _V(0,-1,0), RCSTH7, RCS6, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS FORWARD LEFT SIDE DOWN
th_rcs[8] = CreateThruster (_V( 1.171,1.94, -16.125), _V(0,1,0), RCSTH8, RCS7, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS AFT RIGHT SIDE UP
th_rcs[9] = CreateThruster (_V( -1.171,1.94, -16.125), _V( 0,1,0), RCSTH9, RCS8, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS AFT LEFT SIDE UP
th_rcs[10] = CreateThruster (_V(1.171,-1.836,-16.125), _V(0,-1,0), RCSTH10, RCS9, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS AFT RIGHT SIDE DOWN
th_rcs[11] = CreateThruster (_V(-1.171,-1.836,-16.125), _V( 0,-1,0), RCSTH11, RCS10, VACSHD_ISP, NMLSHD_ISP, P_NML);//TRUSS AFT LEFT SIDE DOWN
th_rcs[12] = CreateThruster (_V( 1.89,0,-29.371), _V(0,0, -1), RCSTH12, RCS11, VACSHD_ISP, NMLSHD_ISP, P_NML);//SM BACK RIGHT SIDE BACKWARDS
th_rcs[13] = CreateThruster (_V( -1.89,0,-29.371), _V(0,0,-1), RCSTH13, RCS12, VACSHD_ISP, NMLSHD_ISP, P_NML);//SM BACK LEFT SIDE BACKWARDS
th_rcs[14] = CreateThruster (_V(2.22,0,-28.963), _V( -1,0,0), RCSTH14, RCS11, VACSHD_ISP, NMLSHD_ISP, P_NML);//SM BACK RIGHT SIDE RIGHT
th_rcs[15] = CreateThruster (_V(-2.22,0,-28.963), _V(1,0, 0), RCSTH15, RCS12, VACSHD_ISP, NMLSHD_ISP, P_NML);//SM BACK LEFT SIDE LEFT
AddExhaust (th_rcs[12], 0.6, 0.078, _V( 1.601,0,24.707), _V(0,0,1));
AddExhaust (th_rcs[13], 0.6, 0.078, _V( -1.601,0,24.707), _V(0,0,1));
AddExhaust (th_rcs[2], 0.79, 0.103, _V(1.8905,0, 24.299), _V(-1, 0,0));
AddExhaust (th_rcs[3], 0.79, 0.103, _V(-1.8905,0, 24.299), _V(1,0,0));
AddExhaust (th_rcs[6], 0.6, 0.078, _V( 1.171,1.94,16.182), _V(0, 1,0));
AddExhaust (th_rcs[7], 0.6, 0.078, _V( -1.171,1.94,16.182), _V(0,1,0));
AddExhaust (th_rcs[4], 0.79, 0.103, _V(1.171,-1.836,16.182), _V(0,-1,0));
AddExhaust (th_rcs[5], 0.79, 0.103, _V(-1.171,-1.836,16.182), _V(0,-1,0));
AddExhaust (th_rcs[10], 0.6, 0.078, _V( 1.171,1.94, -16.125), _V(0,1,0));
AddExhaust (th_rcs[11], 0.6, 0.078, _V( -1.171,1.94, -16.125), _V( 0,1,0));
AddExhaust (th_rcs[8], 0.79, 0.103, _V(1.171,-1.836,-16.125), _V(0,-1,0));
AddExhaust (th_rcs[9], 0.79, 0.103, _V(-1.171,-1.836,-16.125), _V( 0,-1,0));
AddExhaust (th_rcs[0], 0.6, 0.078, _V( 1.89,0,-29.371), _V(0,0, -1));
AddExhaust (th_rcs[1], 0.6, 0.078, _V( -1.89,0,-29.371), _V(0,0,-1));
AddExhaust (th_rcs[14], 0.79, 0.103, _V(2.22,0,-28.963), _V( -1,0,0));
AddExhaust (th_rcs[15], 0.79, 0.103, _V(-2.22,0,-28.963), _V(1,0, 0));
th_group[0] = th_rcs[4];
th_group[1] = th_rcs[5];
th_group[2] = th_rcs[10];
th_group[3] = th_rcs[11];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHUP);
th_group[0] = th_rcs[6];
th_group[1] = th_rcs[7];
th_group[2] = th_rcs[8];
th_group[3] = th_rcs[9];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHDOWN);
th_group[0] = th_rcs[4];
th_group[1] = th_rcs[7];
th_group[2] = th_rcs[8];
th_group[3] = th_rcs[11];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKLEFT);
th_group[0] = th_rcs[5];
th_group[1] = th_rcs[6];
th_group[2] = th_rcs[9];
th_group[3] = th_rcs[10];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKRIGHT);
th_group[0] = th_rcs[4];
th_group[1] = th_rcs[5];
th_group[2] = th_rcs[8];
th_group[3] = th_rcs[9];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);
th_group[0] = th_rcs[6];
th_group[1] = th_rcs[7];
th_group[2] = th_rcs[10];
th_group[3] = th_rcs[11];
CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN);
th_group[0] = th_rcs[2];
th_group[1] = th_rcs[15];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);
th_group[0] = th_rcs[3];
th_group[1] = th_rcs[14];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);
th_group[0] = th_rcs[2];
th_group[1] = th_rcs[14];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_LEFT);
th_group[0] = th_rcs[3];
th_group[1] = th_rcs[15];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_RIGHT);
th_group[0] = th_rcs[0];
th_group[1] = th_rcs[1];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_FORWARD);
th_group[0] = th_rcs[12];
th_group[1] = th_rcs[13];
CreateThrusterGroup (th_group, 2, THGROUP_ATT_BACK);
Dock0 = CreateDock(_V(0,-0.737,25.385),_V(0,0,1),_V(0,1,0));
Dock1 = CreateDock(_V(0,2.630,-22.568),_V(0,1,0),_V(0,0,1));
// ************************ Attachment points ****************************
// char attach_id[8]={"SH"};
//
// payload_attachment[0] = CreateAttachment (false,_V(1.76f,0.0f,-7.000f),_V(0.0f,0.0f,-1.0f),_V(0.0f,1.0f,0.0f),attach_id);
// payload_attachment[1] = CreateAttachment (false,_V(-1.76f,0.0f,-7.000f),_V(0.0f,0.0f,-1.0f),_V(0.0f,1.0f,0.0f),attach_id);
}
void ShuttleD::clbkMFDMode (int mfd, int mode)
{
// When an MFD changes mode (either in Panel or VC modes), this call back is
// invoked. Here, it is a general TriggerRedrawArea function used, which can
// be used to redraw MFD's for VC or Panel views. You can just as effectively
// use oapiTriggerVCRedrawArea for this ship, however, as there is no 2D panel.
switch (mfd) {
case MFD_LEFT:
oapiTriggerRedrawArea (1, 2, AID_MFD1_LBUTTONS);
oapiTriggerRedrawArea (1, 3, AID_MFD1_RBUTTONS);
break;
case MFD_RIGHT:
oapiTriggerRedrawArea (1, 2, AID_MFD2_LBUTTONS);
oapiTriggerRedrawArea (1, 3, AID_MFD2_RBUTTONS);
}
}
//-------------------------------------------------------------------------
bool ShuttleD::clbkLoadVC (int id)
{
// VCHUDSPEC hud;
VCMFDSPEC mfd;
oapiVCRegisterMFD(0,&mfd);
// mfd.ngroup=19;
// mfd.nmesh=1;
oapiVCRegisterMFD(1,&mfd);
static VCHUDSPEC hud_pilot = {1, 4,{0.55,1.94,24.4162},1.12999};
static VCHUDSPEC hud_copilot = {1, 4,{-0.55,1.94,24.4162},1.12999};
static VCHUDSPEC hud_fdeckfloor = {1, 4,{0.55,1.94,23.86},1.12999};
// oapiVCRegisterHUD (&hud_pilot); // HUD parameters
mfds_right.nmesh = 1; // The mesh number (the first one loaded, or 0, in this case).
mfds_right.ngroup = 19; // The mesh group that is the MFD screen in the above identified mesh.
mfds_left.nmesh = 1; // The mesh number (the first one loaded, or 0, in this case).
mfds_left.ngroup = 18; // The mesh group that is the MFD screen in the above identified mesh.
SetCameraDefaultDirection(_V(0, 0, 1)); // View angles down so you can see the
// MFD in VC view by default (it is the sine and cosine of 11º in Y and Z, respectively).
SURFHANDLE MFDbuttons1 = oapiGetTextureHandle (DVCInterior,12);
// Get the MFDButtons.dds D texture for redrawing purposes.
int i;
switch (id) {
case 0: // The first VC cockpit view (id 0). Carefull with mixing up id.
// There are more references to id in the code, but what they identify is
// according to the specific callback. For example, in clbkVCMouseEvent,
// id is the identity of the MFD buttons, not the cockpit view.
SetCameraOffset (_V(0.50,1.94,22.86));
SetCameraRotationRange (RAD*120, RAD*120, RAD*180, RAD*100);
SetCameraShiftRange (_V(0,0,0.1), _V(-0.2,0,0), _V(0.05,0,0));
oapiVCSetNeighbours (1, -1, -1, 2);
oapiVCRegisterMFD (MFD_LEFT, &mfds_left);
oapiVCRegisterMFD (MFD_RIGHT, &mfds_right);
oapiVCRegisterHUD (&hud_pilot); // HUD parameters
// oapiVCRegisterSYSTAT (&systat_pilot); // Sytem Display parameters
// Register main panel SYSTAT display
oapiVCRegisterArea (AID_MFD1_LBUTTONS, _R( 0, 0, 32, 220), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, MFDbuttons1);
oapiVCRegisterArea (AID_MFD1_RBUTTONS, _R( 32, 0, 64, 220), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, MFDbuttons1);
oapiVCRegisterArea (AID_MFD2_LBUTTONS, _R( 0, 0, 32, 220), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, MFDbuttons1);
oapiVCRegisterArea (AID_MFD2_RBUTTONS, _R( 32, 0, 64, 220), PANEL_REDRAW_USER, PANEL_MOUSE_IGNORE, PANEL_MAP_BACKGROUND, MFDbuttons1);
// These area registrations are for redrawing purposes only, and are used by
// the clbkVCRedrawEvent. The _R(X1, Y1, X2, Y2) coordinates pertain to the
// texture coordinates on the MFDButtons.dds texture (in PIXELS), which is the
// dynamic texture that SURFHANDLE MFDbuttons1 gets from the mesh file.
// Note that as the bottom buttons are not ever redrawn, no registration of
// them for texture coords is needed.
// Have a look at the clbkMFDMode and clbkVCRedrawEvent.
// The only areas triggered for redrawing and then redrawn are
// those two registered above (AID_MFD1_LBUTTONS and AID_MFD1_RBUTTONS.
// And have a look at the definitions in the AstroMatiz.h file. You will see their
// id's that are passed to the preprocessor during compile.
// For reference, here are the rectangular area 3D coordinates of the
// left, right and bottom MFD buttons, in MESH coordinates. You WILL need to
// get this info, if you want to make your own VC work properly.
// (Use Meshwizard, or go into the mesh file itself and find them).
// The mesh area of the 6 left buttons of MFD_LEFT
// _V(-0.32f, 0.067f, 0.654f),
// _V(-0.30f, 0.067f, 0.654f),
// _V(-0.32f, -0.080f, 0.643f),
// _V(-0.30f, -0.080f, 0.643f));
// The mesh area of the 6 right buttons of MFD_LEFT
// _V(-0.117f, 0.067f, 0.654f),
// _V(-0.097f, 0.067f, 0.654f),
// _V(-0.117f, -0.080f, 0.643f),
// _V(-0.097f, -0.080f, 0.643f));
// The mesh area of the three bottom buttons of MFD_LEFT
// _V(-0.267f, -0.095f, 0.642f),
// _V(-0.158f, -0.095f, 0.642f),
// _V(-0.267f, -0.114f, 0.641f),
// _V(-0.158f, -0.114f, 0.641f));
for (i = 0; i < 6; i++) {
oapiVCRegisterArea (MFD1_LBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD1_LBUTTON1+i, _V(-0.07125, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
oapiVCRegisterArea (MFD1_RBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD1_RBUTTON1+i, _V(0.25895, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
}
// Define the area for mouse events on each button of left and right columns.
for (i = 0; i < 3; i++) {
oapiVCRegisterArea (MFD1_BBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD1_BBUTTON1+i, _V(0.05295 + (i * 0.0387), 2.2081, 23.87965), 0.0300);
}
for (i = 0; i < 6; i++) {
oapiVCRegisterArea (MFD2_LBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD2_LBUTTON1+i, _V(0.27325, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
oapiVCRegisterArea (MFD2_RBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD2_RBUTTON1+i, _V(0.60355, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
}
// Define the area for mouse events on each button of left and right columns.
for (i = 0; i < 3; i++) {
oapiVCRegisterArea (MFD2_BBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD2_BBUTTON1+i, _V(0.3975 + (i * 0.0387), 2.2081, 23.87965), 0.0300);
}
// Define the area for mouse events on the bottom buttons. Coordinates are in
// mesh 3D coords (see why you needed to get this info?)
campos = CAM_VCPILOT;
break;
case 1: // front left passenger
SetCameraOffset (_V(-0.55,1.94,22.86));
SetCameraRotationRange (RAD*120, RAD*120, RAD*100, RAD*180);
SetCameraShiftRange (_V(0,0,0.1), _V(-0.05,0,0), _V(0.2,0,0));
// SetCameraMovement (_V(0.2,-0.05,0.3), -10*RAD, 10*RAD, _V(-0.3,0,0), 80*RAD, 0, _V(0.4,0,0), -90*RAD, 0);
oapiVCSetNeighbours (-1, 0, -1, 2);
oapiVCRegisterHUD (&hud_copilot); // HUD parameters
oapiVCRegisterMFD (MFD_LEFT, &mfds_left);
oapiVCRegisterMFD (MFD_RIGHT, &mfds_right);
for (i = 0; i < 6; i++) {
oapiVCRegisterArea (MFD1_LBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD1_LBUTTON1+i, _V(-0.07125, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
oapiVCRegisterArea (MFD1_RBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD1_RBUTTON1+i, _V(0.25895, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
}
// Define the area for mouse events on each button of left and right columns.
for (i = 0; i < 3; i++) {
oapiVCRegisterArea (MFD1_BBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD1_BBUTTON1+i, _V(0.05295 + (i * 0.0387), 2.2081, 23.87965), 0.0300);
}
for (i = 0; i < 6; i++) {
oapiVCRegisterArea (MFD2_LBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD2_LBUTTON1+i, _V(0.29325, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
oapiVCRegisterArea (MFD2_RBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD2_RBUTTON1+i, _V(0.62355, 2.4464 - (i *0.0352), 23.77135 + (i *0.0161)), 0.0300);
}
// Define the area for mouse events on each button of left and right columns.
for (i = 0; i < 3; i++) {
oapiVCRegisterArea (MFD2_BBUTTON1+i, PANEL_REDRAW_NEVER, PANEL_MOUSE_LBDOWN);
oapiVCSetAreaClickmode_Spherical(MFD2_BBUTTON1+i, _V(0.4175 + (i * 0.0387), 2.2081, 23.87965), 0.0300);
}
// Define the area for mouse events on the bottom buttons. Coordinates are in
// mesh 3D coords (see why you needed to get this info?)
campos = CAM_VCPSNGR1;
break;
case 2: // front right passenger
SetCameraOffset (_V(0,-0.3,22.86));
SetCameraRotationRange (RAD*180, RAD*70, RAD*100, RAD*100);
SetCameraShiftRange (_V(0,0,0.1), _V(-0.05,0,0), _V(0.05,0,0));
oapiVCSetNeighbours (1, 0, -1, 3);
oapiVCRegisterHUD (&hud_fdeckfloor); // HUD parameters
oapiVCRegisterMFD (MFD_LEFT, &mfds_left);
oapiVCRegisterMFD (MFD_RIGHT, &mfds_right);
// oapiVCRegisterSYSTAT (&systat_fdeckfloor); // Sytem Display parameters
campos = CAM_VCPSNGR2;
break;
case 3: // rear left passenger
SetCameraOffset (_V(0.5, -0.1, -0.67));
SetCameraRotationRange (RAD*180, RAD*70, RAD*270, RAD*100);
SetCameraShiftRange (_V(0,0,10.0), _V(-0.05,0,0), _V(0.05,0,0));
oapiVCSetNeighbours (-1, -1, 2, 4);
campos = CAM_VCPSNGR3;
break;
case 4: // rear right passenger
SetCameraOffset (_V(0, 0.1, -23.07));
SetCameraRotationRange (RAD*180, RAD*180, RAD*180, RAD*180);
SetCameraShiftRange (_V(0,0,1.0), _V(-0.05,0,0), _V(0.05,0,0));
oapiVCSetNeighbours (-1, -1, 3, -1);
campos = CAM_VCPSNGR4;
return true;
};
return true;
}
bool ShuttleD::clbkDrawHUD(int mode, const HUDPAINTSPEC *hps, oapi::Sketchpad *skp)
{
// draw the default HUD
VESSEL3::clbkDrawHUD (mode, hps, skp);
// UMmu display messages
if(dHudMessageDelay>0)
{
skp->Text(5,hps->H/60*25,cUmmuHudDisplay,strlen(cUmmuHudDisplay));
dHudMessageDelay-=oapiGetSimStep();
if(dHudMessageDelay<0)
dHudMessageDelay=0;
}
// UCGO display messages
if(dCargHudMessageDelay>0)
{
skp->Text(5,hps->H/60*15,cCargoHudDisplay,strlen(cCargoHudDisplay));
dCargHudMessageDelay-=oapiGetSimStep();
if(dCargHudMessageDelay<0)
dCargHudMessageDelay=0;
}
return true;
}
char *ShuttleD::SendHudMessage() //<---- Change the class name here
{
dHudMessageDelay=15;
return cUmmuHudDisplay;
}
//-------------------------------------------------------------------------
bool ShuttleD::clbkVCMouseEvent (int id, int event, VECTOR3 &p)
{
if ((id) >= MFD1_LBUTTON1 && (id) < MFD1_LBUTTON1 + 12)
{
oapiProcessMFDButton (MFD_LEFT, id - MFD1_LBUTTON1, event);
return true;
}
// Processes the events for mouse clicks on VC view MFD buttons, left and
// right columns, by matching the id of the event to the #defined identifier of
// the button (see AstroMatiz.h file).
if ((id) == MFD1_BBUTTON1)
{
oapiToggleMFD_on (MFD_LEFT);
return true;
}
// The ON / OFF button (left MFD button on the bottom).
if ((id) == MFD1_BBUTTON2)
{
oapiSendMFDKey (MFD_LEFT, OAPI_KEY_F1);
return true;
}
// The MODE button (center MFD button on the bottom).
if ((id) == MFD1_BBUTTON3)
{
oapiSendMFDKey (MFD_LEFT, OAPI_KEY_GRAVE);
return true;
}
// The MENU button (right MFD button on the bottom).
if ((id) >= MFD2_LBUTTON1 && (id) < MFD2_LBUTTON1 + 12)
{
oapiProcessMFDButton (MFD_RIGHT, id - MFD2_LBUTTON1, event);
return true;
}
// Processes the events for mouse clicks on VC view MFD buttons, left and
// right columns, by matching the id of the event to the #defined identifier of
// the button (see AstroMatiz.h file).
if ((id) == MFD2_BBUTTON1)
{
oapiToggleMFD_on (MFD_RIGHT);
return true;
}
// The ON / OFF button (left MFD button on the bottom).
if ((id) == MFD2_BBUTTON2)
{
oapiSendMFDKey (MFD_RIGHT, OAPI_KEY_F1);
return true;
}
// The MODE button (center MFD button on the bottom).
if ((id) == MFD2_BBUTTON3)
{
oapiSendMFDKey (MFD_RIGHT, OAPI_KEY_GRAVE);
return true;
}
// The MENU button (right MFD button on the bottom).
return false;
}
//-------------------------------------------------------------------------
bool ShuttleD::clbkVCRedrawEvent (int id, int event, SURFHANDLE surf)
{
int bt, side;
switch (id) {
const char *label;
case AID_MFD1_LBUTTONS:
case AID_MFD1_RBUTTONS:
side = (id == AID_MFD1_LBUTTONS ? 0: 1);
HDC hDC = oapiGetDC (surf);
SelectObject (hDC, hFont);
SetTextColor (hDC, RGB(250, 250, 100));
SetTextAlign (hDC, TA_CENTER);
SetBkMode (hDC, TRANSPARENT);
for (bt = 0; bt < 6; bt++) {
if (label = oapiMFDButtonLabel (MFD_LEFT, bt+side*6))
TextOut (hDC, 16, 8+36*bt, label, strlen(label));
else break;
}
oapiReleaseDC (surf, hDC);
return true;
}
return false;
// This redraw business is the most complicated thing about making VC's. This is
// where the registered areas AID_MFD1_LBUTTONS and AID_MFD1_RBUTTONS are used.
// This part has absolutely nothing to do with triggering mouse events. It is
// ONLY blitting your MFDButtons texture on the buttons again, but with text on it.
// Important points with this issue are;
// 1. Get your mesh UV coordinates right for the mesh. DON'T get is backwards.
// 2. Make sure your texture is dynamic (just D suffix it in the mesh file).
// 3. Get the texture in the program (in clbkLoadVC) as a SURFHANDLE.
};
//=========================================================
// Vessel Load and Save Parameters
//=========================================================
void ShuttleD::clbkLoadStateEx (FILEHANDLE scn, void *status)
{
char *line;
while (oapiReadScenario_nextline (scn, line))
{
if (!_strnicmp (line, "GEAR", 4)) {
sscanf (line+4, "%d%lf", &GEAR_status, &GEAR_proc);
}
if (!_strnicmp (line, "PLBAYA", 6)) {
sscanf (line+6, "%d%lf", &PLBAYA_status, &PLBAYA_proc);
}
if (!_strnicmp (line, "PLBAYB", 6)) {
sscanf (line+6, "%d%lf", &PLBAYB_status, &PLBAYB_proc);
}
if (!_strnicmp (line, "O2Tank", 6)) {
sscanf (line+6, "%lf", &O2Tank);
}
if(Crew.LoadAllMembersFromOrbiterScenario(line)==TRUE)
continue;
// Load UCGO 2.0 cargo from scenario
if(hUcgo.LoadCargoFromScenario(line)==TRUE) // UCGO load cargo
continue;
ParseScenarioLineEx (line, status);
}
SetAnimation (anim_gear, GEAR_proc);
SetAnimation (anim_PLBAYA, PLBAYA_proc);
SetAnimation (anim_PLBAYB, PLBAYB_proc);
}
void ShuttleD::clbkSaveState (FILEHANDLE scn)
{
char cbuf[256];
VESSEL3::clbkSaveState (scn);
sprintf (cbuf, "%d %0.4f", GEAR_status, GEAR_proc);
oapiWriteScenario_string (scn, "GEAR", cbuf);
sprintf (cbuf, "%d %0.4f", PLBAYA_status, PLBAYA_proc);
oapiWriteScenario_string (scn, "PLBAYA", cbuf);
sprintf (cbuf, "%d %0.4f", PLBAYB_status, PLBAYB_proc);
oapiWriteScenario_string (scn, "PLBAYB", cbuf);
sprintf (cbuf, "%0.4f", O2Tank);
oapiWriteScenario_string (scn, "O2Tank", cbuf);
Crew.SaveAllMembersInOrbiterScenarios(scn);
// Save UCGO 2.0 cargo in scenario
hUcgo.SaveCargoToScenario(scn);
}
// --------------------------------------------------------------
// clbkVisualCreated
// --------------------------------------------------------------
void ShuttleD::clbkVisualCreated (VISHANDLE vis, int refcount)
{
hUcgo.SetUcgoVisual(vis); // must be called in clbkVisualCreated.
}
////////////////////////////////////////////////////////
// SendCargHudMessage
////////////////////////////////////////////////////////
char *ShuttleD::SendCargHudMessage(void)
{
dCargHudMessageDelay=15; // 15 seconds display delay for msg
return cCargoHudDisplay;
}
//=========================================================
// Animation Template
//=========================================================
void ShuttleD::clbkPostStep(double simt, double simdt, double mjd)
{
// double OxygenLevel = GetPropellantMass(O2Tank);
// double CrewNumber = Crew.GetCrewTotalNumber();
// double OxygenConsumption = 1.2*CrewNumber;
int ReturnCode=Crew.ProcessUniversalMMu();
switch(ReturnCode)
{
case UMMU_TRANSFERED_TO_OUR_SHIP:
sprintf(SendHudMessage(),"%s \"%s\" aged %i was transfered to our ship",
Crew.GetCrewMiscIdByName(Crew.GetLastEnteredCrewName()),Crew.GetLastEnteredCrewName()
,Crew.GetCrewAgeByName(Crew.GetLastEnteredCrewName()));
break;
case UMMU_RETURNED_TO_OUR_SHIP:
sprintf(SendHudMessage(),"%s \"%s\" aged %i entered into our ship",
Crew.GetCrewMiscIdByName(Crew.GetLastEnteredCrewName()),
Crew.GetLastEnteredCrewName(),Crew.GetCrewAgeByName(Crew.GetLastEnteredCrewName()));
break;
}
int ActionAreaReturnCode=Crew.DetectActionAreaActivated();
if(ActionAreaReturnCode>-1)
{
// this is just an example, we have four area declared
// action area ID 0 triggered
if(ActionAreaReturnCode==0)
{
RevertPLBAYA();
}
// action area ID 1 triggered
else if(ActionAreaReturnCode==1)
{
RevertPLBAYB();
}
// action area ID 2 triggered
else if(ActionAreaReturnCode==2)
{
// switch state
Crew.SetAirlockDoorState(!Crew.GetAirlockDoorState());
// display state
if(Crew.GetAirlockDoorState()==TRUE)
strcpy(SendHudMessage(),"Airlock is now open");
else
strcpy(SendHudMessage(),"Airlock is now closed");
}
}
if (GEAR_status >= GEAR_RAISING) {
double da = simdt * GEAR_OPERATING_SPEED;
if (GEAR_status == GEAR_RAISING) {
if (GEAR_proc > 0.0) GEAR_proc = max (0.0, GEAR_proc-da);
else GEAR_status = GEAR_UP;
} else {
if (GEAR_proc < 1.0) GEAR_proc = min (1.0, GEAR_proc+da);
else GEAR_status = GEAR_DOWN;
}
SetAnimation (anim_gear, GEAR_proc);
}
SetTouchdownPoints (_V(0,-4.89+GEAR_proc*0.99,1), _V(-1,-4.89+GEAR_proc*0.99,-1), _V(1,-4.89+GEAR_proc*0.99,-1));
//sprintf(oapiDebugString(),"anim %2.2f", GEAR_proc );
if (PLBAYA_status >= PLBAYA_CLOSING) {
double da = simdt * PLBAYA_OPERATING_SPEED;
if (PLBAYA_status == PLBAYA_CLOSING) {
if (PLBAYA_proc > 0.0) PLBAYA_proc = max (0.0, PLBAYA_proc-da);
else PLBAYA_status = PLBAYA_UP;
} else {
if (PLBAYA_proc < 1.0) PLBAYA_proc = min (1.0, PLBAYA_proc+da);
else PLBAYA_status = PLBAYA_DOWN;
}
SetAnimation (anim_PLBAYA, PLBAYA_proc);
}
if (PLBAYB_status >= PLBAYB_CLOSING) {
double da = simdt * PLBAYB_OPERATING_SPEED;
if (PLBAYB_status == PLBAYB_CLOSING) {
if (PLBAYB_proc > 0.0) PLBAYB_proc = max (0.0, PLBAYB_proc-da);
else PLBAYB_status = PLBAYB_UP;
} else {
if (PLBAYB_proc < 1.0) PLBAYB_proc = min (1.0, PLBAYB_proc+da);
else PLBAYB_status = PLBAYB_DOWN;
}
SetAnimation (anim_PLBAYB, PLBAYB_proc);
}
if (GEAR_status == GEAR_RAISING) {
{if(GEAR_proc > 0.99)
PlayVesselWave3(SHD,GEARDOWN);
}
}
if (GEAR_status == GEAR_LOWERING) {
{if(GEAR_proc < 0.01)
PlayVesselWave3(SHD,GEARUP);
}
}
if (PLBAYA_status == PLBAYA_CLOSING) {
{if(PLBAYA_proc > 0.99)
PlayVesselWave3(SHD,PLBAYACLOSE);
}
}
if (PLBAYA_status == PLBAYA_OPENING) {
{if(PLBAYA_proc < 0.01)
PlayVesselWave3(SHD,PLBAYAOPEN);
}
}
if (PLBAYB_status == PLBAYB_CLOSING) {
{if(PLBAYB_proc > 0.9)
PlayVesselWave3(SHD,PLBAYBCLOSE);
}
}
if (PLBAYB_status == PLBAYB_OPENING) {
{if(PLBAYB_proc < 0.1)
PlayVesselWave3(SHD,PLBAYBOPEN);
}
}
if(GroundContact()==TRUE)
{
// we check vertical speed
int I;
VECTOR3 vHorizonAirspeedVector={0};
GetHorizonAirspeedVector (vHorizonAirspeedVector);
double VertSpeed =vHorizonAirspeedVector.y;
if(VertSpeed<-3)
{
// we touched ground with more than -3 m/s, sorry dude, time to kill you all :(
for(I=0;I<Crew.GetCrewTotalNumber();I++)
{
Crew.SetCrewMemberPulseBySlotNumber(I,0); // set cardiac pulse to zero
}
strcpy(SendHudMessage(),"Oooh no ! Crash - All crew aboard killed");
}
}
if (PLBAYA_status == PLBAYA_UP) {
hUcgo.SetSlotDoorState(FALSE);
}
if (PLBAYA_status == PLBAYA_DOWN) {
hUcgo.SetSlotDoorState(TRUE);
}
if (PLBAYB_status == PLBAYB_OPENING) {
{if(PLBAYB_proc < 0.1)
PlayVesselWave3(SHD,PLBAYBOPEN);
}
}
double CrewNumber = Crew.GetCrewTotalNumber();
double OxygenConsumption = 1.2*1.157407E-5*CrewNumber;
double OxygenLevel = O2Tank;
{
if (O2Tank>0)
{
O2Tank = (O2Tank - OxygenConsumption*simdt);
}
else
{
O2Tank=0;
}
}
int I;
if(O2Tank == 0)
{
// You ran out of oxygen, sorry dude, time to kill you all :(
for(I=0;I<Crew.GetCrewTotalNumber();I++)
{
Crew.SetCrewMemberPulseBySlotNumber(I,0); // set cardiac pulse to zero
}
strcpy(SendHudMessage(),"Oooh no ! Oxygen Depleted - All crew dead");
}
// Orientation mode switch
{
// RCS Stack Optimization...
double RCSMode = GetAttitudeMode (); // Checks current RCS mode 1 = ROT, 2 = LIN
if (RCSMode==2)
{
}
if (RCSMode==1)
{
}
}
//Cancel Linear Torque.
// IncThrusterLevel_SingleStep (th_rcs[2],456.6447615);
// IncThrusterLevel_SingleStep (th_rcs[3],456.6447615);
// SetThrusterLevel (th_rcs[14],1);
// SetThrusterLevel (th_rcs[15],1);
// IncThrusterLevel (th_rcs[14],5);
// IncThrusterLevel (th_rcs[15],5);
// IncThrusterLevel_SingleStep (th_rcs[12], VertThrust*Ratio*0.965925826289);
// IncThrusterLevel_SingleStep (th_rcs[13],-VertThrust*Ratio*0.965925826289);
// if (GetAttitudeMode = RCS_LIN)
// {
// RCS Stack Optimization...
// double RCSMode = GetAttitudeMode (); // Checks current RCS mode 1 = ROT, 2 = LIN
// if (RCSMode==2)
// {
// (RCSTH0 = EXP_LINRCSTH0);
// (RCSTH1 = EXP_LINRCSTH1);
// (RCSTH2 = EXP_LINRCSTH2);
// (RCSTH3 = EXP_LINRCSTH3);
// (RCSTH4 = EXP_LINRCSTH4);
// (RCSTH5 = EXP_LINRCSTH5);
// (RCSTH6 = EXP_LINRCSTH6);
// (RCSTH7 = EXP_LINRCSTH7);
// (RCSTH8 = EXP_LINRCSTH8);
// (RCSTH9 = EXP_LINRCSTH9);
// (RCSTH10 = EXP_LINRCSTH10);
// (RCSTH11 = EXP_LINRCSTH11);
// (RCSTH12 = EXP_LINRCSTH12);
// (RCSTH13 = EXP_LINRCSTH13);
// (RCSTH14 = EXP_LINRCSTH14);
// (RCSTH15 = EXP_LINRCSTH15);
// }
// if (RCSMode==1)
// {
// (RCSTH0 = EXP_RCSTH0);
// (RCSTH1 = EXP_RCSTH1);
// (RCSTH2 = EXP_RCSTH2);
// (RCSTH3 = EXP_RCSTH3);
// (RCSTH4 = EXP_RCSTH4);
// (RCSTH5 = EXP_RCSTH5);
// (RCSTH6 = EXP_RCSTH6);
// (RCSTH7 = EXP_RCSTH7);
// (RCSTH8 = EXP_RCSTH8);
// (RCSTH9 = EXP_RCSTH9);
// (RCSTH10 = EXP_RCSTH10);
// (RCSTH11 = EXP_RCSTH11);
// (RCSTH12 = EXP_RCSTH12);
// (RCSTH13 = EXP_RCSTH13);
// (RCSTH14 = EXP_RCSTH14);
// (RCSTH15 = EXP_RCSTH15);
// }
AddUMmuToVessel();
Crew.WarnUserUMMUNotInstalled("Shuttle-D");
// At the very end of clbkPostStep or clbkPreStep
hUcgo.WarnUserUCGONotInstalled("Shuttle-D");
}
// --------------------------------------------------------------
// Respond to buffered keyboard events
// --------------------------------------------------------------
int ShuttleD::clbkConsumeBufferedKey (DWORD key, bool down, char *kstate)
{
if (!down) return 0; // only process keydown events
if(key==OAPI_KEY_G)
{ //Gear
RevertGEAR();
return 1;
}
if(key==OAPI_KEY_K)
{// Payload Bay B
RevertPLBAYB();
return 1;
}
if(key==OAPI_KEY_O)
{// Payload Bay A
RevertPLBAYA();
return 1;
}
if(key==OAPI_KEY_E&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
// PERFORM THE EVA, first we get is name with "GetCrewNameBySlotNumber" then we perform EVA with "EvaCrewMember"
int Returned=Crew.EvaCrewMember(Crew.GetCrewNameBySlotNumber(SelectedUmmuMember));
// we provide feedback to user (You can display a message on panel or wathewer)
// here below all the return code possible:
switch(Returned)
{
case TRANSFER_TO_DOCKED_SHIP_OK:
sprintf(SendHudMessage(),"Transfer to docked ship Ok - %s transfered",
Crew.GetLastEvaedCrewName());SelectedUmmuMember=0;
break;
case EVA_OK:
sprintf(SendHudMessage(),"EVA OK - %s left the ship",
Crew.GetLastEvaedCrewName());SelectedUmmuMember=0;
break;
case ERROR_NO_ONE_ON_BOARD:
strcpy(SendHudMessage(),"Error, no one on board, unable to EVA");
break;
case ERROR_AIRLOCK_CLOSED:
strcpy(SendHudMessage(),"Error, airlock is closed, unable to EVA");
break;
case ERROR_DOCKED_SHIP_HAVE_AIRLOCK_CLOSED:
strcpy(SendHudMessage(),"Error, docked ship's airlock is closed, unable to transfer");
break;
case ERROR_DOCKED_SHIP_IS_FULL:
strcpy(SendHudMessage(),"Error, docked ship is already full transfer failed");
break;
case ERROR_CREW_MEMBER_NOT_FOUND:
strcpy(SendHudMessage(),"Error, no crew by this name in ship");
break;
case ERROR_DOCKEDSHIP_DONOT_USE_UMMU:
strcpy(SendHudMessage(),"Error, docked ship do not use UMmu 2.0, ask author to add it");
break;
case ERROR_MISC_ERROR_EVAFAILED:
strcpy(SendHudMessage(),"Misc error with UMMU install it again");
break;
}
return TRUE;
}
//---------------------------------------------------------------------------
// Ummu Key "1" Select next member This is just internal to the demo
// you may do your own selection system by panel button, name etc etc
if(key==OAPI_KEY_1&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
// we test there is someone aboard
if(Crew.GetCrewTotalNumber()==0)
{
strcpy(SendHudMessage(),"Sorry no one aboard unable to select");
return 1;
}
// we test that we select existing member
if(SelectedUmmuMember<Crew.GetCrewTotalNumber()-1)
SelectedUmmuMember++;
char * Name=Crew.GetCrewNameBySlotNumber(SelectedUmmuMember);
sprintf(SendHudMessage(),"Slot %i %s \"%s\" aged %i Selected for EVA or Transfer, please press \"E\" to EVA",
SelectedUmmuMember,Crew.GetCrewMiscIdBySlotNumber(SelectedUmmuMember),
Name,Crew.GetCrewAgeBySlotNumber(SelectedUmmuMember));
return 1;
}
//---------------------------------------------------------------------------
// Ummu Key "2" Select previous member This is just internal to the demo
// you may do your own selection system by panel button
if(key==OAPI_KEY_2&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
// we test there is someone aboard
if(Crew.GetCrewTotalNumber()==0)
{
strcpy(SendHudMessage(),"Sorry no one aboard unable to select");
return 1;
}
if(SelectedUmmuMember>0)
SelectedUmmuMember--;
char * Name=Crew.GetCrewNameBySlotNumber(SelectedUmmuMember);
sprintf(SendHudMessage(),"Slot %i %s \"%s\" aged %i Selected for EVA or Transfer"
", please press \"E\" to EVA",SelectedUmmuMember,
Crew.GetCrewMiscIdBySlotNumber(SelectedUmmuMember),Name,
Crew.GetCrewAgeBySlotNumber(SelectedUmmuMember));
return 1;
}
//---------------------------------------------------------------------------
// Ummu Key "3" Select next member This is just internal to the demo
// you may do your own selection system by panel button, name etc etc
if(key==OAPI_KEY_4&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
// we test that we select existing member
if(iSelectedCargo<18-1)
iSelectedCargo++;
char * SlotName=Crew.GetCrewNameBySlotNumber(SelectedUmmuMember);
double GetCargoSlotMass(int Num);
sprintf(SendHudMessage(),"Slot %i selected",
iSelectedCargo);
return 1;
}
//---------------------------------------------------------------------------
// Ummu Key "4" Select previous member This is just internal to the demo
// you may do your own selection system by panel button
if(key==OAPI_KEY_3&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
if(iSelectedCargo>0)
iSelectedCargo--;
char * SlotName=Crew.GetCrewNameBySlotNumber(SelectedUmmuMember);
double GetCargoSlotMass(int Num);
sprintf(SendHudMessage(),"Slot %i selected",
iSelectedCargo);
return 1;
}
//---------------------------------------------------------------------------
// Ummu Key "5" Select next Dock/Airlock
if(key==OAPI_KEY_5&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
if(iActiveDockNumber > 0)
iActiveDockNumber--;
sprintf(SendHudMessage(),"Active dock number changed to: %i", iActiveDockNumber);
SetUMMUAirlockPos();
return 1;
}
//---------------------------------------------------------------------------
// Ummu Key "6" Select previous Dock/Airlock
if(key==OAPI_KEY_6&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
if(iActiveDockNumber < 1)
iActiveDockNumber++;
sprintf(SendHudMessage(),"Active dock number changed to: %i", iActiveDockNumber);
SetUMMUAirlockPos();
return 1;
}
//---------------------------------------------------------------------------
// Ummu Key "A" Open & Close the virtual UMMU airlock door
if(key==OAPI_KEY_A&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
// switch state
Crew.SetAirlockDoorState(!Crew.GetAirlockDoorState());
// display state
if(Crew.GetAirlockDoorState()==TRUE)
strcpy(SendHudMessage(),"Airlock is now open");
else
strcpy(SendHudMessage(),"Airlock is now closed");
return 1;
}
//---------------------------------------------------------------------------
// Get some infos Name of ship and total soul aboard
if(key==OAPI_KEY_S)
{
sprintf(SendHudMessage(),"%i souls aboard ship %s, %i seats available",
Crew.GetCrewTotalNumber(),GetName(),4-Crew.GetCrewTotalNumber());
return 1;
}
//---------------------------------------------------------------------------
// ADD some Fun, Eject the guy, No check of all return code here to keep listing small and clear.
// Notice eject function doesn't check airlock state at all.
// GOOD IDEA: Get the Object's handle after ejection with function "GetObjHandleOfLastEVACrew"
// and add to it one very small tank, thruster and smoke, then fire thruster (see pilot ejection of DGIV)
// BAD IDEA: Not testing the handle returned by "GetObjHandleOfLastEVACrew" before using may
// cause a CTD if by any bad luck the pointer is invalid (handle==NULL)
if(key==OAPI_KEY_ESCAPE&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
if(Crew.EjectCrewMember(Crew.GetCrewNameBySlotNumber(SelectedUmmuMember))==EVA_OK)
sprintf(SendHudMessage(),"%s EJECTED",Crew.GetLastEvaedCrewName());
SelectedUmmuMember=0;
return 1;
}
// THIS IS FOR ADDING CREW SEE PDF doc "Allow user to add crew to your ship
// without scenery editor"
if(key==OAPI_KEY_M&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
AddUMmuToVessel(TRUE);
}
// 9 key "select" one cargo on disk (cycle)
if(key==OAPI_KEY_9&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
sprintf(SendCargHudMessage(),"%s - selected",hUcgo.ScnEditor_SelectNextCargoAvailableOnDisk());
return 1;
}
// SHIFT+9 key "add last cargo selected by key 9"
// If iSelectedCargo=-1 (default) add to the first free slot found
if(key==OAPI_KEY_9&&KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
if(hUcgo.ScnEditor_AddLastSelectedCargoToSlot(iSelectedCargo)==TRUE)
{
strcpy(SendCargHudMessage(),"Cargo added to ship");
}
else
{
if(iSelectedCargo<0)
{
strcpy(SendCargHudMessage(),"Cargo not added (ship full or weight excess ?)");
}
else
{
strcpy(SendCargHudMessage(),"Cargo not added (slot full ship full or weight excess ?)");
}
}
return 1;
}
// "C" grapple cargo. If iSelectedCargo=-1 (default) add to the first free slot found
if(key==OAPI_KEY_C&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
int ReturnedCode=hUcgo.GrappleOneCargo(iSelectedCargo);
// for return code list see function "GrappleOneCargo" in the header
switch(ReturnedCode)
{
case 1:
strcpy(SendCargHudMessage(),"Cargo grappled");
break;
case 0:
strcpy(SendCargHudMessage(),"No cargo in range");
break;
case -1:
strcpy(SendCargHudMessage(),"cargo exceed maximum mass");
break;
case -2:
strcpy(SendCargHudMessage(),"bad config, mesh not found or slot not declared");
break;
case -3:
strcpy(SendCargHudMessage(),"Can't grapple cargo, slot not empty");
break;
case -4:
strcpy(SendCargHudMessage(),"Can't grapple cargo,doors closed ");
break;
case -5:
strcpy(SendCargHudMessage(),"Can't grapple cargo,Ship full");
break;
default:
strcpy(SendCargHudMessage(),"Misc error Unable to grapple cargo");
}
return 1;
}
// SHIFT+C release cargo. If iSelectedCargo=-1 (default) release the first free slot found
if(key==OAPI_KEY_C&&KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
if(hUcgo.ReleaseOneCargo(iSelectedCargo)!=FALSE)
{
strcpy(SendCargHudMessage(),"Cargo released");
}
else
{
strcpy(SendCargHudMessage(),"Cargo not released (empty slot, no cargo aboard?)");
}
return 1;
}
// "8" show some info on cargo
if(key==OAPI_KEY_8&&!KEYMOD_SHIFT(kstate)&&!KEYMOD_CONTROL (kstate))
{
sprintf(SendCargHudMessage(),"%i cargos aboard. "
"Total cargos weight: %.0fkg",hUcgo.GetNbrCargoLoaded(),hUcgo.GetCargoTotalMass());
return 1;
}
return 0;
}
//-------------------------------------------------------------------------
// THIS IS FOR ADDING CREW SEE PDF doc "Allow user to add crew to your ship
// without scenery editor"
bool UMmuCrewAddCallback(void *id, char *str, void *data)
{
if(strlen(str)<2||strlen(str)>38)
return false;
char *cPtr=(char*)data; if(*cPtr==2){*cPtr=3;strcpy(cPtr+2,str);}
else if(*cPtr==4){*cPtr=5;strcpy(cPtr+42,str);}
else if(*cPtr==6){*cPtr=7;strcpy(cPtr+82,str);}return true;
}
void ShuttleD::AddUMmuToVessel(BOOL bStartAdding)
{
if(bStartAdding==FALSE&&cAddUMmuToVessel[0]==0)
return;
if(bStartAdding==TRUE){
int salut=sizeof(cAddUMmuToVessel);
memset(cAddUMmuToVessel,0,sizeof(cAddUMmuToVessel));
cAddUMmuToVessel[0]=1;
}
else if(cAddUMmuToVessel[0]==1){
cAddUMmuToVessel[0]=2;
oapiOpenInputBox ("Enter new crew's name (or escape)",UMmuCrewAddCallback,0,30,(void*)cAddUMmuToVessel);
}
else if(cAddUMmuToVessel[0]==3){
cAddUMmuToVessel[0]=4;
oapiOpenInputBox ("Enter crew's age",UMmuCrewAddCallback,0,30,(void*)cAddUMmuToVessel);
}
else if(cAddUMmuToVessel[0]==5){
cAddUMmuToVessel[0]=6;
oapiOpenInputBox ("Enter function (Capt,Sec,Vip,Sci,Doc,Tech,Crew,Pax)",UMmuCrewAddCallback,0,30,(void*)cAddUMmuToVessel);
}
else if(cAddUMmuToVessel[0]==7){
cAddUMmuToVessel[0]=0;
int Age=max(5,min(100,atoi(&cAddUMmuToVessel[42])));
if(Crew.AddCrewMember(&cAddUMmuToVessel[2],Age,70,70,&cAddUMmuToVessel[82])==TRUE){
sprintf(SendHudMessage(),"Crew \"%s\" aged %i added to vessel",&cAddUMmuToVessel[2],Age);
}
else{
strcpy(SendHudMessage(),"ERROR: Crew not added (vessel full?)");
}
}
}
// hFont = CreateFont (-20, 3, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, "Arial");
//=========================================================
// Load and Delete Module Stuff
//=========================================================
DLLCLBK void InitModule (HINSTANCE hModule)
{
g_hDLL = hModule;
hFont = CreateFont (-20, 3, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, "Haettenschweiler");
hPen = CreatePen (PS_SOLID, 3, RGB (120,220,120));
hBrush = CreateSolidBrush (RGB(0,128,0));
// perform global module initialisation here
}
DLLCLBK void ExitModule (HINSTANCE hModule)
{
// perform module cleanup here
DeleteObject (hFont);
DeleteObject (hPen);
DeleteObject (hBrush);
}
//=========================================================
// Load and Delete Vessel Stuff
//=========================================================
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
return new ShuttleD (hvessel, flightmodel);
}
DLLCLBK void ovcExit (VESSEL *vessel)
{
if (vessel)
delete (ShuttleD*)vessel;
}
void ShuttleD::clbkPostCreation (void)
{
////////////////////////////////////////////////////////////////
// 3-ORBITERSOUND EXAMPLE - INIT AND LOADING OF WAV
// THIS MUST BE CALLED ABSOLUTELY IN THE "POSTCREATION CALLBACK"
////////////////////////////////////////////////////////////////
// here we connect to OrbiterSound and store the returned ID in your class
// this is the first thing to do. You must call this in "clbkPostCreation"
// (new version of ovcPostCreation wich is now obsolet)
SHD=ConnectToOrbiterSoundDLL3(GetHandle());
RequestLoadVesselWave3(SHD,GEARUP,"Sound\\ShuttleD\\gearup.wav",INTERNAL_ONLY);
RequestLoadVesselWave3(SHD,GEARDOWN,"Sound\\ShuttleD\\geardown.wav",INTERNAL_ONLY);
RequestLoadVesselWave3(SHD,PLBAYAOPEN,"Sound\\ShuttleD\\plbayaopen.wav",INTERNAL_ONLY);
RequestLoadVesselWave3(SHD,PLBAYACLOSE,"Sound\\ShuttleD\\plbayaclose.wav",INTERNAL_ONLY);
RequestLoadVesselWave3(SHD,PLBAYBOPEN,"Sound\\ShuttleD\\plbaybopen.wav",INTERNAL_ONLY);
RequestLoadVesselWave3(SHD,PLBAYBCLOSE,"Sound\\ShuttleD\\plbaybclose.wav",INTERNAL_ONLY);
// now we are allowed for example to replace variable sound of OrbiterSound.
// it will use them instead of the stock one when our vessel have the focus, see header file for parameter
// (you can replace more than the four below see parameters for "ReplaceStockSound3()")
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\mainext.wav", REPLACE_MAIN_THRUST);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\attfire.wav", REPLACE_RCS_THRUST_ATTACK);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\attsustain.wav", REPLACE_RCS_THRUST_SUSTAIN);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_AIR_CONDITIONNING);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_1);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_2);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_3);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_4);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_5);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_6);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_7);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_8);
ReplaceStockSound3(SHD,"Sound\\ShuttleD\\aircond.wav", REPLACE_COCKPIT_AMBIENCE_9);
// Now your ship have custom sound you can end here if you don't want to bother anymore
// with sound, your ship is already customised. Anyway I'll show you more below.
//...
// here we will load a sound that will play when we pass 500 meter altitude
// We will play it later ourself when we reach 500 meter (see opcPreStep below)
RequestLoadVesselWave3(SHD,MY500METERSOUND,"Sound\\OrbiterSound_SDK\\sound\\my500meter.wav",RADIO_SOUND);
// AS we will play it using the "radioexclusive function" and as we don't want to be disturbed
// by OrbiterSound's ATC we set the ATC option of OrbiterSound to false (no more ATC will play)
// it's not an obligation while the "playradio..." function stop any stock ATC sound that is already playing
// but if you want to use radio sound you may not want to be disturbed by "off-topic" atc.
SoundOptionOnOff3(SHD,PLAYRADIOATC,FALSE);
// we disable also the stock countdown when we take-off.. it's annoying :)
SoundOptionOnOff3(SHD,PLAYCOUNTDOWNWHENTAKEOFF,FALSE);
// Here we will load a radar sound that will play in cockpit view only and after take-off below 500 meter
// this sound will be looped and will see it's frequency varying as we approach ground
RequestLoadVesselWave3(SHD,MYRADARSOUND,"Sound\\OrbiterSound_SDK\\sound\\myradar.wav",INTERNAL_ONLY);
// Here is THE example of an external sound that must be also faded by distance and pressure
// as stated in the header of ObiterSoundSDK3.h it's IMPORTANT that you call this sound looped
// and at each frame otherwise it will not be faded properly.
// "EXTERNAL_ONLY_FADED_CLOSE" mean that it will be faded at close distance as the RCS sound in external view.
RequestLoadVesselWave3(SHD,MYEXTERNAL_UFO_FADEDSOUND,"Sound\\OrbiterSound_SDK\\sound\\myUfoSound.wav",EXTERNAL_ONLY_FADED_CLOSE);
}
// --------------------------------------------------------------
// loop called each frame
// --------------------------------------------------------------
void ShuttleD::clbkPreStep (double simt, double simdt, double mjd)
{
double Altitude=0;
static BOOL AltitudeSoundPlayed=FALSE;
static BOOL RadarFlagForSound=FALSE;
///////////////////////////////////////////////////////////////////
// 4-ORBITERSOUND EXAMPLE - PLAYING THE SOUND WE LOADED DYNAMICALLY
///////////////////////////////////////////////////////////////////
// ----------------------------------------------------------
// We play the "500 meter" sound we loaded previously
// we use the function "playradio" wich stop OrbiterSound atc
// sound if one is playing.
// ----------------------------------------------------------
oapiGetFocusAltitude(&Altitude);
if(Altitude>500&&Altitude<550&&AltitudeSoundPlayed==FALSE)
{
PlayVesselRadioExclusiveWave3(SHD,MY500METERSOUND,255); // 255=volume maximum
AltitudeSoundPlayed=TRUE;
}
if(Altitude<500||Altitude>550)
AltitudeSoundPlayed=FALSE;
// ------------------------------------------------------
// here we play our radar sound that slide with altitude
// ------------------------------------------------------
if(Altitude<500&&Altitude>2)
{
PlayVesselWave3(SHD,MYRADARSOUND,LOOP,255,(int)(11025+((500-Altitude)*40))); // play looped and a frequency that increase with altitude
RadarFlagForSound=TRUE;
}
else if(RadarFlagForSound=TRUE)
{
// we stop the sound only once (it would not harm else but it will save a bit of processor time)
StopVesselWave3(SHD,MYRADARSOUND);
}
// ------------------------------------------------------
// here we play our external "ufo" sound
// ------------------------------------------------------
// As stated a sound that play in external view must be called looped heach frame so it
// fade properly with distance and pressure. Also we add a litle effect: if the ship is landed
// the frequency is lower simulating an "iddle" engine.
if(Altitude<2)
PlayVesselWave3(SHD,MYEXTERNAL_UFO_FADEDSOUND,LOOP,255,11025); // original wav is 11025 hz
else
PlayVesselWave3(SHD,MYEXTERNAL_UFO_FADEDSOUND,LOOP,255,9000);
// -------------------------------------------------------------
// another example with a different behaviour of the "Ufo" sound
// -------------------------------------------------------------
// here an example of the ufo sound that will play only beetween 0 and 500 meter high.
// I show it here so you know how to stop/start an external sound.
//if(Altitude<500)
// PlayVesselWave3(MyID,MYEXTERNAL_UFO_FADEDSOUND,LOOP,255); // original wav is 11025 hz
//else
// StopVesselWave3(MyID,MYEXTERNAL_UFO_FADEDSOUND); // you can use a flag to avoid reapeated call (even the impact is very low, the function return immediately if the sound is already stoped)
}
ShuttleD::~ShuttleD()
{
delete th_rcs, th_main, th_hover;
}