.dll Question Staging a .dll

MJR

C++ developer in the mix
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 19, 2008
Messages
2,460
Reaction score
5
Points
0
Location
United States
I am so frustrated. I have been working a a multistage .dll for so long, but to no success. I don't really understand where to start. I can make a spacecraft and SSTOs, but multistaging is not working for me. I need some pointers on how to do this a quick and easy way. For example, do I make a .cpp for every stage, how to flag a jettison for low fuel, etc.

---------- Post added at 06:53 PM ---------- Previous post was at 06:47 PM ----------

Oh yeah, I looked at the Atlantis code, but it is far too detailed for my purpose.
 

Nistenf

Member
Joined
Sep 30, 2008
Messages
114
Reaction score
0
Points
16
Location
Argentina
I never coded for Orbiter myself so this is pure guess, but can't you check when the fuel tank is empty, and when it is, you create two vessels, one will be the used first stage and the other will be the rest of the rocket. Of course you will need the meshes
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
I never coded for Orbiter myself so this is pure guess, but can't you check when the fuel tank is empty, and when it is, you create two vessels, one will be the used first stage and the other will be the rest of the rocket.
Just like that, except just create one new vessel which has the lower stage mesh. Your primary vessel deletes its lower stage mesh, engines, etc, and shifts its CoG up to the correct location, then adds the second stage engine. That's the basic concept anyway. The devil is in the detail, as they say.
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
One of my first .dll addons attempt was to make a DeltaIV rocket with SRBS and staging. As far as I remember, it was working rather correctly. Here's the code (very unoptimized !!!, there's not even a header file) if that can help you :

Code:
#define STRICT
#define ORBITER_MODULE

#include "orbitersdk.h"

// ==============================================================
// Some vessel parameters
// ==============================================================
const double LOX_LH2_STG1 = 199640;
const double LOX_LH2_STG2 = 15000; //21320
const double SEP1_FUEL1 = 10;
const double SEP1 = 10;
const double PLD_FUEL = 100;
const double BOOSTER_FUEL = 29949*2;
const double RS68_ISP = 4120.2;
const double BSTR_ISP = 2697.75;
const double ISP_SL = 3580.65;
const double BSTR_MAXMAINTH = 851500;
const double STG1_MAXMAINTH = 3312755;
const double STG2_MAXMAINTH = 110050;
const double PB_MAXRCSTH = 0;

// ==============================================================
// Shuttle-PB class interface
// ==============================================================

class DeltaIV: public VESSEL2 {
public:
	DeltaIV (OBJHANDLE hVessel, int flightmodel)
		: VESSEL2 (hVessel, flightmodel) {}

    PROPELLANT_HANDLE LOX_LH2_1, LOX_LH2_2, PLD_FUEL_ph, SOLID, SEP1_EXP;
	THRUSTER_HANDLE th_main, th_rcs[14], th_group[4], th_sep1[12], th_bstr[2], th_fx1, th_fx2[2], th_fx3;

	void clbkSetClassCaps (FILEHANDLE cfg);
	void clbkPreStep(double SimT, double SimDT, double MJD);
	void SpawnObject(char* classname, char* ext, VECTOR3 ofs);
	void PLD_Handling();
	int DeltaIV::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate);

	int FAIR;
	int J1ST;
	int PLD;
	double BSTRIG;
	double MET;
	double MET0;
	double CTD;
	double CTD0;
	double CTD2;
	double CTDL;
	double X;
	double Course;
	double pitch;
	int PitchState;
	double Phase2;
	double HDG;
	double Matt;
	double CoM;
	double HorzAcc;
	double VerAcc;
};

// ==============================================================
// Overloaded callback functions
// ==============================================================

// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void DeltaIV::clbkSetClassCaps (FILEHANDLE cfg)
{

FAIR=0;
J1ST=0;
BSTRIG=0;
PLD=10300;
MET=-1;
MET0=-1;
CTD=-100;
CTD0=10;
CTDL=0;
CTD2=0;
X=5.5;
PitchState=0;
Phase2=0;
HDG=90;
Matt=1;
CoM=0;
VerAcc=0;

	// physical specs
	SetSize (40);
	SetEmptyMass (3849*2+26760+2850+LOX_LH2_STG2+3550+PLD);
	SetCW (0.15, 0.2, 0.5, 0.5);
	SetCrossSections (_V(2.89,3.14,26.84));
	SetRotDrag (_V(0.1,0.1,0.1));
	SetPMI (_V(60,60,30));
	SetCameraOffset (_V(0,2.75,-10));
	SetTouchdownPoints (_V(0,-20,-52), _V(-14,14,-52), _V(14,14,-52));
	// Atlantis // SetTouchdownPoints (_V(0,-10,-53.3), _V(-7,7,-53.3), _V(7,7,-53.3));
	SetSurfaceFrictionCoeff (100, 100);

	// propellant ressources

	LOX_LH2_1 = CreatePropellantResource (LOX_LH2_STG1);
	SOLID = CreatePropellantResource (BOOSTER_FUEL);


	// ***************** thruster definitions *******************

	PARTICLESTREAMSPEC condensation = {
		0, 4.0, 60, 40, 0.20, 0.2, 2, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
		PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
	};

	PARTICLESTREAMSPEC cryo = {
		0, 0.3, 14, 2, 0.20, 0.5, 0.5, 0, PARTICLESTREAMSPEC::DIFFUSE,
		PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
	};

	PARTICLESTREAMSPEC contrail_main = {
		0, 4.0, 18, 220, 0.15, 0.5, 4, 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
	};

	PARTICLESTREAMSPEC contrail_booster = {
		0, 8, 40, 150, 0.2, 8, 4, 4, PARTICLESTREAMSPEC::DIFFUSE,
		PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
		PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
	};
	PARTICLESTREAMSPEC exhaust_booster = {
		0, 3.5, 50, 250, 0.05, 0.6, 20, 4, PARTICLESTREAMSPEC::EMISSIVE,
		PARTICLESTREAMSPEC::LVL_FLAT, 1, 1,
		PARTICLESTREAMSPEC::ATM_FLAT, 1, 1
	};
	PARTICLESTREAMSPEC fx_fire = {
		0, 15, 20, 5, 1, 5, 30, 4, PARTICLESTREAMSPEC::EMISSIVE,
		PARTICLESTREAMSPEC::LVL_FLAT, 1, 1,
		PARTICLESTREAMSPEC::ATM_FLAT, 1, 1
	};

	SURFHANDLE tex = oapiRegisterExhaustTexture ("Exhaust2");
	exhaust_booster.tex = oapiRegisterParticleTexture ("Contrail2");
	fx_fire.tex = oapiRegisterParticleTexture ("Contrail2");

	th_fx1 = CreateThruster (_V(0,0,45), _V(0,0,1), 0, LOX_LH2_1, 1);
	CreateThrusterGroup (&th_fx1, 1, THGROUP_USER);
	AddExhaustStream (th_fx1, _V(0,0,45), &condensation);

	th_fx2[0] = CreateThruster (_V(0,2.5,29), _V(0,-1,0), 0, LOX_LH2_1, 1);
	th_fx2[1] = CreateThruster (_V(0,2.5,-23), _V(0,-1,0), 0, LOX_LH2_1, 1);
	CreateThrusterGroup (th_fx2, 2, THGROUP_USER);
	AddExhaustStream (th_fx2[0], _V(0,2.5,29), &cryo);
	AddExhaustStream (th_fx2[1], _V(0,2,-23), &cryo);

	th_fx3 = CreateThruster (_V(0,0,25), _V(0,0,1), 0, LOX_LH2_1, 1);
	CreateThrusterGroup (&th_fx3, 1, THGROUP_USER);
	AddExhaustStream (th_fx3, _V(0,0,25), &fx_fire);

	th_main = CreateThruster (_V(0,0,-26), _V(0,0,1), STG1_MAXMAINTH, LOX_LH2_1, RS68_ISP, ISP_SL, 101400);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 18, 1.5, _V(0,0,-28), _V(0,0,-1));

	AddExhaustStream (th_main, _V(0,0,-30), &contrail_main);
	//AddExhaustStream (th_main, _V(0,0,-30), &exhaust_main);

	th_bstr[0] = CreateThruster (_V(3.25,0,-24), _V(0,0,1), BSTR_MAXMAINTH, SOLID, BSTR_ISP);
	th_bstr[1] = CreateThruster (_V(-3.25,0,-24), _V(0,0,1), BSTR_MAXMAINTH, SOLID, BSTR_ISP);
	CreateThrusterGroup (th_bstr, 2, THGROUP_USER);

	AddExhaustStream (th_bstr[0], _V(3.5,0,-30), &contrail_booster);
	AddExhaustStream (th_bstr[0], _V(3.5,0,-24.5), &exhaust_booster);
	AddExhaustStream (th_bstr[1], _V(-3.5,0,-30), &contrail_booster);
	AddExhaustStream (th_bstr[1], _V(-3.5,0,-24.5), &exhaust_booster);

	th_rcs[ 0] = CreateThruster (_V( 1,0, 3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 1] = CreateThruster (_V( 1,0, 3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 2] = CreateThruster (_V(-1,0, 3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 3] = CreateThruster (_V(-1,0, 3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 4] = CreateThruster (_V( 1,0,-3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 5] = CreateThruster (_V( 1,0,-3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 6] = CreateThruster (_V(-1,0,-3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 7] = CreateThruster (_V(-1,0,-3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 8] = CreateThruster (_V( 1,0, 3), _V(-1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[ 9] = CreateThruster (_V(-1,0, 3), _V( 1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[10] = CreateThruster (_V( 1,0,-3), _V(-1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[11] = CreateThruster (_V(-1,0,-3), _V( 1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[12] = CreateThruster (_V( 0,0,-3), _V(0,0, 1), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
	th_rcs[13] = CreateThruster (_V( 0,0, 3), _V(0,0,-1), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[2];
	th_group[2] = th_rcs[5];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHUP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[3];
	th_group[2] = th_rcs[4];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHDOWN);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKLEFT);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKRIGHT);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_LEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_RIGHT);

	CreateThrusterGroup (th_rcs+12, 1, THGROUP_ATT_FORWARD);
	CreateThrusterGroup (th_rcs+13, 1, THGROUP_ATT_BACK);

	// visual specs
	VECTOR3 Stg1 = _V(0,0,CoM);
	AddMesh ("DeltaIVstg1",&Stg1); // IDX 0
	SetMeshVisibilityMode (0, MESHVIS_ALWAYS);

	VECTOR3 Stg2 = _V(0,0,24.25);
    AddMesh("DeltaIVstg2",&Stg2); // IDX 1
	SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

	VECTOR3 Plf1 = _V(0,0,29);
    AddMesh("DeltaIVplf_1",&Plf1); // IDX 2
	SetMeshVisibilityMode (2, MESHVIS_ALWAYS);

	VECTOR3 Plf2 = _V(0,0,29);
    AddMesh("DeltaIVplf_2",&Plf2); // IDX 3
	SetMeshVisibilityMode (3, MESHVIS_ALWAYS);

	VECTOR3 Pld = _V(0,0,31.75);
    AddMesh("Carina",&Pld); // IDX 4
	SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

	VECTOR3 Bstr1 = _V(-3.25,0,-15);
    AddMesh("Gem60_1",&Bstr1); // IDX 5
	SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

	VECTOR3 Bstr2 = _V(3.25,0,-15);
    AddMesh("Gem60_2",&Bstr2); // IDX 6
	SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

ShiftCentreOfMass(_V(0,0,4.31));

}

void DeltaIV::SpawnObject(char* classname, char* ext, VECTOR3 ofs) {
  VESSELSTATUS vs;
  char name[256];
  GetStatus(vs);
  Local2Rel (ofs, vs.rpos);
  vs.eng_main = vs.eng_hovr = 0;
  vs.status = 0;
  strcpy (name, GetName()); strcat (name, ext);
  oapiCreateVessel (name, classname, vs);
};

void DeltaIV::clbkPreStep(double SimT, double SimDT, double MJD) {


/// VISUAL EFFECTS ////////////////////////////////////////////////////////////////////////////

if (GetDynPressure() > 20000 && FAIR==0) {
	SetThrusterLevel(th_fx1, 1);
		} else {
		SetThrusterLevel(th_fx1, 0);
}

if (GetDynPressure() > 40000) {
	SetThrusterLevel(th_fx3, 1);
		} else {
			SetThrusterLevel(th_fx3, 0);
}

if (GetDynPressure() > 45000) {
	SetThrusterLevel(th_main, 0);
}

if (BSTRIG < 2) {
	SetThrusterLevel(th_fx2[0], 1);
	SetThrusterLevel(th_fx2[1], 1);
		} else {
	SetThrusterLevel(th_fx2[0], 0);
	SetThrusterLevel(th_fx2[1], 0);
}


/// BOOSTERS IGNITION //////////////////////////////////////////////////////////////////////////

if ((GetThrusterLevel(th_main) > 0.90) && (BSTRIG==2)) {
	SetThrusterLevel(th_bstr[0], 1);
	SetThrusterLevel(th_bstr[1], 1);
	MET0 = SimT;		// MET+0
	BSTRIG=3;
}

/// THRUST VECTORING ///////////////////////////////////////////////////////////////////////////

double P,Y,R;
P=GetThrusterGroupLevel(THGROUP_ATT_PITCHUP)-GetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN);
Y=GetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT)-GetThrusterGroupLevel(THGROUP_ATT_YAWLEFT);
R=GetThrusterGroupLevel(THGROUP_ATT_BANKRIGHT)-GetThrusterGroupLevel(THGROUP_ATT_BANKLEFT);
SetThrusterDir(th_main,_V((-0.0005*Y),(-0.0005*P),1)); // soustraire valeur absolue P+R


/// STAGE 2 SEPARATION //////////////////////////////////////////////////////////////////////////

if (J1ST==3 && GetPropellantMass(LOX_LH2_2) < 4) {
	DelMesh(1);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("DIV_stg2","-Stage2",_V(0,0,0));
	SetEmptyMass (PLD);
	SetCameraOffset (_V(0,0,9));

	PLD_FUEL_ph = CreatePropellantResource (PLD_FUEL);
	SetDefaultPropellantResource(PLD_FUEL_ph);
	SetMaxFuelMass(100);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, PLD_FUEL_ph, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	J1ST=4;
}

/// COUNTDOWN //////////////////////////////////////////////////////////////////////////////////

//if (CTDL=0) {
//	SetThrusterLevel(th_main, 0);
//}

if (CTDL == 1) {
	CTD0 = SimT+10;
	CTDL = 2;
	BSTRIG = 1; // BOOSTERS READY
}

if (BSTRIG == 1) { 
	CTD = SimT - CTD0;
}
if (CTD > -10 && CTD < -5) {
	SetThrusterLevel(th_main, 0.01);
}
if (CTD > -5 && CTD < 0) {
	double MainE;
	MainE = CTD * 0.083 + 1;
	SetThrusterLevel (th_main, MainE);
	SetPropellantMass (LOX_LH2_1, 199640);
}
if (CTD>=0.2 && BSTRIG==1) {
	BSTRIG=2;
}

/// MISSION ELAPSED TIME ///////////////////////////////////////////////////////////////////////

if (BSTRIG >= 2) {
	MET = SimT - MET0;
}

/// BOOSTERS POWER CURVE ///////////////////////////////////////////////////////////////////////

if (MET > 0 && MET < 7) {
	double BstrThr1;
	double BstrIsp1;
	BstrThr1 = 7894.6214 * MET + 774098.65;
	BstrIsp1 = 25.1096 * MET + 2451.8427;
	SetThrusterIsp (th_bstr[0], BstrIsp1);
	SetThrusterIsp (th_bstr[1], BstrIsp1);
	SetThrusterMax0 (th_bstr[0], BstrThr1);
	SetThrusterMax0 (th_bstr[1], BstrThr1);
}
if (MET > 7 && MET < 17) {
	double BstrThr2;
	double BstrIsp2;
	BstrThr2 = 2213.9 * (MET-7) + 829361;
	BstrIsp2 = 7.014 * (MET-7) + 2627.61;
	SetThrusterIsp (th_bstr[0], BstrIsp2);
	SetThrusterIsp (th_bstr[1], BstrIsp2);
	SetThrusterMax0 (th_bstr[0], BstrThr2);
	SetThrusterMax0 (th_bstr[1], BstrThr2);
}
if (MET > 17 && MET < 39) {
	double BstrThr3;
	double BstrIsp3;
	BstrThr3 = -10430.875 * (MET-17) + 851500;
	BstrIsp3 = -33.0474 * (MET-17) + 2697.75;
	SetThrusterIsp (th_bstr[0], BstrIsp3);
	SetThrusterIsp (th_bstr[1], BstrIsp3);
	SetThrusterMax0 (th_bstr[0], BstrThr3);
	SetThrusterMax0 (th_bstr[1], BstrThr3);
}
if (MET > 39 && MET < 57) {
	double BstrThr4;
	double BstrIsp4;
	BstrThr4 = 4607.5611 * (MET-39) + 622020.75;
	BstrIsp4 = 14.597824 * (MET-39) + 1970.7064;
	SetThrusterIsp (th_bstr[0], BstrIsp4);
	SetThrusterIsp (th_bstr[1], BstrIsp4);
	SetThrusterMax0 (th_bstr[0], BstrThr4);
	SetThrusterMax0 (th_bstr[1], BstrThr4);
}
if (MET > 57 && MET < 81) {
	double BstrThr5;
	double BstrIsp5;
	BstrThr5 = -10945.323 * (MET-57) + 704956.85;
	BstrIsp5 = -34.677327 * (MET-57) + 2233.4672;
	SetThrusterIsp (th_bstr[0], BstrIsp5);
	SetThrusterIsp (th_bstr[1], BstrIsp5);
	SetThrusterMax0 (th_bstr[0], BstrThr5);
	SetThrusterMax0 (th_bstr[1], BstrThr5);
}
if (MET > 81 && MET < 88) {
	double BstrThr6;
	double BstrIsp6;
	BstrThr6 = -51333.286 * (MET-81) + 442269.1;
	BstrIsp6 = -189.74176 * (MET-81) + 1401.2114;
	SetThrusterIsp (th_bstr[0], BstrIsp6);
	SetThrusterIsp (th_bstr[1], BstrIsp6);
	SetThrusterMax0 (th_bstr[0], BstrThr6);
	SetThrusterMax0 (th_bstr[1], BstrThr6);
}
if (MET > 88 && MET < 94) {
	double BstrThr7;
	double BstrIsp7;
	BstrThr7 = -9210.3917 * (MET-88) + 82936.1;
	BstrIsp7 = -27.126808 * (MET-88) + 262.76085;
	SetThrusterIsp (th_bstr[0], BstrIsp7);
	SetThrusterIsp (th_bstr[1], BstrIsp7);
	SetThrusterMax0 (th_bstr[0], BstrThr7);
	SetThrusterMax0 (th_bstr[1], BstrThr7);
}
if (MET > 94 && MET < 100) {
	double BstrThr8;
	double BstrIsp8;
	BstrThr8 = 1000;
	BstrIsp8 = 100;
	SetThrusterIsp (th_bstr[0], BstrIsp8);
	SetThrusterIsp (th_bstr[1], BstrIsp8);
	SetThrusterMax0 (th_bstr[0], BstrThr8);
	SetThrusterMax0 (th_bstr[1], BstrThr8);
}

/// ASCENT PROGRAM /////////////////////////////////////////////////////////////////////////////

double BFUEL;
double MFUEL;
double MASS;
double ISP;
double Course1;
double CRS;
double YawRate;
double PitchRate;
double PS;
double alt;
double VVel;
double AVel;
double YVel;
double ApA;
double PeA;

double Vacc;
double dt;
dt = oapiGetSimStep();

BFUEL = GetPropellantMass(SOLID);
MFUEL = GetPropellantMass(LOX_LH2_1);
MASS = GetEmptyMass();
ISP = GetThrusterIsp(th_main)/9.81;
Course1 = oapiGetFocusHeading(&Course);
Course*=DEG;
CRS = Course;
pitch = GetPitch();
alt=GetAltitude();

//if (MET > 0) {
//CoM = -8.9311e-5 * -MFUEL + 22.14;
//}

pitch*=DEG;

VECTOR3 xyz;
GetHorizonAirspeedVector(xyz);
VVel=xyz.y;

VECTOR3 abc;
GetAngularVel(abc);
AVel=abc.x;
AVel*=DEG;
YVel=abc.y;
YVel*=DEG;

Vacc = VVel;

VESSEL *v;
v = oapiGetFocusInterface();

OBJHANDLE hBody=NULL;
hBody = v->GetSurfaceRef();
v->GetApDist(ApA);
v->GetPeDist(PeA);
ApA -=oapiGetSize(hBody);
PeA -=oapiGetSize(hBody);

///***

    static double SimTimeOld = 0;

    static double horz_speed_old = 0;
    static double vert_speed_old = 0;

    double SimTimeNew = oapiGetSimTime();
    
    VESSEL* V = oapiGetFocusInterface();
    VECTOR3 V3;

    V->GetHorizonAirspeedVector    (V3);

    double horz_speed_new = sqrt((V3.x*V3.x)+(V3.z*V3.z));
    double vert_speed_new = V3.y;
    
    HorzAcc = (horz_speed_new - horz_speed_old) / SimDT;
    VerAcc  = (vert_speed_new - vert_speed_old) / SimDT;
    //TotAcc = sqrt((HorzAcc*HorzAcc)+(VerAcc*VerAcc));
    SimTimeOld = SimTimeNew;
    horz_speed_old = horz_speed_new;
    vert_speed_old = vert_speed_new;

///***


//ShiftCentreOfMass(_V(0,0,CoM));

if (MET<0) {PitchState=0;}

PS=PitchState;

if (GetThrusterLevel(th_main)<0.6 && GetThrusterLevel(th_main)>0.01 && MET>0 && J1ST<2) {
		SetThrusterLevel(th_main, 0.6);
}
if (GetThrusterLevel(th_main) < 0.6 && GetThrusterLevel(th_main) > 0.01 && MET > 254+X) {
		SetThrusterLevel(th_main, 0.6);
}

//double;

if (alt < 2500) {YawRate=1;}
if (alt > 2500 && alt < 7500) {YawRate=1;}
if (alt > 7500 && alt < 15000) {YawRate=1;}
if (alt > 15000 && alt < 25000) {YawRate=1;}
if (alt > 25000 && MET < 230+X) {YawRate=1;}

if (MET < 5) {PitchRate=1;}
if (alt < 5000 && MET > 6) {PitchRate=0.4;}

if (alt > 5000 && alt < 10000) {PitchRate=1;}
if (alt >= 10000 && alt < 25000) {PitchRate=1;}
if (alt >= 25000 && alt < 50000) {PitchRate=1;}
if (alt >= 50000 && alt < 80000) {PitchRate=1;}
if (alt >= 80000 && alt < 100000) {PitchRate=1;}
if (alt >= 100000 && MET < 230+X) {PitchRate=1;}
if (MET >= 230+X && MET < 285+X) {PitchRate=0; YawRate=0;}
if (MET >= 285+X) {PitchRate=1; YawRate=1;}


if (MET > 0 && MET <=5 && GetAltitude() > 75) {PitchState=-1;}

if (YVel <= -0.25) {
	SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, 0);
	SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, 1);
}
if (YVel >= 0.25) {
	SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, 1);
	SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, 0);
}
if (MET > 4 && CRS < HDG && fabs(YVel) < 0.25) {
	SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, YawRate);
	SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, 0);
}

if (MET > 4 && CRS > HDG && fabs(YVel) < 0.25) {
	SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, YawRate);
	SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, 0);
}

if ((pitch > 90-(alt/1000) && MET>5 && MET<230+X) || (ApA > 35000 && MET<230+X)) {PitchState=-1;}
if (pitch < 90-(alt/1000) && MET>5 && ApA < 35000 && MET<230+X) {PitchState=1;}
if (alt > 50000 && alt < 80000 && pitch > 7) {PitchState=-1;}
if (alt > 65000 && alt < 80000 && pitch < 6) {PitchState=1;}
if (alt > 80000 && alt < 90000 && pitch > 6) {PitchState=-1;}
if (alt > 80000 && alt < 90000 && pitch < 5) {PitchState=1;}
if (alt > 90000 && alt < 100000 && pitch > 5) {PitchState=-1;}
if (alt > 90000 && alt < 100000 && pitch < 4) {PitchState=1;}
if (alt > 100000 && alt < 1000000 && pitch > 4 && MET<230+X) {PitchState=-1;}
if (alt > 100000 && alt < 1000000 && pitch < 4 && MET<230+X) {PitchState=1;}
if (MET > 196+X && pitch < 30 && MET < 230+X) {PitchState=1;}

if (MET > 285+X && Phase2<1 && pitch>35 && (pitch>35 || ApA>135000 || VerAcc>0.1))

{PitchState=-1; Matt=0.75;
}

if (MET > 285+X && Phase2<1 && pitch<35 && (pitch<35 || ApA<135000 || VerAcc<0.1))

{PitchState=1; Matt=0.75;
}

if (alt > 135000 && Phase2<1) {
Phase2=1;
PitchState=0;
HDG=106;
Matt=0.5;
}

if (alt<135000 && Phase2==1) {
Phase2=0;
PitchState=0;
HDG=106;
Matt=0.5;
}

if (Phase2==1) {Matt=0.3;}

/// PHASE 2 : Altitude > 150,000 km ///

/// PROGRAMS

double AAP200, AAP201, AAP210, AAP211, AAP220, AAP221, AAP230, AAP231, AAP240, AAP241;
double PROG;

/// 200 & 201 : basic pitch control [0-35]

if (Phase2==1 && pitch>35 && pitch>0)
{AAP200=1;  // pitch up limit exceeded
} else {AAP200=0;}

if (Phase2==1 && pitch<0 && pitch<35)
{AAP201=1;		// pitch low limit exceeded
} else {AAP201=0;}

/// 210 & 211 : Vertical Acceleration control [-1 +1]

if (Phase2==1 && VerAcc>1)
{AAP210=1;		// max vertical acc. exceeded
} else {AAP210=0;}

if (Phase2==1 && VerAcc<-1)
{AAP211=1;		// min vertical acc. exceeded
} else {AAP211=0;}


/// 220 & 221 : Vertical Velocity control

if (Phase2==1 && VVel>100)
{AAP220=1;		// vertical vel. > 0
} else {AAP220=0;}

if (Phase2==1 && VVel<-100)
{AAP221=1;  	// vertical vel. < 0
} else {AAP221=0;}


/// 230 & 231 : Vertical Acceleration control [0]

if (Phase2==1 && VerAcc > 0)
{AAP230=1;		// vertical acc. > 0
} else {AAP230=0;}

if (Phase2==1 && VerAcc < 0)
{AAP231=1;		// vertical acc. < 0
} else {AAP231=0;}

/// 240 & 241 : Altitude control [185000]

if (Phase2==1 && alt>185000)
{AAP240=1;		// vertical acc. > 0
} else {AAP240=0;}

if (Phase2==1 && alt<185000)
{AAP241=1;		// vertical acc. > 0
} else {AAP241=0;}


/// PHASE 2 PITCH CONTROL

if (AAP200==1) {
	PitchState = -1; PROG=200;
} else {
	AAP200=0;
}

if (AAP201==1) {
	PitchState = 1;  PROG=201;
} else {
	AAP201=0;
}

if (AAP210==1 && !(AAP200==1 || AAP201==1)) {
	PitchState = -1; PROG=210;
} else {
	AAP210=0;
}

if (AAP211==1 && !(AAP200==1 || AAP201==1 || AAP221==1)) {
	PitchState = 1;  PROG=211;
} else {
	AAP211=0;
}

if (AAP220==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1)) {
	PitchState = -1; PROG=220;
} else {
	AAP220=0;
}

if (AAP221==1 && !(AAP200==1 || AAP201==1 || AAP210==1)) {
	PitchState = 1;  PROG=221;
} else {
	AAP221=0;
}

if (AAP230==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1 || AAP240==1 || AAP241==1)) {
	PitchState = -1; PROG=230;
} else {
	AAP230=0;
}

if (AAP231==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1 || AAP240==1 || AAP241==1)) {
	PitchState = 1;  PROG=231;
} else {
	AAP231=0;
}

if (AAP240==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1)) {
	PitchState = -1; PROG=240;
} else {
	AAP240=0;
}

