Page 4 of 4

Re: Station Defense Minigame

Posted: Sun Jun 03, 2012 4:54 am
by Wildeblood
Missed a bracket:
Capt. Murphy wrote:
if(station.hasRole("coriolisStationStationDefense"))

Re: Station Defense Minigame

Posted: Sun Jun 03, 2012 5:09 am
by Capt. Murphy
Thanks sharp-eyed-one (it's only just 6am here and I've had 3 hrs sleep - that's my excuse for typos and I'm sticking to it. :twisted: )

Re: Station Defense Minigame

Posted: Sun Jun 03, 2012 11:59 am
by Commander Xvyto
Okay, thanks guys. Its working now.

Re: Station Defense Minigame

Posted: Tue Jun 05, 2012 3:57 am
by Commander Xvyto
How do I ensure that a station is spawned even if the player quits the game and logs back out? Something like:

Code: Select all

if(!station)
    {
    spawnStation();
    }
/pseudocode
I believe it would be put in this.startUp().

Re: Station Defense Minigame

Posted: Tue Jun 05, 2012 6:32 am
by Commander McLane
Commander Xvyto wrote:
How do I ensure that a station is spawned even if the player quits the game and logs back out?
I don't think I understand at all what your question is.

If the player quits the game, the game doesn't run. Neither your station nor anything else exists while the game doesn't run. If you switch your computer off, it's off.

I don't believe that this is what you wanted to ask. Can you try to rephrase?

*********

On the off-chance that the question is about what the best place is for ship-spawning routines:

As so often, there are several possibilities, also depending on what you actually want.

First of all, in which system(s) would you like your station to be spawned? In each system? Randomly in half of all systems? Only in one specific system per Galaxy? Or only in one specific system in the whole Ooniverse?

For each of these cases the moment when the player jumps into a new system is the natural moment to check which system it is, and to spawn or not-spawn. Thus:

Code: Select all

this.shipWillExitWitchspace = function()
{
     // your spawning code
}
shipWillExitWitchspace is for all cases where the ship is supposed to be already there when the player comes in. If the NPC's entry shall be visible to the player, shipExitedWitchspace is the better choice. Although this matters only for NPCs spawned at the witchpoint, therefore it doesn't apply to your station anyway.

What about the system you start your game in? After loading you don't exit witchspace, thus the code above isn't executed. That's what shipWillLaunchFromStation and shipLaunchedFromStation are for. Just make sure that those are only executed after restarting the game, but not if shipWillExitWitchspace or shipWillExitWitchspace have been executed previously. Checking for the presence of your ship first in your spawning code is a good way to do that.

startUp is a good place for doing things that need to be done immediately after loading the game, like getting missionVariables from the save-game and storing them in JS-variables, or checking for the presence of other world scripts and interacting with them. It's not a good place for spawning ships for two reasons: (a) Do you really need your ships to be spawned immediately? The player is still docked and can't watch them anyway. He won't notice a difference to anything spawned when he launches. And (b) what sense does it make to spawn your ship only in the system in which the player happens to be when (re-)loading a game, but nowhere else? For most situations this makes no sense at all. For instance, extra stations are in most cases supposed to be, well, stationary. They are supposed to be reliably present in the same system at the same place, regardless whether the player happened to load in that system or just to pass by. Just imagine: you jump into a system. Your station isn't there. You dock with the main station, save your game, and call it a day. In your next session (which means that in-game no time has passed at all) there is suddenly a huge station in the system that wasn't there even a second (in-game time) ago, just because the player outside the game world decided to save the game and to continue it on the next evening. This makes no sense at all from an in-game perspective.

Re: Station Defense Minigame

Posted: Tue Jun 05, 2012 7:36 am
by cim
Commander McLane wrote:
Checking for the presence of your ship first in your spawning code is a good way to do that.

startUp is a good place for doing things that need to be done immediately after loading the game, like getting missionVariables from the save-game and storing them in JS-variables, or checking for the presence of other world scripts and interacting with them. It's not a good place for spawning ships for two reasons:
This is a strong case for using startUp instead of the launch functions - you can use startUp and shipWillExitWitchspace to place your ships without worrying if they're already there (because one or the other function will fire exactly one per system entry). Since 1.76 the system info is correctly in place when startUp runs, so you can do the same checks for "is this the right system" that you would do on launch before deciding to add the station.

It's true that startUp will add the station before the player can possibly interact with it, so shipWillLaunchFromStation is more efficient, but the efficiency gain is extremely marginal, so I think it's better to follow the easier coding practice, now that it can be done at all. I have seen bugs in a few OXPs with "addition on launch", even from experienced OXP authors.

shipLaunchedFromStation only fires when the player is granted flight control on exit from the docking tunnel, which is slightly too late to add ships, though if the ship is nowhere near the main station probably no-one will notice...

Re: Station Defense Minigame

Posted: Tue Jun 05, 2012 12:57 pm
by Commander Xvyto
I don't believe that this is what you wanted to ask. Can you try to rephrase?
What I meant was, if the player goes into the system with the special station, docks at the main station, saves, and exits oolite, the station won't still exist. This is because the station is spawned in this.shipExitedWitchspace. I was just wondering how I should add the code. I'm trying

Code: Select all

if(!system.shipsWithRole("coriolisStationStationDefense"))
            {
            system.addShips("coriolisStationStationDefense", 1, Vector3D(0, 0, 1.5).fromCoordinateSystem("psu"), 0);
            }
