Scripters cove

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

Moderators: winston, another_commander

User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Thanks Kaks, I already thought that is was something like this. Therefor I later on used the function "rotationTo()" to change a Vector to an quaternion. The errors were gone but the station was still not aligned.

Now I used your code and first thought it also didn't do anything. But dumping the orientation before and after to the log showed it did something.:

Code: Select all

Orientation before: (1 + 0i + 0j + 0k), heading: (0, 0, 1)
Orientation after: (1 - 58315.3i - 9482.46j + 51081.1k), heading: (-0.645553, -0.104984, -0.756465)
To double check I added two stations and only changed the orientation of one. And yes, both had different orientations. To let the docking slit point to the planet I probably need an extra transformation of the vector, but that is for next week.
User avatar
Kaks
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 3009
Joined: Mon Jan 21, 2008 11:41 pm
Location: The Big Smoke

Post by Kaks »

Getting there! I just realized that all the numbers given to a quaternion must be between -1 & 1; probably the results you're getting are based on the decimal part of the original factoryVector.

One way to improve matters is to use the direction function to normalize the vector:

Code: Select all

        system.legacy_addShipsAt("factoryStation", 1, "pwp", 0.5, 0.5, 1.5)
        let factory = system.shipsWithPrimaryRole("factoryStation")[0];
        let planet = system.mainPlanet.position
        let factoryVector = (planet.subtract(factory.position)).direction();
        factory.setOrientation(1,factoryVector.x,factoryVector.y,factoryVector.z);
the first number sets the spin along the station's main axis, it shouldn't really make any difference to the orientation itself!
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

In the very impressive list with changes in 1.71 I miss a note that subentity handling changed. And in my opinion for the better.

Yesterday I noticed that flashers of subentities also flash. They never did.
And now I noticed after shooting down a subentity from a ship that the enclosed "death_actions" were executed. I my case this was exactly what I needed.
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Eric Walch wrote:
sterday I noticed that flashers of subentities also flash. They never did.
And now I noticed after shooting down a subentity from a ship that the enclosed "death_actions" were executed. I my case this was exactly what I needed.
I don’t think this was intentional, so I guess it’s a misbug. The relationship between subentities and their superentities was made more explicit, and in the process various cases where they weren’t made properly were fixed.

I now look forward to reports that switchLightsOn/switchLightsOff don’t work for subentity flashers. :-) (Fixed for 1.72.)
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Ahruman wrote:
I now look forward to reports that switchLightsOn/switchLightsOff don’t work for subentity flashers. :-) (Fixed for 1.72.)
I think this is what most people want. All flashers on/off simultaneously by the AI commands because it should like one single ship.

In my case the subentity is seen by the player as an inactive separate thing. There I like it more to be off. By using the right commands I can switch the flashers of the subentity on/off independent of the main ship by:

Code: Select all

if(this.ship.subEntities[2].shipDescription == "mySubentity")
     this.ship.subEntities[2].call("switchLightsOff")
I just tested it. The first line is just a test if the subentity is still present.

Whow, I really do like the possibilities of the build in ship scripts.
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

The fix for 1.72 is hierarchical. Switching flashers on/off for an entity also switches the flashers for subentities, but subentities can be explicitly switched on/off separately from the parent.

As I mentioned before, please do a bug report or scripting requests thread entry for any situation where you need to use call. It won’t be available in the stable release.
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

As I mentioned before, please do a bug report or scripting requests thread entry for any situation where you need to use call. It won’t be available in the stable release.
I know, but this was just a quick test to see if it would work on a subentity. Switching lights would probably be useful to use from within the JS. I am sure there are more AI commands that are useful to be used from within a ship-script. In my current work I use several occasions were I let the JS switch the AI to a special state to execute some AI commands. This way avoiding the call function. An own function would be easier.

Only on working with the scripts, one notices which AI commands are really useful as JS functions. It will take some practice work to see what functions will get used. (e.g. launching ships directly from within a station script instead of telling the AI to do that). I'll make a list.
User avatar
Commander McLane
---- E L I T E ----
---- E L I T E ----
Posts: 9520
Joined: Thu Dec 14, 2006 9:08 am
Location: a Hacker Outpost in a moderately remote area
Contact:

Post by Commander McLane »

Question: I see that the thargoid curses ("%R, %R, %R"), when being killed are now realized in a ship-script, no longer in death_actions (there was also something in the release notes about this, wasn't it?). Does that mean that death_actions are no longer working or supported? So do I have to have ship-script, if I want a ship to send a message or set a variable on being killed?
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Commander McLane wrote:
Question: I see that the thargoid curses ("%R, %R, %R"), when being killed are now realized in a ship-script, no longer in death_actions (there was also something in the release notes about this, wasn't it?). Does that mean that death_actions are no longer working or supported? So do I have to have ship-script, if I want a ship to send a message or set a variable on being killed?
All foo_actions on ships will be deprecated, but still functional, in the MNSR (just like script.plist). Since 1.70, the various foo_actions (launch_actions, death_actions, script_actions and setup_actions) are dispatched through oolite-default-ship-script.js but should function exactly as before. The various built-in ships using actions (constrictor, Thargoid, cloaking device target) have been ported to JavaScript in part to demonstrate the principle, and in part because it’s more efficient.
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

I want to rotate a station with its heading towards the planet. I have a vector to rotate about and an angle for how much to rotate. But whenever I use it with the rotate command I get errors. I don't see what I do wrong.

Maybe I use the wrong syntax. For testing purposes I created next two commands. Both generate an error but I see not why:
new Quaternion().rotate(new Vector([1,0,0]), 0))
Exception: SyntaxError: missing ; before statement
Active script: "oolite-debug-console" 1.71
oolite-debug-console.js, line 159:
let result = eval(command);
new Quaternion(rotate(new Vector([1,0,0]), 0)))
Exception: SyntaxError: missing ; before statement
Active script: "oolite-debug-console" 1.71
oolite-debug-console.js, line 159:
let result = eval(command);
Or more specific: I have a station "this.grsStation" that I want to align with vector "this.grs.Vector".

