Here's an example of the resulting progress as I fly from the general weather type 1 (good) to type 5 (rain). Each change occurs at radial distances of 40, 30, 20 and 10km for weather types 2, 3, 4 and 5, respectively. The variables presented by the invoked method HUD.training() I use when testing:
- dist = distance from the StormFront object, in meters.
- clouds = the CloudType entry in the .mis file.
- front = the new weather type.
- height = the cloud base altitude ASL.
- turb = turbulence, on a scale of 0 to 12.
- gust = gusts, on a scale of 0 to 6.
The 1st screenie is well enough outside the radius of 40km for invocation of the next weather type, that being 2 (hazy). The following grabs were taken fairly soon after the weather had changed. Because of the 30-second timer setting (much better than the former 300-second value), there is a delay before the execution of the change. The plane is moving along at something in the range of 1km every 10 seconds or so. Perhaps I should reduce the timer value even further? Which would be better if one set an even smaller stormDistanceInterval than the 10km I used here. Of course, something of a delay is good for this reason: If one is maneuvering about, crossing a particular distance threshold back and forth, a too-small delay would have the weather changing back and forth at an annoying pace.
And so the hysteresis imposed by a delay is a good thing.
Compared to the initial cloud height of 900m, in the rain it has lowered to roughly half.
The turbulence and gust behaviour works really well with my improved Wind.class, as it doesn't get ridiciulous.
[click for larger]
Here's my code as of now:
package com.maddox.il2.objects.vehicles.stationary;
import com.maddox.JGP.Point3d;
import com.maddox.il2.ai.World;
import com.maddox.il2.engine.*;
import com.maddox.il2.game.HUD; //when using HUD.training output
import com.maddox.il2.game.Mission;
import com.maddox.rts.SectFile;
import com.maddox.rts.Time;
// Referenced classes of package com.maddox.il2.objects.vehicles.stationary:
// CandCGeneric, CandC
//public static class CandC$StormFrontUnit extends CandCGeneric //static not allowed by my compiler
public class CandC$StormFrontUnit extends CandCGeneric
{
public boolean danger()
{
if(Time.current() < (long)(Mission.cur().sectFile().get("Mods", "StormFrontDelay", 0) * 60))
return false;
super.pos.getAbs(point3d);
com.maddox.il2.objects.air.Aircraft aircraft = World.getPlayerAircraft();
clouds = Mission.cur().sectFile().get("Main", "CloudType", 2); //NEW
height = Mission.cur().sectFile().get("Main", "CloudHeight", 1500F); //NEW
int worstClouds = Mission.cur().sectFile().get("Mods", "WorstClouds", 6);
if(worstClouds < clouds)
worstClouds = clouds + 1;
if(worstClouds > 6)
worstClouds = 6;
float stormDistanceInterval = Mission.cur().sectFile().get("Mods", "StormDistanceInterval", 50); //NEW; 50km if not specified in .mis file
if(stormDistanceInterval < 5F)
stormDistanceInterval = 5F;
if(stormDistanceInterval > 100F)
stormDistanceInterval = 100F;
double distanceFront = ((Actor) (aircraft)).pos.getAbsPoint().distance(point3d);
if(distanceFront > 0.0D)
{
if(distanceFront > 6000D * (double) stormDistanceInterval)
{
front = worstClouds - 6;
if(front < clouds)
front = clouds;
}
else
if(distanceFront > 5000D * (double) stormDistanceInterval && distanceFront <= 6000D * (double) stormDistanceInterval)
{
front = worstClouds - 5;
if(front < clouds)
front = clouds;
}
else
if(distanceFront > 4000D * (double) stormDistanceInterval && distanceFront <= 5000D * (double) stormDistanceInterval)
{
front = worstClouds - 4;
if(front < clouds)
front = clouds;
}
else
if(distanceFront > 3000D * (double) stormDistanceInterval && distanceFront <= 4000D * (double) stormDistanceInterval)
{
front = worstClouds - 3;
if(front < clouds)
front = clouds;
}
else
if(distanceFront > 2000D * (double) stormDistanceInterval && distanceFront <= 3000D * (double) stormDistanceInterval)
{
front = worstClouds - 2;
if(front < clouds)
front = clouds;
}
else
if(distanceFront > 1000D * (double) stormDistanceInterval && distanceFront <= 2000D * (double) stormDistanceInterval)
{
front = worstClouds - 1;
if(front < clouds)
front = clouds;
}
else
if(distanceFront <= 1000D * (double) stormDistanceInterval) //NEW
{
front = worstClouds; //if <= 1 * stormDistanceInterval
if(front < clouds) //superfluous?
front = clouds;
}
}
// ======================================================================================================================== //experiment for updating turbulence and gusts
direction = Mission.cur().sectFile().get("WEATHER", "WindDirection", direction, 0.0F, 359.99F);
speed = 0.25F + (float)(clouds * clouds) * 0.12F;
speed = Mission.cur().sectFile().get("WEATHER", "WindSpeed", speed, 0.0F, 15F);
gust = clouds > 3 ? (float)clouds * 2.0F : 0.0F;
gust = Mission.cur().sectFile().get("WEATHER", "Gust", gust, 0.0F, 12F); //0, 8, 10, 12
if(front - clouds > 0)
{
gust += (float) (front - clouds) * 1.5F;
if(gust > 12F)
gust = 12F;
}
turb = clouds > 2 ? clouds : 0.0F;
turb = Mission.cur().sectFile().get("WEATHER", "Turbulence", turb, 0.0F, 6F); //0, 3, 4, 5, 6
if(front - clouds > 0)
{
turb += (float) (front - clouds) / 2F;
if(turb > 6F)
turb = 6F;
}
World.wind().set(height, direction, speed, gust, turb);
// ========================================================================================================================
if(front != lastfront)
{
// Mission.createClouds(front, 1000F); //original
Mission.createClouds(front, height * (float) Math.pow(0.85F, (float) (front - clouds)));
World.land().cubeFullUpdate();
HUD.training("dist: " + distanceFront + " clouds: " + clouds + " front:" + front + " height:" + height * (float) Math.pow(0.85F, (float) (front - clouds)) + " turb:" + turb + " gust:" + gust);
}
lastfront = front;
return true;
}
private Point3d point3d;
private int front;
private int lastfront;
private int clouds; //NEW
private float height; //NEW
private int worstClouds; //NEW
private float stormDistanceInterval; //NEW
private float direction; //NEW
private float speed; //NEW
private float gust; //NEW
private float turb; //NEW
public CandC$StormFrontUnit()
{
point3d = new Point3d();
front = -1; //was 1
lastfront = -1; //was 1
// clouds = 2; //NEW
// height = 1500; //NEW
// stormDistanceInterval = 50F; //NEW
// super.Timer1 = super.Timer2 = 300F; //original; 5 min
super.Timer1 = super.Timer2 = 30F; //30 sec
}
}