Aircraft.msgCollision() controls what happens when a plane contacts objects and suffers damage. For wreckage { if(actor instanceof Wreckage) } it looks like that stuff is simply ignored. Could be a potentially fruitful area to add more things to worry about.
A check could be done based on the wreckage chunk size, a threshold below which is ignored. Meaning only the bigger bits can cause damage. And of course a user control could be supplied (if not a difficulty option for a more sophisticated approach, eventually?) to enable/disable this.
public void msgCollision(Actor actor, String s, String s1) //called by AircraftState.update(), for small chance of exploding engine instead being total destruction
{
if(isNet() && isNetMirror())
return;
if(actor instanceof ActorCrater)
{
if(!s.startsWith("Gear"))
return;
if(netUser() != null && netUser() == ((ActorCrater)actor).netOwner)
return;
}
if(this == World.getPlayerAircraft())
TimeSkip.airAction(1);
FM.dryFriction = 1.0F;
if(s.startsWith("Pilot"))
if(this == World.getPlayerAircraft() && !World.cur().diffCur.Vulnerability)
{
return;
} else
{
int i = s.charAt(5) - 49;
killPilot(this, i);
return;
}
if(s.startsWith("Head"))
if(this == World.getPlayerAircraft() && !World.cur().diffCur.Vulnerability)
{
return;
} else
{
int j = s.charAt(4) - 49;
killPilot(this, j);
return;
}
if(actor instanceof Wreckage)
{
if(s.startsWith("CF_"))
return;
if(actor.getOwner() == this)
return;
if(netUser() != null && netUser() == ((Wreckage)actor).netOwner)
{
return;
} else
{
actor.collide(false);
nextDMGLevels(3, 0, s, this);
return;
}
}
if(actor instanceof Paratrooper)
{
FM.getSpeed(v1);
actor.getSpeed(Vd);
Vd.x -= v1.x;
Vd.y -= v1.y;
Vd.z -= v1.z;
if(Vd.length() > 30D)
{
setDamager(actor, 4);
nextDMGLevels(4, 0, s, actor);
}
return;
}
if((actor instanceof RocketryRocket) && s1.startsWith("Wing"))
{
RocketryRocket rocketryrocket = (RocketryRocket)actor;
Loc loc = new Loc();
Point3d point3d = new Point3d();
Vector3d vector3d = new Vector3d();
Vector3d vector3d1 = new Vector3d();
pos.getAbs(loc);
point3d.set(actor.pos.getAbsPoint());
loc.transformInv(point3d);
boolean flag = point3d.y > 0.0D;
vector3d.set(0.0D, flag ? hierMesh().collisionR() : -hierMesh().collisionR(), 0.0D);
loc.transform(vector3d);
point3d.set(FM.Loc);
point3d.add(vector3d);
actor.pos.getAbs(loc);
loc.transformInv(point3d);
vector3d.set(FM.Vwld);
actor.pos.speed(vector3d1);
vector3d.sub(vector3d1);
loc.transformInv(vector3d);
vector3d.z += (flag ? 1.0D : -1D) * FM.getW().x * (double)hierMesh().collisionR();
if(vector3d.x * vector3d.x + vector3d.y * vector3d.y < 4D)
{
if(point3d.y * vector3d.z > 0.0D)
rocketryrocket.sendRocketStateChange('a', this);
else
rocketryrocket.sendRocketStateChange('b', this);
return;
}
rocketryrocket.sendRocketStateChange(flag ? 'l' : 'r', this);
}
if(FM.turnOffCollisions && (s.startsWith("Wing") || s.startsWith("Arone") || s.startsWith("Keel") || s.startsWith("Rudder") || s.startsWith("Stab") || s.startsWith("Vator") || s.startsWith("Nose") || s.startsWith("Tail")))
return;
if((actor instanceof Aircraft) && Actor.isValid(actor) && getArmy() == actor.getArmy())
{
double d = Engine.cur.land.HQ(FM.Loc.x, FM.Loc.y);
Aircraft aircraft = (Aircraft)actor;
if(FM.Loc.z - (double)(2.0F * FM.Gears.H) < d && aircraft.FM.Loc.z - (double)(2.0F * aircraft.FM.Gears.H) < d)
setDamagerExclude(actor);
}
if(s != null && hierMesh().chunkFindCheck(s) != -1)
{
hierMesh().setCurChunk(s);
hierMesh().getChunkLocObj(tmpLoc1);
Vd.set(FM.Vwld);
FM.Or.transformInv(Vd);
Vd.normalize();
Vd.negate();
Vd.scale(2000F / FM.M.mass);
Vd.cross(tmpLoc1.getPoint(), Vd);
FM.getW().x += (float)Vd.x;
FM.getW().y += (float)Vd.y;
FM.getW().z += (float)Vd.z;
}
setDamager(actor, 4);
nextDMGLevels(4, 0, s, actor);
}