The code I use is:

Code: Select all

let angle = this.grsStation.heading.angleTo(this.grsVector)
let cross = new Vector(this.grsStation.heading.cross(this.grsVector))
let quaternion = new Quaternion(this.grsStation.orientation.rotate(cross, angle))
log("cross: "+cross+", angle: "+angle+", quaternion: "+ quaternion)
this.grsStation.setOrientation(this.grsStation.orientation.rotate(cross, angle))
It generates the log:

Code: Select all

cross: (-0.374901, 0.370731, -0.529527), angle: 0.8439223170280457, quaternion: (1 + 0i + 0j + 0k)
Exception: Error: Entity.setOrientation(): could not construct quaternion from parameters (undefined) -- expected Quaternion, Entity or four numbers.
The quaternion calculation with "(this.grsStation.orientation.rotate(cross, angle)" goes wrong and returns the unit vector instead of giving an error.

How must I use the function to let act the "rotation" on the "station.orientation"
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Hmm. rotate() is completely broken, by the look of things. (It fails to advance over the argument list before getting the angle argument. I haven’t seen this in tests because my tests used a list of numbers instead of a vector object). Not only that, but it’s causing a crashing double exception on my system. :-/

Some minor stuff:

Code: Select all

new Quaternion().rotate(new Vector([1,0,0]), 0))
This is parsed as new (Quaternion().rotate(...)) rather than (new Quaternion()).rotate. (Remember, JS doesn’t have classes; the new operator can take essentially any object as an argument.) I’m not sure how this leads to a missing-semicolon error.
Also, you don’t need the brackets; new Vector(1, 0, 0) works and is marginally more efficient.

Code: Select all

let angle = this.grsStation.heading.angleTo(this.grsVector)
let cross = new Vector(this.grsStation.heading.cross(this.grsVector))
let quaternion = new Quaternion(this.grsStation.orientation.rotate(cross, angle))
The news in this are making redundant copies. The following should have the same effect:

Code: Select all

 let angle = this.grsStation.heading.angleTo(this.grsVector);
let cross = this.grsStation.heading.cross(this.grsVector);
let quaternion = this.grsStation.orientation.rotate(cross, angle);
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Ahruman wrote:
Hmm. rotate() is completely broken, by the look of things. (It fails to advance over the argument list before getting the angle argument. I haven’t seen this in tests because my tests used a list of numbers instead of a vector object). Not only that, but it’s causing a crashing double exception on my system. :-/
DIgging into this exception has exposed a huge set of related bugs based on me not quite understanding error handling in Spidermonkey. I now know how to fix them, but it’ll take a while since there are a few hundred.

Of course, it’s good that I know this so it gets fixed. I just wish I didn’t. :-)
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Ahruman wrote:
Hmm. rotate() is completely broken, by the look of things.
Thanks for looking in to it. I somehow suspected that it was the rotate itself that was confused and not me. But because of my limited JS skills I wasn't sure.

Understanding vectors itself shouldn't be a to big problem. I have a background of chemical engineering and during my education there was enough in it about vector calculations. (But never used that part in practice).

Rotate won't be fixed until 1.72 so I go for my last resort to align the station: use the same method as used for the mainStation: just give it a random orientation and than place it at such a position around the planet that it is aligned. The method just looks stupid because you never know were it will be placed.

EDIT: Just tried it and the station is heading to the planet with its docking bay:

Code: Select all

this.grsVector = this.grsStation.orientation.vectorForward().direction()
this.grsStation.setPosition(system.mainPlanet.position.subtract(this.grsVector.multiply(system.mainPlanet.radius * 2)))
Only the position around the planet is now random.
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

Alternatively, here’s a fix for you:

Code: Select all

if (0 < oolite.compareVersion("1.72"))
{
    this.rotateQ = function(q, axis, angle)
    {
        angle *= 0.5;
        let w = Math.cos(angle);
        axis = axis.multiply(Math.sin(angle));
        
        return new Quaternion
        (
            q.w * w - axis.x * q.x - q.y * axis.y - q.z * axis.z,
            q.w * axis.x + q.x * w + q.y * axis.z - q.z * axis.y,
            q.w * axis.y + q.y * w + q.z * axis.x - q.x * axis.z,
            q.w * axis.z + q.z * w + q.x * axis.y - q.y * axis.x
        )
    }
}
else
{
    this.rotateQ = function(q, axis, angle) { return q.rotate(axis, angle); }
}
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Ahruman wrote:
Alternatively, here’s a fix for you:
Thanks, it is working. I should have thought myself at such a solution. Now the station is upright at the desired location and not just a random one.

Great.

This code will also be useful for other stations.

Code: Select all

this.grsStation = system.shipsWithPrimaryRole("repaired-buoy-station")[0];
let upVector = this.grsStation.orientation.vectorUp()
let angle = upVector.angleTo(this.grsVector)
let cross = upVector.cross(this.grsVector).direction()
let quaternion = this.rotateQ(this.grsStation.orientation, cross, -angle)
this.grsStation.setOrientation(quaternion)
I now aligned the discs of the GRS station to the surface and not the docking bay. Looks much better think.

EDIT: normalised cross vector
Last edited by Eric Walch on Wed May 21, 2008 5:42 pm, edited 1 time in total.
Post Reply