Back to Index Page generated: Dec 20, 2024, 7:22:09 AM

Expansion Escort Formations

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Vary the flight formations used by escort pilots to give some alternatives to the usual 'v' shape. Vary the flight formations used by escort pilots to give some alternatives to the usual 'v' shape.
Identifier oolite.oxp.cim.escort-formations oolite.oxp.cim.escort-formations
Title Escort Formations Escort Formations
Category Mechanics Mechanics
Author cim cim
Version 1.3 1.3
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/Escort_Formations n/a
Download URL https://wiki.alioth.net/img_auth.php/d/d4/Escort_Formations_1.3.oxz http://compsoc.dur.ac.uk/~cim/oolite/Escort_Formations_1.1.oxz
License CC-BY-SA 3.0 CC-BY-SA 3.0
File Size n/a
Upload date 1693392141

Documentation

Also read http://wiki.alioth.net/index.php/Escort%20Formations

Equipment

This expansion declares no equipment.

Ships

This expansion declares no ships.

Models

This expansion declares no models.

Scripts

Path
Scripts/escort-formations.js
this.author = "cim";
this.copyright = "� 2011-2014 cim.";
this.licence = "CC-BY-SA 3.0";
this.version = "1.3";
this.name = "Escort Formations Randomiser";
this.description = "Randomise escort formations for traders and pirates";

"use strict";

this.startUp = function () {
	this.$escortPatterns = new Object;
	this.$escortPatterns["combat-spread"] = [new Vector3D(1, 0, 0),
		new Vector3D(-1, 0, 0)
	];
	this.$escortPatterns["echelon"] = [new Vector3D(1, 0, -1)];
	this.$escortPatterns["trail"] = [new Vector3D(1, 0, -5),
		new Vector3D(-1, 0, -6)
	];
	this.$escortPatterns["vform"] = [new Vector3D(1, 0, -1),
		new Vector3D(-1, 0, -1)
	];
	this.$escortPatterns["arrowhead"] = [new Vector3D(1, 0, -1),
		new Vector3D(-1, 0, -1),
		new Vector3D(0, 1, -1),
		new Vector3D(0, -1, -1)
	];
	this.$escortPatterns["convoy"] = [new Vector3D(0, 1, 7),
		new Vector3D(0, -1, -7),
		new Vector3D(1, 1, 6),
		new Vector3D(-1, 1, 6),		
		new Vector3D(-1, -1, -6),
		new Vector3D(1, -1, -6),
		new Vector3D(0, 1.5, -3),		
		new Vector3D(0, -1.5, 3)		
	];
	this.$escortPatterns["scouting-spread"] = [new Vector3D(5, 0, -4),
		new Vector3D(-5, 0, 4)
	];
	this.$escortPatterns["planebox"] = [new Vector3D(2, 0, 2),
		new Vector3D(-2, 0, -2),
		new Vector3D(-2, 0, 2),
		new Vector3D(2, 0, -2)
	];
	this.$escortPatterns["twistbox"] = [new Vector3D(2, 0, 2),
		new Vector3D(0, 2, -2),
		new Vector3D(0, -2, -2),
		new Vector3D(-2, 0, 2)
	];
	this.$escortPatterns["octahedron"] = [new Vector3D(4, 0, 0),
		new Vector3D(-4, 0, 0),
		new Vector3D(0, 4, 0),
		new Vector3D(0, -4, 0),
		new Vector3D(0, 1, 4),
		new Vector3D(0, -1, -4)
	];
	this.$escortPatterns["pyramid"] = [new Vector3D(0, 1, 4.5),
		new Vector3D(3, 3, -3),
		new Vector3D(-3, -3, -3),
		new Vector3D(-3, 3, -3),
		new Vector3D(3, -3, -3)
	];
	this.$escortPatterns["wave"] = [new Vector3D(1, 0, -0.5),
		new Vector3D(-1, 0, -0.5),
		new Vector3D(1, 0, -5.5),
		new Vector3D(-1, 0, -5.5),
		new Vector3D(2, 0, -6.5),
		new Vector3D(-2, 0, -6.5)
	];
	this.$escortPatterns["screen"] = [new Vector3D(1, 0, 3),
		new Vector3D(-1, 0, 3),
		new Vector3D(4, 0, 2.5),
		new Vector3D(-4, 0, 2.5)
	];
	this.$escortPatterns["opencolumn"] = [new Vector3D(-0.5, 0, -2),
		new Vector3D(0.5, 0, -2),
		new Vector3D(-0.5, 0, -4),
		new Vector3D(0.5, 0, -4),
		new Vector3D(-0.5, 0, -6),
		new Vector3D(0.5, 0, -6)
	];
	this.$escortPatterns["stack"] = [new Vector3D(0.5, 1, 0),
		new Vector3D(-0.5, -1, 0)
	];
	this.$escortPatterns["flank"] = [new Vector3D(1, 0, -1),
		new Vector3D(-1, 0, -1),
		new Vector3D(7, 0, -1),
		new Vector3D(-7, 0, -1)
	];
	this.$escortPatterns["bulge"] = [new Vector3D(-1, 0, -1),
		new Vector3D(1, 0, -1),
		new Vector3D(0, 0.5, 7),
		new Vector3D(0, -0.5, -7)
	];
	this.$escortPatterns["near-far"] = [new Vector3D(-1, 0, -1),
		new Vector3D(7, 0, -1),
		new Vector3D(1, 0, -1),
		new Vector3D(6, 0, -2)
	];
	this.$escortPatterns["helix"] = [new Vector3D(-3, 0, -1),
		new Vector3D(0, 3, -2),
		new Vector3D(3, 0, -3),
		new Vector3D(0, -3, -4),
		new Vector3D(-4, 0, -5),
		new Vector3D(0, 4, -6),
		new Vector3D(4, 0, -7),
		new Vector3D(0, -4, -8)
	];
	this.$escortPatterns["trigon"] = [new Vector3D(-1, -0.5, 4.14),
		new Vector3D(1, -0.5, 4.14),
		new Vector3D(0, 1, 3),		
		new Vector3D(0, -1.5, 3),
		new Vector3D(3, 1.5, 2),
		new Vector3D(-3, 1.5, 2)
	];
	this.$escortPatterns["tetrahedron"] = [new Vector3D(-2, -0.83, 1.16), // 4 pos (tetrahedron), 8 pos (double-tetrahedron), 12-16 pos (swarm)
		new Vector3D(2, -0.83, 1.16),
		new Vector3D(0, -0.83, -2.31),		
		new Vector3D(0, 2.43, 0),
		new Vector3D(-2, 0.83, -1.16),
		new Vector3D(2, 0.83, -1.16),
		new Vector3D(0, 0.83, 2.31),		
		new Vector3D(0, -2.43, 0)
	];			
	this.$escortPatterns["vwide"] = [new Vector3D(4, 0, -4),
		new Vector3D(-4, 0, -4)
	];		
}

