| Config/script.js | "use strict";
this.name        = "station_ads"; 
this.author      = "spara";
this.description = "Pooling ad service";
this.$vertAdPool = [];
this.$horzAdPool = [];
//public function for adding vertical ad to pool. the parameter is the filename of the ad.
this._setVertAd = function(ad) {
  this.$vertAdPool.push(ad);
}
//public function for adding horizontal ad to pool. the parameter is the filename of the ad.
this._setHorzAd = function(ad) {
  this.$horzAdPool.push(ad);
}
this.startUp = function() {
  //add vertical ads to pools
  for (var i = 1; i <= 73; i++) {
    this.$vertAdPool.push("station_ads_vert_" + i + ".png");
  }
  //add horizontal ads to pools
  for (var i = 1; i <= 379; i++) {
    this.$horzAdPool.push("station_ads_horz_" + i + ".png");
  }
}
this.startUpComplete = function() {
  //shuffle the pools
  this.$vertAdPool = this._shuffle(this.$vertAdPool);
  this.$horzAdPool = this._shuffle(this.$horzAdPool);
  
	//Pools are divided to two parts to prevent the same ad to be seen in a quick succession. Pools are split into two parts and a primary part is randomly selected. When the active part is emptied, then the secondary part is used. When that is emptied too, pool is initialized and we draw from the primary part again.
  this._initVertPool();
	this.$vertPrimary = Math.round(Math.random());
  this._initHorzPool();
	this.$horzPrimary = Math.round(Math.random());
}
this._shuffle = function(pool) {
  var shuffled = new Array();
  var poolSize = pool.length;
  for (var i = poolSize; i > 0; i--) {
    shuffled.push(pool.splice(Math.floor(Math.random() * i), 1)[0]);
  }
  return shuffled;
}
//init the pool and divide it into two parts.
this._initVertPool = function() {
	var vertPoolSize = this.$vertAdPool.length;
  this.$vertPool = [this.$vertAdPool.slice(0, Math.floor(vertPoolSize / 2)), this.$vertAdPool.slice(Math.ceil(vertPoolSize / 2), vertPoolSize - 1)];
}
//init the pool and divide it into two parts.
this._initHorzPool = function() {
	var horzPoolSize = this.$horzAdPool.length;
  this.$horzPool = [this.$horzAdPool.slice(0, Math.floor(horzPoolSize / 2)), this.$horzAdPool.slice(Math.ceil(horzPoolSize / 2), horzPoolSize - 1)];	
}
//public function that returns a random vertical ad filename from the pool
this._getVerticalAd = function() {
	//is the active part empty?
	if (this.$vertPool[this.$vertPrimary].length === 0) {
		//switch the active part
		this.$vertPrimary = (this.$vertPrimary + 1) % 2;
		//is the active part still empty
		if (this.$vertPool[this.$vertPrimary].length === 0) {
			//init pool
			this._initVertPool();
		};
	};
	//select an ad randomly from the active part
	var adNum = Math.floor(Math.random() * this.$vertPool[this.$vertPrimary].length);
	//return and remove the selected ad from the pool
	return this.$vertPool[this.$vertPrimary].splice(adNum, 1)[0];
}
//public function that returns a random horizontal ad filename from the pool
this._getHorizontalAd = function() {
	if (this.$horzPool[this.$horzPrimary].length === 0) {
		this.$horzPrimary = (this.$horzPrimary + 1) % 2;
		if (this.$horzPool[this.$horzPrimary].length === 0) {
			this._initHorzPool();
		};
	};
	var adNum = Math.floor(Math.random() * this.$horzPool[this.$horzPrimary].length);
	return this.$horzPool[this.$horzPrimary].splice(adNum, 1)[0];
}
 | 
                
                    | Scripts/station_ads.js | "use strict";
