Oolite Bulletins

For information and discussion about Oolite.
It is currently Fri Nov 24, 2017 12:05 am

All times are UTC




Post new topic  Reply to topic  [ 15 posts ] 
Author Message
 Post subject: Missile Beep
PostPosted: Sun Mar 26, 2017 6:58 pm 
Offline
Commodore
Commodore
User avatar

Joined: Sun Jan 08, 2006 7:32 pm
Posts: 148
Greetings Commanders,

Today, I made my first OXP: Missile Beep.
(Edit: updated v1.3 here.)
(Another edit: link updated to point to the file on the wiki. This OXP is now available in the in-app OXP manager.)


It plays high pitched beeps whenever a missile is targeted at the player.

It is extremely small & simple, but it got me to look into what it takes to make a working OXP.
If the OXP is installed, it will just work. It is not buyable equipment. So I categorised it as Ambience.
Everything is based on what I saw in other OXPs.

Please let me know what I've omitted, done wrong, or could improve.

Thanks.


Last edited by hoqllnq on Wed May 17, 2017 5:42 pm, edited 4 times in total.

Top
   
 Post subject: Re: Missile Beep
PostPosted: Sun Mar 26, 2017 7:07 pm 
Offline
Sharp Shooter Spam Assassin
Sharp Shooter Spam Assassin
User avatar

Joined: Sat Jul 04, 2009 9:31 pm
Posts: 12924
Location: Corke's Drift
Sweet! Seems to work fine, but threw a couple of these:
Code:
20:05:43.672 [script.javaScript.exception.unexpectedType]: ***** JavaScript exception (Missile Beep 1.0): TypeError: things is undefined
20:05:43.672 [script.javaScript.exception.unexpectedType]:       ../AddOns/oolite.oxp.hoqllnq.missile_beep.oxz/Scripts/missile_beep.js, line 31.

_________________
The only good fnord is a dead fnord!


Top
   
 Post subject: Re: Missile Beep
PostPosted: Sun Mar 26, 2017 8:01 pm 
Offline
Commodore
Commodore
User avatar

Joined: Sun Jan 08, 2006 7:32 pm
Posts: 148
Thanks Commander.

Can you or someone help me out? I'm not that familiar with javascript.

This the function where the exception is thrown:
Code:
this._timer_hook = function()
{
	var things = player.ship.checkScanner(true);
	
	for (var i = 0;i < things.length;i++)	// <-- this is line 31
	{
		if (things[i].isMissile && things[i].target == player.ship)
		{
			this._sound_source.play();
			return;
		}
	}
	
	if (this._sound_source.isPlaying)
		this._sound_source.stop();
}
I was guessing that this happens when the scanner is empty, and checkScanner() returns null. (And therefor I can not reference its 'length' member.) I tested this, but I don't get this exception when my scanner is empty. Do you know when/why it happens / how to reproduce it?

After some more testing, I was able to get this exception by killing myself. So maybe at that time, player == null or player.ship == null?

Adding the following extra checks gets rid of the exception in the suicide case:
Code:
this._timer_hook = function()
{
	var things;
 
	if (player && player.ship)
	{
		things = player.ship.checkScanner(true);
		
		if (things)
		{
			for (var i = 0;i < things.length;i++)
			{
				if (things[i].isMissile && things[i].target == player.ship)
				{
					this._sound_source.play();
					return;
				}
			}
		}
	}
	
	if (this._sound_source.isPlaying)
		this._sound_source.stop();
}
Is this the correct solution? Is my line of thinking correct as to why? Or is it overkill?

An updated OXP with the extra checks is here: oolite.oxp.hoqllnq.missile_beep-1.1.oxz

Thanks.


Top
   
 Post subject: Re: Missile Beep
PostPosted: Sun Mar 26, 2017 8:09 pm 
Offline
Sharp Shooter Spam Assassin
Sharp Shooter Spam Assassin
User avatar

Joined: Sat Jul 04, 2009 9:31 pm
Posts: 12924
Location: Corke's Drift
That seems to have disappeared the error messages - thanks! Cookies in the jar!

Of javascript, I know nothing!

_________________
The only good fnord is a dead fnord!


Top
   
 Post subject: Re: Missile Beep
PostPosted: Sun Mar 26, 2017 8:21 pm 
Offline
Commodore
Commodore
User avatar

Joined: Sun Jan 08, 2006 7:32 pm
Posts: 148
Wow, you're fast. Thank you for testing and confirming.


Top
   
 Post subject: Re: Missile Beep
PostPosted: Sun Mar 26, 2017 10:13 pm 
Offline
---- E L I T E ----
---- E L I T E ----
User avatar