this.shipSpawned = function (ship) {
	if (!ship.script) return; // odd, but seems to happen occasionally
	if (ship.script.coordinatesForEscortPosition != Script.prototype.coordinatesForEscortPosition) {
		this.$debug(ship.displayName + " has escort coordinates already");
		return;
	} // already has some custom coordinates
	if (ship.script.$efr_pattern) {
		this.$debug(ship.displayName + " has $efr_pattern already");
		return;
	} // variable name conflict
	if (ship.script.$efr_timer) {
		this.$debug(ship.displayName + " has $efr_pattern already");
		return;
	} // variable name conflict
	var offensiveChance = 0;
	if (ship.primaryRole == "trader") {
		offensiveChance = 0.15;
	} else if (ship.primaryRole == "bigTrader" && ship.name != "Super Bulk Hauler") {
		offensiveChance = 0.15;
	} else if (ship.primaryRole == "liner" || ship.primaryRole == "coachwhip" || ship.primaryRole == "fuelship") { // from Transports OXP
		offensiveChance = 0.05;
	} else if (ship.primaryRole == "pirate") {
		offensiveChance = 0.75;
	} else if (ship.primaryRole == "police" || ship.primaryRole == "hunter") {
		offensiveChance = 0.9;
	} else {
		this.$debug(ship.displayName + " has no included role");
		return; // stock ships only
	}
	if (Math.random() < 0.10) {
		this.$debug("No escort change for " + ship.displayName);
		return;
	} // keep default formation

	// timer to allow escorts to be set up too
	if (Math.random() < offensiveChance) {
		ship.script.$efr_timer = new Timer(ship, function () {
			worldScripts["Escort Formations Randomiser"].$setupOffensiveEscorts(ship);
		}, 0.25);
	} else {
		ship.script.$efr_timer = new Timer(ship, function () {
			worldScripts["Escort Formations Randomiser"].$setupDefensiveEscorts(ship);
		}, 0.25);
	}
}

this.$setupOffensiveEscorts = function (ship) {
	var formations = new Array();
	if (!ship.escorts) {
		return; // no escorts
	} else if (ship.escorts.length <= 2) {
		formations.push("combat-spread", "echelon", "vform", "trail", "near-far", "trigon", "vwide");
	} else if (ship.escorts.length <= 4) {
		formations.push("combat-spread", "echelon", "arrowhead", "vform", "wave", "stack", "flank", "near-far", "trigon", "helix", "vwide");
	} else {
		formations.push("arrowhead", "vform", "wave", "stack", "flank", "trigon", "helix");
	}
	this.$setupEscortFormation(ship, formations[Math.floor(Math.random() * formations.length)]);
}

this.$setupDefensiveEscorts = function (ship) {
	var formations = new Array();
	if (!ship.escorts) {
		return; // no escorts
	} else if (ship.escorts.length <= 2) {
		formations.push("convoy", "vform", "scouting-spread", "screen", "near-far", "vwide");
	} else if (ship.escorts.length <= 4) {
		formations.push("planebox", "twistbox", "vform", "convoy", "screen", "opencolumn", "bulge", "near-far", "tetrahedron", "vwide");
	} else {
		formations.push("octahedron", "pyramid", "vform", "convoy", "tetrahedron", "bulge");
	}
	this.$setupEscortFormation(ship, formations[Math.floor(Math.random() * formations.length)]);
}

this.$setupEscortFormation = function (ship, formation) {
	ship.script.$efr_pattern = formation;
	ship.script.coordinatesForEscortPosition = function (index) {
		var positions = worldScripts["Escort Formations Randomiser"].$getEscortPositions(this.$efr_pattern);
		var layer = 1 + Math.floor(index / positions.length); 
		var component = index % positions.length;

		return positions[component].multiply(this.ship.collisionRadius * 5 * layer).add([0, 0, 7.5 * this.ship.collisionRadius]);
	}
	this.$debug(ship.displayName + " assigned formation: " + formation);
	ship.updateEscortFormation();
}

this.$getEscortPositions = function (pattern) {
	if (this.$escortPatterns[pattern]) { return this.$escortPatterns[pattern];
	} else { return this.$escortPatterns["vform"]; }
}

this.$debug = function (msg) {
	//log(this.name,msg);
}