Page 1 of 2

Berth Control for OXP authors

Posted: Tue Jan 21, 2014 1:43 pm
by Smivs
Following Paradox's suggestion here I'm starting this thread so that we might build up a library of small, useful scripts that OXP authors may draw on. Many authors are not very strong on js (ha, I count myself among these and still consider myself a novice!) so these could be useful, and also it might avoid others needlessly re-inventing the wheel.
So, my first contribution...


Edited to re-purpose this thread - as Commander McLane points out further down there is a place for scripting examples elsewhere, and as you will see this thread becomes a very interesting discussion in its own right.

Passenger Berth Script

This script is to allow a ship to have a number of 'permanent' passenger berths fitted - berths that cannot be removed - while allowing extra berths to be bought and sold. When the last 'removeable' berth is sold, a console message confirms that it is the last removeable berth and warns against trying to remove the permanent ones. If an attempt is made to remove a permanent berth a console message points out that it cannot be removed. About 25 minutes of game-time is lost while the technicians confirm this, but the permanent berth remains in place and there is no cost to the player.

For this to work, you will need to specify the number of permanent berths in the shipyard.plist as 'standard equipment' thus:-

Code: Select all

        
"standard_equipment" =
                               {
                               extras =
                                           ( 
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH"
                                           );
                                  };
This example gives five permanent berths, and of course you might want to add other equipment and missiles etc.
DO NOT list "EQ_PASSENGER_BERTH" in the "optional_equipment" section of the shipyard.plist.

Next you will need to refer to the script in the shipdata.plist thus:-

Code: Select all

script = "Smivs'_passenger_berth_script.js";
Then add the script below to the Scripts folder of your OXP - copy and paste it into your text editor and save as "Smivs'_passenger_berth_script.js" (without the quote marks).

Code: Select all

/*jslint white: true, undef: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */

"use strict";

// Standard attributes 
this.name           = "Smivs'_passenger_berth_script.js"; 
this.author         = "Smivs"; 
this.copyright      = "This script is hereby placed in the public domain."; 
this.version        = "1.0"; 
this.description    = "script to prevent sale of 'permanent' passenger berths, and keep a tally of any 'normal' berths bought to allow their sale."; 


this.playerBoughtNewShip = function(ship)
// starts counter, and sets berth count to zero when ship is bought ('Permanent' berths are ignored)
{
  if(ship.name === "shipName")
    {
      if (!missionVariables.passengerBerth_count)
        {
          missionVariables.passengerBerth_count = 0;
        }
    }
}
this.playerBoughtEquipment = function(equipment)
// adds +1 to counter when a non-permanent berth is bought
{
  if (equipment == "EQ_PASSENGER_BERTH")
    {
      missionVariables.passengerBerth_count++;
    }
// allows non-permanent berths to be removed, and reduces counter by -1 for each removal
  if (equipment == "EQ_PASSENGER_BERTH_REMOVAL" && missionVariables.passengerBerth_count > 1)
    {
      missionVariables.passengerBerth_count--;
      return;
    }
// when final non-permanent berth is removed, adds warning about permanent berths.
  else if (equipment == "EQ_PASSENGER_BERTH_REMOVAL" && missionVariables.passengerBerth_count === 1)
    {
      missionVariables.passengerBerth_count--;
      player.consoleMessage("There are no more removeable berths. Do not attempt to remove the Permanent Berths.",5);
      return;
    }
// effectively prevents removal of permanent berths
  else if (equipment == "EQ_PASSENGER_BERTH_REMOVAL" && missionVariables.passengerBerth_count === 0)
    {
      player.ship.awardEquipment("EQ_PASSENGER_BERTH");
      player.consoleMessage("The Permanent Passenger Berth could not be removed.",5);
      player.credits += 100;
    }
}
In line 16

Code: Select all

  if(ship.name === "shipName")
you will need to insert the display name of your new ship as it appears in the shipdata.plist in place of "shipName". This is the "name = XXX" line of shipdata, not the identifier name at the head of the shipdata entry for the ship.

I hope this will be useful to some of you.

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 2:08 pm
by dertien
Awesome Smivs, I will put this to good use on the playable version of my orbital shuttle. Thank you.

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 2:20 pm
by Commander McLane
"Building up a library of small, useful scripts that OXP authors may draw on" is exactly the purpose of the Scripters cove sticky. Thus I propose to move the original post of this thread into the sticky.

Yes, the scripters' cove has become clogged, blurred, and derailed several times over. However, the same thing is going to happen to this (and any other "library of …"-) thread anyway. And it's still easier to find resources in one thread than it is to find them in several threads.

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 2:39 pm
by Smivs
Commander McLane wrote:
"Building up a library of small, useful scripts that OXP authors may draw on" is exactly the purpose of the Scripters cove sticky. Thus I propose to move the original post of this thread into the sticky.