but I think the problem is that when system.shipsWithRole() returns, it either gives an empty array or the ships it finds, not null. However, there isn't a good way to see what the function returns when it does find a ship.

Re: Station Defense Minigame

Posted: Tue Jun 05, 2012 1:02 pm
by Capt. Murphy
You could use countShipsWithRole() instead which returns an integer, or check for system.shipsWithRole("coriolisStationStationDefense").length===0

Re: Station Defense Minigame

Posted: Tue Jun 05, 2012 1:03 pm
by Commander Xvyto
Ok, thanks. That seems like it would work.

Edit: Tested, it does indeed work. Thanks again.

Re: Station Defense Minigame

Posted: Tue Jun 05, 2012 1:04 pm
by Thargoid
If you add

Code: Select all

this.shipWillLaunchFromStation = function()
	{
	this.shipWillExitWitchspace();
	delete this.shipWillLaunchFromStation;
	}
to the script (presuming there isn't an existing use of the shipWillLaunchFromStation function) then when you first launch (ie just after loading a save game) the code in the shipWillExitWitchspace will fire. The launch function then self-deletes, so you don't get unwanted firings of it from subsequent launches.

If there is already a use of the function in the script, you can get around it in a similar fashion by setting a variable on first launch and then checking it on subsequent ones.[/color]

Re: Station Defense Minigame

Posted: Wed Jun 06, 2012 3:36 am
by Commander Xvyto
If I want to have an event triggered when a certain number of ships are killed:

a. What function would I put the code in? I don't see a player.killedShip();

b. would the code be something like this:

Code: Select all

var killArray = system.shipsWithRole("coriolisStationStationDefense");
var i=0
var specKills = 0
for(i, i<=7, i++)
    {
    if( ! killArray[i].isValid() )
        {
        specKills++;
        }
    }
if(specKills==7)
    {
    // Do stuff
    }

Re: Station Defense Minigame

Posted: Wed Jun 06, 2012 4:27 am
by Capt. Murphy
this.shipKilledOther = function(whom,damageType) in a worldScript is the event handler that fires when the player makes a kill (except with some OXP weapons). http://wiki.alioth.net/index.php/Oolite ... illedOther

There are a few problems with your code snippet, mostly with the use of local variables (var within a function limits the scope to the function) so each time the player kills something specKills will be reset to 0. If you need a variable to persist through a session and/or be accessible to several functions within the same script you should create it as an Object attached to your script (which is simple done by use of this.). Some example code below.

Code: Select all

this.shipKilledOther = function(whom,damageType)
{
if (whom.primaryRole !== "coriolisStationStationDefense"){return;}
if (!this.specKills) {this.specKills = 1;} else {this.specKills++;}
if (this.specKills >= 7)
{//do something}
}

Re: Station Defense Minigame

Posted: Wed Jun 06, 2012 8:34 am
by Commander McLane
The code from Capt. Murphy will however only trigger if the player kills the ship, not if anything else does it.

If you want to keep track of the number of ships killed, regardless of who the killer is, you can do that in the ships' ship script by using the shipDied handler.

The ship script itself disappears together with its ship, but one of the cooler features of JS-scripts is that they can interact with each other. Thus, when the shipDied handler in one of the ship scripts is triggered, it can manipulate a property of your world script. It can even trigger a self-defined function in your world script. So you can do this:

In your world script, create a property that counts kills, and a function that does stuff:

Code: Select all

this.startUp = function()
{
    this.specKills = 0;
}

this.$checkSpecKills = function()
{
    if(this.specKills >= 7)
    {
        // do stuff
    }
}
this.$checkSpecKills is not an official event handler, but a self-created function that you can use like an event handler by triggering it yourself. There's a convention to distinguish such self-created functions from "official" handlers by preceding their names with an "$". (This way you avoid the confusion that may arise if some day the developers create a new event handler that happens to be named exactly like a function you created yourself. This would result in your function being triggered each time the new handler fires, and not only if your code calls it, with predictably undesired results. However, the developers will never create a new handler that begins with "$", so you're safe if you use this "name space" for your own functions. Even if it's highly unlikely that there will ever be an event handler named "checkSpecKills", you should make this a habit from the get-go, because one day you may come up with a more generic sounding function name in one of your scripts.)

Now you need to create a ship script and attach it to the ship type(s) whose kills you want to count. You do that via the script key in shipdata, which takes the file name of the ship script as a value (including the ".js"). Your ship script would look like this:

Code: Select all

this.shipDied = function()
{
    worldScripts["yourWorldScriptName"].specKills ++;
    worldScripts["yourWorldScriptName"].$checkSpecKills();
}
"yourWorldScriptName" is the name that you defined in the this.name property at the beginning of your world script. If it doesn't contain special characters like "-", ".", or " ", you can simplify it to worldScripts.yourWorldScriptName.specKills.

worldScripts["yourWorldScriptName"] is what the this inside the world script is actually standing for. So there is no difference between using this inside a world script and worldScripts["worldScriptName"] outside that script. This way each one of the running scripts can access and manipulate every other script.

So, what your ship scripts do is to increment the specKills property in your world script, and to run the function in your world script that checks if it has already reached 7 or more. Now your stuff is done, independent of who killed the ships.

Re: Station Defense Minigame

Posted: Sat Nov 06, 2021 8:20 pm
by Cholmondely
Commander Xvyto wrote: Tue Jun 05, 2012 1:03 pm
Ok, thanks. That seems like it would work.

Edit: Tested, it does indeed work. Thanks again.
Did this ever see the light of day?