Sorry Rohrschachhamster, but I can't help you on this.
I've got some problem of my own, or rather some strange behaviour I want to report.
Since subentities can't be restored selectively but only all together / at once, in order to simulate the repair of only a single subentity with my
External Repair System (ERS), I wrote a function which destroys all subentites that have not been repaired by the ERS after I called
player.ship.restoreSubEntities()
. Or at least it ought to do this (it does now in my updated version), but it didn't work properly and it took me some time to find out why.
Here is the original code:
Code: Select all
this.$setupSubentities = function() {
var damagedSubents = $getDamagedSubentsAsString();
$showDebugInfo("damagedSubents: " + damagedSubents, 1);
for (var x in player.ship.subEntities) {
var subentity = player.ship.subEntities[x];
$showDebugInfo("setting up subEnt(" + x + "): " + subentity, 1);
// if subentity is marked as damaged, remove it / damage it again (it might just have been restored by "restoreSubentities()")
if (damagedSubents.indexOf("" + subentity) > -1) {
$showDebugInfo("removing damaged subentity(" + x + "): " + subentity, 1);
player.ship.subEntities[x].remove(true); // true: suppress death event
} else {
// subentity is operational => prepare subentity for ERS by setting up "subentity died" functions
$showDebugInfo("preparing subentity for ERS repairs(" + x + "): " + subentity, 1);
// remember original shipDied() in order to be able to start it later:
player.ship.subEntities[x].script._shipDiedOld = player.ship.subEntities[x].script.shipDied;
player.ship.subEntities[x].script.shipDied = function(whom, why) {
worldScripts["GGIndustries_ERS_MainScript.js"].$notifyERS(this.ship, why); // let ERS know that subentity has been destroyed
if (this._shipDiedOld) {
this._shipDiedOld(whom, why);
}
}
}
}
}
The part which ought to remove all subentities that are known to be damaged didn't work. Only some of the subentities where removed, but approximately half of it was skipped.
Through many experiments I came to the conclusion that the reason for this is that the for-loop
Code: Select all
for (var x in player.ship.subEntities) {
doesn't grant access to all members of player.ship.subEntities because the line
Code: Select all
player.ship.subEntities[x].remove(true);
changes the array so that player.ship.subEntities[x] varies over the loop-iterations. So, for instance, let's say there are seven subentities marked as damaged of a total of 8 subentites, what happens is that player.ship.subentites[0] to player.ship.subEntities[4] still return a subEntity, but player.ship.subEntites[5] does not because the array has already been shrinked by "subEntites[x].remove()". Therefore, approximately half of the subEntites which ought to get removed will stay alive.
My quick workaround for this is to only mark the subEntities for removal as long as I'm inside the for-loop, and to remove them
after I left it. That way it works!
Here is the working version:
Code: Select all
this.$setupSubentities = function() {
var damagedSubents = $getDamagedSubentsAsString();
$showDebugInfo("damagedSubents: " + damagedSubents, 1);
var subents2Remove = new Array();
for (var x in player.ship.subEntities) {
var subentity = player.ship.subEntities[x];
$showDebugInfo("setting up subEnt(" + x + "): " + subentity, 1);
// if subentity is marked as damaged, remove it / damage it again (it might just have been restored by "restoreSubentities()")
if (damagedSubents.indexOf("" + subentity) > -1) {
$showDebugInfo("removing damaged subentity(" + x + "): " + subentity, 1);
// player.ship.subEntities[x].remove(true); // true: suppress death event // can't do it immediately because this will change player.ship.subEntities, preventing access to all
subents2Remove.push(player.ship.subEntities[x]);
} else {
// subentity is operational => prepare subentity for ERS by setting up "subentity died" functions
$showDebugInfo("preparing subentity for ERS repairs(" + x + "): " + subentity, 1);
// remember original shipDied() in order to be able to start it later:
player.ship.subEntities[x].script._shipDiedOld = player.ship.subEntities[x].script.shipDied;
player.ship.subEntities[x].script.shipDied = function(whom, why) {
worldScripts["GGIndustries_ERS_MainScript.js"].$notifyERS(this.ship, why); // let ERS know that subentity has been destroyed
if (this._shipDiedOld) {
this._shipDiedOld(whom, why);
}
}
}
}
// remove damaged subEntities:
for (var x in subents2Remove) {
$showDebugInfo("subents2Remove(" + x + "): " + subents2Remove[x], 1);
subents2Remove[x].remove(true); // true: suppress death event
}
}
Is this behaviour of
subEntities.remove()
intentional? It sure makes sense, but for writers of OXP's which think they can remove
all subEnts in a single for-loop this might come quite unexpected (as it was for me).
忍 knowing that enough is enough, you'll always have enough.
Running Oolite 1.77 on Ubuntu Linux 12.04 LTS