Yes, the scripters' cove has become clogged, blurred, and derailed several times over. However, the same thing is going to happen to this (and any other "library of …"-) thread anyway. And it's still easier to find resources in one thread than it is to find them in several threads.
Ha, yes perhaps they should be merged although the truth is I think the Scripters Cove thread got well and truly derailed on the first page which is probably why myself (and others?) didn't actually realise its intended function. But you are right that this thread will probably share the same fate :roll:
And my title is better anyway as it does what it says! 8)

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 7:02 pm
by Nyarlatothep
Hi, I've recently downloaded Oolite 1.77, & Oolite-trunk, and I'm really interested in programming. I've got a few ideas that might eventually become OXPs in the fullness of time, but I'm not yet sure when.

Smivs, thank you very much for the example, it was very useful, the Oolite specific stuff can be quite a lot to take in.
There's still a ton of events and properties I'm trying to figure out & stuff like this is really helpful, rather than trying to understand the inner workings of a whole OXP in one go. I've started reading through the documentation, even though I almost missed out the 'how to make OXP' link tucked at the very bottom of the OXP page in the wiki!

But I digress!


Using your example as a starting point, and using the goodness of script_info, I've added the possibility of purchasing a ship with a mixture of permanent & removable passenger berths, and removed the need to check for the ship name from inside the script.

Ok, here goes nothing:

Passenger Berth Script (tweaked)

Specify the number of permanent berths in the shipyard.plist as 'standard equipment' thus:-

Code: Select all

"standard_equipment" =
                               {
                               extras =
                                           ( 
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH",
                                            "EQ_PASSENGER_BERTH"
                                           );
                                  };
This example gives five permanent berths, and of course you might want to add other equipment and missiles etc.
You can now add "EQ_PASSENGER_BERTH" to the "optional_equipment" section of the shipyard.plist, which will allow ships for sale with a mixture of permanent and removable berths.

Next you will need to refer to the script in the shipdata.plist thus:-

Code: Select all

script = "Smivs'_passenger_berth_script.js";
script_info = 
                {
                minBerths = 5;
                }
NB: If you put less "EQ_PASSENGER_BERTH"s inside the extras than the number of minBerths inside script_info, you might be able to buy a ship with less than the specified minBerths. In that case, the number of permanent berths will be automatically adjusted to the number of berths you had at the time of purchase.

Then add the script below to the Scripts folder of your OXP - copy and paste it into your text editor and save as "Smivs'_passenger_berth_script.js" (without the quote marks).

Code: Select all

/*jslint white: true, undef: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */

"use strict";

// Standard attributes 
this.name           = "Smivs'_passenger_berth_script.js"; 
this.author         = "Smivs, Nyarlatothep"; 
this.copyright      = "This script is hereby placed in the public domain."; 
 this.version        = "1.1"; 
this.description    = "script to prevent sale of 'permanent' passenger berths, and keep a tally of any 'normal' berths bought to allow their sale."; 


this.playerBoughtNewShip = function(ship)
// set removable berth count when ship is bought
{
  // do we have min berths defined in shipyard.plist and does it contain a valid value (an integer greater than zero)?
  if (ship.scriptInfo.minBerths && ship.scriptInfo.minBerths === parseInt(ship.scriptInfo.minBerths) && ship.scriptInfo.minBerths > 0)
  {
    var i = 0;  // count berths at time of purchase
    for (var e = 0; e < ship.equipment.length; e++)
    {
        if (ship.equipment[e].equipmentKey === "EQ_PASSENGER_BERTH") i++;
    }
    if (i === 0)
    {
        //  no berths when purchased? no permanent berths, by definition
       missionVariables.minBerths_removableBerths =  null;
    }
    else
    {
        //  find out how many of the berths at purchase can actually be removed
        i = i - ship.scriptInfo.minBerths;
        //  make sure we don't have a negative amount of removable berths 
        missionVariables.minBerths_removableBerths =  i < 0 ? 0 : i;
    }
  }
  else
  {
     missionVariables.minBerths_removableBerths =  null;
  }
}

