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

Expansion Harder Hermits

Content

Warnings

  1. License not specified
  2. No version in dependency reference to oolite.oxp.spara.spicy_hermits:null
  3. Optional Expansions mismatch between OXP Manifest and Expansion Manager at character position 0064 (DIGIT ZERO vs LATIN SMALL LETTER N)
  4. Unknown key 'upload_date' at https://wiki.alioth.net/img_auth.php/5/54/Oolite.oxp.UK_Eliter.HarderHermits.oxz!manifest.plist

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description This expansion packs (further) toughens up some rock hermits. This expansion packs (further) toughens up some rock hermits.
Identifier oolite.oxp.UK_Eliter.HarderHermits oolite.oxp.UK_Eliter.HarderHermits
Title Harder Hermits Harder Hermits
Category Mechanics Mechanics
Author UK_Eliter UK_Eliter
Version 1.22 1.22
Tags dockables mechanics hard hermit dockables mechanics hard hermit
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
  • oolite.oxp.spara.spicy_hermits:0
  • oolite.oxp.spara.spicy_hermits:
  • Conflict Expansions
    Information URL http://www.aegidian.org/bb/viewtopic.php?f=4&t=20802 n/a
    Download URL https://wiki.alioth.net/img_auth.php/5/54/Oolite.oxp.UK_Eliter.HarderHermits.oxz http://wiki.alioth.net/img_auth.php/5/54/Oolite.oxp.UK_Eliter.HarderHermits.oxz
    License
    File Size n/a
    Upload date 1646067191

    Documentation

    Also read http://wiki.alioth.net/index.php/Harder%20Hermits

    Readme & License.txt

        __  __               __             __  __                    _ __
       / / / /___ __________/ /__  _____   / / / /__  _________ ___  (_) /______
      / /_/ / __ `/ ___/ __  / _ \/ ___/  / /_/ / _ \/ ___/ __ `__ \/ / __/ ___/
     / __  / /_/ / /  / /_/ /  __/ /     / __  /  __/ /  / / / / / / / /_(__  )
    /_/ /_/\__,_/_/   \__,_/\___/_/     /_/ /_/\___/_/  /_/ /_/ /_/_/\__/____/
    
    
    An expansion pack for Oolite
    
    by 'UK_Eliter'
    
    
    
    ------------
    REQUIREMENTS
    ------------
    
    � This expansion pack requires Oolite version *1.82* or above.
    
    -------
    PURPOSE
    -------
    
    This expansion packs toughens up some rock hermits - or, toughens them *further* if some other pack already makes them harder.
    
    
    ---------------------------------
    RECOMMENDED OTHER EXPANSION PACKS
    ---------------------------------
    
    � This expansion pack is compatible with, and is best used with, 'Spicy Hermits' by Spara.
    
    � Also, to add more types of defence ships for the hermits, install, in addition to HarderHermits, these OXPs of mine:
    	- Super Sidewinder
    	- Fer-de-Lance 3G
    
    
    -------
    LICENSE
    -------
    
    This expansion pack is released under the Creative Commons Attribution - Non-Commercial - Share Alike 3.0 license. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/ or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. 
    
    You are free:
    
    � to copy, distribute, display, and perform the work;
    � to make derivative works. 
    
    But only under the following conditions.
    
    � Attribution: you must give the original author credit. 
    � Non-commercial use: you may not use this work for commercial purposes. 
    � Share Alike: if you alter, transform, or build upon this work, you may distribute the resulting work only under a license materially identical to this one. 
    
    Your fair use right and other rights are in no way affected by the above.
    
    
    ----------------
    ACKNOWLEDGEMENTS
    ----------------
    
    My thanks to the following:
    
    	- spara (who wrote 'Spicy Hermits', which is much more ambitious than this my OXP);
    	- dybal (for encouragement and suggestions).
    
    
    ------------------------------
    NOTE FOR EXPANSION PACK MAKERS
    ------------------------------
    
    This expansion pack works mainly in the following way. It uses the this.shipExitedWitchspace handler. When Oolite sends my code a message that that handler has fired, my code seeks entities with rock-hermit roles and then (sometimes) does things to (some of) them.
    
    
    ----------------- END OF FILE ----------------- 
    

    Equipment

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

    Ships

    Name
    Abandoned Rock Hermit

    Models

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

    Scripts

    Path
    Scripts/harderHermits.js
    /*
    ========================================================================
    harderHermits.js
    This file is part of the Harder Hermits expansion pack.
    Author: UK_Eliter
    License: 2017 Creative Commons: attribution, non-commercial, sharealike.
    ========================================================================
    */
    
    
    
    /*
    ===================
    JSHINT: set options
    ===================
    */
    
    /*jshint esversion: 6*/
    /*jshint sub:true*/
    
    // Needs oolite >=1.82 (or, er, higher?)
    
    /*
     */
    
    this.name = "harderHermits"; // should be 'harderHermits.js'?
    this.author = "UK_Eliter";
    this.copyright = "See the license field";
    this.description = "harderHermits.js";
    this.license = "2014 CC-by-nc-sa 3.0";
    
    
    /*
    ==================
    DEBUGGING SWITCHES
    ==================
    */
    
    // this.logging = true;
    
    //	Do NOT comment-out any of the following three assignments. Rather, to disable any one of them, set it to false.
    var consoleDebugMessages = false;
    
    this.debug = false;
    
    this.debug_testResurrection = false;
    //	Requires this.debug to be true, but does not *make* that variable true,
    
    
    /*
    ========================
    JSLINT: start of wrapper
    ========================
    */
    
    (function() {
    
    	"use strict";
    
    
    	/*
    	=======
    	GLOBALS
    	=======
    	*/
    
    	this.name = "harderHermits";
    
    	this.abandoned_chanceAct = 0.15;
    	//	0.15
    
    	this.installed_spicyHermits = false;
    	//	Gets changed to true if the OXP is installed.
    	this.installed_hermitage = false;
    	//	Gets changed to true if the OXP is installed.
    	this.installed_pirateCove = false;
    	//	Gets changed to true if the OXP is installed.
    
    
    	/*
    	=========
    	DEBUGGING
    	=========
    	*/
    
    	this.$msg_dbg = function(debugTxt) {
    		if (!debugTxt) {
    			player.consoleMessage("Problem with debug message text!", 30);
    			return;
    		}
    		player.consoleMessage(this.name + " - " + debugTxt, 12);
    		log(this.name + " - DEBUG", debugTxt);
    	};
    
    	this.$msg_info = function(msgTxt) {
    		// if( !msgTxt ) { player.consoleMessage( "Problem with info message text!", 30 ); return; }
    		log(this.name + " - INFO", msgTxt);
    	};
    
    
    	/*
    	================
    	SOUNDS
    	================
    	*/
    
    	this.mySound_hullBang = new SoundSource();
    	this.mySound_hullBang.sound = "hullbang.ogg";
    	// this sound built-in to Oolite - and does not need to be declared in the 'customsounds' file.
    
    
    	/*
    	================
    	ENTITY PICKER(S)
    	================
    
    	The following roles are from Oolite itself:
    
    		rockhermit
    		rockhermit-chaotic
    		rock-hermit-pirate
    
    	The following role is from SpicyHermits:
    
    		spicy_hermits_abandoned
    	*/
    
    	this.$isCove = function(e) {
    		return e.isShip && e.AI === "pirateCoveAI.plist";
    		// Seemingly there is no more efficient way of doing the above.
    	};
    
    	this.$isAbandonedHermit = function(e) {
    		return e.isShip && (e.primaryRole === "asteroid" && e.name === "Abandoned Rock Hermit");
    	};
    
    	this.$isHermit = function(e) {
    		return e.isShip &&
    			(e.primaryRole === "rockhermit" || e.primaryRole === "rockhermit-chaotic" || e.primaryRole === "rockhermit-pirate");
    	};
    
    	this.$isHermitButNotHermitage = function(e) {
    		return e.isShip &&
    			(e.primaryRole === "rockhermit" || e.primaryRole === "rockhermit-chaotic" || e.primaryRole === "rockhermit-pirate") &&
    			!e.hasRole("hermitage");
    	};
    
    
    	/*
    	======
    	TIMERS
    	======
    	*/
    
    	this.$timer_delete_hermitAction_warn = function() {
    		if (!this.timer_hermitAction_warn) {
    			return;
    		}
    		if (this.timer_hermitAction_warn.isRunning) {
    			this.timer_hermitAction_warn.stop();
    		}
    		delete this.timer_hermitAction_warn;
    	};
    
    	this.$timer_delete_hermitAction_warnThenExplode = function() {
    		if (!this.timer_hermitAction_warnThenExplode) {
    			return;
    		}
    		if (this.timer_hermitAction_warnThenExplode.isRunning) {
    			this.timer_hermitAction_warnThenExplode.stop();
    		}
    		delete this.timer_hermitAction_warnThenExplode;
    	};
    
    	this.$timer_delete_hermitAction_explode = function() {
    		if (!this.timer_hermitAction_explode) {
    			return;
    		}
    		if (this.timer_hermitAction_explode.isRunning) {
    			this.timer_hermitAction_explode.stop();
    		}
    		delete this.timer_hermitAction_explode;
    	};
    
    	this.$timer_delete_hermitAction_resurrect = function() {
    		if (!this.timer_hermitAction_resurrect) {
    			return;
    		}
    		if (this.timer_hermitAction_resurrect.isRunning) {
    			this.timer_hermitAction_resurrect.stop();
    		}
    		delete this.timer_hermitAction_resurrect;
    	};
    
    	this.$timer_delete_die = function() {
    		if (!this.timer_die) {
    			return;
    		}
    		if (this.timer_die.isRunning) {
    			this.timer_die.stop();
    		}
    		delete this.timer_die;
    	};
    
    	this.$timer_delete_treatHermits_coves = function() {
    		if (!this.timer_treatHermits_coves) {
    			return;
    		}
    		if (this.timer_treatHermits_coves.isRunning) {
    			this.timer_treatHermits_coves.stop();
    		}
    		delete this.timer_treatHermits_coves;
    	};
    
    	this.$timer_delete_all = function() {
    		this.$timer_delete_die();
    		this.$timer_delete_treatHermits_coves();
    		this.$timer_delete_hermitAction_resurrect();
    		this.$timer_delete_hermitAction_warn();
    		this.$timer_delete_hermitAction_warnThenExplode();
    		this.$timer_delete_hermitAction_explode();
    		if (this.abandonedHermit) {
    			delete this.abandonedHermit;
    		}
    	};
    
    
    	/*
    	===============
    	TIMED FUNCTIONS
    	===============
    	*/
    
    	this.$treatHermits_coves = function() {
    		var s = system.filteredEntities(this, this.$isCove);
    
    		if (this.debug) {
    			// DEBUGGING version
    			if (s.length === 0) {
    				this.$msg_dbg("Seeking coves: none found.");
    				return;
    			}
    			this.$msg_dbg("Seeking coves: at least one found ..");
    			this.$treatHermits_core(s);
    			return;
    		}
    
    		// NON-DEBUGGING VERSION
    		if (s.length === 0) {
    			return;
    		}
    		this.$treatHermits_core(s);
    	};
    
    	this.$die_timed = function $die_timed() {
    		// The above format, with its repetition of the function name, is right. See http://aegidian.org/bb/viewtopic.php?p=257147#p257147.
    		this.$timer_delete_die();
    		// Do not automatically delete it, because it might not be running; other things can call this.
    		if (!player.ship) {
    			return;
    		}
    		// Next two lines are to avoid auto-eject shenanigans, etc.
    		if (player.ship.equipmentStatus("EQ_AUTO_EJECT") === "EQUIPMENT_OK") {
    			player.ship.removeEquipment("EQ_AUTO_EJECT");
    		}
    		if (player.ship.equipmentStatus("EQ_EEU") === "EQUIPMENT_OK") {
    			player.ship.removeEquipment("EQ_EEU");
    		}
    		player.ship.explode();
    	};
    
    	this.$timed_hermitAction_message_warn = function(e) {
    		if (!e || !e.isValid) {
    			return;
    		}
    		e.commsMessage("WARNING: This station will explode. Clear the area.");
    		e.broadcastCascadeImminent();
    	};
    
    	this.$timed_hermitAction_warn = function() {
    		if (this.debug) {
    			this.$msg_dbg("timed_hermitAction_warn.");
    		}
    		this.$timer_delete_hermitAction_warn();
    		if (!this.abandonedHermit) {
    			return;
    		}
    		if (!this.abandonedHermit.isValid) {
    			delete this.abandonedHermit;
    			return;
    		}
    		var e = this.abandonedHermit;
    		this.$timed_hermitAction_message_warn(e);
    	};
    
    	this.$timed_hermitAction_warnThenExplode = function() {
    		if (this.debug) {
    			this.$msg_dbg("timed_hermitAction_warnThenExplode.");
    		}
    		this.$timer_delete_hermitAction_warnThenExplode();
    		if (!this.abandonedHermit) {
    			return;
    		}
    		if (!this.abandonedHermit.isValid) {
    			delete this.abandonedHermit;
    			return;
    		}
    		this.$timed_hermitAction_message_warn(this.abandonedHermit);
    		var seconds = ~~((Math.random() * 60) + 0.5); // * 60
    		this.timer_hermitAction_explode = new Timer(this, this.$timed_hermitAction_explode, seconds);
    	};
    
    	this.$timed_hermitAction_explode = function() {
    		if (this.debug) {
    			this.$msg_dbg("timed_hermitAction_explode.");
    		}
    		this.$timer_delete_hermitAction_explode();
    		if (!this.abandonedHermit) {
    			return;
    		}
    		if (!this.abandonedHermit.isValid) {
    			delete this.abandonedHermit;
    			return;
    		}
    		this.abandonedHermit.explode();
    		// NB SpicyHermits occasionally adds a q-mine death action!
    		delete this.abandonedHermit;
    	};
    
    	this.$timed_hermitAction_resurrect = function() {
    		if (this.debug) {
    			this.$msg_dbg("timed_hermitAction_resurrect.");
    		}
    		this.$timer_delete_hermitAction_resurrect();
    		if (!this.abandonedHermit) {
    			return;
    		}
    		if (!this.abandonedHermit.isValid) {
    			delete this.abandonedHermit;
    			return;
    		}
    
    		// We have to *replace* the hermit (otherwise it cannot be a station).
    		// If the hermit is close enough to the player to notice the change, abort.
    		if (!player.ship || !player.ship.position) {
    			delete this.abandonedHermit;
    			return;
    		}
    		var ps = player.ship; // for speed, but changes won't affect the original variable
    		if (this.abandonedHermit.position.distanceTo(ps.position) < 50000) {
    			if (this.debug) {
    				this.$msg_dbg("Hermit too close to player for resurrection.");
    			}
    			delete this.abandonedHermit;
    			return;
    		}
    
    		// Get data for the replacement.
    		var orientation = this.abandonedHermit.orientation;
    		var position = this.abandonedHermit.position;
    
    		if (this.abandonedHermit) {
    			this.abandonedHermit.remove(true);
    			delete this.abandonedHermit;
    		}
    
    		// Do the replacement.
    		// Note that Spicy Hermits overrides Oolite's rockhermit shipdata, so what we'll get here is 'spicy' stuff.
    
    		var replacement;
    		replacement = system.addShips("harderHermits_resurrected", 1, position);
    
    		// this.replacement = this.abandonedHermit.spawnOne( "harderHermits_resurrected" );
    
    		if (replacement[0] && replacement[0].isValid) {
    			if (this.debug) {
    				this.$msg_dbg("Created replacement.");
    			}
    			// this.replacement.orientation = this.abandonedHermit.orientation; 
    			// this.replacement.position = this.abandonedHermit.position;
    			replacement[0].orientation = orientation;
    			replacement[0].lightsActive = false;
    			replacement[0].desiredRange = 13000; // Tested?
    			if (this.debug) {
    				replacement[0].displayName = "Abandoned rock hermit (RESURRECTED)";
    			}
    			// Energy
    			var r = Math.random();
    			replacement[0].maxEnergy *= (r + 1.5);
    		} else if (this.debug) {
    			this.$msg_dbg("Replacement failed to exist.");
    		}
    	};
    
    
    	/*
    	==============
    	EVENT HANDLERS
    	==============
    	*/
    
    	this.startUp = function() {
    		if (this.debug) {
    			this.$msg_dbg("DEBUGGING is ON.");
    			if (this.debug_testResurrection) {
    				this.$msg_dbg("Testing resurrection.");
    			}
    		}
    
    		if (worldScripts["Hermitage_Main"]) {
    			// Hermitage_Main is the name the script itself declares.
    			// Yet, that script's *filename* is hermitage_main.js.
    			this.installed_spicyHermits = true;
    			this.$msg_info("Detected hermitage OXP");
    		}
    		if (worldScripts["spicy_hermits_abandoned"]) {
    			this.installed_spicyHermits = true;
    			this.$msg_info("Detected SpicyHermits OXP");
    		}
    		if (worldScripts["Pirate_Coves"]) {
    			this.installed_pirateCove = true;
    			this.$msg_info("Detected pirateCove OXP.");
    		}
    	};
    
    	this.shipDockedWithStation = function(station) {
    		if (!player.ship.docked || player.ship.dockedStation.name !== "Abandoned Rock Hermit") {
    			return;
    		}
    
    		// Unmodified abandoned hermits from SpicyHermits do not allow the player to dock (at all), so this routine won't fire for that.
    		this.showScreen = "rejectPage";
    		mission.runScreen({
    				title: "Abandoned Rock Hermit (well, not really abandoned)",
    				color: "redColor",
    				message: "You have docked at a disguised pirate cove.\n\nNine out of ten for style, but minus several thousand for good thinking.",
    				model: "rockhermit",
    				choicesKey: "harderHermits_docked"
    			},
    			function(choice) {
    				if (choice === "1_RETURN") {
    					var r = Math.random();
    					// r = 0.1; // TESTING
    					if (r < 0.2) {
    						player.commsMessage("The pirates attack your launching ship!");
    						player.ship.launch();
    						if (!this.timer_die) {
    							this.timer_die = new Timer(this, this.$die_timed, 1.7);
    						}
    						this.mySound_hullBang.play();
    					} else if (r < 0.8) {
    						var d = 40 + ~~((Math.random() * 500) + 1);
    						player.commsMessage("The pirates attack your launching ship!");
    						player.ship.launch();
    						player.ship.energy = player.ship.energy - d;
    						if (player.ship.energy < 0) {
    							if (!this.timer_die) {
    								this.timer_die = new Timer(this, this.$die_timed, 1.7);
    							}
    						} else {
    							this.mySound_hullBang.play();
    						}
    					}
    					station.reactToAIMessage("ATTACKED");
    				}
    			}
    		);
    	};
    
    	this.playerWillEnterWitchspace = function() {
    		this.$timer_delete_all();
    	};
    
    	this.shipExitedWitchspace = function() {
    		if (system.isInterstellarSpace) {
    			return;
    		}
    		if (this.debug) {
    			this.$msg_dbg("shipExitedWitchspace");
    		}
    
    		this.$treatHermits_normalAndSpicy();
    
    		if (this.installed_spicyHermits) {
    			this.$treatHermits_spicy_abandoned();
    		}
    
    		if (this.installed_pirateCove) {
    			// PirateCoves adds hermits upon shipExitedWitchspace
    			this.timer_$treatHermits_coves = new Timer(this, this.$treatHermits_coves, 1);
    			if (this.debug) {
    				this.$msg_dbg("Set timer to seek coves.");
    			}
    		}
    	};
    
    
    	/*
    	=======================
    	OTHER
    	=======================
    	*/
    
    	this.$treatHermits_core = function(s) {
    		var i;
    		var debugStr;
    		var energyToAdd;
    
    		/*
    		Adjust energy of all hermits detected. Those hermits comprise:
    		- all hermits added by the core game;
    		- hermits added by the SpicyHermits OXP (er, I think);
    		- hermits added by the PirateCove OXP (which get added on Witchspace exit and so are detected within this function only when it is run on a timer.
    
    		SpicyHermits gives pirate rock-hermits a maxEnergy of 2500.
    		SpicyHermits leaves the maxEnergy of other types alone, i.e. at Oolite default, which is 1,000.
    		(SpicyHermits saves the position of its hermits but anything else - including their maxEnergy - about them.
    		We will not try to save that, either.)
    		*/
    
    		i = s.length;
    		if (this.debug) {
    			// * Debugging version *
    			debugStr = "Hermits: iterating through <" + i + "> found ..";
    			this.$msg_dbg(debugStr);
    			while (i--) {
    				if (!s[i] || !s[i].isValid) {
    					continue;
    				}
    				debugStr = ".. Rock hermit <" + s[i].displayName + "> HAD energy " + s[i].maxEnergy;
    				this.$msg_dbg(debugStr);
    				if (s[i].maxEnergy === 1000) {
    					energyToAdd = Math.ceil(Math.random() * 1499);
    				} else if (s[i].maxEnergy === 2500) {
    					energyToAdd = Math.ceil(Math.random() * 180);
    				}
    				s[i].maxEnergy += energyToAdd;
    				debugStr = ".. Rock hermit <" + s[i].displayName + ">: added <" + energyToAdd + ">; NOW HAS energy " + s[i].maxEnergy;
    				this.$msg_dbg(debugStr);
    			}
    		} else {
    			// * NON-debugging version *
    			while (i--) {
    				if (!s[i] || !s[i].isValid) {
    					continue;
    				}
    				if (s[i].maxEnergy === 1000) {
    					energyToAdd = Math.ceil(Math.random() * 1499);
    				} else if (s[i].maxEnergy === 2500) {
    					energyToAdd = Math.ceil(Math.random() * 180);
    				}
    				s[i].maxEnergy += energyToAdd;
    			}
    		}
    	};
    
    	this.$treatHermits_spicy_abandoned = function() {
    		if (!this.debug && !this.debug_testResurrection) {
    			if (Math.random() > this.abandoned_chanceAct) {
    				if (this.debug) {
    					this.$msg_dbg("Abandoned hermits: decided to ignore.");
    				}
    				return;
    			}
    		}
    
    		var action, debugStr, i, r, s, seconds;
    
    		if (this.debug) {
    			// DEBUGGING version
    			this.$msg_dbg("Abandoned hermits: seeking ..");
    			s = system.filteredEntities(this, this.$isAbandonedHermit);
    			if (s.length < 1) {
    				this.$msg_dbg(".. found no abandoned hermits.");
    				return;
    			}
    			this.$msg_dbg(".. found at least one abandoned hermit.");
    			// Pick one of them.
    			i = ~~(Math.random() * s.length);
    			// Check there is nothing fundamentally wrong with it.
    			if (!(s[i] && s[i].isValid)) {
    				this.$msg_dbg("Invalid abandoned hermit selected.");
    				return;
    			}
    			this.abandonedHermit = s[i];
    			if (this.debug_testResurrection) {
    				action = "resurrect";
    				seconds = 5;
    				this.timer_hermitAction_resurrect = new Timer(this, this.$timed_hermitAction_resurrect, seconds);
    			} else {
    				seconds = ~~((Math.random() * 10800) + 1) + 5; // * 10800 + 5
    				r = Math.random();
    				if (r < 0.7) {
    					action = "warn-then-explode";
    					this.timer_hermitAction_warnThenExplode = new Timer(this, this.$timed_hermitAction_warnThenExplode, seconds);
    				} else if (r < 0.75) {
    					action = "warn";
    					this.timer_warn = new Timer(this, this.$timed_hermitAction_warn, seconds);
    				} else if (r < 0.8) {
    					action = "explode";
    					this.timer_hermitAction_explode = new Timer(this, this.$timed_hermitAction_explode, seconds);
    				} else {
    					action = "resurrect";
    					this.timer_hermitAction_resurrect = new Timer(this, this.$timed_hermitAction_resurrect, seconds);
    				}
    			}
    			s[i].displayName = "Abandoned Rock Hermit (TWEAKED)";
    			debugStr = ".. Primed abandoned hermit <" + this.abandonedHermit.displayName + "> to <" + action + "> in " + seconds + " seconds time.";
    			this.$msg_dbg(debugStr);
    		} else {
    			// NON-DEBUGGING version
    			s = system.filteredEntities(this, this.$isAbandonedHermit);
    			if (s.length < 1) {
    				return;
    			}
    			i = ~~(Math.random() * s.length);
    			if (!(s[i] && s[i].isValid)) {
    				return;
    			}
    			this.abandonedHermit = s[i];
    			seconds = ~~((Math.random() * 10800) + 1) + 5; // * 10800 + 5
    			r = Math.random();
    			if (r < 0.7) {
    				this.timer_hermitAction_warnThenExplode = new Timer(this, this.$timed_hermitAction_warnThenExplode, seconds);
    			} else if (r < 0.75) {
    				this.timer_warn = new Timer(this, this.$timed_hermitAction_warn, seconds);
    			} else if (r < 0.8) {
    				this.timer_hermitAction_explode = new Timer(this, this.$timed_hermitAction_explode, seconds);
    			} else {
    				this.timer_hermitAction_resurrect = new Timer(this, this.$timed_hermitAction_resurrect, seconds);
    			}
    		}
    	};
    
    	this.$treatHermits_normalAndSpicy = function() {
    		var s;
    		if (this.installed_hermitage) {
    			s = system.filteredEntities(this, this.$isHermitButNotHermitage);
    		} else {
    			s = system.filteredEntities(this, this.$isHermit);
    		}
    
    		if (this.debug) {
    			// DEBUGGING version
    			if (s.length === 0) {
    				this.$msg_dbg("Seeking normal and spicy hermits: none found.");
    				return;
    			}
    			this.$msg_dbg("Seeking normal and spicy hermits ..");
    			this.$treatHermits_core(s);
    			return;
    		}
    
    		// NON-DEBUGGING VERSION
    		if (s.length > 0) {
    			this.$treatHermits_core(s);
    		}
    	};
    
    	/*
    	=======================
    	JSHINT: end of wrapper
    	=======================
    	*/
    
    }).call(this);
    
    
    // EOF