Nexus Modding > Scripting

Code improving (check wether a ship is headed towards an object or not)

(1/3) > >>

Mularac:
I built this code for my latest mission as a way to check wheter a ship was headed towards an other or not (I've removed any way for the player to change the velocity, which is set always at 200)
The thing is, the code doesn't work too well. It often gives false readings, like 0, or very low numbers or too high ones.
I was hoping you guys could help me to improve it.


--- Code: ---Rule event tick
name "HeadingCheck"
:action
Dist1:=Distance(m.al, m.ac); //first, we take the initial distance between the alkesh and the achilles
delay(0,0.5,
Dist2:=Distance(m.al, m.ac); //we wait half a second and then we take it again
dif:=dist1-dist2;  //and we compare and take the difference of those two distances
debug(dif);  //we show it on the console, for debugging purposes
if(Dist1-dist2>100,  //if the difference is higher than 100, it means that the distance between the two ships is decreasing rapidly, which means one thing: you're headed straight to the alkesh. Bad mojo, bro.
Debug("too close for confort");
counter2:=counter2+1;  //we take a counter of how many times this crossing appears
if(warn1!=1,
LocalEvent(TooCloseForConfort);  //if the difference is higher than 100 this event is issued (see that event for the use of the "warn" variable)
);
,  //this coma means "else"
if(dist1-dist2!=0&warn1=1&nonrepeated=1,  //sometimes the code malfunctions for some extrange reason and it gives a "0" reading, as both distances were the same, it also gives false readings (lower than the real deal)   
milestone:=counter2; //so, in order to counter that, we take a "milestone" of how many crossings took place and we re-check it 5 secons later
nonrepeated:=0; //this is meant so that this doesn't happen over and over again
delay(0,5,
Milestone2:=counter2;
if(milestone=milestone2,  //if the milestone 5 seconds later is the same as the one five seconds earlier, it means that "counter" hasn't changed, which means that no number higher than 100 has appeared, and then we can safely assume that the player has changed course (in order to come up with this I spent a long time looking at the debugging windown...)
ReRouted:=1;  //we "tell" the script that the ship has rerouted
);
nonrepeated:=1;  //with this we re-open the check for future porpuses
,0);
);

);
,0);
:end
END

tick 0.5


--- End code ---




EDIT: Nevermind, solved it... I turned the tick rule into a regular one and added a localevent(*rule in question*) in the bottom of it to make it a little like a "tick" rule of my own, hehehehehe

Arparso:
I'd guess, your false readings were caused by the delay function and because of variable sharing. Let me elaborate: your tick event runs every 0.5 seconds and stores the current distance in "Dist1". Then it orders some script commands to be run 0.5 seconds later using the delay function before finishing its job. So approximately 0.5 seconds later both the next tick event and your delayed commands get executed with the latter one measuring the distance again in Dist2 and comparing it to the old value in Dist1. There are two cases to think about now:

1) the delayed commands start first and the comparison works smoothly as expected... almost immediately afterwards the tick event gets to work, saves a new value in Dist1 and orders the next batch of delayed commands - everything works fine

2) the tick event manages to start first, saves a new value in Dist1 and orders the next batch of delayed commands... immediately afterwards the old batch of delayed commands get their CPU time, measure the current distance and compare that to to the NEW Dist1 the tick event just saved... which is the wrong one, obviously. That's why you get readings of 0 or other extremely small values

The second causes the problems here. Keep in mind, that both the tick event and the delay don't work THAT precise - you can't predict, when exactly both get executed... depending on the current CPU load and game situation, both the tick length and the delay amount will vary. It's generally best to avoid delays or overly complex tick commands because of that. That's actually a very common problem with multithreading in programming as well, which makes using multiple CPU cores to their fullest so hard to do.

I think, I've got a pretty simple and more robust sample measuring distance changes between both vessels:

--- Code: ---TICK 0.5

RULE event Tick
    :action
        // store distance in temporary variable
        E.temp := distance(m.al, m.ac);
       
        // only compare the distances, if the lastDistance-variable has
        // already been initialized by our script
        If(lastDistance != 0,
            // store distance difference in local variable
            E.diff := lastDistance - E.temp;
            debug(E.diff);
        );
       
        // store the current distance in lastDistance-variable
        lastDistance := E.temp;
    :end
END
--- End code ---

That code only uses one variable (lastDistance) to store the distances and avoid's delay entirely. The returned distance changes will not be constant, however, even with constant speeds and flight vectors - that's because Tick isn't executed exactly every 0.5 seconds... some pauses between Ticks just take longer than others. You can't really avoid that.

Mularac:
yeah, I also think it has something to do with the lenght of the event... However, it got more complicated now, as I added the ships's current velocity to it, and using the "delay" command to re start the event instead of the "tick" solved the 0 thing and the extremely low values, however the values still fluctuate a bit, probably due to the delay command not working too well. I'll take a look at that now, see what I come up with.


EDIT: I'm sorry, but that way is no good, it fluctuates a lot. here's a log of what it read (constant speed and heading):
        233.5
        248.633
        250.914
        283.848
        167.789
        225.223
        252.934
        174.43
        226.711
        268.512
        238.773
        214.434
        205.113
        207.535
        181.633
        180.781

with my old code it only variated about 20 points top, here it gets up to 80. So it seems that a tick rule is not very reliable....

Arparso:
What exactly are you trying to achieve? If you only want to know, if ship A is getting nearer to ship B, you don't really need much precision... just seeing the distance getting bigger or smaller would be enough to do that - and we already have that kind of information.

Mularac:
What I'm trying to do is a rule that can identify when youre headed towards a ship or not, and also, part of the rule is to detect when you are NOT headed towards that ship. And if the readings vary so much, it would either give me false positive or false negatives values.

On an other, completely unconnected question: is it posible to disable a fighter or commando's engines or other fighter device for that matter?

Navigation

[0] Message Index

[#] Next page

Go to full version