if (AAP241==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1)) {
	PitchState = 1; PROG=241;
} else {
	AAP241=0;
}


sprintf(oapiDebugString(),"MET %f BOOSTERS %f MASS %f ISP %f COURSE %f PITCH %f VACC %f AVel %f PROG %f Phase2 %f", MET, BFUEL, MASS, ISP, CRS, pitch, VerAcc, AVel, PROG, Phase2);

/// End PHASE 2 ///

if (AVel >= Matt) {
	SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 1);
	SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 0);
}
if (AVel <= -Matt) {
	SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 0);
	SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 1);
}
if (PitchState==-1 && fabs(AVel) < Matt) {
	SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, PitchRate);
	SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 0);
}
if (PitchState==1 && fabs(AVel) < Matt) {
	SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 0);
	SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, PitchRate);
}
if (PitchState==0) {
	SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 0);
	SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 0);
}

if (MET > 100 && BSTRIG==3) {
	DelMesh(5);
	DelMesh(6);
	DelThruster (th_bstr[0]);
	DelThruster (th_bstr[1]);
	SpawnObject("DIVbstr_1","-Booster1",_V(3.25,0,-15));
	SpawnObject("DIVbstr_2","-Booster2",_V(-3.25,0,-15));
	SetEmptyMass (26760+2850+LOX_LH2_STG2+3550+PLD);
	BSTRIG=4;
	HDG=96;
}

if (MET >= 230+X && MET < 237+X) {
	ActivateNavmode (NAVMODE_KILLROT);
	HDG=98;
}

if (MET >= 237+X && MET < 242+X) {
	double CBCLvl;
	CBCLvl = -0.08 * (MET-(237+X)) + 1;
	SetThrusterLevel(th_main, CBCLvl);
}
if (MET >= 247+X && MET < 253+X) {
	SetThrusterLevel(th_main, 0);
	DeactivateNavmode (NAVMODE_KILLROT);
}

if (MET >= 242+X && MET < 247+X) {
	J1ST=10;
	double CBCLvl;
	CBCLvl = -0.12 * (MET-(242+X)) + 0.6;
	SetThrusterLevel(th_main, CBCLvl);
	J1ST=5;
}

