Back to Index Page generated: Nov 12, 2024, 11:02:04 PM

Expansion Spicy hermits

Content

Warnings

  1. http://wiki.alioth.net/index.php/Spicy%20hermits -> 404 Not Found
  2. Information URL mismatch between OXP Manifest and Expansion Manager string length at character position 0

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Spices rock hermits to better fit their core roles by modifying their behavior and markets. Adds abandoned hermits to the game. Spices rock hermits to better fit their core roles by modifying their behavior and markets. Adds abandoned hermits to the game.
Identifier oolite.oxp.spara.spicy_hermits oolite.oxp.spara.spicy_hermits
Title Spicy hermits Spicy hermits
Category Mechanics Mechanics
Author Mika Spara Mika Spara
Version 1.0.3 1.0.3
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL n/a
Download URL https://wiki.alioth.net/img_auth.php/5/58/Spicy_hermits_1.0.3.oxz n/a
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1610873302

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/

Equipment

This expansion declares no equipment. This may be related to warnings.

Ships

Name
Abandoned Rock Hermit
spicy_hermits_abandoned_dock
spicy_hermits_abandoned_dock_griff
spicy_hermits_abandoned_door
Abandoned Rock Hermit
spicy_hermits_abandoned_tunnel_extras
spicy_hermits_abandoned_tunnel_extras_griff

Models

This expansion declares no models. This may be related to warnings.

Scripts

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));
		}
	}
}