Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion OxpConfig

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Provides menus to configure supported OXPs. Provides menus to configure supported OXPs.
Identifier oolite.oxp.Svengali.OXPConfig oolite.oxp.Svengali.OXPConfig
Title OxpConfig OxpConfig
Category Miscellaneous Miscellaneous
Author Svengali, Lone_Wolf Svengali, Lone_Wolf
Version 2.3.4 2.3.4
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
  • oolite.oxp.Svengali.CCL:1.7.1
  • oolite.oxp.Svengali.CCL:1.7.1
  • Optional Expansions
    Conflict Expansions
    Information URL http://wiki.alioth.net/index.php/OXPConfig n/a
    Download URL https://wiki.alioth.net/img_auth.php/f/f3/OxpConfig_2.3.4.oxz http://wiki.alioth.net/img_auth.php/5/50/OxpConfig_2.3.4.oxz
    License CC BY-NC-SA 3 CC BY-NC-SA 3
    File Size n/a
    Upload date 1610873512

    Documentation

    Also read http://wiki.alioth.net/index.php/OxpConfig

    Equipment

    Name Visible Cost [deci-credits] Tech-Level
    HUD no 0 100+
    HUD no 0 100+
    HUD no 0 100+
    HUD no 0 100+
    HUD no 0 100+
    HUD no 0 100+
    HUD no 0 100+
    HUD no 0 100+

    Ships

    Name
    oxpconfig_modelview
    oxpconfig_sub

    Models

    This expansion declares no models.

    Scripts

    Path
    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);
    };