Scripters cove

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

Moderators: winston, another_commander

User avatar
JeffBTX
---- E L I T E ----
---- E L I T E ----
Posts: 366
Joined: Sun Dec 27, 2009 2:23 pm
Location: Abilene Texas

Post by JeffBTX »

I kind of hate to ask this, but I need help. I really would rather do the research and figure it out, but there are not enough resources; and the resources that are there can be confusing.

I've been through the Wiki (information there is definitive and specific, but there are no tutorials to "tie things together").

I've searched through the forums using keywords.

I've tried studying the BGS OXP, but it is too sophisticated for the simple thing that I want to do; there seems to be a lot of OXPConfig-associated code in it, and I can't seperate what is "basically essential" from what would be, for me, superfluous. The JS in it is beyond my capability to understand. I can't see how the sounds are linked to the sound events; BGS seems to be "structured around" OXPConfig, and the JS statements are not "direct enough, simple enough" to fully understand.

I just need to script 5 sound events.

(1) Ambient - engine running. STOPS looping when throttle is at zero.

(2) Throttle the engine up (Will "replace" ambient engine running when initiated -> Leads to -> ambient engine running).

(3) Throttle the engine down (Will "replace" ambient engine running when initiated -> Leads to -> ambient engine running if throttle is NOT at zero. Otherwise if throttle reaches zero, ambient engine running = stopped).

(4) Exit from witchspace. NOTE that a "breakpattern" sound is currently linked in my customsound.plist:

Code: Select all

"[player-exit-witchspace]" = "[@breakpattern]";
(5) One sound to be looped whenever / while docked at any station. (not "station music" per se, though it could work LIKE it... it will be ambient sound whenever docked... a fairly low volume level loop / sound effects).

There are currently 19 sounds linked in my customsounds.plist (all working just fine).

EDIT:

... and one more. Can there be a specific link for when the Torus Drive is running?
Sword, thy name is Cobra. And Cobra has fangs!
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 »

If you want to permanently change sounds, you don't need to bother with JS. Simply change the soundfile names in customsounds.plist (or create different soundfiles with the same names as the default ones).

customsounds.plist is among the resources used by the game and can be found in the same place as all the other resources: Oolite/Contents/Resources/Config/.

As usual, it is not advised to directly alter the resource. Instead c&p the customsounds.plist wholesale into your AddOns folder (you can create a Config folder inside the AddOns folder if it doesn't yet exist). Then you can edit the copy. It will override the original (that's how OXPs work).

You only need to find and alter the entries related to the events you mentioned. The entries are understandably named, so that shouldn't be a problem.
User avatar
JeffBTX
---- E L I T E ----
---- E L I T E ----
Posts: 366
Joined: Sun Dec 27, 2009 2:23 pm
Location: Abilene Texas

Post by JeffBTX »

Yes, I've already done that; I've created an OXP with \Config\customsounds.plist, and a \Sounds folder with custom sounds in it.

