| Scripts/OXPConfig.js | "use strict";
this.name = "OXPConfig";
this.author = "Svengali, Lone_Wolf";
this.copyright = "(C)2009-2015, License:CC-by-nc-sa-3.0";
this.description = "Tool. Configures settings to en/disable features or adjusts them.";
this.version = "2.3.4";
this.oxpcSettings = {
	Info: {Name:"OXPConfig",MinVersion:this.version,Display:"0XPConfig",EarlyCall:false,EarlySet:false,Notify:false,DynamicNotify:false,LeaveData:false,
		InfoB:"logEarly measures the startUp time. Note that time is quantised in units of maybe 50/60ms or 16 ms or 10ms or ..., depending on system. Changes to OXPConfigs displayAll and collectAll require a restart to take effect.",
		InfoS:"The 'sliders' are short unsigned integers in range of 0-255 (or 0x0-0xff) and can be adjusted via increase / decrease or onscreen keyboard. They could also be used as additional bitmasks.",
		InfoE:"The entities entries are one 24Bit unsigned integer in range of 0-16777216 (or 0x0-0xffffff) and are splitted into single bits. This is meant specially for oxps to en/disable appearance of entities, like replacement sets."},
	Bool0: {Name:"logging",Def:false,Desc:"Logging functions. Verbose and slow."},
	Bool1: {Name:"logEarly",Def:false,Desc:"Logs early calls and time."},
	Bool2: {Name:"displayAll",Def:false,Desc:"Included OXPs or with oxpcSettings."},
	Bool3: {Name:"collectAll",Def:false,Desc:"All worldScripts. Slow."},
	SInt0: {Name:"SIntA",Def:0x2,Max:0xf,Desc:"Only a test"},
	SInt1: {Name:"SIntB",Def:0xaf,Max:0xbf,Desc:"for the"},
	SInt2: {Name:"SIntC",Def:0xfe,Max:0xff,Desc:"integers"},
	SInt3: {Name:"SIntD",Def:0x10,Max:0x13,Desc:"mechanism."},
	EInt0: {Name:"EIntA",Def:0xffffff,Max:0xffffff,Desc:["description 01","description 02","description 03","description 04","description 05","description 06","description 07","description 08","description 09","description 10","description 11","description 12","description 13","description 14","description 15","description 16","description 17","description 18","description 19","description 20","description 21","description 22","description 23","description 24"]}
};
// Color definitions
this.genericUserColors = [[[1,0.9,0.4,1],null],[[1,0.5,0,1],null],[[1,0,1,1],null],[[0.9,0.2,0.5,1],null],[[0.3,0.6,0.3,1],null],[[1,1,1,1],[1,0,0,1]],[[1,1,1,1],[0,1,0,1]],[[0.4,0.4,0.4,1],[0.6,0.9,1,1]],[[1,0.3,0.3,1],[0.3,1,0.3,1]],[[0.6,0,0,1],[1,0,0,1]],[[0,0.5,0.6,1],null],[[0.6,0.4,0.2,0.9],null],[[0.6,0,1,0.8],null],[[0.6,1,0.7,1],null],[[0,0.5,1,0.8],null],[[1,0,0,0.9],[0.9,0.3,0.9,1]],[[0.7,0.8,0,1],[0,0,1,1]],[[1,1,0,1],[0,1,1,1]],[[0,0,0.7,1],[0,1,0,1]],[[0,0,1,0.9],[1,0,0,1]]];
// OXPconfig gathers the infos on startUp and builds the searchtrees and arrays.
// For applying settings it runs two cycles - one on startUp and the other on guiScreenChanged/alertConditionChanged or timer.
this.startUp = function()
{
	var start = (new Date()).getTime();
	delete this.startUp;
	if(missionVariables.genericUserColors) this.genericUserColors = JSON.parse(missionVariables.genericUserColors);
	else missionVariables.genericUserColors = JSON.stringify(this.genericUserColors);
	if(!worldScripts.Cabal_Common_Functions || typeof(worldScripts.Cabal_Common_Functions.Cabal_Common)==='undefined'){this.killSelf(" -> Cabal_Common_Functions missing."); return;}
	else {
		this.helper = new worldScripts.Cabal_Common_Functions.Cabal_Common();
		if(this.helper.internalVersion<15){this.killSelf(" -> Cabal_Common_Functions is too old."); return;}
	}
	this.logging = false;
	this.logEarly = false;
	this.displayAll = false;
	this.collectAll = false;
	this.SIntA = 0x2;
	this.SIntB = 0xaf;
	this.SIntC = 0xfe;
	this.SIntD = 0x10;
	this.EIntA = 0xffffff;
	// Load OXPConfigs settings first.
	if(missionVariables.OXPConfig_Self){
		var confSelf = missionVariables.OXPConfig_Self.split(','),temp,what = ["logging","logEarly","displayAll","collectAll"];
		for(var i=0;i<4;i++){temp = what[i]; if(confSelf[i]==='true') this[temp] = true; else this[temp] = false;}
	}
	if(this.collectAll) this.displayAll = true;
	this.prepare();
	this.changed = [];
	this.loadDone = [];
	this.excludeGUI = ['GUI_SCREEN_OPTIONS','GUI_SCREEN_SAVE','GUI_SCREEN_LOAD','GUI_SCREEN_INTRO1','GUI_SCREEN_INTRO2'];
	this.oxpCTimer = new Timer(this,this.doOxpCTimer,1);
	this.init = true;
	// Cleanup stuff from older versions.
	missionVariables.oxpConfig_defaults = null;
	missionVariables.oxpConfig_selectiveLoad = null;
	missionVariables.oxpConfig_settings = null;
	missionVariables.oxpConfig_storedOxps = null;
	// New mV - floats are not allowed in missionVariables!!!
	this.myVersion = this.version.replace(/\./gi,"_");
	if(!missionVariables.OXPConfig_Change) missionVariables.OXPConfig_Change = this.myVersion;
	// Check oxps and apply stored settings (first cycle)
	this.getAvailable();
	this.loadSettings(1);
	delete this.killSelf;
	var diff = (new Date()).getTime() - start;
	if(this.logEarly) log(this.name,this.name+": OXPConfig startUp done in: "+diff+" ms.");
};
this.killSelf = function(desc)
{
	player.consoleMessage(this.name+" - Check your Latest.log.",10);
	log(this.name,this.name+" - Shutting down."+desc);
	for(var prop in this){if(prop!=='name' && prop!=='version' && prop!=='genericUserColors') delete this[prop];}
	this.deactivated = true;
	return;
};
this.prepare = function()
{
	// Collect data from oxps and build binary search trees. Call startUp if EarlyCall is set.
	// The list is sorted by ID, but will be resorted by .Display when completed/expanded.
	this.supported = [
		{Name:"OXPConfig",ID:0x0,Display:"OXPConfig"},
		{Name:"hyperradio",ID:0x1,Display:"Hyperradio"},
		{Name:"BGS-M",ID:0x2,Display:"BGS"},
		{Name:"vector",ID:0x3,Display:"Vector"},
		{Name:"snoopers",ID:0x4,Display:"Snoopers"},
		{Name:"SE-main-script",ID:0x5,Display:"BlOomberg"},
		{Name:"buoyRepair",ID:0x6,Display:"BuoyRepair"},
		{Name:"Famous Planets Launch Script",ID:0x7,Display:"FamousPlanets1.x"},
		{Name:"FuelStation-Setup",ID:0x8,Display:"FuelStation"},
		{Name:"LaveAcademy",ID:0x9,Display:"LaveAcademy"},
		{Name:"localhero",ID:0xa,Display:"Localhero"},
		{Name:"OXPShipRegulator",ID:0xb,Display:"OXPShipRegulator"},
		{Name:"ScriptTimer",ID:0xc,Display:"ScriptTimer"},
		{Name:"Welcome Information Script",ID:0xd,Display:"WelcomeMat"},
		{Name:"Shield Cycler",ID:0xe,Display:"Shield Cycler"},
		{Name:"Famous Planets",ID:0xf,Display:"FamousPlanets"},
		{Name:"System Redux",ID:0x10,Display:"SystemRedux"},
		{Name:"explorer_club.js",ID:0x11,Display:"Explorer Club"},
		{Name:"Furball",ID:0x12,Display:"Furball"},
		{Name:"murphy-thargoid-drive.js",ID:0x13,Display:"Thargoid Witchspace Drive"},
		{Name:"illegal_goods_tweak",ID:0x14,Display:"Illegal Goods Tweak"},
		{Name:"Safe_Docking",ID:0x15,Display:"Safe Docking"},
		{Name:"Jaguar Company",ID:0x16,Display:"Jaguar Company"},
		{Name:"Friend or Foe",ID:0x17,Display:"Friend or Foe"},
		{Name:"Skilled NPCs",ID:0x18,Display:"Skilled NPCs"},
		{Name:"Deep_Horizon_Adv_Nav_Comp",ID:0x19,Display:"Deep Horizon - Adv. Nav. Computer"},
		{Name:"HyperspaceHangar",ID:0x1a,Display:"Hyperspace Hangar"}
	];
	this.fullSupported = this.supported; // Holds the internal list of OXPs (Name, ID and Display). Used for loading defaults.
	this.idSearch = new worldScripts.Cabal_Common_Functions.Cabal_Common_BinSearch(); // Quick search for ID or Name of internal OXPs.
	var il = this.supported.length;
	for(var i=0;i<il;i++) this.idSearch.add(this.supported[i].Name,this.supported[i].ID);
	for(var i=0;i<il;i++) this.idSearch.add(String(this.supported[i].ID),this.supported[i].Name);
	this.infoSearch = new worldScripts.Cabal_Common_Functions.Cabal_Common_BinSearch(); // Holds the infos about OXPs. Rebuild by changeOXPData(obj).
	var w = {},o,fflag,oxpb,prop,temp;
	if(!this.displayAll && !this.collectAll){
		for(var sup in this.supported){
			if(typeof(sup)!=='string' || isNaN(parseInt(sup,null))) continue;
			var a = this.supported[sup].Name;
			w[a] = this.supported[sup];
		}
	} else w = worldScripts;
	for(var temp in w){
		if(!this.displayAll && !this.collectAll && typeof(worldScripts[temp])==='undefined') continue;
		if(worldScripts[temp]===null || typeof(worldScripts[temp])!=='object' || typeof(temp)!=='string') continue;
		if(typeof(worldScripts[temp].name)!=='undefined'){
			if(typeof(worldScripts[temp].oxpcLookup)!=='undefined') worldScripts[temp].oxpcLookup();
			if(typeof(worldScripts[temp].oxpcSettings)!=='undefined' && typeof(worldScripts[temp].oxpcSettings)==='object'){
				o = worldScripts[temp].oxpcSettings;
				if(!Object.isExtensible(o) || Object.isSealed(o) || Object.isFrozen(o)){
					log(this.name,"OXPConfig rejected non extensible, sealed or frozen object in: "+temp);
					this.collectWorld(temp,-4);
					continue;
				}
				if(typeof(o.Info.EarlyCall)!=='boolean') o.EarlyCall = false;
				else o.EarlyCall = o.Info.EarlyCall;
				if(o.EarlyCall){
					if(worldScripts[temp].startUp){
						worldScripts[temp].startUp();
						if(this.logEarly) log(this.name,"Early call for: "+temp);
					}
				}
				if(typeof(o.Info)==='object'){
					if(typeof(o.Info.Name)==='string' && o.Info.Name===worldScripts[temp].name){
						if(typeof(o.Info.LeaveData)!=='boolean' || o.Info.LeaveData!==true){delete worldScripts[temp].oxpcSettings;}
						o.Name = o.Info.Name;
						o.Error = 0;
						if(typeof(o.Info.Display)!=='string') o.Display = o.Name;
						else o.Display = o.Info.Display.substr(0,30);
						if(typeof(o.Info.MinVersion)!=='string') o.MinVersion = '0.0';
						else o.MinVersion = o.Info.MinVersion;
						if(typeof(o.Info.EarlySet)!=='boolean') o.EarlySet = false;
						else o.EarlySet = o.Info.EarlySet;
						if(typeof(o.Info.Notify)!=='boolean') o.Notify = false;
						else o.Notify = o.Info.Notify;
						if(typeof(o.Info.DynamicNotify)!=='boolean') o.DynamicNotify = false;
						else o.DynamicNotify = o.Info.DynamicNotify;
						fflag = this.idSearch.contains(o.Name);
						if(typeof(fflag)==='number'){
							o.ID = fflag;
							o.Support = 1;
							this.supported[fflag].Support = 1;
						} else {
							if(!this.displayAll) continue;
							o.ID = -1;
							o.Support = -5;
							var r = {Name:o.Name,ID:-1,Display:o.Display,Support:-5};
							this.supported.push(r);
						}
						oxpb = 0; prop = ["Bool0","Bool1","Bool2","Bool3"]
						for(var i=0;i<4;i++){
							temp = prop[i]
							if(typeof(o[temp])==='object'){
								if(typeof(o[temp].Name)!=='string' || typeof(o[temp].Def)!=='boolean' || typeof(o[temp].Desc)!=='string'){
									o[temp] = -1;
									o.Error |= 1;
								} else {
									oxpb |= Math.pow(2,i);
									o[temp].Desc = o[temp].Desc;
								}
							} else o[temp] = -1;
						}
						if(oxpb){
							o.BOptions = oxpb;
							if(typeof(o.Info.InfoB)==='string') o.InfosB = o.Info.InfoB;
							else o.InfoB = "not available";
						} else {
							o.BOptions = -1;
							o.InfoB = "not available";
						}
						oxpb = 0; prop = ["SInt0","SInt1","SInt2","SInt3"]
						for(var i=0;i<4;i++){
							temp = prop[i]
							if(typeof(o[temp])==='object'){
								if(typeof(o[temp].Name)!=='string' || typeof(o[temp].Def)!=='number' || typeof(o[temp].Max)!=='number' || typeof(o[temp].Desc)!=='string'){
									o[temp] = -1;
									o.Error |= 2;
								} else {
									oxpb |= Math.pow(2,i);
									o[temp].Desc = o[temp].Desc;
								}
							} else o[temp] = -1;
						}
						if(oxpb){
							o.SOptions = oxpb;
							if(typeof(o.Info.InfoS)==='string') o.InfosS = o.Info.InfoS;
							else o.InfoS = "not available";
						} else {
							o.SOptions = -1;
							o.InfoS = "not available";
						}
						oxpb = 0; prop = ["EInt0"]
						for(var i=0;i<1;i++){
							temp = prop[i]
							if(typeof(o[temp])==='object'){
								if(typeof(o[temp].Name)!=='string' || typeof(o[temp].Def)!=='number' || typeof(o[temp].Max)!=='number' || typeof(o[temp].Desc)!=='object'){
									o[temp] = -1;
									o.Error |= 4;
								} else {
									oxpb |= Math.pow(2,i);
									var m = this.helper.msbPos(o[temp].Max);
									if(m!==o[temp].Desc.length) o.Error |= 8;
								}
							} else o[temp] = -1;
						}
						if(oxpb){
							o.EOptions = oxpb;
							if(typeof(o.Info.InfoE)==='string') o.InfosE = o.Info.InfoE;
							else o.InfoE = "not available";
						} else {
							o.EOptions = -1;
							o.InfoE = "not available";
						}
						if(this.logging) for(var prop in o){log(this.name,prop+" : "+o[prop]);}
						// All checks passed, put in tree
						this.infoSearch.add(o.Name,o);
					} else this.collectWorld(temp,-4);
				} else this.collectWorld(temp,-6);
			} else this.collectWorld(temp,-7);
		} else log(this.name,"Error: Shouldn't be in worldScripts list: "+temp);
	}
	if(!this.displayAll){
		// Remove from this.supported.
		var n = this.supported.length;
		while(n--) if(typeof(this.supported[n].Support)==='undefined' || this.supported[n].Support<1) this.supported.splice(n,1);
	}
	this.oxps = this.supported.length;
	if(this.logging || this.logEarly) log("OXPs in list:"+this.oxps);
	for(var prop in this.supported){
		if(typeof(this.supported[prop])==='object'){
			if(typeof(this.supported[prop].Support)==='undefined') this.supported[prop].Support = 0;
			if(this.logging) log(this.name,this.supported[prop].Name+" "+prop+" Support:"+this.supported[prop].Support+" ID:"+this.supported[prop].ID);
		}
	}
	// Sort by Display for screens. One time job, sorting is slow.
	var first = false;
	if(this.supported[0].Name==='OXPConfig'){this.supported.shift(); first = true;}
	this.supported = this.helper.arrSortByProperty(this.supported,"Display");
	if(first) this.supported.unshift({Name:'OXPConfig',ID:0x0,Display:'OXPConfig',Support:1});
	delete this.prepare;
	delete this.collectWorld;
	return;
};
this.collectWorld = function(what,mode)
{
	// mode -7=no settings, -6=no Info, -4=wrong Name
	if(typeof(what)==='undefined') log("Undefined:"+what);
	var fflag = this.idSearch.contains(what),o = {};
	if(typeof(fflag)==='number'){
		if(!this.displayAll) return;
		o.Name = this.supported[fflag].Name;
		o.Display = this.supported[fflag].Display;
		o.ID = fflag;
		o.Support = mode;
		this.supported[fflag].Support = -4;
	} else {
		if(!this.collectAll) return;
		o.Name = what;
		o.Display = what;
		o.ID = -1;
		o.Support = mode;
		this.supported.push(o);
	}
	o.Info = -1;
	o.InfoB = -1;
	o.InfoS = -1;
	o.InfoE = -1;
	o.BOptions = -1;
	o.SOptions = -1;
	o.EOptions = -1;
	o.MinVersion = '0.0';
	o.EarlyCall = false;
	o.EarlySet = false;
	o.Notify = false;
	this.infoSearch.add(what,o);
	return;
};
this.getAvailable = function()
{
	this.available = []; // Status for entries in this.supported (installed, disabled, etc.). Rebuild on every start/activation.
	var temp,avail,minv;
	for(var w=0;w<this.oxps;w++){
		if(typeof(this.supported[w].Name)==='undefined'){
			if(this.logging) for(var prop in this.supported[w]) log(this.name,prop+" : "+this.supported[w][prop]);
			this.available[w] = -9;
			continue;
		} else {
			if(typeof(this.supported[w].Support)!=='undefined' && (this.supported[w].Support<0 && this.supported[w].Support!==-5)){
				this.available[w] = this.supported[w].Support;
				continue;
			}
			avail = this.supported[w].Name
			temp = this.infoSearch.contains(avail);
			minv = temp.MinVersion;
			if(worldScripts[avail]){
				if(worldScripts[avail].deactivated) this.available[w] = -1;
				else {
					if(typeof(minv)==='undefined') this.available[w] = -3;
					else {
						if(worldScripts[avail].version && !this.helper.strCompareVersion(worldScripts[avail].version,minv)) this.available[w] = -2;
						else this.available[w] = 1;
					}
				}
			} else this.available[w] = 0;
		}
	}
	if(this.logging || this.logEarly) log(this.name,this.name+": available:"+this.available);
	return;
};
this.doInit = function()
{
	this.cleanTimer();
	delete this.init;
	delete this.doInit;
	// Check oxps and apply stored settings (second cycle)
	this.getAvailable();
	this.loadSettings();
	this.loadDone = [];
	return;
};
this.doOxpCTimer = function()
{
	if(this.init) this.doInit();
	if(!player.ship.isValid || !player.ship.docked || this.excludeGUI.indexOf(guiScreen)!==-1) return;
	if(guiScreen==='GUI_SCREEN_GAMEOPTIONS'){
		this.cleanTimer();
		player.consoleMessage("OXPConfig prepared.\nStep to SYSTEM_DATA_SCREEN (F7) to activate.",6);
		this.activate = true;
		var oxpcSound = new SoundSource(); oxpcSound.loop = false; oxpcSound.sound = 'cabal_common_key.ogg'; oxpcSound.play();
	}
};
this.cleanTimer = function()
{
	if(this.oxpCTimer){this.oxpCTimer.stop(); delete this.oxpCTimer;}
	return;
};
this.alertConditionChanged = function()
{
	if(this.init) this.doInit();
	delete this.alertConditionChanged;
};
this.guiScreenChanged = function(to)
{
	if(this.init){this.doInit(); return;}
	if(!player.ship || !player.ship.isValid || !player.ship.docked) return;
	if(this.activate){
		if(to==='GUI_SCREEN_SYSTEM_DATA'){
			this.oxpc = new Object({page:0,activeID:0,activeOXP:-1,activeSlider:-1,activeEntity:0,notify:0});
			this.showStartScreen();
			this.getAvailable();
			return;
		} else {
			var includeGUI = ['GUI_SCREEN_OPTIONS','GUI_SCREEN_MISSION','GUI_SCREEN_STATUS'];
			var ch = includeGUI.indexOf(to);
			this.activate = false;
			if(ch===-1) player.consoleMessage("OXPConfig de-activated.",3);
			if(!ch){
				if(!this.oxpCTimer) this.oxpCTimer = new Timer(this,this.doOxpCTimer,0,3);
			} else this.cleanTimer();
		}
	} else if(to==='GUI_SCREEN_OPTIONS'){
		if(!this.oxpCTimer) this.oxpCTimer = new Timer(this,this.doOxpCTimer,0,3);
		else this.oxpCTimer.start();
	} else this.cleanTimer();
};
this.showScreen = function(message,chc,pic,mod)
{
	var ti = "OXPConfig",img = {name:'OXPConfig_colors.png',width:1024,height:512};
	switch(pic){
		case 1: img = 'OXPConfig_logo.png'; break;
		case 3: if(this.oxp) ti = this.oxp.Display; break;
		case 4: ti = "User Definable Colors"; break;
	}
	if(message){
		var temp = expandMissionText(message);
		if(temp) message = temp;
	}
	if(!mod) mission.runScreen({title:ti,message:message,choicesKey:chc,background:img,allowInterrupt:false},this.choiceEval);
	else mission.runScreen({title:ti,message:message,choicesKey:chc,background:img,model:mod,spinModel:false,allowInterrupt:false},this.choiceEval);
	player.ship.hud = "hud_oxpconfig.plist";
	return;
};
this.showStartScreen = function(work)
{
	if(player.ship.hud!=="hud_oxpconfig.plist") this.oxpHUD = player.ship.hud; // store for resetting
	this.aspect = this.helper.screenChecks();
	this.showScreen('OXPCONFIG_FIRST','OXPCONFIG_TOPLEVEL',1);
	mission.addMessageTextKey('OXPCONFIG_WELCOMEA');
	mission.addMessageTextKey('OXPCONFIG_QUEST');
	if(work){
		switch(work){
			case 1: player.ship.awardEquipment("EQ_OXPCONFIG_M0"); break;
			case 2: player.ship.awardEquipment("EQ_OXPCONFIG_M1"); break;
			case 3: player.ship.awardEquipment("EQ_OXPCONFIG_M2"); break;
			case 4: player.ship.awardEquipment("EQ_OXPCONFIG_M3"); break;
			case 5: player.ship.awardEquipment("EQ_OXPCONFIG_M4"); break;
			case 6: player.ship.awardEquipment("EQ_OXPCONFIG_M5"); break;
		}
	}
};
this.choiceEval = function(choice)
{
	for(var i=0;i<6;i++) if(player.ship.equipmentStatus("EQ_OXPCONFIG_M"+i)==="EQUIPMENT_OK") player.ship.removeEquipment("EQ_OXPCONFIG_M"+i);
	player.ship.removeEquipment("EQ_OXPCONFIG_W0");
	switch(choice){
		case "OXPCONFIG_BROWSE":
			this.keyboardBrowse = true;
			worldScripts.Cabal_Common_Keyboard.start(this.name,1,1);
			break;
		case "OXPCONFIG_CHANGE":
			this.oxpc.page = 0;
			this.showOXPSelection();
			break;
		case "OXPCONFIG_DEFAULTS":
			this.loadDefaults();
			this.showStartScreen(1);
			break;
		case "OXPCONFIG_RELOAD":
			var l = this.loadSettings();
			if(l) this.showStartScreen(2);
			else this.showStartScreen(4);
			break;
		case "OXPCONFIG_SAVE":
			var s = this.storeSettings();
			if(s) this.showStartScreen(3);
			else this.showStartScreen(5);
			break;
		case "OXPCONFIG_PAGEA0":
			this.showOXPConfig(0);
			break;
		case "OXPCONFIG_PAGEA1":
			this.showOXPConfig(1);
			break;
		case "OXPCONFIG_PAGEA2":
			this.showOXPConfig(2);
			break;
		case "OXPCONFIG_PAGEA3":
			this.showOXPConfig(3);
			break;
		case "OXPCONFIG_PAGEX":
			this.oxpc.page++;
			this.showOXPSelection();
			break;
		case "OXPCONFIG_PAGEY":
			this.oxpc.page--;
			this.showOXPSelection();
			break;
		case "OXPCONFIG_PAGEZ":
			if(player.ship.equipmentStatus("EQ_OXPCONFIG_COLORS")==="EQUIPMENT_OK") player.ship.removeEquipment("EQ_OXPCONFIG_COLORS");
			missionVariables.genericUserColors = JSON.stringify(this.genericUserColors);
			this.showStartScreen();
			break;
		case "OXPCONFIG_CHANGEA":
			this.oxpc.notify |= 1;
			var temp = this.oxp["Bool0"].Name;
			this.changeBool(temp);
			this.showOXPConfig(this.oxpc.activeOXP);
			break;
		case "OXPCONFIG_CHANGEB":
			this.oxpc.notify |= 1;
			var temp = this.oxp["Bool1"].Name;
			this.changeBool(temp);
			this.showOXPConfig(this.oxpc.activeOXP);
			break;
		case "OXPCONFIG_CHANGEC":
			this.oxpc.notify |= 1;
			var temp = this.oxp["Bool2"].Name;
			this.changeBool(temp);
			this.showOXPConfig(this.oxpc.activeOXP);
			break;
		case "OXPCONFIG_CHANGED":
			this.oxpc.notify |= 1;
			var temp = this.oxp["Bool3"].Name;
			this.changeBool(temp);
			this.showOXPConfig(this.oxpc.activeOXP);
			break;
		case "OXPCONFIG_CHANGEE":
			if(this.oxp.SOptions>0) this.showSliderPage(this.oxpc.activeOXP,0);
			else if(this.oxp.EOptions>0) this.showEntityPage(this.oxpc.activeOXP,0);
			else this.showOXPSelection();
			break;
		case "OXPCONFIG_SLIDERNEXT":
			this.oxpc.activeSlider++;
			if(this.oxpc.activeSlider>3) this.oxpc.activeSlider = 0;
			var avail = "SInt"+this.oxpc.activeSlider;
			if(this.oxp[avail]===-1 || this.oxp[avail].Hide){
				while(this.oxp[avail]===-1 || this.oxp[avail].Hide){
					this.oxpc.activeSlider++;
					if(this.oxpc.activeSlider>3) this.oxpc.activeSlider = 0;
					avail = "SInt"+this.oxpc.activeSlider;
				}
			}
			this.showSliderPage(this.oxpc.activeOXP,this.oxpc.activeSlider);
			break;
		case "OXPCONFIG_SLIDERDEC":
			var decCheck,temp;
			this.oxpc.notify |= 2;
			temp = this.oxp["SInt"+this.oxpc.activeSlider].Name;
			decCheck = worldScripts[this.oxp.Name][temp]-1;
			if(decCheck>=0){
				worldScripts[this.oxp.Name][temp] = decCheck;
				this.oxp[temp] = decCheck;
				if(this.oxp.DynamicNotify) this.sendNotification(2);
			}
			this.showSliderPage(this.oxpc.activeOXP,this.oxpc.activeSlider);
			break;
		case "OXPCONFIG_SLIDERINC":
			var incCheck,temp;
			this.oxpc.notify |= 2;
			temp = this.oxp["SInt"+this.oxpc.activeSlider];
			incCheck = (worldScripts[this.oxp.Name][temp.Name]+1);
			if(incCheck<=temp.Max){
				worldScripts[this.oxp.Name][temp.Name] = incCheck;
				this.oxp[temp.Name] = incCheck;
				if(this.oxp.DynamicNotify) this.sendNotification(2);
			}
			this.showSliderPage(this.oxpc.activeOXP,this.oxpc.activeSlider);
			break;
		case "OXPCONFIG_SLIDERJINC":
			var full,temp;
			this.oxpc.notify |= 2;
			temp = this.oxp["SInt"+this.oxpc.activeSlider];
			full = temp.Max;
			worldScripts[this.oxp.Name][temp.Name] = full;
			this.oxp[temp.Name] = full;
			if(this.oxp.DynamicNotify) this.sendNotification(2);
			this.showSliderPage(this.oxpc.activeOXP,this.oxpc.activeSlider);
			break;
		case "OXPCONFIG_SLIDERSET":
			this.keyboardSlider = true;
			worldScripts.Cabal_Common_Keyboard.start(this.name,1,3);
			break;
		case "OXPCONFIG_ENTITYNEXT":
			this.oxpc.activeEntity++;
			if(this.oxpc.activeEntity>24 || this.oxpc.activeEntity>this.oxp["EInt0"].Desc.length-1) this.oxpc.activeEntity = 0;
			this.showEntityPage(this.oxpc.activeOXP,this.oxpc.activeEntity);
			break;
		case "OXPCONFIG_ENTITYOSET":
			this.oxpc.notify |= 4;
			var bit = Math.pow(2,this.oxpc.activeEntity),current = this.oxp.EInt0.Name;
			if((this.oxp[current]&bit)) this.oxp[current] &= ((Math.pow(2,24)-1)-bit);
			else this.oxp[current] |= bit;
			worldScripts[this.oxp.Name][current] = this.oxp[current];
			if(this.oxp.DynamicNotify) this.sendNotification(4);
			this.showEntityPage(this.oxpc.activeOXP,this.oxpc.activeEntity);
			break;
		case "OXPCONFIG_ENTITYSET":
			this.keyboardEntity = true;
			worldScripts.Cabal_Common_Keyboard.start(this.name,1,3);
			break;
		case "OXPCONFIG_XA":
			if(this.oxp.Support===1 || this.oxp.Support===-5){
				var current = this.oxp.EInt0.Name;
				worldScripts[this.oxp.Name][current] = this.oxp[current];
			}
			this.showOXPConfig(this.oxpc.activeOXP);
			break;
		case "OXPCONFIG_XB":
			if(this.oxp.Support===1 || this.oxp.Support===-5){
				var current = this.oxp.EInt0.Name;
				worldScripts[this.oxp.Name][current] = this.oxp[current];
			}
			this.showSliderPage(this.oxpc.activeOXP,0);
			break;
		case "OXPCONFIG_YA":
			this.showOXPConfig(this.oxpc.activeOXP);
			break;
		case "OXPCONFIG_YB":
			this.showEntityPage(this.oxpc.activeOXP,0);
			break;
		case "OXPCONFIG_YSPECIALS":
			this.showScreen('OXPCONFIG_FIRST','OXPCONFIG_SPECIALS',1);
			mission.addMessageTextKey('OXPCONFIG_WELCOMEB');
			break;
		case "OXPCONFIG_COLORS":
			player.ship.awardEquipment("EQ_OXPCONFIG_COLORS");
			this.showSpecialColors();
			break;
		case "OXPCONFIG_COLORS_A":
			this.colorWheel++;
			if(this.colorWheel>=20) this.colorWheel = 0;
			this.showSpecialColors();
			break;
		case "OXPCONFIG_COLORS_B":
			this.colorToggle = 0;
			this.showSpecialColors(1);
			break;
		case "OXPCONFIG_COLORS_C":
			if(!this.genericUserColors[this.colorWheel][1]) this.genericUserColors[this.colorWheel][1] = [0,0,0,1];
			this.colorToggle = 1;
			this.showSpecialColors(1);
			break;
		case "OXPCONFIG_COLORS_D":
			if(this.genericUserColors[this.colorWheel][1]) this.genericUserColors[this.colorWheel][1] = null;
			this.colorToggle = 0;
			this.showSpecialColors();
			break;
		case "OXPCONFIG_COLORS_BA":
			this.genColorsAdd(0);
			this.showSpecialColors(1);
			break;
		case "OXPCONFIG_COLORS_BB":
			this.genColorsAdd(1);
			this.showSpecialColors(1);
			break;
		case "OXPCONFIG_COLORS_BC":
			this.genColorsAdd(2);
			this.showSpecialColors(1);
			break;
		case "OXPCONFIG_COLORS_BD":
			this.genColorsAdd(3);
			this.showSpecialColors(1);
			break;
		case "OXPCONFIG_COLORS_BF":
			this.showSpecialColors();
			break;
		case "OXPCONFIG_DUMPWS":
			this.showWSList();
			break;
		case "OXPCONFIG_WSNEXT":
			this.wsActive++;
			if(this.wsActive>19 || this.wsList.length<=(this.wsIndex*20+this.wsActive)) this.wsActive = 0;
			this.showWSList();
			break;
		case "OXPCONFIG_WSNEXTPAGE":
			this.wsIndex++;
			if(this.wsIndex && this.wsIndex>(this.wsList.length-1)/20) this.wsIndex = 0;
			this.showWSList();
			break;
		case "OXPCONFIG_WSZDUMP":
			this.dumpWSProps();
			break;
		case "OXPCONFIG_DUMPMVS":
			this.dumpMVs();
			break;
		case "OXPCONFIG_DUMPCS":
			this.dumpSounds();
			break;
		case "OXPCONFIG_ZA":
			if(this.oxp.Support===1 || this.oxp.Support===-5){
				if(this.oxp.Notify && this.oxpc.notify) this.sendNotification(this.oxpc.notify);
				this.checkChanged();
			}
			this.oxpc.notify = 0;
			this.oxpc.activeOXP = -1;
			delete this.oxp;
			this.showOXPSelection();
			break;
		case "OXPCONFIG_ZB":
			if(this.oxp.Support===1 || this.oxp.Support===-5){
				var current = this.oxp.EInt0.Name;
				worldScripts[this.oxp.Name][current] = this.oxp[current];
				if(this.oxp.Notify && this.oxpc.notify) this.sendNotification(this.oxpc.notify);
				this.checkChanged();
			}
			this.oxpc.notify = 0;
			this.oxpc.activeOXP = -1;
			delete this.oxp;
			this.showOXPSelection();
			break;
		case "OXPCONFIG_ZQUIT":
			this.cleanProps();
			if(this.oxpHUD && player.ship.hud==="hud_oxpconfig.plist"){
				player.ship.hud = this.oxpHUD;
				delete this.oxpHUD;
			}
			break;
	}
	return;
};
this.genColorsAdd = function(i)
{
	var guc = this.genericUserColors[this.colorWheel][this.colorToggle][i];
	guc = this.helper.num2Prec(guc+0.1,2);
	if(guc>1) guc = 0;
	this.genericUserColors[this.colorWheel][this.colorToggle][i] = guc;
	return;
};
this.changeBool = function(temp)
{
	if(this.logging) log("Change:"+temp)
	if(!worldScripts[this.oxp.Name][temp]){
		worldScripts[this.oxp.Name][temp] = true;
		this.oxp[temp] = true;
	} else {
		worldScripts[this.oxp.Name][temp] = false;
		this.oxp[temp] = false;
	}
	if(this.oxp.DynamicNotify) this.sendNotification(1);
	return;
};
this.showOXPSelection = function()
{
	var t = this.oxpc.page*4,s = 1,supper,temp,data=[],txt;
	for(var i=0;i<4;i++){
		if(this.oxps>t+i){
			txt = null;
			supper = this.supported[t+i];
			temp = this.infoSearch.contains(supper.Name);
			if(typeof(temp)!=='boolean') data.push(temp.Support);
			else data.push(0);
			switch(supper.Support){
				case 1: txt = "Configure"; break;
				case 0: txt = "Virtual"; break;
				case -1:
				case -2:
				case -3:
				case -4: txt = "View only"; break;
				case -5: txt = "Change only"; break;
				case -6:
				case -7:
				case -8: txt = "View only"; break;
				case -9: txt = "Virtual"; break;
			}
			if(txt) missionVariables["oxpc_display"+i] = txt+" - "+supper.Display;
		} else missionVariables["oxpc_display"+i] = "---";
	}
	if((t-4)<0) s = 0;
	else if((t+4)>=this.oxps) s = 2;
	switch(s){
		case 0: this.showScreen(null,'OXPCONFIG_PAGEA',2); break;
		case 1: this.showScreen(null,'OXPCONFIG_PAGEB',2); break;
		case 2: this.showScreen(null,'OXPCONFIG_PAGEC',2); break;
	}
	mission.addMessageText("Short overview:\n--------------------------------------------------");
	for(var ov=0;ov<4;ov++){
		txt = null;
		switch(this.available[t+ov]){
			case -9: txt = "installed, but not supported.\n Name not available."; break;
			case -8: txt = "installed, but not supported.\n No Lookup."; break;
			case -7: txt = "installed, but not supported.\n No oxpcSettings."; break;
			case -6: txt = "installed, but not supported.\n No Info."; break;
			case -5: txt = "installed and settings available, but no ID.\n  Load/Save disabled."; break;
			case -4: txt = "installed, but failure in settings.\n No settings available."; break;
			case -3: txt = "installed, but not supported.\n No MinVersion."; break;
			case -2: txt = "installed, but not supported.\n MinVersion to low."; break;
			case -1: txt = "installed, but deactivated."; break;
			case 0: txt = "not installed."; break;
			case 1: txt = "installed and active."; if(data[ov]===-5) txt += "\n Load/Save disabled."; break;
		}
		if(txt) mission.addMessageText(this.supported[t+ov].Display+": "+txt+"\n");
	}
};
this.showNot = function(m)
{
	this.showScreen('OXPCONFIG_FIRST','OXPCONFIG_CHANGE0',2);
	mission.addMessageText("\n"+this.oxp.Display+" version:"+this.oxp.version+" "+m);
	return;
};
this.showOXPConfig = function(which)
{
	var t = this.oxpc.page*4+(which&3),temp,text,countOff=0;
	if(t!==this.oxpc.activeOXP || typeof(this.oxp)==='undefined') this.oxp = this.getOXPInfo(t);
	if(typeof(this.oxp.Error)!=='undefined' && this.oxp.Error>0) log(this.name,"Error in "+this.oxp.Name+" declaration:"+this.oxp.Error);
	if(this.oxp.Support<1 && this.oxp.Support!==-5){
		if(this.oxp.Support===0) this.showNot("is not installed.");
		else if(this.oxp.Support===-1) this.showNot("is deactivated - Check Latest.log for details.\n");
		else if(this.oxp.Support<-1) this.showNot("is not supported.\n");
		return;
	}
	if((this.oxp.BOverride===15 && (this.oxp.Support===1 || this.oxp.Support===-5))){
		if(this.oxp.BOptions<1){
			if(this.oxp.SOptions>0) this.showSliderPage(t,0);
			else if(this.oxp.EOptions>0 && !this.oxp.EInt0.Hide) this.showEntityPage(t,0);
			else this.showNot("- nothing to configure yet.");
		} else this.showNot("is not compatible.");
		return;
	}
	if(this.oxp.Support===-1){this.showNot("is deactivated - Check Latest.log for details.\n"); return;}
	var a = this.oxp.BOptions-(this.oxp.BOverride&this.oxp.BOptions), chc = 'OXPCONFIG_CHANGE', mv=0;
	if(this.oxp.SOptions>0 || this.oxp.EOptions>0) a += 16;
	for(var i=0;i<4;i++){
		mv = Math.pow(2,i);
		if((this.oxp.BOptions&mv) && !(this.oxp.BOverride&mv)){
			temp = this.oxp["Bool"+i];
			if(!temp.Hide) missionVariables["oxpc_bool"+i] = "Change "+this.oxp["Bool"+i].Name;
			else {
				a -= mv;
				countOff += mv;
			}
		}
	}
	chc += a;
	this.showScreen(null,chc,3);
	if(this.oxp.Support===1) text = "Current: "+this.oxp.Name+"\fv: "+this.oxp.version+"\f\f#"+this.oxp.ID;
	else {
		text = "Current: "+this.oxp.Name+"\fv: "+this.oxp.version;
		player.ship.awardEquipment("EQ_OXPCONFIG_W0");
	}
	text = text.substr(0,70); mission.addMessageText(text);
	mission.addMessageText("Author(s): "+this.oxp.Author);
	mission.addMessageText("Copyright: "+this.oxp.Copyright);
	mission.addMessageText("Desc: "+this.oxp.Description);
	mission.addMessageTextKey('OXPCONFIG_DIVIDE');
	if(countOff===this.oxp.BOptions) mission.addMessageText("\nNothing to configure yet.");
	else {
		for(var i=0;i<4;i++){
			a = Math.pow(2,i);
			if((this.oxp.BOptions&a) && !(this.oxp.BOverride&a)){
				temp = this.oxp["Bool"+i];
				if(temp && !temp.Hide){
					text = temp.Name+":";
					text = this.helper.strToWidth(text,9);
					text += worldScripts[this.oxp.Name][temp.Name];
					text = this.helper.strToWidth(text,13);
					text += temp.Desc;
					text = this.helper.strToWidth(text,31);
					mission.addMessageText(text);
				} else mission.addMessageText("-");
			} else mission.addMessageText("-");
		}
		mission.addMessageText("--------------------------------------------------\nInfo:");
		if(this.oxp.Info && typeof(this.oxp.Info.InfoB)==='string') mission.addMessageText(this.oxp.Info.InfoB.substr(0,240));
		else mission.addMessageText("Not available.");
	}
	return;
};
this.showSliderPage = function(which,ini)
{
	var t = this.oxpc.page*4+(which&3),text;
	if(t!==this.oxpc.activeOXP || typeof(this.oxp)==='undefined') this.oxp = this.getOXPInfo(t);
	if(this.oxp.SOptions<1 || this.oxp.SOverride===15){this.showNot("is not compatible."); return;}
	var chc = 'OXPCONFIG_CHANGESLIDER';
	if(this.oxp.BOptions<1 && this.oxp.EOptions<1) chc += 'A';
	else if(this.oxp.BOptions>0 && this.oxp.EOptions<1) chc += 'B';
	else chc += 'C';
	if(typeof(ini)!=='undefined') this.oxpc.activeSlider = ini;
	var avail = "SInt"+this.oxpc.activeSlider,loop=0,countOff=0;
	if(typeof(this.oxp[avail])==='undefined' || this.oxp[avail].Hide){
		while(typeof(this.oxp[avail])==='undefined' || this.oxp[avail].Hide){
			this.oxpc.activeSlider++;
			if(this.oxpc.activeSlider>3) this.oxpc.activeSlider = 0;
			avail = "SInt"+this.oxpc.activeSlider;
			countOff |= Math.pow(2,loop);
			loop++;
			if(this.logging) log(this.name,"Slider loop:"+avail+" "+typeof(this.oxp[avail]));
			if(loop>5) break;
		}
	}
	if(countOff===this.oxp.SOptions) chc += 'B';
	this.showScreen(null,chc,3);
	if(this.oxp.Support===1) text = "Current: "+this.oxp.Name+"\fv: "+this.oxp.version+"\f\f#"+this.oxp.ID;
	else {
		text = "Current: "+this.oxp.Name+"\fv: "+this.oxp.version;
		player.ship.awardEquipment("EQ_OXPCONFIG_W0");
	}
	text = text.substr(0,70); mission.addMessageText(text);
	mission.addMessageTextKey('OXPCONFIG_DIVIDE');
	if(countOff===this.oxp.SOptions) mission.addMessageText("\nNothing to configure yet.");
	else {
		var current,show,value = 0,valueD,percent = 0,def = 0,max = 0,pow = 0;
		for(var sc=0;sc<4;sc++){
			text = "";
			pow = Math.pow(2,sc);
			if(sc===this.oxpc.activeSlider) text += "->\f";
			else text += "\f\f";
			avail = "SInt"+sc;
			if(typeof(this.oxp[avail])==='object' && (this.oxp.SOptions&pow) && !(this.oxp.SOverride&pow)){
				current = this.oxp[avail];
				if(!current.Hide){
					value = worldScripts[this.oxp.Name][current.Name]&0xFF;
					valueD = this.helper.baseChange(value,16);
					if(valueD.length<2) valueD = "0x0"+valueD;
					else valueD = "0x"+valueD;
					def = current.Def
					def = this.helper.baseChange(def,16);
					if(def.length<2) def = "0x0"+def;
					else def = "0x"+def;
					percent = Math.ceil((value/Math.max(current.Max,1))*100);
					for(var s=0;s<Math.ceil(percent*0.4);s++){text += "|";}
					text = this.helper.strToWidth(text,10,".");
					text = this.helper.strToWidth(text,11);
					max = current.Max;
					if(max<16) max = "0x0"+this.helper.baseChange(max,16);
					else max = "0x"+this.helper.baseChange(max,16);
					text += "("+valueD+"-"+this.helper.strLZZ(percent)+"% - D:"+def+"-M:"+max+")";
					text = this.helper.strToWidth(text,22);
					show = current.Desc;
					text += " "+show;
				} else text = "-";
			} else text = "-";
			text = this.helper.strToWidth(text,31);
			mission.addMessageText(text);
		}
		mission.addMessageText("--------------------------------------------------\nInfo:");
		if(this.oxp.Info && typeof(this.oxp.Info.InfoS)==='string') mission.addMessageText(this.oxp.Info.InfoS.substr(0,240));
		else mission.addMessageText("Not available.");
	}
	return;
};
this.showEntityPage = function(which,ini)
{
	var t = this.oxpc.page*4+(which&3),text;
	if(t!==this.oxpc.activeOXP || typeof(this.oxp)==='undefined') this.oxp = this.getOXPInfo(t);
	if(this.oxp.EOptions<1 || this.oxp.EOverride===1){this.showNot("is not compatible."); return;}
	var chc = 'OXPCONFIG_CHANGEENTITY';
	if(this.oxp.BOptions<1 && this.oxp.SOptions<1) chc += 'A';
	else if(this.oxp.BOptions>0 && this.oxp.SOptions<1) chc += 'B';
	else chc += 'C';
	if(this.oxp.EInt0.Hide) chc += 'B';
	this.showScreen(null,chc,3);
	if(this.oxp.Support===1) text = "Current: "+this.oxp.Name+"\fv: "+this.oxp.version+"\f\f#"+this.oxp.ID;
	else {
		text = "Current: "+this.oxp.Name+"\fv: "+this.oxp.version;
		player.ship.awardEquipment("EQ_OXPCONFIG_W0");
	}
	text = text.substr(0,70); mission.addMessageText(text);
	mission.addMessageTextKey('OXPCONFIG_DIVIDE');
	if(this.oxp.EInt0.Hide) mission.addMessageText("\nNothing to configure yet.");
	else {
		if(typeof(ini)!=='undefined') this.oxpc.activeEntity = ini;
		var current,loop,def = 0,max = 0,pow = 0,value = 0,row = 0,endOut = "",sign = "";
		current = this.oxp.EInt0;
		loop = current.Desc.length;
		for(var s=0;s<loop;s++){
			if(this.oxpc.activeEntity===s) sign = "->\f";
			else sign = "\f\f";
			var pow = Math.pow(2,s);
			if((this.oxp[current.Name]&pow)) value = 1;
			else value = 0;
			text = value+" "+current.Desc[s];
			text = this.helper.strToWidth(text,8);
			if((row&2)){
				row = 0;
				if(s===loop-1) endOut += sign+text;
				else endOut += sign+text+"\n";
				text = "";
			} else {
				endOut += sign+text;
				row++;
			}
		}
		var displayDec = this.oxp[current.Name];
		var displayHex = this.helper.baseChange(displayDec,16);
		var def = current.Def;
		var max = current.Max;
		def = "0x"+this.helper.baseChange(def,16);
		max = "0x"+this.helper.baseChange(max,16);
		mission.addMessageText(endOut);
		mission.addMessageText("---------- Status: (#"+displayDec+" $0x"+displayHex+" - Def:"+def+" Max:"+max+") ----------");
		mission.addMessageText("Info:");
		if(this.oxp.Info && typeof(this.oxp.Info.InfoE)==='string') mission.addMessageText(this.oxp.Info.InfoE.substr(0,240));
		else mission.addMessageText("Not available.");
	}
	return;
};
this.getOXPInfo = function(n)
{
	if(n>this.oxps-1){grab = new Object({Name:" ",Display:" ",Support:0,version:" "}); return(grab);}
	this.oxpc.activeOXP = n;
	var supper = this.supported[n];
	if(!this.available[n] || typeof(supper.Support)==='undefined' || typeof(supper.ID)==='undefined'){
		grab = new Object({Name:supper.Name,Display:supper.Name,Support:0,version:" "}); return(grab);
	}
	var grab = this.infoSearch.contains(supper.Name);
	if(!worldScripts[grab.Name]){
		grab.Support = 0; grab.version = " ";
		if(this.logging){for(var prop in grab){log(this.name,"0 - prop:"+prop+" : "+grab[prop]);}}
		return(grab);
	} else {
		if(this.logging) log(this.name,"OXP:"+grab.Name+" ID:"+grab.ID+" Support:"+grab.Support+" Avail:"+this.available[n]);
		if(typeof(worldScripts[grab.Name].version)!=='string') grab.version = "0.0";
		else grab.version = worldScripts[grab.Name].version;
		if(typeof(worldScripts[grab.Name].deactivated)!=='undefined' && worldScripts[grab.Name].deactivated){grab.Support = -1; return(grab);}
		if(worldScripts[grab.Name].version && !this.helper.strCompareVersion(worldScripts[grab.Name].version,grab.MinVersion)){
			grab.Support = -2; return(grab);}
		if(typeof(worldScripts[grab.Name].author)!=='string') grab.Author = "missing data";
		else grab.Author = worldScripts[grab.Name].author.substr(0,70);
		if(typeof(worldScripts[grab.Name].copyright)!=='string') grab.Copyright = "missing data";
		else grab.Copyright = worldScripts[grab.Name].copyright.substr(0,70);
		if(typeof(worldScripts[grab.Name].description)!=='string') grab.Description = "missing data";
		else grab.Description = worldScripts[grab.Name].description.substr(0,70);
		if(grab.Support!==1 && grab.Support!==-5){
			if(this.logging) for(var prop in grab) log(this.name,"1 - prop:"+prop+" : "+grab[prop]);
			return(grab);
		} else {
			if(grab.Support!==-5) grab.Support = 1;
			var temp = "";
			// Check booleans
			grab.BOverride = 0;
			for(var b=0;b<4;b++){
				temp = grab["Bool"+b].Name;
				if(typeof(worldScripts[grab.Name][temp])!=='boolean'){
					grab.BOverride |= Math.pow(2,b);
					grab[temp] = -1;
				} else grab[temp] = worldScripts[grab.Name][temp];
			}
			if(grab.BOptions!==-1 && (grab.BOverride&grab.BOptions)) grab.Error |= 1;
			// Check sliders
			grab.SOverride = 0;
			for(var b=0;b<4;b++){
				temp = grab["SInt"+b].Name;
				if(typeof(worldScripts[grab.Name][temp])!=='number'){
					grab.SOverride |= Math.pow(2,b);
					grab[temp] = -1;
				} else grab[temp] = worldScripts[grab.Name][temp];
			}
			if(grab.SOptions!==-1 && (grab.SOverride&grab.SOptions)) grab.Error |= 2;
			// Check entities
			grab.EOverride = 0;
			for(var b=0;b<1;b++){
				temp = grab["EInt"+b].Name;
				if(typeof(worldScripts[grab.Name][temp])!=='number'){
					grab.EOverride |= Math.pow(2,b);
					grab[temp] = -1;
				} else grab[temp] = worldScripts[grab.Name][temp];
			}
			if(grab.EOptions!==-1 && (grab.EOverride&grab.EOptions)) grab.Error |= 4;
			// Check array of descriptions
			if(typeof(grab.EInt0.Desc)==='object'){
				var a = grab.EInt0.Desc;
				var l = grab.EInt0.Desc.length;
				for(var i=0;i<l;i++) a[i] = a[i].replace(/[\t\r\f\n\v]/g,"");
				grab.EInt0.Desc = a;
			}
			if(this.logging) for(var prop in grab) log(this.name,"2 - prop:"+prop+" : "+grab[prop]);
			if(grab.Error){
				log(this.name,"Type mismatch detected in "+grab.Name+" with Error #"+grab.Error);
				log(this.name,"Error #: 1 = Boolean, 2 = SInt, 4 = EInt.");
			}
			return(grab);
		}
	}
	return(grab);
};
this.checkChanged = function()
{
	var flag = false, c = 0, pow = 0, prop = "";
	if(this.oxp.Support===1){
		var supper = this.supported[this.oxpc.activeOXP];
		var def = this.infoSearch.contains(supper.Name);
		if(def.BOptions>0){
			for(var i=0;i<4;i++){
				pow = Math.pow(2,i);
				if(!(def.BOptions&pow)) continue;
				prop = "Bool"+i;
				c = this.oxp[prop].Name;
				if(this.logging) log(this.name,"BOptions:"+def.BOptions+" Current:"+this.oxp[c]+" Def:"+def[prop].Def);
				if(this.oxp[c]!=def[prop].Def) flag = true;
			}
		}
		if(def.SOptions>0){
			for(var i=0;i<4;i++){
				pow = Math.pow(2,i);
				if(!(def.SOptions&pow)) continue;
				prop = "SInt"+i;
				c = this.oxp[prop].Name;
				if(this.logging) log(this.name,"SOptions:"+def.SOptions+" Current:"+this.oxp[c]+" Def:"+def[prop].Def);
				if(this.oxp[c]!=def[prop].Def) flag = true;
			}
		}
		if(def.EOptions>0){
			for(var i=0;i<1;i++){
				pow = Math.pow(2,i);
				if(!(def.EOptions&pow)) continue;
				prop = "EInt"+i;
				c = this.oxp[prop].Name;
				if(this.logging) log(this.name,"EOptions:"+def.EOptions+" Current:"+this.oxp[c]+" Def:"+def[prop].Def);
				if(this.oxp[c]!=def[prop].Def) flag = true;
			}
		}
		if(flag) this.changed.push(def.ID);
		else {
			this.helper.arrRemoveByValue(this.changed,def.ID);
			var id = "#"+this.helper.baseChange(def.ID,16)+"|";
			this.ripOff(id);
			if(this.logging) log(this.name,"mV:"+missionVariables.OXPConfig_Change);
			if(def.ID===0) missionVariables.OXPConfig_Self = null;
		}
		this.changed = this.helper.arrUnique(this.changed);
		if(this.logging) log(this.name,this.name+" New changed array:"+this.changed);
	}
	return;
};
this.loadSettings = function(mode)
{
	if(missionVariables.OXPConfig_Change.length!==this.myVersion.length){
		var settings = missionVariables.OXPConfig_Change.split("#")
		var subset = [],temp,loop = settings.length,n,what;
		goA:for(var i=1;i<loop;i++){
			subset = settings[i].split("|");
			subset[0] = parseInt("0x"+subset[0],null);
			if(this.loadDone.length && this.loadDone.indexOf(subset[0])!==-1) continue goA;
			for(var sub=1;sub<10;sub++){
				if(sub<5 || subset[sub]=="-1") subset[sub] = parseInt(subset[sub],null);
				else subset[sub] = parseInt("0x"+subset[sub],null);
			}
			if(this.logging) log(this.name,"Subset:"+subset);
			n = String(subset[0]);
			what = this.idSearch.contains(n);
			this.oxp = this.infoSearch.contains(what);
			if(what===false || this.oxp===false) continue goA;
			if(mode){
				if(!this.oxp.EarlySet || this.oxp.Support!==1) continue goA;
				if(worldScripts[this.oxp.Name].deactivated) continue goA;
			}
			this.changed.push(subset[0]);
			for(var b=0;b<4;b++){
				temp = this.oxp["Bool"+b];
				if((mode && subset[b+1]!==-1) || (!mode && this.oxp["Bool"+b]!==-1)){
					if(subset[b+1]) worldScripts[this.oxp.Name][temp.Name] = true;
					else worldScripts[this.oxp.Name][temp.Name] = false;
				}
			}
			for(var s=0;s<4;s++){
				temp = this.oxp["SInt"+s];
				if((mode && subset[s+5]!==-1) || (!mode && this.oxp["SInt"+s]!==-1)){
					worldScripts[this.oxp.Name][temp.Name] = parseInt(subset[s+5],null);
				}
			}
			temp = this.oxp["EInt0"];
			if((mode && subset[9]!==-1) || (!mode && this.oxp["EInt0"]!==-1)) worldScripts[this.oxp.Name][temp.Name] = subset[9];
			if(mode) this.loadDone.push(this.oxp.ID);
			if(this.oxp.Notify) this.sendNotification(7);
			if(this.logging) log(this.name,this.name+": Values set for:"+this.oxp.Name+" with ID:"+this.oxp.ID);
			continue goA;
		}
	} else return(false);
	if(this.logging) log(this.name,this.name+"Loading done. loadDone:"+this.loadDone+" changed:"+this.changed);
	delete this.oxp;
	return(true);
};
this.loadDefaults = function()
{
	var temp,loop=this.fullSupported.length,what;
	for(var o=0;o<loop;o++){
		what = this.fullSupported[o].Name
		this.oxp = this.infoSearch.contains(what);
		if(this.oxp===false || typeof(this.oxp.Support)==='undefined') continue;
		if(this.oxp.Support!==1) continue;
		for(var b=0;b<4;b++){
			temp = this.oxp["Bool"+b];
			if(this.oxp["Bool"+b]!==-1) worldScripts[this.oxp.Name][temp.Name] = temp.Def;
		}
		for(var s=0;s<4;s++){
			temp = this.oxp["SInt"+s];
			if(this.oxp["SInt"+s]!==-1) worldScripts[this.oxp.Name][temp.Name] = temp.Def;
		}
		temp = this.oxp["EInt0"];
		if(this.oxp["EInt0"]!==-1) worldScripts[this.oxp.Name][temp.Name] = temp.Def;
		if(this.oxp.Notify) this.sendNotification(7);
	}
	missionVariables.OXPConfig_Change = this.myVersion;
	missionVariables.OXPConfig_Self = null;
	this.changed = [];
	delete this.oxp;
	return;
};
this.storeSettings = function()
{
	if(this.changed.length){
		var comp,temp,early = [],notEarly = [],confSelf = [];
		var loop = this.changed.length,n,what;
		for(var o=0;o<loop;o++){
			n = String(this.changed[o]);
			what = this.idSearch.contains(n);
			this.oxp = this.infoSearch.contains(what);
			comp = this.buildString();
			if(this.oxp.EarlySet) early.push(comp);
			else notEarly.push(comp);
			if(this.oxp.ID===0){
				for(var s=0;s<4;s++){
					temp = this.oxp["Bool"+s].Name;
					comp = this.oxp[temp];
					confSelf.push(comp);
				}
				missionVariables.OXPConfig_Self = confSelf.join(',');
				if(this.logging) log(this.name,"mV.OXPConfig_Self:"+missionVariables.OXPConfig_Self);
			}
			continue;
		}
		if(early.length) missionVariables.OXPConfig_Change += early.join("");
		if(notEarly.length) missionVariables.OXPConfig_Change += notEarly.join("");
		if(this.logging) log(this.name,"mV.OXPConfig_Change:"+missionVariables.OXPConfig_Change);
	} else return(false);
	delete this.oxp;
	return(true);
};
this.buildString = function()
{
	var str,id = 0,std = "",sli = "",ent,temp;
	id = "#"+this.helper.baseChange(this.oxp.ID,16)+"|";
	this.ripOff(id);
	for(var i=0;i<4;i++){
		temp = this.oxp["Bool"+i].Name;
		if(typeof(worldScripts[this.oxp.Name][temp])==='undefined') std += "-1|";
		else if(worldScripts[this.oxp.Name][temp]) std += "1|";
		else std += "0|";
	}
	for(var i=0;i<4;i++){
		temp = this.oxp["SInt"+i].Name;
		if(typeof(worldScripts[this.oxp.Name][temp])==='undefined') sli += "-1|";
		else sli += this.helper.baseChange(worldScripts[this.oxp.Name][temp],16)+"|";
	}
	temp = this.oxp["EInt0"].Name;
	if(typeof(worldScripts[this.oxp.Name][temp])==='undefined') ent = "-1";
	else ent = this.helper.baseChange(worldScripts[this.oxp.Name][temp],16)
	str = id+std+sli+ent+"|";
	return(str);
};
this.ripOff = function(what)
{
	if(missionVariables.OXPConfig_Change && missionVariables.OXPConfig_Change.length>=what.length){
		var temp = missionVariables.OXPConfig_Change;
		var pos = temp.indexOf(what);
		if(pos!==-1){
			var posB = temp.length;
			for(var z=pos+1;z<posB;z++){
				if(temp[z]==="#"){
					posB = z;
					break;
				}
			}
			var cut = temp.slice(pos,posB);
			temp = temp.replace(cut,"");
			missionVariables.OXPConfig_Change = temp;
		}
	}
	return;
};
this.sendNotification = function(what)
{
	if(worldScripts[this.oxp.Name].oxpcNotifyOnChange) worldScripts[this.oxp.Name].oxpcNotifyOnChange(what);
	if(this.logging) log(this.name,this.name+": Notification sent to "+this.oxp.Name);
	return;
};
this.Cabal_Common_Keyboard_Output = function(str)
{
	if(this.keyboardSlider){
		if(str!==""){
			var incCheck = parseInt("0x"+str,null),temp;
			if(!isNaN(incCheck)){
				temp = this.oxp["SInt"+this.oxpc.activeSlider];
				if(incCheck>temp.Max) incCheck = temp.Max;
				worldScripts[this.oxp.Name][temp.Name] = incCheck;
				this.oxp[temp.Name] = incCheck;
				this.oxpc.notify |= 2;
			}
			if(this.oxp.DynamicNotify) this.sendNotification(2);
			this.showSliderPage(this.oxpc.activeOXP,this.oxpc.activeSlider);
		}
		this.showSliderPage(this.oxpc.activeOXP,this.oxpc.activeSlider);
		delete this.keyboardSlider;
	} else if(this.keyboardEntity){
		if(str!==""){
			var incCheck = parseInt("0x"+str,null),current = this.oxp.EInt0.Name;
			if(!isNaN(incCheck)){
				this.oxp[current] = Math.min(incCheck,this.oxp.EInt0.Max);
				this.oxpc.notify |= 4;
			}
		}
		worldScripts[this.oxp.Name][current] = this.oxp[current];
		if(this.oxp.DynamicNotify) this.sendNotification(4);
		this.showEntityPage(this.oxpc.activeOXP,this.oxpc.activeEntity);
		delete this.keyboardEntity;
	} else if(this.keyboardBrowse){
		this.oxpc.page = 0;
		var list =[],temp,pos,flag=false;
		for(var i=1;i<this.oxps;i++) list.push(this.supported[i].Display.substr(0,str.length).toUpperCase());
		while(!flag){
			pos = list.indexOf(str)+1;
			if(!pos){
				for(var b=0;b<this.oxps-1;b++){
					if(str[0]===list[b].substr(0,1)){
						pos = b+1;
						flag = true;
						break;
					}
				}
				temp = str.charCodeAt(0);
				temp--;
				if(temp>64) str = String.fromCharCode(temp);
				else {
					pos = 0;
					break;
				}
			} else break;
		}
		this.oxpc.page = Math.floor(pos*0.25);
		this.showOXPSelection();
		delete this.keyboardBrowse;
	}
};
this.cleanProps = function()
{
	var a = ["activate","oxp","oxpc","aspect","wsList","wsIndex","wsActive"];
	for(var i=0;i<a.length;i++) delete this[a[i]];
	for(var i=0;i<4;i++){
		missionVariables["oxpc_display"+i] = null;
		missionVariables["oxpc_bool"+i] = null;
	}
	return;
};
this.shipWillLaunchFromStation = function()
{
	if(this.oxp && this.oxpc){
		if(this.oxp.Notify && this.oxpc.notify) this.sendNotification(this.oxpc.notify);
	}
	this.cleanTimer();
	this.cleanProps();
	if(this.oxpHUD && player.ship.hud==="hud_oxpconfig.plist"){
		player.ship.hud = this.oxpHUD;
		delete this.oxpHUD;
	}
};
// Rebuild the searchtree and apply changes for specified OXP - no real checks for validity!!
// Tip: Use LeaveData flag, apply your changes to oxpcSettings and pass it to OXPConfig.
this.changeOXPData = function(obj)
{
	if(this.logging) log(this.name,"Change requested by: "+obj.Info.Name);
	var data = this.infoSearch.toArray();
	var where = data.indexOf(obj.Info.Name);
	if(where===-1) return(false);
	var fflag = this.idSearch.contains(obj.Info.Name);
	if(typeof(fflag)==='number'){
		var iN = ["InfoB","InfoS","InfoE","InfosB","InfosS","InfosE"],iNI = -1;
		var cB = ["Bool0","Bool1","Bool2","Bool3"],cBI = -1;
		var cS = ["SInt0","SInt1","SInt2","SInt3"],cSI = -1;
		var cE = ["EInt0"],cEI = -1;
		for(var prop in obj){
			if(typeof(obj[prop])!=='object') continue;
			for(var drop in obj[prop]){
				if(!isNaN(drop)) break; // Enum?
				iNI = iN.indexOf(drop);
				if(iNI!==-1){
					data[where+1][iN[iNI+3]] = obj[prop][drop];
					data[where+1][prop][drop] = obj[prop][drop];
					continue;
				}
				cBI = cB.indexOf(prop);
				if(cBI!==-1){
					data[where+1].BOptions |= Math.pow(2,cBI);
					data[where+1][prop][drop] = obj[prop][drop];
					continue;
				}
				cSI = cS.indexOf(prop);
				if(cSI!==-1){
					data[where+1].SOptions |= Math.pow(2,cSI);
					data[where+1][prop][drop] = obj[prop][drop];
					continue;
				}
				cEI = cE.indexOf(prop);
				if(cEI!==-1){
					data[where+1].EOptions |= Math.pow(2,cEI);
					data[where+1][prop][drop] = obj[prop][drop];
					continue;
				}
			}
		}
		delete this.infoSearch;
		this.infoSearch = new worldScripts.Cabal_Common_Functions.Cabal_Common_BinSearch();
		for(var i=0;i<data.length;i++) this.infoSearch.add(data[i],data[i+1]);
	}
	return(true);
};
this.showSpecialColors = function(rgb)
{
	var colorWheelPos = [[-361,-192,-24,148,320],[330,220,110,0]];
	var chc = "OXPCONFIG_COLORSA";
	if(rgb) chc = "OXPCONFIG_COLORSB";
	this.showScreen(null,chc,4,"oxpconfig_modelview");
	mission.displayModel.position=[0,0,900*this.aspect[3]];
	var c,posx,posy,txt="",act;
	for(var i=0;i<20;i++){
		c=i%5;
		switch(c){
			case 0: posx = colorWheelPos[0][0]; txt += "         "+this.helper.strToWidth("c"+i,6.2); break;
			case 1: posx = colorWheelPos[0][1]; txt += this.helper.strToWidth("c"+i,6.2); break;
			case 2: posx = colorWheelPos[0][2]; txt += this.helper.strToWidth("c"+i,6.2); break;
			case 3: posx = colorWheelPos[0][3]; txt += this.helper.strToWidth("c"+i,6.2); break;
			case 4: posx = colorWheelPos[0][4];
				if(i<19) mission.addMessageText(txt+"c"+i+"\n\n\n");
				else mission.addMessageText(txt+"c"+i);
				txt = "";
				break;
		}
		if(i<5) posy = colorWheelPos[1][0];
		else if(i<10) posy = colorWheelPos[1][1];
		else if(i<15) posy = colorWheelPos[1][2];
		else if(i<20) posy = colorWheelPos[1][3];
		mission.displayModel.subEntities[i+1].position=[posx,0,posy];
		var m1 = this.genericUserColors[i][0][3];
		var e1 = [this.genericUserColors[i][0][0]*m1,this.genericUserColors[i][0][1]*m1,this.genericUserColors[i][0][2]*m1,m1];
		if(this.genericUserColors[i][1]){
			var m2 = this.genericUserColors[i][1][3];
			var e2 = [this.genericUserColors[i][1][0]*m2,this.genericUserColors[i][1][1]*m2,this.genericUserColors[i][1][2]*m2,m2];
			mission.displayModel.subEntities[i+1].setMaterials({"oxpconfig_modelview.png":{ambient_color:e1,diffuse_color:e1},"oxpconfig_modelviewB.png":{ambient_color:e2,diffuse_color:e2}},{});
		} else mission.displayModel.subEntities[i+1].setMaterials({"oxpconfig_modelview.png":{ambient_color:e1,diffuse_color:e1},"oxpconfig_modelviewB.png":{ambient_color:e1,diffuse_color:e1}},{});
	}
	if(!this.colorWheel) this.colorWheel = 0;
	if(!this.colorToggle) this.colorToggle = 0;
	act = [colorWheelPos[0][this.colorWheel%5]-5,-2,colorWheelPos[1][Math.floor(this.colorWheel/5)]+5];
	mission.displayModel.subEntities[0].position=act;
	if(this.genericUserColors[this.colorWheel][1]) mission.addMessageText("\nCurrent: "+this.genericUserColors[this.colorWheel][0]+" : "+this.genericUserColors[this.colorWheel][1]);
	else mission.addMessageText("\nCurrent: "+this.genericUserColors[this.colorWheel][0]);
	return;
};
this.dumpMVs = function()
{
	log(this.name,"-------------------------------");
	log(this.name,"Dump missionvariables in current system:"+system.ID+" in galaxy:"+galaxyNumber);
	var list = Object.keys(missionVariables).sort();
	for(var l=0;l<list.length;l++){
		var t = list[l];
		var a = missionVariables[t],b;
		if(typeof(a)!=="string") log(this.name,list[l]+" : "+a);
		else if(a[0]==="{"){
			b = JSON.parse(a);
			log(this.name,list[l]+": Object");
			for(var prop in b) log(this.name,"  "+prop+" : "+b[prop]);
		} else if(a[0]==="["){
			b = JSON.parse(a);
			log(this.name,list[l]+": Array");
			for(var i=0;i<b.length;i++) log(this.name,"  "+b[i]);
		} else {
			if(a.search(/\|/g)!==-1){
				b = a.split("|");
				log(this.name,list[l]+": Serialized");
				for(var i=0;i<b.length;i++) log(this.name,"  "+b[i]);
			} else log(this.name,list[l]+" : "+a);
		}
	}
	log(this.name,"-------------------------------");
	this.showScreen('OXPCONFIG_FIRST','OXPCONFIG_SPECIALS',1);
	mission.addMessageTextKey('OXPCONFIG_WELCOMEB');
	player.ship.awardEquipment("EQ_OXPCONFIG_M5");
	return;
};
this.showWSList = function()
{
	if(!this.wsList){
		this.wsList = worldScriptNames.sort();
		this.wsIndex = 0;
		this.wsActive = 0;
	}
	this.showScreen('OXPCONFIG_FIRST','OXPCONFIG_WSLIST',2);
	var min = this.wsIndex*20;
	var max = Math.min(this.wsList.length,min+20);
	var cur = this.wsActive+min;
	var temp;
	for(var i=min;i<max;i+=2){
		if(cur===i) temp = this.helper.strToWidth("->"+this.wsList[i],15);
		else temp = this.helper.strToWidth(this.wsList[i],15);
		if(i<max-1){
			if(cur===i+1) temp += this.helper.strToWidth("->"+this.wsList[i+1],14);
			else temp += this.helper.strToWidth(this.wsList[i+1],14);
		}
		mission.addMessageText(temp);
	}
	return;
};
this.dumpWSProps = function()
{
	log(this.name,"-------------------------------");
	var test = this.wsList[this.wsActive+this.wsIndex*20],f=[],o=[],a=[],b=[],n=[],s=[],ss=[],ve=[],qu=[],ti=[];
	log(this.name,"Dump script properties for "+test+" in current system:"+system.ID+" in galaxy:"+galaxyNumber);
	for(var prop in worldScripts[test]){
		switch(typeof(worldScripts[test][prop])){
			case "undefined": log(this.name,"-- Undefined: "+test+"."+prop); break;
			case "boolean": b.push(prop); break;
			case "number": n.push(prop); break;
			case "string": s.push(prop); break;
			default:
				if(typeof(worldScripts[test][prop])==="object" && !worldScripts[test][prop]) log(this.name,"-- Null: "+test+"."+prop);
				else {
					switch(worldScripts[test][prop].constructor.name){
						case "Timer": ti.push(prop); break;
						case "Array": a.push(prop); break;
						case "Object": o.push(prop); break;
						case "SoundSource": ss.push(prop); break;
						case "Vector3D": ve.push(prop); break;
						case "Quaternion": qu.push(prop); break;
						case "Function": f.push(prop); break;
					}
				}
		}
	}
	if(b.length){
		log(this.name,"Boolean:");
		for(var i=0;i<b.length;i++) log(this.name,"  "+b[i]+" : "+worldScripts[test][b[i]]);
	}
	if(n.length){
		log(this.name,"Number:");
		for(var i=0;i<n.length;i++) log(this.name,"  "+n[i]+" : "+worldScripts[test][n[i]]);
	}
	if(s.length){
		log(this.name,"String:");
		for(var i=0;i<s.length;i++) log(this.name,"  "+s[i]+" : "+worldScripts[test][s[i]]);
	}
	if(a.length){
		log(this.name,"Array:");
		for(var i=0;i<a.length;i++){
			log(this.name,"  "+a[i]);
			if(typeof(worldScripts[test][a[i]])==="object"){
				for(var prop in worldScripts[test][a[i]]){
					log(this.name,"    "+a[i]+"."+prop+" : "+worldScripts[test][a[i]][prop]);
				}
			} else log(this.name,"    "+a[i]+" : "+worldScripts[test][a[i]]);
		}
	}
	if(o.length){
		log(this.name,"Object:");
		for(var i=0;i<o.length;i++){
			log(this.name,"  "+o[i]);
			for(var prop in worldScripts[test][o[i]]){
				if(typeof(worldScripts[test][o[i]][prop])==="object"){
					for(var drop in worldScripts[test][o[i]][prop])
					log(this.name,"    "+prop+"."+drop+" : "+worldScripts[test][o[i]][prop][drop]);
				} else log(this.name,"    "+prop+" : "+JSON.stringify(worldScripts[test][o[i]][prop]));
			}
		}
	}
	if(f.length) log(this.name,"Function: "+f);
	if(ss.length) log(this.name,"SoundSource: "+ss);
	if(ve.length) log(this.name,"Vector3D: "+ve);
	if(qu.length) log(this.name,"Quaternion: "+qu);
	if(ti.length) log(this.name,"Timer:" +ti);
	log(this.name,"-------------------------------");
	this.showWSList();
	player.ship.awardEquipment("EQ_OXPCONFIG_M5");
	return;
};
this.dumpSounds = function()
{
	var check,list = [
		"[@beep]","[@boop]","[@breakpattern]","[@click]","[@switch-off]","[@switch-on]","[@warning]","[@witchabort]",
		"[aegis-planet]","[aegis-station]","[alert-condition-red]","[autopilot-cannot-dock-with-target]","[autopilot-denied]",
		"[autopilot-off]","[autopilot-on]","[autopilot-out-of-range]","[buy-commodity]","[buy-ship]","[cargo-jettisoned]",
		"[changed-option]","[cloaking-device-insufficent-energy]","[cloaking-device-off]","[cloaking-device-on]",
		"[contract-accepted]","[contract-rejected]","[could-not-buy-commodity]","[could-not-buy-ship]","[could-not-sell-commodity]",
		"[dismissed-mission-screen]","[dismissed-report-screen]","[energy-bomb-fired]","[energy-low]","[escape-pod-scooped]",
		"[fuel-leak]","[galactic-hyperspace-countdown-begun]","[game-over]","[hold-full]","[hostile-warning]",
		"[hyperspace-countdown-aborted]","[hyperspace-countdown-begun]","[ident-locked-on]","[ident-off]","[ident-on]",
		"[incoming-missile]","[jump-mass-locked]","[menu-navigation-down]","[menu-navigation-not]","[menu-navigation-up]",
		"[menu-next-page]","[menu-previous-page]","[mine-armed]","[mine-launched]","[missile-armed]","[missile-launched]",
		"[missile-locked-on]","[missile-safe]","[next-missile-selected]","[no-target-in-memory]","[player-direct-hit]",
		"[player-dock-with-station]","[player-exit-witchspace]","[player-fired-ecm]","[player-hit-by-ecm]","[player-hit-by-weapon]",
		"[player-laser-hit]","[player-laser-miss]","[player-launch-from-station]","[player-scrape-damage]","[save-overwrite-no]",
		"[save-overwrite-yes]","[scoop]","[sell-commodity]","[target-lost]","[target-switched]","[trumble-idle]","[trumble-squeal]",
		"[weapon-overheat]","[witch-blocked-by-@]","[witch-no-fuel]","[witch-no-target]","[witch-too-far]","[witchdrive-failure]",
		"[witchdrive-malfunction]","[wormhole-created]"
	];
	var a = list.length,snames = [];
	for(var i=0;i<a;i++){
		check = Sound.load(list[i]);
		if(check) snames.push(list[i]+":"+check.name);
		else snames.push(list[i]+":"+"-");
	}
	log(this.name,"-------------------------------");
	log(this.name,"Dump sound declarations");
	log(this.name,snames);
	log(this.name,"-------------------------------");
	this.showScreen('OXPCONFIG_FIRST','OXPCONFIG_SPECIALS',1);
	mission.addMessageTextKey('OXPCONFIG_WELCOMEB');
	player.ship.awardEquipment("EQ_OXPCONFIG_M5");
	return;
};
this.doOXPCleanUp = function(who)
{
	var inf = worldScripts.OXPConfig.infoSearch.contains(who);
	if(inf){
		var mvs = inf.cleanUp.mv,data=[];
		for(var i=0;i<mvs.length;i++){
			if(missionVariables[mvs[i]]){
				data.push(mvs[i]);
				missionVariables[mvs[i]] = null;
			}
		}
		if(data.length) log(this.name,"Found and cleaned:"+data);
		return(true);
	}
	return(false);
};
 |