Page 6 of 11

Posted: Sun Mar 09, 2008 1:34 pm
by Roberto
Damn - I've run into the old "getting a ship to spawn something" issue again!

Basically, how can I get an NPC ship to launch a barrel on command (i.e. from its own AI)?

Things I've tried so far:

"spawnShip: barrel"
"ejectItem: barrel"
"ejectItem: barrel 1"
"ejectItem: cargopod"
"ejectItem: cargopod 1"

Does spawnShip require there to be a "spawn" entry (describing position and facing) in the barrel's shipdata? Do I need to use sendScriptMessage again (and if so, what goes in the script?)?

Posted: Sun Mar 09, 2008 1:51 pm
by JensAyton
Hmm. It looks like you’d need to use the call() method:

Code: Select all

this.spitOutCargoCanister = function ()
{
    this.call("ejectItem:", "barrel");
}
(The legacy equivalent is “ejectItem: barrel”, but I think that’ll only work in ship foo_actions.)
I’ll add a native JS ejectItem() for 1.71.

Edit: however, on further consideration this won’t do what you want since the barrel won’t get the ship’s cargo. To do that, you want to call dumpCargo, which should work from an AI.

(I do hereby declare that dumpCargo is a sanctioned AI method, unless it doesn’t work, in which case it isn’t.)

dumpCargo will not do anything if (a) the ship has no cargo or (b) the ship has dumped cargo in the last 0.5 seconds.

Posted: Sun Mar 09, 2008 1:54 pm
by Kaks
this is the way I'd do it.

First put the function ejectStuff inside the ship js script:

Code: Select all


this.ejectStuff=function(){
	this.ship.call('spawn:', 'barrel 1');
}
then call ejectStuff from the ai with sendScriptMessage.

Hope this helps! :)

edit Ahruman, you're too fast! :D

Posted: Sun Mar 09, 2008 2:08 pm
by Roberto
Thanks guys - I'll give it a try after lunch :)

Posted: Sun Mar 09, 2008 2:11 pm
by JensAyton
Kaks wrote:
this.ship.call('spawn:', 'barrel 1');
Surely you mean system.legacy_spawn… oh, wait, you don’t because it’s broken in ways that are now completely obvious. It should of course be ship.legacy_spawn. Bah.

Edit: also read edit to previous post.

Posted: Sun Mar 09, 2008 3:23 pm
by JensAyton
I’ve added dumpCargo(), ejectItem() and ejectSpecificItem() JavaScript methods. Note that ejectSpecificItem(), not ejectItem(), is the equivalent of the legacy ejectItem: method.

These are nice modern methods, not legacy wrappers, so they return the ejected item (if any). As a trivial example, this helpful macro causes the player’s target to eject an item, and immediately targets it:

Code: Select all

:setM stealCargo this.cargo = player.target.dumpCargo(); if (this.cargo) player.target = this.cargo;

Posted: Sun Mar 09, 2008 5:40 pm
by Roberto
Qapla'! After trying everything else (I got some exciting error messages for ejectItem, which I guess can't be applied to NPC ships), I found the combination that works:

Code: Select all

this.ejectbarrel = function ()
{
	system.legacy_spawn("cargopod", 1);
}
I didn't go for dumpCargo, as I'm having this ship eject barrels and then use them for target practice! The barrel didn't last long... :)

Posted: Sun Mar 09, 2008 6:11 pm
by JensAyton
So create a Target Drone entity. ;-)

(Actually, I’d expect that to look a lot like the Buoy, only smaller and with a different colour scheme. The nav bouys appear to be based on corner reflectors, as used for making things easy to spot on radar, among other uses.)

Legacy_spawn has proven problematic. In 1.71 I’ll probably make it a ship method instead (so in your case it would be ship.legacy_spawn()) and remove the system version completely. I think that’ll address the problems with it.

Welcome to the joys of using an unstable scripting interface. :-)

Posted: Sun Mar 09, 2008 6:18 pm
by Kaks
Yep, system.legacy_spawn seems to add entities next to the player, not next to the spawning ship... in here, svengali did say he had a problem or two with that function...

Posted: Sun Mar 09, 2008 6:38 pm
by JensAyton
Yeah, but I didn’t understand the problem then on account of being an idiot. Oh, and also not having much clue as to how most of the script methods are actually used. Anyway, unless someone points out something else I’ve missed, I’ll make it a Ship method and hunky-doriness shall ensue. *waits for Eric to point out something I’ve missed*

Posted: Sun Mar 09, 2008 7:48 pm
by Roberto
Ah, that explains what I've been seeing!

I've had a look at that thread, and it's a bit over my head to be honest. OK, a lot over my head! :) Is there a reliable workaround (to correct instances where objects are spawned near the player), or should I just leave things as they are until 1.71?

Also, I'm assuming I don't have to have an entry such as this...

Code: Select all

<key>spawn</key>
<dict>
      <key>facing_position</key>
      <string>spu 0 0 0</string>
      <key>position</key>
      <string>wpu 0 0 0.2</string>
</dict>
...in my barrel's shipdata code, as it's designed for spawning stuff in a fixed position (not necessarily where the ship doing the spawning is). Or am I wrong? :)

Posted: Sun Mar 09, 2008 8:01 pm
by JensAyton
I’m not aware of a workaround.

The issue is that spawned ships are positioned relative to the “legacy scripting target”. The legacy scripting target when executing legacy ship actions is the ship, but the legacy scripting target for system.legacy_spawn() is the player.

Posted: Sun Mar 09, 2008 8:10 pm
by Eric Walch
Roberto wrote:
Also, I'm assuming I don't have to have an entry such as this...
...in my barrel's shipdata code, as it's designed for spawning stuff in a fixed position (not necessarily where the ship doing the spawning is). Or am I wrong? :)
NO. A bit confusing sometimes, I also have to look back at earlier scripts for the correct syntax.
"spawn" and "spawnShip" are two completely different commands. The first needs a role and works like other ship adding commands. The second needs a name and a "spawndirectory" and should only be used in rare events for very accurate placement and orientation of ships.

Posted: Sun Mar 09, 2008 8:27 pm
by Kaks
Roberto wrote:
Is there a reliable workaround (to correct instances where objects are spawned near the player), or should I just leave things as they are until 1.71?
As far as I know, this.ship.call('spawn:', 'barrel 1'); inside the NPC ship script should work reliably, that's why I suggested it. Do you get errors with that?

Posted: Sun Mar 09, 2008 9:03 pm
by JensAyton
Kaks is almost correct; that should work, except it takes a role (i.e., “cargopod”) rather than a ship name. (If you use that particular role, it also takes pains to ensure the resulting pod has cargo in it.)

I’ve added Ship.spawn() and Ship.spawnOne() for 1.71. The distinction is that the first takes an optional count and returns an array of ships, while the latter does not take a count and just returns a ship. For your particular usage, this probably doesn’t matter.

I don’t like the name “spawn”, though. All the methods that create ships “spawn” them, in game terminology. Right now I can’t think of a better alternative than addShipsExtremelyNear(). (Extremely near is right, though; it adds a ship inside the collision radius of the parent ship, which might cause your ship to randomly blow up. I believe spawn: is intended to be used to replace a ship with something else when it dies, as in the cloaking device mission.)