The 6 events that I noted above have to be scripted (the 5 I mentioned, plus one that I added... Torus Drive). (At least I assume they have to be scripted... the default customsounds.plist doesn't list, say, engine running or throttle up).
Sword, thy name is Cobra. And Cobra has fangs!
User avatar
Svengali
Commander
Commander
Posts: 2370
Joined: Sat Oct 20, 2007 2:52 pm

Post by Svengali »

JeffBTX wrote:
I've tried studying the BGS OXP, but it is too sophisticated for the simple thing that I want to do; <snip>
Damn, you know how to catch ppl. Sophisticated! Argh! And even more Argh! because it works.
Hmm - sophisticated... doesn't sound bad... hmm... i thought more along the lines 'what a mess'... but hey .-)

If I remember right you are progging assembler, so you are familiar with splitting big ideas into pieces. It's the same in Oolite. Let's start with Engine up/down and we can build up on this one then. You'll need a Timer, a SoundSource and 2 properties to store the speed/mode and, yes, two soundfiles .-)

Code: Select all

this.name = "Workshop_EngineSounds";
this.author = "Svengali";
this.copyright = "Public Domain";
this.description = "Funny engine up and down.";
this.version = "1.0";

this.startUp = function()
{
	this.myTimer = new Timer(this,this.doMyTimer,0,0.5);
	this.myTimer.stop();
	this.myEngineFX = new SoundSource;
	this.myEngineFX.loop = false;
	this.mySpeed = 0;
	this.currentFXMode = 0;
}
this.doMyTimer = function()
{
	var s = player.ship.speed;
	if(s > this.mySpeed) this.changeFX(1,"workshop_EngineUp.ogg");
	else if(s < this.mySpeed) this.changeFX(-1,"workshop_EngineDown.ogg");
	return;
}
this.changeFX = function(mode,what)
{
	if(this.myEngineFX.isPlaying){
		this.mySpeed = player.ship.speed;
		if(mode === this.currentFXMode) return;
	}
	this.myEngineFX.sound = what;
	this.myEngineFX.play();
	this.currentFXMode = mode;
	return;
}
this.shipWillLaunchFromStation = function()
{
	this.myTimer.start();
}
this.shipWillDockWithStation = function()
{
	this.myTimer.stop();
}
User avatar
JeffBTX
---- E L I T E ----
---- E L I T E ----
Posts: 366
Joined: Sun Dec 27, 2009 2:23 pm
Location: Abilene Texas

Post by JeffBTX »

Svengali;

:lol:
... at your 1st 2 statements.

your 3rd and 4th statements: Good Memory! And correct...

The code; Yes! Between the code you posted, and comparing to BGS to learn implementation, and finding what I can find on the Wiki, I think I can work with that.

Thanks! VERY MUCH appreciated!
Sword, thy name is Cobra. And Cobra has fangs!
User avatar
JeffBTX
---- E L I T E ----
---- E L I T E ----
Posts: 366
Joined: Sun Dec 27, 2009 2:23 pm
Location: Abilene Texas

Post by JeffBTX »

Just to follow my reasoning here... I hope I am on the right track...

I finally navigated (stumbled on to) useful sections on the wiki; also, with that code snippet, I now know how to interpret them better (learn from them, make use of them).

(And others thinking the same thing might make use of this)

=====

speed (as in player.speed)

speed : Number (read-only)

The ship’s current speed.

See also: maxSpeed

=====

To implement a "Torus Drive Sound Event";

=====

maxSpeed (as in player.maxSpeed?)
(check; this IS implemented in 1.74.2?)

maxSpeed : Number (read-only)

The ship’s maximum speed under normal power. Note that speed may exceed this when witch fuel injectors or hyperspeed are in use.
(hyperspeed = "Torus Drive"?)

See also: speed

=====

I guess when checking for player.speed > player.maxSpeed, I have to do some experiments to determine the difference between fuel injectors and hyperspeed.

IF I want different sounds for fuel injectors (afterburner1.ogg) and the Torus Drive.

Hmmm.

At this point, we DO know that different player ships (Cobra Mk III versus Big Heavy Anaconda) have different speeds.

I don't know for CERTAIN if different player ships have different fuel injector speeds or Torus Drive Speeds. I'm guessing that IF they are different, there is a percentage involved... maybe fuel injectors = 125% (just as an example), Torus Drive = 500% (just as an example).

Too bad that SHFT-F -> FPS Counter doesn't give velocities...
What is the difference between the abs coordinates and the "pwm" coordinates?
NevermindFounditIThink... p=Planet=Origin / w=Witchpoint=ZAxis / m=units=meters

SO....

FIRST, (when I get around to it), I'll make a "little utility OXP" that displays the player.speed and the player.maxSpeed; try them with different ships, w/ fuel injectors and at hyperspeed, and explore this. Which WILL involve learning how to display a message on the screen while in flight (or even while docked too... doesn't matter).

What Fun.

UNLESS; there is an easier way to do this... a section on the Wiki I haven't found yet. Probably not, it would probably be on this page, and it isn't:
http://wiki.alioth.net/index.php/Oolite ... ence:_Ship

If I am way off base, then, this.player isBoulder

HungryNow.
SandwichAndCoffee.
Sword, thy name is Cobra. And Cobra has fangs!
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 »

JeffBTX wrote:
I guess when checking for player.speed > player.maxSpeed, I have to do some experiments to determine the difference between fuel injectors and hyperspeed.
it is player.ship.speed and player.ship.maxSpeed.

player.ship is a subset of ship. player.ship contains also all the properties listed under ship. So sometimes you think there is missing something but than its listed under ship. And both are subsets of Entity, so all those properties are valid for ship or player.ship also.

By head, gives fuel-injection 7x maxSpeed. And hyperspeed something about 32x.
User avatar
JeffBTX
---- E L I T E ----
---- E L I T E ----
Posts: 366
Joined: Sun Dec 27, 2009 2:23 pm
Location: Abilene Texas

Post by JeffBTX »

Eric;

Thanks, yes, just a typo / lack of proofreading on my part re: player.ship.speed / player.ship.maxSpeed.

So, if those off-the-top-of-your-head figures are close to correct;

