Scripters cove

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: winston, another_commander

User avatar
Okti
---- E L I T E ----
---- E L I T E ----
Posts: 700
Joined: Sun Sep 26, 2010 1:51 pm
Location: A GH shop, near witchpoint to Oresrati in Galaxy 8

Re: Scripters cove

Post by Okti »

Eric Walch wrote:
Okti wrote:
The method is

Code: Select all

worldScripts["scriptname"]["functionname"](args);
I tried it at the first place but I forgot to add this. before the function name :D
That you need to include "this." when writing it down as string is new to me. I always used:

Code: Select all

worldScripts.scriptname.functionname(args)
for calling functions with parameters in other scripts. Or

Code: Select all

worldScripts["scriptname"].functionname(args)
I meant for the main function I forgot to add this. before the function name in the world script. So probably it is not recognized as a function which belongs to the world script.
My OXP's
And Latest Mission Coyote's Run
zsozso
Above Average
Above Average
Posts: 23
Joined: Tue Apr 12, 2011 3:54 pm
Location: Toronto, Canada

Re: Scripters cove

Post by zsozso »

Hi,

I am having fun with the large variety of missiles and bombs available from various OXPs, especially since I recently purchased a Vortex ship with its mighty 5x5 pylons, so I can equip 25 missiles at once having plenty of space for the variety. The only problem is I cannot remember all the icon-to-missile-type associations -- not to mention that the mapping isn't even unique, i.e. there are multiple types using the same icon.

So, I thought maybe I could add a few lines of script that would display the name of the currently active missile somewhere. As I am new to Oolite scripting I started looking around to find the right function, property names and events to use, but I did not get too far. What I found so far:

1. The string I want to display can be obtained from the array: player.ship.missiles[pylonCounter].name
Trouble here: I do not know what is the currently active pylonCounter value

2. Ideally I would like to display the name in some permanent position, i.e. making it part of the HUD, but I have no idea how to do that, so for now I am willing to settle with the use of the function player.consoleMessage(string) to dump the info onto the screen at the "right time"

3. The next problem is when should the consoleMessage be called ? Ideally, I'd like it to be called when the pilot switches the current missile (press 'y' by default key mapping), and also when a missile was fired and the next one is auto-selected. For this second case I can use the this.shipFiredMissile event callback, so that is fine. However, I could not find an event for the active missile switching.

If I could solve #2 (have a permanent display on HUD), then I could use a timer event and just periodically update it, so #3 would be solved too.

I would appreciate any ideas or pointers to information how to solve these!
Thanks in advance!
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5528
Joined: Thu Jun 12, 2008 6:55 pm

Re: Scripters cove

Post by Thargoid »

I like your idea, and also your ship ;)

What you're trying to do is along the good lines, but I think there are certain pieces of information that aren't visibly exposed to the scripting that will scupper you though, like the active pylon number (your pylonCounter variable) and the ability to put messages on a certain place on the screen.

To my knowledge neither is currently available/possible, although the "text box" display position can be changed within the HUD design itself (but not I think via scripting).

But I do agree with the problem you are trying to solve. The best I could do to get around it is the missile display screen that the Vortex has, which can be used to list the names of what is on each pylon for each bay. It's not ideal as it's on a mission screen and so not exactly combat-friendly, but it is better than nothing and needed with so many bays and pylons available on that ship. It's accessed via the same route as the cargo hold display screens (F5-F8 when in-docked or F5-F5-F8 when in-flight) and then via the menu selections if needed (you can flip between cargo and missile lists there too).
zsozso
Above Average
Above Average
Posts: 23
Joined: Tue Apr 12, 2011 3:54 pm
Location: Toronto, Canada

Re: Scripters cove

Post by zsozso »

Thanks Thargoid! That's good enough for now.
And the ship is awesome :wink:

My only fear is that I'll get too much used to it shooting down the bad guys with the turrets automatically for me, that at the end I'll be unable to fight without that crutch :oops:
I know they can be turned off, but they are so helpful :lol:
User avatar
Capt. Murphy
Commodore
Commodore
Posts: 1127
Joined: Fri Feb 25, 2011 8:46 am
Location: UK South Coast.

