Page 1 of 1

Applying Multiple Scripts to an NPC ship

Posted: Mon Sep 30, 2013 4:59 am
by realbrit70
Hi,

I'm back to playing and attempting to mod Oolite after a hiatus caused by hectic family life. I downloaded version 1.77 over the weekend and liked a lot of what I've seen, especially some of the newer OXPs that make use of the ability to change market prices and the change to the use of the accuracy property.

One thing that is confusing me for a little OXP I'm writing is whether you can assign multiple Javascript files as script files to a NPC ship and if so how do you do that. I know that I can add multiple Javascript files to the world-scripts.plist to contain handlers for world events and that this will work for the player's ship because all events raised on the player ship are also raised as world events, however what I want to do is add events to NPC ships on shipSpawned to handle the new shipBountyChanged event.

As I read it I can add a single Javascript file containing the event handlers to the ship.script property. However I also have Griff's Alloys and Wreckage installed on my system and that is adding it's own Javascript handler for NPC ship events. I'd like to co-exist peacefully and have been trying to figure out how to do it.

Any illumination would be appreciated.

Re: Applying Multiple Scripts to an NPC ship

Posted: Mon Sep 30, 2013 5:31 am
by Tricky
It is called event chaining.

A very simple ship script would look like this.

Code: Select all

(function () {
    "use strict";

    /* Standard public variables for OXP scripts. */
    this.name = "unique_name_here";
    this.author = "Your name";
    this.copyright = "Your copyright";
    this.license = "CC BY-NC-SA 3.0";
    this.description = "Your ship script description here.";
    this.version = "0.0";

    /* Save the original ship script event handler hook. */
    this.$myoxpname_shipBountyChanged = this.shipBountyChanged;

    this.shipBountyChanged = function (delta, reason) {
        /* Code for myoxpname here. */

        if (this.$myoxpname_shipBountyChanged) {
            /* Call the original. */
            this.$myoxpname_shipBountyChanged.apply(this, arguments);
        }
    };
}.bind(this)());
This will stop your script from overriding any other shipBountyChanged events that have or will be attached to the ship.

Remember to change the myoxpname_ prefix to something unique for your OXP.

Re: Applying Multiple Scripts to an NPC ship

Posted: Mon Sep 30, 2013 6:47 am
by cim
Tricky wrote:
It is called event chaining.
You can't apply it directly like that, though - you can only have one ship script applied at once, and if you apply a new one it completely erases the old one (which is usually desirable behaviour), so this.shipBountyChanged will always be undefined when that script runs. You need to make the changes from a worldscript using ship.script.shipBountyChanged = ...

Re: Applying Multiple Scripts to an NPC ship

Posted: Mon Sep 30, 2013 7:11 am
by realbrit70
I think I get what you're saying Cim.. in my world-script for the shipSpawned function I'm going to set

ship.script.shipBountyChanged = [name_of_my_function_to_run_on_bounty_changed]

and that function should be contained within the same JS file?

Re: Applying Multiple Scripts to an NPC ship

Posted: Mon Sep 30, 2013 7:52 am
by spara
realbrit70 wrote:
I think I get what you're saying Cim.. in my world-script for the shipSpawned function I'm going to set

ship.script.shipBountyChanged = [name_of_my_function_to_run_on_bounty_changed]

and that function should be contained within the same JS file?
Be careful not to overwrite shipBountyChanged set by someone else. If a ship has shipBountyChanged already defined you should follow Tricky's advice of chaining and do something like this:

* Move the old event definition out of the way.
* Insert your own definition in.
* Call for the original definition at the end of your new definition.

Re: Applying Multiple Scripts to an NPC ship

Posted: Mon Sep 30, 2013 6:05 pm
by Tricky
Ah! Just assumed it would work for ship scripts too. Ironically I do event chaining through a world script. Use shipSpawned in the worldScript and check for the ship ID passed in.

Sorry about that.