Joined: Wed Dec 04, 2013 12:34 pm
Posts: 952
Location: London, UK
Do the beeps speed up as it gets closer? That would be a lovely bit of ambience.


Top
   
 Post subject: Re: Missile Beep
PostPosted: Sun Mar 26, 2017 11:06 pm 
Offline
---- E L I T E ----
---- E L I T E ----
User avatar

Joined: Mon Apr 06, 2009 12:20 pm
Posts: 6241
Location: Aboard the Pitviper S.E. "Blackwidow"
Quote:
Do the beeps speed up as it gets closer? That would be a lovely bit of ambience.
Seconded! That would be very useful, as well as inducing a slight sense of panic in the player! :twisted:

_________________
Most games have some sort of paddling-pool-and-water-wings beginning to ease you in: Oolite takes the rather more Darwinian approach of heaving you straight into the ocean, often with a brick or two in your pockets for luck. ~ Disembodied


Top
   
 Post subject: Re: Missile Beep
PostPosted: Mon Mar 27, 2017 12:06 pm 
Offline
Commodore
Commodore
User avatar

Joined: Sun Jan 08, 2006 7:32 pm
Posts: 148
Quote:
Do the beeps speed up as it gets closer? That would be a lovely bit of ambience.
In this update, they do: oolite.oxp.hoqllnq.missile_beep-1.2.oxz

The previous version would check for incoming missiles once a second, and if one was found, play a 0.5 second beep.

To make the beep speed depend on missile distance, I had to change "everything":
* Rather than detecting just any incoming missile, I now have to find the nearest one.
* Calculate a beep-interval based on the distance to the nearest incoming missile.
* Register a FCB to turn the beep on/off when the beep-interval has expired.

It now plays 1 beep per second when the missile is at the edge of the scanner range, 10 bps when distance is zero. Maybe these numbers need some tweaking. The 'duty cycle' is always 50%, i.e. the duration of the beeps is half the period.


Edit to add:

And here is version 1.3 --> oolite.oxp.hoqllnq.missile_beep-1.3.oxz
Functionality is the same as V1.2, but I made some code changes. Hopefully improvements...

* Lower the timer interval to 0.5 sec. while missiles are present, so that the change in beeping speed is smoother. (Put it back to 1 sec. when no more incoming missiles are around.)
* Added shipAttackedWithMissile() event handler that calls the timer hook when an incoming missile is fired, so beeping starts immediately instead of at the next timer interval.

This is the entire thing:
Code:
// This is the world script for Missile Beep OXP
"use strict";
this.name        = "Missile Beep";
this.description = "Missile Beep World Script";
this.version     = "1.3";
this.author      = "hoqllnq";
this.copyright   = "2017 hoqllnq";
this.licence     = "CC-BY-NC-SA 3.0";

this._timer = null;         // To periodically check for incoming missiles
this._fcb = null;           // To time the beeps
this._sound_source = null;  // To play the beeps
this._beep_time = 0;        // How long beep (or silence) has been playing
this._beep_interval = 0;    // How long beep (or silence) should last
this._beep_on = false;      // Currently beeping?

this._debug = false;        // Logging


// Initialize the timer and the sound source
this.startUp = function()
{
    if (!this._timer)
    {
        this._timer = new Timer(this, this._timer_hook.bind(this),1,1);
    }
    
    if (!this._sound_source)
    {
        this._sound_source = new SoundSource();
        this._sound_source.loop = false;
        this._sound_source.sound = "[missile_beep]";
    }
    
    if (this._debug)
        log(this.name,"Started");
}

// A missile was fired at us, it could be the nearest one,
// don't wait for timer to fire, call timer hook now to check
this.shipAttackedWithMissile = function(missile,whom)
{
    if (this._debug)
        log(this.name,"Missile fired");
    
    this._timer_hook();
}

// Periodic check for presence and distance of incoming missiles
this._timer_hook = function()
{
    var things;
    var dist;
 
    if (player && player.ship)
    {    // Find all missiles in scanner range
        things = system.entitiesWithScanClass("CLASS_MISSILE",player.ship,25600);
        
        // See if any of them are targeted at us
        for (var i = 0;i < things.length;i++)
        {
            if (things[i].target == player.ship)
            {    // Yes.
                // This is the nearest one, since the list is ordered by distance
                dist = things[i].position.distanceTo(player.ship.position);
                if (this._debug)
                    log(this.name,"Missile at " + dist);
                
                // Beep duration based on distance
                this._beep_interval = 0.05 + dist / 51200.0;
                
                // If we weren't beeping yet, start now
                if(!isValidFrameCallback(this._fcb))
                {
                    this._fcb = addFrameCallback(this._fcb_hook.bind(this));
                    this._timer.interval = 0.5;
                }
                
                return;
            }
        }
    }
    
    // No incoming missiles
    // If we were beeping, stop now.
    if (isValidFrameCallback(this._fcb))
    {
        if (this._debug)
            log(this.name,"No more incoming missiles");
        
        removeFrameCallback(this._fcb);
        this._timer.interval = 1.0;
    }
    
    if (this._sound_source.isPlaying)
        this._sound_source.stop();
    
    this._beep_time = 0;
    this._beep_on = false;
}

