Back to Index Page generated: Jun 13, 2026, 7:54:51 PM

Expansion NPB Neutralizer

Content

Warnings

  1. Syntax Error Config/shipdata-overrides.plist[1:0] mismatched input 'escape-capsule' expecting {'(', '{'}
  2. Found 1 issues in Config/shipdata-overrides.plist
  3. http://wiki.alioth.net/index.php/NPB%20Neutralizer -> 404 Not Found
  4. Low hanging fuit: Information URL exists...

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Galcop's Neutral Particle Beam weapon causes catastrophic internal damage - frying computers, disabling power, knocking out weapons and critical systems - while throwing off little energy as surface heat. A direct hit leaves the target a drifting hulk without triggering fatal explosions of fuel or ordinance. Galcop's Neutral Particle Beam weapon causes catastrophic internal damage - frying computers, disabling power, knocking out weapons and critical systems - while throwing off little energy as surface heat. A direct hit leaves the target a drifting hulk without triggering fatal explosions of fuel or ordinance.
Identifier oolite.oxp.Reval.Neutralizer oolite.oxp.Reval.Neutralizer
Title NPB Neutralizer NPB Neutralizer
Category Weapons Weapons
Author Reval Reval
Version 1.3 1.3
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Dependent Expansions
  • oolite.oxp.Reval.Tractor-Tow:1.1
  • Information URL https://wiki.alioth.net/index.php/NPB_Neutralizer_OXZ n/a
    Download URL https://wiki.alioth.net/img_auth.php/f/f7/Neutralizer.oxz https://wiki.alioth.net/img_auth.php/f/f7/Neutralizer.oxz
    License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
    File Size n/a
    Upload date 1779263364

    Relationships Diagram

    Documentation

    ReadMe.txt

    Category: Weapons
    
    NPB Neutralizer OXZ
    
    
    == Galcop's Open Secret ==
    
    Galcop reports that its Neutralizer NPB, now being retrofitted to Police Vipers and Viper Interceptors, is a '''Neutral Particle Beam''' weapon that works by accelerating hydrogen atoms to near-light speed and then neutralizing their charge. Upon hitting a target, the high-energy particles penetrate deep into a ship's structure, depositing their energy '''inside''' critical systems like electronics and power conduits.
    
    This causes '''catastrophic internal damage''' - frying computers, disabling power generation, and knocking out weapons, engines, and other critical systems - while throwing relatively little energy as surface heat. In complete contrast to the external burning and blasting effect of a conventional laser, the NPB leaves its target a '''powerless, drifting derelict''' without triggering fatal explosions in fuel supply or ordinance. 
    
    Such '''soft-kill''' capability, where the ship is disabled but intact, was a key factor and a spur to Galcop, whose Black Labs invested considerable time and resources into developing and perfecting it. 
    
    Because NPB <i>is</i> the perfect first-strike and last-resort enforcer. A sustained well-aimed burst can render the offending vessel essentially salvage. The resulting derelict, along with its surviving crew, can be boarded or towed back to Station for processing and penalties. No funerals (or not so many). Win-Win.
    
    Rights to mount NPB Neutralizers are granted under Galcop contract. Such a license is issued solely to members of the Police SDD-Network, along with permissions to deploy Ship Defence Drones (SDD). 
    
    It scarcely needs emphasizing that an applicant's legal record must be Clean. And yes, that's a Capital C. Galcop's Civilian SDD Authority's screening and vetting border on merciless. Relatively few applicants are accepted for final consideration. And this technology is not particularly cheap. Galcop is not 'giving away' its Neutralizers (unlike their SDDs).
    
    
    

    Equipment

    Name Visible Cost [deci-credits] Tech-Level
    NPB Neutralizer yes 80000 5+

    Ships

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

    Models

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

    Scripts

    Path
    Scripts/npb-escape-pod.js
    "use strict";
    
    this.name = "NPB NPC Escape Pod";
    this.description = "Dummy script for possible later escape-capsule use.";
    
    this.startUp = function() {}
    Scripts/npb-player.js
    "use strict";
    
    this.name = "NPB Neutralizer";
    this.author = "Reval";
    this.version = "1.3";
    this.license = "CC-BY-NC-SA 4.0";
    this.description = "Galcop's Neutral Particle Beam weapon causes catastrophic internal damage while throwing off little energy as surface heat. A direct hit leaves the target a powerless drifting hulk without triggering fatal explosions of fuel or ordinance.";
    
    // test beam timings with Transporters?
    this.$npbTest = false;
    // fully disable the target?
    this.$npbDisabling = true;
    // cripple target on first hit?
    this.$npbCrippling = true;
    // OPTION: adjust Neutralizing threshold (must be < C-thresh)
    this.$npbNeutralizingThreshold = 0.90; 
    // OPTION: adjust Crippling threshold (must be > N-thresh)
    this.$npbCripplingThreshold = 0.99;
    
    this.$log = true;
    
    /* NOTE: there are two options for where the Neutralizer logic fires from:
    	1. This world Script's shipAttackedOther ($npbNPCScript=false);
    	2. The individual NPC NPB ship script's shipBeingAttacked ($npbNPCScript=true);
    	Both work equally well, with a possible efficiency gain using (1).
    	The main difference in behaviour is in the number of log entries: (2) has more.
    	But then the logging can be toggled too ($log=true/false).
    	There is also the option not to disable the victim, with $npbDisabling=false.
    	Option to cripple (or not) the victim on first NPB hit ($npbCrippling=true/false).
    */ 
    
    /*
    	Version 1.3
    		OPTION: Adjust Neutralizing threshold, after which victim is definitively NPB'd.
    		OPTION: Adjust Crippling threshold, after which victim's systems and armament suffer.
    		Remove fuel injectors from a crippled ship, if fitted, to simulate disabling them.
    		Several cosmetic enhancements and logical tightenings.
    		
    	Version 1.2a
    		Not a true update: remedied omission to reset the $npbTesting option on last release.
    		
    	Version 1.2
    		OPTION: On first NPB hit, cripple victim ship's performance and armament.
    		On neutralization, disable (remove) victim's lasers and missiles.
    		Crippling also disables the victim's hyperdrive, preventing escape.
    		Victim crew's voice-comm reactions to being hit by NPB.
    		Ship's sensors' recording of NPB weapon's effects on victim vessel.
    		Pevent double score after killing a neutralized ship.
    		Code refactoring, optimizations, log & comment additions and amendments.
    		
    	Version 1.1
    		Fully implemented Galcop License-granting conditions.
    		OXP now distinguishes when the NPB Neutralizer is causing the damage to a victim.
    		NPB can be effected either from the world script or ship script (see NOTE).
    		Changed the 'kill message' and several strings in the log entries.
    */
    
    /*
    	To Do
    
    */
    
    // Conditionally, give every system-spawned NPC ship (except SDD) a NPB script
    this.shipSpawned = function(ship) {
        if ((ship.primaryRole != "police") && (ship.dataKey != "sdd-mambita") && (ship.name!="Asteroid")) {
            // Conditionally assign system NPCs their own neutralizer-reaction script
    		if (this.$npbNPCScript) {
    			ship.setScript("npc-npb.js");
    			this._npbCheckScripts()
    		}
        }
    }  
    
    
    this.shipWillLaunchFromStation = function() {
    	var ps = player.ship;
    	this.$npbHasEQ = (ps.equipmentStatus ("EQ_WEAPON_NEUTRALIZER") === "EQUIPMENT_OK");
    }
    
    
    this.startUpComplete = function() {   
    	var ps = player.ship;
    	this.$npbHasEQ = (ps.equipmentStatus ("EQ_WEAPON_NEUTRALIZER") === "EQUIPMENT_OK");
    }
    
    
    // spawn some dollies to test Neutralizer beam timings
    	
    this.shipExitedStationAegis = function(station) {
        if (this.$npbTest) {
            var ps = player.ship;
            // spawn some transporters
            var dummy = system.addShips("[transporter]", 10, ps.position);
            // make them distinctive
            for (var i = 0; i < dummy.length; i++) {
                // set its scanner blip colours
                dummy[i].scannerDisplayColor1 = "orangeColor";
                dummy[i].scannerDisplayColor2 = "whiteColor";
                // make it legal to shoot at
                dummy[i].bounty = 1;
    			// conditionally, assign NPB reaction script
    			if (this.$npbNPCScript) dummy[i].setScript("npc-npb.js");
            }
        }
    }   
    
    this.shipExitedWitchspace = function() {
    	if (this.$npbTest) {
    		var ps = player.ship;
    		// spawn some transporters
            var dummy = system.addShips("[transporter]", 10, ps.position);
    		for (var i=0; i<dummy.length; i++) {
    			// set its scanner blip colours
    			dummy[i].scannerDisplayColor1 = "orangeColor";
    			dummy[i].scannerDisplayColor2 = "whiteColor";
    			// make it legal to shoot at
    			dummy[i].bounty = 1;
    			// conditionally, assign NPB reaction script
    			if (this.$npbNPCScript) dummy[i].setScript("npc-npb.js");
    		}
    	}
    }
    
    
    // Neutralize! (or not)
    this.shipAttackedOther = function(other) {
        
    	// exit if neutralizing from an NPC script
    	if (this.$npbNPCScript) return;
    	// exit if we don't have a Neutralizer
    	if (!this.$npbHasEQ) return;
        // no neutralizing of invalid or disabled ships, debris, rocks, stations or buoys...
    	if ((!other.isValid) || (!other.isShip) || (other.isStation || other.isDisabled)) return;
        // don't proceed if victim is already neutralized
    	if (other.$neutralized) return;
    	
    	// establish if we're firing NPB
    	var currentWeapon = player.ship.currentWeapon;
        var usedNPB = (currentWeapon && currentWeapon.equipmentKey == "EQ_WEAPON_NEUTRALIZER");
    	// In combat, a victim is likely to be damaged already...
    	// abbreviate thresholds
    	var cthresh = this.$npbCripplingThreshold;
    	var nthresh = this.$npbNeutralizingThreshold;
    	var mE = other.maxEnergy, E = other.energy;
    	// Conditions for Crippling: victim must not be below Neutralizing threshold.
    	var cte = (E<=nthresh);
    	var cripg = this.$npbCrippling;
    	// sanity check
    	if (cte) {
    		player.consoleMessage("Crippling threshold below Neutralizing threshold!",9);
    		if (this.$log) this._log("Crippling threshold <= Neutralizing threshold!");
    	}
    	
    	// First hit: optionally cripple weapons, speed and manoevrability
    	if ((usedNPB) && (!cte) && (cripg) && (!other.$crippled) && (E/mE < cthresh)) {
    		// make victim's armament a Pulse Laser, simulating crippled weaponry
    		this._npbGivePulse(other);
    		// remove victim's missiles and mines to simulate disabling
    		this._npbRemoveMissilesMines(other);
    		// cripple speed and manoevrability
    		other.$crippled = this._npbCripple(other,0.25);
    		// disable hyperdrive
    		other.hyperspaceSpinTime = -1;
    		// disable fuel injector, if fitted, by removing it
    		if (this._npbShipHasEquipment(other, "EQ_FUEL_INJECTION"))
    			other.removeEquipment("EQ_FUEL_INJECTION");
    		// make victim's scanner blip blink
    		var osdc = other.scannerDisplayColor1;
    		other.scannerDisplayColor1 = osdc;
    		other.scannerDisplayColor2 = "blackColor";
    		// amend display name to 'crippled' + ship name
    		other.displayName = 'Crippled '+other.name;
    		// victim crew reaction to NPB effects
    		this._npbExclaim(other);
    		// sensors advise on NPB effects
    		this._npbAdvisory(other);
    		// Notify victim and SDD-Net of crippling
    		var name = other.name;
    		var dname = other.displayName;
    		var bount = other.bounty;
    		var ps = player.ship;
    		var pc = player.consoleMessage;
    		var oc = ps.messageGuiTextColor;
    		// set the 'police comms' colour - a light purple
    		ps.messageGuiTextColor = "0.7 0.3 0.8";
    		// communicate crippling and potential bounty on subspace comm
    		pc(" ", 5); // line break
    		pc(dname+" awaits further action. (+"+bount+" cr).", 9);
    		ps.messageGuiTextColor = oc;
    		if (this.$log) this._log(dname+" awaits further action. (Possible +"+bount+").");
    
    	}
    	
    	// Neutralize if NPB is the weapon and quarry's energy is below threshold
        if ((usedNPB) && (!other.$neutralized) && (E / mE < nthresh)) {
        
    		// victim crew reaction to NPB
    		this._npbExclaim(other);
    		// remove victim's lasers to simulate weapons disabled
    		this._npbRemoveLasers(other);
    		// remove victim's missiles and mines to simulate disabling
    		this._npbRemoveMissilesMines(other);
    		// Apply disabling effects:
    		// victim's engine is disabled, so make it drift 
    		other.maxSpeed = 0;
    		other.setAI("dumbAI.plist");
    		// Conditionally, disable the ship, making it a drifting hulk
    		if (this.$npbDisabling) other.isDisabled = true;
        
    		// set its scanner blip to reflect its derelict status
    		other.scannerDisplayColor1 = "grayColor";
    		other.scannerDisplayColor2 = "whiteColor";
    		// amend display name to 'neutralized' + ship name
    		other.displayName = 'Neutralized '+other.name;
    		// custom property to flag victim's neutralized state
    		other.$neutralized = true;
    		
    		// neutralization counts as a valid 'kill'
    		player.score ++;
    	
    		// collect bounty
    		var bounty = other.bounty;
    		player.credits += bounty;
    		// nullify ex-ship's bounty
    		// keeping it a nominal 1 for missions.
    		other.bounty = 1; // was 0
    		// but remember previous bounty!
    		other.$oldBounty = bounty;
    		
    		// Notify victim and SDD-Net
    		var name = other.name;
    		var ps = player.ship;
    		var pc = player.consoleMessage;
    		var oc = ps.messageGuiTextColor;
    		// set the 'police comms' colour - a light purple
    		ps.messageGuiTextColor = "0.7 0.3 0.8";
    		// communicate neutralization on subspace comm
    		pc(" ", 5); // line break
    		pc(name+" neutralized. Awaits tow.", 9);
            pc("Bounty: "+bounty+" cr transferred via SDD-Net.", 9);
    		ps.messageGuiTextColor = oc;
    		if (this.$log) this._log(name+" neutralized. Bounty: "+bounty+".");
    	}
    }; 
    
    
    this.shipKilledOther = function(whom, damageType) {
    	// prevent double scoring on a ship already neutralized
    	if (whom.$neutralized) {
    		player.credits -= whom.$oldBounty;
    		player.score --;
    		player.consoleMessage("Well done. You killed a dead ship.", 9);
    		if (this.$log) this._log("Killed neutralized "+whom.name+". No extra score.");
    	}
    }
    
    
    // verify that all system NPC ships have an NPB script
    this._npbCheckScripts = function() {
        var count = 0;
        var sas = system.allShips.length;
    	// Loop through all ships in the system
        for (var i = 0; i < sas; i++) {
            var ship = system.allShips[i];
            // Skip if it's not a valid ship (e.g., debris, buoys)
            if (!ship.isShip || !ship.isValid) continue;
            // Check if it has the npc-npb.js script
            if (ship.script && ship.script.name == "NPC NPB") count++;
        }
        this._log(count + " / " + sas + " entities are ships with NPC NPB script.");
    };
    
    
    // Reduce a ship to a desired level of performance
    this._npbCripple = function(other, level) {
    	// reduce their speed, turn rate, acceleration
    	other.maxSpeed = other.maxSpeed * level;
    	other.maxThrust = other.maxThrust * level;
    	other.maxPitch = other.maxPitch * level;
    	other.maxRoll = other.maxRoll * level;
    	other.maxYaw = other.maxYaw * level;
    	// they are crippled
    	return true;
    }
    
    
    // remove any and all lasers from NPC ship
    this._npbRemoveLasers = function(ship) {
        var laserKeys = [
            "EQ_WEAPON_PULSE_LASER",
            "EQ_WEAPON_BEAM_LASER",
            "EQ_WEAPON_MINING_LASER",
            "EQ_WEAPON_MILITARY_LASER"
        ];
        var lasersRemoved = false;
        
        for (var i = 0; i < laserKeys.length; i++) {
            var key = laserKeys[i];
            if (ship.equipmentStatus(key) !== "EQUIPMENT_NONE") {
                ship.removeEquipment(key);
                lasersRemoved = true;
            }
        }
        return lasersRemoved;
    };   
    
    
    // remove any and all missiles and mines from a NPC ship
    this._npbRemoveMissilesMines = function(ship) {
        var missileMineKeys = [
            "EQ_MISSILE", "EQ_HARDENED_MISSILE", "EQ_QC_MINE"
        ];
        var itemsRemoved = false;
        
        for (var i = 0; i < missileMineKeys.length; i++) {
            var key = missileMineKeys[i];
            // Check status once, then remove
            if (ship.equipmentStatus(key) !== "EQUIPMENT_NONE") {
                ship.removeEquipment(key);
                itemsRemoved = true;
            }
        }
        return itemsRemoved;
    };   
    
    
    // Give victim a Pulse Laser as its only armament
    this._npbGivePulse = function(ship) {
        // already has a Pulse Laser?
        if (ship.equipmentStatus("EQ_WEAPON_PULSE_LASER") !== "EQUIPMENT_NONE") {
            return false;
        }
        // List of other lasers to remove
        var otherWeapons = [
            "EQ_WEAPON_BEAM_LASER",
            "EQ_WEAPON_MINING_LASER",
            "EQ_WEAPON_MILITARY_LASER"
        ];
        // Remove any other lasers
        for (var i = 0; i < otherWeapons.length; i++) {
            if (ship.equipmentStatus(otherWeapons[i]) !== "EQUIPMENT_NONE") {
                ship.removeEquipment(otherWeapons[i]);
            }
        }
        // Award the Pulse Laser
        ship.awardEquipment("EQ_WEAPON_PULSE_LASER");
        return true;
    };   
    
    
    this._npbShipHasEquipment = function(ship, equip) {
        return (ship.equipmentStatus(equip) !== "EQUIPMENT_NONE");
    };   
    
    
    this._npbExclaim = function(ship) {
        var exclamations = [
            "Our scanners are dead!",
            "S.O.S. Electronics fried!",
            "Weapons and engines failing!",
            "Systems are down!",
            "We're blind and powerless!",
            "Critical systems overload!",
            "All power failing!",
            "Hull integrity failing!",
    		"Anyone... Notify Station!",
    		"S.O.S. Ship dying... need tow...",
    		"S.O.S. Uknown weapon hit us!",
    		"What the... what's happened to our ship?!",
    		"S.O.S. Our controls are dead...",
    		"Something's turning our ship into salvage!",
    		"S.O.S. We're helpless, drifting!",
    		"S.O.S. Our life-support failing!",
    		"S.O.S. Ship's computers offline!",
    		"Mercy! Drive inoperative, cannot flee!",
    		"Please! You're firing on a helpless vessel!",
    		"S.O.S! Our airlocks inoperative!",
    		"Hyperspace engine unresponsive!"
        ];
        var randomIndex = Math.floor(Math.random() * exclamations.length);
        ship.commsMessage(exclamations[randomIndex]);
    };
    
    
    this._npbAdvisory = function(ship) {
        var n = ship.name;
    	var advisories = [
    		n+"'s voice comms unclear.",
    		n+"'s transponder ceased sending.",
    		n+"'s course erratic.",
    		n+"'s drive wake in massive decline.",
    		n+"'s power output falling.",
    		n+"'s scan indicator intermittent.",
    		n+"'s EM signature fluctuating."
        ];
        var randomIndex = Math.floor(Math.random() * advisories.length);
    	var ps = player.ship;
    	var pc = player.consoleMessage;
    	var oc = ps.messageGuiTextColor;
    	// set the 'police comms' colour - a light purple
    	ps.messageGuiTextColor = "0.7 0.3 0.8";
    	// communicate advisories on subspace comm
    	pc(" ", 5); // line break
    	pc(advisories[randomIndex], 9);
    	ps.messageGuiTextColor = oc;
    };
    
    
    this._npbLogVictimData = function(vdata) {
        this._log("Victim Data:");
        this._log("  Unique ID: " + vdata.ID);
    	this._log("  spawnTime: " + vdata.spawnTime);
        this._log("  position: " + vdata.position);
        this._log("  dataKey: " + vdata.dataKey);
        this._log("  speed: " + vdata.speed);
        this._log("  bounty: " + vdata.bounty);
        this._log("  scanClass: " + vdata.scanClass);
        this._log("  name: " + vdata.name);
        this._log("  displayName: " + vdata.displayName);
        this._log("  primaryRole: " + vdata.primaryRole);
        this._log("  scannerDisplayColor1: " + vdata.scannerDisplayColor1);
        this._log("  scannerDisplayColor2: " + vdata.scannerDisplayColor2);
    };      
    
    
    this.startUp = function() {
        // maintain a list of neutralized ships
    	this.$npbNeutralizedShips = {};
    	// for ship-resurrection experiments
    	this.$npbCloning = false;
    	// Neutralizer code inside ship-scripts?
    	this.$npbNPCScript = false;
    };   
    
    
    // echo to Oolite log for this script only
    this._log = function(msg) {
    	log(this.name+".debug", msg);
    }
    
           
    Scripts/npb_equipment_conditions.js
    "use strict";
    
    this.allowAwardEquipment = function(equipment, ship, context) {
        // Disallow license if legal status is not clean
        if (context == "purchase" && player.legalStatus != "Clean") {
            player.consoleMessage("NPB Licensing disallowed due to legal status. You must have a clean record.",9);
            return false;
        }    
        // this allows other purchases
        return true;
    }   
    Scripts/npc-npb.js
    "use strict";
    this.name = "NPC NPB";
    this.author = "Reval";
    this.license = "CC-BY-NC-SA 4.0";
    this.version = "1.3";
    this.description = "This is the replacement script for Oolite populator-spawned NPCs. Used to register damage taken, from whom and from which weapon.";   
    
    /* 
    	Version 1.3
    		Fix: Removed redundant shipDied event.
    		
    */
    
    
    this.$log = true;
    
    
    this.shipSpawned = function() {
        // runs as soon as the ship is spawned (or should!)
        if (this.$log) this._log(this.ship.name+" NPC spawned as "+this.ship.primaryRole+".");
    }   
    
    
    this.startUp = function() {
        // runs as soon as the script is assigned by world (or should!)
        this._log(this.ship.name+" NPC signing on as "+this.ship.primaryRole+".");
    }
    
    
    // echo to Oolite log for this script only
    this._log = function(msg) {
    	log(this.name+".debug", msg);
    }
    
    
    this.shipDied = function(whom, why) {
    	// prevent double scoring on a ship already neutralized
    	if (this.ship.$neutralized) {
    		player.credits -= this.ship.$oldBounty;
    		player.score --;
    		player.consoleMessage("Well done. You killed a dead ship.", 9);
    		if (this.$log) this._log("Killed neutralized "+this.ship.name+". No extra score.", 9);
    	}
    };
    
    
    // Get Neutralized! (or not)
    this.shipBeingAttacked = function(whom) {
        // optimize
    	var s = this.ship;
    	// Exit if no attacker
        if (!whom) return;
    	if (s.isDisabled) return;
    	
        // Array of weapon facings to check
        var facings = ["forwardWeapon", "portWeapon", "starboardWeapon", "aftWeapon"];
        var neutralizerFound = false;
        var wName = "";
    
        // Check for NPB if the attacker is the player
        if (whom == player.ship) {
            var currentWeapon = player.ship.currentWeapon;
            if (currentWeapon && currentWeapon.equipmentKey == "EQ_WEAPON_NEUTRALIZER") {
                neutralizerFound = true;
                wName = currentWeapon.name;
            }
        }
        // Check for NPB if attacker is an NPC
        else {
            for (var i = 0; i < facings.length; i++) {
                var weapon = whom[facings[i]];
                if (weapon && weapon.equipmentKey == "EQ_WEAPON_NEUTRALIZER") {
                    neutralizerFound = true;
                    wName = weapon.name;
                    break;
                }
            }
        }
    
        // NPB Neutralizer used - proceed with Neutralizer logic
        if (neutralizerFound) {
            //this._log("Attacked by " + whom.name + " with " + wName);
    		// call functions and vars from world script (declare once)
    		var ws = ws || worldScripts["NPB Neutralizer"];   
    		
    		// first hit: optionally disable weapons, cripple speed and manoevrability
    		if ((ws.$npbCrippling) && (!s.$crippled)) {
    			// make my armament a Pulse Laser, simulating crippled weaponry
    			ws._npbGivePulse(s);
    			// remove my missiles and mines to simulate disabling
    			ws._npbRemoveMissilesMines(s);
    			// cripple my speed and manoevrability
    			ws.$npbCrippled = ws._npbCripple(s,0.25);
    			// disable hyperdrive
    			s.hyperspaceSpinTime = -1;
    			// disable fuel injector, if fitted, by removing it
    			if (ws._npbShipHasEquipment(s,"EQ_FUEL_INJECTION"))
    				s.removeEquipment("EQ_FUEL_INJECTION");
    			// make victim's scanner blip blink
    			var osdc = s.scannerDisplayColor1;
    			s.scannerDisplayColor1 = osdc;
    			s.scannerDisplayColor2 = "blackColor";
    			// amend display name to 'crippled' + ship name
    			s.ship.displayName = 'Crippled '+s.displayName;
    			// victim crew reaction to NPB effects
    			ws._npbExclaim(s);
    			// sensors advise on NPB effects
    			ws._npbAdvisory(s);
    		}
            
    		// Neutralize me if my energy is below 90%
    		if ((!this.ship.$neutralized) && (s.energy / s.maxEnergy < 0.9) {
    			// victim crew reaction to NPB
    			ws._npbExclaim(s);
    			// Apply disabling effects:
    			// engine disabled, so make me drift
    			s.maxSpeed = 0;
    			s.setAI("dumbAI.plist");
    			// remove my lasers to simulate weapons disabled
    			ws._npbRemoveLasers(s);
    			// remove my missiles and mines to simulate disabling
    			ws._npbRemoveMissilesMines(s);
    			// fully disable me if world script says so
    			if (ws && ws.$npbDisabling)
    				s.isDisabled = true;
    			// set my scanner blip colour to reflect derelict status
    			s.scannerDisplayColor1 = "grayColor";
    			s.scannerDisplayColor2 = "whiteColor";
            
    			player.score++;
    			// collect bounty on me
    			var bounty = s.bounty;
    			player.credits += bounty;
    			// nullify my existing bounty
    			// keeping it a nominal 1 for player missions.
    			s.bounty = 1; // was 0
    			// but remember previous bounty!
    			s.$oldBounty = bounty;
    			// Notify SDD-Net
    			var ps = player.ship;
    			var pc = player.consoleMessage;
    			var oc = ps.messageGuiTextColor;
    			ps.messageGuiTextColor = "0.7 0.3 0.8";
    			pc(s.name + " neutralized. Await tow.", 9);
    			pc("Bounty: "+bounty+" cr transferred via SDD-Net.", 9);
    			ps.messageGuiTextColor = oc;
    		}
    		
    	} else {
    		// No Neutralizer - general catch-all case
    		var weaponInfo = EquipmentInfo.infoForKey(whom.forwardWeapon.equipmentKey);
    		if (weaponInfo) {
    			var wName = weaponInfo.name; // eg. "Military Laser"
    		   	if (this.$log) this._log(s.name+" <-* "+whom.displayName+" ("+wName+")");
    		}
    	}
    } 
    
      
    // Test for docking
    this.shipDockedWithStation = function(station) {
        if (this.$log) this._log(this.ship.displayName + " docked with " + station.name);
    };