Page 1 of 3

Death Comms OXP

Posted: Tue Sep 08, 2015 8:07 am
by phkb
Not sure if this has been done before, but here's a little OXP to add a bit of comms flavour to battles. Essentially, this OXP will occasionally transmit a final comms message from a ship that is exploding, kind of like a death cry. Things like "Oh no!", or "Aieeee!", that sort of thing. Only standard ships (no police or Thargoids).

Comments and suggestions welcome!

Download OXZ version 1.3 here: DeathComms.oxz
Also available via the download manager.

Re: Death Comms OXP

Posted: Tue Sep 08, 2015 9:18 am
by Diziet Sma
Great idea! 8)

Re: Death Comms OXP

Posted: Tue Sep 08, 2015 10:57 am
by popsch
I'm really new to javascript, but doesn't this override existing shipDied functions?

Code: Select all

 ship.script.shipDied = this.$shipDied;

Re: Death Comms OXP

Posted: Tue Sep 08, 2015 11:16 am
by Layne
"Do you have any famous last words!?"
"Not yet."
"...is that famous?"

Very fun idea, I look forward to seeing this in action.

Re: Death Comms OXP

Posted: Tue Sep 08, 2015 1:00 pm
by phkb
popsch wrote:
but doesn't this override existing shipDied functions?
Yeah, I'll add a bit of protection for the next version.

Re: Death Comms OXP

Posted: Tue Sep 08, 2015 3:48 pm
by phkb
OK, version 1.1 should address the issues raised popsch. It should play nice with other OXP's now. Link in the first post.

Re: Death Comms OXP

Posted: Tue Sep 08, 2015 8:56 pm
by popsch
It's a very nice idea. Now still, doesn't that break all OXPs that also use this.shipKilledOther? Maybe I misunderstand something about how the callback system is working in Oolite: does it permit only one callback, or is it a list of callbacks?

If it's only one callback, then other OXPs such as exhibition or your own GalCopAdminServices won't work anymore.

A really necessary extension for Oolite would be to change the callbacks to support lists of callbacks, in the same way that many other systems and languages support registering event handlers.

Re: Death Comms OXP

Posted: Tue Sep 08, 2015 10:24 pm
by phkb
popsch wrote:
doesn't that break all OXPs that also use this.shipKilledOther?
Not really. I'm using two different methods to determine when a ship is destroyed: method 1 for when a ship is destroyed by an NPC, and method 2 for when a ship is destroyed by the player.

For method 1, I'm attempting to attached my script to the "shipKilledOther" event of all NPC ships, but only when there is no existing script in place. If there's something there already, I'm not changing anything.

For method 2, I'm defining a global "shipKilledOther" function, which all OXP's can define, which is called for when the player kills another ship. When the player destroys a ship, every OXP that has a "shipKilledOther" function defined will be called, GalCopAdminServices included.

You raise an interesting question, though. If two OXP's want to utilise the same event on an NPC ship, how do you attach your script to it without overwriting the previous one? Doing a "ship.script.shipKilledOther += this.myfunctionname;" certainly doesn't work (I just tested it).

Re: Death Comms OXP

Posted: Wed Sep 09, 2015 6:35 am
by cim
phkb wrote:
You raise an interesting question, though. If two OXP's want to utilise the same event on an NPC ship, how do you attach your script to it without overwriting the previous one? Doing a "ship.script.shipKilledOther += this.myfunctionname;" certainly doesn't work (I just tested it).
Something like this

Code: Select all

if (ship.script.shipKilledOther) {
    ship.script.$myoxp_old_shipKilledOther = ship.script.shipKilledOther;
}
ship.script.shipKilledOther = function(parameter) {
    // your code goes here
    if (this.$myoxp_old_shipKilledOther) {
        this.$myoxp_old_shipKilledOther(parameter)
    }
}

Re: Death Comms OXP

Posted: Wed Sep 09, 2015 7:04 am
by phkb
cim wrote:
Something like this {snip}
Thanks, cim, that's brilliant! Version 1.2 now up which reverts back to using the shipDied event, and (I think) will be fully compatible with other OXP's that use shipDied.

Re: Death Comms OXP

Posted: Wed Sep 09, 2015 8:57 am
by Svengali
Sidenote: [Wikipedia] Monkey patches are evil and usually the last resort. If you can avoid it.
Races, clashes between patches, overhead and completely uncontrollable runtime behaviour is really not such a good thing.

Oh, and if your code does not modify properties/values in the patched script call the other code before your own.

Re: Death Comms OXP

Posted: Wed Sep 09, 2015 9:49 am
by phkb
Thanks Svengali! Now I know what a Monkey patch actually is! :D

I can see how they might be problematic, but in these sorts of cases where you want to utilise the same ship event as another OXP, what options are there? Other than not using the events in the first place, I mean.

Re: Death Comms OXP

Posted: Wed Sep 09, 2015 11:07 am
by Svengali
phkb wrote:
I can see how they might be problematic, but in these sorts of cases where you want to utilise the same ship event as another OXP, what options are there? Other than not using the events in the first place, I mean.
Personally I think there is only one 'clean' way for OXP/OXZ content.
Offer the option to be used by other AddOns, e.g. via script_info keys or script properties, un-/registering functionality or direct calls. The other way round ('tell/flag if you want to be excluded') does not work unless all other AddOns create code/flags for features they are not interested in. This doesn't make sense.

I'm fully aware that 'global mechanisms' like [EliteWiki] Random Ship Names wouldn't do anything this way for OXP content unless flagged / invoked, but races, clashes or timeouts caused by modified content is a nightmare. Another advantage would be that concurrent AddOns can safely be installed at the same time. In the end it's a question if we think that users can know every little detail of the things 'under the hood' or if authors finally do start being responsible.

For Oolites native entities there's no real way and I guess patching is the only real option.
Here you are on your own to determine if you can safely modify or not. Clashes are unavoidable unless this community starts looking for solutions. All in all it's a difficult question. Performing lots of checks in .shipSpawned() is a time eater par excellence while not checking anything is simply asking for trouble.

Re: Death Comms OXP

Posted: Wed Sep 09, 2015 11:23 am
by phkb
I can tell you've had a bit of experience in the "nightmare" of Monkey patching... thank you for your thoughts on it. It would be good to have a core-design solution that would circumvent the need for monkey-patching, even working in a similar way to the player-centric global events would be nice.

In the interim, I'll add more documentation for this OXP that a monkey patch is in use so future OXP's will know what to expect.

Re: Death Comms OXP

Posted: Wed Sep 09, 2015 4:29 pm
by popsch
As I mentioned before, it would be good for Oolite to have a solid solution for the problem, otherwise compatibility between OXPs will become even more an issue than it is now. The monkey patch is a possible approach, but why not internalize this in Oolite by registering and de-registering listeners for events? The concept of event listeners is quite widely used in many languages and frameworks through the observer pattern: https://en.wikipedia.org/wiki/Observer_pattern