When a plane runs out of fuel whatever fire and smoke effects were being generated at that moment are retained. I would think that for fuel tanks, upon running dry the fire intensity should be expected to diminish.
And so I've added a new check for the fuel quantity; when reaching zero a boolean is set true. This is then used in the same manner as:
- Altitude is for activating/de-activating contrails.
- Airspeed is for changing to the ground fire/smoke effects when the speed drops below a threshold indicating the plane should be taxying or parked. (The stock scheme used speed only, but this meant ground effects would switch on when the plane stalled in a zoom climb--ugly! I've added a low altitude above ground threshold as well, which assures the ground effects will be used ONLY when the plane really is on the ground.)
Now upon a plane's fuel quantity going to zero, a heavy fire from a fuel tank will step down to a smaller fire.
Note that fuel consumption/loss is greatly increased when the damage is heavier, with the fuel running out faster. And so instances of a badly damaged plane that has no gas left yet have furious fires from the tank(s) would not be uncommon.
I'm contemplating adapting this to engine fires as well...
To give an indication of the degree of complexity I've given to Aircraft.doSetTankState, which results in a much greater variety of effects, below are the stock method and my modded method. Dare to compare!
Stock Aircraft.doSetTankState()
public boolean doSetTankState(Actor actor1, int i, int j)
{
boolean flag = aircraft.isChunkAnyDamageVisible(astateEffectChunks[i + 0]);
Aircraft.debugprintln(aircraft, "Stating Tank " + i + " to state " + j + (flag ? ".." : " rejected (missing part).."));
if(!flag)
return false;
if(World.getPlayerAircraft() == actor)
{
if(astateTankStates[i] == 0 && (j == 1 || j == 2))
HUD.log("FailedTank");
if(astateTankStates[i] < 5 && j >= 5)
HUD.log("FailedTankOnFire");
}
byte byte0 = astateTankStates[i];
astateTankStates[i] = (byte)j;
boolean flag1 = false;
boolean flag2 = false;
if(j == 5 && byte0 < 4)
flag1 = true;
if(j == 4 && byte0 == 4)
flag2 = true;
if(j == 4 && byte0 < 3)
{
flag2 = true;
flag1 = true;
}
if(astateTankStates[i] < 5 && j >= 5)
{
aircraft.FM.setTakenMortalDamage(true, actor1);
aircraft.FM.setCapableOfACM(false);
}
if(j < 4 && aircraft.FM.isCapableOfBMP())
aircraft.FM.setTakenMortalDamage(false, actor1);
byte byte1 = 0;
if(!bIsAboveCriticalSpeed)
byte1 = 21;
for(int k = 0; k < 3; k++)
{
if(astateTankEffects[i][k] != null)
Eff3DActor.finish(astateTankEffects[i][k]);
astateTankEffects[i][k] = null;
String s = astateTankStrings[byte1 + k + j * 3];
if(flag2 && s == null)
s = "3DO/Effects/Aircraft/FireSPDShort.eff";
if(s == null)
continue;
if(j > 2)
{
boolean flag3 = false;
Hook hook1 = actor.findHook("_Tank" + (i + 1) + "Burn");
String s1 = hook1.chunkName();
if(s1.toLowerCase().startsWith("wing"))
{
flag3 = true;
if(aircraft.hierMesh().isChunkVisible(s1) && j == 5)
flag1 = true;
}
if(s.equals("3DO/Effects/Aircraft/FireSPD.eff"))
{
if(flag3)
s = "3DO/Effects/Aircraft/FireSPDWing.eff";
} else
if(s.equals("3DO/Effects/Aircraft/FireSPDLong.eff"))
{
if(flag3)
s = "3DO/Effects/Aircraft/FireSPDWingLong.eff";
} else
if(s.equals("3DO/Effects/Aircraft/BlackHeavySPD.eff"))
{
if(flag1)
s = null;
else
if(flag3)
s = "3DO/Effects/Aircraft/BlackHeavySPDWing.eff";
} else
if(s.equals("3DO/Effects/Aircraft/BlackHeavyTSPD.eff") && flag1 && !flag2)
s = null;
if(s != null)
astateTankEffects[i][k] = Eff3DActor.New(actor, hook1, null, 1.0F, s, -1F);
} else
{
astateTankEffects[i][k] = Eff3DActor.New(actor, actor.findHook("_Tank" + (i + 1) + "Leak"), null, 1.0F, s, -1F);
}
if(j > 4)
{
Hook hook = actor.findHook("_Tank" + (i + 1) + "Burn");
Point3d point3d = aircraft.getTankBurnLightPoint(i, hook);
boolean flag4 = true;
for(int l = 0; l < astateTankBurnLights.length; l++)
{
if(astateTankBurnLights[l] == null)
continue;
Point3d point3d1 = astateTankBurnLights[l].relPos;
double d = point3d.distance(point3d1);
if(d >= 1.0D)
continue;
flag4 = false;
break;
}
if(flag4)
{
for(int i1 = 0; i1 < astateEngineBurnLights.length; i1++)
{
if(astateEngineBurnLights[i1] == null)
continue;
Point3d point3d2 = astateEngineBurnLights[i1].relPos;
double d1 = point3d.distance(point3d2);
if(d1 >= 1.0D)
continue;
flag4 = false;
break;
}
}
if(flag4)
{
astateTankBurnLights[i] = new LightPointActor(new LightPoint(), point3d);
astateTankBurnLights[i].light.setColor(1.0F, 0.9F, 0.5F);
astateTankBurnLights[i].light.setEmit(5F, 5F);
actor.draw.lightMap().put("_TankBurnLight" + i, astateTankBurnLights[i]);
}
continue;
}
if(astateTankBurnLights[i] != null)
{
actor.draw.lightMap().remove("_TankBurnLight" + i);
astateTankBurnLights[i].destroy();
astateTankBurnLights[i] = null;
}
}
aircraft.sfxSmokeState(2, i, j > 4);
return true;
}
My Aircraft.doSetTankState()
public boolean doSetTankState(Actor actor1, int i, int j) //i = tank#; j = eff state; (0 = null; 1,2 = leak; 3,4 = smoke; 5,6 = fire)
// astateTankStrings GUIDE
// =======================
// null, null, null,
// "3DO/Effects/Aircraft/RedLeakSmallTSPD.eff", null, null,
// "3DO/Effects/Aircraft/RedLeakTSPD.eff", null, null,
// "3DO/Effects/Aircraft/TankSmokeMediumSPD.eff", "3DO/Effects/Aircraft/TankSmokeMediumTSPD.eff", null,
// "3DO/Effects/Aircraft/TankSmokeHeavySPD.eff", "3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff", null,
// "3DO/Effects/Aircraft/FireSPD.eff", "3DO/Effects/Aircraft/TankSmokeHeavySPD.eff", "3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff",
// "3DO/Effects/Aircraft/FireSPDLong.eff", "3DO/Effects/Aircraft/TankSmokeHeavySPD.eff", "3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff",
// null, null, null,
// "3DO/Effects/Aircraft/RedLeakSmallGND.eff", null, null,
// "3DO/Effects/Aircraft/RedLeakGND.eff", null, null,
// "3DO/Effects/Aircraft/SmokeMediumGND.eff", null, null,
// "3DO/Effects/Aircraft/SmokeHeavyGND.eff", null, null,
// "3DO/Effects/Aircraft/FireGND.eff", "3DO/Effects/Aircraft/SmokeHeavyGND.eff", null,
// "3DO/Effects/Aircraft/FireHeavyGND.eff", "3DO/Effects/Aircraft/SmokeHeavyGND.eff", null
{
//Exception test=new Exception("doSetTankState method call!"); //add this wherever desired to trace a method call; disable when done testing! not working here...
//test.printStackTrace();
boolean flag = aircraft.isChunkAnyDamageVisible(astateEffectChunks[i + 0]);
Aircraft.debugprintln(aircraft, "Stating Tank " + i + " to state " + j + (flag ? ".." : " rejected (missing part).."));
if(!flag)
return false;
if(World.getPlayerAircraft() == actor)
{
if(astateTankStates[i] == 0 && j == 1)
HUD.log("FailedTank");
if((astateTankStates[i] == 0 || astateTankStates[i] == 1) && j == 2)
HUD.log("FailedTankHeavy");
if(!bNoFuel && (astateTankStates[i] == 2 || astateTankStates[i] == 1) && j == 0)
HUD.log("FailedTankRepaired");
if(astateTankStates[i] < 5 && j >= 5) //when fire first invoked
HUD.log("FailedTankOnFire");
}
byte byte0 = astateTankStates[i]; //takes OLD state
astateTankStates[i] = (byte)j; //makes NEW state to update to the current state
boolean flag1b = false; //incrementing upward to heavy smoke or to 1st fire or to 2nd fire, chance of fuel leak fireball
boolean flag2 = false; //2+ jumps to 2nd smoke; to invoke small (short) fire
boolean flag3 = false; //2+ jumps to 1st fire; to invoke thin smoke and chance of intermittent fire
boolean flag4 = false; //3+ jumps to 2nd fire; to invoke thin smoke and chance of intermittent fire
boolean flag5 = false; //hook is "wing" & chunk is visible; to assign wing variations of fire and smoke
if(byte0 < j && j >= 4) //step UP to heavy smoke or 1st or 2nd fire; chance of fuel leak fireball
flag1b = true;
if(byte0 < 3 && j == 4) //if OLD leak or no dmg & NEW 2nd smoke, i.e., eff state jumps 2 or more steps to 2nd smoke
flag2 = true;
if(byte0 < 4 && j == 5) //if OLD 1st smoke or leak & NEW 1st fire, i.e., eff state jumps 2 or more steps to 1st fire
flag3 = true;
if(byte0 < 4 && j == 6) //if OLD 1st smoke or leak & NEW 2nd fire, i.e., eff state jumps 3 or more steps to 2nd fire
flag4 = true;
if(j < 4 && aircraft.FM.isCapableOfBMP()) //if 1st smoke or less, do not set mortal damage
aircraft.FM.setTakenMortalDamage(false, actor1);
byte byte1 = 0; //in the air
if(!bIsAboveCriticalSpeed)
byte1 = 21; //on the ground
boolean bSmokeNull = false; //NEW; to properly match the new TSPD smoke null to the substituted SPD thin smoke
for(int k = 0; k < 3; k++) //check each effect slot--0, 1 and 2-- in the group of three related effects for a given state
{
if(astateTankEffects[i][k] != null)
Eff3DActor.finish(astateTankEffects[i][k]);
astateTankEffects[i][k] = null; //wipes effect name, ready afresh to read next assigned name
String s1 = astateTankStrings[byte1 + k + j * 3]; //NAME AS INITIALIZED! STRING COMPARE IS AGAINST THIS ONLY!
//-------------------------------------------------------- //for smaller fire effects when no fuel; put these checks at top, with all opther checks dependent on fuel in tanks being below
if(bNoFuel)
{
if(s1 == "3DO/Effects/Aircraft/FireSPD.eff") //normally assigned string in flight
s1 = "3DO/Effects/Aircraft/FireSPDShort.eff";
if(s1 == "3DO/Effects/Aircraft/FireSPDLong.eff") //normally assigned string in flight
s1 = "3DO/Effects/Aircraft/FireSPDShort.eff";
if(s1 == "3DO/Effects/Aircraft/FireGND.eff") //normally assigned string on ground
s1 = "3DO/Effects/Aircraft/FireLightGND.eff";
if(s1 == "3DO/Effects/Aircraft/FireHeavyGND.eff") //normally assigned string on ground
s1 = "3DO/Effects/Aircraft/FireLightGND.eff";
}
//-------------------------------------------------------- //A
if(!bNoFuel && flag2 && k == 2 && s1 == null) //if fuel in tanks and 2+ jumps to 2nd smoke (j = 4), where 3rd field (k = 2) is null, add a small fire not normally present with this state...
{
if(bIsAboveCriticalSpeed && TrueRandom.nextFloat() < 0.5F)
{
s1 = "3DO/Effects/Aircraft/FireSPDShort.eff";
flag_TankGNDfireSml = true;
}
if(!bIsAboveCriticalSpeed && flag_TankGNDfireSml) //if tank state changes while on ground
{
s1 = "3DO/Effects/Aircraft/FireLightGND.eff";
flag_TankGNDfireSml = false;
}
}
//--------------------------------------------------------
if(s1 == null)
continue;
if(j > 2) //if 1st smoke or worse
{
Hook hook1 = actor.findHook("_Tank" + (i + 1) + "Burn");
String s2 = hook1.chunkName();
if(s2.toLowerCase().startsWith("wing") && aircraft.hierMesh().isChunkVisible(s2)) //should the check for isChunkVisible be done for all like this??? It wasn't before, for fire...
flag5 = true; //if hook is "wing" and chunk visible
//-------------------------------------------------------- //3
if(flag2) //if 2+ jumps to 2nd smoke, j = 4, make lighter smoke 2/3 of time (has accompanying short fire too)
{
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavySPD.eff") && TrueRandom.nextFloat() < 0.67F) //for j = 4, k = 1
{
s1 = "3DO/Effects/Aircraft/TankSmokeMediumSPD.eff";
bSmokeNull = true;
flag_TankGNDsmokeSml = true;
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff") && bSmokeNull) //this will be true for j = 4, k = 2 when k = 1 was changed in the prior run through the loop
{
s1 = "3DO/Effects/Aircraft/TankSmokeMediumTSPD.eff";
bSmokeNull = false;
} else
if(s1.equals("3DO/Effects/Aircraft/SmokeHeavyGND.eff") && flag_TankGNDsmokeSml) //if tank state changes while on ground
{
s1 = "3DO/Effects/Aircraft/SmokeMediumGND.eff";
flag_TankGNDsmokeSml = false;
}
} else
//-------------------------------------------------------- //1
if(!flag3) //if NOT big jump to 1st fire
{
if(!bNoFuel && s1.equals("3DO/Effects/Aircraft/FireSPD.eff"))
{
if(flag5) //if hook is "wing"
{
if(TrueRandom.nextFloat() < 0.9F)
{
s1 = "3DO/Effects/Aircraft/FireSPDWing.eff"; //WING 'standard' fire...
}
else
{
s1 = "3DO/Effects/Aircraft/PulsingFireSPD.eff"; //... or chance WING animated fire
}
}
else //not "wing"
{
if(TrueRandom.nextFloat() < 0.8F)
{
s1 = "3DO/Effects/Aircraft/FireSPD.eff"; //FUSELAGE 'standard' fire...
}
else
{
s1 = "3DO/Effects/Aircraft/PulsingFireSPD.eff"; //... or chance FUSELAGE animated fire
}
}
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavySPD.eff") && TrueRandom.nextFloat() < 0.33F) //if NOT big jump to 1st fire; to accompany either FUSELAGE or WING fire //1a
{
s1 = "3DO/Effects/Aircraft/TankSmokeHeavyThinSPD.eff";
bSmokeNull = true;
flag_TankGNDsmokeSml = true;
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff") && bSmokeNull) //if NOT big jump to 1st fire; 1b
{
s1 = null;
bSmokeNull = false;
} else
if(s1.equals("3DO/Effects/Aircraft/SmokeHeavyGND.eff") && flag_TankGNDsmokeSml) //if NOT big jump to 1st fire; if tank state changes while on ground
{
s1 = "3DO/Effects/Aircraft/SmokeMediumGND.eff";
flag_TankGNDsmokeSml = false;
}
}
else
//-------------------------------------------------------- //2
if(!flag4) //if NOT big jump to 2nd fire
{
if(!bNoFuel && s1.equals("3DO/Effects/Aircraft/FireSPDLong.eff"))
{
if(flag5) //if hook is "wing"
{
s1 = "3DO/Effects/Aircraft/FireSPDWingLong.eff"; //WING 'standard' fire, no chance of animated fire
}
else //hook is NOT "wing"
{
if(TrueRandom.nextFloat() < 0.1F)
{
s1 = "3DO/Effects/Aircraft/PulsingFireSPD.eff"; //... or small chance of animated fire (normally more common for fuselage)
}
}
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavySPD.eff") && TrueRandom.nextFloat() < 0.2F) //if NOT big jump to 2nd fire; to accompany either FUSELAGE or WING fire //2a
{
s1 = "3DO/Effects/Aircraft/TankSmokeHeavyThinSPD.eff";
bSmokeNull = true;
flag_TankGNDsmokeSml = true;
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff") && bSmokeNull) //if NOT big jump to 2nd fire; 2b
{
s1 = null;
bSmokeNull = false;
} else
if(s1.equals("3DO/Effects/Aircraft/SmokeHeavyGND.eff") && flag_TankGNDsmokeSml) //if NOT big jump to 2nd fire; if tank state changes while on ground
{
s1 = "3DO/Effects/Aircraft/SmokeMediumGND.eff";
flag_TankGNDsmokeSml = false;
}
}
else
//-------------------------------------------------------- //4
if(flag3) //big leap to FIRST fire (j = 5), moderate chance of intermittent
{
if(!bNoFuel && s1.equals("3DO/Effects/Aircraft/FireSPD.eff"))
{
if(TrueRandom.nextFloat() < 0.5F)
{
s1 = "3DO/Effects/Aircraft/PulsingFireSPD.eff"; //chance FUSELAGE animated fire...
}
else
{
s1 = "3DO/Effects/Aircraft/FireSPD.eff"; //... or make FUSELAGE 'standard' fire
}
if(flag5) //if hook is "wing"
{
if(TrueRandom.nextFloat() < 0.75F)
{
s1 = "3DO/Effects/Aircraft/FireSPDWing.eff"; //WING 'standard' fire...
}
else
{
s1 = "3DO/Effects/Aircraft/PulsingFireSPD.eff"; //... or make WING animated fire
}
}
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavySPD.eff") && TrueRandom.nextFloat() < 0.75F) //4a
{
s1 = "3DO/Effects/Aircraft/TankSmokeHeavyThinSPD.eff";
bSmokeNull = true;
flag_TankGNDsmokeSml = true;
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff") && bSmokeNull) //4b
{
s1 = null;
bSmokeNull = false;
} else
if(s1.equals("3DO/Effects/Aircraft/SmokeHeavyGND.eff") && flag_TankGNDsmokeSml) //if tank state changes while on ground
{
s1 = "3DO/Effects/Aircraft/SmokeMediumGND.eff";
flag_TankGNDsmokeSml = false;
}
}
else
//-------------------------------------------------------- //5
if(flag4) //big leap to SECOND fire (j = 6), smaller chance of intermittent
{
if(!bNoFuel && s1.equals("3DO/Effects/Aircraft/FireSPDLong.eff"))
{
if(TrueRandom.nextFloat() < 0.3F)
{
s1 = "3DO/Effects/Aircraft/PulsingFireSPD.eff"; //chance FUSELAGE animated...
}
else
{
s1 = "3DO/Effects/Aircraft/FireSPD.eff"; //... or FUSELAGE 'standard' (not long) fire
}
if(flag5) //if hook is "wing"
{
if(TrueRandom.nextFloat() < 0.85F)
{
s1 = "3DO/Effects/Aircraft/FireSPDWingLong.eff"; //WING 'standard' fire...
}
else
{
s1 = "3DO/Effects/Aircraft/PulsingFireSPD.eff"; //...or make WING animated fire
}
}
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavySPD.eff") && TrueRandom.nextFloat() < 0.5F) //5a
{
s1 = "3DO/Effects/Aircraft/TankSmokeHeavyThinSPD.eff";
bSmokeNull = true;
flag_TankGNDsmokeSml = true;
} else
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff") && bSmokeNull) //5b
{
s1 = null;
bSmokeNull = false;
} else
if(s1.equals("3DO/Effects/Aircraft/SmokeHeavyGND.eff") && flag_TankGNDsmokeSml) //if tank state changes while on ground
{
s1 = "3DO/Effects/Aircraft/SmokeMediumGND.eff";
flag_TankGNDsmokeSml = false;
}
}
else
//-------------------------------------------------------- //6
if(flag5 && !flag2 && !flag3 && !flag4) //if "wing" and no large jump to HEAVY smoke or FIRST fire or SECOND fire
{
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavySPD.eff"))
s1 = "3DO/Effects/Aircraft/TankSmokeHeavySPDWing.eff";
if(s1.equals("3DO/Effects/Aircraft/TankSmokeHeavyTSPD.eff"))
s1 = "3DO/Effects/Aircraft/TankSmokeHeavyTSPDWing.eff";
}
//--------------------------------------------------------
if(s1 != null) //if an effect for a given state is assigned, generate the effect; hook1 is "_Tank Burn"
{
if(!bNoFuel && flag1b && k == 0) //to assign random fuel leak fireball when fuel on board, HVY smoke or fire starts (flag1b is j=4+), and for the first effect slot (0) only
{
if(j == 4 && TrueRandom.nextFloat() < 0.2F) //(flag1b is j=4+); if heavy smoke (tank not on fire), makes intermittent fuel leak fireball
{
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s3.eff", TrueRandom.nextFloat(2F, 4F));
} else
if(j >= 5 && TrueRandom.nextFloat() < 0.13F) //(flag1b is j=4+); if tank is on fire, can make this smaller fuel leak fireball...
{
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s2.eff", -1F);
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 1.0F, "3DO/Effects/Fireworks/Tank_SmokeBoiling_s2.eff", -1F);
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 0.7F, "3DO/Effects/Fireworks/Tank_Sparks_s.eff", -1F);
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 0.7F, "3DO/Effects/Fireworks/Tank_SparksP_s.eff", -1F);
} else
if(j >= 5 && TrueRandom.nextFloat() < 0.12F) //(flag1b is j=4+); ...or this larger fuel leak fireball
{
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s.eff", -1F);
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 1.0F, "3DO/Effects/Fireworks/Tank_SmokeBoiling_s.eff", -1F);
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 1.0F, "3DO/Effects/Fireworks/Tank_Sparks_s.eff", -1F);
astateTankEffects[i][0] = Eff3DActor.New(actor, hook1, null, 1.0F, "3DO/Effects/Fireworks/Tank_SparksP_s.eff", -1F);
}
}
astateTankEffects[i][k] = Eff3DActor.New(actor, hook1, null, 1.0F, s1, -1F); //draws all smoke or fire effects (not leak), singly in their turn, with each cycling of the for loop
}
} else //if j <= 2, 1st or 2nd leak
{
Hook hook2 = actor.findHook("_Tank" + (i + 1) + "Leak");
astateTankEffects[i][k] = Eff3DActor.New(actor, hook2, null, 1.0F, s1, -1F); //assign RedLeakTSPD/RedLeakGND;
//in the following, note the specifiying of k=2 (last effect 'slot')! ! ! This keeps an unwanted additional fuel leak effect from being created, which then NEVER changes nor disappears! ! !
if(!bNoFuel && byte0 == 0 && j == 2 && TrueRandom.nextInt(0, 5) == 0) //for jump from no damage to 2nd leak (j=2), as for lack of self-sealing capability
{
if(TrueRandom.nextFloat() < 0.33F) //makes pulsing, small fuel leak fireball, or...
{
if(!aircraft.FM.Gears.onGround())
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s3.eff", TrueRandom.nextFloat(2F, 4F)); //intermittent, separable fire bursts
else
if(aircraft.FM.Gears.onGround())
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "Effects/Explodes/Objects/StAir/BoilingFire.eff", -1F); //animated fireball from stationary aircraft, 10m, 2.5s
} else
if(TrueRandom.nextFloat() < 0.5F) //...smaller fuel leak fireball, or...
{
if(!aircraft.FM.Gears.onGround())
{
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s2.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_SmokeBoiling_s2.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 0.7F, "3DO/Effects/Fireworks/Tank_Sparks_s.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 0.7F, "3DO/Effects/Fireworks/Tank_SparksP_s.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Aircraft/IntFuelLeakFirePulses.eff", TrueRandom.nextFloat(3F, 6F));
} else
if(aircraft.FM.Gears.onGround())
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "Effects/Explodes/Objects/StAir/BoilingFire.eff", -1F); //animated fireball from stationary aircraft, 10m, 2.5s
} else //...larger fuel leak fireball
{
if(!aircraft.FM.Gears.onGround())
{
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_SmokeBoiling_s.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_Sparks_s.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_SparksP_s.eff", -1F);
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Aircraft/IntFuelLeakFire.eff", TrueRandom.nextFloat(4F, 8F));
} else
if(aircraft.FM.Gears.onGround())
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "Effects/Explodes/Objects/StAir/BoilingFire.eff", -1F); //animated fireball from stationary aircraft, 10m, 2.5s
}
}
if(!bNoFuel && byte0 == 0 && j == 1 && !(aircraft.FM.Gears.onGround()) && TrueRandom.nextInt(0, 10) == 0) //for 1st leak state, usually for self-sealing type
{
if(TrueRandom.nextFloat() < 0.5F)
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s3.eff", TrueRandom.nextFloat(1.5F, 3F)); //intermittent, separable fire bursts
else
if(TrueRandom.nextFloat() < 0.33F)
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Aircraft/IntFuelLeakFirePulses.eff", TrueRandom.nextFloat(2F, 5F));
else
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Aircraft/IntFuelLeakFire.eff", TrueRandom.nextFloat(3F, 6F));
}
if(!bNoFuel && byte0 == 1 && j == 2 && !(aircraft.FM.Gears.onGround()) && TrueRandom.nextInt(0, 5) == 0) //for step up from 1st to 2nd leak state, which applies at least mostly for self-sealing type
{
if(TrueRandom.nextFloat() < 0.33F)
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Fireworks/Tank_Burn_s3.eff", TrueRandom.nextFloat(2.5F, 4F)); //intermittent, separable fire bursts
else
if(TrueRandom.nextFloat() < 0.5F)
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Aircraft/IntFuelLeakFirePulses.eff", TrueRandom.nextFloat(3F, 6F));
else
astateTankEffects[i][2] = Eff3DActor.New(actor, hook2, null, 1.0F, "3DO/Effects/Aircraft/IntFuelLeakFire.eff", TrueRandom.nextFloat(4F, 8F));
}
}
if(j > 4) // 5 and 6 are fire, create burn light light illumination
{
Hook hook3 = actor.findHook("_Tank" + (i + 1) + "Burn");
Point3d point3d = aircraft.getTankBurnLightPoint(i, hook3);
boolean flag6 = true;
for(int l = 0; l < astateTankBurnLights.length; l++)
{
if(astateTankBurnLights[l] == null)
continue;
Point3d point3d1 = astateTankBurnLights[l].relPos;
double d = point3d.distance(point3d1);
if(d >= 1.0D)
continue;
flag6 = false;
break;
}
if(flag6)
{
for(int i1 = 0; i1 < astateEngineBurnLights.length; i1++)
{
if(astateEngineBurnLights[i1] == null)
continue;
Point3d point3d2 = astateEngineBurnLights[i1].relPos;
double d1 = point3d.distance(point3d2);
if(d1 >= 1.0D)
continue;
flag6 = false;
break;
}
}
if(flag6)
{
astateTankBurnLights[i] = new LightPointActor(new LightPoint(), point3d);
astateTankBurnLights[i].light.setColor(1.0F, 0.3F, 0.0F);
astateTankBurnLights[i].light.setEmit(1.0F, 10F);
actor.draw.lightMap().put("_TankBurnLight" + i, astateTankBurnLights[i]);
}
continue;
}
if(astateTankBurnLights[i] != null)
{
actor.draw.lightMap().remove("_TankBurnLight" + i);
astateTankBurnLights[i].destroy();
astateTankBurnLights[i] = null;
}
}
aircraft.sfxSmokeState(2, i, j > 4);
return true;
}