Page 1 of 2
Missile intercept code
Posted: Thu Dec 27, 2007 11:10 pm
by Cmdr James
Guys, I have made a small modification to the code used for the missile interception logic. It is now, normally much more likely to strike a target, as it will predict the target location based upon its current velocity. I guess it might be better to add some damping due to the imperfect ability to read a target velocity?
Anyway the code is here if anyone wants to comment.
Code: Select all
- (double) missileTrackPrimaryTarget:(double) delta_t
{
Vector relPos;
GLfloat d_forward, d_up, d_right, range2;
Entity *target = [self primaryTarget];
if (!target) // leave now!
return 0.0;
Vector leading = [target velocity];
double damping = 0.5 * delta_t;
double rate2 = 4.0 * delta_t;
double rate1 = 2.0 * delta_t;
double stick_roll = 0.0; //desired roll and pitch
double stick_pitch = 0.0;
relPos = vector_subtract(target->position, position);
//how long till I get there
float lead = sqrt(magnitude2(relPos)) / [self speed];
//adjust where we are going to take into account his velocity
relPos.x += (lead * leading.x);
relPos.y += (lead * leading.y);
relPos.z += (lead * leading.z);
range2 = magnitude2(relPos);
if (!vector_equal(relPos, kZeroVector)) relPos = vector_normal(relPos);
else relPos.z = 1.0;
d_right = dot_product(relPos, v_right); // = cosine of angle between angle to target and v_right
d_up = dot_product(relPos, v_up); // = cosine of angle between angle to target and v_up
d_forward = dot_product(relPos, v_forward); // = cosine of angle between angle to target and v_forward
// begin rule-of-thumb manoeuvres
stick_roll = 0.0;
if (pitching_over)
pitching_over = (stick_pitch != 0.0);
if ((d_forward < -pitch_tolerance) && (!pitching_over))
{
pitching_over = YES;
if (d_up >= 0)
stick_pitch = -max_flight_pitch;
if (d_up < 0)
stick_pitch = max_flight_pitch;
}
if (pitching_over)
{
pitching_over = (d_forward < 0.5);
}
else
{
stick_pitch = -max_flight_pitch * d_up;
stick_roll = -max_flight_roll * d_right;
}
// end rule-of-thumb manoeuvres
// apply damping
if (flightRoll < 0)
flightRoll += (flightRoll < -damping) ? damping : -flightRoll;
if (flightRoll > 0)
flightRoll -= (flightRoll > damping) ? damping : flightRoll;
if (flightPitch < 0)
flightPitch += (flightPitch < -damping) ? damping : -flightPitch;
if (flightPitch > 0)
flightPitch -= (flightPitch > damping) ? damping : flightPitch;
// apply stick movement limits
if (flightRoll + rate1 < stick_roll)
stick_roll = flightRoll + rate1;
if (flightRoll - rate1 > stick_roll)
stick_roll = flightRoll - rate1;
if (flightPitch + rate2 < stick_pitch)
stick_pitch = flightPitch + rate2;
if (flightPitch - rate2 > stick_pitch)
stick_pitch = flightPitch - rate2;
// apply stick to attitude
flightRoll = stick_roll;
flightPitch = stick_pitch;
//
// return target confidence 0.0 .. 1.0
//
if (d_forward < 0.0)
return 0.0;
return d_forward;
}
Posted: Fri Dec 28, 2007 1:03 am
by TGHC
That looks like a nifty bit of work, I'd better go service and polish my ECM
Posted: Fri Dec 28, 2007 1:15 am
by Cmdr James
I only added about 4 lines, I cant take credit for most of this
Posted: Fri Dec 28, 2007 9:24 am
by another_commander
Does the added missile code affect game balance? Make sure that you have not created some kind of unbeatable superweapon. I will give it a test at first opportunity, probably during the weekend.
Posted: Fri Dec 28, 2007 9:34 am
by Cmdr James
I have never seen evading missiles by cool flying as really viable. Except for photon torpedos which I often seem to end up having circle me as they cannot hit. You can of course inject fuel to get away, and this is uneffected.
This does not improve speed, or effect ecm interaction so I dont think there should be much effect on balance.
The main thing which concerns me is that for very fast moving targets (especially faster than the missile) you can get a weird looking missile flight path as it tries to converge.
This code is currently only on this forum (and my machine), I have not put it into trunk, (I do not have privileges to do that) and I am not sure it should go in.
Posted: Fri Dec 28, 2007 3:50 pm
by JensAyton
This is something I’ve wanted to do for a while. I’ll definitely check it out… at some point. :-)
Evading missiles is definitely viable in the current game, but rather a bother. Injectors are a better option.
Posted: Sat Dec 29, 2007 11:02 am
by another_commander
I tried the modification and I must say I like it very much. Missiles definitely fly more aggressively now and I like how it looks like they are thrown off-course during the first moments of flight and then just start hunting down the target mercilessly. My one and only concern is that, with this modification, any player without ECM or injectors who has such a missile launched against him, is definitely toast.
But there is a bug in the code in its current form. When I tested it, I noticed that I was getting very frequent freezes whenever there were missiles in the air. Entering some alert debug messages that were printed whenever the missile speed dropped below a value of 2.5 revealed this at the moment of crash (last three lines of stderr.txt):
Code: Select all
2007-12-28 18:39:36.141 oolite.exe[6788] [jstest.witchSpace.begin]: Player is entering witchspace. Cause: standard jump
2007-12-28 18:39:38.565 oolite.exe[6788] [jstest.witchSpace.arrive]: Player is exiting witchspace.
2007-12-28 18:39:38.685 oolite.exe[6788] [script.javaScript.context.create]: Creating JS context.
2007-12-28 18:39:41.268 oolite.exe[6788] [jstest.witchSpace.complete]: Player exited witchspace into galaxy 6, planet 160 ("Xeleza"), govt = 2 (Multi-Government), economy = 7 (Poor Agricultural), tech level = 4
2007-12-28 18:39:41.349 oolite.exe[6788] [jstest.alert]: Player alert condition changed to green (clear)
2007-12-28 18:39:51.283 oolite.exe[6788] [jstest.alert]: Player alert condition changed to yellow (mass locked)
2007-12-28 18:40:02.529 oolite.exe[6788] [jstest.alert]: Player alert condition changed to red (mass locked)
2007-12-28 18:40:27.655 oolite.exe[6788] [unclassified.ShipEntity]: [self speed] = 2.499960, 1 / [self speed] = 0.400006
2007-12-28 18:40:27.675 oolite.exe[6788] [unclassified.ShipEntity]: [self speed] = 0.000000, 1 / [self speed] = 1.#INF00
2007-12-28 18:40:27.685 oolite.exe[6788] [unclassified.ShipEntity]: [self speed] = 0.000000, 1 / [self speed] = 1.#INF00
Missile speed can and does become zero sometimes. This leads to a division by zero error on the line that reads
Code: Select all
float lead = sqrt(magnitude2(relPos)) / [self speed];
One solution for this would be to introduce a low enough threshold (I believe 0.01 does the job fine), below which there will be no attempt to adjust course for the target's velocity. Readjustment will take place only when speed goes above 0.01 again. So, I would modify a bit the code to something like this:
Code: Select all
//how long till I get there
float missileSpeed = (float)[self speed];
if (missileSpeed > 0.01) // Avoid getting ourselves in a divide by zero situation.
{
Vector leading = [target velocity];
float lead = magnitude(relPos) / missileSpeed;
//adjust where we are going to take into account his velocity
relPos.x += (lead * leading.x);
relPos.y += (lead * leading.y);
relPos.z += (lead * leading.z);
}
I would also think it could be a good idea to have something like an aggressiveness random factor ranging from 0.0 to 1.0, that can be used to multiply the (lead * leading.[xyz]) value. This way we could incorporate this behavior to the game, at the same time giving a chance to new players to survive missile attacks. In the best case scenario the missile would behave like it does now (agressiveness = 0.0) and in the worst case scenario it would behave like Cmdr James' missiles (aggressiveness = 1.0). In most cases, it would just behave somewhat better than it currently does.
Posted: Sat Dec 29, 2007 11:03 am
by Cmdr James
This all makes sense to me.
I would personally like to see missiles less manouverable, and shorter max range, making them more like a missile and less like a suicide pilot in a fast ship. But I think this is moving too far from the tradition of elite. In the original (Amstrad CPC disk version at least) elite, as far as I remember missiles were rubbish and flew around almost forever rarely hitting anything.
Posted: Sat Dec 29, 2007 11:35 am
by Cmdr James
I also think missiles should not stop if the target disappears, either :
a) explode
b) continue in the direction they were going
My old commander (Giles bless his soul) got quite a few kills shooting dead torpedos that were just hanging around in space. It always seemed a bit cheap that I get one kill for hours of cat and mouse with a rattlecutter and the same for a dead missile floating about. Now a live missile is a different matter
Posted: Sat Dec 29, 2007 2:51 pm
by jonnycuba
would this work as a missile upgrade oxp? i.e you purchase a missile with this improved tech (like hard hats). So only a commander skilled enough would want to install it?
Posted: Sat Dec 29, 2007 3:32 pm
by Cmdr. Maegil
Since we've been on a randomizing mood...
...I'd like the "Faulcon de Lacy HM3" as the average missile , unmodified , with its agressiveness representing 0.5 and available at most systems, but have other options of HMs according to the system's tech level. (on HMs, I mean - there is the more exotical equipment from Ramirez'
Missiles & Bombs OXP).
E.g.: a "Taranis EX5 MRSSM" missile with a state-of-the-art guidance system and high explosive yield would be available on the highest tech level systems, or crazy stuff such as a Benulobiweed Tailchaser 2.5 Guided Missile" with a maximum speed of 2.5LM and high agressiveness but a pitch of only 1.5; the midranges should be variations on the basic HM3; and in crummy anarchies it shouldn't be possible to find but worthless crap (except, perhaps, on some seedy black markets - but then again, you should be able to find anything there).
Anyone up to it?
Posted: Sat Dec 29, 2007 5:16 pm
by Eric Walch
Another_Commander wrote:I would also think it could be a good idea to have something like an aggressiveness random factor ranging from 0.0 to 1.0, that can be used to multiply the (lead * leading.[xyz]) value. This way we could incorporate this behavior to the game, at the same time giving a chance to new players to survive missile attacks.
I agree there should be a random factor to give the player a change with some of the missiles. But why not use the existing key: accuracy.
At the moment it must have a value between -5 and 10. (when not it is selecting its own randomised value.
This "accuracy" is used to change "pitch_tolerance". But you could also use the same "accuracy" entry to randomise an other parameter. (better than having two entries for something similar.
Posted: Sat Dec 29, 2007 10:57 pm
by JensAyton
Cmdr James wrote:I also think missiles should not stop if the target disappears, either :
a) explode
b) continue in the direction they were going
...
It always seemed a bit cheap that I get one kill for hours of cat and mouse with a rattlecutter and the same for a dead missile floating about. Now a live missile is a different matter ;)
The built-in missiles do explode when they lose their target. This behaviour is defined by the AI, so third parties can do what they wish.
Posted: Mon Dec 31, 2007 7:21 am
by another_commander
Eric Walch wrote: I agree there should be a random factor to give the player a change with some of the missiles. But why not use the existing key: accuracy.
At the moment it must have a value between -5 and 10. (when not it is selecting its own randomised value.
This "accuracy" is used to change "pitch_tolerance". But you could also use the same "accuracy" entry to randomise an other parameter. (better than having two entries for something similar.
Yes, it looks like using accuracy is the way to go. I had initially thought about using it, then discarded the thought when I saw that it was used to calculate pitch_tolerance. What I did not realize at the time, was that, in the case of a missile, once it is used to calculate pitch tolerance, it doesn't get used again for anything, so it is essentially a variable hanging free. Plus accuracy is probably a better name than aggressiveness for what we are trying to describe.
Posted: Mon Dec 31, 2007 6:35 pm
by Cmdr. Maegil
Well, let' have an OXP, then!
Can someone test this? Due to power supply problems, I can't run Oolite (nor any heavyish applications) on the laptop...
shipdata.plist
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Home made Missile</key>
<dict>
<key>like_ship</key>
<string>missile</string>
<key>ai_type</key>
<string>missileAI.plist</string>
<key>max_flight_pitch</key>
<real>6</real>
<key>max_flight_roll</key>
<real>6</real>
<key>max_flight_speed</key>
<real>700</real>
<key>accuracy</key>
<integer>0</integer>
<key>name</key>
<string>Crude missile</string>
<key>roles</key>
<string>missile EQ_HOMEMADE_MISSILE</string>
<key>thrust</key>
<real>200</real>
<key>weapon_energy</key>
<real>3500</real>
</dict>
<key>FdL HM3</key>
<dict>
<key>like_ship</key>
<string>missile</string>
<key>accuracy</key>
<integer>5</integer>
<key>name</key>
<string>HM3 missile</string>
</dict>
<key>Vega Tracker RHM</key>
<dict>
<key>like_ship</key>
<string>missile</string>
<key>ai_type</key>
<string>missileAI.plist</string>
<key>max_flight_pitch</key>
<real>6</real>
<key>max_flight_speed</key>
<real>850</real>
<key>accuracy</key>
<integer>7</integer>
<key>name</key>
<string>Tracker missile</string>
<key>roles</key>
<string>missile EQ_TRACKER_MISSILE</string>
<key>scanClass</key>
<string>CLASS_MISSILE</string>
<key>thrust</key>
<real>300</real>
<key>weapon_energy</key>
<real>5500</real>
</dict>
<key>Vega Bloodhound XHM</key>
<dict>
<key>like_ship</key>
<string>ecm-proof-missile</string>
<key>ai_type</key>
<string>hardMissileAI.plist</string>
<key>max_flight_pitch</key>
<real>6</real>
<key>accuracy</key>
<integer>4</integer>
<key>name</key>
<string>Bloodhound hardened missile</string>
<key>roles</key>
<string>missile EQ_BLOODHOUND_MISSILE</string>
</dict>
<key>FdL HMX5</key>
<dict>
<key>like_ship</key>
<string>ecm-proof-missile</string>
<key>accuracy</key>
<integer>6</integer>
<key>name</key>
<string>FdL HMX5 hardened missile</string>
</dict>
<key>Benulobiweed Tailchaser Hardhat</key>
<dict>
<key>like_ship</key>
<string>ecm-proof-missile</string>
<key>ai_type</key>
<string>hardMissileAI.plist</string>
<key>max_energy</key>
<real>5</real>
<key>max_flight_pitch</key>
<real>3</real>
<key>max_flight_roll</key>
<real>6</real>
<key>max_flight_speed</key>
<real>1500</real>
<key>accuracy</key>
<integer>5</integer>
<key>name</key>
<string>Tailchaser hardened missile</string>
<key>roles</key>
<string>missile EQ_TAILCHASER_MISSILE</string>
<key>scanClass</key>
<string>CLASS_MISSILE</string>
<key>thrust</key>
<real>500</real>
<key>weapon_energy</key>
<real>4000</real>
</dict>
<key>Taranis ECMR2 MRHSSM</key>
<dict>
<key>like_ship</key>
<string>ecm-proof-missile</string>
<key>ai_type</key>
<string>hardMissileAI.plist</string>
<key>max_flight_pitch</key>
<real>10</real>
<key>max_flight_roll</key>
<real>12</real>
<key>accuracy</key>
<integer>8</integer>
<key>name</key>
<string>ECMR2 hardened missile</string>
<key>roles</key>
<string>missile EQ_ECMR2_MISSILE</string>
</dict>
</dict>
</plist>
equipment.plist
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<array>
<integer>0</integer>
<integer>100</integer>
<string>Home made Missile</string>
<string>EQ_HOMEMADE_MISSILE</string>
<string>Made in some backyard sweatshop, this crude but effective homing missile has the most basic guidance system.</string>
<dict>
<key>available_to_all</key>
<true/>
</dict>
</array>
<array>
<integer>2</integer>
<integer>300</integer>
<string>FdL HM3</string>
<string>EQ_MISSILE</string>
<string>Faulcon de Lacy HM3 homing missile, fast and accurate when used in conjunction with standard targetting scanners.</string>
<dict>
<key>available_to_all</key>
<true/>
</dict>
</array>
<array>
<integer>4</integer>
<integer>500</integer>
<string>Vega Tracker RHM</string>
<string>EQ_TRACKER_MISSILE</string>
<string>Vega Corp's homing missile, fast and powerful. Targetting scanners recommended.</string>
<dict>
<key>available_to_all</key>
<true/>
</dict>
</array>
<array><!-- ecm hardened missile -->
<integer>8</integer>
<integer>3000</integer>
<string>Vega Bloodhound XHM</string>
<string>EQ_BLOODHOUND_MISSILE</string>
<string>Vega Corp's ECM-hardened missile. Targetting scanners recommended.</string>
<dict>
<key>available_to_all</key>
<true/>
</dict>
</array>
<array><!-- ecm hardened missile -->
<integer>9</integer>
<integer>3500</integer>
<string>FdL HMX5</string>
<string>EQ_HARDENED_MISSILE</string>
<string>Faulcon de Lacy HMX5 homing missile - hardened against ECM.</string>
<dict>
<key>available_to_all</key>
<true/>
</dict>
</array>
<array><!-- ecm hardened missile -->
<integer>11</integer>
<integer>5000</integer>
<string>Benulobiweed Tailchaser Hardhat</string>
<string>EQ_TAILCHASER_MISSILE</string>
<string>The first practicable result of Benulobiweed, inc.'s foray into weaponmaking is in this faaaasst ECM-hardened interceptor missile.</string>
<dict>
<key>available_to_all</key>
<true/>
</dict>
</array>
<array><!-- ecm hardened missile -->
<integer>12</integer>
<integer>5000</integer>
<string>Taranis ECMR2 MRHSSM</string>
<string>EQ_ECMR2_MISSILE</string>
<string>Taranis corp's Medium Range (ECM-)Hardened Ship-to-Ship Missile, packing a good punch and a state-of-the-art guidance system than the FdL counterpart.</string>
<dict>
<key>available_to_all</key>
<true/>
</dict>
</array>
</array>
</plist>
EDIT: I had 'misspelled' shipdata.plist as ship
yard.Plist. Corrected.
Moderator: Follow-ups moved here.