Vector calculation help..

Post by Capt. Murphy »

Hi,

Anyone well versed in the mysteries of vector calculations help me out with this?

I've got the following variables for my entity:

currentposition = this.ship.position
heading = this.ship.heading
jumpdistance = (this.ship.scannerRange / 2)

and I want to calculate a new position that is jumpdistance away from currentposition in the direction of heading. Anyone help with the JS formula?

Ta,
[EliteWiki] Capt. Murphy's OXPs
External JavaScript resources - W3Schools & Mozilla Developer Network
Win 7 64bit, Intel Core i5 with HD3000 (driver rev. 8.15.10.2696 - March 2012), Oolite 1.76.1
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Re: Scripters cove

Post by JensAyton »

currentPosition.add(heading.multiply(jumpDistance))
User avatar
Mauiby de Fug
---- E L I T E ----
---- E L I T E ----
Posts: 847
Joined: Tue Sep 07, 2010 2:23 pm

Re: Scripters cove

Post by Mauiby de Fug »

newPosition = this.ship.position.add(this.ship.orientation.vectorForward().multiply(jumpDistance)); which can be simplified to
newPosition = currentPosition.add(heading.multiply(jumpDistance));
I used something similar with my wormhole drones, which I in turn found in someone else's oxp...

Edit: ninja'd (a while ago, damn my internet!) by the mighty Ahruman, written as succinctly as ever!
User avatar
Capt. Murphy
Commodore
Commodore
Posts: 1127
Joined: Fri Feb 25, 2011 8:46 am
Location: UK South Coast.

Re: Scripters cove

Post by Capt. Murphy »

Thanks gents.
[EliteWiki] Capt. Murphy's OXPs
External JavaScript resources - W3Schools & Mozilla Developer Network
Win 7 64bit, Intel Core i5 with HD3000 (driver rev. 8.15.10.2696 - March 2012), Oolite 1.76.1
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Re: Scripters cove

Post by JensAyton »

This was originally posted in this thread. I’ve moved it here since it’s generic, reusable code.



My suggested approach to handling structured data in an OXP script is:
  • Think about how you’ll implement your structure in JavaScript.
  • Implement that.
  • In response to playerWillSaveGame() events, convert your data structure to JSON using JSON.stringify(), and write that to a mission variable.
There are some limitations to this approach – JSON can’t represent cyclical structures, or multiple references to the same object, or Oolite-defined types – but the point is that you don’t need to think in terms of how information will be represented in strings. That’s basically a solved problem.

For storing per-system information, there are basically two choices: arrays (best if you expect to have data for most systems), and objects with numerical keys (best if your data is likely to be sparse). You’ll either want an array of such structures, or just keep one for the current galaxy and discard it on galactic jump.

Here’s a template that will let you associate arbitrary properties with any system:

Code: Select all

this.startUp = function startUp()
{
    // Load saved state.
    try
    {
        this.$state = JSON.parse(missionVariables.myOXPSuperUniqueIdentifier_state);
    }
    catch (e) {} // Squash any parse errors and treat as uninitialized.
   if (!this.$state)  this.$state = [];
}


this.playerWillSaveGame = function playerWillSaveGame()
{
    // Save state.
    missionVariables.myOXPSuperUniqueIdentifier_state = JSON.stringify(this.$state);
}


this.$getState = function getState(galaxyID, systemID, key)
{
    var sysInfo = this.$lookupSystemState(galaxyID, systemID, false);
    if (sysInfo)  return sysInfo[key];
}


this.$setState = function setState(galaxyID, systemID, key, value)
{
    if (value !== undefined)
    {
        this.$lookupSystemState(galaxyID, systemID, true)[key] = value;
    }
    else
    {
        this.$deleteState(galaxyID, systemID, key);
    }
}


