| Scripts/snoopers.js | "use strict";
this.name = "snoopers";
this.author = "DaddyHoggy, Drew, Disembodied and Svengali";
this.copyright = "(C)2009-2013, License:CC-by-nc-sa-3.0";
this.description = "The Galactic News Network.";
this.version = "2.5";
this.logging = false; // Extended logging on/off. Default false.
this.audio = true; // Audio for internal news on/off. Default true.
this.extraA = true; // Full mode for internal news on/off. Default true.
this.sliderA = 0x3; // Chance for newsflashes. Default 0x3 (#3).
this.sliderB = 0x19; // Max days between newsflashes. Default 0x19 (#25).
this.sliderC = 0x4; // Brightness for model. Default 0x4 (#4).
this.nextDate = 0;
this.startUp = function()
{
	delete this.startUp;
	if(!worldScripts.Cabal_Common_Functions || typeof(worldScripts.Cabal_Common_Functions.Cabal_Common)==='undefined'){this.killSelf(" -> Cabal_Common_Library is missing."); return;}
	this.helper = new worldScripts.Cabal_Common_Functions.Cabal_Common();
	if(this.helper.internalVersion<15){this.killSelf(" -> Cabal_Common_Library is too old."); return;}
	this.snoopStation = true;
	this.shouldShow = false;
	this.peepDone = false;
	this.priorityMessages = false;
	this.fifoNews = [];
	this.unusedNews = [];
	this.CRCNews = [];
	this.galList = [1,2];
	this.specials = [];
	this.specialNews = [];
	this.hotNews = [];
	if(missionVariables.snoopers_allInfos){
		var snoopersInfos = JSON.parse(missionVariables.snoopers_allInfos),oxpID,snoopersUnused;
		if(missionVariables.snoopers_unusedInfos){
			snoopersUnused = JSON.parse(missionVariables.snoopers_unusedInfos);
			for(var i=0;i<snoopersUnused.length;i++){
				oxpID = snoopersUnused[i].ID;
				if(worldScripts[oxpID]) this.fifoNews.push(snoopersUnused[i]);
				else this.unusedNews.push(snoopersUnused[i]);
			}
		}
		this.hotNews = snoopersInfos.hotNews;
		this.nextDate = snoopersInfos.nextDate;
		this.CRCNews = snoopersInfos.CRCNews;
		for(var i=0;i<snoopersInfos.fifoNews.length;i++){
			oxpID = snoopersInfos.fifoNews[i].ID;
			if(worldScripts[oxpID]) this.fifoNews.push(snoopersInfos.fifoNews[i]);
			else this.unusedNews.push(snoopersInfos.fifoNews[i]);
		}
		if(this.fifoNews.length) this.resort = true;
		if(!this.unusedNews.length) delete this.unusedNews;
	} else this.nextDate = clock.days+2;
	if(oolite.gameSettings.wireframeGraphics) this.extraA = false;
	if(oolite.gameSettings.musicMode==='MUSIC_OFF') this.audio = false;
	this.snoopersInit = true;
	this.clearMVs();
	delete this.killSelf;
};
this.killSelf = function(desc)
{
	if(desc!==1){
		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') delete this[prop];}
	this.deactivated = true;
	this.insertNews = function(){return(27);}
	return;
};
this.playerWillSaveGame = function()
{
	var snoopersInfos = {};
	snoopersInfos.CRCNews = this.CRCNews;
	snoopersInfos.nextDate = this.nextDate;
	snoopersInfos.hotNews = this.hotNews;
	snoopersInfos.fifoNews = this.fifoNews;
	snoopersInfos.snoopVersion = this.version;
	missionVariables.snoopers_allInfos = JSON.stringify(snoopersInfos);
	if(this.unusedNews && this.unusedNews.length) missionVariables.snoopers_unusedInfos = JSON.stringify(this.unusedNews);
	this.clearMVBit = true;
	return;
};
this.clearMVs = function()
{
	missionVariables.snoopers_allInfos = null;
	missionVariables.snoopers_unusedInfos = null;
	delete this.clearMVBit;
	return;
};
this.rndSubSet = function(iter,ln,sub)
{
	var aSet = [],j,k,n;
	if(iter>ln) iter = ln;
	for(k=1;k<=iter;k++){
		n = ln-iter+k;
		j = Math.floor(n*(Math.random()%1))+1;
		aSet[j]?(aSet[n]=n):(aSet[j]=j);
	}
	for(j=k=0;k<aSet.length;k++) if(aSet[k]) aSet[j++] = aSet[k];
	aSet.length = j;
	if(!aSet.length) return 0;
	if(typeof(sub)==='number'){
		if(sub===1) return aSet[j-1];
		else return aSet[0];
	}
	return aSet;
};
this.calcNewDate = function()
{
	if(this.hotNews.length && 0>(clock.days-this.nextDate)) this.nextDate = clock.days+2;
	else {
		var limiter = Math.floor(Math.sqrt(this.fifoNews.length*4)+Math.sqrt(this.CRCNews.length)/4);
		var iterations = 10-limiter;
		var interval = (this.sliderB-limiter>3?this.sliderB-limiter:3);
		this.nextDate = clock.days+this.rndSubSet(iterations,interval,1);
	}
	if(this.logging) log(this.name,this.name+": Date:"+this.nextDate);
	return;
};
this.alertConditionChanged = this.missionScreenOpportunity = function()
{
	if(this.snoopersInit) this.guiScreenChanged();
	delete this.alertConditionChanged;
	if(player.ship.docked && this.checkStored) this.showNewsScreen();
};
this.shipDockedWithStation = function(station)
{
	if(!player.ship.docked) return;
	if(this.resort) this.sortFIFO();
	else if(this.fifoNews.length){
		var fl = this.fifoNews.length;
		while(fl--) if(this.fifoNews[fl].Priority && this.fifoNews[fl].Priority===1) this.priorityMessages = true;
	}
	if(station.isMainStation || station.scriptInfo.snoopersNews || station.hasNPCTraffic) this.snoopStation = true;
	else this.snoopStation = false;
	if(this.snoopStation && this.checkStored) this.peepShow(1);
	this.checkSpecials();
};
this.checkSpecials = function()
{
	if(!this.specials.length) return;
	var i = this.specials.length,go=0,temp,c;
	while(i--){
		go=0;
		if(this.specials[i].hasOwnProperty('mV') && missionVariables[this.specials[i].mV]===this.specials[i].value) go++;
		if(this.specials[i].hasOwnProperty('prop')){
			temp = this.specials[i].what,c = this.specials[i].prop;
			if(worldScripts[temp][c] && worldScripts[temp][c]===this.specials[i].value) go++;
		}
		if(go){
			this.hotNews.push(this.specials[i]);
			if(0>(clock.days-this.nextDate)) this.nextDate = clock.days+2;
			if(this.specials[i].hasOwnProperty('addMV')){
				var t = 'snoopers_'+this.specials[i].mV;
				missionVariables[t] = system.name;
			}
		}
	}
};
this.guiScreenChanged = function()
{
	if(this.snoopersInit){
		var requires = ['buoyRepair','1.3.2','AsteroidStorm','4.03','oolite-constrictor-hunt','1.77','oolite-nova','1.77','PlanetFall','1.51'];
		var checked = this.helper.oxpVersionTest2Array(this.name,requires,1);
		for(var i=0;i<checked.length;i++){
			if(checked[i]>0){
				switch(i){
					case 0: this.specialNews.push(91); break;
					case 1: this.specials.push({what:requires[i*2],prop:'badRockKiller',value:'PLAYER',ht:2}); break;
					case 2: this.specials.push({what:requires[i*2],mV:'conhunt',value:'CONSTRICTOR_DESTROYED',ht:1}); break;
					case 3: this.specials.push({what:requires[i*2],mV:'nova',value:'TWO_HRS_TO_ZERO',ht:3,addMV:1}); break;
					case 4: this.specialNews.push(92); break;
				}
			}
		}
		delete this.snoopersInit;
	}
	if(this.clearMVBit) this.clearMVs();
	if(player.ship.docked){
		if(this.resort) this.sortFIFO();
		if(this.snoopStation && !this.avoidSecond && (this.shouldShow || (this.fifoNews.length && Math.random()<(this.sliderA+this.fifoNews.length*0.2)*0.02))) this.peepShow(1);
	}
};
this.peepShow = function(dck)
{
	this.shouldShow = true;
	if(dck && this.shouldShow && !this.avoidSecond){
		if(!this.peepDone) player.commsMessage("Special news report. Check your News Channel (F4).");
		var it = {title:"The Galactic News Network.",category:"News",summary:"4 established news agencies are bringing you the latest news. Directly onto your screen, through your eyeballs and into your brain.",callback: worldScripts.snoopers.callbackShowNewsScreen}
		player.ship.dockedStation.setInterface("Snoopers",it);
	}
	if(this.audio && !this.peepDone){
		var peep = new SoundSource();
		peep.sound = '[snoopers_peep]';
		peep.play();
	}
	this.peepDone = true;
	return;
};
this.callbackShowNewsScreen = function(){worldScripts.snoopers.showNewsScreen(); return;};
this.showNewsScreen = function(obj)
{
	var scObj = {}, flagFIFO = false, rot, flagMV = false, special, e, t;
	if(this.checkStored) scObj = this.checkStored;
	else {
		if(obj) scObj = obj;
		else if(this.fifoNews.length && (this.priorityMessages || Math.random()>0.3) && typeof(this.fifoNews[0])=== 'object'){
			flagFIFO = true;
			scObj = this.fifoNews[0];
		} else {
			if(this.hotNews.length || (this.specialNews.length && Math.random()<0.03)){
				if(this.hotNews.length){
					t = this.hotNews[0].what;
					if(worldScripts[t]){
						e = this.hotNews[0].ht;
						if(this.hotNews[0].addMV) flagMV = this.hotNews[0].mV;
						special = 1;
					}
					this.hotNews.shift(); // unblock
				} else {
					e = this.specialNews[this.helper.randSpan(0,this.specialNews.length-1)];
					special = 1;
				}
			}
			if(special){
				switch(e){
					case 1: scObj = {Message:'[SNOOPERS_SPECIALS_1]',Model:'constrictor',Anim:[[1,'rot',[0,-1,6.5,0,0.002,0,0,1,1]],[20,'rot',[0,-1,3,0.002,0,0,0,1,1]],[28,'zoom',[0,-1,2,0.998,1,0.3,0.3]],[30,'face',[0,-1,3,-1,0,3,0,1]],[46,'rot',[0,-1,10,0.002,0,0,0,1,1]],[70,'zoom',[0,-1,2,1.005,1,0.3,0.3]],[451,0]]}; break;
					case 2: scObj = {Message:'[SNOOPERS_SPECIALS_2]',Model:'badrock',Ori:4,Anim:[[1,'zoom',[0,-1,20,0.9996,1,0.3,0.3]],[2,'rot',[0,-1,600,0,0.004,-0.004,0,1,1]],[601,0]]}; break;
					case 3: scObj = {Message:'[SNOOPERS_SPECIALS_3]',Model:'snoopers_solar',Ori:[0.68,0.73,0,0],Anim:[[1,'turn',[0,0,600,0.001,0.001,0,0]],[4,'zoom',[0,-1,12,1.001,0,0.3,0.3]],[601,0]]}; break;
					case 91: scObj = {Message:'[SNOOPERS_SPECIALS_91]',Model:'repaired-buoy-station',Anim:[[1,'zoom',[0,-1,20,0.995,1,0.3,0.3]],[4,'face',[0,-1,16,-1,0,3,3,1]],[81,'rot',[0,-1,3.6,0.001,-0.008,0.001,0,1,1]],[82,'zoom',[0,-1,8,1.003,1,0.3,0.3]],[282,'zoom',[0,-1,12,1.005,1,0.3,0.3]],[290,'prop',[0,-1,'fuel',6,0,0,0]],[401,0]]}; break;
					case 92: scObj = {Message:'[SNOOPERS_SPECIALS_92]',Model:'snoopers_pf',Ori:1,Anim:[[5,0]]}; break;
				}
				scObj.Message = expandDescription(scObj.Message);
				scObj.ID = this.name;
				scObj.Pic = 'snoopers_gcnews_clean.png';
			} else {
				var a='', b='';
				scObj.ID = 'Internal';
				if(this.galList.length && this.galList.indexOf(galaxyNumber)!==-1 && Math.random()>0.3){
					a = '[SNOOPERS_'+galaxyNumber+'_G'+system.government+']';
					b = '[SNOOPERS_'+galaxyNumber+'_G'+system.government+'_';
				} else {
					a = '[SNOOPERS_0_G'+system.government+']';
					b = '[SNOOPERS_0_G'+system.government+'_';
				}
				var ex = this.helper.randSpan(1,parseInt(expandDescription(a),null));
				var m = expandDescription(b+ex+']');
				if(m[0]==='#'){
					scObj.Agency = parseInt(m[1],null);
					m = m.substr(3);
				}
				scObj.Message = m;
			}
		}
	}
	if(!scObj.Agency) scObj.Agency = false;
	if(this.audio || flagFIFO){
		if(!scObj.Music) scObj.Music = 'snoopers_gcnews.ogg';
	} else scObj.Music = null;
	if(scObj.Agency){
		if(!isNaN(scObj.Agency) && scObj.Agency>0 && scObj.Agency<4){
			if(flagFIFO && Math.random()<0.5) scObj.Pic = 'snoopers_gcnewsA'+scObj.Agency+'1.png';
			else {
				scObj.Agency = parseInt(scObj.Agency,null);
				switch(scObj.Agency){
					case 1: scObj.Pic = 'snoopers_gcnewsA'+scObj.Agency+''+this.helper.randSpan(1,4)+'.png'; break;
					case 2: scObj.Pic = 'snoopers_gcnewsA'+scObj.Agency+''+this.helper.randSpan(1,4)+'.png'; break;
					case 3: scObj.Pic = 'snoopers_gcnewsA'+scObj.Agency+''+this.helper.randSpan(1,3)+'.png'; break;
				}
			}
			scObj.Model = 'snoopers_gcnewsA'+scObj.Agency;
			scObj.Pos = null;
			scObj.Music = 'snoopers_gcnews.ogg';
		} else log(this.name,this.name+': Error. Agency not valid:'+scObj.Agency+'.');
	} else {
		if(!scObj.Pic) scObj.Pic = 'snoopers_gcnews'+this.helper.randSpan(1,4)+'.png';
		else {
			switch(scObj.Pic){
				case 'snoopers_gcnewsA1.png': scObj.Pic = 'snoopers_gcnewsA11.png'; break;
				case 'snoopers_gcnewsA2.png': scObj.Pic = 'snoopers_gcnewsA21.png'; break;
				case 'snoopers_gcnewsA3.png': scObj.Pic = 'snoopers_gcnewsA31.png'; break;
			}
		}
		if(!scObj.Model){
			scObj.Model = 'snoopers_gcnews_b';
			scObj.Pos = null;
		}
	}
	this.sliderC &= 7;
	if(scObj.Model && scObj.Pos){
		if(typeof(scObj.Pos)==='string'){
			var ar = scObj.Pos.split(',');
			for(var cp=0;cp<ar.length;cp++) ar[cp] = parseFloat(ar[cp]);
			scObj.Pos = ar;
		}
	}
	if(!scObj.Model) scObj.Model = 'cabal_common_modelview';
	mission.runScreen({title:"News channel",screenID:"snoopers",message:"\n\n\n\n\n\n\n\n"+scObj.Message,model:scObj.Model,music:scObj.Music,overlay:scObj.Pic,spinModel:false},this.choiceEval);
	if(mission.displayModel){
		var ori = [0,0,1,0],fx = 0.4,fy = 0.25,fz = 3;
		switch(mission.displayModel.primaryRole){
			case 'snoopers_gcnews': fz = 3; scObj.Pos = null; scObj.Ori = 4; rot = 1; break;
			case 'snoopers_gcnews_b': fx = 0.43; fz = 1.3; scObj.Pos = null; scObj.Ori = 1; break;
			case 'snoopers_gcnewsA1': fx = 0.43; fz = 1.5; scObj.Pos = null; scObj.Ori = 1; break;
			case 'snoopers_gcnewsA2': fx = 0.43; fz = 1; scObj.Pos = null; scObj.Ori = 1; break;
			case 'snoopers_gcnewsA3': fx = 0.43; fz = 1; scObj.Pos = null; scObj.Ori = 1; break;
			case 'snoopers_pf': fx = 0.42; fz = 1.6; scObj.Pos = null; scObj.Ori = 1; break;
			default: if(scObj.Rot && !scObj.Anim) rot = scObj.Rot;
		}
		var r=this.helper.screenChecks(),z=mission.displayModel.position.z;
		if(!scObj.Pos){
			mission.displayModel.position=[(z/r[3])*(fx+((r[2]/r[0])*0.1)),(z/r[3])*(fy+((r[2]/r[0])*0.15)),z];
			mission.displayModel.position=mission.displayModel.position.multiply(fz);
		} else {
			scObj.Pos[0] += r[0]/1024/scObj.Pos[0];
			scObj.Pos[1] += (r[1]/768/scObj.Pos[1])*0.75;
			scObj.Pos[2] = (scObj.Pos[2]/(1024/768))*r[3];
			mission.displayModel.position = [scObj.Pos[0],scObj.Pos[1],scObj.Pos[2]];
		}
		switch(parseInt(scObj.Ori,null)){
			case 1: ori = [1,0,0,0]; break;
			case 2: ori = [1,0,0,1]; break;
			case 4: ori = [0,0,1,0]; break;
			case 8: ori = [1,1,0,0]; break;
			default:
				if(!scObj.Ori || typeof(scObj.Ori)==='number') ori = [0,0,1,0];
				else ori = scObj.Ori;
		}
		mission.displayModel.orientation = ori;
		mission.displayModel.fuel = this.sliderC;
		if(scObj.Anim) rot=99;
	}
	if(!scObj.Direct){
		this.shouldShow = false;
		this.avoidSecond = true;
		if(player.ship.docked) player.ship.dockedStation.setInterface("Snoopers",null);
		if(flagFIFO){
			this.priorityMessages = false;
			this.fifoNews.shift();
		}
		if(this.CRCNews.length){
			if(this.CRCNews.length>2){this.CRCNews.sort(function(){return Math.random()<0.5?-1:1}); this.CRCNews.shift();}
			if(Math.random()<0.6) this.CRCNews.shift();
		}
		this.calcNewDate();
	}
	if(rot){
		var ani;
		switch(rot){
			case 1: ani = [[1,'rot',[0,-1,600,0,0.006,0,0,20,20]],[40,'rot',[0,-1,40,0.004,0,0,0,20,20]],[601,0]]; break;
			case 2: ani = [[1,'rot',[0,-1,600,0,0.008,0.004,0,20,20]],[601,0]]; break;
			case 99: ani = scObj.Anim; break;
		}
		if(ani) worldScripts.Cabal_Common_Briefing.startBriefing({capture:1,briefing:ani,repRelative:1});
	}
	if(flagMV){
		var mv = 'snoopers_'+flagMV;
		missionVariables[mv] = null;
	}
	if(!this.checkStored || scObj.Recall){
		if(worldScripts[scObj.ID] && worldScripts[scObj.ID].newsDisplayed) worldScripts[scObj.ID].newsDisplayed(scObj.Message.substr(0,20));
	}
	if(scObj.ID!=='Internal') this.checkStored = scObj;
	this.snoopTimer = new Timer(this,this.doSnoopTimer,0.1);
	if(this.logging) log(this.name,this.name+": CRCs:"+this.CRCNews+" PriorityMessages:"+this.priorityMessages);
	return;
};
this.doSnoopTimer = function()
{
	if(!player.ship.docked) this.logBoos();
	else if(!mission.screenID || mission.screenID!=="snoopers") this.logBoos(2);
	delete this.snoopTimer;
};
this.logBoos = function(n)
{
	log(this.name,"REPORT Snoopers: "+JSON.stringify(this.checkStored));
	if(n) player.consoleMessage("This OXP screen has overriden a Snoopers screen. Please report it to the author.",10);
	else player.commsMessage("Oops. A Snoopers screen was killed by another OXP. This is a clash between OXPs - please report it.",10);
	return;
};
this.choiceEval = function(){worldScripts.snoopers.choiceEvaluation(); return;};
this.choiceEvaluation = function()
{
	delete this.checkStored;
};
/* Handle incoming messages from other OXPs. Snoopers stores up to 10 messages and 20 CRCs if .Direct is not used.
Parameters:		obj		- Object.
Returns:		n		- Number. Errorcode.
ID			- String. Required. worldScript Name.
Message		- String. Required. Message. Keynames will be expanded, mixtures are allowed, max length 900 chars, min length 10 chars.
Agency		- Number. Defines 1=GNN, 2=Rooters, 3=Snoopers. Disables custom pics and models.
Priority	- Number. 1=highest (bypasses CRC check and storing), used to sort the inserted news. Default 3.
Pic			- String. Overlay image, use tranparent areas if model should be used!!! Fileextension is required.
Music		- String. Music for Newsflash. Fileextension is required.
Model		- String. Model for Newsflash.
Pos			- Array. 3 valid numbers.
Ori			- Number/Array. Orientation of Model. If number: 1=[1,0,0,0], 2=[1,0,0,1], 4=[0,0,1,0], 8=[1,1,0,0]. Default 8. Otherwise Array with 4 valid numbers.
Recall		- Boolean. Resend callback in case other OXPs have overridden Snoopers screen and Replay got activated.
Direct		- Boolean. Display message directly without storing, CRC or other buffer checks. Requires to be docked.
Anim		- Array. Uses Cabal_Common_Briefing capture option. Ignored if .Direct is not used.
Errorcodes:
<0 - Snoopers buffers are full, oxp already placed a newsflash or CRC is still stored.
 0 - Success.
>0 - Error occured.
*/
this.insertNews = function(obj)
{
	var crc = 0, c = 0, i = 0, priflag = false;
	var desc=[{x:"",y:0}], ca="", cb, flagP, loop, m;
	var cList = ['ID','Agency','Priority','Message','Pic','Music','Model','Pos','Ori','Recall','Direct','Anim'];
	if(!obj.ID || !obj.Message) return(1);
	for(var prop in obj){
		if(cList.indexOf(prop)===-1) return(2);
		++c;
	}
	if(!c || c>cList.length) return(3);
	if(!worldScripts[obj.ID] || obj.ID===this.name) return(4);
	if(!obj.Direct){
		if(this.fifoNews.length>9) return(-5);
		if(obj.Priority && obj.Priority===1) priflag = true;
		if(!priflag){
			if(this.CRCNews.length>20) return(-3);
			crc = this.helper.strGetCRC(obj.ID);
			if(this.CRCNews.length && this.CRCNews.indexOf(crc)!==-1) return(-2);
		}
		obj.CRC = crc;
		if(this.fifoNews.length){
			i = this.fifoNews.length;
			while(i--) if(this.fifoNews[i].ID.indexOf(obj.ID)!==-1) return(-1);
		}
		delete obj.Anim;
		delete obj.Direct;
	}
	// Message handling
	m = obj.Message;
	if(typeof(m)!=='string') return(5);
	if(m.length<10 || m.length>900) return(6);
	m = m.trim();
	// String Expansion
	for(var se=0;se<m.length;se++){
		if(flagP){
			loop = 0;
			switch(m[se]){
				case "H":
				case "I":
				case "R":
				case "N": loop=1; break;
				case "J": loop=5; break;
				default: desc[desc.length-1].y = 0; loop=1;
			}
			for(var q=0;q<loop;q++) desc[desc.length-1].x += m[se+q];
			if(loop) se += loop-1;
			desc.push({x:"",y:0});
			flagP=0;
		} else switch(m[se]){
			case "[":
				desc.push({x:"",y:1});
				break;
			case "]":
				desc.push({x:"",y:0});
				break;
			case "%":
				desc.push({x:"",y:2});
				flagP=1;
				break;
			default: desc[desc.length-1].x += m[se];
		}
	}
	for(var p=0;p<desc.length;p++){
		if(desc[p].x){
			if(desc[p].y){
				cb = expandMissionText(desc[p].x);
				if(!cb){
					if(desc[p].y===2) cb = expandDescription("%"+desc[p].x);
					else cb = expandDescription("["+desc[p].x+"]");
				}
				ca += cb;
			} else ca += desc[p].x
		}
	}
	m = ca;
	if(!m || m==='') return(8);
	// Overlengthy (words)
	if(m.length>900) return(12);
	var overlength = m.split(' ');
	i = overlength.length;
	while(i--) if(overlength[i].length>79) return(13);
	// Linebreaks
	var strs = m.split('\n');
	if(strs.length>10) return(14);
	obj.Message = m;
	if(obj.Priority){
		c = parseInt(obj.Priority,null);
		if(isNaN(c) || c<1 || c>3) return(16);
	} else obj.Priority = 3;
	if(obj.Agency){
		c = parseInt(obj.Agency,null);
		if(isNaN(c) || c<1 || c>3) return(15);
		delete obj.Pic;
		delete obj.Music;
		delete obj.Model;
		delete obj.Pos;
	}
	if(obj.Pic){
		if(typeof(obj.Pic)!=='string') return(17);
		if(!obj.Pic.match('.png')) return(18);
	}
	if(obj.Music){
		if(typeof(obj.Music)!=='string') return(19);
		if(!obj.Music.match('.ogg')) return(20);
	}
	if(obj.Model){
		if(typeof(obj.Model)!=='string') return(21);
		if(obj.Pos){
			if(typeof(obj.Pos)!=='object') return(22);
			if(obj.Pos.length!==3) return(23);
			for(c=0;c<3;c++) if(typeof(obj.Pos[c])!=='number') return(24);
		}
		if(obj.Ori && obj.Ori!==null){
			if(typeof(obj.Ori)!=='number'){
				if(obj.Ori.constructor.name!=='Array') return(25);
				for(c=0;c<4;c++) if(typeof(obj.Ori[c])!=='number') return(24);
			} else if(obj.Ori<1 || obj.Ori>15) return(26);
		} else obj.Ori = 8;
	}
	if(obj.hasOwnProperty('Recall')){
		if(!obj.Recall) delete obj.Recall;
		else obj.Recall = 1;
	}
	if(!obj.Direct){
		this.fifoNews.push(obj);
		if(!priflag) this.CRCNews.push(crc);
		this.resort = true;
	} else {
		if(!player.ship.isValid) return(28);
		if(!player.ship.docked) return(29);
		if(guiScreen==='GUI_SCREEN_MISSION') return(30);
		this.showNewsScreen(obj);
	}
	return(0);
};
this.sortFIFO = function()
{
	var fl = this.fifoNews.length;
	if(fl && fl>1) this.fifoNews = this.helper.arrSortByProperty(this.fifoNews,'Priority');
	while(fl--) if(this.fifoNews[fl].Priority && this.fifoNews[fl].Priority===1) this.priorityMessages = true;
	if(this.logging) log(this.name,this.name+": PriorityMessages:"+this.priorityMessages);
	delete this.resort;
	this.oxpcNotifyOnChange(2);
	return;
};
this.shipEnteredStationAegis = function()
{
	var offset = clock.days-this.nextDate;
	if(offset<0 && !this.priorityMessages) return;
	var chance = 0.1*(offset?Math.abs(offset)*0.5:1)*Math.sqrt((this.sliderA?this.sliderA:1)*(this.fifoNews.length?this.fifoNews.length*3:1)*(this.CRCNews.length?this.CRCNews.length:1))*(this.priorityMessages?2:1);
	if(Math.random()<chance){
		worldScripts.Cabal_Common_Overlay.ovAdd({cclov_png:"ccl_ovi02.png",cclov_type:0,cclov_blend:5,cclov_id:"Snoopers",cclov_autoremove:1});
		worldScripts.Cabal_Common_Overlay.ovSpeak("Snoopers",5,"Special news report. Check your News Channel (F4) when docked.");
		this.peepShow();
	}
};
this.shipWillLaunchFromStation = function(station)
{
	if(this.checkStored) this.logBoos();
	if(this.snoopStation) station.setInterface("Snoopers",null);
	this.snoopStation = false;
	this.peepDone = false;
	if(this.logging) log(this.name,this.name+": Date:"+this.nextDate);
};
this.shipWillEnterWitchspace = function()
{
	delete this.avoidSecond;
	this.shouldShow = false;
};
this.oxpcNotifyOnChange = function(a)
{
	if((a&2) && (this.nextDate-clock.days)>this.sliderB){
		this.nextDate = parseInt(clock.days,null)+this.sliderB;
		if(this.logging) log(this.name,this.name+": New date: "+this.nextDate);
	}
	return;
};
this.oxpcSettings = {
	Info: {Name:"snoopers",Display:"Snoopers",Notify:true,
		InfoB:"4 established news agencies are bringing you the latest news. OXPs can insert newsflashes to be displayed via Snoopers.",
		InfoS:"General chance for newsflashes (0=never)\nMax. pause in days between newsflashes (0=no pause, but tends to 1)\nBrightness for Logo (0 disabled) - Shaders required."},
	Bool0: {Name:"logging",Def:false,Desc:"Logging functions."},
	Bool1: {Name:"audio",Def:true,Desc:"Music and sound for internal news."},
	Bool2: {Name:"extraA",Def:true,Desc:"Full mode for internal news."},
	SInt0: {Name:"sliderA",Def:0x3,Max:0xa,Desc:"Chance."},
	SInt1: {Name:"sliderB",Def:0x19,Max:0x20,Desc:"Max days."},
	SInt2: {Name:"sliderC",Def:0x4,Max:0x7,Desc:"Brightness."},
	cleanUp:{
		mv:["snoopers_dateCheck","snoopers_usedSlots","snoopers_CRCNews","snoopers1","snoopers2","snoopers4","snoopers8","snoopers16","snoopers32","snoopers64","snoopers128"]
	}
};
 |