| Path |
| Scripts/Lib_2DCollision.js |
/* jshint bitwise:false, forin:false */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_2DCollision";
/** _inBox() - Checks if point is inside the bounding box
@box - Array. 4 positions in a.x,a.y,b.x,b.y
@pos - Vector. Position to be checked
@return - Boolean. True if inside
*/
this._inBox = function(box,pos){
if(pos.x<box[0] || pos.x>box[1] || pos.y<box[2] || pos.y>box[3]) return false;
return true;
};
/** _inPoly() - Checks if a point is inside a polygon
@nvert - Number of vertices in the polygon
@vertx, verty - Arrays containing the x- and y-coordinates of the polygon's vertices
@pos - Vector. x- and y-coordinate of the test point
@con - Boolean. Concave shapes may need to set it
@return - Boolean. True if inside
*/
this._inPoly = function(nvert,vertx,verty,pos,con){
var i,j,c = false,r1=0;
for(i=0,j=nvert-1;i<nvert;j=i++){
if(((verty[i]>pos.y)!==(verty[j]>pos.y)) && (pos.x<(vertx[j]-vertx[i])*(pos.y-verty[i])/(verty[j]-verty[i])+vertx[i])){
c = !c;
r1++;
}
if(!con && r1>1) break;
}
return c;
};
/** _onLine() - Checks if point is on a specified line
@pa - Vector. Starting point of the line
@pb - Vector. End point of the line
@pc - Vector. Position to be checked
@tol - Number. Tolerance. Default 0.01
@return - Boolean. True if on line (within tolerance)
*/
this._onLine = function(pa,pb,pc,tol){
var s,rnum,denom,check,distLine,distSegment,dist1,dist2;
if(typeof(tol)!=='number') tol = 0.01;
rnum = (pc.x-pa.x)*(pb.x-pa.x)+(pc.y-pa.y)*(pb.y-pa.y);
denom = (pb.x-pa.x)*(pb.x-pa.x)+(pb.y-pa.y)*(pb.y-pa.y);
check = rnum/denom;
s = ((pa.y-pc.y)*(pb.x-pa.x)-(pa.x-pc.x)*(pb.y-pa.y))/denom;
distLine = Math.abs(s)*Math.sqrt(denom);
if(check>=0 && check<=1) distSegment = distLine;
else {
dist1 = (pc.x-pa.x)*(pc.x-pa.x)+(pc.y-pa.y)*(pc.y-pa.y);
dist2 = (pc.x-pb.x)*(pc.x-pb.x)+(pc.y-pb.y)*(pc.y-pb.y);
if(dist1<dist2) distSegment = Math.sqrt(dist1);
else distSegment = Math.sqrt(dist2);
}
return (distSegment<tol);
};
}).call(this);
|
| Scripts/Lib_Animator.js |
/* jshint bitwise:false, forin:false */
/* global _Animator,Sound,SoundSource,Timer,Vector3D,addFrameCallback,clock,isValidFrameCallback,mission,player,removeFrameCallback,setScreenBackground,setScreenOverlay,worldScripts */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_Animator";
/**
* TODO:
* Flags - append
* Fixme - modifyMaterials
*/
this._start = function(ani){
if(!player.ship.docked || !ani || !ani.model || !ani.flow || (this._a && !ani.replace && !ani.capture)) return false;
if((this._a && (!ani.replace || !ani.capture) ) && (!mission.displayModel || mission.displayModel.dataKey!==ani.model)) return false;
var obj = worldScripts.Lib_Main._lib.objClone(ani),hud,hudHide,i,msc;
if(this._a && (obj.replace || obj.capture)){
this._a.reset();
if(this.$anim){
hud = this.$anim.prevHUD;
hudHide = this.$anim.prevHUDHide;
}
this._cleanUp(1);
}
this._a = new this._Animator();
if(!obj.capture){
msc = {
background: null,
choices: (obj.choices?obj.choices:null),
choicesKey: (obj.choicesKey?obj.choicesKey:null),
model: (obj.model?obj.model:null),
music: (obj.music?obj.music:null),
overlay: null,
screenID: (obj.screenID?obj.screenID:"Lib_Animator"),
spinModel: false,
title: (obj.title?obj.title:"")
};
if(obj.text) msc.message = obj.text;
if(obj.background){
msc.background = obj.background;
this._a.bg.name = obj.background;
}
if(obj.overlay){
msc.overlay = obj.overlay;
this._a.ov.name = obj.overlay;
}
if(obj.fadeIn) msc.overlay = {name:"lib_blend10.png",width:1024,height:512};
}
this.$anim = {
count: 0,
index: 0,
flow: obj.flow,
caller: (obj.caller?obj.caller:null),
callback: (obj.callback?obj.callback:null),
checkpoint: (obj.checkpoint?obj.checkpoint:null),
prevHUD: (hud?hud:player.ship.hud),
prevHUDHide: (typeof hudHide!=="undefined"?hudHide:player.ship.hudHidden),
custom: obj.custom,
capture: obj.capture?obj.capture:null,
md: obj.model
};
if(!obj.capture){
if(obj.hud){
player.ship.hud = obj.hud;
player.ship.hudHidden = false;
} else player.ship.hudHidden = true;
mission.runScreen(msc,this._choiceEval);
}
if(!mission.displayModel) return false;
this._a.init(mission.displayModel);
this.$waitUntil = -1;
if(obj.corner) this._a.screenCornerPos(obj.corner);
if(obj.aPos) for(i=0;i<obj.aPos.length;i++) this._a.setPosition(obj.aPos[i]);
if(obj.aExh) for(i=0;i<obj.aExh.length;i++) this._a.setExhaust(obj.aExh[i]);
if(obj.aOris) for(i=0;i<obj.aOris.length;i++) this._a.setOrientation(obj.aOris[i]);
if(obj.aBinds) for(i=0;i<obj.aBinds.length;i++) this._a.setBinding(obj.aBinds[i]);
if(obj.aProps) for(i=0;i<obj.aProps.length;i++) this._a.setProp(obj.aProps[i]);
if(obj.bPos) for(i=0;i<obj.bPos.length;i++) this._a.setPosition(obj.bPos[i]);
if(obj.bOris) for(i=0;i<obj.bOris.length;i++) this._a.setOrientation(obj.bOris[i]);
if(obj.bBinds) for(i=0;i<obj.bBinds.length;i++) this._a.setBinding(obj.bBinds[i]);
if(obj.bProps) for(i=0;i<obj.bProps.length;i++) this._a.setProp(obj.bProps[i]);
if(obj.shadeMaps) for(i=0;i<obj.shadeMaps.length;i++) this._a.setShaderProp(obj.shadeMaps[i]);
if(obj.pilots) for(i=0;i<obj.pilots.length;i++) this._a._setPilot(obj.pilots[i]);
if(obj.subRots) for(i=0;i<obj.subRots.length;i++) this._a.subs[obj.subRots[i].e].subEntityRotation = obj.subRots[i].r;
if(obj.subTex) for(i=0;i<obj.subTex.length;i++) this._a.setMaterials(obj.subTex[i]);
this.$sndA = new SoundSource();
this.$sndB = new SoundSource();
if(obj.delta) this._a.defDelta = obj.delta;
else this._a.defDelta = 0.005;
if(!this.$animTimer) this.$animTimer = new Timer(this,this._doAnimTimer,0,0.25);
else this.$animTimer.start();
return true;
};
this._cleanUp = function(all){
if(this.$animTimer) this.$animTimer.stop();
delete this.$animTimer;
if(all){
delete this.$anim;
delete this.$sndA;
delete this.$sndB;
delete this._a;
}
};
this._choiceEval = function(choice){worldScripts.Lib_Animator._choice(choice); return;};
this._choice = function(choice){
this._a.reset();
player.ship.hud = this.$anim.prevHUD;
player.ship.hudHidden = this.$anim.prevHUDHide;
var a = this.$anim.caller, b = this.$anim.callback;
this._cleanUp(1);
if(a && b) worldScripts[a][b](choice);
return;
};
this._doAnimTimer = function(){
if(!this.$anim.flow.length || !mission.displayModel || !mission.displayModel.isValid || this.$anim.index>=this.$anim.flow.length){
this._a.reset();
this._cleanUp();
return;
}
var cur = this.$anim.flow[this.$anim.index],i,p;
if(this.$anim.count >= cur[0]){
// [time,cmd,obj,other]
switch(cur[1]){
case "reset": this._a.reset(); break;
case "clr": this._a.clear(); break;
case "clrMov": this._a.clearMoves(); break;
case "kill": // Get CPU usage down
if(this.$anim.index===this.$anim.flow.length-1){
mission.displayModel.remove();
if(cur[2] && cur[2].txt) mission.addMessageText(cur[2].txt);
}
break;
case "rotw": this._a.rotateW(cur[2]); break;
case "rot": this._a.rotate(cur[2]); break;
case "rotTo": this._a.rotateTo(cur[2]); break;
case "rotX": this._a.rotateXDeg(cur[2]); break;
case "rotY": this._a.rotateYDeg(cur[2]); break;
case "rotZ": this._a.rotateZDeg(cur[2]); break;
case "stopRot": this._a.stopRotate(cur[2]); break;
case "fly": this._a.flight(cur[2]); break;
case "flyTo": this._a.flightTo(cur[2]); break;
case "stopFly": this._a.stopFlight(cur[2]); break;
case "velo": this._a.velocity(cur[2]); break;
case "veloTo": this._a.velocityTo(cur[2]); break;
case "veloSet": this._a.setVelocity(cur[2]); break;
case "stopVelo": this._a.stopVelocity(cur[2]); break;
case "walk": this._a.walk(cur[2]); break;
case "walkTo": this._a.walkTo(cur[2]); break;
case "stopWalk": this._a.stopWalk(cur[2]); break;
case "aiDest": this._a.aiDestination(cur[2]); break;
case "aiFace": this._a.aiFace(cur[2]); break;
case "aiFly": this._a.aiFly(cur[2]); break;
case "aiHold": this._a.aiHold(cur[2]); break;
case "aiRange": this._a.aiRange(cur[2]); break;
case "aiSpeed": this._a.aiSpeed(cur[2]); break;
case "aiStop": this._a.aiStop(cur[2]); break;
case "zoom": this._a.zoom(cur[2]); break;
case "zoomTo": this._a.zoomTo(cur[2]); break;
case "stopZoom": this._a.stopZoom(cur[2]); break;
case "prop": this._a.setProp(cur[2]); break;
case "matSet": this._a.setMaterials(cur[2]); break;
case "matMod": this._a.modifyMaterials(cur[2]); break;
case "lit": this._a.highlight(cur[2]); break;
case "tex": this._a.setTextures(cur[2]); break;
case "shadeSet": this._a.setShader(cur[2]); break;
case "shadeMod": this._a.setShaderProp(cur[2]); break;
case "sun": this._a.sun(cur[2]); break;
case "twinkle": this._a.twinkle(cur[2]); break;
case "moon": this._a.moon(cur[2]); break;
case "boom": this._a.explosion(cur[2]); break;
case "hyper":
this._a.hyper(cur[2]);
this.$sndB.playSound("[bgs_fxWitch]");
break;
case "shoot":
var d = [0.00001,clock.absoluteSeconds,0];
//if(cur[2].rear) d[2] = cur[2].rear;
if(this._a.cur[cur[2].tg].ang>0.098){
this.$sndA.playSound("[player-laser-miss]");
} else {
d[0] = 1/this._a.cur[cur[2].tg].mag;
this.$sndA.playSound("[player-laser-hit]");
}
this._a.setProp({e:cur[2].e,p:"destination",v:d});
break;
case "laser":
var act, tg, mag, ang, v;
var d = [0.00001,clock.absoluteSeconds,0];
if(cur[2].e>-1) act = this._a.subs[cur[2].e];
else act = this._a.ent;
if(cur[2].tg>-1) tg = this._a.subs[cur[2].tg];
else tg = this._a.ent;
v = act.position.subtract(tg.position).direction().multiply(-1);
mag = act.position.subtract(tg.position).magnitude();
ang = act.heading.angleTo(v);
if(ang>0.098){
this.$sndA.playSound("[player-laser-miss]");
} else {
d[0] = 1/mag;
this.$sndA.playSound("[player-laser-hit]");
}
this._a.setProp({e:cur[2].e,p:"destination",v:d});
break;
case "bind": this._a.setBinding(cur[2]); break;
case "stopBind": this._a.stopBinding(cur[2]); break;
case "pos": this._a.setPosition(cur[2]); break;
case "posTo": this._a.setPositionTo(cur[2]); break;
case "posFl": this._a.setFlasherPositionTo(cur[2]); break;
case "ori": this._a.setOrientation(cur[2]); break;
case "snap": this._a.snapIn(cur[2]); break;
case "bg": this._a.setBackground(cur[2]); break;
case "bgZoom": this._a.zoomBackground(cur[2]); break;
case "bgZoomTo": this._a.zoomBackgroundTo(cur[2]); break;
case "bgStop": this._a.stopBackground(); break;
case "bgClr": this._a.clearBackground(); break;
case "bgRes": this._a.resetBackground(cur[2]); break;
case "ov": this._a.setOverlay(cur[2]); break;
case "ovZoom": this._a.zoomOverlay(cur[2]); break;
case "ovStop": this._a.stopOverlay(); break;
case "ovClr": this._a.clearOverlay(); break;
case "ovFadeIn": this._a.fadeIn(cur[2]); break;
case "ovFadeOut": this._a.fadeOut(cur[2]); break;
case "corner": this._a.screenCornerPos(cur[2]); break;
case "txt": mission.addMessageText(cur[2]); break;
case "snd1": this.$sndA.playSound(cur[2].snd); break;
case "snd2": this.$sndB.playSound(cur[2].snd); break;
case "mus": Sound.playMusic(cur[2].snd); break;
case "custom": this.$anim.custom[cur[2]](); break;
case "goto": this._goto(cur[2]); break;
case "check":
var ch = false;
if(this.$anim.caller && this.$anim.checkpoint) ch = worldScripts[this.$anim.caller][this.$anim.checkpoint](cur[0]);
if(typeof ch==='number') this._goto(ch);
else {
if(!ch){this._a.reset(); this._cleanUp();}
}
break;
case "waitExt":
if(this.$waitUntil>-1){
this._goto(this.$waitUntil);
this.$waitUntil = -1;
} else {
this.$anim.index--;
this.$anim.count--;
}
break;
case "speak":
this._a._pilotSpeak(cur[2]);
if(cur[2].snd) this.$sndB.playSound(cur[2].snd);
break;
}
if(cur[3]){
for(i=0;i<cur[3].length;i++){
p = cur[3][i];
switch(p.id){
case "txt": mission.addMessageText(p.txt); break;
case "snd1": this.$sndA.playSound(p.snd); break;
case "snd2": this.$sndB.playSound(p.snd); break;
case "mus": Sound.playMusic(p.snd); break;
}
}
}
this.$anim.index++;
}
this.$anim.count++;
return;
};
this._goto = function(cmp){
var from,to;
if(cmp>this.$anim.count){
from = this.$anim.index;
to = this.$anim.flow.length;
} else {
from = 0;
to = this.$anim.index;
}
for(var i=from;i<to;i++){
if(this.$anim.flow[i][0]===cmp){
this.$anim.index = i-1;
this.$anim.count = cmp-1;
break;
}
}
};
/** Animation API
*/
this._Animator = function(){};
_Animator.prototype = {
constructor: _Animator,
w: 1024,
h: 512,
fcb: 0,
fcbs: [],
bg: {name:null,width:this.w,height:this.h,mw:1,mh:1},
ov: {name:null,width:this.w,height:this.h,mw:1,mh:1},
ovFade: {n:10,dir:1,t:2,cur:0},
defDelta: 0.005,
ent: null,
subs: null,
flow: {
bind:{},
flight:{},
props:{},
rotate:{},
velocity:{},
walk:{},
zoom:{},
bg:{},
ov:{},
aiDest:{}
},
cur: {},
/** ent = Entity. Must be called before anything else!
*/
init: function(ent){
this.cur = {"-1":{mf:0,ang:0,mag:0,tOri:null}};
this.ent = ent;
if(ent.subEntities && ent.subEntities.length){
this.subs = ent.subEntities;
for(var i=0;i<ent.subEntities.length;i++) this.cur[i] = {mf:0,ang:0,mag:0,tOri:null};
}
else this.subs = null;
this.w = 1024;
this.h = 512;
this.bg.width = this.w;
this.bg.height = this.h;
this.ov.width = this.w;
this.ov.height = this.h;
},
reset: function(){
this.clear();
this.bg = {name:null,width:this.w,height:this.h,mw:1,mh:1};
this.ov = {name:null,width:this.w,height:this.h,mw:1,mh:1};
this.ovFade = {n:10,dir:1,t:2,cur:0};
this.ent = null;
this.subs = null;
this.defDelta = 0.005;
},
clear: function(){
this._removeFCBs();
this.flow = {
bind:{},
flight:{},
props:{},
rotate:{},
velocity:{},
walk:{},
zoom:{},
bg:{},
ov:{},
aiDest:{}
};
},
clearMoves: function(){
var m = ["flight","rotate","velocity","walk","zoom","aiDest"],k;
for(var o=0;o<m.length;o++){
k = Object.keys(this.flow[m[o]]);
for(var i=0;i<k.length;i++){
this._stopIt({e:k[i]},m[o]);
}
}
},
/** e, t, rx,ry,rz [, z, da, db] World!
*/
rotateW: function(obj){
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].rx) act.orientation = act.orientation.rotateX(c[4].rx*da*db*bz*f);
if(c[4].ry) act.orientation = act.orientation.rotateY(c[4].ry*da*db*bz*f);
if(c[4].rz) act.orientation = act.orientation.rotateZ(c[4].rz*da*db*bz*f);
return;
});
this._addTo("rotate",this.fcb,obj);
return true;
},
/** e, t, rx,ry,rz [, z, da, db] Model!
*/
rotate: function(obj){
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].rx) act.orientation = act.orientation.rotate(act.vectorRight,c[4].rx*da*db*bz*f);
if(c[4].ry) act.orientation = act.orientation.rotate(act.vectorUp,c[4].ry*da*db*bz*f);
if(c[4].rz) act.orientation = act.orientation.rotate(act.vectorForward,c[4].rz*da*db*bz*f);
return;
});
this._addTo("rotate",this.fcb,obj);
return true;
},
/** e, t, tg [, z, da, db, s]
*/
rotateTo: function(obj){
this._stopIt(obj,"rotate");
if(!obj.tg.isShip){
if(typeof obj.tg==='number') obj.tg = this.subs[obj.tg];
else if(obj.tg.constructor.name==="Array") obj.tgv = new Vector3D(obj.tg);
}
var c = [this.ent,this.subs,0,this.defDelta,obj,this.cur[obj.e]];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid || !c[4].tg || (!c[4].tg.isValid && !c[4].tgv)) return;
var f=1, bz=1, da=1, db=1, act, v, a, cr, steps = 0.01;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].tgv){
v = act.position.subtract(c[4].tgv).direction().multiply(-1);
c[5].mag = act.position.subtract(c[4].tgv).magnitude();
} else {
v = act.position.subtract(c[4].tg.position).direction().multiply(-1);
c[5].mag = act.position.subtract(c[4].tg.position).magnitude();
}
a = act.heading.angleTo(v);
c[5].ang = a;
if(c[4].z) bz = 1-1/Math.sqrt(Math.max(Math.abs(act.position.z),0.001));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].s) steps = c[4].s*da;
cr = act.heading.cross(v);
act.orientation = act.orientation.rotate(cr,-a*steps*f*bz*da*db);
return;
});
this._addTo("rotate",this.fcb,obj);
return true;
},
/** e, t, deg [, z, da, db, inf] World!
*/
rotateXDeg: function(obj){
if(obj.e>-1) obj.nt = this.subs[obj.e].orientation.rotateX(0.017453293916206696*obj.deg);
else obj.nt = this.ent.orientation.rotateX(0.017453293916206696*obj.deg);
if(obj.inf) this.cur[obj.e].tOri = obj.nt;
obj.st = obj.deg/(obj.t*1000);
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act, sp;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
sp = act.orientation.dot(c[4].nt);
if(sp>0.999) return;
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].deg) act.orientation = act.orientation.rotateX(c[4].st*da*db*bz*f);
return;
});
this._addTo("rotate",this.fcb,obj);
return true;
},
/** e, t, deg [, z, da, db, inf] World!
*/
rotateYDeg: function(obj){
if(obj.e>-1) obj.nt = this.subs[obj.e].orientation.rotateY(0.017453293916206696*obj.deg);
else obj.nt = this.ent.orientation.rotateY(0.017453293916206696*obj.deg);
if(obj.inf) this.cur[obj.e].tOri = obj.nt;
obj.st = obj.deg/(obj.t*1000);
// obj.st = ((0.017453293916206696*obj.deg)/obj.t)*this.defDelta;
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act, sp;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
sp = act.orientation.dot(c[4].nt);
if(sp>0.9999) return;
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].deg) act.orientation = act.orientation.rotateY(c[4].st*da*db*bz*f);
return;
});
this._addTo("rotate",this.fcb,obj);
return true;
},
/** e, t, deg [, z, da, db, inf] World!
*/
rotateZDeg: function(obj){
if(obj.e>-1) obj.nt = this.subs[obj.e].orientation.rotateZ(0.017453293916206696*obj.deg);
else obj.nt = this.ent.orientation.rotateZ(0.017453293916206696*obj.deg);
if(obj.inf) this.cur[obj.e].tOri = obj.nt;
obj.st = obj.deg/(obj.t*1000);
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act, sp;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
sp = act.orientation.dot(c[4].nt);
if(sp>0.999) return;
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].deg) act.orientation = act.orientation.rotateZ(c[4].st*da*db*bz*f);
return;
});
this._addTo("rotate",this.fcb,obj);
return true;
},
/** e
*/
stopRotate: function(obj){
this._stopIt(obj,"rotate");
return true;
},
/** e, t, mu,mr,mf, rx,ry,rz [,da, db, z, fu, en]
*/
flight: function(obj){
this.rotate(obj);
this.velocity(obj);
},
/** e, t, tg, s, mu,mr,mf [, da, db, z, fu, en]
*/
flightTo: function(obj){
this.rotateTo(obj);
this.velocityTo(obj);
},
/** e
*/
stopFlight: function(obj){
this.stopVelocity(obj);
this.stopRotate(obj);
return true;
},
aiDestination: function(obj){
var act;
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
this._stopIt(obj,"aiDest");
if(obj.dest){
if(typeof obj.dest==='number') act.destination = this.subs[obj.dest];
else act.destination = obj.dest;
} else {
var c = [this.ent,this.subs,0,this.defDelta,obj,0];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var act, st;
c[2] += delta;
c[5]++;
// Updating only every 50. framecallback!!!
if(c[2]>=c[4].t || c[5]<50) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
act.destination = c[1][c[4].tg].position;
c[5] = 0;
return;
});
this._addTo("aiDest",this.fcb,obj);
}
},
aiFace: function(obj){
this.aiDestination(obj);
if(obj.e>-1) this.subs[obj.e].performFaceDestination();
else this.ent.performFaceDestination();
},
aiFly: function(obj){
this.aiSpeed(obj);
this.aiRange(obj);
this.aiDestination(obj);
var act;
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.performFlyToRangeFromDestination();
},
aiHold: function(obj){
if(obj.e>-1) this.subs[obj.e].performHold();
else this.ent.performHold();
this._stopIt(obj,"aiDest");
},
aiRange: function(obj){
if(obj.e>-1) this.subs[obj.e].desiredRange = obj.rng;
else this.ent.desiredRange = obj.rng;
},
aiSpeed: function(obj){
if(obj.e>-1) this.subs[obj.e].desiredSpeed = obj.spd;
else this.ent.desiredSpeed = obj.spd;
},
aiStop: function(obj){
if(obj.e>-1) this.subs[obj.e].performStop();
else this.ent.performStop();
this._stopIt(obj,"aiDest");
},
/** e, t, mu,mr,mf [,da, db, z, fu, en]
*/
velocity: function(obj){
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].mu) act.velocity = act.vectorUp.multiply(c[4].mu*bz*da*db*f);
if(c[4].mr) act.velocity = act.vectorRight.multiply(c[4].mr*bz*da*db*f);
if(c[4].mf) act.velocity = act.vectorForward.multiply(c[4].mf*bz*da*db*f);
if(c[4].fu) act.fuel = (act.velocity.magnitude()/act.maxSpeed)*7;
if(c[4].en) act.energy = (act.velocity.magnitude()/act.maxSpeed)*act.maxEnergy;
return;
});
this._addTo("velocity",this.fcb,obj);
return true;
},
/** e, t, tg, mu,mr,mf [, da, db, z, fu, en]
*/
velocityTo: function(obj){
this._stopIt(obj,"velocity");
var x;
if(!obj.tg.isShip){
if(typeof obj.tg==='number') obj.tg = this.subs[obj.tg];
else if(obj.tg.constructor.name==="Array") obj.tgv = new Vector3D(obj.tg);
} else if(obj.tg.isInSpace) obj.tgv = obj.tg.position;
if(obj.e>-1) x = this.subs[obj.e].velocity.magnitude();
else x = this.ent.velocity.magnitude();
if(x>1) obj.da = obj.da/x;
var c = [this.ent,this.subs,0,this.defDelta,obj,this.cur[obj.e],0];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid || c[6]) return;
var f=1, bz=1, da=1, db=1, act, col, v, dist, mul,slow, check;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
col = act.collisionRadius;
if(c[4].tgv) v = c[4].tgv;
else v = c[4].tg;
if(c[4].tg.isInSpace) col += c[4].tg.collisionRadius;
dist = act.position.distanceTo(v);
if(dist<col*4){
f *= 1/(col*4/dist);
slow = 1;
}
if(dist<col){
if(!c[6]){
act.velocity = [0,0,0];
c[6] = 1;
if(c[4].fu) act.fuel = 0;
if(c[4].en) act.energy = 0;
c[5].mf = 0;
}
return;
}
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
mul = bz*da*db*f;
if(c[4].mu) act.velocity = act.vectorUp.multiply(c[4].mu*mul);
if(c[4].mr) act.velocity = act.vectorRight.multiply(c[4].mr*mul);
if(c[4].mf){
check = c[4].mf*mul;
if(!slow && c[5].mf>check) check = c[5].mf;
act.velocity = act.vectorForward.multiply(check);
c[5].mf = check;
}
if(c[4].fu) act.fuel = (act.velocity.magnitude()/act.maxSpeed)*7;
if(c[4].en) act.energy = (act.velocity.magnitude()/act.maxSpeed)*act.maxEnergy;
return;
});
this._addTo("velocity",this.fcb,obj);
return true;
},
/** e, velo
*/
setVelocity: function(obj){
this._stopIt(obj,"velocity");
if(obj.e>-1) this.ent.subEntities[obj.e].velocity = obj.velo;
else this.ent.velocity = obj.velo;
return true;
},
/** e
*/
stopVelocity: function(obj){
this._stopIt(obj,"velocity");
if(obj.e>-1) this.ent.subEntities[obj.e].velocity = [0,0,0];
else this.ent.velocity = [0,0,0];
return true;
},
/** e, t, st [,z, da, db]
*/
walk: function(obj){
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act, up,rol, mul, steps;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
steps = Math.floor(c[2]);
if(c[2]>=c[4].t || steps>=c[4].st) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
mul = Math.PI*bz*da*db*f;
rol = Math.cos(c[2]*mul);
up = Math.cos(c[2]*3*mul);
act.position = act.position.subtract([rol*0.05,up*0.15,mul*0.15]);
return;
});
this._addTo("walk",this.fcb,obj);
return true;
},
walkTo: function(){},
/** e
*/
stopWalk: function(obj){
this._stopIt(obj,"walk");
return true;
},
/** e, t, mz [, z, da, db]
*/
zoom: function(obj){
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, bz=1, da=1, db=1, act, mf=1;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].z) bz = Math.sqrt(Math.abs(act.position.z));
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(c[4].mz>1) mf = 1+(da*db*bz*(c[4].mz%1));
else mf = 1-(f*da*db*bz*(1%c[4].mz));
act.position = act.position.multiply(mf);
return;
});
this._addTo("zoom",this.fcb,obj);
return true;
},
zoomTo: function(){},
/** e
*/
stopZoom: function(obj){
this._stopIt(obj,"zoom");
return true;
},
/** e, p, v [, t, da, db]
*/
setProp: function(obj){
if(!obj.t){
if(obj.e>-1) this.subs[obj.e][obj.p] = obj.v;
else this.ent[obj.p] = obj.v;
} else {
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, da=1, db=1, act;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].da && c[2]<c[4].da) da = 1-((c[4].da-c[2])/c[4].da);
if(c[4].db && c[2]>c[4].t-c[4].db) db = (c[4].t-c[2])/c[4].db;
if(typeof act[c[4].p]==='number') act[c[4].p] += c[4].v*f*da*db/c[4].t;
else act[c[4].p] = act[c[4].p].multiply(c[4].v*f*da*db/c[4].t); // TODO check
return;
});
this._addTo("props",this.fcb,obj);
}
return true;
},
/** e, mat, sha
*/
setMaterials: function(obj){
var act;
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
if(obj.mat && obj.sha) act.setMaterials(obj.mat,obj.sha);
else if(obj.mat) act.setMaterials(obj.mat,{});
else if(obj.sha) act.setMaterials({},obj.sha);
return true;
},
/** e, prop
* i, p, v
*/
modifyMaterials: function(obj,prop){
var m = this._getMaterials(obj),k = Object.keys(m),w;
if(!k.length) return;
for(var o=0;o<obj.prop.length;o++){
w = obj.prop[o];
m[k[w.i]][w.p] = w.v;
}
this._setMaterials(obj,m);
},
/** e, mat, tex, col
*/
highlight: function(obj){
var act,m;
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
m = act.getMaterials();
m[obj.mat].emission_map = obj.tex;
m[obj.mat].emission_modulate_color = obj.col;
act.setMaterials(m);
},
setTextures: function(obj){},
/** e, sha [, rep]
*/
setShader: function(obj){
if(obj.rep){
var k = Object.keys(obj.sha),w,h,v;
for(var o=0;o<k.length;o++){
w = obj.sha[k[o]].uniforms;
h = Object.keys(w);
for(var i=0;i<h.length;i++){
v = obj.sha[k[o]].uniforms[h[i]];
if(v.value==="p1") v.value = clock.absoluteSeconds-1;
}
}
}
if(obj.e>-1) this.subs[obj.e].setShaders(obj.sha);
else this.ent.setShaders(obj.sha);
return true;
},
/** e, tex (Array), uni (Array), val (Array)
*/
setShaderProp: function(obj){
var a,b,flagM,i;
a = this._getShaders(obj);
b = Object.keys(a);
if(!b.length){
a = this._getMaterials(obj);
flagM = 1;
b = Object.keys(a);
}
if(!b.length) return false;
if(obj.tex) for(i=0;i<obj.tex.length;i++) a[b[0]].textures = obj.tex;
if(obj.uni) for(i=0;i<obj.uni.length;i++) a[b[0]].uniforms[obj.uni[i]].value = obj.val[i];
if(flagM){
if(obj.e>-1) this.subs[obj.e].setMaterials(a);
else this.ent.setMaterials(a);
} else {
if(obj.e>-1) this.subs[obj.e].setShaders(a);
else this.ent.setShaders(a);
}
return true;
},
/** e, id, scale, pos
*/
explosion: function(obj){
var act,sha = {};
sha[obj.id] = {
fragment_shader:"lib_ms_whexit.fs",
vertex_shader:"lib_ms_bbT.vs",
textures:["lib_explode2.png"],
uniforms:{
colorMap:{type:"texture",value:0},
Time:{binding:"universalTime"},
Dest:{binding:"destination",bindToSubentity:true,normalized:false}}};
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.destination = [2,clock.absoluteSeconds-1,obj.scale];
act.setShaders(sha);
if(obj.pos) act.position = obj.pos;
},
/** e, id, scale, pos
*/
hyper: function(obj){
var act,sha = {};
sha[obj.id] = {
fragment_shader:"lib_ms_whexit.fs",
vertex_shader:"lib_ms_bbT.vs",
textures:["lib_hyper.png"],
uniforms:{
colorMap:{type:"texture",value:0},
Time:{binding:"universalTime"},
Dest:{binding:"destination",bindToSubentity:true,normalized:false}}};
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.destination = [6,clock.absoluteSeconds-1,obj.scale];
act.setShaders(sha);
if(obj.pos) act.position = obj.pos;
},
/** e, id, scale, pos, col
*/
sun: function(obj){
var act,sha = {};
sha[obj.id] = {
fragment_shader:"lib_ms_sun.fs",
vertex_shader:"lib_ms_bbT.vs",
uniforms:{
Suncolor:{type:"vector",value:obj.col},
Time:{type:"float",value:0},
Dest:{binding:"destination",bindToSubentity:true,normalized:false}}};
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.destination = [1,1,obj.scale];
act.setShaders(sha);
if(obj.pos) act.position = obj.pos;
},
/** e, id, scale, pos, col
*/
twinkle: function(obj){
var act,sha = {};
sha[obj.id] = {
fragment_shader:"lib_ms_bg_twinkle.fs",
vertex_shader:"lib_ms_bbT.vs",
uniforms:{
Time:{binding:"universalTime"},
Dest:{binding:"destination",bindToSubentity:true,normalized:false}}};
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.destination = [99999999,0,obj.scale];
act.setShaders(sha);
if(obj.pos) act.position = obj.pos;
},
/** e, id, scale, pos, col
*/
moon: function(obj){
var act,sha = {};
sha[obj.id] = {
fragment_shader:"lib_ms_moon.fs",
vertex_shader:"lib_ms_moon.vs",
textures:[{name:obj.tex,cube_map:true}],
uniforms:{
colorMap:{type:"texture",value:0},
Suncolor:{type:"vector",value:obj.col},
Scale:{type:"float",value:obj.scale}}};
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.setShaders(sha);
if(obj.pos) act.position = obj.pos;
},
/** e, t, tg, [exh, fe, dist, swap]
*/
setBinding: function(obj){
if(typeof obj.tg==='number'){
if(obj.tg>-1) obj.tg = this.subs[obj.tg];
else obj.tg = this.ent;
}
if(obj.dist){
if(obj.e>-1) obj.distv = this.subs[obj.e].position.subtract(obj.tg.position);
else obj.distv = obj.tg.position;
}
var c = [this.ent,this.subs,0,this.defDelta,obj];
this.fcb = addFrameCallback(function(delta){
if(!delta || !c[0] || !c[0].isValid) return;
var f=1, act, p, o, s = 0;
if(c[3]>delta) f = 1/(c[3]/delta);
else f = 1-(c[3]-delta);
c[2] += delta;
if(c[2]>=c[4].t) return;
if(c[4].e>-1) act = c[1][c[4].e];
else act = c[0];
if(c[4].fe){
act.fuel = c[4].tg.fuel;
act.energy = c[4].tg.energy;
}
if(c[4].exh){
if(c[4].tg.desiredSpeed) s = c[4].tg.speed+1;
act.fuel = (s/c[4].tg.maxSpeed)*0.7;
act.energy = (s/c[4].tg.maxSpeed)*c[4].tg.maxEnergy;
}
if(c[4].dsor){
act.destination = c[4].tg.position;
act.energy = 0;
}
if(c[4].distv){
o = c[4].tg.orientation;
if(c[4].swap) o = o.rotate(c[4].tg.vectorUp,-Math.PI);
act.orientation = o;
p = c[4].tg.position.add(c[4].distv.rotateBy(o));
act.position = p;
}
return;
});
this._addTo("bind",this.fcb,obj);
return true;
},
/** e
*/
stopBinding: function(obj){
this._stopIt(obj,"bind");
return true;
},
/** e, pos
*/
setPosition: function(obj){
if(obj.e>-1) this.subs[obj.e].position = obj.pos;
else this.ent.position = obj.pos;
return true;
},
/** e, tg, ex, p
*/
setExhaust: function(obj){
if(obj.e>-1){
this.subs[obj.e].position = this.subs[obj.tg].exhausts[obj.ex].position;
this.subs[obj.e][obj.p] = this.subs[obj.tg].exhausts[obj.ex].size.multiply(0.11764); // .dat 1/8.5
}
return true;
},
/** e, tg [, off]
*/
setPositionTo: function(obj){
var pos;
if(obj.tg>-1) pos = this.subs[obj.tg].position;
else pos = this.ent.position;
if(obj.off) pos.add(obj.off);
if(obj.e>-1) this.subs[obj.e].position = pos;
else this.ent.position = pos;
return true;
},
/** e, f, tg [, off]
*/
setFlasherPositionTo: function(obj){
var pos;
if(obj.tg>-1) pos = this.subs[obj.tg].position;
else pos = this.ent.position;
if(obj.off) pos = pos.add(obj.off);
if(obj.e>-1) this.subs[obj.e].flashers[obj.f].position = pos;
else this.ent.flashers[obj.f].position = pos;
return true;
},
/** e, ori
*/
setOrientation: function(obj){
if(obj.e>-1) this.subs[obj.e].orientation = obj.ori;
else this.ent.orientation = obj.ori;
return true;
},
/** e, inf
*/
snapIn: function(obj){
this._stopIt(obj,"rotate");
var act,ori;
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
ori = act.orientation;
ori.w = this._snapIn(ori.w);
ori.x = this._snapIn(ori.x);
ori.y = this._snapIn(ori.y);
ori.z = this._snapIn(ori.z);
act.orientation = ori;
},
/** n
*/
setBackground: function(obj){
this.bg.name = obj.n;
setScreenBackground(this.bg);
},
/** mw, mh [, n]
*/
zoomBackground: function(obj){
this.bg.mw = obj.mw;
this.bg.mh = obj.mh;
if(obj.n) this.bg.name = obj.n;
this.fcb = addFrameCallback(this._zoomBG.bind(this));
this.fcbs.push(this.fcb);
this.flow.bg["-1"] = [this.fcb];
},
zoomBackgroundTo: function(){},
/**
*/
stopBackground: function(){
this._stopIt({e:-1},"bg");
},
/**
*/
clearBackground: function(){
this.stopBackground();
setScreenBackground(null);
},
resetBackground: function(obj){
this.stopBackground();
this.bg = {name:null,width:this.w,height:this.h,mw:1,mh:1};
if(obj && obj.n) this.setBackground(obj);
},
/** n
*/
setOverlay: function(obj){
this.ov.name = obj.n;
setScreenOverlay(this.ov);
},
/** mw, mh [, n]
*/
zoomOverlay: function(obj){
this.ov.mw = obj.mw;
this.ov.mh = obj.mh;
if(obj.n) this.ov.name = obj.n;
this.fcb = addFrameCallback(this._zoomOV.bind(this));
this.fcbs.push(this.fcb);
this.flow.ov["-1"] = [this.fcb];
},
/**
*/
stopOverlay: function(){
this._stopIt({e:-1},"ov");
},
/**
*/
clearOverlay: function(){
this.stopOverlay();
setScreenOverlay(null);
},
/** t
*/
fadeIn: function(obj){
this._stopIt({e:-1},"ov");
this.ov = {name:"lib_blend0.png",width:this.w,height:this.h,mw:1,mh:1};
this.ovFade = {n:0,dir:1,t:obj.t};
this.fcb = addFrameCallback(this._fadeOV.bind(this));
this.fcbs.push(this.fcb);
this.flow.ov["-1"] = [this.fcb];
},
/** t
*/
fadeOut: function(obj){
this._stopIt({e:-1},"ov");
this.ov = {name:"lib_blend10.png",width:this.w,height:this.h,mw:1,mh:1};
this.ovFade = {n:0,dir:0,t:obj.t};
this.fcb = addFrameCallback(this._fadeOV.bind(this));
this.fcbs.push(this.fcb);
this.flow.ov["-1"] = [this.fcb];
},
/** e, lv, x, y, mz
*/
screenCornerPos: function(obj){
var pos,
w = 1024/this.w,
h = 768/this.h;
if(obj.e>-1) pos = this.subs[obj.e].position;
else pos = this.ent.position;
pos.x = obj.lv*pos.z*obj.x;
pos.y = obj.lv*pos.z*0.75*obj.y;
if(obj.mz) pos.z *= obj.mz;
else pos.z *= 1.3;
var wh = w/h;
pos = pos.add([w*wh-1,h*wh-1,0]);
this.ent.position = pos;
return true;
},
// Sub functions
_addTo: function(w,id,obj){
this.fcbs.push(id);
if(this.flow[w][obj.e]) this.flow[w][obj.e].push(id);
else this.flow[w][obj.e] = [id];
},
/** e, what
*/
_stopIt: function(obj,what){
var f = this.flow[what][obj.e],ind;
if(!f) return false;
for(var i=0;i<f.length;i++){
if(isValidFrameCallback(f[i])) removeFrameCallback(f[i]);
ind = this.fcbs.indexOf(f[i]);
if(ind!==-1) this.fcbs.splice(ind,1);
}
this.flow[what][obj.e] = [];
return true;
},
/**
*/
_zoomBG: function(delta){
if(!delta) return;
this.bg.width *= this.bg.mw;
this.bg.height *= this.bg.mh;
setScreenBackground(this.bg);
},
/**
*/
_zoomOV: function(delta){
if(!delta) return;
this.ov.width *= this.ov.mw;
this.ov.height *= this.ov.mh;
setScreenOverlay(this.ov);
},
/**
*/
_fadeOV: function(delta){
if(!delta) return;
var f = Math.floor(this.ovFade.n*10/this.ovFade.t);
if(this.ovFade.dir) f = 10-f;
else f++;
if(f<0) f = 0;
if(f>10) f = 10;
this.ov.name = "lib_blend"+f+".png";
setScreenOverlay(this.ov);
this.ovFade.n += delta;
},
_removeFCBs: function(){
if(!this.fcbs.length) return false;
for(var i=0;i<this.fcbs.length;i++){
if(isValidFrameCallback(this.fcbs[i])) removeFrameCallback(this.fcbs[i]);
}
this.fcb = 0;
this.fcbs = [];
return true;
},
_getMaterials: function(obj){
if(obj.e>-1) return this.subs[obj.e].getMaterials();
return this.ent.getMaterials();
},
_setMaterials: function(obj,m){
if(obj.e>-1) return this.subs[obj.e].setMaterials(m);
return this.ent.setMaterials(m);
},
_getShaders: function(obj){
if(obj.e>-1) return this.subs[obj.e].getShaders();
return this.ent.getShaders();
},
_setPilot: function(obj){
var act;
this.setShaderProp(obj);
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.destination = obj.scpos;
act.lightsActive = obj.init;
},
_pilotSpeak: function(obj){
var act;
if(obj.e>-1) act = this.subs[obj.e];
else act = this.ent;
act.energy = obj.fade;
if(obj.txt) mission.addMessageText(obj.txt);
},
_sRND: function(seed,max){
return ((0x731753*seed)>>16)%max;
},
_snapIn: function(e){
if(e>0.9) e = 1;
if(e>0.6 && e<0.8) e = 0.707107;
if(e>0.4 && e<0.6) e = 0.5;
if(e>-0.1 && e<0.1) e = 0.0;
if(e>-0.6 && e<-0.4) e = -0.5;
if(e>-0.8 && e<-0.6) e = -0.707107;
if(e<-0.9) e = -1;
return e;
}
};
}).call(this); |
| Scripts/Lib_Animator.txt |
Lib_Animator
The Animator is a helper for animations on missionscreens.
Methods:
_start(obj)
worldScripts.Lib_Animator._start(obj);
Required members:
obj.model - String. Role
obj.flow - Array. Animation flow object.
Optional members:
obj.background - String.
obj.choices - Object.
obj.choicesKey - String.
obj.music - String
obj.overlay - String.
obj.screenID - String.
obj.title - String.
obj.fadeIn - Bool. If used replaces obj.overlay.
obj.corner - Object. See below.
obj.aPos - Array.
obj.aOris - Array.
obj.aBinds - Array.
obj.aProps - Array.
obj.bPos - Array.
obj.bOris - Array.
obj.bBinds - Array.
obj.bProps - Array.
obj.pilots - Array. Sets texture, scale, position and display for character overlay.
obj.caller - String. worldScript name for callback and checkpoints.
obj.callback - String. Function to be called when user
obj.checkpoint - String. Function to be called when 'check' gets processed.
obj.custom - Object. Holds custom Functions to be called when 'custom' gets processed.
obj.hud - String.
obj.aSnd - String.
obj.bSnd - String.
obj.delta - Number.
obj.flow
Array containing Arrays with at least 2 members (frame and cmd).
frame - Number.
cmd - String. Action command.
obj - Object or String.
subCMD - Array.
Action commands:
reset
Removes all Framecallbacks
clr
Removes all Framecallbacks and resets
clrMov
Removes all object movement Framecallbacks (flight, rotate, speed, velocity, walk and zoom).
kill
Removes mission.displayModel.
rotw
Rotate entity in world space.
e, t, rx,ry,rz [, z, da, db]
rot
Rotate entity in model space
e, t, rx,ry,rz [, z, da, db]
rotTo
Rotate entity to target. Clears other rotations for this entity.
e, t, tg [, z, da, db, s]
stopRot
Clear rotations for this entity.
e
fly
e, t, mu,mr,mf, rx,ry,rz [,da, db, z, fu, en]
flyTo
e, t, tg, s, mu,mr,mf [, da, db, z, fu, en]
stopFly
e
KI
stopKI
spd
spdTo
stopSpd
velo
e, t, mu,mr,mf [,da, db, z, fu, en]
veloTo
e, t, tg, mu,mr,mf [, da, db, z, fu, en]
veloSet
e, velo
stopVelo
e
walk
e, t, st [,z, da, db]
walkTo
stopWalk
e
zoom
e, t, mz [, z, da, db]
zoomTo
stopZoom
e
prop
e, t, p, v [, da, db]
matSet
e, mat, sha
matMod
e, prop
i, p, v
tex
shadeSet
e, sha, rep
shadeMod
e, tex, uni, val
sun
Replaces shader with textureless sun shader.
e, id, scale, pos, col
moon
Replaces shader with cubemapped moon shader.
e, id, scale, pos, col
boom
Replaces shader with explosion shader.
e, id, scale, pos
hyper
Replaces shader with hyperjump exit shader and plays sound.
e, id, scale, pos
shoot
Sets energy for laser shader and plays sound.
speak
Sets energy for character overlay and plays sound or adds message text.
bind
e, t, tg [,fe, dist, swap]
stopBind
e
pos
e, pos
posTo
e, tg [, off]
posFl
e, f, tg [, off]
ori
e, ori
bg
n
bgZoom
mw, mh [, n]
bgZoomTo
bgStop
none
bgClr
none
ov
n
ovZoom
mw, mh [, n]
ovStop
none
ovClr
none
ovFadeIn
t
ovFadeOut
t
corner
e, lv, x, y [, mz]
txt
String.
snd1
snd
snd2
snd
mus
snd
custom
Calls custom function declared in the passed obj.custom.
String.
goto
Goto animation frame time.
Number.
check
Request action from obj.caller. Passes current frame time.
If returned value is a Number goto frame.
If no returned value (or false) stops the animation.
|
| Scripts/Lib_BinSearch.js |
/* jshint bitwise:false, forin:false */
/* global _lib_BinSearch */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_BinSearch";
/** This search tree uses two corresponding entries.
* Must be instantiated!
* this.$myTree = new worldScripts.Lib_BinSearch._lib_BinSearch();
*/
this._lib_BinSearch = function(){this._lbs = null;};
_lib_BinSearch.prototype = {
constructor: _lib_BinSearch,
/** add() - Adds nodes to the search tree with the corresponding entry.
@key - String. Add node with key.
@val - Object. Corresponding entry
*/
add: function(key,val){
var node = {key: key,left: null,right: null, val: val},cur;
if(this._lbs === null) this._lbs = node;
else {
cur = this._lbs;
while(true){
if(key < cur.key){
if(cur.left === null){
cur.left = node;
break;
} else cur = cur.left;
} else if(key > cur.key){
if(cur.right === null){
cur.right = node;
break;
} else cur = cur.right;
} else break;
}
}
return;
},
/** contains() - Returns corresponing entry or false.
@key - String. Search for entry.
@return - Object. Corresponding entry or false.
*/
contains: function(key){
var found = false,cur = this._lbs;
while(!found && cur){
if(key < cur.key) cur = cur.left;
else if(key > cur.key) cur = cur.right;
else found = true;
}
if(!found) return false;
return cur.val;
},
traverse: function(process){
function inOrder(node){
if(node){
if(node.left !== null) inOrder(node.left);
process.call(this,node);
if(node.right !== null) inOrder(node.right);
}
}
inOrder(this._lbs);
},
/** size() - Returns the number of nodes in the search tree.
@return - Number. Number of nodes.
*/
size: function(){
var length = 0;
this.traverse(function(node){length++;});
return length;
},
/** toArray() - Returns an array containing all nodes in the search tree. The nodes are processed in-order.
@return - Array. Entries.
*/
toArray: function(){
var result = [];
this.traverse(function(node){result.push(node.key,node.val);});
return result;
},
/** toString() - Returns a comma-separated string consisting of all entries. The nodes are processed in-order.
@separator - String. Optional. If specified separates the elements.
@return - String. Concatenation of all entries.
*/
toString: function(separator){
if(separator) return this.toArray().join(separator);
else return this.toArray().toString();
}
};
}).call(this);
|
| Scripts/Lib_Config.js |
/* jshint bitwise:false, forin:false */
/* global expandMissionText,log,mission,player,worldScripts */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function () {
"use strict";
this.name = "Lib_Config";
this.description = expandMissionText("LIB_CONFIG_DESCRIPTION");
this.$sets = {}; // Settings objects
this.$setNames = []; // Sorting
this.$setProbs = {}; // Error codes
this.$curSet = null;
this.$defCHC = {
allowInterrupt: false,
choices: {
ZZZ: expandMissionText("LIB_CONFIG_EXIT")
},
initialChoicesKey: null,
message: "",
screenID: this.name,
textEntry: false,
title: expandMissionText("LIB_CONFIG_TITLE")
};
this.$oxpc = {
curBit: 0,
curInd: 0,
curKeys: [],
curMSB: 0,
curOpt: 0,
curPage: 0,
curTyp: 0,
div: "",
entry: 0,
intern: 0,
resort: 0,
scr: ['Bool', 'SInt', 'EInt']
};
/** _registerSet(obj) - Use on .startUpComplete() or later.
@obj - Settings object
@return Number. Error code. 0 - ok, >0 - error (see missiontext.plist)
*/
this._registerSet = function (obj) {
if (this.startUp) return 99;
if (!obj || typeof obj !== 'object') return 101;
if (!Object.keys(obj).length) return 102;
var e = this._checkSet(obj);
if (e) return e;
var id = obj.Name + obj.Display,
ind = this.$setNames.indexOf(id);
this.$sets[id] = obj; // Store or update
if (ind === -1) { // No double entries
this.$setNames.push(id);
this.$oxpc.entry++;
this.$oxpc.resort = 1;
this.$setProbs[id] = e;
}
return 0;
};
/** _unregisterSet(obj)
@obj - Settings object
@return Number. Error code. 0 - ok, >0 - error (see missiontext.plist)
*/
this._unregisterSet = function (obj) {
if (typeof obj !== 'object') return 501;
var id = obj.Name + obj.Display,
ind = this.$setNames.indexOf(id);
if (!this.$sets[id]) return 502;
if (ind === -1) return 503;
delete this.$sets[id];
this.$oxpc.entry--;
this.$oxpc.resort = 1;
this.$setNames.splice(ind, 1);
return 0;
};
this._updSet = function (obj) {
if (typeof obj !== 'object') return 601;
var ind = -1,
tmp, tmps,
e = this._checkSet(obj);
if (!e || e === 211) {
ind = this.$setNames.indexOf(obj.Name + obj.Display);
if (ind !== -1) {
tmp = this.$setNames[ind];
if (tmp) {
if (!e) {
tmps = this._aid.objGrab(worldScripts[obj.Name], obj.Alive);
this.$sets[tmp] = tmps[0][tmps[1]];
}
this.$curSet = this.$sets[tmp];
}
} else { // Not registered
this.$curSet = obj;
this.$oxpc.intern = 0;
return e;
}
} else this.$curSet = obj;
return e;
};
this.startUp = function () {
delete this.startUp;
this._aid = worldScripts.Lib_Main._lib; // Covered by manifest
worldScripts.Lib_GUI.$IDRules.Lib_Config = {
pic: 1,
mus: 1
};
this.$oxpc.div = this._aid.scrToWidth("-", 31, "-") + "\n";
};
this.startUpComplete = function () {
delete this.startUpComplete;
this.shipDockedWithStation(); // Implement interface
};
this.shipDockedWithStation = function () {
if (!player.ship || !player.ship.isValid || !player.ship.docked) return;
player.ship.dockedStation.setInterface(this.name, {
title: expandMissionText("LIB_CONFIG_INTERFACE_TITLE"),
category: expandMissionText("LIB_CONFIG_INTERFACE_CATEGORY"),
summary: this.description,
callback: this._showStart.bind(this)
});
};
this._checkSet = function (obj) {
var e = 0,
t = ['string', 'function', 'object', 'undefined'],
noti;
if (typeof obj.Name !== t[0]) return 201;
if (typeof obj.Display !== t[0]) return 202;
if (typeof obj.Alive !== t[0]) return 203;
if (obj.Alias && typeof obj.Alias !== t[0]) return 209;
if (obj.Notify) {
if (typeof obj.Notify !== t[0]) return 204;
noti = this._aid.objGrab(worldScripts[obj.Name], obj.Notify);
if (typeof noti[0] === 'undefined') return 212;
if (typeof noti[0] !== t[1] && typeof noti[0][noti[1]] !== t[1]) return 212;
}
var k = this.$oxpc.scr,
v;
for (var i = 0; i < k.length; i++) {
v = k[i];
if (typeof obj[v] !== t[3]) {
if (typeof obj[v] !== t[2]) return 206 + i;
if (!obj[v] || !Object.keys(obj[v]).length) return 213 + i;
} else e++;
}
if (e === 3) return 205;
if (!this._checkAvail(obj)) return 211;
return 0;
};
this._checkAvail = function (obj) {
var ws = worldScripts[obj.Name];
if (!ws || ws.$deactivated) return false;
var a = this._aid.objGrab(ws, obj.Alive);
if (typeof a[0][a[1]] !== 'object' || !Object.keys(a[0][a[1]]).length) return false;
return true;
};
this._checkHeader = function (obj) {
var h = {
Name: "-",
Alias: 0,
Display: "-",
Mani: "-",
Author: "-",
Copyright: "-",
Licence: "-",
Desc: "-",
Version: "-",
Ref: false,
Extern: false
},
ws = worldScripts[obj.Name];
h.Ref = this._checkAvail(obj);
if (ws) {
if (ws.name) h.Name = ws.name;
if (obj.Name) h.Name = obj.Name;
if (ws.author) h.Author = ws.author;
if (ws.copyright) h.Copyright = ws.copyright;
if (ws.licence) h.Licence = ws.licence;
else if (ws.license) h.Licence = ws.license;
if (ws.description) h.Desc = ws.description;
if (ws.version) h.Version = ws.version;
if (ws.oolite_manifest_identifier) h.Mani = ws.oolite_manifest_identifier;
} else if (obj.Name) h.Name = obj.Name;
if (obj.Display) h.Display = obj.Display;
if (obj.Alias) h.Alias = obj.Alias;
if (!this.$oxpc.intern) h.Extern = true;
return h;
};
this._checkValues = function (obj, typ) {
var wc = obj[typ],
ws = worldScripts[obj.Name],
max = 16777215,
min = -16777215,
c, ty, de, val;
switch (typ) {
case 'Bool':
ty = 'boolean';
de = 'string';
break;
case 'SInt':
ty = 'number';
de = 'string';
break;
case 'EInt':
ty = 'number';
de = 'object';
break;
}
for (var t in wc) {
if (!wc[t]) return 301;
if (t === 'Info' || t === 'Notify') continue;
c = wc[t];
if (typeof c.Name !== 'string') return 302;
if (typeof c.Def !== ty) return 303;
if (typeof c.Desc !== de) return 304;
val = this._aid.objGet(ws, c.Name);
if (typeof val !== ty) return 401;
if (typ !== 'Bool') {
if (typeof c.Max !== ty) return 311;
if (typeof c.Min !== ty) return 312;
if (typ === 'EInt') min = 0;
if (c.Max < min) return 313;
if (c.Max > max) return 314;
if (c.Min > c.Max) return 315;
if (c.Min < min) return 316;
if (c.Def > c.Max) return 317;
if (c.Def < c.Min) return 318;
if (c.Def > max) return 319;
if (c.Def < min) return 320;
if (val > max || val > c.Max) return 411;
if (val < min || val < c.Min) return 412;
}
}
return 0;
};
this._fillOptions = function (chc, tit, ent) {
var obj = JSON.parse(JSON.stringify(this.$defCHC));
if (chc) obj.choices = chc;
if (tit) obj.title = tit;
if (ent) obj.textEntry = true;
return obj;
};
this._resort = function () {
this.$setNames = this.$setNames.sort();
this.$oxpc.resort = 0;
};
this._reset = function () {
this.$curSet = null;
this.$defCHC.initialChoicesKey = null;
var o = this.$oxpc;
o.curBit = 0;
o.curMSB = 0;
o.curInd = 0;
o.curKeys = [];
o.curOpt = 0;
o.curPage = 0;
o.curTyp = 0;
o.intern = 0;
};
this._showScr = function (obj, mes, mesKey, cb) {
if (mesKey) {
obj.messageKey = mesKey;
obj.message = null;
} else if (mes) obj.message = mes;
if (cb) mission.runScreen(obj, cb);
else mission.runScreen(obj, this._choiceEval);
};
this._showStart = function () {
var ch = {
goLI: expandMissionText("LIB_CONFIG_LIST_SETTINGS"),
ZZZ: expandMissionText("LIB_CONFIG_EXIT")
},
chc, txt,
o = this.$oxpc;
this._reset();
if (!o.entry) ch = this._aid.scrChcUnsel(ch, 'goLI');
chc = this._fillOptions(ch);
chc.exitScreen = "GUI_SCREEN_INTERFACES";
this._showScr(chc, 0, 'LIBC_HEAD');
txt = o.div;
o.intern = 1;
txt += expandMissionText("LIB_CONFIG_REGISTERED", { count: o.entry });
mission.addMessageText(txt);
if (o.resort) this._resort();
};
this._showList = function () {
var ch = {
LINext: expandMissionText("LIB_CONFIG_NEXTSET"),
lioOXP: expandMissionText("LIB_CONFIG_SELECTSET"),
LIPNext: expandMissionText("LIB_CONFIG_NEXTPAGE"),
LIPPrev: expandMissionText("LIB_CONFIG_PREVPAGE"),
LIRet: expandMissionText("LIB_CONFIG_BACK")
},
chc, txt, tmp, tmq, ind,
o = this.$oxpc,
max = o.curPage * 10,
e = o.entry;
txt = this._aid.scrAddLine([
["", 1],
[expandMissionText("LIB_CONFIG_COL_SETTINGS"), 10],
[expandMissionText("LIB_CONFIG_COL_SCRIPT"), 10],
[expandMissionText("LIB_CONFIG_COL_VERSION"), 7],
[expandMissionText("LIB_CONFIG_COL_REF"), 3]
], "", "\n");
txt += o.div;
for (var i = 0; i < 10; i++) {
ind = i + max;
if (e <= ind) break;
tmq = this.$setNames[ind];
tmp = this._checkHeader(this.$sets[tmq]);
txt += this._aid.scrAddLine([
[(o.curInd === ind ? ">" : ""), 1]
]);
txt += this._addHeader(tmp, 1);
}
if (e <= max) ch = this._aid.scrChcUnsel(ch, 'LINext');
if (e <= (1 + o.curPage) * 10) ch = this._aid.scrChcUnsel(ch, 'LIPNext');
if (!o.curPage) ch = this._aid.scrChcUnsel(ch, 'LIPPrev');
chc = this._fillOptions(ch);
this._showScr(chc, txt);
};
/** _showOXPPage(obj) - for direct access
@obj - Settings object
@return Number. Error code. 0 - ok, >0 - error (see missiontext.plist)
*/
this._showOXPPage = function (obj) {
if (!obj || typeof obj !== 'object') return 101;
if (!Object.keys(obj).length) return 102;
var e = this._updSet(obj),
ch = {
goBool: expandMissionText("LIB_CONFIG_SHOW_SWITCH"),
goEInt: expandMissionText("LIB_CONFIG_SHOW_FLAGS"),
goSInt: expandMissionText("LIB_CONFIG_SHOW_VALUES"),
OXPZZZ: expandMissionText("LIB_CONFIG_BACK")
},
c = this.$curSet,
o = this.$oxpc,
tmp = this._checkHeader(c),
chc, txt;
if (e || !tmp.Ref) {
ch = this._aid.scrChcUnsel(ch, 'goBool');
ch = this._aid.scrChcUnsel(ch, 'goEInt');
ch = this._aid.scrChcUnsel(ch, 'goSInt');
} else {
if (!c.Bool) ch = this._aid.scrChcUnsel(ch, 'goBool');
if (!c.EInt) ch = this._aid.scrChcUnsel(ch, 'goEInt');
if (!c.SInt) ch = this._aid.scrChcUnsel(ch, 'goSInt');
if (c.Reset) ch.OXPDef = expandMissionText("LIB_CONFIG_RESET");
}
txt = this._addHeader(tmp);
txt += o.div;
txt += this._aid.scrAddLine([
[expandMissionText("LIB_CONFIG_LINE_AUTHOR", { author: tmp.Author }), 29],
[expandMissionText("LIB_CONFIG_LINE_MANIFEST", { manifest: tmp.Mani }), 29],
[expandMissionText("LIB_CONFIG_LINE_COPYRIGHT", { copy: tmp.Copyright }), 29],
[expandMissionText("LIB_CONFIG_LINE_LICENCE", { licence: tmp.Licence }), 29],
[expandMissionText("LIB_CONFIG_LINE_DESC", { desc: tmp.Desc }), 29]
], "\n");
txt += o.div;
if (e || !tmp.Ref) txt += "\n" + this._addError(tmp, e, 'obj');
else txt += expandMissionText("LIB_CONFIG_SETTINGS_FOUND");
chc = this._fillOptions(ch, tmp.Display);
this._showScr(chc, txt);
o.curBit = 0;
o.curMSB = 0;
o.curOpt = 0;
o.curTyp = 0;
return e;
};
/** _showOXPSub(obj) - for direct access
@obj - Settings object
@typ - String. Either "Bool","SInt" or "EInt"
@return Number. Error code. 0 - ok, >0 - error (see missiontext.plist)
*/
this._showOXPSub = function (obj, typ) {
if (!obj || typeof obj !== 'object') return 101;
if (!Object.keys(obj).length) return 102;
if (!typ || this.$oxpc.scr.indexOf(typ) === -1) return 701;
var e = this._updSet(obj),
c = this.$curSet,
ch = {
OXPNext: expandMissionText("LIB_CONFIG_NEXTOPT"),
OXPToggle: expandMissionText("LIB_CONFIG_CHANGECURR"),
OXPZZZ: expandMissionText("LIB_CONFIG_BACK")
},
o = this.$oxpc,
r, tp, val, inf,
z = 0,
sh = 1;
o.curTyp = typ;
var op = Object.keys(c[typ]),
opl = op.length,
opk = [],
pass = this._checkValues(c, typ),
tmp = this._checkHeader(c),
txt = this._addHeader(tmp);
if (e || pass) sh = 0;
txt += o.div;
if (sh) {
for (var x = 0; x < opl; x++) {
tp = op[x];
if (tp === 'Info' || tp === 'Notify') continue;
if (opk.length > 8) break;
if (!c[typ][tp].Hide) opk.push(tp);
}
o.curKeys = opk;
if (!opk.length) {
txt += expandMissionText("LIB_CONFIG_NOTHING");
z++;
} else {
for (var t in c[typ]) {
if (z > 8) break;
if (t === 'Info' || t === 'Notify') continue;
val = c[typ][t];
if (!val || val.Hide) txt += this._aid.scrAddLine([
["", 1],
["-", 1]
], "", "\n");
else {
if (!o.curOpt) o.curOpt = t;
r = this._calcs(val);
switch (typ) {
case 'Bool':
txt += this._aid.scrAddLine([
[(o.curOpt === t ? ">" : " "), 1],
[z, 1],
[r.Dec, 4],
[expandMissionText("LIB_CONFIG_ITEM_DEFAULT", { def: val.Def }), 5],
[val.Desc, 19]
], "", "\n"); // orig 8, new 19
break;
case 'SInt':
txt += this._aid.scrAddLine([
[(o.curOpt === t ? ">" : ""), 1],
[z, 1],
[r.Dec, 5],
[expandMissionText("LIB_CONFIG_ITEM_DEFAULT", { def: r.Def }), 5],
[expandMissionText("LIB_CONFIG_ITEM_RANGE", { min: r.Min, max: r.Max }), 10],
[val.Desc, 10]
], "", "\n"); // orig 8, new 10
break;
case 'EInt':
o.curMSB = r.msb;
txt += this._aid.scrAddLine([
["", 1],
[z, 10],
[r.Dec, 5],
[r.str, 14],
[r.msb, 0]
], "", "\n");
var curLen = 0;
for (var i = 0; i < r.msb; i++) {
var txtbit = this._aid.scrAddLine([
[(o.curBit === i ? ">" : ""), 1],
[(r.revstr.length > i ? r.revstr[i] : "0"), 1],
[(val.Desc.length > i ? val.Desc[i] + " " : " "), defaultFont.measureString((val.Desc.length > i ? val.Desc[i] + " " : " "))]
], ""); // orig 8, new variable
// only jump to a new line if we're about to go over
if (curLen + defaultFont.measureString(txtbit) > 30) {
txt += "\n";
curLen = 0;
}
curLen += defaultFont.measureString(txtbit);
txt += txtbit;
}
txt += "\n";
z = Math.ceil(r.msb / 3);
break;
}
}
z++;
}
}
} else {
if (e) txt += this._addError(tmp, e, typ);
if (pass) txt += this._addError(tmp, pass, typ);
z += (e ? 1 : 0) + (pass ? 1 : 0);
}
txt += this._aid.scrFillLines(z, 9);
if (c[typ].Info) {
inf = c[typ].Info;
if (inf[0] === "^") inf = expandMissionText(inf.substr(1));
// this code restricts the info text to 5 lines or 10 lines, based on whether the hud allows Big Gui.
var max = 32 * 5;
if (player.ship.hudAllowsBigGui) max = 32 * 10;
var final = inf.toString();
// start reducing the size of text until it fits in.
if (defaultFont.measureString(final) > max) {
var ilen = final.length;
do {
ilen -= 1;
final = inf.toString().substr(0, ilen);
} while (defaultFont.measureString(final) > max)
}
txt += "\nDesc:\n" + final + "\n"; // was inf.toString().substr(0, 240) (ie only 240 characters)
}
if (!sh || (opk.length < 2 && typ !== 'EInt')) ch = this._aid.scrChcUnsel(ch, 'OXPNext');
if (!sh || !opk.length) ch = this._aid.scrChcUnsel(ch, 'OXPToggle');
var chc = this._fillOptions(ch, tmp.Display);
this._showScr(chc, txt);
return e;
};
this._calcs = function (val) {
var s = this._aid.objGet(worldScripts[this.$curSet.Name], val.Name);
var r = {
Dec: s
};
switch (this.$oxpc.curTyp) {
case 'SInt':
r.Dec = r.Dec;
r.Def = val.Def;
r.Max = val.Max;
r.Min = val.Min;
break;
case 'EInt':
r.str = this._aid.toBase(r.Dec, 2);
r.msb = this._aid.getMSB(val.Max);
r.revstr = this._aid.strRev(r.str);
break;
}
return r;
};
this._showOXPValueEnter = function () {
var c = this.$curSet,
o = this.$oxpc,
tmp = this._checkHeader(c),
txt = this._addHeader(tmp) + o.div,
val = c[o.curTyp][o.curOpt],
r = this._calcs(val);
txt += this._aid.scrAddLine([
["", 1],
["", 1],
[r.Dec, 5],
["D:" + r.Def, 5],
["R:" + r.Min + " - " + r.Max, 10],
[val.Desc, 0]
], "", "\n");
txt += o.div;
txt += expandMissionText("LIB_CONFIG_HEX_INFO");
if (val.Min < 0) txt += expandMissionText("LIB_CONFIG_NEG_INFO");
if (val.Float) txt += expandMissionText("LIB_CONFIG_FLOAT_INFO");
txt += expandMissionText("LIB_CONFIG_ENTER_VALUE");
var chc = this._fillOptions({}, tmp.Name, 1);
this._showScr(chc, txt, null, this._choiceEnter);
};
this._addHeader = function (tmp, flag) {
return this._aid.scrAddLine([
[tmp.Display, 10],
[(tmp.Alias ? tmp.Alias : tmp.Name), 10],
[tmp.Version, 4],
[(flag ? "" : "#"), 1],
[(flag ? "" : ""), 1],
[(flag ? "" : (tmp.Extern ? "Ex" : "")), 1],
[(tmp.Ref ? "" : "!") + (tmp.Extern ? "-" : String(this.$setProbs[tmp.Name + tmp.Display])), 2.5]
], "", "\n");
};
this._addError = function (w, e, typ) {
this.$setProbs[w.Name + w.Display] = e;
log(this.name, "Error: " + w.Name + " " + w.Display + " - (" + typ + ") " + expandMissionText('LIBC_E' + e));
return "Error: " + e + " - (" + typ + ") " + expandMissionText('LIBC_E' + e) + "\n";
};
this._notiError = function (s, w) {
log(this.name, expandMissionText("LIB_CONFIG_NOTIFY_FAIL", { s: s, w: w }));
};
this._choiceEval = function (choice) {
worldScripts.Lib_Config._choices(choice);
return;
};
this._choices = function (choice) {
if (choice) this.$defCHC.initialChoicesKey = choice;
var o = this.$oxpc,
c = this.$curSet,
p = Math.floor(o.curInd / 10),
cur = this.$setNames[o.curInd],
a, b, flag, ind, ok, ws;
var pp = p * 10;
switch (choice) {
case 'goBool':
this._showOXPSub(c, 'Bool');
break;
case 'goEInt':
this._showOXPSub(c, 'EInt');
break;
case 'goLI':
o.intern = 1;
this._showList();
break;
case 'lioOXP':
this._showOXPPage(this.$sets[cur]);
break;
case 'goSInt':
this._showOXPSub(c, 'SInt');
break;
case 'LINext':
o.curInd++;
if (o.curInd >= pp + 10 || o.curInd < pp || o.curInd >= o.entry) o.curInd = pp;
this._showList();
break;
case 'LIPNext':
o.curPage++;
o.curInd = pp + 10;
this._showList();
break;
case 'LIPPrev':
if (o.curPage > -1) {
o.curPage--;
o.curInd = pp - 10;
}
this._showList();
break;
case 'LIRet':
this._showStart();
break;
case 'OXPDef':
ws = worldScripts[c.Name];
if (c.Notify) a = 1;
ind = o.scr;
for (var i = 0; i < 3; i++) {
flag = ind[i];
if (c[flag]) {
if (!a && c[flag].Notify) b = 1;
else b = 0;
for (var j in c[flag]) {
if (typeof c[flag][j] !== 'object') continue;
this._aid.objSet(ws, c[flag][j].Name, c[flag][j].Def);
if (!a && !b && c[flag][j].Notify) this._aid.objPass(ws, c[flag][j].Notify, j);
}
if (b) this._aid.objPass(ws, c[flag].Notify, flag);
}
}
if (a) this._aid.objPass(ws, c.Notify, "All");
this._showOXPPage(this.$sets[cur]);
mission.addMessageText(expandMissionText("LIB_CONFIG_RESET"));
break;
case 'OXPNext':
switch (o.curTyp) {
case 'Bool':
case 'SInt':
ind = o.curKeys.indexOf(o.curOpt) + 1;
if (ind > o.curKeys.length - 1) ind = 0;
o.curOpt = o.curKeys[ind];
break;
case 'EInt':
o.curBit++;
if (o.curBit >= o.curMSB) o.curBit = 0;
break;
}
this._showOXPSub(c, o.curTyp);
break;
case 'OXPToggle':
ws = worldScripts[c.Name];
ind = c[o.curTyp][o.curOpt].Name;
switch (o.curTyp) {
case 'Bool':
a = this._aid.objGet(ws, ind);
a = !a;
this._aid.objSet(ws, ind, a);
flag = 1;
break;
case 'SInt':
this._showOXPValueEnter();
break;
case 'EInt':
a = this._aid.objGet(ws, ind);
b = Math.pow(2, o.curBit);
if (c[o.curTyp][o.curOpt].OneOf) a = b;
else if (c[o.curTyp][o.curOpt].OneOfZero) {
if (a === b) a = 0;
else a = b;
} else {
if (a & b) a -= b;
else a += b;
}
this._aid.objSet(ws, ind, a);
flag = 1;
break;
}
if (flag) {
if (c[o.curTyp][o.curOpt].Notify) {
ok = this._aid.objPass(ws, c[o.curTyp][o.curOpt].Notify, o.curOpt);
if (!ok) this._notiError(c.Name, c[o.curTyp][o.curOpt].Notify);
}
this._showOXPSub(c, o.curTyp);
}
break;
case 'OXPZZZ':
ws = worldScripts[c.Name];
if (o.curTyp) {
if (c[o.curTyp].Notify) {
ok = this._aid.objPass(ws, c[o.curTyp].Notify, o.curTyp);
if (!ok) this._notiError(c.Name, c[o.curTyp].Notify);
}
this._showOXPPage(c);
} else {
if (c.Notify) {
ok = this._aid.objPass(ws, c.Notify, "All");
if (!ok) this._notiError(c.Name, c.Notify);
}
this.$curSet = null;
if (o.intern) {
this.$defCHC.initialChoicesKey = 'LIRet';
this._showList();
} else this._reset(); // Bye
}
break;
case 'ZZZ':
this._reset();
break;
}
};
// Numerical input
this._choiceEnter = function (choice) {
worldScripts.Lib_Config._choiceEnterB(choice);
return;
};
this._choiceEnterB = function (choice) {
var o = this.$oxpc,
c = this.$curSet,
ws = worldScripts[c.Name],
ind = c[o.curTyp][o.curOpt],
sign = 1,
ok, val;
if (choice) {
// Store sign
if (choice[0] === '-') {
choice = choice.substr(1);
sign = -1;
}
if (choice.length > 2 && choice.substr(0, 2) === "0x" && !isNaN(parseInt(choice))) val = parseInt(choice);
else if (ind.Float && !isNaN(parseFloat(choice))) val = parseFloat(choice);
else if (!isNaN(parseInt(choice))) val = parseInt(choice);
if (typeof (val) !== 'undefined') {
val *= sign; // Reapply sign
val = this._aid.clamp(val, ind.Min, ind.Max);
this._aid.objSet(ws, ind.Name, val);
if (c[o.curTyp][o.curOpt].Notify) {
ok = this._aid.objPass(ws, c[o.curTyp][o.curOpt].Notify, o.curOpt);
if (!ok) this._notiError(c.Name, c[o.curTyp][o.curOpt].Notify);
}
}
}
this._showOXPSub(c, o.curTyp);
};
}).call(this); |
| Scripts/Lib_Crypt.js |
/* jshint bitwise:false, forin:false */
/* global log */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_Crypt";
/** _decrypt() - Decrypts string.
@str - String. Minimum length 6 chars.
@pwd - String. Password. Minimum length 4 chars.
@return - String/Boolean. String or false.
Author: Terry Yuen.
*/
this._decrypt = function(str,pwd){
if(!str || !pwd || str.length<6 || pwd.length<4){log(this.name,expandMissionText("LIB_DECRYPT_PARAM_ERROR")); return false;}
var prand = "";
for(var i=0;i<pwd.length;i++) prand += pwd.charCodeAt(i).toString();
var sPos = Math.floor(prand.length/5);
var mult = parseInt(prand.charAt(sPos)+prand.charAt(sPos*2)+prand.charAt(sPos*3)+prand.charAt(sPos*4)+prand.charAt(sPos*5),null);
var incr = Math.round(pwd.length/2);
var modu = Math.pow(2,31)-1;
var salt = parseInt(str.substring(str.length-8,str.length),16);
str = str.substring(0,str.length-8);
prand += salt;
while(prand.length>10) prand = (parseInt(prand.substring(0,10),null)+parseInt(prand.substring(10,prand.length),null)).toString();
prand = (mult*prand+incr)%modu;
var enc_chr = "",dec_str = "";
for(var j=0;j<str.length;j+=2){
enc_chr = parseInt(parseInt(str.substring(j,j+2),16)^Math.floor((prand/modu)*255),null);
dec_str += String.fromCharCode(enc_chr);
prand = (mult*prand+incr)%modu;
}
return dec_str;
};
/** _encrypt() - Encrypts string.
@str - String. Minimum length 6 chars.
@pwd - String. Password. Minimum length 4 chars.
@return - String/Boolean. String or false.
Author: Terry Yuen.
*/
this._encrypt = function(str,pwd){
if(!str || !pwd || str.length<6 || pwd.length<4){log(this.name,expandMissionText("LIB_ENCRYPT_PARAM_ERROR")); return false;}
var prand = "";
for(var i=0;i<pwd.length;i++) prand += pwd.charCodeAt(i).toString();
var sPos = Math.floor(prand.length/5);
var mult = parseInt(prand.charAt(sPos)+prand.charAt(sPos*2)+prand.charAt(sPos*3)+prand.charAt(sPos*4)+prand.charAt(sPos*5),null);
var incr = Math.ceil(pwd.length/2);
var modu = Math.pow(2,31)-1;
if(mult<2){log(this.name,expandMissionText("LIB_ENCRYPT_HASH_ERROR")); return false;}
var salt = Math.round(Math.random()*1000000000)%100000000;
prand += salt;
while(prand.length>10) prand = (parseInt(prand.substring(0,10),null)+parseInt(prand.substring(10,prand.length),null)).toString();
prand = (mult*prand+incr)%modu;
var enc_chr = "",enc_str = "";
for(var j=0;j<str.length;j++){
enc_chr = parseInt(str.charCodeAt(j)^Math.floor((prand/modu)*255),null);
if(enc_chr<16) enc_str += "0"+enc_chr.toString(16);
else enc_str += enc_chr.toString(16);
prand = (mult*prand+incr)%modu;
}
salt = salt.toString(16);
while(salt.length<8) salt = "0"+salt;
enc_str += salt;
return enc_str;
};
/** _getCRC() - Returns simple checksum. Limits every char via &0xff and result via &0x3fff.
*/
this._getCRC = function(str){
var crc = 0, i = str.length;
while(i--) crc += (str.charCodeAt(i)&0xff);
return crc&0x3fff;
};
/** _rot5() - Number rotation. Can be paired with _rot13.
*/
this._rot5 = function(str){
return (str+'').replace(/[0-9]/g,function(s){return String.fromCharCode(s.charCodeAt(0)+(s<'5'?5:-5));});
};
/** _rot13() - Alphabet rotation. Can be paired with _rot5.
*/
this._rot13 = function(str){
return (str+'').replace(/[a-z]/gi,function(s){return String.fromCharCode(s.charCodeAt(0)+(s.toLowerCase()<'n'?13:-13));});
};
/** _rot513 - Combined rot5 and rot13.
*/
this._rot513 = function(str){
var a = this._rot5(str),b = this._rot13(a);
return b;
};
/** _rot47() - Expanded rotation.
*/
this._rot47 = function(a,b){return++b?String.fromCharCode((a=a.charCodeAt()+47,a>126?a-94:a)):a.replace(/[^ ]/g,this._rot47);};
/** _Vigenere
* input String.
* key String. Alphabetical key.
* forward Bool. Set to true for decryption.
* $return String.
*/
this._Vigenere = function(input, key, forward){
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
adjusted_key = "", i, key_char, output = "", key_index = 0, in_tag = false;
if(key===null) key = "";
key = key.toUpperCase();
var key_len = key.length;
for(i=0;i<key_len;i++){
key_char = alphabet.indexOf(key.charAt(i));
if(key_char<0) continue;
adjusted_key += alphabet.charAt(key_char);
}
key = adjusted_key;
key_len = key.length;
if (key_len===0){
key = "a";
key_len = 1;
}
var input_len = input.length;
for(i=0;i< input_len;i++){
var input_char = input.charAt(i);
if(input_char==="<") in_tag = true;
else if(input_char===">") in_tag = false;
if(in_tag){
output += input_char;
continue;
}
var input_char_value = alphabet.indexOf(input_char);
if(input_char_value<0){
output += input_char;
continue;
}
var lowercase = input_char_value >= 26 ? true : false;
if(forward) input_char_value += alphabet.indexOf(key.charAt(key_index));
else input_char_value -= alphabet.indexOf(key.charAt(key_index));
input_char_value += 26;
if(lowercase) input_char_value = input_char_value % 26 + 26;
else input_char_value %= 26;
output += alphabet.charAt(input_char_value);
key_index = (key_index + 1) % key_len;
}
return output;
};
}).call(this);
|
| Scripts/Lib_Cubecode.js |
/* global mission,worldScripts,SoundSource */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_Cubecode";
/** _initCubes
* @obj.pass - Number
* @obj.card - Texture
* @obj.ws - String
* @obj.path - String
*/
this._initCubes = function(obj){
if(this.$cub.init) return false;
var ret,map = "lib_lock.png",lo = 0,ws=null,wsf=null;
if(obj){
if(obj.card) map = obj.card;
if(typeof obj.pass==="number") lo = obj.pass;
if(obj.ws && obj.path){
ws = obj.ws;
wsf = obj.path;
}
}
this.$cub.lock = lo;
this.$cub.ws = ws;
this.$cub.path = wsf;
this.$head.subTex[0].mat["lib_null.png"].emission_map = map;
this.$cub.code = -1;
this.$cub.init = 1;
ret = this._showCubes();
return ret;
};
this.startUp = function(){
this.$head = {
model: "lib_ms_cubes",
title: expandMissionText("LIB_CUBE_TITLE"),
background: "lib_console_bg.png",
choices: {NEXT:expandMissionText("LIB_CUBE_NEXT"),ROTX:expandMissionText("LIB_CUBE_ROTATEX"),ROTY:expandMissionText("LIB_CUBE_ROTATEY"),ROTZ:expandMissionText("LIB_CUBE_ROTATEZ"),ZZZ:expandMissionText("LIB_CUBE_QUIT")},
text: expandMissionText("LIB_CUBE_SELECT"),
caller: this.name,
callback: "_choiceEval",
checkpoint: "_checkpoints",
aOris: [{e:-1,ori:[1,0,0,0]}],
aPos: [{e:-1,pos:[0,30,250]}],
subTex: [{e:0,mat:{"lib_null.png":{emission_map:"lib_lock.png"}}}],
flow:[]
};
this.$cub = {
code:-1,
lock:0,
cur:1,
init:0,
ws:null,
path:null,
curOri:[[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0]],
flows:{a:[4,"rotX",{e:1,t:2,deg:90,da:1,db:1,inf:1}],b:[4,"rotY",{e:1,t:2,deg:90,da:1,db:1,inf:1}],c:[4,"rotZ",{e:1,t:2,deg:90,da:1,db:1,inf:1}]}
};
this.$snd = new SoundSource();
this._aid = worldScripts.Lib_Main._lib;
};
this._showCubes = function(fl,w){
var obj = this._aid.objClone(this.$head),ac,c = 0,ret,i,un = ['ROTX','ROTY','ROTZ','ZZZ'],m = "lib_ms_cube_a.png";
for(i=1;i<10;i++){obj.aOris.push({e:i,ori:this.$cub.curOri[i]});}
if(w) obj.replace = 1;
else {
obj.fadeIn = true;
obj.flow.push([c,"ovFadeIn",{t:1.5}]);
c++;
obj.flow.push([c,"snd1",{snd:"lib_enter_code.ogg"}]);
c++;
}
if(this.$cub.lock===this.$cub.code){
for(i=0;i<4;i++) obj.choices = this._aid.scrChcUnsel(obj.choices,un[i]);
obj.flow.push([c,"clr"]);
c++;
for(i=1;i<10;i++){
obj.flow.push([c,"lit",{e:i,mat:m,tex:m,col:[0,0.6,0,1]}]);
c++;
}
} else {
obj.flow.push([c,"lit",{e:this.$cub.cur,mat:m,tex:m,col:[0,0.6,0,1]}]);
c++;
if(fl){
ac = this.$cub.flows[fl];
ac[0] = c;
ac[2].e = this.$cub.cur;
obj.flow.push(ac);
c++;
obj.flow.push([c,"check"]);
c+=5;
obj.flow.push([c,"snap",{e:this.$cub.cur}]);
c++;
obj.flow.push([c,"check"]);
c++;
}
}
c+=5;
obj.flow.push([c,"clr"]);
ret = worldScripts.Lib_Animator._start(obj);
if(ret && !w && !fl) this._getRes();
return ret;
};
this._choiceEval = function(choice){worldScripts.Lib_Cubecode._delayChoice(choice); return;};
this._delayChoice = function(choice){
var cb,ws;
switch(choice){
case "NEXT":
this.$cub.cur++;
if(this.$cub.cur>9) this.$cub.cur = 1;
if(this.$cub.lock===this.$cub.code){
cb = 1;
this.$cub.init = 0;
} else this._showCubes(0,1);
break;
case "ROTX": this._showCubes("a",1); break;
case "ROTY": this._showCubes("b",1); break;
case "ROTZ": this._showCubes("c",1); break;
case "ZZZ": cb = 1; this.$cub.init = 0; break;
}
if(cb && this.$cub.ws && this.$cub.path){
ws = worldScripts[this.$cub.ws];
this._aid.objPass(ws,this.$cub.path,this.$cub.code);
}
this.$snd.sound = "[changed-option]";
this.$snd.play();
};
this._checkpoints = function(n){
var o;
switch(n){
case 2:
o = worldScripts.Lib_Animator._a;
if(o) this.$cub.curOri[this.$cub.cur] = o.cur[this.$cub.cur].tOri;
break;
case 8:
this._getRes();
if(this.$cub.lock===this.$cub.code){
this.$snd.sound = "lib_code_verified.ogg";
this.$snd.play();
this._showCubes(0,1);
}
break;
}
return true;
};
this._getRes = function(){
var res = 0,pri = [3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61],a,b,c = mission.displayModel;
for(var i=1;i<10;i++){
a = pri[i];
b = c.subEntities[i].vectorUp;
if(b.x>0) res += b.x*11*a;
if(b.y>0) res += b.y*13*a;
if(b.z>0) res += b.z*17*a;
b = c.subEntities[i].vectorRight;
if(b.x>0) res += b.x*19*a;
if(b.y>0) res += b.y*23*a;
if(b.z>0) res += b.z*29*a;
b = c.subEntities[i].vectorForward;
if(b.x>0) res += b.x*31*a;
if(b.y>0) res += b.y*37*a;
if(b.z>0) res += b.z*41*a;
}
this.$cub.code = Math.floor(res);
};
}).call(this);
|
| Scripts/Lib_EntityStrength.js |
/* global system,worldScripts */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_EntityStrength";
this.$weapons = ["EQ_WEAPON_NONE","EQ_WEAPON_MINING_LASER","EQ_WEAPON_PULSE_LASER","EQ_WEAPON_BEAM_LASER","EQ_WEAPON_MILITARY_LASER","EQ_WEAPON_THARGOID_LASER"];
this.$slotsA = ["forwardWeapon","aftWeapon","portWeapon","starboardWeapon"];
this.$slotsB = ["weaponPositionForward","weaponPositionAft","weaponPositionPort","weaponPositionStarboard"];
/** Returns strength value for passed entity.
*/
this._check = function(ent){
var w = ent.weaponFacings,
eq = ent.equipment,
esc = ent.escorts,
sec = ent.subEntityCapacity,
c = 0, wc = 0, ind = 0,
i, l, s, t, tt;
c += ent.maxEnergy*(ent.maxPitch+ent.maxRoll+ent.maxYaw)*ent.energyRechargeRate;
if(ent.isPlayer) c += (ent.maxAftShield*ent.aftShieldRechargeRate+ent.maxForwardShield*ent.forwardShieldRechargeRate)*0.5;
c += ent.maxSpeed*ent.maxThrust;
c *= 0.001;
if(eq && eq.length){
if(ent.isPlayer) c += eq.length;
else c += eq.length*5;
}
if(esc && esc.length){
l = esc.length;
for(i=0;i<l;i++) c += this._check(esc[i])*0.5;
}
c += ent.maxEscorts;
if(w){
for(i=0;i<4;i++){
t = ent[this.$slotsA[i]];
if(t && t.equipmentKey){
ind = this.$weapons.indexOf(t.equipmentKey);
if(ind<0) ind = 6;
tt = ent[this.$slotsB[i]];
if(tt && tt.length) ind += tt.length; // multi
wc += ind;
}
}
if(ent.accuracy>1) wc *= ent.accuracy;
c += wc*10;
}
if(sec){
s = ent.subEntities;
l = (s?s.length:0);
for(i=0;i<l;i++) if(s[i].isTurret) c += 50;
if(ent.isPlayer && l<sec) c += 50*(sec-l); // no cheats
}
c += ent.missileCapacity*5;
if(!ent.maxSpeed) c /= ent.mass*0.000005;
if(ent.isThargoid) c *= 1.5;
c = Math.round(c);
// Add value to ship script.
if(ent.script) ent.script.$libStrength = c;
return c;
};
/** Returns maximum value of NPC ships in the system.
Params:
rel - Piloted ships relative to entity.
all - Return Array of all numbers.
redo - Set script values. Do not use careless.
*/
this._gather = function(rel,all,redo){
var a = [],b,l,i=0,c;
if(rel) b = system.filteredEntities(this,function(e){return(e.isShip && e.isValid && e.isPiloted && !e.isPlayer);},rel,52000);
else {
b = system.allShips;
i = 1;
}
l = b.length;
if(l>400) l = 400; // Cap
if(redo){
for(i;i<l;i++) a.push(this._check(b[i]));
} else {
for(i;i<l;i++){
if(b[i].script){
if(typeof b[i].script.$libStrength==='number') c = b[i].script.$libStrength;
else c = this._check(b[i]);
} else c = -1;
a.push(c);
}
}
if(!all){
if(a.length) a = Math.max.apply(Math,a);
else a = 0;
if(!isFinite(a)) a = 999999;
if(!rel) worldScripts.Lib_Main._lib.$entLastStrength = a;
}
return a;
};
this.shipSpawned = function(ent){
this._check(ent);
if(ent.primaryRole==="lib_test" && ent.script.name!=="lib_test") worldScripts.Lib_Main._lib.$entCstRemoved = true;
};
this.missionScreenOpportunity = function(){this._gather(0,0,1); delete this.missionScreenOpportunity;};
this.shipWillDockWithStation = this.shipExitedWitchspace = function(){this._gather(0,0,1);};
}).call(this);
|
| Scripts/Lib_GUI.js |
/* global addFrameCallback,galaxyNumber,guiScreen,mission,missionVariables,player,removeFrameCallback,setScreenBackground,setScreenOverlay,worldScripts,SoundSource,System */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_GUI";
this.copyright = "(C)2016-2018";
this.description = "GUI images and sounds handling.";
// Full Sets
this.$guis = {};
this.$IDs = {};
// Extension - temporary overrides, FIFO
this.$guisExt = {
GUI_SCREEN_EQUIP_SHIP: [],
GUI_SCREEN_GAMEOPTIONS: [],
GUI_SCREEN_INTERFACES: [],
GUI_SCREEN_KEYBOARD: [],
GUI_SCREEN_LOAD: [],
GUI_SCREEN_LONG_RANGE_CHART: [],
GUI_SCREEN_MANIFEST: [],
GUI_SCREEN_MARKET: [],
GUI_SCREEN_MARKETINFO: [],
GUI_SCREEN_OPTIONS: [],
GUI_SCREEN_REPORT: [],
GUI_SCREEN_SAVE: [],
GUI_SCREEN_SAVE_OVERWRITE: [],
GUI_SCREEN_SHIPLIBRARY: [],
GUI_SCREEN_SHIPYARD: [],
GUI_SCREEN_SHORT_RANGE_CHART: [],
GUI_SCREEN_STATUS: [],
GUI_SCREEN_STICKMAPPER: [],
GUI_SCREEN_STICKPROFILE: [],
GUI_SCREEN_SYSTEM_DATA: []
};
// Extension
this.$IDsExt = {};
// screenID rules - expand, but do not change!
this.$IDRules = {
"oolite-contracts-cargo-none": {pic:1,ov:1,snd:1,mus:1},
"oolite-contracts-cargo-details": {mpic:1,snd:1,mus:1},
"oolite-contracts-cargo-summary": {pic:1,ov:1,snd:1,mus:1},
"oolite-contracts-parcels-none": {pic:1,ov:1,snd:1,mus:1},
"oolite-contracts-parcels-details": {mpic:1,snd:1,mus:1},
"oolite-contracts-parcels-summary": {pic:1,ov:1,snd:1,mus:1},
"oolite-contracts-passengers-none": {pic:1,ov:1,snd:1,mus:1},
"oolite-contracts-passengers-details": {mpic:1,snd:1,mus:1},
"oolite-contracts-passengers-summary": {pic:1,ov:1,snd:1,mus:1},
"oolite-primablemanager": {pic:1,ov:1,snd:1,mus:1},
"oolite-register": {pic:1,ov:1,snd:1,mus:1}
};
this.$ambi = {
audio: true,
guiFX: true,
ex: 0,
last: 0,
reinit: 0,
crowd: "generic",
generic: [],
redux: [],
none: []
};
this.$noEx = Object.keys(this.$IDRules);
this.startUp = function(){
this._aid = worldScripts.Lib_Main._lib;
for(var i=0;i<this.$noEx.length;i++) this._aid.objLock(this.$IDRules[this.$noEx[i]]);
this._aid.objLock(this.$IDRules);
};
// remove missionVariables.LIB_GUI sometime
this.startUpComplete = function(){
delete this.startUpComplete;
var gu,ms = missionVariables.LIB_GUI,ind=0,max=0,mv=missionVariables.LIB_GUI_CONFIG,mvp;
this.$s = new SoundSource();
this.$amb = new SoundSource();
this.$op = null;
this.$cur = null;
this.$k = Object.keys(this.$guis);
if(ms && worldScripts[ms]) this.$cur = ms;
if(mv){
mvp = JSON.parse(missionVariables.LIB_GUI_CONFIG);
if(mvp.cur && worldScripts[mvp.cur]) this.$cur = mvp.cur;
this.$ambi.audio = mvp.audio;
this.$ambi.guiFX = mvp.guiFX;
}
gu = this.$k;
if(!this.$cur && gu.length) this.$cur = gu[gu.length-1];
if(gu && gu.length){
ind = gu.indexOf(this.$cur);
this.$E0 = 0;
if(ind!==-1){
ind = Math.pow(2,ind);
this.$E0 = ind;
}
max = Math.pow(2,gu.length)-1;
this.$inf = {Name:"Lib_GUI",Alias:"Library",Display:expandMissionText("LIB_GUI_DISPLAY"),Alive:"$inf",
Bool:{
B0:{Name:"$ambi.audio",Def:true,Desc:expandMissionText("LIB_GUI_AMBIENT")},
B1:{Name:"$ambi.guiFX",Def:true,Desc:expandMissionText("LIB_GUI_SFXGUI")}
},
EInt:{E0:{Name:"$E0",Def:ind,Min:0,Max:max,Desc:gu,Notify:"_chgSet",OneOfZero:1},Info:expandMissionText("LIB_GUI_CHOOSE_BKD")}};
worldScripts.Lib_Config._registerSet(this.$inf);
}
// TODO: Attempt to avoid JS-reset bug - remove when solved.
setScreenBackground("lib_black.png");
this._setCrowd(player.ship.dockedStation);
this._stationAmb();
missionVariables.LIB_GUI = null;
};
this._chgSet = function(){
var gu = this.$k, ind = this._aid.getMSB(this.$E0)-1;
if(ind<0) this.$cur = null;
else this.$cur = gu[ind];
};
this.playerWillSaveGame = function(){
var o = {
cur: this.$cur,
audio: this.$ambi.audio,
guiFX: this.$ambi.guiFX
};
missionVariables.LIB_GUI_CONFIG = JSON.stringify(o);
};
this.alertConditionChanged = function(){
if(player.ship.isInSpace) this.guiScreenChanged();
};
this.gameResumed = function(){
this.guiScreenChanged();
this._stationAmb();
};
this.gamePaused = function(){
this._stationAmb(1);
};
this.shipDied = function(){
if(this.$guiFCB) removeFrameCallback(this.$guiFCB);
this._stationAmb(1);
};
this.shipDockedWithStation = function(st){
this._setCrowd(st);
this._stationAmb();
};
this._setCrowd = function(st){
var inf, p = ["generic","redux","none"];
if(st.scriptInfo && st.scriptInfo.lib_crowd && p.indexOf(st.scriptInfo.lib_crowd)>-1) inf = st.scriptInfo.lib_crowd;
if(!st.isMainStation && !st.hasNPCTraffic && !inf) this.$ambi.crowd = "none";
else {
if(inf) this.$ambi.crowd = inf;
else if(st.name==="Rock Hermit") this.$ambi.crowd = "redux";
else this.$ambi.crowd = "generic";
}
};
this._stationAmb = function(s){
if(player.ship.isInSpace || s){
if(this.$AmbTimer) this.$AmbTimer.stop();
this.$amb.stop();
this.$ambi.last = 0;
} else {
if(!this.$ambi.audio) return;
if(this.$ambi.ex){
this.$ambi.last = 0;
if(this.$AmbTimer){
this.$AmbTimer.stop();
this.$AmbTimer.nextTime = clock.absoluteSeconds+1;
this.$AmbTimer.start();
}
return;
}
var w = this.$ambi[this.$ambi.crowd], i = Math.floor(Math.random()*w.length), d,r;
if(w.length){
this.$amb.sound = w[i].name;
this.$amb.volume = w[i].vol;
this.$amb.play();
d = w[i].dur-1;
if(this.$AmbTimer) this.$AmbTimer.stop();
else this.$AmbTimer = new Timer(this,this._stationAmb,-1,d);
this.$AmbTimer.nextTime = clock.absoluteSeconds+d;
this.$AmbTimer.start();
this.$ambi.reinit = 0;
this.$ambi.last = clock.absoluteSeconds+d;
}
}
};
this.shipWillLaunchFromStation = function(){
this.$s.stop();
this._stationAmb(1);
};
this.guiScreenChanged = function(){
var gu = guiScreen, amb;
switch(gu){
case "GUI_SCREEN_EQUIP_SHIP":
case "GUI_SCREEN_LONG_RANGE_CHART":
case "GUI_SCREEN_MANIFEST":
case "GUI_SCREEN_MARKET":
case "GUI_SCREEN_MARKETINFO":
case "GUI_SCREEN_REPORT":
case "GUI_SCREEN_SHIPYARD":
case "GUI_SCREEN_SHORT_RANGE_CHART":
case "GUI_SCREEN_STATUS":
this.$op = null;
this._setGUI(gu,0);
this.$ambi.ex = 0;
break;
case "GUI_SCREEN_SYSTEM_DATA":
var inf = System.infoForSystem(galaxyNumber,player.ship.infoSystem),sp = 0;
if(inf.sun_gone_nova || inf.sun_going_nova) sp = 1;
this.$op = null;
this._setGUI(gu,sp);
this.$ambi.ex = 0;
break;
case "GUI_SCREEN_INTERFACES":
case "GUI_SCREEN_SHIPLIBRARY":
this.$op = gu;
this._setGUI(gu,0);
this.$ambi.ex = 0;
break;
case "GUI_SCREEN_GAMEOPTIONS":
case "GUI_SCREEN_KEYBOARD":
case "GUI_SCREEN_LOAD":
case "GUI_SCREEN_OPTIONS":
case "GUI_SCREEN_SAVE":
case "GUI_SCREEN_SAVE_OVERWRITE":
case "GUI_SCREEN_STICKMAPPER":
case "GUI_SCREEN_STICKPROFILE":
this.$op = gu;
this._setGUI(gu,0);
this._stationAmb(1);
amb = 1;
break;
case "GUI_SCREEN_MISSION":
this.$op = null;
if(mission.screenID) this._setMS(mission.screenID);
else {
this._stationAmb(1);
this.$ambi.reinit = 1;
amb = 1;
}
if(mission.exitScreen) this.$op = gu;
break;
case "GUI_SCREEN_MAIN":
amb = 1;
this.$op = null;
break;
default:
this.$op = null;
}
if(this.$op){
if(!this.$guiFCB) this.$guiFCB = addFrameCallback(this._checkGUI.bind(this));
} else {
if(this.$guiFCB) removeFrameCallback(this.$guiFCB);
delete this.$guiFCB;
}
if(!amb && !this.$ambi.reinit && this.$ambi.last<=clock.absoluteSeconds+2) this._stationAmb();
if(amb) this.$ambi.ex = 1;
};
this.missionScreenEnded = function(){
if(this.$ambi.reinit) this._stationAmb();
};
this._checkGUI = function(){
if(!player.ship.isValid) return;
if(this.$op && guiScreen!==this.$op && guiScreen!=="GUI_SCREEN_MISSION") this.guiScreenChanged();
};
this._setGUI = function(gui,spc){
if(!this.$cur && !this.$guisExt[gui].length){
setScreenBackground("lib_black.png");
return;
}
var g = this.$guis[this.$cur],
ex = this.$guisExt[gui],
big = (player.ship.hudAllowsBigGui || player.ship.hudHidden),
img,ov,ref,snd,sou,w;
if(!ex.length && (!g || (!g[gui] && !g.generic))) return;
if(ex.length) w = ex[0];
else if(g[gui]) w = g[gui];
else w = g.generic;
if(player.ship.isInSpace){
sou = "sndF";
if(spc && w.picNova) img = "picNova";
else if(w.picFlight) img = "picFlight";
else if(w.pic) img = "pic";
} else {
sou = "snd";
if(spc && w.picNova) img = "picNova";
else if(player.ship.dockedStation.script.$guiVoid && w.picVoid){
img = "picVoid";
sou = null;
} else if(w.pic) img = "pic";
}
if(sou){
if(w[sou]) snd = w[sou];
else if(w.sndRef){
ref = this.$guis[w.sndRef];
if(ref && ref[gui] && ref[gui][sou]) snd = ref[gui][sou];
}
}
if(img){
if(player.alertCondition===3 && w[img+"Red"]) img = img+"Red";
if(big && w[img+"Big"]) img = img+"Big";
this._applyBG(w[img]);
}
if(w.ov){
ov = "ov";
if(player.alertCondition===3 && w[ov+"Red"]) ov = ov+"Red";
if(big && w[ov+"Big"]) ov = ov+"Big";
this._applyOV(w[ov]);
}
if(snd && this.$ambi.guiFX) this.$s.playSound(snd);
this.$guisExt[gui].shift();
};
this._setMS = function(id){
if(!this.$cur && !this.$IDsExt[id]) return;
var m = this.$IDRules,
s = this.$IDs[this.$cur],
ex = (this.$noEx.indexOf(id)===-1 && this.$IDsExt[id]?this.$IDsExt[id]:null),
big = (player.ship.hudAllowsBigGui || player.ship.hudHidden),
sou = "snd",
img,ov,w,ref;
if(!m[id] || (!ex && !s && (!s[id] && !s.generic))){
this.$s.stop();
this._stationAmb(1);
this.$ambi.reinit = 1;
this.$ambi.ex = 1;
return;
}
if(ex) w = ex;
else if(s[id]) w = s[id];
else w = s.generic;
if(player.ship.isInSpace) sou = "sndF";
if(m[id].snd && this.$ambi.guiFX){
if(w[sou]) this.$s.playSound(w[sou]);
else if(w.sndRef){
ref = this.$IDs[w.sndRef];
if(ref && ref[id] && ref[id][sou]) this.$s.playSound(ref[id][sou]);
} else this.$s.stop();
} else this.$s.stop();
if(m[id].mpic && w.mpic) ov = "mpic";
else {
if(m[id].pic && w.pic) img = "pic";
if(m[id].ov && w.ov) ov = "ov";
}
if(img){
if(big && w.picBig) img = "picBig";
this._applyBG(w[img]);
}
if(ov){
if(big && w[ov+"Big"]) ov = ov+"Big";
this._applyOV(w[ov]);
}
};
this._applyBG = function(img){
if(typeof img==="object" && img.scale){
var sc = this._aid.ooImageScale(img.x,img.y,img.zoom);
setScreenBackground({name:img.name,height:sc.height,width:sc.width});
} else setScreenBackground(img);
};
this._applyOV = function(ov){
if(typeof ov==="object" && ov.scale){
var sc = this._aid.ooImageScale(ov.x,ov.y,ov.zoom);
setScreenOverlay({name:ov.name,height:sc.height,width:sc.width});
} else setScreenOverlay(ov);
};
}).call(this);
|
| Scripts/Lib_Main.js |
/* jshint bitwise:false, forin:false */
/* global _libMain,defaultFont,expandMissionText,galaxyNumber,global,log,missionVariables,oolite,player,system,worldScripts,Ship,System */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 - Helper functions and data objects */
(function () {
"use strict";
this.name = "Lib_Main";
this.author = "Svengali";
/** _libMain - Main class. There's often no need to instantiate it for other AddOns.
* Just create a reference -> this._aid = worldScripts.Lib_Main._lib;
*/
this._libMain = function () {};
_libMain.prototype = {
constructor: _libMain,
/** Contains connected systems based on players position when
* the game starts or player jumps to a new galaxy.
*/
$connections: [
[],
[],
[],
[],
[],
[],
[],
[]
],
$missionActive: null,
/** Contains data keys of all ships.
*/
$ships: [],
spc: String.fromCharCode(31),
spcw: defaultFont.measureString(String.fromCharCode(31)),
spcs: String.fromCharCode(32),
spcsw: defaultFont.measureString(String.fromCharCode(32)),
// Sanity
$entCstChanged: [],
$entCstPatched: false,
$entCstRemoved: false,
$entLastStrength: 0,
// ***** Number *****
/** Returns clamped Number in range min...max.
*/
clamp: function (n, min, max) {
return ((n > max) ? max : (n < min) ? min : n);
},
/** Counts set bits in Number.
*/
cntBits: function (n) {
var res = 0;
if (n < 0) n = ~n;
while (n > 0) {
if ((n & 1)) res++;
n >>= 1;
}
return res;
},
/** Returns greatest common denominator.
*/
gcd: function (x, y) {
return (y === 0 ? x : this.gcd(y, x % y));
},
/** Returns position of most significant bit of non-negative Number or zero.
*/
getMSB: function (n) {
var res = 15;
for (var r = 8; r > 0; r >>= 1) res = (n < 1 << res) ? res - r : res + r;
return ((n < 1 << res) ? res : res + 1);
},
/** Modulo. Differs from JS native for negative values.
* -2%3 = -2 while this._aid.mod(-2,3) = 1
*/
mod: function (x, y) {
return x - Math.floor(x / y) * y;
},
/** Returns random Number in range 0...n.
*/
rand: function (n) {
return n * (Math.random() % 1) | 0;
},
/** Returns random Number in range min...max.
*/
randXY: function (min, max) {
return min + this.rand(max - min + 1);
},
/** Returns String with converted base of Number.
* this._aid.toBase(-29,16) = "-1d"
*/
toBase: function (n, bas, from) {
return parseInt(n, from || 10).toString(bas);
},
/** Returns String with converted base of Number. Programmers version.
* this._aid.toBaseSign(-29,16) = "-0xffffe3"
*/
toBaseSign: function (n, bas) {
return (n < 0 ? "-" : "") + (bas === 16 ? "0x" : "") + (parseInt((n < 0 ? (0xffffffffffff + n) + 1 : n), 10) & 0xffffff).toString(bas);
},
/** Returns String with a leading zero if n<10.
*/
toLZ: function (n) {
return ((n !== null && n < 10 && n >= 0 ? "0" : "") + n);
},
/** Returns String with a leading zeros if n<100.
*/
toLZZ: function (n) {
return (n !== null && n < 100 && n >= 0 ? "0" + this.toLZ(n) : "" + n);
},
/** Returns String with specified length filled with leading zeros.
*/
toNLZ: function (n, len) {
return ("0000000000000000" + n).substr(-len);
},
/** Returns rounded Number with specified precision.
*/
toPrec: function (n, p) {
if (!n) return 0;
var y = Math.pow(10, p);
return Math.round(n * y) / y;
},
// ***** String *****
/** Returns reverted String.
*/
strRev: function (str) {
if (!str) return "";
var i = str.length,
res = "";
while (i--) res += str[i];
return res;
},
/** Returns random String with specified length.
*/
strRND: function (len, chars) {
chars = chars || 'abcdefghijklmnopqrstuvwxyz';
var res = '',
rndPos;
for (var i = 0; i < len; i++) {
rndPos = Math.floor(Math.random() * chars.length);
res += chars.substring(rndPos, rndPos + 1);
}
return res;
},
/** Returns random numbered String with specified length.
*/
strRNDInt: function (len) {
var res = String(1000000000 + Math.random() * 1000000000 | 0);
return res.substr(0, len);
},
/** Returns trimmed String. Unlike .trim() it also removes control chars.
*/
strTrim: function (str) {
return str.replace(/[\f\r\n\t\v]/g, "").trim();
},
// ***** Array *****
/** Merges nested Arrays
*/
arrConcat: function (arrA, arrB) {
if (this.typeGet(arrB) !== "array") return arrA;
var res = arrA.slice(0),
na = arrB.slice(0);
var la = res.length,
lb = na.length;
for (var i = 0; i < lb; i++) {
if (i > la - 1) break;
if (this.typeGet(na[i]) === "array") res[i] = res[i].concat(na[i]);
}
return res;
},
/** Returns difference between Arrays. Strict equality.
*/
arrDiff: function (a, b, oneway) {
var res = [],
i = a.length;
while (i--)
if (b.indexOf(a[i]) === -1) res.push(a[i]);
if (oneway) return res;
i = b.length;
while (i--)
if (a.indexOf(b[i]) === -1) res.push(b[i]);
return res;
},
/** Returns flattened Array.
*/
arrFlat: function (arr) {
return this._arrFlatten(arr, []);
},
/** Returns Array with min and max of flat input Array containing only numbers.
*/
arrMinMax: function (arr) {
return [Math.min.apply(Math, arr), Math.max.apply(Math, arr)];
},
/** Returns Array without specified element. Strict equality.
*/
arrOmit: function (arr, ele) {
var len = arr.length,
res = arr.slice(0);
for (var i = 0; i < len; i++) {
if (res[i] === ele) res.splice(i, 1);
}
return res;
},
/** Returns shuffled Array.
*/
arrShuffle: function (arr) {
var j, k, t, res = arr.slice(0);
j = res.length;
do {
k = (Math.random() * (j--)) << 0;
t = res[j];
res[j] = res[k];
res[k] = t;
} while (j);
return res;
},
/** Returns sorted Array of Objects. Selectionsort.
*/
arrSortBy: function (arr, prop) {
var res = arr.slice(0),
len = res.length,
min, i, j;
for (i = 0; i < len; i++) {
min = i;
for (j = i + 1; j < len; j++) {
if (j > 0 && j < len && res[j][prop] < res[min][prop]) min = j;
}
if (i !== min) this._arrSwap(res, i, min);
}
return res;
},
/** Merges Arrays.
*/
arrUnion: function () {
var len = arguments.length,
res = [];
while (len--) {
var arg = arguments[len];
for (var i = 0; i < arg.length; i++) {
var ele = arg[i];
if (res.indexOf(ele) === -1) res.push(ele);
}
}
return res;
},
/** Returns Array with unique entries. Strict equality.
*/
arrUnique: function (arr) {
var res = arr.slice(0),
len = res.length,
i = -1;
while (i++ < len) {
var j = i + 1;
for (; j < res.length; ++j) {
if (res[i] === res[j]) res.splice(j--, 1);
}
}
return res;
},
// ***** Object *****
/** Return deep cloned Object.
*/
objClone: function (obj) {
if (typeof obj !== 'object' || obj === null) return obj;
var res = obj.constructor();
for (var i in obj) res[i] = this.objClone(obj[i]);
return res;
},
/** Deep freeze Object. In-place.
*/
objFreeze: function (obj) {
var prop, propKey;
Object.freeze(obj);
for (propKey in obj) {
prop = obj[propKey];
if (!obj.hasOwnProperty(propKey) || typeof prop !== "object" || Object.isFrozen(prop)) continue;
this.objFreeze(prop);
}
},
/** Returns value of the Objects member in the specified path or null.
*/
objGet: function (obj, path) {
var a = this.objGrab(obj, path);
if (!a[0] || !a[1]) return null;
return a[0][a[1]];
},
/** Returns Array with Object and key following the specified path.
*/
objGrab: function (obj, path) {
var p = path.split("."),
len = p.length - 1,
last = p.pop(),
o = obj;
if (len < 1) return [obj, last];
for (var i = 0; i < len; i++) o = this._objRet(o, p[i]);
return [o, last];
},
/** Lock object, but leave expandable.
*/
objLock: function (obj) {
var props = Object.getOwnPropertyNames(obj);
for (var i = 0; i < props.length; i++) {
var desc = Object.getOwnPropertyDescriptor(obj, props[i]);
if ("value" in desc) desc.writable = false;
desc.configurable = false;
Object.defineProperty(obj, props[i], desc);
}
},
/** Returns merged object. In-place.
*/
objMerge: function (target, obj, omit) {
for (var key in obj) {
if (!this._objHasOwn(obj, key)) continue;
if (omit && !this._objHasOwn(target, key)) continue;
var val = obj[key];
if (typeof target[key] === "object") {
if (!target[key]) target[key] = this.objClone(val);
else target[key] = this.objMerge(target[key] || {}, val);
} else target[key] = this.objClone(val);
}
return target;
},
/** Returns deep merged object. In-place.
*/
objMergeDeep: function (orig, objects) {
if (typeof orig !== "object") orig = {};
var len = arguments.length,
target = this.objClone(orig);
for (var i = 1; i < len; i++) {
var val = arguments[i];
if (typeof val === "object") this.objMerge(target, val);
}
return target;
},
/** Passes value to Function in Object following the specified path. Returns true or false.
*/
objPass: function (obj, path, val) {
var a = this.objGrab(obj, path);
if (!a[0] || !a[1]) return false;
if (typeof a[0][a[1]] === 'function') {
a[0][a[1]](val);
return true;
}
return false;
},
/** Passes value to Function in Object following the specified path. Returns returned value.-)
*/
objRequest: function (obj, path, val) {
var a = this.objGrab(obj, path);
if (!a[0] || !a[1]) return false;
if (typeof a[0][a[1]] === 'function') return a[0][a[1]](val);
return false;
},
/** Deep seal Object. In-place.
*/
objSeal: function (obj) {
var prop, propKey;
Object.seal(obj);
for (propKey in obj) {
prop = obj[propKey];
if (!obj.hasOwnProperty(propKey) || typeof prop !== "object" || Object.isSealed(prop)) continue;
this.objSeal(prop);
}
},
/** Sets value in Object following the specified path. Returns true or false.
*/
objSet: function (obj, path, val) {
var a = this.objGrab(obj, path);
if (!a[0] || !a[1]) return false;
if (!a[1]) {
obj[path] = val;
return true;
}
a[0][a[1]] = val;
return true;
},
// ***** Type *****
/** Returns lowercase type of Argument for JS native and Oolites classes.
*/
typeGet: function (obj) {
var t = typeof obj;
switch (t) {
case 'undefined':
case 'boolean':
case 'number':
case 'string':
case 'function':
return t;
}
if (!obj) return null;
t = Object.prototype.toString.call(obj).substr(8).replace("]", "");
return t.toLowerCase();
},
// ***** AddOn *****
/** Checks required worldScripts and versions. The Array req is expected to contain two elements
* (name and version) per check and version must be null for legacy scripts or if you want to
* check only for existance!
* Note: Checks property '$deactivated' in scripts.
*/
addOnVersion: function (who, req, quiet) {
var ok, ws, len = req.length,
res = [];
for (var i = 0; i < len; i += 2) {
ok = 1;
ws = worldScripts[req[i]];
if (typeof ws === 'undefined') ok = 0;
else if (ws.$deactivated || (req[i + 1] && !this.cmpVersion(ws.version, req[i + 1]))) ok = 0;
if (!ok) {
if (!quiet) {
if (!req[i + 1]) this._addOnVersion(who, req[i], null);
else this._addOnVersion(who, req[i], req[i + 1]);
}
}
res.push(ok);
}
return res;
},
/** Clears specified missionVariables.
*/
clrMVs: function (arr) {
var i = 0,
l = arr.length;
for (i; i < l; i++) missionVariables[arr[i]] = null;
return;
},
/** Delete specified properties.
*/
clrProps: function (where, arr) {
var i = 0,
l = arr.length;
for (i; i < l; i++) delete worldScripts[where][arr[i]];
return;
},
/** Compares dotted version Strings. Strips pre-/suffixes in first argument.
* Returns 0 if smaller, 1 if equal and 2 if bigger.
* JS native .localeCompare() may be another option.
*/
cmpVersion: function (act, exp) {
var x = act.replace(/[^\d\.]/g, "").split('.'),
y = exp.split('.');
if (!x.length) return 0;
for (var i = 0; i < x.length; i++) {
if (i > y.length - 1 || x[i] > y[i]) return 2;
if (x[i] < y[i]) return 0;
}
return 1;
},
// ***** Screens *****
/** Returns aligned String.
* e.g. this._aid.scrAddLine([ ["First",8],["Second",8],["Third",8] ],"","\n");
*/
scrAddLine: function (line, sep, brk) {
if (!line) {
if (brk) return brk;
return "";
}
var le = line.length,
res = "",
coun = 0,
tmp;
for (var i = 0; i < le; i++) {
if (coun > 30) break;
tmp = this.scrToWidth(line[i][0], line[i][1], "", 1);
res += tmp[0] + (sep ? sep : "");
coun += tmp[1];
if (sep === "\n") coun = 0;
}
if (brk) res += brk;
return res;
},
/** Sets unselectable flag for missionscreen choices. In-place.
*/
scrChcUnsel: function (opt, key) {
if (typeof opt[key] === 'string') opt[key] = {
text: opt[key],
unselectable: true
};
else if (typeof opt[key] === 'object') opt[key].unselectable = true;
return opt;
},
/** Returns String with linebreaks up to max.
*/
scrFillLines: function (cur, max) {
var res = "";
for (var i = cur; i < max; i++) res += "\n";
return res;
},
/** Returns String with specified length in em.
* Truncated if width > max, otherwise filled up with space or chr.
*/
scrToWidth: function (str, max, chr, ret, rgt) {
if (typeof str === 'object' && str) str = str.toSource();
str = String(str);
var l = defaultFont.measureString(str),
c, d;
if (max < 1) {
if (ret) return [str, l];
return str;
}
if (chr) c = defaultFont.measureString(chr);
if (l > max) {
while (l > max) {
if (str && str.length > 1) str = str.substr(0, str.length - 1);
d = defaultFont.measureString(str);
l = d;
}
}
if (l < max) {
while (l < max) {
if (chr && c < max - l) {
str += chr;
l += c;
} else {
if (max - l > this.spcsw) {
if (rgt) str = this.spcs + str;
else str += this.spcs;
l += this.spcsw;
} else {
if (max - l > this.spcw) {
if (rgt) str = this.spc + str;
else str += this.spc;
l += this.spcw;
} else break;
}
}
}
}
if (ret) return [str, l];
return str;
},
// ***** Oolite *****
/** Returns Object with width, height, gcd and ratio of screen window.
*/
ooScreen: function () {
var g = this._ooGame(),
w, h, d, a;
w = g.gameWindow.width;
h = g.gameWindow.height;
d = this.gcd(w, h);
a = w / h;
return {
width: w,
height: h,
gcd: d,
ratio: a
};
},
/** Returns shader support level.
*/
ooShaders: function () {
var g = this._ooGame();
if (g.wireframeGraphics) return 0;
switch (g.detailLevel) {
case 'DETAIL_LEVEL_MINIMUM':
case 'DETAIL_LEVEL_NORMAL':
return 0;
case 'DETAIL_LEVEL_SHADERS':
return 1;
case 'DETAIL_LEVEL_EXTRAS':
return 2;
default:
return 0;
}
},
/** Returns Object with width and height to be used for images
* x and y are width and height in pixels, zoom any number or 0.
* Author: Norbert Nagy.
*/
ooImageScale: function (x, y, zoom) {
var he = 480,
wi = 0,
o = this.ooScreen();
if (x > 0 && y > 0) {
if (o.ratio >= x / y) {
if (zoom < 0) wi = 0;
else {
if (zoom) he = 0;
wi = o.ratio * 480;
}
} else if (zoom < 0) {
he = 0;
wi = o.ratio * 480;
} else if (!zoom) wi = o.ratio * 480;
}
if (!wi && he > 0) wi = null;
else if (wi > 0 && !he) he = null;
return {
height: he,
width: wi
};
},
// ***** Entities *****
/** Spawns VisualEffect in front of (or behind) the player.
*/
entFXCreate: function (ent, mul) {
return system.addVisualEffect(ent, player.ship.position.add(player.ship.vectorForward.multiply(mul)));
},
/** Sets main texture for entity.
*/
entSetMainTex: function (ent, tex) {
var ta = ent.getMaterials(),
tb = Object.keys(ta),
tc = ta[tb[0]].textures;
if (!tc) return false;
if (typeof tc[0] === 'string') ta[tb[0]].textures[0] = tex;
else ta[tb[0]].textures[0].name = tex;
ent.setMaterials(ta);
},
setMaterials: function (ent, obj) {
if (obj.mat && obj.sha) ent.setMaterials(obj.mat, obj.sha);
else if (obj.mat) ent.setMaterials(obj.mat, {});
else if (obj.sha) ent.setMaterials({}, obj.sha);
return true;
},
// ***** Helper *****
_addOnVersion: function (w, r, v) {
log("Check", expandMissionText("LIB_MAIN_CHECK_ADDONVER", {w:w, r:r, v:(v ? expandMissionText("LIB_MAIN_MINVER", {v:v}): "")}));
return;
}, // w + " requirement not matched : " + r + (v ? " required min. version " + v : "") + " not found."
_arrFlatten: function (arr, res) {
var len = arr.length,
i = -1;
while (len--) {
var cur = arr[++i];
if (Array.isArray(cur)) this._arrFlatten(cur, res);
else res.push(cur);
}
return res;
},
_arrSwap: function (arr, f, s) {
var temp = arr[f];
arr[f] = arr[s];
arr[s] = temp;
},
_chkGlobal: function () {
var a = Object.getOwnPropertyNames(global),
warn = [],
t, ok = expandMissionText("LIBC_GLOB").split("|");
for (var i = 0; i < a.length; i++)
if (ok.indexOf(a[i]) === -1) warn.push(a[i]);
if (warn.length) {
log("WARNING", expandMissionText("LIB_MAIN_GLOBAL_WARNING"));
t = JSON.stringify(warn);
log("WARNING", t);
}
},
_cmpNum: function (a, b) {
return a - b;
},
_cmpGen: function (a, b) {
return (b < a) - (a < b);
},
_cmpObjKey: function (a, b, k) {
return a[k] - b[k];
},
_cmpArrKey: function (a, b) {
return a[0] - b[0];
},
_getMat: function (ent) {
var ta = ent.getMaterials(),
tb = Object.keys(ta);
return ta[tb[0]];
},
// Collecting the data + Class A algorithm is expensive.
_getConnected: function (gal, sys, coo) {
var gn = galaxyNumber,
id = system.ID,
cpp = player.ship.galaxyCoordinatesInLY,
check = [],
cur = [],
gInfo = [],
c, cp, dist, len, i, o, r, s, t, u, w;
if (typeof gal === 'number') {
gn = gal;
cpp = coo;
id = sys;
}
// Collect coordinates
for (i = 0; i < 256; i++) {
c = System.infoForSystem(gn, i).coordinates;
r = {
x: c.x,
y: c.y,
id: i,
done: 0
};
gInfo.push(r);
}
cp = {
x: cpp.x,
y: cpp.y,
z: 0
};
gInfo = this.arrSortBy(gInfo, "x");
this.$connections[gn] = [];
// Start loop
for (u = 0; u < 256; u++) {
t = gInfo[u];
if (t.x > cp.x + 7.15) break;
if (t.x < cp.x - 7.15 || t.y < cp.y - 7.15 || t.y > cp.y + 7.15) continue;
dist = Math.sqrt((cp.x - t.x) * (cp.x - t.x) + (cp.y - t.y) * (cp.y - t.y));
if (dist < 7.341) cur.push(t);
}
// Grow
while (cur.length) {
check = check.concat(cur);
cur = [];
for (o = 0; o < check.length; o++) {
cp = check[o];
if (cp.id === id || cp.done) continue;
for (i = 0; i < 256; i++) {
t = gInfo[i];
if (t.x > cp.x + 7.15) break;
if (t.x < cp.x - 7.15 || t.y < cp.y - 7.15 || t.y > cp.y + 7.15) continue;
dist = Math.sqrt((cp.x - t.x) * (cp.x - t.x) + (cp.y - t.y) * (cp.y - t.y));
if (dist < 7.341 && check.indexOf(t) === -1 && cur.indexOf(t) === -1) cur.push(t);
}
}
len = check.length;
for (w = 0; w < len; w++) check[w].done = 1;
}
len = check.length;
for (s = 0; s < len; s++) this.$connections[gn].push(check[s].id);
},
_objHasOwn: function (obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
},
_objRet: function (obj, prop) {
if (obj[prop] && typeof obj[prop] === 'object') return obj[prop];
return obj;
},
_ooGame: function () {
return oolite.gameSettings;
},
_sanity: function () {
return {
changed: this.$entCstChanged,
removed: this.$entCstRemoved,
strength: this.$entLastStrength,
patched: this.$entCstPatched
};
},
_shuffle: function () {
return 0.5 - Math.random();
}
};
/* Do before startUp. These features are useful for other OXPs, but are somewhat slow
and it's better to have it done only once instead of slow code in lots of OXPs.
*/
this._lib = new this._libMain(); // Create instance
this._lib.$ships = Ship.keys().sort();
this.startUp = this.playerEnteredNewGalaxy = function () {
this._lib._getConnected();
};
this.missionScreenOpportunity = function () {
delete this.missionScreenOpportunity;
this._lib._chkGlobal();
this.shipWillExitWitchspace();
};
this.shipWillExitWitchspace = function () {
system.addShips('lib_test', 1, [99999999, 99999999, 99999999], 15000);
};
}).call(this); |
| Scripts/Lib_MissionCoord.js |
/* jshint bitwise:false, forin:false */
/* global galaxyNumber,log,system,worldScripts */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_MissionCoord";
// TODO: use $missionActive in Lib_Main
this.$pool = [];
this.startUp = function(){
delete this.startUp;
this._bSearch = new worldScripts.Lib_BinSearch._lib_BinSearch();
this.$checked = false;
this.$isMission = false;
this.$dbg = false;
};
this._prepare = function(){
var s = [],r = this.$pool.length;
if(r){
var merged = [],pos=0;
for(var m=0;m<r;m++){
s = this.$pool[m];
if(s.length!==2 || !s[1].name || typeof s[1].name!=='string' || !s[1].func || typeof s[1].func!=='string') continue;
if(s[1].hasOwnProperty("incOXP")){
var temp = s[1].incOXP;
for(var i=0;i<temp.length;i++){
if(worldScripts[temp[i]]!=='undefined'){
log(this.name,expandMissionText("LIB_MISSCOORD_DROPTOKEN", {s0:s[0], name:s[1].name, func:s[1].func, inc:temp[i]}));
continue;
}
}
}
if(!s[1].hasOwnProperty("mutalEx") || typeof s[1].mutalEx!=='number') s[1].mutalEx = 0;
pos = merged.indexOf(s[0]);
if(pos===-1) merged.push(s[0],{0:s[1]});
else {
var q = merged[pos+1];
for(var p=1;p<10;p++){
if(q.hasOwnProperty(p)) continue;
q[p] = s[1];
break;
}
}
}
r = merged.length;
for(var j=0;j<r;j+=2){
this._bSearch.add(merged[j],merged[j+1]);
}
if(this.$dbg) log(this.name,"merged: "+JSON.stringify(merged));
} else {
delete this._performCheck;
delete this.shipWillExitWitchspace;
delete this.shipWillLaunchFromStation;
this.$checked = true;
}
delete this.alertConditionChanged;
delete this.guiScreenChanged;
delete this._prepare;
};
this._performCheck = function(early){
this.$checked = true;
if(this.$isMission) return;
var test = system.description,prop;
var pRand = Math.floor(100*system.scrambledPseudoRandomNumber(system.ID));
var rest = test.replace(/[^a-zA-Z]/g,' ');
rest = rest.split(" ");
rest = worldScripts.Lib_Main._lib.arrUnique(rest);
var fflag = false, l = rest.length, muteGroup = [];
for(var s=0;s<l;s++){
fflag = this._bSearch.contains(rest[s]);
if(fflag){
for(prop in fflag){
var c = fflag[prop];
if((early && !c.early) || (!early && c.early)) continue;
if(muteGroup.indexOf(c.mutalEx)!==-1) continue;
if(c.chance && Math.random()>c.chance) continue;
if(c.gal && c.gal.indexOf(galaxyNumber)===-1) continue;
if(c.ID && c.ID.indexOf(system.ID)===-1) continue;
if(c.gov && c.gov.indexOf(system.government)===-1) continue;
if(c.seeds && c.seeds.indexOf(pRand)===-1) continue;
if(c.exToken && rest.indexOf(c.exToken)!==-1) continue;
if(this.$dbg) log(this.name,expandMissionText("LIB_MISSCOORD_CHECK", {name:c.name, muteg:c.mutalEx, rest:rest[s]}));
if(worldScripts[c.name]){
var act = false;
if(c.func && worldScripts[c.name][c.func]) act = worldScripts[c.name][c.func](rest[s]);
if(act){
muteGroup.push(c.mutalEx);
this.$isMission = true;
}
}
}
}
}
};
this.alertConditionChanged = this.guiScreenChanged = function(){
if(this._prepare) this._prepare();
if(!this.$checked && this._performCheck) this._performCheck();
};
this.shipWillExitWitchspace = function(){
this.$isMission = false;
if(this._performCheck) this._performCheck(1);
};
this.shipExitedWitchspace = function(){
if(this._performCheck) this._performCheck();
};
this.shipWillLaunchFromStation = function(){
if(this._prepare) this._prepare();
if(!this.$checked && this._performCheck) this._performCheck(1);
};
this.shipLaunchedFromStation = function(){
if(!this.$checked && this._performCheck) this._performCheck();
};
}).call(this);
|
| Scripts/Lib_Music.js |
/* jshint forin:false, bitwise:false */
/* global Sound,SoundSource,Timer,clock,guiScreen,mission,missionVariables,player,system,worldScripts */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function () {
"use strict";
this.name = "Lib_Music";
this.copyright = "(C)2016-2018";
this.description = "Event-driven and generic music handling.";
this.$E0 = 0;
this.$inf = {
Name: "Lib_Music", Display: expandMissionText("LIB_MUSIC_DISPLAY"), Alive: "$inf", Alias: "Library",
SInt: { S0: { Name: "$dub.vol", Def: 0.8, Min: 0, Max: 1, Float: true, Desc: expandMissionText("LIB_MUSIC_VOL"), Notify: "_updateVol" } },
EInt: { E0: { Name: "$E0", Def: 0, Min: 0, Max: 1, Hide: true, Desc: [" "] }, Info: expandMissionText("LIB_MUSIC_NOADDON"), Notify: "_buildList" }
};
this.$act = {
generic: 0
};
this.$groupIDs = [];
this.$radios = [];
this.$media = {
aegis: { enter: [], exit: [] },
alert: { red: [] },
docked: { main: [], any: [] },
exitWS: { inter: [], goneNova: [], doNova: [], standard: [] },
killed: { any: [] },
launch: { inter: [], goneNova: [], doNova: [], main: [], any: [] },
planetIn: { enterMain: [], enterSun: [], any: [] },
planetOut: { exitMain: [], exitSun: [], any: [] },
radio: { generic: [] },
rescued: { any: [] },
scooped: { any: [] },
scoopFuel: { fuel: [] }
};
this.$dub = {
auto: 0,
channel: null,
cnt: 0,
cur: null,
dur: 0,
ent: null,
hand: null,
kick: 0,
lockAlert: 1,
lockDock: 0,
lockFuel: 1,
lockKill: 1,
lockPlanet: 1,
now: 0,
queue: [],
radio: null,
reinit: 0,
spec: null,
vol: 0.8
};
this.startUp = function () {
delete this.startUp;
var mus;
this._aid = worldScripts.Lib_Main._lib;
this.$snd = new SoundSource();
this.$snd.sound = "lib_music_fade.ogg";
if (missionVariables.LIB_MUSIC) {
mus = JSON.parse(missionVariables.LIB_MUSIC);
this.$dub.vol = mus.vol;
this.$snd.volume = mus.vol;
}
};
this.playerWillSaveGame = function () {
var t, s = [], ind, mus = {};
if (this.$E0) {
t = [].concat(this.$inf.EInt.E0.Desc);
for (var i = 0; i < t.length; i++) {
ind = Math.pow(2, i);
if (this.$E0 & ind) s.push(t[i]);
}
if (s.length > 24) s.length = 24;
missionVariables.LIB_RADIO = JSON.stringify(s);
} else missionVariables.LIB_RADIO = null;
mus.vol = this.$dub.vol;
missionVariables.LIB_MUSIC = JSON.stringify(mus);
};
/** Expects Object with the structure of this.$media (can be partial),
* except radio. The Arrays contain Objects with members:
* {snd: <filename>, dur: duration seconds <integer>, vol: optional, volume 0...1 <float>}
*/
this._addEventMusic = function (obj, ID) {
if (!obj || typeof obj !== "object" || typeof ID !== "string") return false;
var c = this._aid.objClone(obj);
for (var h in c) {
if (!this.$media[h] || h === "radio") continue;
for (var s in c[h]) {
if (s === "any" && !this.$media[h][s]) continue;
if (!this.$media[h][s]) this.$media[h][s] = [];
for (var i = 0; i < c[h][s].length; i++) {
c[h][s][i].act = ID;
this.$media[h][s].push(c[h][s][i]);
}
}
}
if (this.$actClone) {
this.$actClone[ID] = 0;
this.$act[ID] = 0;
} else if (typeof this.$act[ID] !== "number") this.$act[ID] = 0;
if (this.$groupIDs.indexOf(ID) === -1) this.$groupIDs.push(ID);
return true;
};
/** Toggle status for group ID.
* - ID: Name <string>
*/
this._toggleGroup = function (ID) {
var a = this.$act;
if (typeof a[ID] !== "number") return false;
if (this.$actClone) a = this.$actClone;
if (!a[ID]) a[ID] = 1;
else a[ID] = 0;
return a[ID];
};
/** Take priority for the specified GroupID.
* - ID: Name <string>
*/
this._setPriorityGroup = function (ID) {
var g, i, l;
if (typeof this.$act[ID] !== "number") return false;
this._clrPriorityGroup();
this.$actClone = this._aid.objClone(this.$act);
g = this.$groupIDs;
l = g.length;
for (i = 0; i < l; i++) this.$act[g[i]] = 0;
this.$act[ID] = 1;
return true;
};
/** Clear priority.
*/
this._clrPriorityGroup = function () {
if (this.$actClone) this.$act = this.$actClone;
delete this.$actClone;
return;
};
/** Add radio channel or merges. Expects Object with members:
* - name: Channel name <string>. Can be generic, docking, fight, (docked) entity name or a custom channel
* - sounds: Array of Objects with {snd: <filename>, dur: duration seconds <integer>, vol: optional, volume <float>}
* - radio: If set channel name will be listed in this.$radios
*/
this._addChannel = function (obj) {
var c = this._aid.objClone(obj), i, len = obj.sounds.length;
if (!this.$media.radio[c.name]) this.$media.radio[c.name] = [];
for (i = 0; i < len; i++) {
c.sounds[i].act = c.name;
this.$media.radio[c.name].push(c.sounds[i]);
}
if (this.$actClone) {
this.$actClone[c.name] = 1;
this.$act[c.name] = 0;
} else this.$act[c.name] = 1;
if (c.radio && this.$radios.indexOf(c.name) === -1) this.$radios.push(c.name);
return true;
};
/** Sets or clears custom radio channel.
* - str: Channel name <string> or null.
*/
this._setChannel = function (str) {
var d = this.$dub;
switch (typeof str) {
case "string": if (typeof this.$act[str] === "number" && typeof this.$media.radio[str] !== "undefined") d.channel = str; break;
case "object": if (!str) d.channel = null; break;
}
return d.channel;
};
this._buildList = function () {
var c = this.$radios, l = c.length, ind, d = [];
for (var i = 0; i < l; i++) {
ind = Math.pow(2, i);
if (this.$E0 & ind) d = d.concat(this.$media.radio[c[i]]);
}
if (this.$E0 && d.length) {
this._addChannel({ name: "RadioPlaylist", sounds: [] });
this.$media.radio.RadioPlaylist = d;
this._setChannel("RadioPlaylist");
} else this.$dub.channel = null;
};
this._updateInf = function () {
var c = this.$radios, l = c.length, max = Math.pow(2, l) - 1, o = this.$inf.EInt;
o.E0.Max = max & 0xffffff;
o.E0.Desc = [].concat(c);
if (l) {
o.E0.Hide = false;
o.Info = expandMissionText("LIB_MUSIC_PUSH");
}
};
this._updateVol = function () {
var d = this.$dub, mus, vol, cvol = 1, i;
if (d.cur) {
mus = Sound.musicSoundSource();
vol = d.vol;
if (mus.isPlaying) {
for (i = 0; i < d.queue.length; i++) {
if (d.queue[i].snd === d.cur) {
if (d.queue[i].vol) cvol = d.queue[i].vol;
break;
}
}
mus.volume = vol * cvol;
}
}
this.$snd.volume = d.vol;
};
this._selectGeneric = function (d) {
if (d.channel) {
d.queue = this.$media.radio[d.channel];
d.spec = "generic";
} else {
if (d.radio) {
d.queue = this.$media.radio[d.radio];
d.spec = d.radio;
} else {
d.queue = this.$media.radio.generic;
d.spec = "generic";
}
}
d.hand = "radio";
d.now = 0;
};
this._resetTimer = function (t) {
if (this.$mediaTimer) this.$mediaTimer.stop();
this.$mediaTimer = null;
if (typeof t === "number") this.$mediaTimer = new Timer(this, this._doPlay, t, 1);
};
this._doPlay = function (q, d) {
var sel, r, found, vol;
if (!d) d = this.$dub;
d.cnt++;
if (!q) {
q = [];
if (d.lockDock && player.ship.isValid && player.ship.docked) {
d.lockDock = 0;
this.shipDockedWithStation(player.ship.dockedStation);
return;
}
}
if (d.cnt > d.dur) {
if (!d.now && d.hand === "radio") this._selectGeneric(d);
if (!q.length) {
this._selectGeneric(d);
q = d.queue;
if (q.length) found = 1;
} else found = 1;
if (found) {
if (d.now && d.kick) this.$snd.play();
// TODO: selection
r = Math.floor(Math.random() * q.length);
sel = q[r];
vol = d.vol;
if (sel.vol) vol *= sel.vol;
Sound.playMusic(sel.snd, false, vol);
d.dur = sel.dur;
d.cnt = d.dur - 2;
d.cur = sel.snd;
} else {
d.dur = 1;
d.cnt = 0;
}
d.ent = null;
d.now = 0;
d.kick = 0;
//if (found) this._resetTimer(d.dur + this._aid.randXY(13, 22));
if (found) {
var randomAddition = this._aid.randXY(13, 22);
if (d.radio === "fight") randomAddition = 0;
this._resetTimer(d.dur + randomAddition);
} else this._resetTimer();
if (d.hand !== "radio") return d.dur;
else return 10;
} else d.hand = "radio";
return 0;
};
this._performMedia = function (hand, spec, ent) {
var d = this.$dub, i, q = [], len, w, add = this.$media[hand].any, any = 1;
if (hand !== "alert" && guiScreen === "GUI_SCREEN_MISSION") return 0;
//if (!ent && d.radio === "fight" && player.alertHostiles && hand !== "killed") return 0;
if (!ent && d.radio === "fight" && (hand !== "alert" || spec !== "red") && player.alertHostiles && hand !== "killed") return 0;
if (ent && this.$media[hand][ent]) {
w = this.$media[hand][ent];
if (w.length) any = 0;
} else w = this.$media[hand][spec];
if ((!w || !w.length) && any && add) {
if (w) w = w.concat(add);
else w = add;
}
if (w) {
len = w.length;
// TODO: move the hard work to _toggleGroup and _setPriorityGroup
for (i = 0; i < len; i++) {
if (this.$act[w[i].act]) q.push(w[i]);
}
if (q.length) {
d.cnt = 1;
d.dur = 0;
d.hand = hand;
d.spec = spec;
d.queue = q;
if (ent) d.ent = ent;
else d.ent = null;
d.now = 1;
return this._doPlay(q, d);
}
}
d.kick = 0;
return 10;
};
// Handler
this.alertConditionChanged = function (to) {
var c = clock.absoluteSeconds, d = this.$dub;
if (!player.ship.isInSpace) return;
switch (to) {
case 1:
case 2:
if (d.radio === "fight") d.radio = "generic";
break;
case 3:
if (this.$media.radio.fight) d.radio = "fight";
if (c >= d.lockAlert) {
d.kick = 1;
d.lockAlert = c + this._performMedia("alert", "red");
}
if (this.$media.radio.fight)
if (!this.$mediaTimer || !this.$media.alert.red.length) this._resetTimer(0);
/*if (c >= d.lockAlert) {
d.kick = 1;
d.lockAlert = c + this._performMedia("alert", "red");
}
if (this.$media.radio.fight) {
d.radio = "fight";
if (!this.$mediaTimer || !this.$media.alert.red.length) this._resetTimer(0);
}*/
break;
}
};
this.playerRescuedEscapePod = function (fee, reason, occupant) {
var c = clock.absoluteSeconds;
if (!occupant || !occupant.name || c < this.$dub.lockDock) return;
this.$dub.lockDock = clock.absoluteSeconds + this._performMedia("rescued", "ent", occupant.name);
};
this.shipDockedWithStation = function (station) {
var c = clock.absoluteSeconds, d = this.$dub;
this._clrLock();
if (!station) return;
if (this.$media.radio[station.name]) d.radio = station.name;
else d.radio = "generic";
if (c < d.lockDock) return;
this._resetTimer(0); // autopilot!
if (station.isMainStation) this._performMedia("docked", "main");
else this._performMedia("docked", "ent", station.name);
d.lockDock = 0;
};
this.shipEnteredPlanetaryVicinity = function (planet) {
var aa, ab, c = clock.absoluteSeconds, d = this.$dub;
if (!player.ship.isInSpace || !planet || c < d.lockPlanet) return;
if (planet.isMainPlanet) aa = "enterMain";
else if (planet.isSun) aa = "enterSun";
else {
aa = "ent";
ab = planet.name;
}
d.kick = 1;
d.lockPlanet = c + this._performMedia("planetIn", aa, ab);
};
this.shipEnteredStationAegis = function (station) {
var c = clock.absoluteSeconds, d = this.$dub;
if (!player.ship.isInSpace || !station || c < d.lockPlanet) return;
d.kick = 1;
d.lockPlanet = c + this._performMedia("aegis", "enter");
};
this.shipExitedStationAegis = function (station) {
var c = clock.absoluteSeconds, d = this.$dub;
if (!player.ship.isInSpace || !station || c < d.lockPlanet) return;
d.kick = 1;
d.lockPlanet = c + this._performMedia("aegis", "exit");
};
this.shipExitedPlanetaryVicinity = function (planet) {
var aa, ab, c = clock.absoluteSeconds, d = this.$dub;
if (!player.ship.isInSpace || !planet || c < d.lockPlanet) return;
if (planet.isMainPlanet) aa = "exitMain";
else if (planet.isSun) aa = "exitSun";
else {
aa = "ent";
ab = planet.name;
}
d.kick = 1;
d.lockPlanet = c + this._performMedia("planetOut", aa, ab);
};
this.shipExitedWitchspace = function () {
this._clrLock();
var a;
if (!player.ship.isInSpace) return;
if (system.isInterstellarSpace) a = "inter";
else if (system.sun.hasGoneNova) a = "goneNova";
else if (system.sun.isGoingNova) a = "doNova";
else a = "standard";
this.$dub.kick = 1;
this._performMedia("exitWS", a);
};
this.shipKilledOther = function (whom) {
var c = clock.absoluteSeconds, d = this.$dub;
if (!player.ship.isInSpace || c < d.lockKill) return;
d.kick = 1;
if (whom && whom.name) d.lockKill = c + this._performMedia("killed", "ent", whom.name);
else d.lockKill = c + this._performMedia("killed", "any");
};
this.shipScoopedFuel = function () {
var c = clock.absoluteSeconds, d = this.$dub;
if (!player.ship.isInSpace || c < d.lockFuel) return;
d.kick = 1;
d.lockFuel = c + this._performMedia("scoopFuel", "fuel");
};
this.shipScoopedOther = function (whom) {
if (!player.ship.isInSpace || !whom || !whom.name) return;
this.$dub.kick = 1;
this._performMedia("scooped", "ent", whom.name);
};
this.shipTargetDestroyed = function (target) {
var c = clock.absoluteSeconds, d = this.$dub, t;
if (!player.ship.isInSpace || c < d.lockKill) return;
d.kick = 1;
if (target) {
t = target.name;
if (t && this.$media.killed[t]) {
d.lockKill = c + this._performMedia("killed", "ent", t);
return;
}
}
d.lockKill = c + this._performMedia("killed", "any");
};
this.shipWillDockWithStation = function () {
var d = this.$dub;
d.auto = 0;
if (d.cur) Sound.stopMusic(d.cur);
};
this.shipWillLaunchFromStation = function (station) {
var d = this.$dub;
if (!station) return;
d.radio = "generic";
d.lockDock = 0;
d.kick = 1;
this._resetTimer(0);
if (station.isMainStation) this._performMedia("launch", "main");
else this._performMedia("launch", "ent", station.name);
};
// Special cases
this.gamePaused = function () {
if (this.$dub.cur) Sound.stopMusic(this.$dub.cur);
this._clrLock();
};
this.gameResumed = function () {
if (this.$dub.auto && this.$media.radio.docking) {
this.playerStartedAutoPilot();
} else this._resetTimer(0);
};
this.guiScreenChanged = function () {
var d = this.$dub, k, m;
if (guiScreen === "GUI_SCREEN_MISSION") {
m = mission.screenID;
if (m) k = worldScripts.Lib_GUI.$IDRules[m];
if (!m || !k || !k.mus) {
if (d.cur) Sound.stopMusic(d.cur);
this._resetTimer();
d.reinit = 1;
}
}
};
this.missionScreenEnded = function () {
if (this.$dub.reinit) {
this.$dub.reinit = 0;
this._resetTimer(0);
}
};
// Start session
this.missionScreenOpportunity = function () {
delete this.missionScreenOpportunity;
if (guiScreen !== "GUI_SCREEN_MISSION") this.shipDockedWithStation(player.ship.dockedStation);
else this.$dub.reinit = 1;
var c = this.$radios, l = c.length, ind, s;
this._updateInf();
if (missionVariables.LIB_RADIO) {
s = JSON.parse(missionVariables.LIB_RADIO);
for (var i = 0; i < l; i++) {
ind = c.indexOf(s[i]);
if (ind !== -1) this.$E0 += Math.pow(2, ind);
}
this._buildList();
}
worldScripts.Lib_Config._registerSet(this.$inf);
};
this.playerCancelledAutoPilot = function () {
var d = this.$dub;
if (d.auto && d.cur) Sound.stopMusic(d.cur);
d.radio = "generic";
d.auto = 0;
this._resetTimer(0);
};
this.playerStartedAutoPilot = function () {
if (this.$media.radio.docking) {
Sound.stopMusic();
this.$dub.radio = "docking";
this.$dub.auto = 1;
this._resetTimer(0);
} else this._resetTimer();
};
this.shipDied = function () {
this._resetTimer();
if (this.$dub.cur) Sound.stopMusic(this.$dub.cur);
};
this.shipLaunchedEscapePod = function () {
this.shipDied();
};
this._clrLock = function () {
var d = this.$dub;
d.lockAlert = 1;
d.lockFuel = 1;
d.lockKill = 1;
d.lockPlanet = 1;
};
}).call(this);
|
| Scripts/Lib_PAD.js |
/* jshint bitwise:false, forin:false */
/* global clock,expandMissionText,mission,missionVariables,player,worldScripts */
/* (C) Svengali & BlackWolf 2016-2018, License CC-by-nc-sa-4.0 */
(function () {
"use strict";
this.name = "Lib_PAD";
this.$data = {
categories: {
GALCOP: expandMissionText("LIB_PAD_GALCOP"),
GUILDS: expandMissionText("LIB_PAD_GUILDS"),
INFOS: expandMissionText("LIB_PAD_INFOS"),
LOGS: expandMissionText("LIB_PAD_LOGS"),
NEWS_HISTORY: expandMissionText("LIB_PAD_NEWS_HISTORY"),
PERSONS: expandMissionText("LIB_PAD_PERSONS"),
SYSTEMS: expandMissionText("LIB_PAD_SYSTEMS"),
ZZX: expandMissionText("LIB_PAD_SEARCH"),
ZZY: expandMissionText("LIB_PAD_PLAYER"),
ZZZ: expandMissionText("LIB_PAD_EXIT")
},
GALCOP: {
GENERIC: { keyDisplay:"", name: "", entry: "2084004:01:01:01", enlisted: "", kills: 0, missions: [], awards: [], info: [], t0: 11, t1: 0, t2: 0, t3: 0, t4: 0, t5: 0 },
NAVY: { keyDisplay: expandMissionText("LIB_PAD_KEY_NAVY"), name: "", entry: "", enlisted: "", kills: 0, missions: [], awards: [], info: [], t0: 21, t1: 0, t2: 0, t3: 0, t4: 0, t5: 0 }
},
GUILDS: {
GENERIC: { keyDisplay: "", name: "", entry: "2084004:01:01:01", enlisted: expandMissionText("LIB_PAD_TRADE_GUILD"), kills: 0, missions: [], awards: [], info: [], t0: 20, t1: 0, t2: 0, t3: 0, t4: 0, t5: 0 }
},
INFOS: {
GENERIC: { keyDisplay: "", name: expandMissionText("LIB_PAD_LAVEACADEMY"), location: expandMissionText("LIB_PAD_LAVE"), beacon: expandMissionText("LIB_PAD_BEACON_NONE"), purpose: expandMissionText("LIB_PAD_PURPOSE"), special: [expandMissionText("LIB_PAD_EXAM_RESULT")], notes: [], t0: 20, t1: 0, t2: 0, t3: 0, t4: 0, t5: 0 }
},
LOGS: {
GENERIC: { keyDisplay: "", list: [expandMissionText("LIB_PAD_LOGS_INIT")] }
},
NEWS_HISTORY: {
GENERIC: { keyDisplay: "", entry: "2084004:01:01:01", text: expandMissionText("LIB_PAD_NEWS_INIT") }
},
PERSONS: {
GENERIC: { keyDisplay: "", name: "", origin: "", species: "", gender: "", age: 0, ship: "", rank: "", info: [], notes: [], t0: 0, t1: 0, t2: 0, t3: 0, t4: 0, t5: 0 }
},
SYSTEMS: {
GENERIC: { keyDisplay: "", name: expandMissionText("LIB_PAD_LAVE"), info: [expandMissionText("LIB_PAD_LAVE1"), expandMissionText("LIB_PAD_LAVE2"), expandMissionText("LIB_PAD_LAVE3")], notes: [], t0: 0, t1: 0, t2: 0, t3: 0, t4: 0, t5: 0 }
}
};
this.$config = {
curCat: "GALCOP",
def: { XXX: expandMissionText("LIB_PAD_PAGEUP"), YYY: expandMissionText("LIB_PAD_PAGEDOWN"), ZZZ: expandMissionText("LIB_PAD_BACK") },
defSpecies: [expandMissionText("LIB_PAD_SPECIES_BIRD"), expandMissionText("LIB_PAD_SPECIES_FELINE"), expandMissionText("LIB_PAD_SPECIES_FROG"), expandMissionText("LIB_PAD_SPECIES_HUMAN"), expandMissionText("LIB_PAD_SPECIES_HUMANOID"), expandMissionText("LIB_PAD_SPECIES_INSECT"), expandMissionText("LIB_PAD_SPECIES_LIZARD"), expandMissionText("LIB_PAD_SPECIES_LOBSTER"), expandMissionText("LIB_PAD_SPECIES_RODENT")],
defGender: [expandMissionText("LIB_PAD_GENDER_MALE"), expandMissionText("LIB_PAD_GENDER_FEMALE"), expandMissionText("LIB_PAD_GENDER_NEUTRAL"), expandMissionText("LIB_PAD_GENDER_ANDROID")],
defImages: [
{ t1: "lib_user.png", s: 3, g: 0, a: [26, 27] },
{ t1: "lib_avatar01.png", s: 3, g: 1, a: [23, 36] }, { t1: "lib_avatar02.png", s: 3, g: 1, a: [23, 32] }, { t1: "lib_avatar03.png", s: 3, g: 1, a: [23, 32] },
{ t1: "lib_avatar04.png", s: 3, g: 0, a: [26, 37] }, { t1: "lib_avatar05.png", s: 3, g: 0, a: [24, 33] }, { t1: "lib_avatar06.png", s: 3, g: 0, a: [44, 63] },
{ t1: "lib_avatar07.png", s: 8, g: 1, a: [23, 43] }, { t1: "lib_avatar08.png", s: 8, g: 0, a: [30, 43] }, { t1: "lib_avatar09.png", s: 0, g: 0, a: [28, 43] },
{ t1: "lib_avatar10.png", s: 0, g: 1, a: [28, 43] }, { t1: "lib_avatar11.png", s: 1, g: 1, a: [28, 43] }, { t1: "lib_avatar12.png", s: 1, g: 0, a: [34, 48] },
{ t1: "lib_avatar13.png", s: 1, g: 1, a: [24, 41] }, { t1: "lib_avatar14.png", s: 1, g: 0, a: [24, 41] }, { t1: "lib_avatar15.png", s: 2, g: 2, a: [24, 41] },
{ t1: "lib_avatar16.png", s: 2, g: 2, a: [24, 41] }, { t1: "lib_avatar17.png", s: 5, g: 2, a: [24, 51] }, { t1: "lib_avatar18.png", s: 5, g: 2, a: [24, 51] },
{ t1: "lib_avatar19.png", s: 6, g: 0, a: [24, 151] }, { t1: "lib_avatar20.png", s: 6, g: 1, a: [24, 111] }, { t1: "lib_avatar21.png", s: 8, g: 1, a: [21, 31] },
{ t1: "lib_avatar22.png", s: 8, g: 0, a: [24, 35] }
],
defTemps: {
GALCOP: {
disp: { name: "", entry: "", enlisted: "", kills: 0, missions: [], awards: [], info: [] },
silent: { keyDisplay:expandMissionText("LIB_PAD_GALCOP"), missions: 5, awards: 5, info: 5, t0: 1, t1: 1, t2: 1, t3: 1, t4: 1, t5: 1, model: "lib_ms_helper6y" }
},
GUILDS: {
disp: { name: "", entry: "", enlisted: "", kills: 0, missions: [], awards: [], info: [] },
silent: { keyDisplay:expandMissionText("LIB_PAD_GUILDS"), missions: 5, awards: 5, info: 5, t0: 1, t1: 1, t2: 1, t3: 1, t4: 1, t5: 1, model: "lib_ms_helper6y" }
},
INFOS: {
disp: { name: "", location: "", beacon: "", purpose: "", special: [], notes: [], $crypt: "" },
silent: { keyDisplay:expandMissionText("LIB_PAD_INFOS"), special: 10, $crypt: 1, notes: 5, t0: 1, t1: 1, t2: 1, t3: 1, t4: 1, t5: 1, model: "lib_ms_helper6y" }
},
LOGS: {
disp: { list: [] }, silent: { keyDisplay: expandMissionText("LIB_PAD_LOGS"), list: 20, model: null }
},
NEWS_HISTORY: {
disp: { entry: "", text: "" },
silent: { keyDisplay: expandMissionText("LIB_PAD_NEWS_HISTORY"), entry:1, text: 1, model: null }
},
PERSONS: {
disp: { name: "", origin: "", species: expandMissionText("LIB_PAD_SPECIES_HUMAN"), gender: expandMissionText("LIB_PAD_GENDER_MALE"), age: 0, rank: "", ship: "", info: [], notes: [] },
silent: { keyDisplay: expandMissionText("LIB_PAD_PERSONS"), info: 7, notes: 5, t0: 1, t1: 1, t2: 1, t3: 1, t4: 1, t5: 1, model: "lib_ms_helper6y" }
},
SYSTEMS: {
disp: { name: "", info: [], notes: [], $hide: "" },
silent: { keyDisplay:expandMissionText("LIB_PAD_SYSTEMS"), info: 10, notes: 5, $hide: 1, t0: 1, t1: 1, t2: 1, t3: 1, t4: 1, t5: 1, model: "lib_ms_helper6y" }
}
},
defOrgs: [null,
"lib_pad_org1.png", "lib_pad_org2.png", "lib_pad_org3.png", "lib_pad_org4.png", "lib_pad_org5.png", "lib_pad_org6.png",
"lib_pad_org7.png", "lib_pad_org8.png", "lib_pad_org9.png", "lib_pad_org10.png", "lib_pad_org11.png", "lib_pad_org12.png",
"lib_pad_org13.png", "lib_pad_org14.png", "lib_pad_org15.png", "lib_pad_org16.png", "lib_pad_org17.png", "lib_pad_org18.png",
"lib_pad_org19.png", "lib_pad_org20.png", "lib_pad_org21.png", "lib_pad_org22.png", "lib_pad_org23.png", "lib_pad_org24.png",
"lib_pad_org25.png", "lib_pad_org26.png", "lib_pad_org27.png", "lib_pad_org28.png", "lib_pad_org29.png", "lib_pad_org30.png",
"lib_pad_org31.png"
],
defRanks: [null,
"lib_pad_rank1.png", "lib_pad_rank2.png", "lib_pad_rank3.png", "lib_pad_rank4.png", "lib_pad_rank5.png", "lib_pad_rank6.png",
"lib_pad_rank7.png", "lib_pad_rank8.png", "lib_pad_rank9.png"
],
defAwards: [null,
"lib_pad_medal1.png", "lib_pad_medal2.png", "lib_pad_medal3.png", "lib_pad_medal4.png", "lib_pad_medal5.png", "lib_pad_medal6.png",
"lib_pad_medal7.png", "lib_pad_medal8.png", "lib_pad_medal9.png", "lib_pad_medal10.png", "lib_pad_medal11.png", "lib_pad_medal12.png",
"lib_pad_medal13.png", "lib_pad_medal14.png", "lib_pad_medal15.png", "lib_pad_medal16.png", "lib_pad_medal17.png"
],
defFFF: [null, "lib_pad_rank1.png"],
defGGG: [null, "lib_pad_rank1.png"],
defTex: ["t0", "t1", "t2", "t3", "t4", "t5"],
defTexLookUp: ["defOrgs", "defImages", "defRanks", "defAwards", "defFFF", "defGGG"],
defHead: {
exitScreen: "GUI_SCREEN_INTERFACES",
message: "",
background: { name: "lib_pad_text_bg.png", height: 512 },
screenID: this.name,
spinModel: false
},
hide: ["$crypt", "$hide"],
HUD: 0,
last: {
news: "",
add: "",
upd: ""
},
lastSearch: "",
noteAdd: "",
page: "INIT",
pageInd: 0,
setInd: 0,
setGal: 0,
relInd: 0,
ps: {
age: 26,
gender: expandMissionText("LIB_PAD_GENDER_MALE"),
species: expandMissionText("LIB_PAD_SPECIES_HUMAN"),
origin: expandMissionText("LIB_PAD_SYSTEM_LAVE"),
image: "lib_user.png"
},
psUpd: 1
};
this.startUp = function () {
var d = this.$data,
load;
this._aid = worldScripts.Lib_Main._lib;
worldScripts.Lib_GUI.$IDRules.Lib_PAD = { mus: 1 };
if (missionVariables.LIB_PAD_DATA) {
load = JSON.parse(missionVariables.LIB_PAD_DATA);
d.GALCOP.GENERIC = load.GALCOP;
d.GALCOP.NAVY = load.NAVY;
d.GUILDS.GENERIC = load.GUILDS;
d.INFOS.GENERIC = load.INFOS;
d.LOGS.GENERIC = load.LOGS;
d.PERSONS.GENERIC = load.PERSONS;
d.SYSTEMS.GENERIC = load.SYSTEMS;
if (load.hasOwnProperty("NEWS_HISTORY")) {
d.NEWS_HISTORY = load.NEWS_HISTORY;
}
this._fixData();
this.$config.ps = JSON.parse(missionVariables.LIB_PAD_PS);
this.$config.last = JSON.parse(missionVariables.LIB_PAD_LAST);
}
this._updatePlayer(1);
this.$Search = {
"GALCOP.GENERIC": [0, [], []],
"GALCOP.NAVY": [0, [], []],
"GUILDS.GENERIC": [0, [], []],
"INFOS.GENERIC": [0, [], []],
"LOGS.GENERIC": [0, [], []],
"PERSONS.GENERIC": [0, [], []],
"SYSTEMS.GENERIC": [0, [], []],
"NEWS_HISTORY.GENERIC": [0, [], []]
};
this._fillSearch();
};
this._fixData = function() {
var d = this.$data;
if (!d.GALCOP.GENERIC.hasOwnProperty("keyDisplay")) d.GALCOP.GENERIC.keyDisplay = "";
if (!d.GALCOP.NAVY.hasOwnProperty("keyDisplay")) d.GALCOP.NAVY.keyDisplay = expandMissionText("LIB_PAD_KEY_NAVY");
if (!d.GUILDS.GENERIC.hasOwnProperty("keyDisplay")) d.GUILDS.GENERIC.keyDisplay = "";
if (!d.INFOS.GENERIC.hasOwnProperty("keyDisplay")) d.INFOS.GENERIC.keyDisplay = "";
if (!d.PERSONS.GENERIC.hasOwnProperty("keyDisplay")) d.PERSONS.GENERIC.keyDisplay = "";
if (!d.SYSTEMS.GENERIC.hasOwnProperty("keyDisplay")) d.SYSTEMS.GENERIC.keyDisplay = "";
}
this._fillSearch = function () {
var d = this.$data;
this.$Search["GALCOP.GENERIC"][0] = this._getEntries(d.GALCOP.GENERIC);
this.$Search["GALCOP.NAVY"][0] = this._getEntries(d.GALCOP.NAVY);
this.$Search["GUILDS.GENERIC"][0] = this._getEntries(d.GUILDS.GENERIC);
this.$Search["INFOS.GENERIC"][0] = this._getEntries(d.INFOS.GENERIC);
this.$Search["LOGS.GENERIC"][0] = this._getEntries(d.LOGS.GENERIC);
this.$Search["PERSONS.GENERIC"][0] = this._getEntries(d.PERSONS.GENERIC);
this.$Search["SYSTEMS.GENERIC"][0] = this._getEntries(d.SYSTEMS.GENERIC);
this.$Search["NEWS_HISTORY.GENERIC"][0] = this._getEntries(d.NEWS_HISTORY.GENERIC);
};
this.startUpComplete = function () {
this._addInterface();
// remove register ship interface
system.mainStation.setInterface("oolite-registership", null);
};
// store only GENERIC, NAVY, last and player data
this.playerWillSaveGame = function () {
var d = this.$data,
store = {
GALCOP: d.GALCOP.GENERIC,
NAVY: d.GALCOP.NAVY,
GUILDS: d.GUILDS.GENERIC,
INFOS: d.INFOS.GENERIC,
LOGS: d.LOGS.GENERIC,
PERSONS: d.PERSONS.GENERIC,
SYSTEMS: d.SYSTEMS.GENERIC,
NEWS_HISTORY: d.NEWS_HISTORY
};
missionVariables.LIB_PAD_DATA = JSON.stringify(store);
missionVariables.LIB_PAD_PS = JSON.stringify(this.$config.ps);
missionVariables.LIB_PAD_LAST = JSON.stringify(this.$config.last);
};
this.shipDockedWithStation = function () {
if (!player.ship.docked) return;
this._addInterface();
// remove register ship interface
system.mainStation.setInterface("oolite-registership", null);
};
this._limit = function (who, how) {
for (var k in who) if (typeof (who[k]) === "object" && who[k].length) who[k] = who[k].splice(-how[k]);
return who;
};
this._getEntries = function (obj) {
if (obj == null) return "";
var ownProps = Object.keys(obj), i = ownProps.length, o, res = "", ex = ["t0", "t1", "t2", "t3", "t4", "t5"];
while (i--) {
if (ex.indexOf(ownProps[i]) !== -1) continue;
o = obj[ownProps[i]];
if (typeof (o) === "object") res += this._getEntries(o);
else res += "|" + o;
}
return res;
};
/** function _addPageInCategory
* path String. Dotted path, e.g. "GALCOP.NAVY".
* content Object.
* parent Array. Member of other pages.
* sil Bool. Silent mode. Does not add to latest additions.
* $return true on success, otherwise false.
*/
this._addPageInCategory = function (path, content, parent, sil) {
var con = this.$config,
d = this.$data,
q = this._aid.objGet(d, path),
s = path.split("."),
obj = this._aid.objClone(content),
temp = this._aid.objClone(con.defTemps[s[0]].disp),
i;
if (q || !temp) return false;
for (i = 0; i < 6; i++) temp[con.defTex[i]] = 0;
if (!content.hasOwnProperty("keyDisplay")) {
temp.keyDisplay = s[s.length - 1];
} else {
temp.keyDisplay = content.keyDisplay;
}
temp = this._aid.objMerge(temp, obj, 1);
temp = this._limit(temp, con.defTemps[s[0]].silent);
this._aid.objSet(d, path, temp);
if (!sil) con.last.add = this._buildKey(s); //s.join(":");
con.psUpd = 1;
this.$Search[path] = [this._getEntries(temp), [], []];
if (parent) {
this.$Search[path][1] = parent;
for (i = 0; i < parent.length; i++) {
this.$Search[parent[i]][2].push(path);
}
}
return true;
};
this._buildKey = function(s) {
var txt = "";
var d = this.$data;
var temp = this.$config.defTemps;
for (var i = 0; i < s.length; i++) {
txt += (txt == "" ? "" : ":")
switch (i) {
case 0:
if (temp[s[0]].silent.keyDisplay)
txt += temp[s[0]].silent.keyDisplay;
else
txt += s[i];
break;
case 1:
if (d[s[0]][s[1]].keyDisplay)
txt += d[s[0]][s[1]].keyDisplay;
else
txt += s[i];
break;
}
if (i == 1) break;
}
return txt;
}
/** _setPageEntry
* path String. Dotted path, e.g. "LOGS.GENERIC.list".
* value Primitive. Value.
* sil Bool. Silent mode. Does not add to latest additions.
* $return true on success, otherwise false.
*/
this._setPageEntry = function (path, value, sil) {
var d = this.$data,
q = this._aid.objGet(d, path),
s = path.split("."),
o = {},
n = clock.clockString.substr(0, 13),
p;
if (typeof (q) === "undefined") return false;
switch (this._aid.typeGet(q)) {
case "array":
if (s[2] === "list") q.push(n + " " + value);
else if (q.indexOf(value) < 0) q.push(value);
o[s[2]] = q;
q = this._limit(o, this.$config.defTemps[s[0]].silent)[s[2]];
break;
case "number":
if (value === "++") q++;
else q = value;
break;
default: q = value;
}
this._aid.objSet(d, path, q);
p = this._aid.objGet(d, s[0] + "." + s[1]);
if (!sil) this.$config.last.upd = this._buildKey(s) + " - " + n + " " + value; // + s[0] + ":" + s[1]
this.$Search[s[0] + "." + s[1]][0] = this._getEntries(p);
return true;
};
/** _getData
* path String. Dotted path, e.g. "GALCOP.NAVY".
* $return Object or null.
*/
this._getData = function (path) {
var q = this._aid.objGet(this.$data, path);
if (q) return this._aid.objClone(q);
return null;
};
this._addInterface = function () {
player.ship.dockedStation.setInterface(this.name, {
title: expandMissionText("LIB_PAD_TITLE"),
category: expandMissionText("LIB_PAD_LOG_CATEGORY"),
summary: expandMissionText("LIB_PAD_LOG_SUMMARY"),
callback: this._showStart.bind(this)
});
};
this._updatePlayer = function (ex) {
var a, b, c, i, ps = this.$config.ps;
a = this.$data.PERSONS.GENERIC;
a.name = player.name;
a.ship = player.ship.displayName;
a.species = ps.species;
a.origin = ps.origin;
a.gender = ps.gender;
a.age = ps.age;
a.rank = player.rank;
a.t1 = ps.image;
b = this.$data.GALCOP;
c = Object.keys(b);
for (i = 0; i < c.length; i++) {
b[c[i]].name = player.name;
b[c[i]].t1 = ps.image;
}
b.GENERIC.kills = player.score;
b = this.$data.GUILDS;
c = Object.keys(b);
for (i = 0; i < c.length; i++) {
b[c[i]].name = player.name;
b[c[i]].t1 = ps.image;
}
b.GENERIC.kills = player.score;
this.$config.psUpd = 0;
if (!ex) this._fillSearch();
};
this._showStart = function (ini) {
var c = this.$config;
if (ini === "Lib_PAD") {
c.psUpd = 1;
if (!player.ship.hudHidden) c.HUD = 1;
}
//player.ship.hudHidden = true;
if (c.psUpd) this._updatePlayer();
c.curCat = "INIT";
var head = this._aid.objClone(c.defHead);
head.choices = this.$data.categories;
if (!worldScripts.GNN || worldScripts.GNN.$snoop.newsHistory == 0) {
delete head.choices["NEWS_HISTORY"];
}
head.message = expandMissionText("LIB_PAD_INFO_LAST", { news: c.last.news, update: c.last.upd, add: c.last.add });
head.background = { name: "lib_pad_bg.png", height: 512 };
head.title = expandMissionText("LIB_PAD_LOG_SUMMARY");
mission.runScreen(head, this._choices.bind(this));
};
this._showCategory = function (ick, note) {
//player.ship.hudHidden = true;
var con = this.$config,
cat = con.curCat,
d = this.$data[cat],
ind = con.pageInd,
max = Object.keys(d),
p = d[con.page],
temps = Object.keys(con.defTemps),
i, md, m, min, template,
tt = con.defTex,
head = this._aid.objClone(con.defHead),
pm = this.$Search[cat + "." + con.page];
con.relInd = 0;
head.choices = this._aid.objClone(con.def);
head.initialChoicesKey = ick;
head.model = con.defTemps[cat].silent.model;
var keyDisp = d[max[ind]].keyDisplay;
head.title = expandMissionText("LIB_PAD_" + cat).toUpperCase() + (ind !== 0 ? "-" + (keyDisp != "" ? keyDisp : max[ind]) : "") + " (" + (ind + 1) + "/" + max.length + ")";
if (max.length < 2) {
head.choices = this._aid.scrChcUnsel(head.choices, 'XXX');
head.choices = this._aid.scrChcUnsel(head.choices, 'YYY');
}
if (p.list) {
if (!p.list.length) head.message = expandMissionText("LIB_PAD_NO_ENTRIES");
else {
min = p.list.length - 1;
max = Math.max(0, min - 20);
for (i = min; i >= max; i--) head.message += this._aid.scrAddLine([[p.list[i], 30]], "", "\n");
}
} else {
if (temps.indexOf(cat) > -1) {
template = con.defTemps[cat];
m = this._fillTemplate(p, template);
head.message = m[0];
} else {
head.message = expandMissionText("LIB_PAD_NO_ENTRIES");
}
if (m[1].silent.notes) {
if (con.page === "GENERIC") head.choices.ZZW = expandMissionText("LIB_PAD_ADD_NOTE");
else head.choices.ZZW = { text: expandMissionText("LIB_PAD_ADD_NOTE"), unselectable: true };
}
if (m[1].$crypt) head.choices.ZZV = expandMissionText("LIB_PAD_DECRYPT");
}
if (pm && (pm[1].length || pm[2].length)) head.choices.ZZU = expandMissionText("LIB_PAD_RELATED");
if (note) head.message += note;
mission.runScreen(head, this._choices.bind(this));
md = mission.displayModel;
if (md) {
md.orientation = [1, 0, 1, 0]; // invisible
md.position = [50, 8, 150];
for (i = 0; i < tt.length; i++) {
if (m[1][tt[i]]) {
md.subEntities[i].setMaterials({ "lib_null.png": { emission_map: m[1][tt[i]] } });
md.subEntities[i].orientation = [-1, 0, 1, 0];
}
}
md.subEntities[0].position = [100, 60, 160]; // organisation
md.subEntities[2].position = [25, 14, -10]; // rank/enlisted
md.subEntities[3].position = [25, -7, -10]; // medal
md.subEntities[4].position = [25, -28, -10]; // tex
md.subEntities[5].position = [140, 75, -80]; // tex
}
};
this._fillTemplate = function (obj, temp, ps) {
var con = this.$config,
a = this._aid.objClone(obj),
b = this._aid.objClone(temp),
ca = Object.keys(b.disp),
m = "", i, j, min, max, fill, spec,
tt = con.defTex,
tts = con.defTexLookUp;
for (i = 0; i < ca.length; i++) {
if (con.hide.indexOf(ca[i]) !== -1) continue;
if (a[ca[i]]) {
if (this._aid.typeGet(a[ca[i]]) === "array") {
if (ps) continue; // opt out for gallery
fill = b.silent[ca[i]] - 1;
if (a[ca[i]].length) {
min = a[ca[i]].length - 1;
max = Math.max(0, a[ca[i]].length - b.silent[ca[i]]);
for (j = min; j >= max; j--) {
if (j === min) m += this._aid.scrAddLine([[expandMissionText("LIB_PAD_SUB_" + ca[i].toUpperCase()) + ": ", 7], [a[ca[i]][j], 23]], "", "\n");
else m += this._aid.scrAddLine([[" ", 7], [a[ca[i]][j], 23]], " ", "\n");
}
if (fill > min) { // Fill up
fill -= min;
while (fill--) m += "\n";
}
} else { // Fill up
for (j = fill; j >= 0; j--) {
if (j === fill) m += this._aid.scrAddLine([[expandMissionText("LIB_PAD_SUB_" + ca[i].toUpperCase()) + ": ", 7], ["-", 23]], "", "\n");
else m += "\n";
}
}
} else if (ca[i] == "text") m += "\n" + a[ca[i]]; // special case for multiline-text items
else m += this._aid.scrAddLine([[expandMissionText("LIB_PAD_SUB_" + ca[i].toUpperCase()) + ": ", 7], [a[ca[i]], 23]], "", "\n");
} else m += this._aid.scrAddLine([[expandMissionText("LIB_PAD_SUB_" + ca[i].toUpperCase()) + ": ", 7], ["-", 23]], "", "\n");
}
for (i = 0; i < tt.length; i++) {
spec = a[tt[i]];
if (spec && b.silent[tt[i]]) {
if (typeof (spec) === "number") {
if (spec > 0 && spec < con[tts[i]].length) b[tt[i]] = con[tts[i]][spec];
} else b[tt[i]] = spec;
}
}
if (a.$crypt && b.silent.$crypt) b.$crypt = a.$crypt;
return [m, b];
};
this._showPlayer = function () {
//player.ship.hudHidden = true;
this._updatePlayer();
var arr = ["LIB_PAD_COMMANDER_NAME", "LIB_PAD_AVATAR", "LIB_PAD_SPECIES", "LIB_PAD_ORIGIN", "LIB_PAD_GENDER", "LIB_PAD_AGE", "LIB_PAD_SHIP_NAME"],
c = this.$config, m, md, mdt, min, i,
head = this._aid.objClone(c.defHead);
head.textEntry = true;
head.model = "lib_ms_helper";
head.title = expandMissionText("LIB_PAD_LOG_SUMMARY");
if (c.setInd === 1) head.model = "lib_ms_helper12x"; // Gallery
m = this._fillTemplate(this.$data.PERSONS.GENERIC, c.defTemps.PERSONS, 1);
head.message = m[0];
head.message += "\n" + expandMissionText(arr[c.setInd]);
mission.runScreen(head, this._pSettings.bind(this));
md = mission.displayModel;
if (md && m && m[1].t1) {
md.setMaterials({ "lib_null.png": { emission_map: m[1].t1 } });
md.orientation = [1, 0, 0, 0];
if (this.$config.setInd === 1) {
mdt = c.defImages;
min = Math.min(mdt.length, c.setGal + 12);
for (i = c.setGal; i < min; i++) md.subEntities[i - c.setGal].setMaterials({ "lib_null.png": { diffuse_map: "lib_pad" + (i - c.setGal + 1) + ".png", emission_map: mdt[i].t1 } });
md.position = [0, -12, 150];
} else md.position = [50, 40, 150];
}
};
this._pSettings = function (choice) {
var c = this.$config, cint = parseInt(choice), mdt, v;
if (choice) {
switch (c.setInd) {
case 0: player.name = choice; break;
case 1:
if (/\.png/.test(choice)) { // No way to test if image exists. Undocumented.
c.ps.image = choice;
} else {
if (!isNaN(cint)) {
mdt = c.defImages;
if (cint === 0) { // Next gallery
c.setInd--;
c.setGal += 12;
if (c.setGal > mdt.length - 1) c.setGal = 0;
} else {
if (cint <= mdt.length && cint > 0) {
v = mdt[c.setGal + cint - 1];
if (!v) v = { t1: "lib_user.png", s: 3, g: 0, a: [26, 27] };
c.ps.image = v.t1;
c.ps.species = c.defSpecies[v.s];
c.ps.gender = c.defGender[v.g];
c.ps.age = this._aid.randXY(v.a[0], v.a[1]);
} else c.setInd--;
}
} else c.setInd--;
}
break;
case 2: c.ps.species = choice; break;
case 3: c.ps.origin = choice; break;
case 4: c.ps.gender = choice; break;
case 5: if (!isNaN(cint) && cint > 0 && cint < 300) c.ps.age = cint; break;
case 6: player.ship.shipUniqueName = choice; break;
}
}
c.setInd++;
if (c.setInd < 7) this._showPlayer();
else {
c.curCat = "INIT";
c.page = "INIT";
c.pageInd = 0;
c.psUpd = 1;
this._showStart(1);
}
};
this._choices = function (choice) {
var con = this.$config,
c = Object.keys(this.$data.categories),
cat = con.curCat,
d = this.$data[cat],
ind = con.pageInd,
max, p1, p2, act, p3, p4;
if (!cat || cat === "INIT") {
switch (choice) {
case "ZZZ": // Bye
if (con.HUD) player.ship.hudHidden = false;
con.HUD = 0;
con.curCat = "";
con.page = "INIT";
con.pageInd = 0;
break;
case "ZZY": // Player settings
con.setInd = 0;
this._showPlayer();
break;
case "ZZX": // Search
this._showSearch();
break;
default:
ind = c.indexOf(choice);
if (ind > -1) {
con.curCat = choice;
con.page = "GENERIC";
con.pageInd = 0;
this._showCategory(choice);
}
}
} else {
max = Object.keys(d);
switch (choice) {
case "XXX": // Page up
ind++;
if (ind >= max.length) ind = 0;
con.page = max[ind];
con.pageInd = ind;
this._showCategory(choice);
break;
case "YYY": // Page down
ind--;
if (ind < 0) ind = max.length - 1;
con.page = max[ind];
con.pageInd = ind;
this._showCategory(choice);
break;
case "ZZU": // Parent/Members
this._showRelated();
break;
case "ZZV": // De-Crypt
p1 = d[con.page].$crypt.split(".");
p2 = p1.shift();
act = this._aid.objGet(worldScripts[p2], p1.join("."), 1);
if (act) {
p3 = d[con.page].special.join("|");
p4 = worldScripts.Lib_Crypt._rot513(p3);
d[con.page].special = p4.split("|");
d[con.page].$crypt = 0;
this.$Search[con.curCat + "." + con.page][0] = this._getEntries(d[con.page]);
this._showCategory(choice);
} else this._showCategory(choice, expandMissionText("LIB_PAD_NO_DECRYPT"));
break;
case "ZZW": // Add note
this._showAddNote(cat + "." + con.page);
break;
case "ZZZ": // Back
con.curCat = "INIT";
con.page = "INIT";
con.pageInd = 0;
this._showStart(1);
break;
}
}
};
this._showAddNote = function (path) {
var m = this._aid.objGet(this.$data, path + ".notes"),
f = m.slice(0).reverse(),
head = this._aid.objClone(this.$config.defHead);
head.textEntry = true;
head.title = expandMissionText("LIB_PAD_ADD_NOTE_PATH", { path: path });
this.$config.noteAdd = path;
for (var i = 0; i < 10; i++) {
if (i < f.length) head.message += this._aid.scrAddLine([[f[i], 23]], "", "\n");
else head.message += "\n";
}
mission.runScreen(head, this._noteAdded.bind(this));
};
this._noteAdded = function (choice) {
if (choice && choice !== "") {
this._setPageEntry(this.$config.noteAdd + ".notes", choice);
this._showCategory("ZZW", expandMissionText("LIB_PAD_NOTE_ADDED"));
} else this._showCategory("ZZW");
this.$config.noteAdd = "";
};
this._showSearch = function () {
var c = this.$config,
head = this._aid.objClone(c.defHead);
if (c.psUpd) this._updatePlayer();
head.textEntry = true;
head.message = null;
head.messageKey = "LIB_PAD_SEARCH";
head.title = expandMissionText("LIB_PAD_LOG_SUMMARY");
mission.runScreen(head, this._pSearch.bind(this));
};
this._pSearch = function (choice) {
var res = null, i, max,
head = this._aid.objClone(this.$config.defHead);
head.choices = { ZZZ: expandMissionText("LIB_PAD_BACK") };
head.title = expandMissionText("LIB_PAD_SEARCH_RESULT", { result: (choice ? expandMissionText("LIB_PAD_SEARCH_CHOICE", { choice: choice }) : "") });
if (choice) {
res = this._searchSData(choice);
this.$config.lastSearch = choice;
}
if (res && res.length) {
max = Math.min(res.length, 20);
for (i = 0; i < max; i++) head.choices[res[i]] = res[i].split(".").join(" : ");
for (i = 0; i < 26 - max; i++) head.choices["ZZY" + i] = { text: "", unselectable: true };
} else head.message = expandMissionText("LIB_PAD_SEARCH_NOTHING");
mission.runScreen(head, this._pSearchRes.bind(this));
};
this._pSearchRes = function (path) {
var con = this.$config,
d = this.$data,
k, ind;
switch (path) {
case "ZZZ": this._showStart(1); break;
default:
path = path.split(".");
con.curCat = path[0];
con.page = path[1];
k = Object.keys(d[path[0]]);
ind = k.indexOf(path[1]);
con.pageInd = ind;
this._showCategory(path[1]);
}
};
this._cullNewsHistory = function (keep) {
if (keep == -1) return;
var keys = Object.keys(this.$data.NEWS_HISTORY);
var num = keys.length;
var pointer = 1;
// have to keep "GENERIC", so the number we keep is always +1 (ie. GENERIC item + however many we've been told to keep)
while (num > (keep + 1)) {
var key = keys[pointer];
delete this.$data.NEWS_HISTORY[key];
delete this.$Search["NEWS_HISTORY." + key];
num -= 1;
pointer += 1;
}
}
// Returns array with paths
this._searchSData = function (word) {
var w = new RegExp(word),
s = this.$Search,
k = Object.keys(s),
kl = k.length,
d,
res = [];
for (var i = 0; i < kl; i++) {
d = s[k[i]][0];
if (w.test(d)) res.push(k[i]);
if (res.length > 20) break;
}
return res;
};
this._showRelated = function () {
var con = this.$config,
head = this._aid.objClone(con.defHead),
pm = this.$Search[con.curCat + "." + con.page],
d = this.$data,
pma = pm[1],
pmb = pm[2],
i;
head.choices = this._aid.objClone(con.def);
var cat1 = con.defTemps[con.curCat].silent.keyDisplay;
if (cat1 == "") cat1 = con.curCat;
var page1 = d[con.curCat][con.page].keyDisplay;
if (page1 == "") page1 = con.page;
head.title = expandMissionText("LIB_PAD_RELATED_TO", { cat: cat1, page: page1 });
head.overlay = { name: "lib_pad_text_ovcatmem.png", height: 512 };
for (i = 5 * con.relInd; i < 5 + (5 * con.relInd); i++) {
if (pma.length > i) {
var keys = pma[i].split(".");
var key1 = con.defTemps[keys[0]].silent.keyDisplay;
if (key1 == "") key1 = keys[0];
var key2 = d[keys[0]][keys[1]].keyDisplay;
if (key2 == "") key2 = keys[1];
head.choices["A" + pma[i]] = key1 + "." + key2;
}
else head.choices["BZZZ" + i] = { text: "", unselectable: true };
}
head.choices.CZZZ = { text: "", unselectable: true };
for (i = 15 * con.relInd; i < 15 + (15 * con.relInd); i++) {
if (pmb.length > i) head.choices["D" + pmb[i]] = pmb[i];
else head.choices["EZZZ" + i] = { text: "", unselectable: true };
}
head.choices.FZZZ = { text: "", unselectable: true };
head.choices.GZZZ = { text: "", unselectable: true };
head.choices.HZZZ = { text: "", unselectable: true };
if (pma.length < 6 && pmb.length < 16) {
head.choices = this._aid.scrChcUnsel(head.choices, 'XXX');
head.choices = this._aid.scrChcUnsel(head.choices, 'YYY');
}
mission.runScreen(head, this._related.bind(this));
};
this._related = function (path) {
var con = this.$config,
pm = this.$Search[con.curCat + "." + con.page],
pma = pm[1],
pmb = pm[2],
d = this.$data,
k, ind;
switch (path) {
case "XXX":
con.relInd++;
if (pma.length <= con.relInd * 5 && pmb.length <= con.relInd * 15) con.relInd = 0;
this._showRelated();
break;
case "YYY":
con.relInd--;
if (con.relInd < 0) con.relInd = Math.max(Math.ceil(pmb.length / 15) - 1, Math.ceil(pma.length / 5) - 1);
this._showRelated();
break;
case "ZZZ": this._showCategory(); break;
default:
path = path.substr(1);
path = path.split(".");
con.curCat = path[0];
con.page = path[1];
k = Object.keys(d[path[0]]);
ind = k.indexOf(path[1]);
con.pageInd = ind;
this._showCategory(path[1]);
}
};
this._Help = function (what) {
var h;
switch (what) {
case "_addPageInCategory": h = "LIB_PAD_HELP_addPageInCategory"; break;
case "_setPageEntry": h = "LIB_PAD_HELP_setPageEntry"; break;
case "_getData": h = "LIB_PAD_HELP_getData"; break;
default: h = "LIB_PAD_HELP";
}
return expandMissionText(h);
};
}).call(this);
|
| Scripts/Lib_PAD_Events.js |
/* jshint bitwise:false, forin:false */
/* global clock,galaxyNumber,guiScreen,mission,missionVariables,player,system,worldScripts */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function () {
"use strict";
this.name = "Lib_PAD_Events";
this.$config = {
bounty: 0,
credits: 0,
fined: 0,
rank: expandMissionText("LIB_PAD_RANK_HARMLESS"),
status: expandMissionText("LIB_PAD_STATUS_CLEAN"),
updCR: 0,
updNavy: 1,
updNova: 1,
updTP: 0
};
this.$delay = [];
this.$init = 1;
this.startUp = function () {
this.$init = 0;
};
this.startUpComplete = function () {
var m = ["PRELUDE", "MISSION_COMPLETE", "STAGE_1", "RUNNING"], mc = -1, mt = -1;
if (missionVariables.Lib_PAD_EVENTS) this.$config = JSON.parse(missionVariables.Lib_PAD_EVENTS);
if (missionVariables.conhunt) mc = m.indexOf(missionVariables.conhunt);
if (missionVariables.thargplans) mt = m.indexOf(missionVariables.thargplans);
if (this.$config.updNavy && worldScripts.Lib_PAD.$data.GALCOP.NAVY.entry === "") this._add("GALCOP.NAVY.entry", clock.clockString, 1);
this.$config.updNavy = 0;
if (mc > -1) this._addCurruthers(1);
if (mt > -1) {
this._addFortesque(1);
if (mt > 0) this._addBlake(1);
}
if (this.$config.updNova && missionVariables.nova === "NOVA_HERO") {
this._add("PERSONS.GENERIC.info", expandMissionText("LIB_EVENTS_NOVA"), 1);
this.$config.updNova = 0;
}
this.$config.bounty = player.bounty;
this.$config.credits = player.credits;
this.$config.rank = player.rank;
this.$config.status = player.legalStatus;
};
this.playerWillSaveGame = function () {
missionVariables.Lib_PAD_EVENTS = JSON.stringify(this.$config);
};
this.guiScreenChanged = function () {
if (!player.ship.docked) return;
if (guiScreen === "GUI_SCREEN_MISSION" && mission.screenID) {
switch (mission.screenID) {
case "oolite-constrictor-hunt-briefing":
if (this.$config.updNavy) this._add("GALCOP.NAVY.entry", clock.clockString.substr(0, 13));
this.$config.updNavy = 0;
this._add("LOGS.GENERIC.list", expandMissionText("LIB_EVENT_CONSTRICTOR_START"));
this._addCurruthers();
this.$config.updCR = 1;
break;
case "oolite-constrictor-hunt-debriefing":
this._add("LOGS.GENERIC.list", expandMissionText("LIB_EVENT_CONSTRICTOR_WIN1"));
this._add("GALCOP.NAVY.missions", expandMissionText("LIB_EVENT_CONSTRICTOR_WIN2"));
this._add("GALCOP.NAVY.kills", "++", 1);
this.$config.updCR = 0;
break;
case "oolite-thargoid-plans-briefing1":
this._addFortesque();
break;
case "oolite-thargoid-plans-briefing2":
this._add("LOGS.GENERIC.list", expandMissionText("LIB_EVENT_THARPLANS_START"));
this._addBlake();
this.$config.updTP = 1;
break;
case "oolite-thargoid-plans-debriefing":
this._add("GALCOP.NAVY.missions", expandMissionText("LIB_EVENT_THARPLANS_WIN2"));
this._add("LOGS.GENERIC.list", expandMissionText("LIB_EVENT_THARPLANS_WIN1"));
this.$config.updTP = 0;
break;
case "oolite-nova-hero":
case "oolite-nova-disappointed":
case "oolite-nova-ignored":
case "oolite-nova-coward":
this._add("PERSONS.GENERIC.info", expandMissionText("LIB_EVENTS_NOVA"));
this.$config.updNova = 0;
break;
}
}
};
this.playerCompletedContract = function (type, result, fee, contract) {
var txt, f, prefix;
if (!fee) {
switch (type) {
case "passenger": txt = expandMissionText("LIB_EVENT_CONTRACT_PSNGR_NOFEE", { name: contract.name }); break;
case "parcel": txt = expandMissionText("LIB_EVENT_CONTRACT_PARCEL_NOFEE", { name: contract.name }); break;
case "cargo": txt = expandMissionText("LIB_EVENT_CONTRACT_CARGO_NOFEE", { name: contract.cargo_description }); break;
}
} else {
// logically, the "failed" result can't get here. in the event of a failed result, the fee would be 0
switch(result) {
case "success":
prefix = expandMissionText("LIB_EVENT_CONTRACT_ARRIVE");
break;
case "short":
prefix = expandMissionText("LIB_EVENT_CONTRACT_SHORT");
break;
default:
prefix = expandMissionText("LIB_EVENT_CONTRACT_LATE");
}
f = formatCredits(fee / 10, 1);
switch (type) {
case "passenger":
txt = expandMissionText("LIB_EVENT_CONTRACT_PSNGR_FEE", { prefix: prefix, fee: f, name: contract.name });
break;
case "parcel":
txt = expandMissionText("LIB_EVENT_CONTRACT_PARCEL_FEE", { prefix: prefix, fee: f, name: contract.name });
break;
case "cargo":
txt = expandMissionText("LIB_EVENT_CONTRACT_CARGO_FEE", { prefix: prefix, fee: f, name: contract.cargo_description });
break;
}
}
if (txt) this._add("LOGS.GENERIC.list", txt);
};
this.playerEnteredNewGalaxy = function () {
this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_JUMP_GAL", { num: +(galaxyNumber + 1) })]);
};
this.playerRescuedEscapePod = function (fee, reason, pilot) {
fee = formatCredits(fee, 1);
if (system.isInterstellarSpace) {
if (fee) this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_RESCUED_POD_INT_FEE", { name: pilot.name, fee: (fee / 10) })]);
else this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_RESCUED_POD_INT", { name: pilot.name })]);
} else {
if (fee) this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_RESCUED_POD_FEE", { name: pilot.name, sys: system.name, fee: (fee / 10) })]);
else this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_RESCUED_POD", { name: pilot.name, sys: system.name })]);
}
};
this.shipLaunchedEscapePod = function () {
if (system.isInterstellarSpace) this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_EJECT_INT")]);
else this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_EJECT", { sys: system.name })]);
};
this.shipWillDockWithStation = function () {
this.$config.bounty = player.bounty;
this.$config.credits = player.credits;
if (player.rank !== this.$config.rank) this._add("LOGS.GENERIC.list", expandMissionText("LIB_EVENT_RANK", { rank: player.rank }));
this.$config.rank = player.rank;
this.$config.status = player.legalStatus;
this._addDelayed();
};
this.shipDockedWithStation = function (st) {
if (!player.ship.docked) return;
var m;
if (this.$config.credits !== player.credits) {
if (player.credits > this.$config.credits) m = expandMissionText("LIB_EVENT_EARNED", { amount: formatCredits(player.credits - this.$config.credits, 1), stn: st.displayName });
else m = expandMissionText("LIB_EVENT_LOST", { amount: formatCredits(this.$config.credits - player.credits, 1), stn: st.displayName });
if (system.isInterstellarSpace) m += ".";
else m += " " + system.name + ".";
this._add("LOGS.GENERIC.list", m);
}
if (player.ship.markedForFines) this.$config.fined++;
};
this.playerBoughtNewShip = function () {
this.$config.credits = player.credits;
};
// Note: Handler is fired (too?) early, so guarding (this.$init) is necessary!!!
this.equipmentAdded = function (eq) {
if (this.$init) return;
this.$config.credits = player.credits;
if (eq === "EQ_NAVAL_ENERGY_UNIT") {
this._add("LOGS.GENERIC.list", expandMissionText("LIB_EVENT_NEU"));
this._add("GALCOP.NAVY.awards", expandMissionText("LIB_EVENT_AWARD_NEU"));
}
if (eq === "EQ_CLOAKING_DEVICE") {
this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_CLOAK")]);
this.$delay.push(["PERSONS.GENERIC.info", expandMissionText("LIB_EVENT_AWARD_CLOAK")]);
}
};
this.shipLaunchedFromStation = function () {
this.$config.bounty = player.bounty;
this.$config.credits = player.credits;
this.$config.rank = player.rank;
this.$config.status = player.legalStatus;
};
this.shipBountyChanged = function (delta) {
var m;
if (this.$config.bounty === player.bounty + delta) return;
if (!player.bounty) m = expandMissionText("LIB_EVENT_BOUNTY_CLEARED");
else {
if (delta > 0) m = expandMissionText("LIB_EVENT_BOUNTY_RCVD");
if (delta < 0) m = expandMissionText("LIB_EVENT_BOUNTY_REDUCED");
if (this.$config.status !== player.legalStatus) m += expandMissionText("LIB_EVENT_BOUNTY_STATUS", { status: player.legalStatus });
}
if (m) this.$delay.push(["LOGS.GENERIC.list", m]);
this.$config.bounty = player.bounty;
this.$config.status = player.legalStatus;
};
this.shipKilledOther = function (whom) {
if (player.rank !== this.$config.rank) {
this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_RANK", { rank: player.rank })]);
this.$config.rank = player.rank;
}
if (this.$config.updTP && whom && whom.isThargoid) this.$delay.push(["GALCOP.NAVY.kills", "++", 1]);
};
this.shipWillExitWitchspace = function () {
if (system.isInterstellarSpace) this.$delay.push(["LOGS.GENERIC.list", expandMissionText("LIB_EVENT_MISJUMP")]);
};
this._add = function (p, w, s) {
worldScripts.Lib_PAD._setPageEntry(p, w, s);
};
this._addDelayed = function (p, w, s) {
var l = this.$delay.length;
if (l) {
for (var i = 0; i < l; i++) worldScripts.Lib_PAD._setPageEntry(this.$delay[i][0], this.$delay[i][1], this.$delay[i][2]);
}
this.$delay.length = 0;
};
this._addPage = function (p, w, t, s) {
worldScripts.Lib_PAD._addPageInCategory(p, w, t, s);
};
this._addCurruthers = function (s) {
this._addPage("PERSONS.CAPTAIN CURRUTHERS",
{ name: expandMissionText("LIB_CHAR_NAME_CURRUTHERS"), origin: expandMissionText("LIB_CHAR_RESTRICTED"), species: expandMissionText("LIB_PAD_SPECIES_HUMAN_COLONIAL"), gender: expandMissionText("LIB_PAD_GENDER_MALE"), age: 45, ship: expandMissionText("LIB_CHAR_SHIP_VIPER"), rank: expandMissionText("LIB_CHAR_RANK_CAPTAIN"), t0: 21, t1: "lib_ovc_curruthers.png", t2: 8 }, ["GALCOP.NAVY"], s);
};
this._addFortesque = function (s) {
this._addPage("PERSONS.CAPTAIN FORTESQUE", { name: expandMissionText("LIB_CHAR_NAME_FORTESQUE"), origin: expandMissionText("LIB_CHAR_RESTRICTED"), species: expandMissionText("LIB_PAD_SPECIES_HUMAN_COLONIAL"), gender: expandMissionText("LIB_PAD_GENDER_MALE"), age: 41, ship: expandMissionText("LIB_CHAR_SHIP_VIPER"), rank: expandMissionText("LIB_CHAR_RANK_CAPTAIN"), t0: 21, t1: "lib_ovc_fortesque.png", t2: 8 }, ["GALCOP.NAVY"], s);
};
this._addBlake = function (s) {
this._addPage("PERSONS.AGENT BLAKE", { name: expandMissionText("LIB_CHAR_NAME_BLAKE"), origin: expandMissionText("LIB_CHAR_RESTRICTED"), species: expandMissionText("LIB_CHAR_RESTRICTED"), gender: expandMissionText("LIB_PAD_GENDER_MALE"), age: 34, ship: expandMissionText("LIB_CHAR_RESTRICTED"), rank: expandMissionText("LIB_CHAR_RANK_AGENT"), t0: 21, t1: "lib_ovc_blake.png" }, ["GALCOP.NAVY"], s);
};
}).call(this);
|
| Scripts/Lib_Starmap.js |
/* jshint bitwise:false, forin:false */
/* global mission,player,system,worldScripts,Vector3D */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "Lib_Starmap";
this.startUpComplete = function(){
worldScripts.Lib_GUI.$IDRules.Lib_Starmap = {mus:1};
this.$defs = {
off: Vector3D([0,0,0]),
rel: Vector3D([0,0,0])
};
this._update();
this.$VSE = null;
this.$OP = worldScripts.Lib_Main._lib.ooShaders();
this.$POI = null;
};
/** function _start( obj ) - System map
* obj - Object
* ini - Array. Max 12 entries.
* String or Object { map:TEXTURE,ent:ENTITY [,col:Number] }
* message - Optional. String. Initial message text.
* title - Optional. String. Screen title.
* ani - Optional. Animation for Lib_Animator. Requires capture flag!
* POI - Optional. Vector. Point of interest.
* MUL - Optional. Number. Multiplier. Default 0.00015.
* $return -
*/
this._start = function(obj,force){
if(!obj || (this.$VSE && this.$VSE.isValid) || !this.$OP) return false;
if(force) this._update();
var absZ,col,fin,i,map,mat,md,mul,pos,tmp,rl, trck = [],
maxZ = 0, maxY = 0, minZ = 0, minY = 0, mag = 0, sd = 0,
dck = player.ship.docked, pls = 0, plm = 0, st = 0, as = 0;
this.$POI = null;
if(obj.POI){
this.$POI = obj.POI;
rl = obj.POI;
} else rl = this.$defs.rel;
if(obj.MUL) mul = obj.MUL;
else mul = 0.00015;
if(dck){
var head = {
choices:{ZZZ:expandMissionText("LIB_STARMAP_CONTINUE")},
message:obj.message?obj.message:"",
background:{name:"lib_starmap_bg.png",height:512},
screenID:"Lib_Starmap",
model:"lib_ms_helper12",
spinModel:false,
title:obj.title?obj.title:expandMissionText("LIB_STARMAP_SYSTEMMAP")
};
this.$HUD = player.ship.hudHidden;
player.ship.hudHidden = true;
mission.runScreen(head,this._choices);
md = mission.displayModel;
md.orientation = [1,0,1,0];
md.position = [0,0,500];
} else {
if(!this.$wp || (this.$wp && !this.$wp.isValid)) this.$wp = system.addVisualEffect("lib_starmap_wp",[0,0,0]);
md = system.addVisualEffect("lib_starmap12",player.ship.position);
md.script.$defs = rl;
md.script.$mul = mul;
}
md.lightsActive = false;
if(obj){
for(i=0;i<12;i++){
mat = md.subEntities[i].getMaterials();
col = 0;
if(i>obj.ini.length-1){
mat["lib_null.png"].textures[0] = "lib_blend0.png";
} else {
if(typeof(obj.ini[i])==="string"){
pos = this.$defs.off;
map = "lib_blend0.png";
switch(obj.ini[i]){
case "PS": map = "lib_starmap_5.png"; pos = player.ship.position; trck.push({ent:player.ship,sub:i}); break;
case "S": if(system.sun){map = "lib_starmap_0.png"; pos = system.sun.position; trck.push({ent:system.sun,sub:i});} break;
case "P": tmp = this._getPlanet(pls); pls++; if(tmp){map = tmp[0]; pos = tmp[1].position; trck.push({ent:tmp[1],sub:i});} break;
case "M": tmp = this._getMoon(plm); plm++; if(tmp){map = tmp[0]; pos = tmp[1].position; trck.push({ent:tmp[1],sub:i});} break;
case "ST": if(this.$st.sta){map = "lib_starmap_3.png"; pos = this.$st.sta.position; trck.push({ent:this.$st.sta,sub:i});} break;
case "STG": tmp = this._getGalStation(st); st++; if(tmp){map = tmp[0]; pos = tmp[1].position; trck.push({ent:tmp[1],sub:i});
if(tmp[1].isPolice) col = 4; else col = 3;} break;
case "WP": map = "lib_starmap_2.png"; trck.push({ent:this.$wp,sub:i}); break;
case "H": if(this.$st.sth.length){map = "lib_starmap_4.png"; pos = this.$st.sth[0].position; trck.push({ent:this.$st.sth[0],sub:i});} break;
case "AS": tmp = this._getAsteroidField(as); as += 20; if(tmp){map = tmp[0]; pos = tmp[1].position; trck.push({ent:tmp[1],sub:i});} break;
}
} else {
if(obj.ini[i].ent){
pos = obj.ini[i].ent.position;
trck.push({ent:obj.ini[i].ent,sub:i});
} else {
if(dck) pos = obj.ini[i].pos;
else continue;
}
map = obj.ini[i].map;
if(obj.ini[i].col) col = obj.ini[i].col;
}
if(col) mat["lib_null.png"].uniforms.MC.value = this._getColor(col);
mat["lib_null.png"].textures[0] = map;
pos = this._compress(pos);
// Scale down for display
fin = pos.subtract(rl).multiply(mul);
if(dck){
if(fin.z>maxZ) maxZ = fin.z;
if(fin.y>maxY) maxY = fin.y;
if(fin.z<minZ) minZ = fin.z;
if(fin.y<minY) minY = fin.y;
} else {
mag = fin.magnitude();
if(mag>110) sd = (mag-100)*0.1;
}
md.subEntities[i].position = fin;
}
md.subEntities[i].setMaterials(mat);
}
if(dck){
// Auto zoom
absZ = Vector3D([(-minZ)+maxZ,(-minY)+maxY,0]).magnitude();
absZ = Math.max(absZ,180);
md.position = [0,0,absZ*2];
// Animation
if(obj.ani) worldScripts.Lib_Animator._start(obj.ani);
} else {
if(sd) md.script.$mul = mul/sd;
// Track
if(trck.length) md.script.$upd = trck;
if(player.ship.compassTarget) md.orientation = player.ship.compassTarget.position.rotationTo(rl);
else md.orientation = player.ship.position.rotationTo(rl);
this.$VSE = md;
this.$EnableTimer = new Timer(this,this._doEnableTimer,1);
}
}
return true;
};
this._getPlanet = function(n){
if(!n){
if(!this.$pl.pla) return null;
return(["lib_starmap_1.png",this.$pl.pla]);
}
if(this.$pl.plp.length<=n-1) return null;
return(["lib_starmap_P1.png",this.$pl.plp[n-1]]);
};
this._getMoon = function(n){
if(this.$pl.plm.length<=n) return null;
return(["lib_starmap_M1.png",this.$pl.plm[n]]);
};
this._getGalStation = function(n){
if(this.$st.stgal.length<=n) return null;
if(this.$st.stgal[n].maxSpeed>5) return(["lib_starmap_i4.png",this.$st.stgal[n]]);
return(["lib_starmap_i5.png",this.$st.stgal[n]]);
};
this._getAsteroidField = function(n){
if(this.$as.length<=n) return null;
return(["lib_starmap_7.png",this.$as[n]]);
};
this._getColor = function(n){
var c;
switch(n){
case 1: c = [0.8,0,0,1]; break; // red
case 2: c = [0,0.8,0,1]; break; // green
case 3: c = [0,0,0.8,1]; break; // blue
case 4: c = [0.6,0,0.8,1]; break; // purple
case 5: c = [0.4,0.4,0.4,1]; break; // gray
case 6: c = [0,0.7,0.7,1]; break; // aqua
case 7: c = [0.8,0.6,0,1]; break; // amber
case 8: c = [0.8,0.6,0.3,1]; break; // gold
case 9: c = [0.3,0,0.5,1]; break; // UV
default: c = [1,1,1,1]; break; // white
}
return c;
};
this._addInFreeSlot = function(ent,map,col){
if(!this.$VSE || !this.$VSE.isValid) return;
var x = this.$VSE.script.$upd,m=x.length,slot,mat;
for(var i=0;i<12;i++){
if(i>m-1 || !x[i].ent){slot = i; break;}
}
if(typeof(slot)!=="number" || slot>11) return false;
mat = this.$VSE.subEntities[slot].getMaterials();
mat["lib_null.png"].textures[0] = map;
mat["lib_null.png"].uniforms.MC.value = this._getColor(col);
if(slot<=m) x[slot] = {ent:ent,sub:slot};
else x.push({ent:ent,sub:slot});
this.$VSE.script.$upd = x;
this.$VSE.subEntities[slot].setMaterials(mat);
this.$VSE.subEntities[slot].shaderVector1 = [0,0,0];
return true;
};
// Inflight options
this._doEnableTimer = function(){
if(player.alertCondition<3 && !player.ship.weaponsOnline){
this._switchOn();
if(!this.$VSE || !this.$VSE.isValid) return;
this.$VSE.shaderFloat1 = 1;
} else this._switchOff();
this.$EnableTimer = null;
};
this.alertConditionChanged = function(s){
if(s>2) this._switchOff();
else if(s>0 && !player.ship.weaponsOnline) this._switchOn();
};
this.compassTargetChanged = function(){
if(!this.$VSE || !this.$VSE.isValid) return;
if(this.$POI) this.$VSE.orientation = player.ship.compassTarget.position.rotationTo(this.$POI);
else this.$VSE.orientation = player.ship.compassTarget.position.rotationTo(this.$defs.rel);
};
this.weaponsSystemsToggled = function(state){
if(state) this._switchOff();
else if(player.alertCondition<3) this._switchOn();
};
this._switchOn = function(){
if(!this.$VSE || !this.$VSE.isValid) return;
this.$VSE.script.$hide = true;
if(!this.$EnableTimer) this.$EnableTimer = new Timer(this,this._doEnableTimer,1);
};
this._switchOff = function(){
if(!this.$VSE || !this.$VSE.isValid) return;
this.$VSE.shaderFloat1 = 0;
this.$VSE.script.$hide = false;
};
this._toggleMP = function(){
if(!this.$VSE || !this.$VSE.isValid) return;
this.$VSE.script.$PSC = !this.$VSE.script.$PSC;
};
// Update after populator
this.shipExitedWitchspace = this.shipWillDockWithStation = this.shipWillLaunchFromStation = function(){
this._update();
};
this._update = function(){
if(this.$VSE && this.$VSE.isValid) this.$VSE.remove();
this.$VSE = null;
this._updPlanets();
this._updStations();
this._updAsteroids();
this._getMidpoint();
};
this._updPlanets = function(){
var pl = system.planets;
this.$pl = {pla:null,plp:[],plm:[]};
for(var i=0;i<pl.length;i++){
if(pl[i].isMainPlanet) this.$pl.pla = pl[i];
else {
if(pl[i].hasAtmosphere) this.$pl.plp.push(pl[i]);
else this.$pl.plm.push(pl[i]);
}
}
};
this._updStations = function(){
var st = system.stations;
this.$st = {sta:null,sth:[],stgal:[],stoth:[]};
for(var i=0;i<st.length;i++){
if(st[i].isMainStation) this.$st.sta = st[i];
else if(st[i].isRock && st[i].name==="Rock Hermit") this.$st.sth.push(st[i]);
else {
switch(st[i].allegiance){
case "galcop":
case "hunter":
case "neutral": this.$st.stgal.push(st[i]); break;
default: if(st[i].beaconCode) this.$st.stoth.push(st[i]);
}
}
}
};
this._updAsteroids = function(){
this.$as = system.filteredEntities(this,function(entity){return entity.isShip && entity.isRock && entity.name==="Asteroid";},player.ship);
};
this._getMidpoint = function(){
if(system.isInterstellarSpace){
this.$defs.rel = this.$defs.off;
return;
} else {
// no c as WP is [0,0,0]
var a = this._compress(system.sun.position), b = this._compress(system.mainPlanet.position);
this.$defs.rel = Vector3D([(a.x+b.x)/3,(a.y+b.y)/3,(a.z+b.z)/3]);
}
};
// Compress far out
this._compress = function(pos){
var pmag = pos.magnitude();
if(pmag>1199998.8) pos = Vector3D.interpolate(this.$defs.off,pos,1199998.8/pmag);
return pos;
};
this._choices = function(choice){worldScripts.Lib_Starmap._choiceEval(choice); return;};
this._choiceEval = function(choice){
player.ship.hudHidden = this.$HUD;
};
}).call(this); |
| Scripts/Lib_Starmap.txt |
// Display traders
var a = system.filteredEntities(this,function(entity){return entity.isShip && !entity.isStation && !entity.owner && entity.isTrader;},player.ship),b=["PS","WP","P","ST","S"];
for(var i=0;i<7;i++){if(a.length>i){b.push({map:"lib_starmap_i2.png",ent:a[i],col:5});}}worldScripts.Lib_Starmap._start({ini:b});
// Display pirates
var a = system.filteredEntities(this,function(entity){return entity.isShip && !entity.isStation && !entity.owner && entity.isPirate;},player.ship),b=["PS","WP","P","ST","S"];
for(var i=0;i<7;i++){if(a.length>i){b.push({map:"lib_starmap_i3.png",ent:a[i],col:1});}}worldScripts.Lib_Starmap._start({ini:b});
// Display police
var a = system.filteredEntities(this,function(entity){return entity.isShip && !entity.isStation && !entity.owner && entity.isPolice;},player.ship),b=["PS","WP","P","ST","S"];
for(var i=0;i<7;i++){if(a.length>i){b.push({map:"lib_starmap_i1.png",ent:a[i],col:4});}}worldScripts.Lib_Starmap._start({ini:b});
// Default - Player, Witchpoint, Planet, Sun, MainStation, Hermit, Asteroid fields and secondary stations
worldScripts.Lib_Starmap._start( { ini:["PS","WP","P","S","ST","H","AS","AS","AS","STG","STG","STG"] } );
// Display fun
var a = system.filteredEntities(this,function(entity){return entity.isShip && !entity.isStation && !entity.owner && entity.isTrader},player.ship),
c = system.filteredEntities(this,function(entity){return entity.isShip && !entity.isStation && !entity.owner && entity.isPirate && entity.group && entity.group.leader && entity.entityPersonality===entity.group.leader.entityPersonality;},player.ship),
b=["PS","WP","P","ST","S"];
for(var i=0;i<15;i++){
if(b.length===12) break;
if((i&1) && a.length>i){b.push({map:"lib_starmap_i2.png",ent:a[i],col:5});}
else if(c.length>i){b.push({map:"lib_starmap_i2.png",ent:c[i],col:1});}
}
worldScripts.Lib_Starmap._start({ini:b});
|
| Scripts/lib_conditions.js |
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
"use strict";
this.name = "lib_conditions";
this.allowSpawnShip = function(shipKey){
return true;
};
|
| Scripts/lib_fx.js |
/* global addFrameCallback,player,removeFrameCallback */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "lib_fx";
this.$time = 0;
// Set on spawning
this.$repos = 250;
this.$reposTil = 0;
this.$ridTime = 4;
this.$look = 0;
this.$view = 0;
this.$offset = 0;
this.$glare = player.ship.sunGlareFilter;
player.ship.sunGlareFilter = 1;
this.effectSpawned = function(){
this.$fcb = addFrameCallback(this._repos.bind(this));
};
this.effectRemoved = function(){
removeFrameCallback(this.$fcb);
};
this._repos = function(delta){
var ps = player.ship,vF=ps.vectorForward,lv,v,pos,npos,sgf;
if(!ps.isValid || this.$time>this.$ridTime){
this.visualEffect.remove();
return;
}
this.$time += delta;
if(!delta) return;
if(this.$glare<1 && this.$time>this.$reposTil-1){
if(ps.sunGlareFilter-delta>this.$glare) ps.sunGlareFilter -= delta;
else ps.sunGlareFilter = this.$glare;
}
if(this.$reposTil && this.$time>this.$reposTil) this.$repos = 0;
if(this.$repos){
if(this.$view){
switch(ps.viewDirection){
case "VIEW_AFT": pos = ps.position.add(ps.viewPositionAft); break;
case "VIEW_PORT": pos = ps.position.add(ps.viewPositionPort); break;
case "VIEW_STARBOARD": pos = ps.position.add(ps.viewPositionStarboard); break;
case "VIEW_FORWARD": pos = ps.position.add(ps.viewPositionForward); break;
default: pos = ps.position;
}
pos = pos.add(vF.multiply(this.$repos));
} else pos = ps.position.add(vF.multiply(this.$repos)).add(ps.vectorUp.multiply(this.$offset));
this.visualEffect.position = pos;
this.visualEffect.orientation = ps.orientation;
if(this.$look){
switch(ps.viewDirection){
case "VIEW_AFT": lv = [0,0,-1.07]; break;
case "VIEW_PORT": lv = [-3,0,1.4]; break;
case "VIEW_STARBOARD": lv = [3,0,1.4]; break;
case "VIEW_FORWARD": lv = [0,0,1.4]; break;
default: lv = [0,0,1.4];
}
this.visualEffect.shaderVector2 = lv;
}
}
};
}).call(this);
|
| Scripts/lib_shield.js |
"use strict";
this.name = "lib_shield";
this.$fcb;
this.$parent;
this.effectSpawned = function(){
this.$fcb = addFrameCallback(this._updatePosition.bind(this));
};
this.effectRemoved = function(){
removeFrameCallback(this.$fcb);
};
this._updatePosition = function(){
if(!this.$parent) return;
if(player.ship.position){
this.visualEffect.position = this.$parent.position.subtract(this.$parent.vectorForward.multiply(-120));
this.visualEffect.position = this.visualEffect.position.add(this.$parent.position.subtract(player.ship.position).direction().multiply(3));
} else removeFrameCallback(this.$fcb);
};
|
| Scripts/lib_starmap12.js |
/* global addFrameCallback,player,removeFrameCallback,Vector3D */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 */
(function(){
"use strict";
this.name = "lib_starmap12";
this.$upd = [];
this.$c = 0;
this.$pos = null;
this.$pmag = 0;
this.$ps = player.ship;
this.$defs = null;
this.$mul = 0.00015;
this.$hide = true;
this.$PSC = 0;
this.effectSpawned = function(){
this.$fcb = addFrameCallback(this._repos.bind(this));
};
this.effectRemoved = function(){
removeFrameCallback(this.$fcb);
};
this._repos = function(){
if(!this.$ps.isValid || !this.$ps.isInSpace){
this.visualEffect.remove();
return;
}
if(!this.$defs || (!this.visualEffect.shaderFloat1 && !this.$hide)) return;
else {
var ul = this.$upd.length;
this.visualEffect.position = this.$ps.position.add(this.$ps.vectorForward.multiply(400)).add(this.$ps.vectorUp.multiply(80)).add(this.$ps.vectorRight.multiply(80));
switch(this.$c){
case 0: if(ul) this._updatePos(this.$upd[0]); break;
case 1: if(ul>1) this._updatePos(this.$upd[1]); break;
case 2: if(ul>2) this._updatePos(this.$upd[2]); break;
case 3: if(ul>3) this._updatePos(this.$upd[3]); break;
case 4: if(ul>4) this._updatePos(this.$upd[4]); break;
case 5: if(ul>5) this._updatePos(this.$upd[5]); break;
case 6: if(ul>6) this._updatePos(this.$upd[6]); break;
case 7: if(ul>7) this._updatePos(this.$upd[7]); break;
case 8: if(ul>8) this._updatePos(this.$upd[8]); break;
case 9: if(ul>9) this._updatePos(this.$upd[9]); break;
case 10: if(ul>10) this._updatePos(this.$upd[10]); break;
case 11: if(ul>11) this._updatePos(this.$upd[11]); break;
}
this.$c++;
this.$c %= 12;
}
};
this._updatePos = function(obj){
if(!obj.ent) return;
if(!obj.ent.isValid || !obj.ent.isInSpace){
this.visualEffect.subEntities[obj.sub].shaderVector1 = [0,0,1];
obj.ent = null;
} else {
this.$pos = obj.ent.position;
this.$pmag = this.$pos.magnitude();
if(this.$PSC){
if(this.$pmag>1199998.8) this.$pos = Vector3D.interpolate(this.$ps.position,this.$pos,1199998.8/this.$pmag);
this.visualEffect.subEntities[obj.sub].position = this.$pos.subtract(this.$ps.position).multiply(this.$mul);
} else {
if(this.$pmag>1199998.8) this.$pos = Vector3D.interpolate(this.$defs,this.$pos,1199998.8/this.$pmag);
this.visualEffect.subEntities[obj.sub].position = this.$pos.subtract(this.$defs).multiply(this.$mul);
}
}
};
}).call(this);
|
| Scripts/lib_test.js |
/* global system,worldScripts,Timer */
/* (C) Svengali 2016-2018, License CC-by-nc-sa-4.0 - Detect changes in custom role entity */
(function(){
"use strict";
this.name = "lib_test";
// There are a few AddOns which are changing / removing custom role entities. Uncalled!
this.shipSpawned = function(){
delete this.shipSpawned;
this.$checkTimer = new Timer(this,this._doCheck,0.5);
};
this._stopTimers = function(warn){
if(this.$checkTimer) this.$checkTimer.stop();
this.$checkTimer = null;
return;
};
this._doCheck = function _doCheck(){
var eq = {
accuracy: -2,
autoAI: false,
autoWeapons: false,
bounty: 0,
cloakAutomatic: false,
energyRechargeRate: 3,
fuel: 6,
heatInsulation: 1,
isBeacon: false,
isCloaked: false,
isDerelict: false,
isJamming: false,
isPirate: false,
isPirateVictim: false,
isPolice: false,
isTrader: false,
maxEnergy: 450,
maxEscorts: 2,
missileCapacity: 4,
missileLoadTime: 4,
name: "Boa",
shipClassName: "Boa"
},
eqs = {
aftWeapon: ["EQ_WEAPON_PULSE_LASER"],
equipment: ["EQ_FUEL_SCOOPS","EQ_ESCAPE_POD"],
forwardWeapon: ["EQ_WEAPON_PULSE_LASER"],
missiles: ["EQ_MISSILE","EQ_MISSILE","EQ_MISSILE"],
portWeapon: ["EQ_WEAPON_NONE"],
starboardWeapon: ["EQ_WEAPON_NONE"]
},
wps = ["weaponPositionForward","weaponPositionAft","weaponPositionPort","weaponPositionStarboard"],
listA = Object.keys(eq), lA = listA.length,
listB = Object.keys(eqs), lB = listB.length,
i,j,k,cur, warn = worldScripts.Lib_Main._lib.$entCstChanged;
for(i=0;i<lA;i++) if(this.ship[listA[i]] !== eq[listA[i]] && warn.indexOf(listA[i])===-1) warn.push(listA[i]);
for(i=0;i<lB;i++){
cur = this.ship[listB[i]];
if(cur.length){
for(j=0;j<cur.length;j++) if(cur[j].equipmentKey !== eqs[listB[i]][j] && warn.indexOf(listB[i])===-1) warn.push(cur[j].equipmentKey);
} else if(cur.equipmentKey !== eqs[listB[i]][0] && warn.indexOf(listB[i])===-1) warn.push(listB[i]);
}
for(k=0;k<4;k++) if(this.ship[wps[k]].length>1 && warn.indexOf(wps[k])===-1) warn.push(wps[k]);
if(145!==this.shipDied.toSource().length+this.shipRemoved.toSource().length) worldScripts.Lib_Main._lib.$entCstPatched = true;
this._stopTimers();
};
this.shipDied = function(){this._stopTimers();};
this.shipRemoved = function(){this._stopTimers(); worldScripts.Lib_Main._lib.$entCstRemoved = true;};
this.entityDestroyed = function(){this._stopTimers();};
this.shipLaunchedEscapePod = function(){this._stopTimers();};
this.shipWillEnterWormhole = function(){this._stopTimers();};
this.playerWillEnterWitchspace = function(){this._stopTimers();};
}).call(this);
|