if (MET > 253+X && J1ST == 5) {
	DelMesh(0);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("DIV_stg1","-Stage1",_V(0,0,0));
	SetPMI (_V(15,15,5));
	SetEmptyMass (2850+3550+PLD);
	SetPropellantMass (LOX_LH2_1, LOX_LH2_STG2);
	SetMaxFuelMass(21320);
	ShiftCG(_V(0,0,26.5));
	SetCameraOffset (_V(0,2.75,0));
	LOX_LH2_2 = CreatePropellantResource (SEP1_FUEL1);
	SEP1_EXP = CreatePropellantResource (SEP1);
	th_sep1[0] = CreateThruster (_V( 2.5,0.1,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[1] = CreateThruster (_V(-2.5,-0.10,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[2] = CreateThruster (_V( 0.1,2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[3] = CreateThruster (_V( -0.1,-2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[4] = CreateThruster (_V( 2.5,-0.1,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[5] = CreateThruster (_V(-2.5,0.1,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[6] = CreateThruster (_V(-0.1,2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[7] = CreateThruster (_V(0.10,-2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
	th_sep1[8] = CreateThruster (_V( 2.5,-0.1,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
	th_sep1[9] = CreateThruster (_V(-2.5,0.1,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
	th_sep1[10] = CreateThruster (_V(-0.1,2.5,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
	th_sep1[11] = CreateThruster (_V(0.10,-2.5,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
	CreateThrusterGroup (th_sep1, 12, THGROUP_USER);
	for (int i=0;i<8;i++) {
		AddExhaust(th_sep1[i],0.75,0.05);
		}
	for (int i=8;i<12;i++) {
		AddExhaust(th_sep1[i],0,0.35);
		}
	J1ST=1;
}
if (J1ST==1 && GetPropellantMass(LOX_LH2_2) > 0) {
	for (int i=0;i<12;i++) {
		SetThrusterLevel(th_sep1[i], 1);
		}
}
if (J1ST==1 && MET >= 254+X && MET < 255+X) {
	th_main = CreateThruster (_V(0,0,-9), _V(0,0,1), STG2_MAXMAINTH, LOX_LH2_1, 4532.22, 10, 101400);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 8, 1, _V(0,0,-9), _V(0,0,-1));
	J1ST=2;
}
if (MET >= 268+X && MET < 274+X) {
	double Stage2Lvl;
	Stage2Lvl = 0.2 * (MET-(268+X)) + 0;
	SetThrusterLevel(th_main, Stage2Lvl);
}
if (MET >= 284+X && MET <= 285+X && FAIR==0) {
	DelMesh(2);
	SpawnObject("DIVplf_1","-Fairing1",_V(0,0,8));
	DelMesh(3);
	SpawnObject("DIVplf_2","-Fairing2",_V(0,0,8));
	SetEmptyMass (2850+PLD);
	FAIR=1;
}

if (PeA>185000) {
	SetThrusterLevel(th_main, 0);
}


};
/// END OF CLBKPRESTEP /////////////////////////////////////////////////////////////////////////

int DeltaIV::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate) {
  if (!down) return 0; // only process keydown events

  if (KEYMOD_SHIFT (kstate)) {

  } else { // unmodified keys
    switch (key) {

		case OAPI_KEY_J:
			J1ST=3;
        return 1;
  
		case OAPI_KEY_O:
			CTDL = 1;
        return 1;
    }
  }
  return 0;
};


// ==============================================================
// API callback interface
// ==============================================================

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
	return new DeltaIV (hvessel, flightmodel);
}

// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
	if (vessel) delete (DeltaIV*)vessel;
}
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,588
Reaction score
2,312
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
Why don't you use attachments for that?
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
I wasn't able to handle attachments back to then :p
 

MJR

C++ developer in the mix
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 19, 2008
Messages
2,460
Reaction score
5
Points
0
Location
United States
One of my first .dll addons attempt was to make a DeltaIV rocket with SRBS and staging. As far as I remember, it was working rather correctly. Here's the code (very unoptimized !!!, there's not even a header file) if that can help you :

Code:
#define STRICT
#define ORBITER_MODULE

#include "orbitersdk.h"

// ==============================================================
// Some vessel parameters
// ==============================================================
const double LOX_LH2_STG1 = 199640;
const double LOX_LH2_STG2 = 15000; //21320
const double SEP1_FUEL1 = 10;
const double SEP1 = 10;
const double PLD_FUEL = 100;
const double BOOSTER_FUEL = 29949*2;
const double RS68_ISP = 4120.2;
const double BSTR_ISP = 2697.75;
const double ISP_SL = 3580.65;
const double BSTR_MAXMAINTH = 851500;
const double STG1_MAXMAINTH = 3312755;
const double STG2_MAXMAINTH = 110050;
const double PB_MAXRCSTH = 0;

// ==============================================================
// Shuttle-PB class interface
// ==============================================================

class DeltaIV: public VESSEL2 {
public:
    DeltaIV (OBJHANDLE hVessel, int flightmodel)
        : VESSEL2 (hVessel, flightmodel) {}

    PROPELLANT_HANDLE LOX_LH2_1, LOX_LH2_2, PLD_FUEL_ph, SOLID, SEP1_EXP;
    THRUSTER_HANDLE th_main, th_rcs[14], th_group[4], th_sep1[12], th_bstr[2], th_fx1, th_fx2[2], th_fx3;

    void clbkSetClassCaps (FILEHANDLE cfg);
    void clbkPreStep(double SimT, double SimDT, double MJD);
    void SpawnObject(char* classname, char* ext, VECTOR3 ofs);
    void PLD_Handling();
    int DeltaIV::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate);

    int FAIR;
    int J1ST;
    int PLD;
    double BSTRIG;
    double MET;
    double MET0;
    double CTD;
    double CTD0;
    double CTD2;
    double CTDL;
    double X;
    double Course;
    double pitch;
    int PitchState;
    double Phase2;
    double HDG;
    double Matt;
    double CoM;
    double HorzAcc;
    double VerAcc;
};

// ==============================================================
// Overloaded callback functions
// ==============================================================

// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void DeltaIV::clbkSetClassCaps (FILEHANDLE cfg)
{

FAIR=0;
J1ST=0;
BSTRIG=0;
PLD=10300;
MET=-1;
MET0=-1;
CTD=-100;
CTD0=10;
CTDL=0;
CTD2=0;
X=5.5;
PitchState=0;
Phase2=0;
HDG=90;
Matt=1;
CoM=0;
VerAcc=0;

    // physical specs
    SetSize (40);
    SetEmptyMass (3849*2+26760+2850+LOX_LH2_STG2+3550+PLD);
    SetCW (0.15, 0.2, 0.5, 0.5);
    SetCrossSections (_V(2.89,3.14,26.84));
    SetRotDrag (_V(0.1,0.1,0.1));
    SetPMI (_V(60,60,30));
    SetCameraOffset (_V(0,2.75,-10));
    SetTouchdownPoints (_V(0,-20,-52), _V(-14,14,-52), _V(14,14,-52));
    // Atlantis // SetTouchdownPoints (_V(0,-10,-53.3), _V(-7,7,-53.3), _V(7,7,-53.3));
    SetSurfaceFrictionCoeff (100, 100);

    // propellant ressources

    LOX_LH2_1 = CreatePropellantResource (LOX_LH2_STG1);
    SOLID = CreatePropellantResource (BOOSTER_FUEL);


    // ***************** thruster definitions *******************

    PARTICLESTREAMSPEC condensation = {
        0, 4.0, 60, 40, 0.20, 0.2, 2, 3.0, PARTICLESTREAMSPEC::DIFFUSE,
        PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
        PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
    };

    PARTICLESTREAMSPEC cryo = {
        0, 0.3, 14, 2, 0.20, 0.5, 0.5, 0, PARTICLESTREAMSPEC::DIFFUSE,
        PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
        PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
    };

    PARTICLESTREAMSPEC contrail_main = {
        0, 4.0, 18, 220, 0.15, 0.5, 4, 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
    };

    PARTICLESTREAMSPEC contrail_booster = {
        0, 8, 40, 150, 0.2, 8, 4, 4, PARTICLESTREAMSPEC::DIFFUSE,
        PARTICLESTREAMSPEC::LVL_PSQRT, 0, 2,
        PARTICLESTREAMSPEC::ATM_PLOG, 1e-4, 1
    };
    PARTICLESTREAMSPEC exhaust_booster = {
        0, 3.5, 50, 250, 0.05, 0.6, 20, 4, PARTICLESTREAMSPEC::EMISSIVE,
        PARTICLESTREAMSPEC::LVL_FLAT, 1, 1,
        PARTICLESTREAMSPEC::ATM_FLAT, 1, 1
    };
    PARTICLESTREAMSPEC fx_fire = {
        0, 15, 20, 5, 1, 5, 30, 4, PARTICLESTREAMSPEC::EMISSIVE,
        PARTICLESTREAMSPEC::LVL_FLAT, 1, 1,
        PARTICLESTREAMSPEC::ATM_FLAT, 1, 1
    };

    SURFHANDLE tex = oapiRegisterExhaustTexture ("Exhaust2");
    exhaust_booster.tex = oapiRegisterParticleTexture ("Contrail2");
    fx_fire.tex = oapiRegisterParticleTexture ("Contrail2");

    th_fx1 = CreateThruster (_V(0,0,45), _V(0,0,1), 0, LOX_LH2_1, 1);
    CreateThrusterGroup (&th_fx1, 1, THGROUP_USER);
    AddExhaustStream (th_fx1, _V(0,0,45), &condensation);

    th_fx2[0] = CreateThruster (_V(0,2.5,29), _V(0,-1,0), 0, LOX_LH2_1, 1);
    th_fx2[1] = CreateThruster (_V(0,2.5,-23), _V(0,-1,0), 0, LOX_LH2_1, 1);
    CreateThrusterGroup (th_fx2, 2, THGROUP_USER);
    AddExhaustStream (th_fx2[0], _V(0,2.5,29), &cryo);
    AddExhaustStream (th_fx2[1], _V(0,2,-23), &cryo);

    th_fx3 = CreateThruster (_V(0,0,25), _V(0,0,1), 0, LOX_LH2_1, 1);
    CreateThrusterGroup (&th_fx3, 1, THGROUP_USER);
    AddExhaustStream (th_fx3, _V(0,0,25), &fx_fire);

    th_main = CreateThruster (_V(0,0,-26), _V(0,0,1), STG1_MAXMAINTH, LOX_LH2_1, RS68_ISP, ISP_SL, 101400);
    CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
    AddExhaust (th_main, 18, 1.5, _V(0,0,-28), _V(0,0,-1));

    AddExhaustStream (th_main, _V(0,0,-30), &contrail_main);
    //AddExhaustStream (th_main, _V(0,0,-30), &exhaust_main);

    th_bstr[0] = CreateThruster (_V(3.25,0,-24), _V(0,0,1), BSTR_MAXMAINTH, SOLID, BSTR_ISP);
    th_bstr[1] = CreateThruster (_V(-3.25,0,-24), _V(0,0,1), BSTR_MAXMAINTH, SOLID, BSTR_ISP);
    CreateThrusterGroup (th_bstr, 2, THGROUP_USER);

    AddExhaustStream (th_bstr[0], _V(3.5,0,-30), &contrail_booster);
    AddExhaustStream (th_bstr[0], _V(3.5,0,-24.5), &exhaust_booster);
    AddExhaustStream (th_bstr[1], _V(-3.5,0,-30), &contrail_booster);
    AddExhaustStream (th_bstr[1], _V(-3.5,0,-24.5), &exhaust_booster);

    th_rcs[ 0] = CreateThruster (_V( 1,0, 3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 1] = CreateThruster (_V( 1,0, 3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 2] = CreateThruster (_V(-1,0, 3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 3] = CreateThruster (_V(-1,0, 3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 4] = CreateThruster (_V( 1,0,-3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 5] = CreateThruster (_V( 1,0,-3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 6] = CreateThruster (_V(-1,0,-3), _V(0, 1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 7] = CreateThruster (_V(-1,0,-3), _V(0,-1,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 8] = CreateThruster (_V( 1,0, 3), _V(-1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[ 9] = CreateThruster (_V(-1,0, 3), _V( 1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[10] = CreateThruster (_V( 1,0,-3), _V(-1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[11] = CreateThruster (_V(-1,0,-3), _V( 1,0,0), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[12] = CreateThruster (_V( 0,0,-3), _V(0,0, 1), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);
    th_rcs[13] = CreateThruster (_V( 0,0, 3), _V(0,0,-1), PB_MAXRCSTH, LOX_LH2_1, RS68_ISP);

    th_group[0] = th_rcs[0];
    th_group[1] = th_rcs[2];
    th_group[2] = th_rcs[5];
    th_group[3] = th_rcs[7];
    CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHUP);

    th_group[0] = th_rcs[1];
    th_group[1] = th_rcs[3];
    th_group[2] = th_rcs[4];
    th_group[3] = th_rcs[6];
    CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHDOWN);

    th_group[0] = th_rcs[0];
    th_group[1] = th_rcs[4];
    th_group[2] = th_rcs[3];
    th_group[3] = th_rcs[7];
    CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKLEFT);

    th_group[0] = th_rcs[1];
    th_group[1] = th_rcs[5];
    th_group[2] = th_rcs[2];
    th_group[3] = th_rcs[6];
    CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKRIGHT);

    th_group[0] = th_rcs[0];
    th_group[1] = th_rcs[4];
    th_group[2] = th_rcs[2];
    th_group[3] = th_rcs[6];
    CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);

    th_group[0] = th_rcs[1];
    th_group[1] = th_rcs[5];
    th_group[2] = th_rcs[3];
    th_group[3] = th_rcs[7];
    CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN);

    th_group[0] = th_rcs[8];
    th_group[1] = th_rcs[11];
    CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);

    th_group[0] = th_rcs[9];
    th_group[1] = th_rcs[10];
    CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);

    th_group[0] = th_rcs[8];
    th_group[1] = th_rcs[10];
    CreateThrusterGroup (th_group, 2, THGROUP_ATT_LEFT);

    th_group[0] = th_rcs[9];
    th_group[1] = th_rcs[11];
    CreateThrusterGroup (th_group, 2, THGROUP_ATT_RIGHT);

    CreateThrusterGroup (th_rcs+12, 1, THGROUP_ATT_FORWARD);
    CreateThrusterGroup (th_rcs+13, 1, THGROUP_ATT_BACK);

    // visual specs
    VECTOR3 Stg1 = _V(0,0,CoM);
    AddMesh ("DeltaIVstg1",&Stg1); // IDX 0
    SetMeshVisibilityMode (0, MESHVIS_ALWAYS);

    VECTOR3 Stg2 = _V(0,0,24.25);
    AddMesh("DeltaIVstg2",&Stg2); // IDX 1
    SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

    VECTOR3 Plf1 = _V(0,0,29);
    AddMesh("DeltaIVplf_1",&Plf1); // IDX 2
    SetMeshVisibilityMode (2, MESHVIS_ALWAYS);

    VECTOR3 Plf2 = _V(0,0,29);
    AddMesh("DeltaIVplf_2",&Plf2); // IDX 3
    SetMeshVisibilityMode (3, MESHVIS_ALWAYS);

    VECTOR3 Pld = _V(0,0,31.75);
    AddMesh("Carina",&Pld); // IDX 4
    SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

    VECTOR3 Bstr1 = _V(-3.25,0,-15);
    AddMesh("Gem60_1",&Bstr1); // IDX 5
    SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

    VECTOR3 Bstr2 = _V(3.25,0,-15);
    AddMesh("Gem60_2",&Bstr2); // IDX 6
    SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

ShiftCentreOfMass(_V(0,0,4.31));

}

void DeltaIV::SpawnObject(char* classname, char* ext, VECTOR3 ofs) {
  VESSELSTATUS vs;
  char name[256];
  GetStatus(vs);
  Local2Rel (ofs, vs.rpos);
  vs.eng_main = vs.eng_hovr = 0;
  vs.status = 0;
  strcpy (name, GetName()); strcat (name, ext);
  oapiCreateVessel (name, classname, vs);
};

void DeltaIV::clbkPreStep(double SimT, double SimDT, double MJD) {


/// VISUAL EFFECTS ////////////////////////////////////////////////////////////////////////////

if (GetDynPressure() > 20000 && FAIR==0) {
    SetThrusterLevel(th_fx1, 1);
        } else {
        SetThrusterLevel(th_fx1, 0);
}

if (GetDynPressure() > 40000) {
    SetThrusterLevel(th_fx3, 1);
        } else {
            SetThrusterLevel(th_fx3, 0);
}

if (GetDynPressure() > 45000) {
    SetThrusterLevel(th_main, 0);
}

if (BSTRIG < 2) {
    SetThrusterLevel(th_fx2[0], 1);
    SetThrusterLevel(th_fx2[1], 1);
        } else {
    SetThrusterLevel(th_fx2[0], 0);
    SetThrusterLevel(th_fx2[1], 0);
}


/// BOOSTERS IGNITION //////////////////////////////////////////////////////////////////////////

if ((GetThrusterLevel(th_main) > 0.90) && (BSTRIG==2)) {
    SetThrusterLevel(th_bstr[0], 1);
    SetThrusterLevel(th_bstr[1], 1);
    MET0 = SimT;        // MET+0
    BSTRIG=3;
}

/// THRUST VECTORING ///////////////////////////////////////////////////////////////////////////

double P,Y,R;
P=GetThrusterGroupLevel(THGROUP_ATT_PITCHUP)-GetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN);
Y=GetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT)-GetThrusterGroupLevel(THGROUP_ATT_YAWLEFT);
R=GetThrusterGroupLevel(THGROUP_ATT_BANKRIGHT)-GetThrusterGroupLevel(THGROUP_ATT_BANKLEFT);
SetThrusterDir(th_main,_V((-0.0005*Y),(-0.0005*P),1)); // soustraire valeur absolue P+R


/// STAGE 2 SEPARATION //////////////////////////////////////////////////////////////////////////

if (J1ST==3 && GetPropellantMass(LOX_LH2_2) < 4) {
    DelMesh(1);
    DelThrusterGroup (THGROUP_MAIN, true);
    SpawnObject("DIV_stg2","-Stage2",_V(0,0,0));
    SetEmptyMass (PLD);
    SetCameraOffset (_V(0,0,9));

    PLD_FUEL_ph = CreatePropellantResource (PLD_FUEL);
    SetDefaultPropellantResource(PLD_FUEL_ph);
    SetMaxFuelMass(100);
    th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, PLD_FUEL_ph, 3000);
    CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
    AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

    ShiftCG(_V(0,0,9));
    SetPMI (_V(3,3,1));
    ShiftMesh (4,_V(0,0,3.75));
    SetThrusterLevel(th_main, 1);
    J1ST=4;
}

/// COUNTDOWN //////////////////////////////////////////////////////////////////////////////////

//if (CTDL=0) {
//    SetThrusterLevel(th_main, 0);
//}

if (CTDL == 1) {
    CTD0 = SimT+10;
    CTDL = 2;
    BSTRIG = 1; // BOOSTERS READY
}

if (BSTRIG == 1) { 
    CTD = SimT - CTD0;
}
if (CTD > -10 && CTD < -5) {
    SetThrusterLevel(th_main, 0.01);
}
if (CTD > -5 && CTD < 0) {
    double MainE;
    MainE = CTD * 0.083 + 1;
    SetThrusterLevel (th_main, MainE);
    SetPropellantMass (LOX_LH2_1, 199640);
}
if (CTD>=0.2 && BSTRIG==1) {
    BSTRIG=2;
}

/// MISSION ELAPSED TIME ///////////////////////////////////////////////////////////////////////

if (BSTRIG >= 2) {
    MET = SimT - MET0;
}

/// BOOSTERS POWER CURVE ///////////////////////////////////////////////////////////////////////

if (MET > 0 && MET < 7) {
    double BstrThr1;
    double BstrIsp1;
    BstrThr1 = 7894.6214 * MET + 774098.65;
    BstrIsp1 = 25.1096 * MET + 2451.8427;
    SetThrusterIsp (th_bstr[0], BstrIsp1);
    SetThrusterIsp (th_bstr[1], BstrIsp1);
    SetThrusterMax0 (th_bstr[0], BstrThr1);
    SetThrusterMax0 (th_bstr[1], BstrThr1);
}
if (MET > 7 && MET < 17) {
    double BstrThr2;
    double BstrIsp2;
    BstrThr2 = 2213.9 * (MET-7) + 829361;
    BstrIsp2 = 7.014 * (MET-7) + 2627.61;
    SetThrusterIsp (th_bstr[0], BstrIsp2);
    SetThrusterIsp (th_bstr[1], BstrIsp2);
    SetThrusterMax0 (th_bstr[0], BstrThr2);
    SetThrusterMax0 (th_bstr[1], BstrThr2);
}
if (MET > 17 && MET < 39) {
    double BstrThr3;
    double BstrIsp3;
    BstrThr3 = -10430.875 * (MET-17) + 851500;
    BstrIsp3 = -33.0474 * (MET-17) + 2697.75;
    SetThrusterIsp (th_bstr[0], BstrIsp3);
    SetThrusterIsp (th_bstr[1], BstrIsp3);
    SetThrusterMax0 (th_bstr[0], BstrThr3);
    SetThrusterMax0 (th_bstr[1], BstrThr3);
}
if (MET > 39 && MET < 57) {
    double BstrThr4;
    double BstrIsp4;
    BstrThr4 = 4607.5611 * (MET-39) + 622020.75;
    BstrIsp4 = 14.597824 * (MET-39) + 1970.7064;
    SetThrusterIsp (th_bstr[0], BstrIsp4);
    SetThrusterIsp (th_bstr[1], BstrIsp4);
    SetThrusterMax0 (th_bstr[0], BstrThr4);
    SetThrusterMax0 (th_bstr[1], BstrThr4);
}
if (MET > 57 && MET < 81) {
    double BstrThr5;
    double BstrIsp5;
    BstrThr5 = -10945.323 * (MET-57) + 704956.85;
    BstrIsp5 = -34.677327 * (MET-57) + 2233.4672;
    SetThrusterIsp (th_bstr[0], BstrIsp5);
    SetThrusterIsp (th_bstr[1], BstrIsp5);
    SetThrusterMax0 (th_bstr[0], BstrThr5);
    SetThrusterMax0 (th_bstr[1], BstrThr5);
}
if (MET > 81 && MET < 88) {
    double BstrThr6;
    double BstrIsp6;
    BstrThr6 = -51333.286 * (MET-81) + 442269.1;
    BstrIsp6 = -189.74176 * (MET-81) + 1401.2114;
    SetThrusterIsp (th_bstr[0], BstrIsp6);
    SetThrusterIsp (th_bstr[1], BstrIsp6);
    SetThrusterMax0 (th_bstr[0], BstrThr6);
    SetThrusterMax0 (th_bstr[1], BstrThr6);
}
if (MET > 88 && MET < 94) {
    double BstrThr7;
    double BstrIsp7;
    BstrThr7 = -9210.3917 * (MET-88) + 82936.1;
    BstrIsp7 = -27.126808 * (MET-88) + 262.76085;
    SetThrusterIsp (th_bstr[0], BstrIsp7);
    SetThrusterIsp (th_bstr[1], BstrIsp7);
    SetThrusterMax0 (th_bstr[0], BstrThr7);
    SetThrusterMax0 (th_bstr[1], BstrThr7);
}
if (MET > 94 && MET < 100) {
    double BstrThr8;
    double BstrIsp8;
    BstrThr8 = 1000;
    BstrIsp8 = 100;
    SetThrusterIsp (th_bstr[0], BstrIsp8);
    SetThrusterIsp (th_bstr[1], BstrIsp8);
    SetThrusterMax0 (th_bstr[0], BstrThr8);
    SetThrusterMax0 (th_bstr[1], BstrThr8);
}

/// ASCENT PROGRAM /////////////////////////////////////////////////////////////////////////////

double BFUEL;
double MFUEL;
double MASS;
double ISP;
double Course1;
double CRS;
double YawRate;
double PitchRate;
double PS;
double alt;
double VVel;
double AVel;
double YVel;
double ApA;
double PeA;

double Vacc;
double dt;
dt = oapiGetSimStep();

BFUEL = GetPropellantMass(SOLID);
MFUEL = GetPropellantMass(LOX_LH2_1);
MASS = GetEmptyMass();
ISP = GetThrusterIsp(th_main)/9.81;
Course1 = oapiGetFocusHeading(&Course);
Course*=DEG;
CRS = Course;
pitch = GetPitch();
alt=GetAltitude();

//if (MET > 0) {
//CoM = -8.9311e-5 * -MFUEL + 22.14;
//}

pitch*=DEG;

VECTOR3 xyz;
GetHorizonAirspeedVector(xyz);
VVel=xyz.y;

VECTOR3 abc;
GetAngularVel(abc);
AVel=abc.x;
AVel*=DEG;
YVel=abc.y;
YVel*=DEG;

Vacc = VVel;

VESSEL *v;
v = oapiGetFocusInterface();

OBJHANDLE hBody=NULL;
hBody = v->GetSurfaceRef();
v->GetApDist(ApA);
v->GetPeDist(PeA);
ApA -=oapiGetSize(hBody);
PeA -=oapiGetSize(hBody);

///***

    static double SimTimeOld = 0;

    static double horz_speed_old = 0;
    static double vert_speed_old = 0;

    double SimTimeNew = oapiGetSimTime();
    
    VESSEL* V = oapiGetFocusInterface();
    VECTOR3 V3;

    V->GetHorizonAirspeedVector    (V3);

    double horz_speed_new = sqrt((V3.x*V3.x)+(V3.z*V3.z));
    double vert_speed_new = V3.y;
    
    HorzAcc = (horz_speed_new - horz_speed_old) / SimDT;
    VerAcc  = (vert_speed_new - vert_speed_old) / SimDT;
    //TotAcc = sqrt((HorzAcc*HorzAcc)+(VerAcc*VerAcc));
    SimTimeOld = SimTimeNew;
    horz_speed_old = horz_speed_new;
    vert_speed_old = vert_speed_new;

///***


//ShiftCentreOfMass(_V(0,0,CoM));

if (MET<0) {PitchState=0;}

PS=PitchState;

if (GetThrusterLevel(th_main)<0.6 && GetThrusterLevel(th_main)>0.01 && MET>0 && J1ST<2) {
        SetThrusterLevel(th_main, 0.6);
}
if (GetThrusterLevel(th_main) < 0.6 && GetThrusterLevel(th_main) > 0.01 && MET > 254+X) {
        SetThrusterLevel(th_main, 0.6);
}

//double;

if (alt < 2500) {YawRate=1;}
if (alt > 2500 && alt < 7500) {YawRate=1;}
if (alt > 7500 && alt < 15000) {YawRate=1;}
if (alt > 15000 && alt < 25000) {YawRate=1;}
if (alt > 25000 && MET < 230+X) {YawRate=1;}

if (MET < 5) {PitchRate=1;}
if (alt < 5000 && MET > 6) {PitchRate=0.4;}

if (alt > 5000 && alt < 10000) {PitchRate=1;}
if (alt >= 10000 && alt < 25000) {PitchRate=1;}
if (alt >= 25000 && alt < 50000) {PitchRate=1;}
if (alt >= 50000 && alt < 80000) {PitchRate=1;}
if (alt >= 80000 && alt < 100000) {PitchRate=1;}
if (alt >= 100000 && MET < 230+X) {PitchRate=1;}
if (MET >= 230+X && MET < 285+X) {PitchRate=0; YawRate=0;}
if (MET >= 285+X) {PitchRate=1; YawRate=1;}


if (MET > 0 && MET <=5 && GetAltitude() > 75) {PitchState=-1;}

if (YVel <= -0.25) {
    SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, 0);
    SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, 1);
}
if (YVel >= 0.25) {
    SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, 1);
    SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, 0);
}
if (MET > 4 && CRS < HDG && fabs(YVel) < 0.25) {
    SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, YawRate);
    SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, 0);
}

if (MET > 4 && CRS > HDG && fabs(YVel) < 0.25) {
    SetThrusterGroupLevel(THGROUP_ATT_YAWLEFT, YawRate);
    SetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT, 0);
}

if ((pitch > 90-(alt/1000) && MET>5 && MET<230+X) || (ApA > 35000 && MET<230+X)) {PitchState=-1;}
if (pitch < 90-(alt/1000) && MET>5 && ApA < 35000 && MET<230+X) {PitchState=1;}
if (alt > 50000 && alt < 80000 && pitch > 7) {PitchState=-1;}
if (alt > 65000 && alt < 80000 && pitch < 6) {PitchState=1;}
if (alt > 80000 && alt < 90000 && pitch > 6) {PitchState=-1;}
if (alt > 80000 && alt < 90000 && pitch < 5) {PitchState=1;}
if (alt > 90000 && alt < 100000 && pitch > 5) {PitchState=-1;}
if (alt > 90000 && alt < 100000 && pitch < 4) {PitchState=1;}
if (alt > 100000 && alt < 1000000 && pitch > 4 && MET<230+X) {PitchState=-1;}
if (alt > 100000 && alt < 1000000 && pitch < 4 && MET<230+X) {PitchState=1;}
if (MET > 196+X && pitch < 30 && MET < 230+X) {PitchState=1;}

if (MET > 285+X && Phase2<1 && pitch>35 && (pitch>35 || ApA>135000 || VerAcc>0.1))

{PitchState=-1; Matt=0.75;
}

if (MET > 285+X && Phase2<1 && pitch<35 && (pitch<35 || ApA<135000 || VerAcc<0.1))

{PitchState=1; Matt=0.75;
}

if (alt > 135000 && Phase2<1) {
Phase2=1;
PitchState=0;
HDG=106;
Matt=0.5;
}

if (alt<135000 && Phase2==1) {
Phase2=0;
PitchState=0;
HDG=106;
Matt=0.5;
}

if (Phase2==1) {Matt=0.3;}

/// PHASE 2 : Altitude > 150,000 km ///

/// PROGRAMS

double AAP200, AAP201, AAP210, AAP211, AAP220, AAP221, AAP230, AAP231, AAP240, AAP241;
double PROG;

/// 200 & 201 : basic pitch control [0-35]

if (Phase2==1 && pitch>35 && pitch>0)
{AAP200=1;  // pitch up limit exceeded
} else {AAP200=0;}

if (Phase2==1 && pitch<0 && pitch<35)
{AAP201=1;        // pitch low limit exceeded
} else {AAP201=0;}

/// 210 & 211 : Vertical Acceleration control [-1 +1]

if (Phase2==1 && VerAcc>1)
{AAP210=1;        // max vertical acc. exceeded
} else {AAP210=0;}

if (Phase2==1 && VerAcc<-1)
{AAP211=1;        // min vertical acc. exceeded
} else {AAP211=0;}


/// 220 & 221 : Vertical Velocity control

if (Phase2==1 && VVel>100)
{AAP220=1;        // vertical vel. > 0
} else {AAP220=0;}

if (Phase2==1 && VVel<-100)
{AAP221=1;      // vertical vel. < 0
} else {AAP221=0;}


/// 230 & 231 : Vertical Acceleration control [0]

if (Phase2==1 && VerAcc > 0)
{AAP230=1;        // vertical acc. > 0
} else {AAP230=0;}

if (Phase2==1 && VerAcc < 0)
{AAP231=1;        // vertical acc. < 0
} else {AAP231=0;}

/// 240 & 241 : Altitude control [185000]

if (Phase2==1 && alt>185000)
{AAP240=1;        // vertical acc. > 0
} else {AAP240=0;}

if (Phase2==1 && alt<185000)
{AAP241=1;        // vertical acc. > 0
} else {AAP241=0;}


/// PHASE 2 PITCH CONTROL

if (AAP200==1) {
    PitchState = -1; PROG=200;
} else {
    AAP200=0;
}

if (AAP201==1) {
    PitchState = 1;  PROG=201;
} else {
    AAP201=0;
}

if (AAP210==1 && !(AAP200==1 || AAP201==1)) {
    PitchState = -1; PROG=210;
} else {
    AAP210=0;
}

if (AAP211==1 && !(AAP200==1 || AAP201==1 || AAP221==1)) {
    PitchState = 1;  PROG=211;
} else {
    AAP211=0;
}

if (AAP220==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1)) {
    PitchState = -1; PROG=220;
} else {
    AAP220=0;
}

if (AAP221==1 && !(AAP200==1 || AAP201==1 || AAP210==1)) {
    PitchState = 1;  PROG=221;
} else {
    AAP221=0;
}

if (AAP230==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1 || AAP240==1 || AAP241==1)) {
    PitchState = -1; PROG=230;
} else {
    AAP230=0;
}

if (AAP231==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1 || AAP240==1 || AAP241==1)) {
    PitchState = 1;  PROG=231;
} else {
    AAP231=0;
}

if (AAP240==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1)) {
    PitchState = -1; PROG=240;
} else {
    AAP240=0;
}

if (AAP241==1 && !(AAP200==1 || AAP201==1 || AAP210==1 || AAP211==1 || AAP220==1 || AAP221==1)) {
    PitchState = 1; PROG=241;
} else {
    AAP241=0;
}


sprintf(oapiDebugString(),"MET %f BOOSTERS %f MASS %f ISP %f COURSE %f PITCH %f VACC %f AVel %f PROG %f Phase2 %f", MET, BFUEL, MASS, ISP, CRS, pitch, VerAcc, AVel, PROG, Phase2);

/// End PHASE 2 ///

if (AVel >= Matt) {
    SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 1);
    SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 0);
}
if (AVel <= -Matt) {
    SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 0);
    SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 1);
}
if (PitchState==-1 && fabs(AVel) < Matt) {
    SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, PitchRate);
    SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 0);
}
if (PitchState==1 && fabs(AVel) < Matt) {
    SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 0);
    SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, PitchRate);
}
if (PitchState==0) {
    SetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN, 0);
    SetThrusterGroupLevel(THGROUP_ATT_PITCHUP, 0);
}

if (MET > 100 && BSTRIG==3) {
    DelMesh(5);
    DelMesh(6);
    DelThruster (th_bstr[0]);
    DelThruster (th_bstr[1]);
    SpawnObject("DIVbstr_1","-Booster1",_V(3.25,0,-15));
    SpawnObject("DIVbstr_2","-Booster2",_V(-3.25,0,-15));
    SetEmptyMass (26760+2850+LOX_LH2_STG2+3550+PLD);
    BSTRIG=4;
    HDG=96;
}

if (MET >= 230+X && MET < 237+X) {
    ActivateNavmode (NAVMODE_KILLROT);
    HDG=98;
}

if (MET >= 237+X && MET < 242+X) {
    double CBCLvl;
    CBCLvl = -0.08 * (MET-(237+X)) + 1;
    SetThrusterLevel(th_main, CBCLvl);
}
if (MET >= 247+X && MET < 253+X) {
    SetThrusterLevel(th_main, 0);
    DeactivateNavmode (NAVMODE_KILLROT);
}

if (MET >= 242+X && MET < 247+X) {
    J1ST=10;
    double CBCLvl;
    CBCLvl = -0.12 * (MET-(242+X)) + 0.6;
    SetThrusterLevel(th_main, CBCLvl);
    J1ST=5;
}

if (MET > 253+X && J1ST == 5) {
    DelMesh(0);
    DelThrusterGroup (THGROUP_MAIN, true);
    SpawnObject("DIV_stg1","-Stage1",_V(0,0,0));
    SetPMI (_V(15,15,5));
    SetEmptyMass (2850+3550+PLD);
    SetPropellantMass (LOX_LH2_1, LOX_LH2_STG2);
    SetMaxFuelMass(21320);
    ShiftCG(_V(0,0,26.5));
    SetCameraOffset (_V(0,2.75,0));
    LOX_LH2_2 = CreatePropellantResource (SEP1_FUEL1);
    SEP1_EXP = CreatePropellantResource (SEP1);
    th_sep1[0] = CreateThruster (_V( 2.5,0.1,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[1] = CreateThruster (_V(-2.5,-0.10,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[2] = CreateThruster (_V( 0.1,2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[3] = CreateThruster (_V( -0.1,-2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[4] = CreateThruster (_V( 2.5,-0.1,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[5] = CreateThruster (_V(-2.5,0.1,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[6] = CreateThruster (_V(-0.1,2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[7] = CreateThruster (_V(0.10,-2.5,0.4), _V(0,0,1), 110, LOX_LH2_2, 3000);
    th_sep1[8] = CreateThruster (_V( 2.5,-0.1,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
    th_sep1[9] = CreateThruster (_V(-2.5,0.1,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
    th_sep1[10] = CreateThruster (_V(-0.1,2.5,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
    th_sep1[11] = CreateThruster (_V(0.10,-2.5,0.4), _V(0,0,1), 7500, SEP1_EXP, 2500);
    CreateThrusterGroup (th_sep1, 12, THGROUP_USER);
    for (int i=0;i<8;i++) {
        AddExhaust(th_sep1[i],0.75,0.05);
        }
    for (int i=8;i<12;i++) {
        AddExhaust(th_sep1[i],0,0.35);
        }
    J1ST=1;
}
if (J1ST==1 && GetPropellantMass(LOX_LH2_2) > 0) {
    for (int i=0;i<12;i++) {
        SetThrusterLevel(th_sep1[i], 1);
        }
}
if (J1ST==1 && MET >= 254+X && MET < 255+X) {
    th_main = CreateThruster (_V(0,0,-9), _V(0,0,1), STG2_MAXMAINTH, LOX_LH2_1, 4532.22, 10, 101400);
    CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
    AddExhaust (th_main, 8, 1, _V(0,0,-9), _V(0,0,-1));
    J1ST=2;
}
if (MET >= 268+X && MET < 274+X) {
    double Stage2Lvl;
    Stage2Lvl = 0.2 * (MET-(268+X)) + 0;
    SetThrusterLevel(th_main, Stage2Lvl);
}
if (MET >= 284+X && MET <= 285+X && FAIR==0) {
    DelMesh(2);
    SpawnObject("DIVplf_1","-Fairing1",_V(0,0,8));
    DelMesh(3);
    SpawnObject("DIVplf_2","-Fairing2",_V(0,0,8));
    SetEmptyMass (2850+PLD);
    FAIR=1;
}

if (PeA>185000) {
    SetThrusterLevel(th_main, 0);
}


};
/// END OF CLBKPRESTEP /////////////////////////////////////////////////////////////////////////

int DeltaIV::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate) {
  if (!down) return 0; // only process keydown events

  if (KEYMOD_SHIFT (kstate)) {

  } else { // unmodified keys
    switch (key) {

        case OAPI_KEY_J:
            J1ST=3;
        return 1;
  
        case OAPI_KEY_O:
            CTDL = 1;
        return 1;
    }
  }
  return 0;
};


// ==============================================================
// API callback interface
// ==============================================================

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
    return new DeltaIV (hvessel, flightmodel);
}

// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
    if (vessel) delete (DeltaIV*)vessel;
}
Actually it did the works. As soon as my charger comes in tomorrow then I will be able to work on it. Only confusing thing about this is the AP. Lol. It's all right though because it is palpable in the state of my understanding.Thank you very much people. :)
 

MJR

C++ developer in the mix
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 19, 2008
Messages
2,460
Reaction score
5
Points
0
Location
United States
As you can see, I took a piece from Molson's code to kind of start out a bit. Just one error which I don't understand.

Code:
Error	1	error LNK2001: unresolved external symbol "void __cdecl dummy(void)" (?dummy@@YAXXZ)	C:\Users\Michael\Documents\Visual Studio 2010\Projects\Nipon-1\Nipon-1\Nipon.obj	Nipon-1
Error	2	error LNK1120: 1 unresolved externals	C:\Users\Michael\Documents\Visual Studio 2010\Projects\Nipon-1\Release\Nipon-1.dll	Nipon-1

Here is the code.

Code:
// ==============================================================
//                 ORBITER MODULE: ShuttlePB
//                  Part of the ORBITER SDK
//          Copyright (C) 2002-2004 Martin Schweiger
//                   All rights reserved
//
// ShuttlePB.cpp
// Control module for ShuttlePB vessel class
//
// Notes:
// This is an example for a "minimal" vessel implementation which
// only overloads the clbkSetClassCaps method to define vessel
// capabilities and otherwise uses the default VESSEL class
// behaviour.
// ==============================================================

#define STRICT
#define ORBITER_MODULE

#include "orbitersdk.h"

// ==============================================================
// Some vessel parameters
// ==============================================================
const double  NIPON_SIZE       = 3.5;             // mean radius [m]
const VECTOR3 NIPON_CS         = {10.5,15.0,5.8}; // x,y,z cross sections [m^2]
const VECTOR3 NIPON_PMI        = {2.28,2.31,0.79};// principal moments of inertia (mass-normalised) [m^2]
const VECTOR3 NIPON_RD         = {0.025,0.025,0.02};//{0.05,0.1,0.05};  // rotation drag coefficients
const double  STG1_EMPTYMASS  = 500.0;           // empty vessel mass [kg]
const double  STG2_EMPTYMASS =  400.0;
const double  STG3_EMPTYMASS =  350.0;
const double  PAYLOAD_EMPTYMASS = 100.0; 

const double  STG1_FUELMASS   = 750.0;           // max fuel mass [kg]
const double  STG2_FUELMASS   = 550.0;
const double  STG3_FUELMASS   = 230.0;
const double  PB_ISP        = 5e4;             // fuel-specific impulse [m/s]
const VECTOR3 NIPON_TDP[3]     = {{0,-1.5,2},{-1,-1.5,-1.5},{1,-1.5,-1.5}}; // touchdown points [m]
const double STAGE1_MAXMAINTH = 3312755;
const double STAGE2_MAXMAINTH = 110050;
const double STAGE3_MAXMAINTH = 90000;
const double PB_MAXRCSTH = 10000;
const double PLD_FUEL = 100;

// ==============================================================
// Shuttle-PB class interface
// ==============================================================

class Nipon: public VESSEL3 {
public:
	Nipon (OBJHANDLE hVessel, int flightmodel);
	~Nipon ();
	void clbkSetClassCaps (FILEHANDLE cfg);
	void clbkPreStep(double SimT, double SimDT, double MJD);
	void SpawnObject(char* classname, char* ext, VECTOR3 ofs);

	PROPELLANT_HANDLE STG_1, STG_2, STG_3;
	THRUSTER_HANDLE th_main, th_rcs[14], th_group[4];
	int J1ST;
	void PYLD_Handling();
	int PYLD;
	int Nipon::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate);

};

Nipon::Nipon (OBJHANDLE hVessel, int flightmodel)
: VESSEL3 (hVessel, flightmodel)
{
}

Nipon::~Nipon ()
{
}

// ==============================================================
// Overloaded callback functions
// ==============================================================

// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void Nipon::clbkSetClassCaps (FILEHANDLE cfg)
{
	

	// physical vessel parameters
	SetSize (NIPON_SIZE);
	SetEmptyMass (STG1_EMPTYMASS+STG2_EMPTYMASS+STG3_EMPTYMASS+PAYLOAD_EMPTYMASS);
	SetPMI (NIPON_PMI);
	SetCrossSections (NIPON_CS);
	SetRotDrag (NIPON_RD);
	SetTouchdownPoints (NIPON_TDP[0], NIPON_TDP[1], NIPON_TDP[2]);

	// propellant resources
	PROPELLANT_HANDLE hpr = CreatePropellantResource (STG1_FUELMASS);

	// main engine
	th_main = CreateThruster (_V(0,0,-4.35), _V(0,0,1), STAGE1_MAXMAINTH, hpr, PB_ISP);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 8, 1, _V(0,0.3,-4.35), _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.3,-10), &contrail_main);
	AddExhaustStream (th_main, _V(0,0.3,-5), &exhaust_main);

	
	// RCS engines
	th_rcs[ 0] = CreateThruster (_V( 1,0, 3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 1] = CreateThruster (_V( 1,0, 3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 2] = CreateThruster (_V(-1,0, 3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 3] = CreateThruster (_V(-1,0, 3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 4] = CreateThruster (_V( 1,0,-3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 5] = CreateThruster (_V( 1,0,-3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 6] = CreateThruster (_V(-1,0,-3), _V(0, 1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 7] = CreateThruster (_V(-1,0,-3), _V(0,-1,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 8] = CreateThruster (_V( 1,0, 3), _V(-1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[ 9] = CreateThruster (_V(-1,0, 3), _V( 1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[10] = CreateThruster (_V( 1,0,-3), _V(-1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[11] = CreateThruster (_V(-1,0,-3), _V( 1,0,0), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[12] = CreateThruster (_V( 0,0,-3), _V(0,0, 1), PB_MAXRCSTH, hpr, PB_ISP);
	th_rcs[13] = CreateThruster (_V( 0,0, 3), _V(0,0,-1), PB_MAXRCSTH, hpr, PB_ISP);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[2];
	th_group[2] = th_rcs[5];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHUP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[3];
	th_group[2] = th_rcs[4];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHDOWN);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKLEFT);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKRIGHT);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_LEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_RIGHT);

	CreateThrusterGroup (th_rcs+12, 1, THGROUP_ATT_FORWARD);
	CreateThrusterGroup (th_rcs+13, 1, THGROUP_ATT_BACK);

	// camera parameters
	SetCameraOffset (_V(0,0.8,0));

	// visual specs
	VECTOR3 Stg1 = _V(0,0,0);
	AddMesh ("Stage1",&Stg1); // IDX 0
	SetMeshVisibilityMode (0, MESHVIS_ALWAYS);

	VECTOR3 Stg2 = _V(0,0,24.25);
    AddMesh("Stage2",&Stg2); // IDX 1
	SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

	VECTOR3 Stg3 = _V(0,0,29);
    AddMesh("Stage3",&Stg3); // IDX 2
	SetMeshVisibilityMode (2, MESHVIS_ALWAYS);

	VECTOR3 Pld = _V(0,0,29);
    AddMesh("Satellite",&Pld); // IDX 3
	SetMeshVisibilityMode (3, MESHVIS_ALWAYS);

ShiftCentreOfMass(_V(0,0,4.31));
}

void Nipon::SpawnObject(char* classname, char* ext, VECTOR3 ofs) {
  VESSELSTATUS vs;
  char name[256];
  GetStatus(vs);
  Local2Rel (ofs, vs.rpos);
  vs.eng_main = vs.eng_hovr = 0;
  vs.status = 0;
  strcpy (name, GetName()); strcat (name, ext);
  oapiCreateVessel (name, classname, vs);
};


void Nipon::clbkPreStep(double SimT, double SimDT, double MJD) {




/// STAGE 2 SEPARATION //////////////////////////////////////////////////////////////////////////

if (J1ST==3 && GetPropellantMass(STG_2) < 4) {
	DelMesh(1);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("Stage2","-Stage2",_V(0,0,0));
	SetEmptyMass (STG2_EMPTYMASS);
	SetCameraOffset (_V(0,0,9));

	STG_2 = CreatePropellantResource (STG2_FUELMASS);
	SetDefaultPropellantResource(STG_2);
	SetMaxFuelMass(550.0);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, STG_2, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	J1ST=4;
}


}

/// END OF CLBKPRESTEP /////////////////////////////////////////////////////////////////////////

int Nipon::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate) {
  if (!down) return 0; // only process keydown events

  if (KEYMOD_SHIFT (kstate)) {

  } else { // unmodified keys
    switch (key) {

		case OAPI_KEY_J:
			J1ST=3;
        return 1;
  
    }
  }
  return 0;
};
// ==============================================================
// API callback interface
// ==============================================================

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
	return new Nipon (hvessel, flightmodel);
}

// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
	if (vessel) delete (Nipon*)vessel;
}
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
Yeah the "AP" (a big word) is a little... binary ! It was my first try :p

(and even worse there is a bad mix between a timer-related AP and a velocity-related AP !)
 

orb

O-F Administrator,
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
As you can see, I took a piece from Molson's code to kind of start out a bit. Just one error which I don't understand.

Code:
Error	1	error LNK2001: unresolved external symbol "void __cdecl dummy(void)" (?dummy@@YAXXZ)	C:\Users\Michael\Documents\Visual Studio 2010\Projects\Nipon-1\Nipon-1\Nipon.obj	Nipon-1
Error	2	error LNK1120: 1 unresolved externals	C:\Users\Michael\Documents\Visual Studio 2010\Projects\Nipon-1\Release\Nipon-1.dll	Nipon-1
This looks like you only included orbiter.lib as additional dependency, without Orbitersdk.lib, as it's Orbitersdk.lib which defines the "void dummy(void)" function. You don't use Orbiter property sheets, but still add the orbiter libraries by hand to your projects, do you?
 

martins

Orbiter Founder
Orbiter Founder
Joined
Mar 31, 2008
Messages
2,448
Reaction score
462
Points
83
Website
orbit.medphys.ucl.ac.uk
:hesaid:
The dummy function is used to create an explicit dependency from your module code to orbitersdk.lib (a call to dummy is embedded in your code via OrbiterAPI.h).

This prevents the linker from skipping orbitersdk.lib when creating the DLL. orbitersdk.lib contains the module entry and exit function (DllMain), which in turn calls your InitModule and ExitModule functions, plus module version information.
 

MJR

C++ developer in the mix
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 19, 2008
Messages
2,460
Reaction score
5
Points
0
Location
United States
This is a question directed towards Molson. This line, SpawnObject("Stage2","-Stage2",_V(0,0,0)); what is the -Stage2 mean? I don't think my mesh names reference itself to that and that is why it crashes every time I jettison.
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
"-Stage2" is a char string and means that the -Stage2 tag will be added to the name of the new spawned object.

The first Stage2 doesn't point to a mesh, it points to a vessel class ! It tells Orbiter to spawn a new vessel. It means that you must create a "Stage2.cfg" file. There's probably no need for a new .dll, just set a realistic empty mass, a mesh path... Something like that (exemple based on Carina.cfg) :

Code:
; === Configuration file for vessel class "Stage1" ===
ClassName = Stage1
MeshName = [I]nameofyourmesh in the meshes directory[/I]
Size = 10.0

Mass = 5000; empty mass [kg]

MaxMainThrust = 0
MaxRetroThrust = 0
MaxHoverThrust = 0
COG_OverGround = 2.0
CameraOffset = -.715 .865 -2.5
CW = 10 10 5
LiftFactor = 0.0
CrossSections = 2.45 6.25 2.45

Edit : Call it "Stage1", it makes much more sense. Because what we want to spawn here is the spent 1st stage. The code redefines the parameters of the rocket after the jettison event, so that the flight parameters of the rocket become those of the second stage. It is what said Tblaxland.
 
Last edited:

MJR

C++ developer in the mix
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 19, 2008
Messages
2,460
Reaction score
5
Points
0
Location
United States
Ok. I've made some progress, but with a few drawbacks. I've managed to get the
second stage to jettison fine with no issues. However, when I try to jettison the second stage I just get a copy of stage 1 jettisoning. Here is the code.


Code:
// ==============================================================
//                 ORBITER MODULE: ShuttlePB
//                  Part of the ORBITER SDK
//          Copyright (C) 2002-2004 Martin Schweiger
//                   All rights reserved
//
// ShuttlePB.cpp
// Control module for ShuttlePB vessel class
//
// Notes:
// This is an example for a "minimal" vessel implementation which
// only overloads the clbkSetClassCaps method to define vessel
// capabilities and otherwise uses the default VESSEL class
// behaviour.
// ==============================================================

#define STRICT
#define ORBITER_MODULE

#include "orbitersdk.h"

// ==============================================================
// Some vessel parameters
// ==============================================================
const double  NIPON_SIZE       = 3.5;             // mean radius [m]
const VECTOR3 NIPON_CS         = {10.5,15.0,5.8}; // x,y,z cross sections [m^2]
const VECTOR3 NIPON_PMI        = {2.28,2.31,0.79};// principal moments of inertia (mass-normalised) [m^2]
const VECTOR3 NIPON_RD         = {0.025,0.025,0.02};//{0.05,0.1,0.05};  // rotation drag coefficients
const double  STG1_EMPTYMASS  = 50000.0;           // empty vessel mass [kg]
const double  STG2_EMPTYMASS =  25000.0;
const double  STG3_EMPTYMASS =  10000.0;
const double  PAYLOAD_EMPTYMASS = 3500.0; 

const double  STG1_FUELMASS   = 7500.0;           // max fuel mass [kg]
const double  STG2_FUELMASS   = 5500.0;
const double  STG3_FUELMASS   = 2300.0;
const double  PB_ISP        = 5e3;             // fuel-specific impulse [m/s]
const VECTOR3 NIPON_TDP[3]     = {{0,-1,-7.25},{-1,1,-7.25},{1,1,-7.25}}; // touchdown points [m]
const double STG1_MAXMAINTH = 3312000;
const double STG2_MAXMAINTH = 1100000;
const double STG3_MAXMAINTH = 90000;
const double PB_MAXRCSTH = 6000;
const double STG2_FUEL = 100;
const double STG1_FUEL = 150;
const double STG3_FUEL = 300;
// ==============================================================
// Shuttle-PB class interface
// ==============================================================

class Nipon: public VESSEL3 {
public:
	Nipon (OBJHANDLE hVessel, int flightmodel);
	~Nipon ();
	void clbkSetClassCaps (FILEHANDLE cfg);
	void clbkPreStep(double SimT, double SimDT, double MJD);
	void SpawnObject(char* classname, char* ext, VECTOR3 ofs);

	PROPELLANT_HANDLE STG1_FUEL_ph, STG2_FUEL_ph, STG3_FUEL_ph;
	THRUSTER_HANDLE th_main, th_rcs[14], th_group[4];
	int Jettison;
	void PYLD_Handling();
	int PYLD;
	int Nipon::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate);

};

Nipon::Nipon (OBJHANDLE hVessel, int flightmodel)
: VESSEL3 (hVessel, flightmodel)
{
}

Nipon::~Nipon ()
{
}

// ==============================================================
// Overloaded callback functions
// ==============================================================

// --------------------------------------------------------------
// Set the capabilities of the vessel class
// --------------------------------------------------------------
void Nipon::clbkSetClassCaps (FILEHANDLE cfg)
{
	

	// physical vessel parameters
	SetSize (NIPON_SIZE);
	SetEmptyMass (STG1_EMPTYMASS+STG2_EMPTYMASS+STG3_EMPTYMASS+PAYLOAD_EMPTYMASS);
	SetPMI (NIPON_PMI);
	SetCrossSections (NIPON_CS);
	SetRotDrag (NIPON_RD);
	SetTouchdownPoints (NIPON_TDP[0], NIPON_TDP[1], NIPON_TDP[2]);

	// propellant resources
	STG1_FUEL_ph = CreatePropellantResource (STG1_FUELMASS);


	// main engine
	th_main = CreateThruster (_V(0,0,-8.35), _V(0,0,1), STG1_MAXMAINTH, STG1_FUEL_ph, PB_ISP);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 8, 1, _V(0,-0.32,-7.55), _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.32,-8.5), &contrail_main);
	AddExhaustStream (th_main, _V(0,-0.32,-8.5), &exhaust_main);

	
	// RCS engines
	th_rcs[ 0] = CreateThruster (_V( 1,0, 3), _V(0, 1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 1] = CreateThruster (_V( 1,0, 3), _V(0,-1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 2] = CreateThruster (_V(-1,0, 3), _V(0, 1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 3] = CreateThruster (_V(-1,0, 3), _V(0,-1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 4] = CreateThruster (_V( 1,0,-3), _V(0, 1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 5] = CreateThruster (_V( 1,0,-3), _V(0,-1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 6] = CreateThruster (_V(-1,0,-3), _V(0, 1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 7] = CreateThruster (_V(-1,0,-3), _V(0,-1,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 8] = CreateThruster (_V( 1,0, 3), _V(-1,0,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[ 9] = CreateThruster (_V(-1,0, 3), _V( 1,0,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[10] = CreateThruster (_V( 1,0,-3), _V(-1,0,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[11] = CreateThruster (_V(-1,0,-3), _V( 1,0,0), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[12] = CreateThruster (_V( 0,0,-3), _V(0,0, 1), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);
	th_rcs[13] = CreateThruster (_V( 0,0, 3), _V(0,0,-1), PB_MAXRCSTH, STG1_FUEL_ph, PB_ISP);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[2];
	th_group[2] = th_rcs[5];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHUP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[3];
	th_group[2] = th_rcs[4];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_PITCHDOWN);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKLEFT);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_BANKRIGHT);

	th_group[0] = th_rcs[0];
	th_group[1] = th_rcs[4];
	th_group[2] = th_rcs[2];
	th_group[3] = th_rcs[6];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_UP);

	th_group[0] = th_rcs[1];
	th_group[1] = th_rcs[5];
	th_group[2] = th_rcs[3];
	th_group[3] = th_rcs[7];
	CreateThrusterGroup (th_group, 4, THGROUP_ATT_DOWN);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWLEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_YAWRIGHT);

	th_group[0] = th_rcs[8];
	th_group[1] = th_rcs[10];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_LEFT);

	th_group[0] = th_rcs[9];
	th_group[1] = th_rcs[11];
	CreateThrusterGroup (th_group, 2, THGROUP_ATT_RIGHT);

	CreateThrusterGroup (th_rcs+12, 1, THGROUP_ATT_FORWARD);
	CreateThrusterGroup (th_rcs+13, 1, THGROUP_ATT_BACK);

	// camera parameters
	SetCameraOffset (_V(0,0.8,0));

	// visual specs
	VECTOR3 Stg1 = _V(0.42,-0.32,0);
	AddMesh ("Stage1",&Stg1); // IDX 0
	SetMeshVisibilityMode (0, MESHVIS_ALWAYS);

	VECTOR3 Stg2 = _V(0,-0.32,10.8);
    AddMesh("Stage2",&Stg2); // IDX 1
	SetMeshVisibilityMode (1, MESHVIS_ALWAYS);

	VECTOR3 Stg3 = _V(0,-0.32,16);
    AddMesh("Stage3",&Stg3); // IDX 2
	SetMeshVisibilityMode (2, MESHVIS_ALWAYS);

	VECTOR3 Pld = _V(0,-0.32,21);
    AddMesh("Satellite",&Pld); // IDX 3
	SetMeshVisibilityMode (3, MESHVIS_ALWAYS);

ShiftCentreOfMass(_V(0,0,4.31));
}

void Nipon::SpawnObject(char* classname, char* ext, VECTOR3 ofs) {
  VESSELSTATUS vs;
  char name[256];
  GetStatus(vs);
  Local2Rel (ofs, vs.rpos);
  vs.eng_main = vs.eng_hovr = 0;
  vs.status = 0;
  strcpy (name, GetName()); strcat (name, ext);
  oapiCreateVessel (name, classname, vs);
};


void Nipon::clbkPreStep(double SimT, double SimDT, double MJD) {




/// STAGE 1 SEPARATION //////////////////////////////////////////////////////////////////////////

if (Jettison==3 && GetPropellantMass(STG1_FUEL_ph) < 4) {
	DelMesh(0);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("Stage1","-Stage1",_V(0,0,0));
	SetEmptyMass (STG1_EMPTYMASS);
	SetCameraOffset (_V(0,0,9));

	STG1_FUEL_ph = CreatePropellantResource (STG1_FUEL);
	SetDefaultPropellantResource(STG1_FUEL_ph);
	SetMaxFuelMass(550.0);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, STG1_FUEL_ph, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	Jettison=4;
}

/// STAGE 2 SEPARATION //////////////////////////////////////////////////////////////////////////

if (Jettison==3 && GetPropellantMass(STG2_FUEL_ph) < 4) {
	DelMesh(1);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("Stage2","-Stage2",_V(0,0,0));
	SetEmptyMass (STG2_EMPTYMASS);
	SetCameraOffset (_V(0,0,9));

	STG2_FUEL_ph = CreatePropellantResource (STG2_FUEL);
	SetDefaultPropellantResource(STG2_FUEL_ph);
	SetMaxFuelMass(550.0);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, STG2_FUEL_ph, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	Jettison=4;
}

/// STAGE 3 SEPARATION //////////////////////////////////////////////////////////////////////////

if (Jettison==3 && GetPropellantMass(STG3_FUEL_ph) < 4) {
	DelMesh(2);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("Stage3","-Stage3",_V(0,0,0));
	SetEmptyMass (STG3_EMPTYMASS);
	SetCameraOffset (_V(0,0,9));

	STG3_FUEL_ph = CreatePropellantResource (STG3_FUEL);
	SetDefaultPropellantResource(STG3_FUEL_ph);
	SetMaxFuelMass(550.0);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, STG3_FUEL_ph, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	Jettison=4;
}

}

/// END OF CLBKPRESTEP /////////////////////////////////////////////////////////////////////////

int Nipon::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate) {
  if (!down) return 0; // only process keydown events

  if (KEYMOD_SHIFT (kstate)) {

  } else { // unmodified keys
    switch (key) {

		case OAPI_KEY_J:
			Jettison=3;
        return 1;
  
    }
  }
  return 0;
};
// ==============================================================
// API callback interface
// ==============================================================

// --------------------------------------------------------------
// Vessel initialisation
// --------------------------------------------------------------
DLLCLBK VESSEL *ovcInit (OBJHANDLE hvessel, int flightmodel)
{
	return new Nipon (hvessel, flightmodel);
}

// --------------------------------------------------------------
// Vessel cleanup
// --------------------------------------------------------------
DLLCLBK void ovcExit (VESSEL *vessel)
{
	if (vessel) delete (Nipon*)vessel;
}

I think the reason why this happens is because the jettison code might be for only one instance.
 

streb2001

Addon Developer
Addon Developer
Donator
Joined
Feb 9, 2008
Messages
326
Reaction score
0
Points
16
Location
North Yorkshire
Still not sure how Jettison variable works but maybe try this?

Change
Code:
if (Jettison==3 && GetPropellantMass(STG1_FUEL_ph) < 4)

to
Code:
if (Jettison==3 && (GetPropellantMass(STG1_FUEL_ph) < 4))
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
Hint :

Rocket is in launch configuration : JETTISON = 1

if (JETTISON == 1 & fuel < x)
then Stage 1 is jettisonned and JETTISON = 2
then redefine flight parameters for stage 2

if (JETTISON == 2 & fuel < x)
then Stage 2 is jettisonned and JETTISON = 3
then redefine flight parameters for stage 3

etc...
 

MJR

C++ developer in the mix
Addon Developer
Tutorial Publisher
Donator
Joined
Mar 19, 2008
Messages
2,460
Reaction score
5
Points
0
Location
United States
Thank you. I figured that might have been the case, but I didn't have the time to fix it. Ill let you know how it goes when I get home.

---------- Post added at 01:48 PM ---------- Previous post was at 12:32 PM ----------

So it should look like this, right?
Code:
void Nipon::clbkPreStep(double SimT, double SimDT, double MJD) {




/// STAGE 1 SEPARATION //////////////////////////////////////////////////////////////////////////

if (Jettison==1 && (GetPropellantMass(STG1_FUEL_ph)) < 2) {
	DelMesh(0);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("Stage1","-Stage1",_V(0,0,0));
	SetEmptyMass (STG1_EMPTYMASS);
	SetCameraOffset (_V(0,0,9));

	STG1_FUEL_ph = CreatePropellantResource (STG1_FUEL);
	SetDefaultPropellantResource(STG1_FUEL_ph);
	SetMaxFuelMass(550.0);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, STG1_FUEL_ph, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	Jettison=2;
}

/// STAGE 2 SEPARATION //////////////////////////////////////////////////////////////////////////

if (Jettison==2 && (GetPropellantMass(STG2_FUEL_ph)) < 3) {
	DelMesh(1);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("Stage2","-Stage2",_V(0,0,0));
	SetEmptyMass (STG2_EMPTYMASS);
	SetCameraOffset (_V(0,0,9));

	STG2_FUEL_ph = CreatePropellantResource (STG2_FUEL);
	SetDefaultPropellantResource(STG2_FUEL_ph);
	SetMaxFuelMass(550.0);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, STG2_FUEL_ph, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	Jettison=3;
}

/// STAGE 3 SEPARATION //////////////////////////////////////////////////////////////////////////

if (Jettison==3 && (GetPropellantMass(STG3_FUEL_ph)) < 4) {
	DelMesh(2);
	DelThrusterGroup (THGROUP_MAIN, true);
	SpawnObject("Stage3","-Stage3",_V(0,0,0));
	SetEmptyMass (STG3_EMPTYMASS);
	SetCameraOffset (_V(0,0,9));

	STG3_FUEL_ph = CreatePropellantResource (STG3_FUEL);
	SetDefaultPropellantResource(STG3_FUEL_ph);
	SetMaxFuelMass(550.0);
	th_main = CreateThruster (_V( 0,0,-0.5), _V(0,0,1), 100, STG3_FUEL_ph, 3000);
	CreateThrusterGroup (&th_main, 1, THGROUP_MAIN);
	AddExhaust (th_main, 0.75, 0.05, _V(0,0,-0.75), _V(0,0,-1));

	ShiftCG(_V(0,0,9));
	SetPMI (_V(3,3,1));
	ShiftMesh (4,_V(0,0,3.75));
	SetThrusterLevel(th_main, 1);
	Jettison=4;
}

}

/// END OF CLBKPRESTEP /////////////////////////////////////////////////////////////////////////

int Nipon::clbkConsumeBufferedKey(DWORD key, bool down, char *kstate) {
  if (!down) return 0; // only process keydown events

  if (KEYMOD_SHIFT (kstate)) {

  } else { // unmodified keys
    switch (key) {

		case OAPI_KEY_J:
			Jettison=1;
        return 1;
  
	}
  }
  return 0;
};

It just crashes everytime I jettison now.
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,271
Reaction score
3,244
Points
203
Location
Toulouse
Are you sure you have the config files and mesh files all set for stages 1, 2 & 3 ?

Also, in clbkConsumeBufferedKey, you should have

Code:
case OAPI_KEY_J:
			Jettison=Jettison+1;
 
Top