Page 28 of 118
Re: Scripters cove
Posted: Sun Apr 10, 2011 3:31 pm
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
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.
Re: Scripters cove
Posted: Wed Apr 13, 2011 6:08 pm
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!
Re: Scripters cove
Posted: Wed Apr 13, 2011 6:34 pm
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).
Re: Scripters cove
Posted: Thu Apr 14, 2011 6:31 pm
by zsozso
Thanks Thargoid! That's good enough for now.
And the ship is awesome
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
I know they can be turned off, but they are so helpful
Vector calculation help..
Posted: Sun Apr 17, 2011 4:23 pm
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,
Re: Scripters cove
Posted: Sun Apr 17, 2011 5:09 pm
by JensAyton
currentPosition.add(heading.multiply(jumpDistance))
Re: Scripters cove
Posted: Sun Apr 17, 2011 5:27 pm
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!
Re: Scripters cove
Posted: Sun Apr 17, 2011 6:19 pm
by Capt. Murphy
Thanks gents.
Re: Scripters cove
Posted: Wed Apr 27, 2011 7:15 pm
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.
Re: Scripters cove
Posted: Wed Aug 03, 2011 6:20 pm
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}
Re: Scripters cove
Posted: Wed Aug 03, 2011 6:27 pm
by Thargoid
Not directly like that, no.
You have to route it via a variable.
Re: Scripters cove
Posted: Thu Aug 04, 2011 5:59 am
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.
Re: Scripters cove
Posted: Thu Aug 04, 2011 7:09 am
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.
Re: Scripters cove
Posted: Sat Aug 06, 2011 12:09 am
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);
Re: Scripters cove
Posted: Sat Aug 06, 2011 5:14 am
by Capt. Murphy
Ahh - thank-you Ahruman.