A script could test for player.ship.speed >= , say, 16x player.ship.maxSpeed to test if the Torus Drive is engaged, (and if not) then, say, >= 4x player.ship.maxSpeed to see if the fuel injectors are engaged. Should work with a margin of error, or account for "unknown anomalies" (shrug). Or if you are very sure of those figures... say, about, 24x for Hyperspeed and 5x for fuel injectors. Still leaves a margin of error / breathing space for gremlins.

Yay!
:idea:
Sword, thy name is Cobra. And Cobra has fangs!
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5528
Joined: Thu Jun 12, 2008 6:55 pm

Post by Thargoid »

The 7x figure is certainly correct, and the other one looks about right too. The scripting in Hired Guns uses something similar to allow the escorts to keep up with the player ship when they use injectors or the torus drive.

Both are fixed multipliers, so there's no need for any approximation.
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 just looked it up:

Code: Select all

#define HYPERSPEED_FACTOR				32.0
It is 32 x maxSpeed. No need for guessing. But a player ship has to accelerate / decelerate to get those speeds. Therefor, there will be a short period were the speed is lower. At least you are sure when the speed is above 7 x maxSpeed, the ship is in hyper-speed mode.
User avatar
JeffBTX
---- E L I T E ----
---- E L I T E ----
Posts: 366
Joined: Sun Dec 27, 2009 2:23 pm
Location: Abilene Texas

Post by JeffBTX »

Thargoid/Eric;

Thank you for the info, that will help.

I think I will take a look at "Hired Guns", I might learn a few things.
Sword, thy name is Cobra. And Cobra has fangs!
User avatar
Lestradae
---- E L I T E ----
---- E L I T E ----
Posts: 3095
Joined: Tue Apr 17, 2007 10:30 pm
Location: Vienna, Austria

..

Post by Lestradae »

While hacking together a "Buy a Cockpit" meta-HUD-oxp, I encounter a problem and don't get what's wrong.

My script looks similar to this (original is longer):

Code: Select all

this.alertConditionChanged = function(newCondition, oldCondition)
   {
   switch(newCondition)
      {
      case 0: // we're docked set the docked HUD
         {
         player.ship.hud = "kwtradinghud.plist";
         break;
         }
      case 1: // we're at green alert
         {
         if(player.ship.energy > 63) // if we're not using the damaged HUD set the standard HUD
            {
            if(missionVariables.CockpitBought = null)
                {
                player.ship.hud = "hud.plist";
                }
        if(player.ship.hasEquipment("EQ_ASPEXP_HUD"))
                {
                player.ship.hud = "aspexp-hud.plist";
                }
        if(player.ship.hasEquipment("EQ_ASPMKI_HUD"))
                {
                player.ship.hud = "aspmk1-hud.plist";
                }
        if(player.ship.hasEquipment("EQ_ASPMKII_HUD"))
                {
                player.ship.hud = "aspmk2-hud.plist";
                }
        if(player.ship.hasEquipment("EQ_AVONDALE_HUD"))
                {
                player.ship.hud = "avondale-hud.plist";
                }
            }
         break;
         }
      case 2: // or we're at yellow alert
         {
         if(player.ship.energy > 63) // if we're not using the damaged HUD set the standard HUD
            {
            if(missionVariables.CockpitBought = null)
                {
                player.ship.hud = "hud.plist";
                }
        if(player.ship.hasEquipment("EQ_ASPEXP_HUD"))
                {
                player.ship.hud = "aspexp-hud.plist";
                }
            }
         break;
         }
      case 3: // we're at red alert
         {
         if(player.alertHostiles && player.ship.energy > 63) // and under attack and not using the damaged HUD
            {
            player.ship.hud = "kwcombathud.plist"; // set the combat HUD
            }
         break;
         }
      }
   }