// Frame callback to turn beep on/off
// This does the timing for the beeping speed
this._fcb_hook = function(delta)
{
    this._beep_time += delta;
    
    // Time for next beep/silence?
    if (this._beep_time < this._beep_interval)
        return; // No.
    
    // Reset time
    this._beep_time -= this._beep_interval;
    
    // Toggle beep
    if (this._beep_on)
    {
        if (this._sound_source.isPlaying)
            this._sound_source.stop();
        
        this._beep_on = false;
    }
    else
    {
        if (this._debug)
            log(this.name,"Beep!");
        
        if (!this._sound_source.isPlaying)
            this._sound_source.play();
        
        this._beep_on = true;
    }
}
I'm happy with how it works. Testing / playing around with it, I found it quite useful. When you fire at another ship, get the 'incoming missile' warning, but no beeping, you know you've already shot the missile, no need for ECM. Conversely, when multiple ships fire multiple missiles, and you hit your ECM, and the beeping continues, then you know it's time to ECM some more and make evasive manoeuvres. Unless there are problems (or really good ideas), I will leave it like this. It fulfils its original purpose, which was continuous alert for incoming missiles, and with the variable beeping speed (thanks cmdr. ffutures!) it does it even nicer than I originally envisioned.


Last edited by hoqllnq on Mon Mar 27, 2017 9:45 pm, edited 1 time in total.

Top
   
 Post subject: Re: Missile Beep
PostPosted: Mon Mar 27, 2017 12:16 pm 
Offline
Sharp Shooter Spam Assassin
Sharp Shooter Spam Assassin
User avatar

Joined: Sat Jul 04, 2009 9:31 pm
Posts: 12924
Location: Corke's Drift
Cool!

_________________
The only good fnord is a dead fnord!


Top
   
 Post subject: Re: Missile Beep
PostPosted: Fri May 12, 2017 10:22 pm 
Offline
---- E L I T E ----
---- E L I T E ----
User avatar

Joined: Wed Dec 04, 2013 12:34 pm
Posts: 952
Location: London, UK
Is this on the manager yet, or only manual install?


Top
   
 Post subject: Re: Missile Beep
PostPosted: Fri May 12, 2017 11:17 pm 
Offline
Sharp Shooter Spam Assassin
Sharp Shooter Spam Assassin
User avatar

Joined: Sat Jul 04, 2009 9:31 pm
Posts: 12924
Location: Corke's Drift
Currently manual only, I believe - and damned useful kit it is too!

_________________
The only good fnord is a dead fnord!


Top
   
 Post subject: Re: Missile Beep
PostPosted: Sat May 13, 2017 3:52 pm 
Offline
Commodore
Commodore
User avatar

Joined: Sun Jan 08, 2006 7:32 pm
Posts: 148
I shall go through the steps outlined in the all-in-one guide to add it to the wiki and the manger.


Top
   
 Post subject: Re: Missile Beep
PostPosted: Sat May 13, 2017 3:53 pm 
Offline
Sharp Shooter Spam Assassin
Sharp Shooter Spam Assassin
User avatar

Joined: Sat Jul 04, 2009 9:31 pm
Posts: 12924
Location: Corke's Drift
It'd be a good idea to update the first post with the latest version too.

_________________
The only good fnord is a dead fnord!


Top
   
 Post subject: Re: Missile Beep
PostPosted: Wed May 17, 2017 7:26 pm 
Offline
Commodore
Commodore
User avatar

Joined: Sun Jan 08, 2006 7:32 pm
Posts: 148
This OXP is now available in the manager. It's in the Ambience category.
Edited the first post to state this, and to add a link to the current version for manual installation.
I've also added it to the sortable list. Are there more steps I should take?
Thanks.


Top
   
 Post subject: Re: Missile Beep
PostPosted: Wed May 17, 2017 8:50 pm 
Offline
Sharp Shooter Spam Assassin
Sharp Shooter Spam Assassin
User avatar

Joined: Sat Jul 04, 2009 9:31 pm
Posts: 12924
Location: Corke's Drift
All is good - thanks.

_________________
The only good fnord is a dead fnord!


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 27 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
cron
Powered by phpBB® Forum Software © phpBB Limited