this.name        = "station_ads_station_script";
this.author      = "spara";
this.description = "Changes and configures the ads shown at system stations.";
this.shipSpawned = function() {
		//in G1 this yields a number from range 1.17 - 315 mean being 72.6 and median 51.8
		var closeSystems = system.info.systemsInRange();
		var profitFactor = 0;//measures the amount of potential traders
		for (var i = 0; i < closeSystems.length; i++) {
			var otherSystem = closeSystems[i];
			//economies on different ends of the scale mean more potential traders
			var prosperFactor = 1 + Math.abs(system.info.economy - otherSystem.economy);
			//unstability means danger and fewer potential traders
			var dangerFactor = 1 + Math.min(system.info.government, otherSystem.government);
			profitFactor += prosperFactor * dangerFactor;
		}
		profitFactor *= (1 + system.info.government) / 6;//emphasize safe govs
	switch (ship.dataKey) {
        case "griff_tetrahedron_mainhull_diamonds":
        case "griff_octahedron_mainhull_diamonds":
		case "griff_coriolis_mainhull":
		case "coriolis-station":
            this.$stationType = "coriolis";
            this.$maxFrontAds = 1;//the number of front ads configured in shipdata
            this.$frontScreenId = 3;//the first front ad screen in shipdata
            this.$dockScreenId = 1;//the first dock ad screen in shipdata
            this.$dockAds = 1;//the number of dock ads
			//dock subent of the station
            if (ship.dataKey === "griff_coriolis_mainhull") {
                this.$dockSubent = 0;
            }
            else if (ship.dataKey.indexOf("diamonds") !== -1) {
                this.$dockSubent = 3;
            }
            else this.$dockSubent = 2;
			//configure the number of front ads based on profitFactor
			if (profitFactor < 50) this.$frontAds = 0;
			else this.$frontAds = 1;
			break;
		case "griff_dodo_mainhull":
		case "dodecahedron-station":
			this.$stationType = "dodo";
			this.$maxFrontAds = 4;
			this.$frontScreenId = 5;
			this.$dockScreenId = 1;
			this.$dockAds = 2;
      if (ship.dataKey === "griff_dodo_mainhull") {
        this.$dockSubent = 0;
      }
      else this.$dockSubent = 1;
			//good combinations: 0, 2 and 4 ads.
			if (profitFactor < 50) this.$frontAds = 0;
			else if (profitFactor < 150) this.$frontAds = 2;
			else this.$frontAds = 4;
			break;
		case "griff_ico_mainhull":
		case "icosahedron-station":
			this.$stationType = "ico";
			this.$maxFrontAds = 12;
			this.$frontScreenId = 5;
			this.$dockScreenId = 1;
			this.$dockAds = 2;
      if (ship.dataKey === "griff_ico_mainhull") {
        this.$dockSubent = 0;
      }
      else this.$dockSubent = 1;
			//good combinations 0, 2, 4, 6, 8, 10 and 12 ads.
			//currently only up to 8 used
			if (profitFactor < 50) this.$frontAds = 0;
			else if (profitFactor < 100) this.$frontAds = 2;
			else if (profitFactor < 150) this.$frontAds = 4;
			else if (profitFactor < 200) this.$frontAds = 6;
			else this.$frontAds = 8;
			break;
		default:
			//in case another oxp has like_shipped overridden core stations...
			return;
	};
	//remove excess screens
	var lastSubent = ship.subEntities[this.$dockSubent].subEntities.length - 1;
	for (var i = 0; i < this.$maxFrontAds - this.$frontAds; i++) {
		ship.subEntities[this.$dockSubent].subEntities[lastSubent - 2 * i].remove();
		ship.subEntities[this.$dockSubent].subEntities[lastSubent - 2 * i - 1].remove();
	};
	//add some rare random malfunctions to the front ads
	this.$brokenScreens = new Array();
	for (var i = 0; i < this.$frontAds; i++) {
		if (Math.random() < 0.01) {
			this.$brokenScreens.push(this.$frontScreenId + 2 * i);
			var prob = Math.random();
			if (prob < 0.33) {
				var error = "station_ads_error_0.png";
				ship.subEntities[this.$dockSubent].subEntities[this.$frontScreenId + 2 * i].setMaterials({"yah_griff_no_shader_screen.png": {diffuse_map: error}});
			}
			else if (prob < 0.66){
				var error = "station_ads_error_1.png";
				ship.subEntities[this.$dockSubent].subEntities[this.$frontScreenId + 2 * i].setMaterials({"yah_griff_no_shader_screen.png": {diffuse_map: error, emission_map: error}});
			}
			else {
				var error = "station_ads_dock_frame.png";
				ship.subEntities[this.$dockSubent].subEntities[this.$frontScreenId + 2 * i].setMaterials({"yah_griff_no_shader_screen.png": {diffuse_map: error}});
			};
		};
	};
	//make sure that the ad pool is up and running
	if (worldScripts["station_ads"]) {
		this.$ws = worldScripts["station_ads"];
		//init dock ads and rotate one every 11/6 seconds
		if (this.$dockAds > 0) {
			//init
			for (var i = 0; i < this.$dockAds; i++) {
				this._changeDockAd();
			};
			//rotate
			if (this.$dockAds === 1) {
				this.$dockAdTimer = new Timer(this, this._changeDockAd, 0, 11);
			}
			else {
				this.$dockAdTimer = new Timer(this, this._changeDockAd, 0, 6);
			}
		}
		//init front ads and rotate one every 10/5 seconds.
		if (this.$frontAds > 0) {
			for (var i = 0; i < this.$frontAds; i++) {
				this._changeFrontAd();
			};
			if (this.$frontAds === 1) {
				this.$frontAdTimer = new Timer(this, this._changeFrontAd, 0, 10);
			}
			else {
				this.$frontAdTimer = new Timer(this, this._changeFrontAd, 0, 5);
			};
		};
	};
}
this._changeDockAd = function() {
	//make sure the the station is still there to prevent timer errors
	if (ship) {
		if (this.$stationType === "ico") {
			var newAd = this.$ws._getVerticalAd();
		}
		else {
			var newAd = this.$ws._getHorizontalAd();
		}
		ship.subEntities[this.$dockSubent].subEntities[this.$dockScreenId].setMaterials({"yah_griff_no_shader_screen.png": {diffuse_map: newAd, emission_map: newAd}});
		this.$dockScreenId = this.$dockScreenId + 2;
		if (this.$dockScreenId > this.$dockAds * 2) {
			this.$dockScreenId = 1;
		}
	}
	else delete this.$dockAdTimer;
}
this._changeFrontAd = function() {
	//make sure the the station is still there to prevent timer errors
	if (ship) {
		if (this.$brokenScreens.indexOf(this.$frontScreenId) === -1) {
			var newAd = this.$ws._getHorizontalAd();
			ship.subEntities[this.$dockSubent].subEntities[this.$frontScreenId].setMaterials({"yah_griff_no_shader_screen.png": {diffuse_map: newAd, emission_map: newAd}});
		}
		this.$frontScreenId = this.$frontScreenId + 2;
		if (this.$frontScreenId > this.$dockAds * 2 - 1 + this.$frontAds * 2) {
			this.$frontScreenId = this.$dockAds * 2 + 1;
		}
	}
	else delete this.$frontAdTimer;
}
 |