Documentation
readme.txt
Spicy Hermits OXP ver 1.0.3 (28.01.2016)
Author: spara (Mika SpÄra)
_Overview_
The core hermits might be considered to be a bit bland. This oxp spices them up a bit.
_Permanency_
The core hermits are practically permanent. You can destroy one, but when you re-enter the system, it's back. This oxp changes that. If a hermit gets destructed, it won't reappear again in a same place.
_Abandoned hermits_
Sometimes hermits are abandoned. Lights are turned off, the dock is sealed and they are just left out there rotating alone orbiting the planet. Often these have been used as pirate/smuggler caches and sometimes stuff is just left behind. Find them, destroy them and see if something has been left for you to salvage.
_Characterization_
Three types of hermit exist in the core game with different allegiances and slightly different markets. This oxp emphasizes that characterization by altering markets and hermit behavior to better match the following roles:
Mining bases
* Small scale mining operations happen here. Mining products for sale and it's possible to do some mining around the hermit and sell extracted minerals to the hermit. Fuel and basic missiles for sale.
Smugglers' dens
* Small scale mining operations and small scale unofficial trading happen here. A small market with no legal restrictions. Some mining products and restricted goods usually for sale. The station is protected by a couple of hired goons that patrol the hermit. Goons only react, if the hermit or themselves are provoked. Be vary, the visitors of this place are from both sides of the law. Fuel and basic missiles for sale.
Pirate havens
* This hermit has been overrun by pirates, that now hang around the station and keep it as their base. Be ready to defend yourself, if you dare to approach this station. Offers high tech ship maintenance and a selection of high level equipment popular amongst pirates for sale at premium prices. A small market is filled with fruits of piracy. This is a rare hermit type, that can only be found from the most unstable systems.
_Credits_
* Big thank you to Cody, Fritz and others who helped by testing and providing invaluable comments and suggestions.
------
This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 4.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/
Path |
Scripts/spicy_hermits_abandoned.js |
"use strict";
this.name = "spicy_hermits_abandoned";
this.description = "abandoned hermit populator";
this.startUp = function() {
//check for griffs hermits
if (!Ship.keysForRole("griff_hermit_subentity")) {
this.$role = "spicy_hermits_abandoned";
}
else this.$role = "spicy_hermits_abandoned_griff";
}
this.systemWillPopulate = function() {
var count = 1 + Math.round(Math.random() * 2); //1-3 hermits. weighted at 2.
//var regions = ["PLANET_ORBIT_HIGH", "STAR_ORBIT_HIGH", "OUTER_SYSTEM_OFFPLANE", "INNER_SYSTEM_OFFPLANE"];
for (var i = 0; i < count; i++) {
//var region = regions[Math.floor(Math.random() * regions.length)];
system.setPopulator("spicy_hermits_abandoned" + i, {
callback: function(pos) {
var hermit = system.addShips(this.$role, 1, pos)[0];
//spawn 2-5 asteroids to help finding
system.addShips("asteroid", 2 + Math.floor(Math.random() * 4), pos, 25E3);
}.bind(this),
location: "PLANET_ORBIT_HIGH"/*region*/
})
}
}
|
Scripts/spicy_hermits_abandoned_ship.js |
"use strict";
this.name = "spicy_hermits_abandoned_ship";
this.description = "ship script for abandoned hermits";
this.shipSpawned = function() {
ship.primaryRole = "asteroid";
}
this.shipDied = function() {
//create 1 - 15 random cargo pods biasing average
var count = 1 + Math.floor(5 * (Math.random() + Math.random() + Math.random()));
var pods = system.addShips("cargopod", count, ship.position);
//give the pods some velocity
for (var i = 0; i < pods.length; i++) {
var pod = pods[i];
var velocity = pod.position.subtract(ship.position).direction().multiply(100);
pod.velocity = velocity;
}
//create 2 - 4 boulders
var count = 2 + Math.floor(Math.random() * 3);
ship.spawn("boulder", count);
//rarely boobytrapped
for (var i = 0; i < 2; i++) {
if (Math.random() < 0.05) {
var qbomb = ship.spawnOne("energy-bomb");
qbomb.AIScript.shipWasDumped();
}
}
}
|
Scripts/spicy_hermits_relocator.js |
"use strict";
this.name = "spicy_hermits_relocator";
this.startUp = function() {
if (missionVariables["spicy_hermits"]) {
this.$movedHermits = JSON.parse(missionVariables["spicy_hermits"]);
}
else this.$movedHermits = new Object();
}
//save relocated hermits
this.playerWillSaveGame = function() {
if (this.$movedHermits) {
missionVariables["spicy_hermits"] = JSON.stringify(this.$movedHermits);
}
}
this.systemWillPopulate = function() {
var currentSystem = this._getCurrentSystemData();
if (currentSystem) {
//create as many populators as needed.
for (var i = 0; i < currentSystem.length; i++) {
system.setPopulator("spicy_hermits" + i, {
callback: function(pos) {
//i like to move it, move it
var origPosition = this._toVect(this._getCurrentSystemData()[this.$hermitPointer][0]);
var offset = pos.subtract(origPosition);
//since we only know the position and we need an entity to focus on, let's create a dummy one.
var positionEntity = system.addVisualEffect("spicy_hermits_dummy", origPosition);
var hermitage = system.entitiesWithScanClass("CLASS_ROCK", positionEntity, 1E3);
for (var i = 0; i < hermitage.length; i++) {
//identify, move and tag the hermit
if (hermitage[i].isStation) {
var hermit = hermitage[i];
hermit.position = hermit.position.add(offset);
hermit.spicy_hermits_original_position = origPosition;
//add an asteroid field, using core rule
var size = 1 + Math.floor(system.scrambledPseudoRandomNumber(Math.floor(pos.x)) * 11);
var rocks = system.addShips("asteroid", size, hermit.position, 25E3);
}
}
//remove the position marker and advance the hermit pointer
positionEntity.remove();
this.$hermitPointer++;
}.bind(this),
location: "LANE_WPS",
locationSeed: currentSystem[i][1]
})
}
}
this.$hermitPointer = 0;
}
//public function for hermit AIs to report death.
this._reportDeath = function(origPosition) {
//create a new location seed
var newSeed = 10000 + Math.floor(Math.random() * 90000);
var dataElement = [origPosition, newSeed];
//get and if needed init current system stored data
var currentSystemData = this._getAndInitCurrentSystemData();
//see if there's already an entry for this hermit
//if yes, update entry
var newHermit = true;
for (var i = 0; i < currentSystemData.length; i++) {
if (this._toVect(currentSystemData[i][0]).subtract(origPosition).magnitude() === 0) {
currentSystemData[i] = dataElement;
newHermit = false;
break;
}
}
//if not, create a new entry
if (newHermit) currentSystemData.push(dataElement);
}
//it seems that position vector gets converted to a generic object on save/load. this converts it back to vector.
this._toVect = function(storedObj) {
var vect = new Vector3D();
vect.x = storedObj.x;
vect.y = storedObj.y;
vect.z = storedObj.z;
return vect;
}
//get current system stored data
this._getCurrentSystemData = function() {
if (!this.$movedHermits[galaxyNumber]) return([]);
if (!this.$movedHermits[galaxyNumber][system.ID]) return([]);
return this.$movedHermits[galaxyNumber][system.ID];
}
//get current system stored data and init new entries
this._getAndInitCurrentSystemData = function() {
if (!this.$movedHermits[galaxyNumber]) {
this.$movedHermits[galaxyNumber] = new Object();
}
if (!this.$movedHermits[galaxyNumber][system.ID]) {
this.$movedHermits[galaxyNumber][system.ID] = new Array();
}
return this.$movedHermits[galaxyNumber][system.ID];
}
|
Scripts/spicy_hermits_ship_script.js |
"use strict";
this.name = "spicy_hermits_ship_script";
this.shipSpawned = function() {
this.$locatorWS = worldScripts["spicy_hermits_relocator"];
//spawn a couple of grunts around the smuggler version
if (ship.primaryRole === "rockhermit-chaotic") {
var count = 1 + Math.floor(Math.random() * 3);
var patrol = system.addShips("pirate", count, ship.position, 25E3);
for (var i = 0; i < patrol.length; i++) {
ship.group.addShip(patrol[i]);
patrol[i].group = ship.group;
patrol[i].switchAI("spicy_hermits-gruntAI.js");
//these are some small time criminals with small bounties on their heads
patrol[i].bounty = 5 + Math.round(Math.random() * 10);
//upgrade weapon, if needed.
if (patrol[i].forwardWeapon === "EQ_WEAPON_PULSE_LASER") {
patrol[i].forwardWeapon = "EQ_WEAPON_BEAM_LASER";
}
}
}
//spawn a leader and a few pirates around the pirate version
if (ship.primaryRole === "rockhermit-pirate") {
var leader = system.addShips("pirate-heavy-fighter", 1, ship.position, 25E3)[0];
//upgrade weapon, if needed.
if (leader.forwardWeapon === "EQ_WEAPON_PULSE_LASER") {
leader.forwardWeapon = "EQ_WEAPON_BEAM_LASER";
}
ship.group.addShip(leader);
leader.group = ship.group;
ship.group.leader = leader;
leader.switchAI("spicy_hermits-pirateAI.js");
var count = 3 + Math.floor(Math.random() * 2);
var patrol = system.addShips("pirate", count, ship.position, 25E3);
for (var i = 0; i < patrol.length; i++) {
//upgrade weapon, if needed.
if (patrol[i].forwardWeapon === "EQ_WEAPON_PULSE_LASER") {
patrol[i].forwardWeapon = "EQ_WEAPON_BEAM_LASER";
}
ship.group.addShip(patrol[i]);
patrol[i].group = ship.group;
patrol[i].switchAI("spicy_hermits-pirateAI.js");
}
}
}
this.shipDied = function() {
//relocator hook
if (this.$locatorWS) {
if (ship.spicy_hermits_original_position) {
this.$locatorWS._reportDeath(ship.spicy_hermits_original_position);
}
else {
this.$locatorWS._reportDeath(ship.position);
}
}
//create 1 - 5 random cargo pods upon death
var count = 1 + Math.floor(Math.random() * 6);
var pods = ship.spawn("cargopod", count);
//destruct pods with non-suitable content.
if (ship.primaryRole === "rockhermit") {
var suitableContents = ["radioactives", "minerals", "gold", "platinum", "gem_stones"];
}
else if (ship.primaryRole === "rockhermit-chaotic") {
var suitableContents = ["radioactives", "minerals", "gold", "platinum", "gem_stones", "narcotics", "firearms", "slaves"];
}
else var suitableContents = null;
if (suitableContents) {
for (var i = 0; i < pods.length; i++) {
if (suitableContents.indexOf(pods[i].commodity) === -1) {
pods[i].explode();
}
}
}
//pirate hermits are sometimes boobytrapped
if (ship.primaryRole === "rockhermit-pirate" && Math.random() < 0.1) {
var qbomb = ship.spawnOne("energy-bomb");
qbomb.AIScript.shipWasDumped();
}
}
this.shipBeingAttacked = function(whom) {
//order those hardheaded morons to stop firing at the base. On top of being lousy aimers, they also have wax in their ears, hence 33.4 % chance of not hearing the order.
if (whom.isPirate && Math.random() < 0.666) {
whom.performFlyToRangeFromDestination();
}
}
|
Scripts/spicy_hermits_star-jellies.js |
//Star-jellies from star-jellies OXP are spawned as asteroids and as such occasionally spawn close to hermits. Destruction of a star-jelly produces a cascading quirium explosion that takes care of the possible close by hermit too. This script pushes star-jellies, that are spawned in scanner range of a hermit, 25 km farther.
"use strict";
this.name = "spicy_hermits_star-jellies";
this.startUp = function() {
//check for star-jelly oxp
if (!Ship.keysForRole("star-jelly1")) {
delete this.startUpComplete;
delete this.shipExitedWitchspace;
}
}
//push star-jellies farther from hermits right after the populator.
this.startUpComplete = this.shipWillExitWitchspace = function() {
//find hermits
var hermitRoles = ["rockhermit", "rockhermit-chaotic", "rockhermit-pirate"];
var hermits = new Array();
for (var i = 0; i < hermitRoles.length; i++) {
hermits = hermits.concat(system.shipsWithRole(hermitRoles[i]));
}
//find jellies close to hermits and move them farther
var jellyRoles = ["star-jelly1", "star-jelly2", "star-jelly-egg", "star-jelly-larva"];
for (var i = 0; i < hermits.length; i++) {
var hermit = hermits[i];
var jellies = new Array();
for (var j = 0; j < jellyRoles.length; j++) {
jellies = jellies.concat(system.shipsWithRole(jellyRoles[j], hermit, 25E3));
}
var hermitPosition = hermit.position;
for (var j = 0; j < jellies.length; j++) {
var jelly = jellies[j];
var hjUnit = jelly.position.subtract(hermitPosition).direction();
jelly.position = hermitPosition.add(hjUnit.multiply(25E3));
}
}
}
|