Missile Beep
Moderators: winston, another_commander
Missile Beep
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.
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.
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Missile Beep
Sweet! Seems to work fine, but threw a couple of these:
Code: Select all
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.
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
Re: Missile Beep
Thanks Commander.
Can you or someone help me out? I'm not that familiar with javascript.
This the function where the exception is thrown:
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:
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.
Can you or someone help me out? I'm not that familiar with javascript.
This the function where the exception is thrown:
Code: Select all
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();
}
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: Select all
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();
}
An updated OXP with the extra checks is here: oolite.oxp.hoqllnq.missile_beep-1.1.oxz
Thanks.
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Missile Beep
That seems to have disappeared the error messages - thanks! Cookies in the jar!
Of javascript, I know nothing!
Of javascript, I know nothing!
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
Re: Missile Beep
Wow, you're fast. Thank you for testing and confirming.
- ffutures
- ---- E L I T E ----
- Posts: 2172
- Joined: Wed Dec 04, 2013 12:34 pm
- Location: London, UK
- Contact:
Re: Missile Beep
Do the beeps speed up as it gets closer? That would be a lovely bit of ambience.
- Diziet Sma
- ---- E L I T E ----
- Posts: 6312
- Joined: Mon Apr 06, 2009 12:20 pm
- Location: Aboard the Pitviper S.E. "Blackwidow"
Re: Missile Beep
Seconded! That would be very useful, as well as inducing a slight sense of panic in the player!
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
Re: Missile Beep
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: Select all
// 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;
}
}
Last edited by hoqllnq on Mon Mar 27, 2017 9:45 pm, edited 1 time in total.
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Missile Beep
Cool!
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
- ffutures
- ---- E L I T E ----
- Posts: 2172
- Joined: Wed Dec 04, 2013 12:34 pm
- Location: London, UK
- Contact:
Re: Missile Beep
Is this on the manager yet, or only manual install?
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Missile Beep
Currently manual only, I believe - and damned useful kit it is too!
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
Re: Missile Beep
I shall go through the steps outlined in the all-in-one guide to add it to the wiki and the manger.
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Missile Beep
It'd be a good idea to update the first post with the latest version too.
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!
Re: Missile Beep
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.
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.
- Cody
- Sharp Shooter Spam Assassin
- Posts: 16081
- Joined: Sat Jul 04, 2009 9:31 pm
- Location: The Lizard's Claw
- Contact:
Re: Missile Beep
All is good - thanks.
I would advise stilts for the quagmires, and camels for the snowy hills
And any survivors, their debts I will certainly pay. There's always a way!
And any survivors, their debts I will certainly pay. There's always a way!