Scripts/sniperlock_plus.js |
"use strict";
this.name = "sniperlock_plus";
this.author = "Dybal";
this.copyright = "Copyright 2020 Dybal";
this.license = "CC BY-NC-SA 4.0"
this.description = "Sniperlock Plus script";
this.version = "1.0.2";
this.$logging = true;
this.$debug = false;
this.$enabled = true; // Other OXPs can deactivate Sniper Lock Plus by assigning false to this
this.$slpAngleToLock = 0.002; // How close to the target you have to move the crosshairs for SniperLock Plus to lock; default: 0.002
this.$slpAngleToUnlock = 0.06; // How far from the center of the crosshairs the target has to move between FCBs for SniperLock Plus to unlock; default: 0.06
this.$slpDuration = 12; // How long SniperLock keeps a target loked; default: 12
this.$slpOriginalPitch; // stores the player's ship original maxPitch, so we can detect maneuverability reductions and compensate
this.$slpState = "OFF";
this.$slpTarget; // target in last FCB call
this.$slpLastAngle; // angle to target in last FCB call
//
// Event Handlers
//
//--------------------------------------------------------------------------------------------//
this.startUp = function _slp_startUp() {
this.$enabled = true; // reset
this.$slpState = "OFF";
this.$slpCounter = 0; // to control the time locked on target
this.$slpTargetPosition_1 = null;// aim is 1 frame behind true target position
this.$slpTargetPosition_2 = null;// aim is 2 frames behind true target position
this.$slpTargetPosition_3 = null;// aim is 3 frames behind true target position
this.$slpOriginalPitch = player.ship.maxPitch;
}
//--------------------------------------------------------------------------------------------//
this.playerBoughtNewShip = this.playerReplacedShip = function _slp_newShip() {
this.$slpOriginalPitch = player.ship.maxPitch;
}
//--------------------------------------------------------------------------------------------//
this.playerBoughtEquipment = function _slp_playerBoughtEquipment(equipmentKey) {
var _player = player;
if (equipmentKey === ("EQ_SNIPERLOCK_PLUS_REMOVAL")) {
let eqInfo = EquipmentInfo.infoForKey("EQ_SNIPERLOCK_PLUS");
_player.ship.removeEquipment("EQ_SNIPERLOCK_PLUS");
_player.ship.removeEquipment("EQ_SNIPERLOCK_REMOVAL");
_player.credits += eqInfo.calculatedPrice * 0.5 / 10;
}
}
//--------------------------------------------------------------------------------------------//
this.equipmentRemoved = function _slp_equipmentRemoved(equipmentKey) {
if (equipmentKey === "EQ_SNIPERLOCK_PLUS" && this.$FCB && isValidFrameCallback(this.$FCB))
removeFrameCallback(this.$FCB);
}
//--------------------------------------------------------------------------------------------//
this.equipmentAdded = function _slp_equipmentAdded(equipmentKey) {
var ship = player.ship;
if (equipmentKey === "EQ_SNIPERLOCK_PLUS" && ship.status === "STATUS_IN_FLIGHT") {
this.$slpState = "OFF";
this.$FCB = addFrameCallback(this.$sniperLock.bind(this, ship));
}
}
//--------------------------------------------------------------------------------------------//
this.shipWillLaunchFromStation = function _slp_shipWillLaunchFromStation() {
var ship = player.ship;
if (ship.equipmentStatus("EQ_SNIPERLOCK_PLUS") === "EQUIPMENT_OK") {
// obtain compensations for off-center weapons
if (ship.forwardWeapon && ship.forwardWeapon.equipmentKey !== "EQ_WEAPON_NONE") {
this.$forwardModelCorrection = this.$weaponModelPositionCorrection(ship.weaponPositionForward, "Forward");
if (this.$logging) log(this.name, ship.displayName+": forward weapon correction: "+this.$forwardModelCorrection);
} else
this.$forwardModelCorrection = Vector3D(0,0,0); // player might have changed ship
if (ship.aftWeapon && ship.aftWeapon.equipmentKey !== "EQ_WEAPON_NONE") {
this.$aftModelCorrection = this.$weaponModelPositionCorrection(ship.weaponPositionAft, "Aft");
if (this.$logging) log(this.name, ship.displayName+": aft weapon correction: "+this.$aftModelCorrection);
} else
this.$aftModelCorrection = Vector3D(0,0,0); // player might have changed ship
this.$slpState = "OFF";
this.$FCB = addFrameCallback(this.$sniperLock.bind(this, ship));
}
}
//--------------------------------------------------------------------------------------------//
this.shipDockedWithStation = function _slp_shipDockedWithStation() {
if (this.$FCB && isValidFrameCallback(this.$FCB)) removeFrameCallback(this.$FCB);
}
//--------------------------------------------------------------------------------------------//
this.shipWillEnterWitchspace = function _slp_shipWillEnterWitchspace() {
if (this.$FCB && isValidFrameCallback(this.$FCB)) removeFrameCallback(this.$FCB);
}
//--------------------------------------------------------------------------------------------//
this.shipExitedWitchspace = function _slp_shipExitedWitchspace() {
var ship = player.ship;
if (ship.equipmentStatus("EQ_SNIPERLOCK_PLUS") === "EQUIPMENT_OK") {
this.$slpState = "OFF";
this.$FCB = addFrameCallback(this.$sniperLock.bind(this, ship));
}
}
//--------------------------------------------------------------------------------------------//
//this.shipTargetAcquired = function _slp_shipTargetAcquired() {
// if (this.$enabled) {
// this.$slpTargetPosition_1 = null;
// this.$slpTargetPosition_2 = null;
// this.$slpTargetPosition_3 = null;
// this.$slpState = "READY";
// this.$slpCounter = 0;
// }
//}
//--------------------------------------------------------------------------------------------//
this.shipDied = function _slp_shipDied() {
if (this.$FCB && isValidFrameCallback(this.$FCB)) removeFrameCallback(this.$FCB);
}
//
// Internal Functions
//
//--------------------------------------------------------------------------------------------//
this.$sniperLock = function _slp_sniperLock(ship) {
var that = _slp_sniperLock;
var fwdModelCorrection = this.$forwardModelCorrection;
var aftModelCorrection = this.$aftModelCorrection;
var applyFwdCorrection = (fwdModelCorrection != Vector3D(0,0,0));
var applyAftCorrection = (aftModelCorrection != Vector3D(0,0,0));
var viewDirection = ship.viewDirection;
var modelCorrection = (viewDirection === "VIEW_FORWARD" ? fwdModelCorrection : aftModelCorrection);
var applyCorrection = (viewDirection === "VIEW_FORWARD" ? applyFwdCorrection : applyAftCorrection);
var debug = this.$debug && ship.weaponsOnline;
var logging = this.$logging;
// compensate for reduced maneuverability in the unlock angle
var angleToUnlock = this.$slpAngleToUnlock * (ship.maxPitch / this.$slpOriginalPitch);
var angleToLock = this.$slpAngleToLock;
var angleChange;
if (angleToUnlock <= angleToLock)
// if maxPitch is reduced too much, angleToUnlock would become less tha angleToLock, making it impossble to keep a lock
angleToUnlock = 1.1 * angleToLock;
if (!ship.target || !this.$enabled ||
(ship.target && ship.speed > ship.maxSpeed && ship.target.dataKey === "telescopemarker") ||
ship.equipmentStatus("EQ_SNIPERLOCK_PLUS") !== "EQUIPMENT_OK" ||
ship.equipmentStatus("EQ_SCANNER_SHOW_MISSILE_TARGET") !== "EQUIPMENT_OK" ||
(viewDirection !== "VIEW_FORWARD" && viewDirection !== "VIEW_AFT")) {
if (this.$slpState !== "OFF") {
this.$slpTargetPosition_1 = null;
this.$slpTargetPosition_2 = null;
this.$slpTargetPosition_3 = null;
this.$slpState = "OFF";
this.$slpCounter = 0;
this.$slpTarget = null;
this.$slpLastAngle = null;
}
return;
}
var sh =(viewDirection === "VIEW_FORWARD" ? ship.heading : ship.heading.multiply(-1));
var tp, tv, ta, tp_aim;
if (ship.target.isValid) {
tp = ship.target.position;
this.$slpDistance = ((tp.distanceTo(ship) - ship.target.collisionRadius) / 1000);
} else {
this.$slpDistance = 0;
}
if (this.$slpDistance > 5.0 && this.$slpDistance < 25.6) {
if (!this.$slpTarget || this.$slpTarget != ship.target) {
// new target, reset everything
if (debug) log(this.name, "Target changed from "+(this.$slpTarget ? this.$slpTarget.displayName : "None")+" to "+ship.target.displayName);
this.$slpTargetPosition_1 = null;
this.$slpTargetPosition_2 = null;
this.$slpTargetPosition_3 = null;
this.$slpState = "READY";
this.$slpCounter = 0;
this.$slpTarget = ship.target;
}
tv = tp.subtract(ship).direction(); // direction to target
ta = sh.angleTo(tv); // angle to target
angleChange = (this.$slpLastAngle != null ? Math.abs(this.$slpLastAngle - ta) : null);
if (this.$slpState === "READY") {
this.$slpLastAngle = ta;
if (debug && (angleChange == null || angleChange > 0.000001)) log(this.name, "target: "+ship.target.displayName+", angle to target: "+ta.toFixed(4)+" lock if <= "+angleToLock.toFixed(6)+", angle change: "+(angleChange?angleChange.toFixed(7):"None"));
if (ta <= this.$slpAngleToLock) {
// close enough, Lock!
if (debug) log(this.name, "target: "+ship.target.displayName+", angle to target: "+ta.toFixed(4)+", less than "+this.angleToLock.toFixed(6)+", LOCKED");
this.$slpTargetPosition_1 = tp;
this.$slpTargetPosition_2 = tp;
this.$slpTargetPosition_3 = tp;
this.$slpLastAngle = null;
this.$slpState = "ON";
}
}
if (this.$slpState === "ON") {
this.$slpCounter += 1;
// if angle to target didn't change from last iteration, weapon is still aligned and nothing to do
if (angleChange && angleChange < 0.000001) return;
this.$slpLastAngle = ta;
if ((angleChange && angleChange > angleToUnlock) || this.$slpCounter > this.$slpDuration) {
if (debug) log(this.name, "target: "+ship.target.displayName+", angle to target: "+ta.toFixed(4)+", changed: "+angleChange.toFixed(7)+" threshold to unlock "+angleToUnlock.toFixed(6)+", counter: "+this.$slpCounter+", UNLOCKED");
this.$slpTargetPosition_1 = null;
this.$slpTargetPosition_2 = null;
this.$slpTargetPosition_3 = null;
this.$slpState = "READY";
this.$slpCounter = 0;
return;
}
if (debug) log(this.name, "target: "+ship.target.displayName+", angle to target: "+ta.toFixed(4)+", changed: "+angleChange.toFixed(7)+" less than "+angleToUnlock.toFixed(6)+", KEPT LOCKED");
if (applyCorrection) {
var correction = this.$weaponPositionCorrection(ship, modelCorrection);
tp_aim = this.$slpTargetPosition_3.add(correction);
if (debug) log(this.name, ship.displayName+" target position: "+this.$slpTargetPosition_3+", aiming point:" + tp_aim);
} else
tp_aim = this.$slpTargetPosition_3;
let tvc = tp_aim.subtract(ship).direction();
let tac = sh.angleTo(tvc);
let cr = sh.cross(tvc).direction();
let new_orientation = ship.orientation.rotate(cr,-tac);
let dot = new_orientation.dot(ship.orientation);
if (dot < 1) {
if (debug) log(this.name, "Orientation changed, dot="+dot.toFixed(4));
ship.orientation = ship.orientation.rotate(cr,-ta);
}
this.$slpTargetPosition_3 = this.$slpTargetPosition_2;
this.$slpTargetPosition_2 = this.$slpTargetPosition_1;
this.$slpTargetPosition_1 = tp;
this.$slpTarget = ship.target;
}
}
if (this.$slpState === "ON" && this.$slpDistance <= 5.0) {
// target closer than minimun distacne, reset but keep target
this.$slpTargetPosition_1 = null;
this.$slpTargetPosition_2 = null;
this.$slpTargetPosition_3 = null;
this.$slpState = "READY";
this.$slpCounter = 0;
}
}
//--------------------------------------------------------------------------------------------//
this.$weaponModelPositionCorrection = function _slp_weaponModelPositionCorrection(weaponPosition, str) {
var avgX, avgY , avgZ;
avgX = avgY = avgZ = 0;
var i = weaponPosition.length;
while (i--) {
avgX += weaponPosition[i].x;
avgY += weaponPosition[i].y;
avgZ += weaponPosition[i].z;
}
avgX /= weaponPosition.length;
avgY /= weaponPosition.length;
var avg_wp_pos = Vector3D(avgX, avgY, avgZ);
var z_wp_pos = Vector3D(0, 0, avgZ);
var correction = z_wp_pos.subtract(avg_wp_pos);
if (this.$debug) log(this.name, str+": average position: "+avg_wp_pos+", centerline position: "+z_wp_pos+", correction: "+correction);
return correction
}
//--------------------------------------------------------------------------------------------//
this.$weaponPositionCorrection = function _slp_weaponPositionCorrection(ship, model_correction) {
var world_correction = model_correction.rotateBy(ship.orientation);
var debug = this.$debug && player.ship.weaponsOnline;
if (this.$debug) log(this.name, ship.displayName+" model_correction: "+model_correction+", world: "+world_correction+", ship position: "+ship.position);
return world_correction;
}
|
Scripts/sniperlock_plus_conditions.js |
"use strict";
this.name = "sniperlock_plus_conditions";
this.author = "Dybal";
this.copyright = "Copyright 2020 Dybal";
this.license = "CC BY-NC-SA 4.0"
this.description = "Sniperlock Plus conditions script";
this.version = "1.0";
//--------------------------------------------------------------------------------------------//
this.updateEquipmentPrice = function _slp_updateEquipmentPrice(equipmentKey, currentPrice) {
var ws = worldScripts.sniperlock_plus;
var slStatus = player.ship.equipmentStatus("EQ_SNIPERLOCK");
var slPrice = EquipmentInfo.infoForKey("EQ_SNIPERLOCK").price;
if (slStatus === "EQUIPMENT_OK") {
var price = currentPrice - slPrice;
if (ws.$debug) log(this.name, "Rebating price of EQ_SNIPERLOCK ("+formatCredits(slPrice/10, true, true)+") from "+equipmentKey+" price ("+formatCredits(currentPrice/10,true,true)+"): "+formatCredits(price/10, true, true));
return price;
}
if (ws.$debug) log(this.name, equipmentKey+" price: "+formatCredits(currentPrice/10, true, true));
return currentPrice;
}
|