Scripts/ferdelance3G_hunter.js |
/*
========================================================================
ferdelance3G_hunter.js
This file is part of the 'Ferdelance 3G' expansion pack.
Author: UK_Eliter
License: 2017 Creative Commons: attribution, non-commercial, sharealike.
========================================================================
*/
/*
====================
JSLINT: set options
====================
*/
/*jshint esversion: 6*/
/*jshint sub:true*/
this.name = "ferdelance3G_hunter";
this.author = "UK_Eliter";
this.copyright = "";
this.description = "ferdelance3G_hunter.js (for NPCs)";
this.license = "2014 CC-by-nc-sa 3.0";
/*
------------------
DEBUGGING SWITCHES
------------------
*/
// this.logging = true;
var consoleDebugMessages = false; // do NOT comment this out. Rather, to disable, set to false.
this.debug = false;
if (this.debug) {
this.ship.reportAIMessages = true;
}
/*
------------------------
JSLINT: start of wrapper
------------------------
*/
(function() {
"use strict";
/*
--------------
EVENT HANDLERS
--------------
*/
this.shipSpawned = function() {
var r = Math.random();
if (r > 0.45) {
// ** Special ORDINANCE **
// 1st level ordinance: possibility of some hardheads; 2nd level: more serious stuff; 3rd: q-bomb..
var capacity;
var chanceThirdLevelOrdinance = 0.11;
var giveSecondLevelOrdinance = false;
var i;
var ordinanceAvailable;
var ordinanceCount;
ordinanceAvailable = ["EQ_MISSILE", "EQ_MISSILE", "EQ_MISSILE"]; // Hard-heads added to the list, below
if (this.ship.hasRole("ferdelance3G_+T")) {
giveSecondLevelOrdinance = true;
chanceThirdLevelOrdinance = 0.15;
} else if (r > 0.7) {
giveSecondLevelOrdinance = true;
}
if (giveSecondLevelOrdinance) {
if (worldScripts["Missiles & Bombs"]) {
ordinanceAvailable.push("EQ_RMB_FRAG_MISSILE", "EQ_RMB_OVERRIDE_MISSILE", "EQ_RMB_LAW_MISSILE", "EQ_RMB_INTERCEPT_MISSILE", "EQ_RMB_INTERCEPT_MISSILE", "EQ_RMB_INTERCEPT_MISSILE");
}
if (EquipmentInfo.infoForKey("EQ_TORPEDO_MISSILE")) {
ordinanceAvailable.push("EQ_TORPEDO_MISSILE");
}
if (EquipmentInfo.infoForKey("EQ_HARPOON_NUKE1_MISSILE")) {
ordinanceAvailable.push("EQ_HARPOON_NUKE1_MISSILE");
}
if (worldScripts["armoury_trackerWorldScript.js"]) {
ordinanceAvailable.push("EQ_ARMOURY_STUNBOMB_MINE");
if (this.ship.equipmentStatus("EQ_CLOAKING_DEVICE") != "EQUIPMENT_OK") {
ordinanceAvailable.push("EQ_KDRONE_LAUNCHER_MINE", "EQ_CDRONE_LAUNCHER_MINE");
}
}
if (EquipmentInfo.infoForKey("EQ_NEXUS_BUG_MISSILE")) {
ordinanceAvailable.push("EQ_NEXUS_PREMIUM_MISSILE");
if (r > 0.9) {
ordinanceAvailable.push("EQ_NEXUS_PREMIUM_MISSILE");
} else {
ordinanceAvailable.push("EQ_NEXUS_BASIC_MISSILE");
}
}
capacity = this.ship.missileCapacity;
// LEVEL THREE
if (Math.random() <= chanceThirdLevelOrdinance) {
this.ship.awardEquipment("EQ_QC_MINE"); // NB: actually award
--capacity;
}
}
ordinanceCount = ordinanceAvailable.length;
i = ordinanceCount;
while (i--) {
ordinanceAvailable.push("EQ_HARDENED_MISSILE");
} // add one of these for every existing missile in the list
// Load ordinance to ship
ordinanceCount = ordinanceAvailable.length; // this will have changed
i = capacity - 1;
do {
this.ship.awardEquipment(ordinanceAvailable[~~(Math.random() * ordinanceCount)]);
}
while (i--);
}
/*
** BOUNTY **
NB: This script is used not only for hunters but also for assassins.
*/
var r2 = Math.random(); // Threshold is 0.7. *Does* need to be r*2*.
if (r2 > 0.7) {
if (r2 < 0.9) {
this.ship.bounty += (Math.ceil(r * 32));
// sic - 'r', not 'r2'.
} else {
this.ship.bounty += 2 + (Math.ceil(r * 120));
// sic - 'r', not 'r2'.
}
}
// **CLEAN-UP **
delete this.shipSpawned;
};
/*
----------------------
JSLINT: end of wrapper
----------------------
*/
}).call(this);
// EOF |
Scripts/ferdelance3G_milInterstellar.js |
/*
========================================================================
ferdelance3G_milInterstellar.js
This file is part of the 'Ferdelance 3G' expansion pack.
Author: UK_Eliter
License: 2017 Creative Commons: attribution, non-commercial, sharealike.
========================================================================
*/
/*
====================
JSLINT: set options
====================
*/
/*jshint esversion: 6*/
/*jshint sub:true*/
this.name = "ferdelance3G_milInterstellar.js";
this.author = "UK_Eliter";
this.copyright = "";
this.description = "ferdelance3G-mainScript.js (for NPCs)";
this.license = "CC-by-nc-sa 3.0";
/*
------------------
DEBUGGING SWITCHES
------------------
*/
this.debug = false;
if (this.debug) {
this.ship.reportAIMessages = true;
}
/*
------------------------
JSLINT: start of wrapper
------------------------
*/
(function() {
"use strict";
/*
--------------
EVENT HANDLERS
--------------
*/
this.shipSpawned = function() {
// Record presence/absence of some OXPs or weapons for multiple use within THIS function.
var OXPInstalled_extraBugs;
if (worldScripts["extraThargoids_populator.js"]) {
OXPInstalled_extraBugs = true;
} else {
OXPInstalled_extraBugs = false;
}
var OXPInstalled_missilesAndBombs;
if (worldScripts["Missiles & Bombs"]) {
OXPInstalled_missilesAndBombs = true;
} else {
OXPInstalled_missilesAndBombs = false;
}
var OXPInstalled_nexus;
if (!EquipmentInfo.infoForKey("EQ_NEXUS_BUG_MISSILE")) {
OXPInstalled_nexus = true;
} else {
OXPInstalled_nexus = false;
}
// Create weighted list of available ordinance - varying with ship type
var ordinanceAvailable;
if (this.ship.hasRole("ferdelance3Bugblatter")) {
// BUGBLATTER
ordinanceAvailable = ["EQ_F3G_ANTISWEEP_MISSILE", "EQ_F3G_ANTISWEEP_MISSILE", "EQ_HARDENED_MISSILE"];
if (OXPInstalled_nexus === true) {
ordinanceAvailable.push("EQ_NEXUS_BUG_MISSILE", "EQ_NEXUS_BUG_MISSILE");
} else if (OXPInstalled_missilesAndBombs) {
ordinanceAvailable.push("EQ_RMB_THARGOID_MISSILE", "EQ_RMB_THARGOID_MISSILE");
}
if (worldScripts["armoury_trackerWorldScript.js"]) {
ordinanceAvailable.push("EQ_ARMOURY_SCREAMER_MINE");
}
if ((worldScripts.TCAT_masterScript != undefined)) {
ordinanceAvailable.push("EQ_TCAT_JAMMER_MINE");
}
if (EquipmentInfo.infoForKey("EQ_TORPEDO_MISSILE")) {
ordinanceAvailable.push("EQ_TORPEDO_MISSILE");
}
} else {
// NORMAL
ordinanceAvailable = ["EQ_F3G_ANTISWEEP_MISSILE", "EQ_F3G_ANTISWEEP_MISSILE", "EQ_HARDENED_MISSILE", "EQ_HARDENED_MISSILE"];
if (OXPInstalled_extraBugs) {
ordinanceAvailable.push("EQ_F3G_ANTISWEEP_MISSILE");
}
if (OXPInstalled_nexus === true) {
ordinanceAvailable.push("EQ_NEXUS_BUG_MISSILE", "EQ_NEXUS_BUG_MISSILE");
if (OXPInstalled_missilesAndBombs) {
ordinanceAvailable.push("EQ_RMB_THARGOID_MISSILE");
}
} else if (OXPInstalled_missilesAndBombs) {
ordinanceAvailable.push("EQ_RMB_THARGOID_MISSILE", "EQ_RMB_THARGOID_MISSILE");
} else if (EquipmentInfo.infoForKey("EQ_MILITARY_MISSILE")) {
ordinanceAvailable.push("EQ_MILITARY_MISSILE", "EQ_MILITARY_MISSILE", "EQ_MILITARY_MISSILE");
}
}
var ordinance_shipSlots = this.ship.missileordinance_shipSlots;
var ordinance_availableArray_length = ordinanceAvailable.length;
var i = ordinance_shipSlots - 1;
do {
this.ship.awardEquipment(ordinanceAvailable[~~(Math.random() * ordinance_availableArray_length)]);
}
while (i--);
//
delete this.shipSpawned;
};
/*
--------
SCANNING
--------
*/
this.$isSweeper = function(e) {
return e.isShip && e.isThargoid && e.hasRole("extraThargoids_sweeper");
};
this.$isBigBug = function(e) {
return e.isShip && e.isThargoid && e.mass > 900000;
};
this.$isVeryBigBug = function(e) {
return e.isShip && e.isThargoid && e.mass > 4600000;
};
this.$scanForPrimaryTarget = function() {
if (!this.ship || !this.ship.isPiloted) {
return;
}
// if ( this.debug ) {player.consoleMessage("3G - SEEKING", 5);}
// Look for sweepers
var bigBugs;
var sweepers = system.filteredEntities(this, this.$isSweeper, this.ship, 25600);
if (sweepers.length > 0) {
// See whether target a sweeper or instead look for a big bug
bigBugs = system.filteredEntities(this, this.$isVeryBigBug, this.ship, 75000); // note range
if (bigBugs.length === 0) {
// Is at least one sweeper, are no (very) big bugs - so, go for a sweeper.
// So -if is more than one sweeper, decide which one to target.
if (sweepers.length === 1 || Math.random() < 0.65) {
this.ship.target = sweepers[0];
} else {
this.ship.target = sweepers[1];
}
this.ship.reactToAIMessage("TARGET_FOUND");
} else {
// Is at least one sweeper and at least one (very) big bug. So decide which type to go for.
var r = Math.random();
if (r < 0.85) {
// Target a sweeper.
if (sweepers.length === 1 || r < 0.6) {
this.ship.target = sweepers[0];
} else {
this.ship.target = sweepers[1];
}
this.ship.reactToAIMessage("TARGET_FOUND");
} else {
// Target a (very) bigbug.
// Now decide which bigbug, if more than one.
if (bigBugs.length === 1 || Math.random() < 0.6) {
this.ship.target = bigBugs[0];
} else {
this.ship.target = bigBugs[1];
}
this.ship.reactToAIMessage("TARGET_FOUND");
}
}
} else {
// Are no sweepers. So look for (very) big bugs.
bigBugs = system.filteredEntities(this, $isVeryBigBug, this.ship, 25600); // note range
if (bigBugs.length > 0) {
if (bigBugs.length === 1 || Math.random() < 0.55) {
this.ship.target = bigBugs[0];
} else {
this.ship.target = bigBugs[1];
}
this.ship.reactToAIMessage("TARGET_FOUND");
} else {
// Found no sweeper nor any very big bug - so look, up to just outside scanner range, for fairly big bugs.
bigBugs = system.filteredEntities(this, this.$isBigBug, this.ship, 25600);
if (bigBugs.length > 0) {
if (bigBugs.length === 1 || Math.random() < 0.6) {
this.ship.target = bigBugs[0];
} else {
this.ship.target = bigBugs[1];
}
this.ship.reactToAIMessage("TARGET_FOUND");
} else {
this.ship.reactToAIMessage("NOTHING_FOUND"); // Do need always to end with this or $doInterceptOfThargoid.
}
}
}
};
this.$isSuitableTarget = function(e) {
return e.isShip && e.isThargoid && e.mass > 500000 && e.primaryRole !== "thargoidRebel";
};
this.$scanForSecondaryTarget = function() {
if (!this.ship || !this.ship.isPiloted) {
return;
}
// if ( this.debug ) {player.consoleMessage("3G - SEEKING", 5);}
// Tharglet mass: 7829.43
// Frigate mass: 110048
// Warship mass: 899378
var targetArray = system.filteredEntities(this, this.$isSuitableTarget, this.ship, 25600);
if (targetArray.length === 0) {
this.ship.reactToAIMessage("NOTHING_FOUND");
return;
}
// else
if ((targetArray.length === 1) || (Math.random() < 0.7)) {
this.ship.target = targetArray[0];
} else {
this.ship.target = targetArray[1];
}
// player.consoleMessage("3G - OK!", 5);
this.ship.reactToAIMessage("TARGET_FOUND");
};
this.$isSuitableNavy = function(e) {
return e.isShip && (e.mass > 20000000) && (e.isPolice || e.scanClass === "CLASS_MILITARY");
};
this.$findNavy = function() {
var navalArray;
navalArray = system.filteredEntities(this, this.$isSuitableNavy, this.ship, 50000);
if (navalArray.length > 0) {
if ((navalArray.length === 1) || (Math.random() < 0.7)) {
this.ship.target = navalArray[0];
} else {
this.ship.target = navalArray[1];
}
this.ship.reactToAIMessage("TARGET_FOUND");
} else {
this.ship.reactToAIMessage("NOTHING_FOUND");
}
};
/*
---------------------
ATTACK ROUTINES & co.
---------------------
*/
this.$considerRespondingToAttack = function() {
if (!this.ship || !this.ship.isPiloted) {
return;
}
if (!this.ship.target || !this.ship.target.isValid) {
return;
}
if (this.ship.target.isThargoid) {
this.ship.reactToAIMessage("RESPOND_TO_ATTACK");
return;
}
// else
if (this.ship.target.scanClass === "CLASS_MILITARY" || this.ship.target.scanClass === "CLASS_POLICE") {
if (Math.random() < 0.02) {
this.ship.reactToAIMessage("RESPOND_TO_ATTACK");
} else {
this.ship.reactToAIMessage("POOTLE_IN_RESPONSE_TO_ATTACK");
}
} else {
if (Math.random() < 0.2) {
this.ship.reactToAIMessage("RESPOND_TO_ATTACK");
} else {
this.ship.reactToAIMessage("POOTLE_IN_RESPONSE_TO_ATTACK");
}
}
};
this.$considerRespondingToAttackWhenInterceptingNavy = function() {
if (!this.ship || !this.ship.isPiloted) {
return;
}
if (!this.ship.target || !this.ship.target.isValid) {
return;
}
if (
this.ship.target.isPlayer ||
(!this.ship.target.isThargoid && (this.ship.target.scanClass !== "CLASS_MILITARY") && (this.ship.target.scanClass !== "CLASS_POLICE"))
) {
if (Math.random() < 0.27) {
this.ship.reactToAIMessage("RESPOND_TO_ATTACK");
} else {
this.ship.reactToAIMessage("DO_NOT_RESPOND_TO_ATTACK");
}
} else {
this.ship.reactToAIMessage("RESPOND_TO_ATTACK");
}
};
this.$setMisjump = function() {
var r = Math.random();
this.ship.scriptedMisjump = true;
if (r < 0.4) {
this.ship.scriptedMisjumpRange = r * 2;
}
};
/*
---------
DEBUGGING
---------
*/
//this.messagePlayerIfPlayerWithinScannerRangeOfShip = function(text)
//{
// if (!this.ship) {return;}
// if (!this.ship.position) {return;}
// if (!player.ship) {return;}
// if (!player.ship.isValid) {return;}
// if ( this.ship.position.distanceTo(player.ship.position) < 23000 ) {player.consoleMessage(text, 6);}
//}
//
//
//this.message = function(text) {player.consoleMessage(text, 6);}
/*
----------------------
JSLINT: end of wrapper
----------------------
*/
}).call(this);
// EOF |
Scripts/ferdelance3G_populator.js |
/*
========================================================================
ferdelance3G_populator.js
This file is part of the 'Ferdelance 3G' expansion pack.
Author: UK_Eliter
License: 2017 Creative Commons: attribution, non-commercial, sharealike.
========================================================================
*/
/*
====================
JSLINT: set options
====================
*/
/*jshint esversion: 6*/
/*jshint sub:true*/
this.name = "ferdelance3G_populator";
this.author = "UK_Eliter";
this.copyright = "2014 Creative Commons: attribution, non-commercial, sharealike.";
this.licence = "CC-NC-SA 4";
this.description = "Fer-de-Lance 3G populator script";
/*
------------------
DEBUGGING SWITCHES
------------------
*/
// this.logging = true;
this.consoleDebugMessages = false; // to disable this, set it to false. DO NOT comment it out.
/*
------------------------
JSLINT: start of wrapper
------------------------
*/
(function() {
"use strict";
/*
-----------------------
INTERSTELLAR population
-----------------------
*/
this.interstellarSpaceWillPopulate = function() {
if (Math.random() < 0.94) {
return;
} // NB: 0.94
// Otherwise
system.setPopulator("ferdelance3G_interstellar", {
priority: 300,
callback: this._addinterstellar3Gs.bind(this)
});
};
this._addinterstellar3Gs = function(pos) {
var threeG_number = ~~(1 + (Math.random() * 8));
this.$addShips_ringless("ferdelance3G_interstellar", threeG_number, [0, 0, 0], 22000);
};
this.$isBug = function(e) {
return e.isThargoid;
};
this.interstellarSpaceWillRepopulate = function() {
// It is important for smooth gameplay that this function runs very quickly. If calculations are needed, run as many as possible in the populator function to save the result.
// 'interstellarSpaceWillRepopulate' does *not* use system.setPopulator
//
// Note re Interstellar Tweaks OXP: that function will stop this routine being called, except in 'modified' scenarios. For 'new' scenarios, InterstellarTweaks can itself spawn 3Gs.
if (!player.ship || !player.ship.position) {
return;
}
if (this.threeG_addNoMore === true) {
return;
}
var bugs = system.filteredEntities(this, this.$isBug);
if (bugs.length < 5) {
return;
}
var police_num = system.countShipsWithRole("police");
if (police_num >= bugs.length) {
return;
}
var threeG_chanceAdd;
if (police_num < 15) {
threeG_chanceAdd = 0.02;
} else {
threeG_chanceAdd = 0.05;
}
var numCarriers = system.countShipsWithRole("thargoid_carrier");
if (numCarriers > 2) {
threeG_chanceAdd = threeG_chanceAdd * (numCarriers - 1);
// "threeG_chanceAdd* = (numCarriers-1)" throws exception
}
if (threeG_chanceAdd > 0.4) {
threeG_chanceAdd = 0.4;
}
if (Math.random() > threeG_chanceAdd) {
return;
}
// Else
var threeG_number = 3 + ~~((Math.random() * 6) + 1);
system.addGroup("ferdelance3G_interstellar", threeG_number, [0, 0, 0], 875);
if (Math.random() < 0.6) {
this.threeG_addNoMore = true;
}
};
/*
------------------
STELLAR population
------------------
*/
this.systemWillPopulate = function() {
/* STELLAR POPULATOR
LANE_PS, LANE_WP, LANE_WS, STATION_AEGIS, PLANET_ORBIT, OUTER_SYSTEM, OUTER_SYSTEM_OFFPLANE
Use 'callback: this._myFunction.bind(this)' not callback: this._myFunction' in order to use global variables and functions
*/
// log("3G - DEBUG", "entered populator"); // TEST
if (!((system.government < 3) && (Math.random() < 0.2))) {
return;
}
var place = ~~(1 + (Math.random() * 8));
// log("3G - DEBUG", "place is <" + place + ">"); // TEST
switch (place) {
case 1:
system.setPopulator("ferDeLance3G-huntersPO", {
groupCount: 1,
priority: 150,
location: "PLANET_ORBIT",
callback: this._addHunter.bind(this)
});
break;
case 2:
system.setPopulator("ferDeLance3G-huntersLWP", {
groupCount: 1,
priority: 111,
location: "LANE_WP",
callback: this._addHunter.bind(this)
});
break;
case 3:
system.setPopulator("ferDeLance3G-huntersOS", {
groupCount: 1,
priority: 150,
location: "OUTER_SYSTEM",
callback: this._addHunter.bind(this)
});
break;
case 4:
system.setPopulator("ferDeLance3G-huntersSA", {
groupCount: 1,
priority: 150,
location: "STATION_AEGIS",
callback: this._addHunter.bind(this)
});
break;
case 5:
system.setPopulator("ferDeLance3G-huntersWP", {
groupCount: 1,
priority: 110,
location: "WITCHPOINT",
callback: this._addHunter.bind(this)
});
break;
case 6:
system.setPopulator("ferDeLance3G-huntersSOL", {
groupCount: 1,
priority: 150,
location: "STAR_ORBIT_LOW",
callback: this._addHunter.bind(this)
});
break;
default:
system.setPopulator("ferDeLance3G-huntersLWPS", {
groupCount: 1,
priority: 111,
location: "LANE_WPS",
callback: this._addHunter.bind(this)
});
}
};
this._addHunter = function(pos) {
var s = system.addShips("ferdelance3G_hunter", 1, pos, 35000);
// function addShips(role : String, count : Number [, position: vectorExpression] [, radius: Number]) : Array
// log("3G TESTING", "Added stellar hunter");
};
/*
-----
OTHER
-----
*/
this.playerWillEnterWitchspace = function() {
this.threeG_addNoMore = false;
};
this.$addShips_ringless = function(role, count, position, radius) {
var i, offset, ships;
offset = new Vector3D(0, 50000, 0);
if (count < 1) {
this.$error("Bad count argument <" + count + "> for function addShips_ringless");
count = 1; // fix the problem.
}
ships = system.addShips(role, count, offset, radius);
offset = new Vector3D(position).subtract(offset);
i = ships.length;
while (i--) {
ships[i].position = ships[i].position.add(offset);
}
return ships;
};
// For TESTING
/*
this.shipWillLaunchFromStation = function()
{
// this.$addShips_ringless("ferdelance3G_trader", 4, player.ship.position, 25000);
// this.$addShips_ringless("ferdelance3G_pirate", 4, player.ship.position, 25000);
this.$addShips_ringless("ferdelance3G_pirateKing", 2, player.ship.position, 25000);
// this.$addShips_ringless("ferdelance3G_hunter", 4, player.ship.position, 25000);
// this.$addShips_ringless("ferdelance3G_police", 3, player.ship.position, 25000);
//this.$addShips_ringless("ferdelance3G_interstellar", 4, player.ship.position, 25000);
this.$addShips_ringless("ferdelance3G_hardPiratePoliceDecomissioned", 1, player.ship.position, 25000);
this.$addShips_ringless("ferdelance3G_hardestHunterPoliceDecomissioned", 1, player.ship.position, 25000);
}
*/
/*
----------------------
JSLINT: end of wrapper
----------------------
*/
}).call(this);
// EOF |