this.playerBoughtEquipment = function(equipment)
{
  if (missionVariables.minBerths_removableBerths === null)
     {
        // no minBerths mission variable? all berths are removable, do nothing
        return;
     }
  
  if (equipment == "EQ_PASSENGER_BERTH")
    {
      missionVariables.minBerths_removableBerths++;  // update counter
    }

  if (equipment == "EQ_PASSENGER_BERTH_REMOVAL")
    {
      if (missionVariables.minBerths_removableBerths > 0)
         {
            missionVariables.minBerths_removableBerths--;  // update counter

           // when last non-permanent berth is removed, adds warning about permanent berths.
           if (missionVariables.minBerths_removableBerths === 0)
              {
                 player.consoleMessage("There are no more removable Passenger Berths left. Do not attempt to remove Permanent Berths.",5);
              } 
         }
       else  //  no removable berths left when trying to sell berths - effectively prevents removal of permanent berths
         {
             //  refund removal price using the equipmentInfo value (.price is in decicredits!) & re-equip berth
             player.credits += (EquipmentInfo.infoForKey("EQ_PASSENGER_BERTH_REMOVAL").price / 10);
             player.ship.awardEquipment("EQ_PASSENGER_BERTH");
             //  inform the captain
             player.consoleMessage("Permanent Passenger Berths cannot be removed.",5);
         }
    }

}

Hope this helps!

I'm a firm believer of the belt & braces school of programming, so I've added a few extra bits that 'might' be a bit excessive. However, provided I haven't made any SNAFU, this tweaked script & .plist method should be quite robust, & not too prone to clashing with other scripts / OXPs, including ones that reprice standard equipment.

Smivs: talking about SNAFUs, I've got the horrible feeling I might well have missed something obvious, and/or made some silly copy/paste mistake somewhere, so it's more than likely that I broke your perfectly working script.
Sorry about that!

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 7:27 pm
by Smivs
Hi Nyarlatothep, and welcome. Great first post!
Nyarlatothep wrote:
Smivs: talking about SNAFUs, I've got the horrible feeling I might well have missed something obvious, and/or made some silly copy/paste mistake somewhere, so it's more than likely that I broke your perfectly working script.
Sorry about that!
Ha, I don't know if it works or not, but it all looks impressive - I confessed to my Novice status above, and some of your additions are probably a little beyond me right now. The concept is interesting though, although I did wonder how the player would know the mix of permanent and temporary berths when they bought the ship?
Of course the proof of any pudding is in the testing...have you tried the script?

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 7:36 pm
by Paradox
Smivs script allows you to "hard code" berths into your ship, with the possibility to add and remove only the additional berths if desired. But lets say you don't feel adding more berths should be an option on your ship. Cim came up with a solution that will block the ability to add and remove passenger berths altogether for just that particular ship, and yet still allows you to "hard code" them into your ship if you need them. First thing you need to do is cut an past the following into a new text file:

Code: Select all

(
	( /* Passenger Compartment, like missiles this can be bought multiple times */
		5, 8250, "Passenger Berth - takes up 5t of cargo space",
		"EQ_PASSENGER_BERTH",
		"Provides life support, entertainment and comfort for a single passenger.",
		{
			available_to_all = false;
			available_to_NPCs = false;
			condition_script = "type_unique_name_here-conditions.js";
			requires_cargo_space = 5;
			damage_probability = 0;
		}
	),
	( /* Passenger Compartment Removal */
		1, 1000, "Remove Passenger Berth - reclaims 5t of cargo space",
		"EQ_PASSENGER_BERTH_REMOVAL",
		"Removes a passenger berth.",
		{
			available_to_all = true;
			available_to_NPCs = false;
			condition_script = "type_unique_name_here-conditions.js";
			requires_free_passenger_berth = true;
		}
	),
)	
Change type_unique_name_here-conditions.js, to something unique to you, like johns-conditions.js or whatever... Remember this name because your going to use it in just a second!

Now save that into your Config folder as equipment.plist.

Now, make a Scripts folder in your ships oxp folder, and inside, make a new text file, and name it with the name I just told you to remember (johns-conditions.js or whatever-conditions.js etc...)! Then paste the following into it:

Code: Select all

this.name = "Passenger berth conditions";

this.allowAwardEquipment = function(equipment, ship, context)
{
   // OXP hook to allow stations to forbid specific equipment
   if (context == "purchase" && player.ship.dockedStation && player.ship.dockedStation.scriptInfo["oolite-barred-equipment"])
   {
      if (player.ship.dockedStation.scriptInfo["oolite-barred-equipment"].indexOf(equipment) != -1)
      {
         return false;
      }
   }

   if (context == "purchase" && ship.scriptInfo.MyCustomKey == "fixed")
   {
      return false;
   }

   // otherwise allowed
   return true;
}
On line 14, if (context == "purchase" && ship.scriptInfo.MyCustomKey == "fixed"), change MyCustomKey, and give it a unique name like JohnsBerths or ImConfused etc, and remember it because we are going to use it in just a minute! }:]

okay, almost done! The last thing you need to do is open your shipdata.plist in your Config folder. In the section that defines the player version of your ship, add the following:

Code: Select all

script_info = 
	{
	"MyCustomKey" = "fixed";
	};
