Yet again a noobish question, but I really want to make sure, I don't litter timers everywhere.
I'm writing an AI (priorityAI) this time and implemented a timer for repeated condition checking. Of course I could have used the priority list itself with timed reconsiderations, but as the method it repeats is more like a function of the ship (it's a simulated Torusdrive) than a decision the ship takes, I wanted to keep them independent from each other to a certain degree.
Here's what I've got:
Code: Select all
this.name = "Solar Harvester AI";
this.aiStarted = function() {
var ai = new worldScripts["oolite-libPriorityAI"].PriorityAIController(this.ship);
ai.setCommunicationsRole("scavenger");
ai.setParameter("_solarHarvesterReturnHome", false);
[...] // Methods implemented for the AI.
ai._solarHarvesterTorusDrive = function() {
-> var timer = this.ship._solarHarvesterTorusSpeedTimer;
if (this.ship.checkScanner().length !== 0 ||
this.ship.position.distanceTo(system.sun.position) < system.sun.radius * 1.48) {
if (timer.isRunning) this.ship.velocity = this.ship.heading.multiply(this.ship.maxSpeed);
// Drop out of Torus Speed to maxSpeed. Deceleration to set
// speed happens naturally afterwards.
timer.stop();
}
else this.ship.velocity = this.ship.heading.multiply(this.ship.maxSpeed * 32);
// Accelerate to or refresh Torus Speed (32*maxSpeed).
if (!this.ship && timer.isRunning) timer.stop(); //<- Will this do anything?
}
// Engage Torusdrive, check every 0.25 sec if there is something masslocking (excluding
// Planets/Suns, including asteroids/loot) and stop or maintain Torus Speed (refresh velocity).
-> this.ship._solarHarvesterTorusSpeedTimer = new Timer(ai, ai._solarHarvesterTorusDrive ,-1 ,0.25);
[...] // More AI methods.
ai.setPriorities([
[...] //Fighting, Fleeing and doing other stuff
// Go to sun
{
condition: !ai._solarHarvesterConditionReadyToHarvest,
behaviour: function () {
ai._solarHarvesterBehaviourGotoHarvestOrbitAboveSun();
-> this.ship._solarHarvesterTorusSpeedTimer.start();
},
reconsider: 20
}
].concat(ai.templateWitchspaceJumpAnywhere()));
}
Please take notice, how implemented the timer as a property of the ship-object (
this.ship._solarHarvesterTorusSpeedTimer
), to make it itself referable and controllable for the method it repeats. The timer itself is bound to the AI object variable (
ai
in
new Timer(
ai, ai._solarHarvesterTorusDrive ,-1 ,0.25);
)
To my knowledge (wiki) the timer should be removed when the ship is destroyed/docks/jumps out, as for once
ai
should be removed and then the object
this.ship
is also deleted.
But woe me, I found contradicting evidence.
Maybe this in itself was the mistake, but to check the timer I referred to it in the debug console by
this.hTimer = this.harvester._solarHarvesterTorusSpeedTimer
and the object behind
this.hTimer
was alive even after the ship's doom by
this.harvester.temperature = 1.1
. Does the timer stay alive, because something is still referring to it?
In another case I did not refer to the timer and blew the ship up, while in torus transit (running timer). The result:
Exception: TypeError: this.ship is undefined
Active script: Solar Harvester AI 0.1.0
solarHarvesterAI.js, line 50:
var timer = this.ship.AIScript._solarHarvesterTorusSpeedTimer;
Over and over again, every 0.25 seconds.
I don't want to create old timers or even still running once for each ship I launch with this AI.
I also tried:
this.entityDestroyed = function()
{
if (this.ship._solarHarvesterTorusSpeedTimer) {
if (this.ship._solarHarvesterTorusSpeedTimer.isRunning) this.ship._solarHarvesterTorusSpeedTimer.stop();
delete this.ship._solarHarvesterTorusSpeedTimer;
}
}
, but at this point
this.ship
is also not referable anymore.
Is there a method (way of scripting, not a certain function) you use, to make sure timers in priorityAIs die as they should?