Just when I thought I was out...

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

Moderators: winston, another_commander

Post Reply
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post 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?)?
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. 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.
Last edited by JensAyton on Sun Mar 09, 2008 2:09 pm, edited 1 time in total.
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 »

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
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post by Roberto »

Thanks guys - I'll give it a try after lunch :)
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 »

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.
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 »

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;
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post 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... :)
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 »

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. :-)
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 »

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...
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
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 »

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*
User avatar
Roberto
---- E L I T E ----
---- E L I T E ----
Posts: 318
Joined: Sun Jun 11, 2006 1:16 pm
Location: London, UK

Post 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? :)
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 »

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.
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 »

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.
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 »

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?
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
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 »

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.)
Post Reply