this.$deleteState = function deleteState(galaxyID, systemID, key)
{
    var sysInfo = this.$lookupSystemState(galaxyID, systemID, false);
    if (sysInfo)  delete sysInfo[key];
}


this.$lookupSystemState = function lookupSystemState(galaxyID, systemID, createIfNeeded)
{
    var galInfo = $state[galaxyID];
    if (!galInfo)
    {
        if (!createIfNeeded)  return;
        galInfo = {};
        $state[galaxyID] = galInfo;
    }
    var sysInfo = galInfo[systemID];
    if (!sysInfo)
    {
        if (!createIfNeeded)  return;
        sysInfo = {};
        galInfo[systemID] = sysInfo;
    }
    return sysInfo;
}
After the following sequence of insertions:

Code: Select all

this.$setState(2, 5, "test", "banana");
this.$setState(2, 7, "foo", "Fred");
this.$setState(0, 250, "wibble", [42, 365, "wobble"]);
…the stored mission variable is [{"250":{"wibble":[42,365,"wobble"]}},null,{"5":{"test":"banana"},"7":{"foo":"Fred"}}] and the corresponding $getState()s work after saving and restoring.
User avatar
Capt. Murphy
Commodore
Commodore
Posts: 1127
Joined: Fri Feb 25, 2011 8:46 am
Location: UK South Coast.

Re: Scripters cove

Post by Capt. Murphy »

Can a parameter be passed to a function when said function is called by timer?

I've tried something along these lines which isn't accepted as valid syntax.

Code: Select all

this.shipSpawned = function(newship)
{this.delayTimer = new Timer (this, this.delayedActions(newship),1,0);}

this.delayedActions = function (newship)

{ //some code that uses newship}
[EliteWiki] Capt. Murphy's OXPs
External JavaScript resources - W3Schools & Mozilla Developer Network
Win 7 64bit, Intel Core i5 with HD3000 (driver rev. 8.15.10.2696 - March 2012), Oolite 1.76.1
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5528
Joined: Thu Jun 12, 2008 6:55 pm

Re: Scripters cove

Post by Thargoid »

Not directly like that, no.

You have to route it via a variable.
User avatar
Capt. Murphy
Commodore
Commodore
Posts: 1127
Joined: Fri Feb 25, 2011 8:46 am
Location: UK South Coast.

Re: Scripters cove

Post by Capt. Murphy »

Thanks Thargoid - and I guess if that was being done for something like newly spawned ships an array would have to be used if multiple ships are being spawned at the same time.
[EliteWiki] Capt. Murphy's OXPs
External JavaScript resources - W3Schools & Mozilla Developer Network
Win 7 64bit, Intel Core i5 with HD3000 (driver rev. 8.15.10.2696 - March 2012), Oolite 1.76.1
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5528
Joined: Thu Jun 12, 2008 6:55 pm

Re: Scripters cove

Post by Thargoid »

Yes. You can assign ships spawned using the new system.addShips (and variants thereof) directly to an array (this.myShips = system.addShips("myRole", 3); or somesuch) and then refer to them directly via the segments of that array.
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Re: Scripters cove

Post by JensAyton »

Capt. Murphy wrote:
Can a parameter be passed to a function when said function is called by timer?

Code: Select all

this.shipSpawned = function(newship)
{this.delayTimer = new Timer (this, this.delayedActions(newship),1,0);}

Code: Select all

this.delayTimer = new Timer(this, function() { this.delayedActions(newShip) }, 1, 0);
User avatar
Capt. Murphy
Commodore
Commodore
Posts: 1127
Joined: Fri Feb 25, 2011 8:46 am
Location: UK South Coast.

Re: Scripters cove

Post by Capt. Murphy »

Ahh - thank-you Ahruman.
[EliteWiki] Capt. Murphy's OXPs
External JavaScript resources - W3Schools & Mozilla Developer Network
Win 7 64bit, Intel Core i5 with HD3000 (driver rev. 8.15.10.2696 - March 2012), Oolite 1.76.1
Post Reply