Back to Index Page generated: Sep 1, 2025, 4:12:03 AM

Expansion HyperRadio 2

Content

Warnings

  1. http://wiki.alioth.net/index.php/HyperRadio%202 -> 404 Not Found
  2. Low hanging fuit: Information URL exists...
  3. Required Expansions mismatch between OXP Manifest and Expansion Manager at character position 0061 (DIGIT ZERO vs LATIN SMALL LETTER N)
  4. No version in dependency reference to oolite.oxp.Svengali.Library:null
  5. No version in dependency reference to oolite.oxp.Svengali.GNN:null
  6. No version in dependency reference to oolite.oxp.Svengali.Hyperradio:null
  7. Conflict Expansions mismatch between OXP Manifest and Expansion Manager at character position 0064 (DIGIT ZERO vs LATIN SMALL LETTER N)

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Your personal tool for playing music in the game. Depends on Library and GNN, suggests Musicpacks. Your personal tool for playing music in the game. Depends on Library and GNN, suggests Musicpacks.
Identifier oolite.oxp.Svengali.HyperRadio2 oolite.oxp.Svengali.HyperRadio2
Title HyperRadio 2 HyperRadio 2
Category Equipment Equipment
Author Svengali, phkb Svengali, phkb
Version 2.0 2.0
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
  • oolite.oxp.Svengali.Library:0
  • oolite.oxp.Svengali.GNN:0
  • oolite.oxp.Svengali.Library:
  • oolite.oxp.Svengali.GNN:
  • Optional Expansions
    Conflict Expansions
  • oolite.oxp.Svengali.Hyperradio:0
  • oolite.oxp.Svengali.Hyperradio:
  • Information URL http://wiki.alioth.net/index.php/Hyperradio_js_OXP n/a
    Download URL https://wiki.alioth.net/img_auth.php/4/40/HyperRadio_2.0.oxz n/a
    License CC BY-NC-SA 3.0 CC BY-NC-SA 3.0
    File Size n/a
    Upload date 1754288551

    Documentation

    readme.txt

    HyperRadio 2.0
    by phkb and Svengali
    
    Overview
    ========
    Trading goods between worlds is an extremely dangerous and hard job and a commander will need some relaxing moments. Listen to your radio station and enjoy Jazz, Folk, Rock or whatever you like. Use one station for all systems or expand it, so you will get different programs in different systems. You can even add your own music to the playlist. So rip your CDs, download songs, or install one or more of the available musicpacks. Everything is possible - and travelling will be much more fun - even 'milkruns' won't be boring business anymore. And with the capacity to be expanded by other users creating their own musicpacks it will always be the right investment. 
    
    HyperRadio 2.0 is an update to the original, which now exclusively uses Library Music for playing music. Music packs loaded into Library music as "radio" stations will become available to HyperRadio 2.0 as selectable stations.
    
    Operation
    =========
    The standard 60 day licence for HyperRadio can be purchased at any TL8 station for 1200cr. Renewing the licence for another 60 days costs just 800cr.
    
    To operate the equipment, first prime it by using the "Shift-N" key combination. Once primed, it can be turned on and off using the "Activate" key (usually "n" on the keyboard). To change stations, used the "Mode" key (usually "b" on the keyboard). 
    
    Compatibility
    =============
    HyperRadio 2.0 is *not* compatible with HyperRadio 1.x. If you have the previous version installed, you will need to remove it in order to install v2.0. However, if you had previously purchased a HyperRadio licence, it should transfer over to version 2.0 without any additional purchases.
    
    HyperRadio 2.0 is compatible with event driven music packs (for example, the "Contextual Jukebox" mod). While playing a radio station, the event driven music will be suspended. Turning off the radio will re-engage the event driven music. In the event of a red alert, the radio will be turned off and the event driven music will be engaged. When the red alert condition is cleared, the radio will automatically restart.
    
    Requirements
    ============
    The only requirement for this OXP is Library OXP.
    
    Music packs
    ===========
    To create a music pack that can be included as one of the selectable radio stations, do the following:
    
    1. Create an OXP folder structure. You will need a "Config" folder, and a "Music" folder in the OXP folder.
    
    2. Copy all your music tracks into the "Music" folder.
    
    3. Create a "script.js" file in the "Config" folder, and add the following code:
    
        "use strict";
        this.name = "hyperradioMYSTATION";
    
        this.startUpComplete = function () {
            worldScripts.Lib_Music._addChannel({
                name: "My Radio Station", radio: true, sounds: [ // << change the name in this line
                    { snd: "hyperradio-exampleA.ogg", dur: 28 }, // for each track, enter the filename inside the quotes, and enter the duration of the track after "dur:"
                    { snd: "hyperradio-exampleB.ogg", dur: 13 }
                ]
            });
        }
    
    4. Create a "manifest.plist" file in the root folder of your OXP. Add text similar to the following:
    
        {
            identifier = "oolite.oxp.name.MyHyperRadioStation"; // change the name and OXP keyname
            required_oolite_version = "1.90";                   // leave this as is
            title = "HyperRadio TYPE - Sample Music";           // change the title as required
            version = "1.0";                                    // if this is the first version, leave this as is. Change this value if an update is released.
            category = "Ambience";                              // leave this as is
            description = "This is a sample music pack";        // change this as required
            author = "name";                                    // put your name/handle here
            information_url = "http://wiki.alioth.net/index.php/Hyperradio_Musicpacks"; // leave this as is
            license = "CC BY-NC-SA 4.0";                        // you can change the license if required, but in most cases this should be suitable
            requires_oxps = (                                   // leave this section as is.
                { identifier = "oolite.oxp.Svengali.Library"; }
            );
        }
    
    When you've finished, you should have a folder structure that looks something like this:
    
        MyHyperRadioStation.oxp
        ├── manifest.plist
        ├── Config
        |   └── script.js
        └── Music
            ├── hyperradio-exampleA.ogg
            └── hyperradio-exampleB.ogg
    
    You should now be able to select your radio station through Hyper Radio 2.0
    
    Licence
    =======
    This OXP is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
    
    Version History
    ===============
    2.0 
    - Initial release
    

    Equipment

    Name Visible Cost [deci-credits] Tech-Level
    HyperRadio™ yes 12000 8+
    HyperRadio™ yes 8000 1+
    HyperRadio™ Social yes 1000 1+

    Ships

    This expansion declares no ships. This may be related to warnings.

    Models

    This expansion declares no models. This may be related to warnings.

    Scripts

    Path
    Scripts/hyperradio2.js
    "use strict";
    this.name = "hyperradio2";
    this.author = "Svengali";
    this.copyright = "(C)2008-2025, License:CC-by-nc-sa-3.0";
    this.description = "Musicplayer. Expandable by musicpacks.";
    this.version = "2.0";
    
    this.currentChannel = expandDescription("[hyper_off]");
    this.currentChannelIndex = -1;
    this.savedChannelIndex = 0;
    this.allowPirateRadio = false;
    this.allowLicenseExtension = false;
    this.canPlay = false;
    this.licenseLength = 60; // increase this value to make subscription last longer
    // note, though, that you should also change the description in equipment.plist to match.
    this.logging = false;
    this.showNews = true;
    this.news = 0;
    this.vNews = 31;
    this.testing = false;
    this.tempDisabled = false;
    
    this.startUp = function () {
    	delete this.startUp;
    
    	this.libMain = worldScripts.Lib_Main._lib;
    	this.libMusic = worldScripts.Lib_Music;
    	this.hyperRadio = false; // true if installed and license is valid
    	if (missionVariables.hyperradio_last) this.hyperradioDuration = parseInt(missionVariables.hyperradio_last, null);
    	else this.hyperradioDuration = 0;
    
    	if (missionVariables.hyperradio_news) {
    		var tmp = missionVariables.hyperradio_news.split("|");
    		this.news = parseInt(tmp[0], null);
    		this.sysA = tmp[1];
    		this.sysB = tmp[2];
    		this.vNews = 15 + parseInt(this.news, null);
    	}
    }
    
    this.startUpComplete = function () {
    	this.libMusic._addChannel({
    		name: "GalaxyRadio 2.0", radio: true, sounds: [
    			{ snd: "hyperradio-exampleA.ogg", dur: 28 },
    			{ snd: "hyperradio-exampleB.ogg", dur: 13 }
    		]
    	});
    }
    
    this.playerWillSaveGame = function () {
    	missionVariables.hyperradio_last = this.hyperradioDuration;
    	missionVariables.hyperradio_licenseLength = this.licenseLength;
    	if (this.news) missionVariables.hyperradio_news = this.news + "|" + this.sysA + "|" + this.sysB;
    	this.saved = true;
    }
    
    this.shipLaunchedFromStation = function () {
    	if (this.CheckHyperradioLicense() == true) {
    		this.checkSwitch = new Timer(this, this.switchTimer.bind(this), 1, 1);
    	}
    }
    
    this.shipDockedWithStation = this.shipDied = function () {
    	if (this.checkSwitch && this.checkSwitch.isRunning) this.checkSwitch.stop();
    	this.CheckHyperradioLicense();
    }
    
    this.shipWillLaunchFromStation = function () {
    	this.allowLicenseExtension = false;
    	if (player.ship.equipmentStatus("EQ_HYPER_RADIO") === "EQUIPMENT_OK") {
    		if (system.isInterstellarSpace || this.tempDisabled) {
    			this.canPlay = false;
    			return;
    		}
    		this.canPlay = true;
    		this.hyperRadio = true;
    		this.SelectHyperradioStation();
    	}
    }
    
    this.playerBoughtEquipment = function (equipmentKey) {
    	if (equipmentKey == "EQ_HYPER_RADIO") {
    		this.hyperRadio = true;
    		this.hyperradioDuration = Math.floor(this.licenseLength + clock.days);
    		this.allowLicenseExtension = true;
    		return;
    	}
    	if (equipmentKey == "EQ_HYPER_RADIO_ADD") {
    		this.hyperRadio = true;
    		this.hyperradioDuration += this.licenseLength;
    		player.ship.removeEquipment("EQ_HYPER_RADIO_ADD");
    		this.allowLicenseExtension = false;
    		return;
    	}
    	if (equipmentKey == "EQ_HYPER_RADIO_PIRATE") {
    		this.hyperRadio = true;
    		player.ship.removeEquipment("EQ_HYPER_RADIO_PIRATE");
    		player.ship.awardEquipment("EQ_HYPER_RADIO");
    		this.allowPirateRadio = false;
    		this.hyperradioDuration += Math.ceil(this.licenseLength / Math.log(system.government + 2.1));
    		this.news = 0;
    		return;
    	}
    }
    
    this.equipmentDamaged = function (equipmentKey) {
    	if (equipmentKey === "EQ_HYPER_RADIO") {
    		this.canPlay = false;
    		this.failPlay(1);
    	}
    }
    
    this.shipExitedWitchspace = function () {
    	if (this.logging) log(this.name, this.name + ": clock:" + (clock.days & 31) + " vNews:" + this.vNews);
    	//this.tempDisabled = false;
    	if (this.hyperRadio) {
    		if (system.isInterstellarSpace) {
    			this.currentChannel = "Off";
    			this.currentChannelIndex = -1;
    			this.libMusic.$E0 = 0;
    			this.libMusic._buildList();
    			this.failPlay(1);
    			player.consoleMessage("HyperRadio deactivated. Could not transfer data.", 8);
    			this.canPlay = false;
    			return;
    		} //else this.SelectHyperradioStation();
    		this.canPlay = true;
    	}
    	if (!this.showNews || system.isInterstellarSpace) return;
    	if (this.news) {
    		if (this.news === 4) {
    			var a = System.systemIDForName(this.sysA);
    			var b = System.systemIDForName(this.sysB);
    			if (!this.allowPirateRadio && (system.ID === a || system.ID === b)) {
    				this.allowPirateRadio = true;
    				this.news = 0;
    				return;
    			} else this.allowPirateRadio = false;
    		} else if (this.news === 3) {
    			this.news = 0;
    			return;
    		}
    	}
    	if (this.news) return;
    	if ((clock.days & 31) === this.vNews || this.testing == true) {
    		this.allowPirateRadio = false;
    		var a = Math.random();
    		if (a > 0.5) {
    			this.sysA = System.systemNameForID(Math.floor(Math.random() * 255));
    			this.sysB = System.systemNameForID(Math.floor(Math.random() * 255));
    			var obj;
    			if (this.hyperRadio) {
    				if (a > 0.9) {
    					this.news = 2;
    					obj = { Message: "[HYPERRADIO2_NEWSA]", Pic: "hyperradio_news.png", Music: "GNN.ogg", Model: "snoopers_gcnewsA1", Pos: [57, 36, 170] };
    				} else if (a > 0.8) {
    					this.news = 3;
    					obj = { Message: "[HYPERRADIO2_NEWSD]", Agency: 1 };
    				} else {
    					this.news = 4;
    					obj = { Message: "[HYPERRADIO2_NEWSE] " + this.sysA + " and " + this.sysB + " [HYPERRADIO2_NEWSE2]", Agency: 3 };
    				}
    			} else {
    				if (a > 0.7) {
    					if (a > 0.9) {
    						this.news = 1;
    						obj = { Message: "[HYPERRADIO2_NEWSB]", Pic: "hyperradio_news.png", Music: "GNN.ogg", Model: "snoopers_gcnewsA1", Pos: [57, 36, 170] };
    					} else {
    						this.news = 4;
    						obj = { Message: "[HYPERRADIO2_NEWSE] " + this.sysA + " and " + this.sysB + " [HYPERRADIO2_NEWSE2]", Agency: 3 };
    					}
    				} else {
    					this.news = 5;
    					obj = { Message: "[HYPERRADIO2_NEWSC] " + this.sysA + " and " + this.sysB + " in this sector. [HYPERRADIO2_NEWSC2]", Agency: 2 };
    				}
    			}
    			if (this.logging) log(this.name, this.name + ": New event:" + this.news);
    			obj.ID = this.name;
    			obj.CB = this.name + ".newsDisplayed";
    			var b = worldScripts.GNN._insertNews(obj);
    			if (b) this.news = 0;
    			else this.vNews ^= this.news + 15;
    		}
    	}
    }
    
    this.newsDisplayed = function () {
    	switch (this.news) {
    		case 3: this.tempDisabled = true; break;
    		case 4: break;
    		default: this.news = 0; break;
    	}
    }
    
    this.failPlay = function (mode) {
    	if (this.libMusic.$dub && this.libMusic.$dub.channel == this.currentChannel) {
    		Sound.stopMusic(this.libMusic.$dub.cur);
    		if (mode) Sound.playMusic("hyperradio-fail.ogg");
    	}
    }
    
    this.CheckHyperradioLicense = function () {
    	if (this.hyperRadio && clock.days >= this.hyperradioDuration) {
    		player.ship.removeEquipment("EQ_HYPER_RADIO");
    		this.canPlay = false;
    		this.hyperradioDuration = 0;
    		player.consoleMessage(expandDescription("[hyper_expired]"), 6);
    		return false;
    	}
    	if (system.isInterstellarSpace) return (false);
    	if (player.ship.equipmentStatus("EQ_HYPER_RADIO") === "EQUIPMENT_DAMAGED") {
    		this.canPlay = false;
    		player.consoleMessage(expandDescription("[hyper_damaged]"), 6);
    		return false;
    	}
    	if (player.ship.equipmentStatus("EQ_HYPER_RADIO") === "EQUIPMENT_OK") this.canPlay = true;
    	return true;
    }
    
    this.SelectHyperradioStation = function (next) {
    	if (this.doInit) this.doInit();
    	if (this.canPlay == false) {
    		player.consoleMessage(expandDescription("[hyper_error]"), 6);
    		return;
    	}
    	if (next && this.currentChannelIndex == -1) {
    		player.consoleMessage(expandDescription("[hyper_channels_off]"));
    		return;
    	}
    	if (next == 0) {
    		if (this.currentChannelIndex == -1) {
    			this.currentChannelIndex = this.savedChannelIndex;
    		} else {
    			this.savedChannelIndex = this.currentChannelIndex;
    			this.currentChannelIndex = -1;
    		}
    	} else {
    		if (next > 0) this.currentChannelIndex += 1;
    		if (this.currentChannelIndex >= (this.stations - 1)) this.currentChannelIndex = 0;
    	}
    
    	if (this.currentChannelIndex == -1) {
    		this.currentChannel = expandDescription("[hyper_off]");
    		this.turnOnEventMusic();
    	} else {
    		this.savedChannelIndex = this.currentChannelIndex;
    		this.currentChannel = this.libMusic.$radios[this.currentChannelIndex];
    		this.turnOffEventMusic();
    	}
    
    	if (this.currentChannelIndex >= 0) player.consoleMessage(expandDescription("[hyper_new_channel]", { name: this.currentChannel }));
    	else player.consoleMessage(expandDescription("[hyper_radio_off]"));
    
    	if (this.currentChannelIndex == -1) {
    		this.libMusic.$E0 = 0;
    	} else {
    		this.libMusic.$E0 = this.masking[this.currentChannelIndex];
    	}
    	this.libMusic._buildList();
    	this.libMusic._resetTimer(0);
    }
    
    this.turnOffEventMusic = function() {
    	var g = this.libMusic.$groupIDs;
    	for (var i = 0; i < g.length; i++) {
    		if (this.libMusic.$act[g[i]] == 1) this.libMusic._toggleGroup(g[i]);
    	}
    }
    
    this.turnOnEventMusic = function() {
    	var g = this.libMusic.$groupIDs;
    	for (var i = 0; i < g.length; i++) {
    		if (this.libMusic.$act[g[i]] == 0) this.libMusic._toggleGroup(g[i]);
    	}
    }
    
    this.doInit = function () {
    	this.stations = this.libMusic.$radios.length;
    	if (this.logging) log(this.name, this.name + ": Stations found:" + this.stations);
    	this.masking = [];
    	var initial = 1;
    	for (var i = 0; i < this.stations; i++) {
    		this.masking.push(initial);
    		initial *= 2;
    	}
    	delete this.doInit;
    }
    
    this.switchTimer = function switchTimer() {
    	if (this.doInit) return; // if we haven't selected a station, just return
    	// if the radio has switched to something other than generic (eg "fight"), 
    	// and the hand property is no longer "radio" switch to that radio channel
    	if (this.libMusic.$dub.radio != "generic" && this.libMusic.$dub.hand != "radio") {
    		this.turnOnEventMusic();
    		this.libMusic._resetTimer(0);
    		return;
    	}
    	// if the radio has switched to generic, and we have previously selected a channel and it's not active
    	// switch to that channel
    	if (this.libMusic.$dub.radio == "generic" && this.currentChannel != expandDescription("[hyper_off]") && this.libMusic.$dub.hand != "radio") {
    		this.turnOffEventMusic();
    		this.libMusic._resetTimer(0);
    	}
    }
    
    Scripts/hyperradio2_eq.js
    "use strict";
    this.name = "hyperradio_eq";
    this.author = "Svengali";
    this.copyright = "(C)2008-2025, License:CC-by-nc-sa-3.0";
    this.description = "Musicplayer. EQ script.";
    this.version = "2.0";
    
    this.activated = function () {
    	// turns radio on/off
    	worldScripts.hyperradio2.SelectHyperradioStation(0);
    };
    this.mode = function () {
    	// select next channel
    	worldScripts.hyperradio2.SelectHyperradioStation(1);
    };
    
    this.allowAwardEquipment = function (equipment, ship, context) {
    	if (context === "scripted") return true;
    	// if no radio channels have been installed, no point in purchasing
    	if (worldScripts.Lib_Music.$radios.length == 0) return false;
    	if (equipment == "EQ_HYPER_RADIO") return true;
    	if (equipment == "EQ_HYPER_RADIO_ADD") {
    		if (worldScripts.hyperradio2.allowLicenceExtension == true && system.government > 4) return true
    	}
    	if (equipment == "EQ_HYPER_RADIO_PIRATE") {
    		if (worldScripts.hyperradio2.allowPirateRadio == true) return true;
    	}
    	return false;
    
    }