this.playerBoughtEquipment = function(equipment)
        {
        switch(equipment)
                {
                case "EQ_ASPEXP_HUD":
                        {
                        player.ship.hud = "aspexp-hud.plist";
                        missionVariables.CockpitBought = 1;
                        return;
                        }
                case "EQ_ASPEXP_HUD_SALE":
                        {
                        player.ship.hud = null;
                        player.ship.removeEquipment("EQ_ASPEXP_HUD");
                        player.ship.removeEquipment("EQ_ASPEXP_HUD_SALE");
                        missionVariables.CockpitBought = null;
                        player.credits += 310;
                        return;
                        }
                case "EQ_ASPMKI_HUD":
                        {
                        player.ship.hud = "aspmk1-hud.plist";
                        missionVariables.CockpitBought = 1;
                        return;
                        }
                case "EQ_ASPMKI_HUD_SALE":
                        {
                        player.ship.hud = null
                        player.ship.removeEquipment("EQ_ASPMKI_HUD");
                        player.ship.removeEquipment("EQ_ASPMKI_HUD_SALE");
                        missionVariables.CockpitBought = null;
                        player.credits += 310;
                        return;
                        }
                case "EQ_ASPMKII_HUD":
                        {
                        player.ship.hud = "aspmk2-hud.plist";
                        missionVariables.CockpitBought = 1;
                        return;
                        }
                case "EQ_ASPMKII_HUD_SALE":
                        {
                        player.ship.hud = null
                        player.ship.removeEquipment("EQ_ASPMKII_HUD");
                        player.ship.removeEquipment("EQ_ASPMKII_HUD_SALE");
                        missionVariables.CockpitBought = null;
                        player.credits += 310;
                        return;
                        }
                case "EQ_AVONDALE_HUD":
                        {
                        player.ship.hud = "avondale-hud.plist";
                        missionVariables.CockpitBought = 1;
                        return;
                        }
                case "EQ_AVONDALE_HUD_SALE":
                        {
                        player.ship.hud = null
                        player.ship.removeEquipment("EQ_AVONDALE_HUD");
                        player.ship.removeEquipment("EQ_AVONDALE_HUD_SALE");
                        missionVariables.CockpitBought = null;
                        player.credits += 310;
                        return;
                        }
                }
        }

this.shipLaunchedFromStation = function()
   {
   if(this.energyCheckTimer)
      {
      this.energyCheckTimer.start()
      }
   else
      {
      this.energyCheckTimer = new Timer(this, this.energyCheck,0,2)      // use a timer to keep an eye on the HUD state
      }
   }


this.energyCheck = function()
   {
   if(player.ship.docked)
      {
      this.energyCheckTimer.stop();
      }
   else
      {
      if(player.ship.energy < 64 )
         {
         player.ship.hud = "kwsnafuhud.plist"; // display the damaged HUD
         return;
         }
      if(player.ship.energy > 63 && player.ship.hud == "kwsnafuhud.plist")
         {
         this.alertConditionChanged(player.alertCondition,0); // if energy is >49 and we're still displaying the damaged HUD, use other code to repair
         }
      }
   }

this.shipDied = function()
   {
   if(this.energyCheckTimer)
      {
      this.energyCheckTimer.stop()
      }
   }
The idea is that you can buy HUDs like cockpits, and that the HUDs change whether you are docked, in combat, ship damaged, condition etc. etc. I hacked that part from Thargoid's and Killerwolf's scripts for that.

I modified this HUD-switch-scripts with the idea that if no HUD is bought a standard is used, and if a specific HUD/Cockpit was bought this is used instead - i.e. in a combat situation without a bought HUD the "standard combat HUD" is used, if the "ASPEXP Cockpit" was bought the "ASPEXP combat HUD" is used and so on.

With the above script, though, HUDs keep on switching when they shouldn't and not switching back when they should in patterns I don't get.

I assume I did something wrong with the nesting of commands?

Glad if should someone help out/explain/clarify/find the problem

L
User avatar
Lestradae
---- E L I T E ----
---- E L I T E ----
Posts: 3095
Joined: Tue Apr 17, 2007 10:30 pm
Location: Vienna, Austria

..

Post by Lestradae »

Anyone? No? Anyone ... :(
User avatar
Thargoid
Thargoid
Thargoid
Posts: 5528
Joined: Thu Jun 12, 2008 6:55 pm

Post by Thargoid »

Code: Select all

if(missionVariables.CockpitBought = null)
should be

Code: Select all

if(missionVariables.CockpitBought == null)
or perhaps even === . You've probably got several cases of = in an if statement there, and if you look in your log file (which you of course did when things failed, didn't you?) you should see some warnings about the use of = where you should have ==.

Your script can also be optimised somewhat. For example rather than checking energy level for each alert condition within the switch, do it at the start before you switch. Similarly rather than using the huge banks of if statements, there also replace those by the switch statement like is already present in my original parts of the code.

Also .hasEquipment is depreciated. Better is to check using player.ship.equipmentStatus("EQ_WHATEVER") == "EQUIPMENT_OK" or player.ship.equipmentStatus("EQ_WHATEVER") != "EQUIPMENT_UNAVAILABLE".

The first one will be true if the equipment is present and operational, the second true if the equipment is present (either operational or broken). See the wiki for details.

Lastly in this.playerBoughtEquipment you're using return; where you should be using break; within each of the case statements.
User avatar
Lestradae
---- E L I T E ----
---- E L I T E ----
Posts: 3095
Joined: Tue Apr 17, 2007 10:30 pm
Location: Vienna, Austria

..

Post by Lestradae »

Thanks T, will do as you say :D

(I knew about the deprecations, but wanted the script to work first and change to the new, non-deprecated version later)
Post Reply