Change MyCustomKey to whatever I just told you to remember a second ago! };] JohnsBerths or ImConfused or whatever you called it... I usually try to add things in there alphabetically so I squeezed mine inbetween roles = "player"; and view_position_aft = " ";. And that should be it, start the game buy your new ship, and see if the option to add or remove passenger berths are available!

Thanks again to Cim and Smivs for all the work they have been doing to help me!

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 8:16 pm
by Paradox
Mr. Smivs, I don't have a clue as to what was happening before, but I just tried your newest version, and it worked like a charm!
I did make one small alteration, because when I bought an extra berth, then sold it, your message reads
"There are no more removable Passenger Berths left. Do not attempt to remove Permanent Berths."
"Umm.. did I just sell one or what?!?" So I went and checked, and it did indeed sell the extra one, it's just the message that was a bit obscure..
So, I changed the message in line 41 to say "Berth removed. There are no more removeable berths. Do not attempt to remove the Permanent Berths.".
Tiny change, but it makes things clearer I think.

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 8:23 pm
by Paradox
@Nyarlatothep
Testing yours now! };]

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 8:24 pm
by Nyarlatothep
Paradox, wow, that oolite-barred-equipment thing looks very interesting!
As well as what you used it for, it should be possible to incorporate that concept to my 1.1 tweak to just show 'remove berths' as an option if missionVariables.minBerths_removableBerths > 0

I'll need some time to look into it properly!


And Smivs, you're too kind. I've got a feeling I'll end up picking your brains a lot more than you'll be picking mine!
About figuring out how many berths are permanent, changing

Code: Select all

    else
    {
        //  find out how many of the berths at purchase can actually be removed
        i = i - ship.scriptInfo.minBerths;
        //  make sure we don't have a negative amount of removable berths
        missionVariables.minBerths_removableBerths =  i < 0 ? 0 : i;
    }
to

Code: Select all

    else
    {
        //  confirm the actual number of permanent berths
        var p =  ship.scriptInfo.minBerths;
        if (p > i) p = i;
        player.consoleMessage( (p ===  i ? "The " + p : p + " of the" ) + " Passenger Berth" + (i === 1 ? "" : "s") + " that came with the ship cannot be removed.",5);
        
        //  save the nr of removable berths for later
        missionVariables.minBerths_removableBerths =  i  - p;
    }
would do the trick.

But I fear I now have to chew over paradox's info & come up with another tweak once I know what I'm doing.
Thanks! :)

Re: Useful scripts for OXP authors

Posted: Tue Jan 21, 2014 8:47 pm
by Paradox
Nyarlatothep wrote:
Paradox, wow, that oolite-barred-equipment thing looks very interesting!
That is all Cim baby! I am soooo not a coder. I can look at some of it, and grasp the general concept of what it is doing (sometimes), but that's about it! I am strictly a vertex and pixel jockey. };]

BTW you need to change:

Code: Select all

	script_info = 
                {
                minBerths = 5;
                }
To:

Code: Select all

	script_info = 
                {
                minBerths = 5;
                };
Notice the ; after the last }. It would'nt load the ship without that. };] (Nasty little syntaxes!) Ship now loads, but it's not working, added 2 berths to the original 4, then sold them as well as all the originals... Might be something I did wrong (again!) so I will go trouble shot some more!

P.S. This started with THIS in case you were interested. }:]

Re: Berth Control for OXP authors

Posted: Tue Jan 21, 2014 8:57 pm
by Smivs
Thread re-named and re-purposed - see first post for more details. :)

Re: Berth Control for OXP authors

Posted: Tue Jan 21, 2014 9:01 pm
by cim
There is a second oolite-barred-equipment use in 1.79, incidentally: you'll be able to set

Code: Select all

script_info = {
  "oolite-barred-equipment" = (
    "EQ_PASSENGER_BERTH",
    "EQ_PASSENGER_BERTH_REMOVAL"
  );
};
in shipdata.plist to make passenger berths completely unavailable for that ship. (Or any other equipment item normally available_to_all)

Re: Berth Control for OXP authors

Posted: Tue Jan 21, 2014 9:33 pm
by Paradox
Smivs wrote:
Thread re-named and re-purposed - see first post for more details. :)
OMG that is too funny!!!! Love the name! :lol: :lol: :lol:

As for spending hours sifting through 70 pages of "stuff" looking for nuggets in that thread.... Well, I am just glad you kept this one out here! };] I think I will go before I say anymore... };]

Re: Berth Control for OXP authors

Posted: Tue Jan 21, 2014 10:30 pm
by Smivs
I know what you mean. There is probably lots of useful stuff in Scripters Cove, but how are you supposed to find it? I was thinking exactly the same earlier, and wondering if something could be done to make the information more accessible. Maybe I'll have a think!

As for the name, well, I couldn't really call it anything else, could I? :D