[WIP] Bounty system OXP
Moderators: winston, another_commander
- phkb
- Impressively Grand Sub-Admiral
- Posts: 4830
- Joined: Tue Jan 21, 2014 10:37 pm
- Location: Writing more OXPs, because the world needs more OXPs.
Re: [WIP] Bounty system OXP
Another bug squashed in v0.7, with thanks to dybal for the tip off.
Re: [WIP] Bounty system OXP
With auto-scanning mode, I targeted an offender from a distance of 20km, and nothing happened. When I approached within 15km and did the same, the scanner MFD appeared and scanning started. I think it would be better if when you target someone that otherwise qualifies to be scanned, the MFD would appear but indicate out of range.
- phkb
- Impressively Grand Sub-Admiral
- Posts: 4830
- Joined: Tue Jan 21, 2014 10:37 pm
- Location: Writing more OXPs, because the world needs more OXPs.
Re: [WIP] Bounty system OXP
Good idea. In for the next release.
Re: [WIP] Bounty system OXP
I recently got myself a fugitive status to be able to find/dock in some of Anarchies features (Renegade Stations and Hacker Outposts).
I slowly worn down the bounty from 111 to 2 by helping police, then with bounty 2 that didn't work anymore (I think that's an intentional feature).
Several GalCop cops commed me to get to the station and pay the fines.
When I docked at secondary stations (I run Additional Planets and Stations for Additional Planets) there were no screens applying a fine and sending me to "attitude adjustment", but I found several emails about 500 Cr fines being applied, and I didn't notice any change in my credit balance (I think that's a potential bug).
I finaly docked at the Main Station and there was a screen applying a 200Cr fine and sending me to "attitude adjustment". My legal status on Status Screen showed Clean.
Then I launched, was scanned by a GalCop Viper and got back my bounty of 2. I reloaded the last savegame and looked at the Security Office and the entry for an offence was there, with fine of 50 Cr payable. I paid it and after that my clean status held.
I suppose the 200 Cr fine and "attitude adjustment" was done by the core game because a cop flagged me to pay my fines, but shouldn't that clear my Bounty System record without having to go to the Security Office and pay the fine again?
I slowly worn down the bounty from 111 to 2 by helping police, then with bounty 2 that didn't work anymore (I think that's an intentional feature).
Several GalCop cops commed me to get to the station and pay the fines.
When I docked at secondary stations (I run Additional Planets and Stations for Additional Planets) there were no screens applying a fine and sending me to "attitude adjustment", but I found several emails about 500 Cr fines being applied, and I didn't notice any change in my credit balance (I think that's a potential bug).
I finaly docked at the Main Station and there was a screen applying a 200Cr fine and sending me to "attitude adjustment". My legal status on Status Screen showed Clean.
Then I launched, was scanned by a GalCop Viper and got back my bounty of 2. I reloaded the last savegame and looked at the Security Office and the entry for an offence was there, with fine of 50 Cr payable. I paid it and after that my clean status held.
I suppose the 200 Cr fine and "attitude adjustment" was done by the core game because a cop flagged me to pay my fines, but shouldn't that clear my Bounty System record without having to go to the Security Office and pay the fine again?
- phkb
- Impressively Grand Sub-Admiral
- Posts: 4830
- Joined: Tue Jan 21, 2014 10:37 pm
- Location: Writing more OXPs, because the world needs more OXPs.
Re: [WIP] Bounty system OXP
Bug in the Email System, fixed in next release.
It would clear the bounty of any local fines, but not necessarily of fines collected in other systems, which the police scan after you launched would have uncovered.
From the Bounty System wiki:
Special note: If a police vessel flags your ship to pay fines upon docking, the fine you pay will be the full amount and will not be reduced by a degrading component. This will only happen if your bounty is small, however. If you have a large bounty, police ships are more likely to attack you. If, after paying your fine, you are scanned again, the bounty may reappear in the current system.
Re: [WIP] Bounty system OXP
I agree with dybal, that behavior is non-intuitive. You would think the local cops would have noted your compliance after fining you. I think it is fine for the bounty to return if you go to a different system and are scanned there (so until you pay off the bounty in the original system or at an HQ, you are at risk of being an offender wherever you go), but as long as you are in the same system after paying the local offender tax, I think you should get to keep your clean status even if the local cops scan you again.
Re: [WIP] Bounty system OXP
The original offence was in another system, yes, but I went to Security Offices several times in that system to monitor the fine as the bounty decreased by helping police and there never was a local offence listed.
Re: [WIP] Bounty system OXP
The scanning isn't about local offences, it's an import of offences from elsewhere. I'm just suggesting that the import of external bounties should be limited once-per-exit-witchspace so if you pay the locals, they don't bother you again until you leave. Of course, they don't actually resolve your bounty elsewhere, they just take your money as a toll for not being shot.
- phkb
- Impressively Grand Sub-Admiral
- Posts: 4830
- Joined: Tue Jan 21, 2014 10:37 pm
- Location: Writing more OXPs, because the world needs more OXPs.
Re: [WIP] Bounty system OXP
That is probably a more intuitive way of dealing with it. I'll add it to the list.Milo wrote: ↑Tue Jul 07, 2020 12:22 pmThe scanning isn't about local offences, it's an import of offences from elsewhere. I'm just suggesting that the import of external bounties should be limited once-per-exit-witchspace so if you pay the locals, they don't bother you again until you leave. Of course, they don't actually resolve your bounty elsewhere, they just take your money as a toll for not being shot.
Re: [WIP] Bounty system OXP
Here is a suggested modification replacing this.$scanTarget (relevant section is in the middle but I optimized[?] the whole function):
Since the npcscan script is both a world script and a ship script, I think the don't apply out-of-system-bounties-again variable needs to be kept somewhere centralized, which is why I put it as worldScripts.BountySystem_Core._alreadyScannedPlayerInThisSystem. We don't have to worry about the case when the player leaves the system because any ships in the previous system are removed.
Below code is all for bountysystem_core.js:
Initialize:
Load (add to this.startUpComplete):
Save (add to this.playerWillSaveGame):
Clear (add to this.shipWillEnterWitchspace):
Docking (just showing the top lines of the function):
I considered that the player might pay a fine before having been scanned. That would imply that they were fined for a local offence only, so I think we should allow a scan to happen after that, which could apply a separate "out-of-system" bounty to them.
TODO: As an enhancement (scope creep?) to Bounty System, the warrant scan could include a manifest scan; then, you could check if any of the goods on the player's public manifest are illegal imports in the current system, and if so demand the player dump them or apply a fine or whatever... (making smuggling OXPs more important!) ... although slaves would have to be handled carefully, since escape pods count as them too. In this case, you'd want the ignore player check to only prevent re-applying out-of-system bounties, but still allow the manifest checks to happen repeatedly while the player is in-system. Since I've enclosed only the out-of-system bounty code in the ignore condition, you could add the manifest check outside that.
Incidentally, here is an unrelated minor optimization (string comparisons after booleans, instead of before):
Code: Select all
this.$scanTarget = function $scanTarget() {
var that = $scanTarget; // pointer to this function
var core = (that.core = that.core || worldScripts.BountySystem_Core); // cache worldScript reference in local property on this function
var w = (that.w = that.w || worldScripts.BountySystem_WarrantScanner); // cache worldScript reference in local property on this function
var npcscan = (that.npcscan = that.npcscan || worldScripts.BountySystem_NPCScan); // cache worldScript reference in local property on this function
var broadcastcomms = (that.broadcastcomms = that.broadcastcomms || worldScripts.BroadcastCommsMFD); // cache worldScript reference in local property on this function
var myShip = this.ship, myScript = myShip.script, myTarget = myScript._checkTarget;
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "running scanTarget :" + myShip);
// make sure ship is valid
if (!myShip.isValid) {
myScript._warrantScannerTimer.stop();
return;
}
if (myShip.target != myTarget || !myTarget.isValid) {
// somethings happened and their target has switched
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "target has shifted - cancelling scan :" + myShip);
myScript._warrantScannerTimer.stop();
myTarget = null;
myScript.$initialiseTimer();
return;
}
// is target still valid
var result = w.$targetIsValid(myShip);
if (result) {
// are we in range?
if (w.$targetInRange(myShip)) {
myScript._rangeCheck = 0;
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "scanning ship (" + myTarget + ") :" + myShip);
// ok, do a pass
myScript._scanPass += 1;
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "pass " + this._scanPass + " :" + myShip);
if (myScript._scanPass === 1 && myTarget.isPlayer) player.consoleMessage(expandDescription("[warrant-scan-detected]"), 5);
if (myScript._scanPass === 2 && myTarget.isPlayer === false) w.$npcReaction(myTarget, myShip);
// are we done?
if (myScript._scanPass >= myScript._warrantScannerTime) {
myScript._warrantScannerTimer.stop();
if (!myTarget.isPlayer || !core._alreadyScannedPlayerInThisSystem) { // only apply out-of-system bounties to the player once per system visit
if (myTarget.isPlayer) core._alreadyScannedPlayerInThisSystem = true; // remember that we did this
// ok, get the hidden bounty;
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "scan complete :" + myShip);
myScript._scannedList.push(myTarget);
var initial = myTarget.bounty;
var check = w.$checkBounty(myTarget, true, myShip); // returns sum of out-of-system bounties and imports any transferable bounties to the current system (this affects the calculation in shipWillDockWithStation that sets player bounty)
if (check > 0) { // an out-of-system bounty was found
if (myTarget.isPlayer && broadcastcomms && broadcastcomms._surrenderBounty > 0) { // player has a hidden bounty after surrendering to police with Broadcast Comms
broadcastcomms._surrenderBounty += check; // add bounty amount to Broadcast Comms' "hidden" value to be restored if the player commits another crime or doesn't go to the station
if (myScript._debugNPCScan && myScript._loggingLevel >= 1) log(this.name, "bounty of " + check + " added to Broadcast Comms' hidden bounty value for surrendered " + myTarget);
} else { // apply the bounty directly
myTarget.bounty += check;
if (myScript._debugNPCScan && myScript._loggingLevel >= 1) log(this.name, "bounty change of " + (myTarget.bounty - initial) + " for " + myTarget);
}
}
}
// add this target to all vessels in range who have the same scan class
npcscan.$addTargetToScannedList(myShip, myTarget); // call to worldScript function from ship-attached script
myScript._lastTarget = myTarget;
myTarget = null;
myScript.$initialiseTimer();
}
} else {
myScript._rangeCheck += 1;
// try to move in range of target so we can continue scanning
if (myShip.position.distanceTo(myTarget) < (myShip.scannerRange * 1.3) && myScript._rangeCheck < 30) {
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "attempting to get in range :" + myShip);
myShip.destination = myTarget.position;
myShip.desiredRange = myScript._warrantScannerRange - parseInt(Math.random * 1000) + 200;
myShip.desiredSpeed = myShip.maxSpeed;
} else {
// give up if the distance is too great, or the range check counter times out
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "unable to get in range of target (timeout or distance too far) :" + myShip);
myScript._warrantScannerTimer.stop();
myShip.target = null;
myTarget = null;
myScript.$initialiseTimer();
}
}
} else {
if (myScript._debugNPCScan && myScript._loggingLevel > 1) log(this.name, "target no longer valid :" + myShip);
myScript._warrantScannerTimer.stop();
myShip.target = null;
myTarget = null;
myScript.$initialiseTimer();
}
}
Below code is all for bountysystem_core.js:
Initialize:
Code: Select all
this._alreadyScannedPlayerInThisSystem = false; // do-once-per-system (not cleared when docked, only when jumping out) for importing out-of-system bounties so if player pays off the locals, they don't get a bounty again from a subsequent scan
Code: Select all
if (missionVariables.BountySystem_alreadyScannedPlayerInThisSystem) {
this._alreadyScannedPlayerInThisSystem = missionVariables.BountySystem_alreadyScannedPlayerInThisSystem;
delete missionVariables.BountySystem_alreadyScannedPlayerInThisSystem;
}
Code: Select all
missionVariables.BountySystem_alreadyScannedPlayerInThisSystem = this._alreadyScannedPlayerInThisSystem;
Code: Select all
this._alreadyScannedPlayerInThisSystem = false;
Code: Select all
this.shipWillDockWithStation = function (station) {
if (this._escapePod === true) {
this._changing = true;
player.bounty += this.$calculateBounty(system.ID); // add instead of setting so other OXPs can update it (currently known:
Broadcast Comms restores hidden bounty for players who surrendered to police)
this._changing = false;
this._escapePod = false;
}
TODO: As an enhancement (scope creep?) to Bounty System, the warrant scan could include a manifest scan; then, you could check if any of the goods on the player's public manifest are illegal imports in the current system, and if so demand the player dump them or apply a fine or whatever... (making smuggling OXPs more important!) ... although slaves would have to be handled carefully, since escape pods count as them too. In this case, you'd want the ignore player check to only prevent re-applying out-of-system bounties, but still allow the manifest checks to happen repeatedly while the player is in-system. Since I've enclosed only the out-of-system bounty code in the ignore condition, you could add the manifest check outside that.
Incidentally, here is an unrelated minor optimization (string comparisons after booleans, instead of before):
Code: Select all
this.$targetAttacked = function (whom, damageType, killed) {
// don't record anything if this is a simulator run
if (this.$simulatorRunning()) return;
var msgType = "attacked";
if (killed) msgType = "killed";
// player shot and killed other with lasers, q-bomb, or by ramming them
if (whom.isPiloted && !whom.isDerelict && !whom.isThargoid) {
if (damageType === "energy damage" || damageType === "cascade weapon" || damageType === "scrape damage") {
// who did we just kill?
if (whom.isPolice) {
this.$addOffence(msgType + " police");
} else {
// is there a police ship/station in range
// (check the holding array first though, so we can avoid doing "findLawVessels" with every laser shot)
if (whom.bounty === 0 && this._holding.indexOf(msgType + "innocent") === -1) {
var police = this.$findLawVessels(player.ship);
if (police.length > 0) this.$addOffence(msgType + " innocent");
}
}
}
}
}
Last edited by Milo on Tue Jul 14, 2020 10:54 pm, edited 2 times in total.
Re: [WIP] Bounty system OXP
worldScript caching for bountysystem_scanner.js:
Code: Select all
"use strict";
this.name = "BountySystem_WarrantScanner";
this.author = "phkb";
this.copyright = "2016 phkb";
this.description = "Routines for controlling the use of the Warrant scanner.";
this.licence = "CC BY-NC-SA 4.0";
this._debug = false; // turns on debug messages in the log
this._warrantScannerTimer = null; // timer object used when scanning NPC's
this._hideMFDTimer = null; // timer used to hide the MFD after a scan completes
//this._scannedShips = []; // list of ships scanned by the player
this._scanTimeMidPoint = 4; // point of time during a scan (in seconds) at which initial information is displayed.
this._lastTarget = null; // holding object of player's target when scanning started (so we can check if the player switches target and stops the scan)
this._mfdID = -1; // ID of the MFD that last held the Warrant Scanner
this._outputMode = 0; // mode = 0 standard MFD view, mode = 1, no MFD
this._scannerMode = 0; // 0 = manual scan, 1 = automatic scan (offenders only), 2 = auto scan everyone
this._overrideMode = false;
this._giveToNPC = true; // flag to control whether NPC's can get the warrant scanner
this._trueValues = ["yes", "1", 1, "true", true];
this._ficcInstalled = false;
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
if (worldScripts.BountySystem_Core._disabled) {
delete this.shipSpawned;
delete this.playerBoughtEquipment;
delete this.shipWillLaunchFromStation;
delete this.startUpComplete;
return;
}
// ensure station dock control has the important script properties noted
var sdc = worldScripts.StationDockControl;
if (sdc && sdc._propertiesToKeep) {
sdc._propertiesToKeep.push("_hiddenBounty");
sdc._propertiesToKeep.push("_storedHiddenBounty");
}
if (missionVariables.BountySystem_WarrantScanAuto) {
this._scannerMode = parseInt(missionVariables.BountySystem_WarrantScanAuto);
worldScripts.BountySystem_Core._warrantScannerMode = this._scannerMode;
}
if (worldScripts.FuelInjectionCruiseControl) this._ficcInstalled = true;
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
missionVariables.BountySystem_WarrantScanAuto = this._scannerMode;
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillLaunchFromStation = function (station) {
var equip = "";
var p = player.ship;
if (p.equipmentStatus("EQ_WARRANT_SCANNER") === "EQUIPMENT_OK" || p.equipmentStatus("EQ_WARRANT_SCANNER_PASSIVE") === "EQUIPMENT_OK") equip = "EQ_WARRANT_SCANNER";
if (p.equipmentStatus("EQ_WARRANT_SCANNER_POLICE") === "EQUIPMENT_OK" || p.equipmentStatus("EQ_WARRANT_SCANNER_POLICE_PASSIVE") === "EQUIPMENT_OK") equip = "EQ_WARRANT_SCANNER_POLICE";
if (equip != "") {
var eq = EquipmentInfo.infoForKey(equip);
p.script._warrantScannerTime = eq.scriptInfo.scan_time;
p.script._warrantScannerRange = p.scannerRange * eq.scriptInfo.scan_range;
}
// if the player doesn't have a way of seeing the target bounty, put the scanner mode into override
this._overrideMode = false;
if (this._scannerMode === 1 && p.equipmentStatus("EQ_SCANNER_SHOW_MISSILE_TARGET") != "EQUIPMENT_OK") this._overrideMode = true;
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function (equip) {
var p = player.ship;
// remove and refund warrant scanner (both versions)
if (equip === "EQ_WARRANT_SCANNER_REMOVAL") {
p.removeEquipment(equip);
var stn = p.dockedStation;
var eqSts = "";
var eqSts1 = p.equipmentStatus("EQ_WARRANT_SCANNER");
if (eqSts1 === "EQUIPMENT_OK" || eqSts1 === "EQUIPMENT_DAMAGED") {
var eq = EquipmentInfo.infoForKey("EQ_WARRANT_SCANNER");
p.removeEquipment("EQ_WARRANT_SCANNER");
eqSts = eqSts1;
}
eqSts1 = p.equipmentStatus("EQ_WARRANT_SCANNER_PASSIVE");
if (eqSts1 === "EQUIPMENT_OK" || eqSts1 === "EQUIPMENT_DAMAGED") {
var eq = EquipmentInfo.infoForKey("EQ_WARRANT_SCANNER_PASSIVE");
p.removeEquipment("EQ_WARRANT_SCANNER_PASSIVE");
eqSts = eqSts1;
}
var eqSts2 = p.equipmentStatus("EQ_WARRANT_SCANNER_POLICE");
if (eqSts2 === "EQUIPMENT_OK" || eqSts2 === "EQUIPMENT_DAMAGED") {
var eq = EquipmentInfo.infoForKey("EQ_WARRANT_SCANNER_POLICE");
p.removeEquipment("EQ_WARRANT_SCANNER_POLICE");
eqSts = eqSts2;
}
eqSts2 = p.equipmentStatus("EQ_WARRANT_SCANNER_POLICE_PASSIVE");
if (eqSts2 === "EQUIPMENT_OK" || eqSts2 === "EQUIPMENT_DAMAGED") {
var eq = EquipmentInfo.infoForKey("EQ_WARRANT_SCANNER_POLICE_PASSIVE");
p.removeEquipment("EQ_WARRANT_SCANNER_POLICE_PASSIVE");
eqSts = eqSts2;
}
// refund the cost of the equipment
if (eq) {
if (eqSts === "EQUIPMENT_OK") player.credits += (eq.price / 10) * stn.equipmentPriceFactor;
if (eqSts === "EQUIPMENT_DAMAGED") player.credits += ((eq.price / 10) * stn.equipmentPriceFactor) / 2;
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.shipSpawned = function (newship) {
if (newship.isShip === false) return;
// ignore these types
if (newship.isPlayer || newship.isRock || newship.isThargoid || newship.isCargo || newship.isDerelict || newship.isBeacon ||
newship.isStation || newship.isBoulder || newship.isWeapon || newship.isWormhole || newship.isVisualEffect || !newship.isPiloted) return;
// for some standard ships that gets spawned we want to create a secondary bounty value that the player can uncover using the warrant scanner
// some assassins
// some traders
// rarely hunters
// most pirates
// no miners/scavengers
// most of these increases will only be marginal (most 10 points, some 20, very few 30 and above)
// if the ship already has the property, we can exit
// this is most likely a relaunch at a station via SDC
if (newship.script.hasOwnProperty("_hiddenBounty")) return;
newship.script._hiddenBounty = 0;
if (newship.isPolice === false) {
if (Ship.roleIsInCategory(newship.primaryRole, "oolite-pirate")) {
if (Math.random() > 0.2) {
var b = parseInt(Math.random() * 10) + 10;
// some larger bounties
if (Math.random() > 0.8) {
b = parseInt(Math.random() * 20) + 30
}
// and rarely, some even larger ones
if (Math.random() > 0.95) {
b = parseInt(Math.random() * 40) + 50
}
newship.script._hiddenBounty = b;
if (this._debug) log(this.name, "adding pirate bounty for " + newship);
}
} else if (Ship.roleIsInCategory(newship.primaryRole, "oolite-assassin")) {
if (Math.random() > 0.5) {
var b = parseInt(Math.random() * 10) + 20;
// rarely some larger bounties
if (Math.random() > 0.92) {
b = parseInt(Math.random() * 20) + 40
}
// and even rarely, some even larger ones
if (Math.random() > 0.99) {
b = parseInt(Math.random() * 40) + 50
}
newship.script._hiddenBounty = b;
if (this._debug) log(this.name, "adding assassin bounty for " + newship);
}
} else if (Ship.roleIsInCategory(newship.primaryRole, "oolite-trader")) {
if (Math.random() > 0.8 && newship.name.indexOf("Medical") === 0) {
newship.script._hiddenBounty = parseInt(Math.random() * 10) + 5;
if (this._debug) log(this.name, "adding trader bounty for " + newship);
}
} else if (Ship.roleIsInCategory(newship.primaryRole, "oolite-bounty-hunter")) {
if (Math.random() > 0.98) {
newship.script._hiddenBounty = parseInt(Math.random() * 10) + 5;
if (this._debug) log(this.name, "adding hunter bounty for " + newship);
}
// most hunters (60%) will have the warrant scanner
if (this._giveToNPC === true) {
if (Math.random() > 0.4) {
if (this._debug) log(this.name, "adding equipment to " + newship);
newship.awardEquipment("EQ_WARRANT_SCANNER");
this.$addScannerRoutines(newship);
}
}
}
}
// store what the hidden bounty is in a separate spot so we can reset back to it if the ship jumps to another system
// allows us to simulate the same rules the player gets
newship.script._storedHiddenBounty = newship.script._hiddenBounty;
// add our shipExitedWormhole, shipDied and shipRemoved events to the ship
// monkey patch if necessary
if (newship.script.shipExitedWormhole) newship.script.$bounty_ovr_shipExitedWormhole = newship.script.shipExitedWormhole;
newship.script.shipExitedWormhole = this.$bounty_shipExitedWormhole;
if (newship.script.shipDied) newship.script.$bounty_ovr_shipDied = newship.script.shipDied;
newship.script.shipDied = this.$bounty_shipDied;
if (newship.script.shipRemoved) newship.script.$bounty_ovr_shipRemoved = newship.script.shipRemoved;
newship.script.shipRemoved = this.$bounty_shipRemoved;
if (newship.script.shipWillEnterWormhole) newship.script.$bounty_ovr_shipWillEnterWormhole = newship.script.shipWillEnterWormhole;
newship.script.shipWillEnterWormhole = this.$bounty_shipWillEnterWormhole;
if (this._giveToNPC === true) {
// only give it to police ships that are piloted, can actually move (ie not stations), and are not satellites.
if (newship.isPolice && newship.isPiloted && newship.maxSpeed > 0 && newship.hasRole("RSsatellite") === false) {
// all police vessels have the scanner
if (this._debug) log(this.name, "adding equipment to " + newship);
newship.awardEquipment("EQ_WARRANT_SCANNER_POLICE");
this.$addScannerRoutines(newship);
}
}
}
//-------------------------------------------------------------------------------------------------------------
this.equipmentDamaged = function (equipmentKey) {
// switch to override mode if the STE is damaged
if (equipmentKey === "EQ_SCANNER_SHOW_MISSILE_TARGET" && this._scannerMode === 1) this._overrideMode = true;
}
//-------------------------------------------------------------------------------------------------------------
this.equipmentRepaired = function (equipmentKey) {
// switch off override mode if the STE is repaired
if (equipmentKey === "EQ_SCANNER_SHOW_MISSILE_TARGET" && this._scannerMode === 1) this._overrideMode = false;
}
//-------------------------------------------------------------------------------------------------------------
this.shipTargetAcquired = function (target) {
var ts = target.script;
if (!ts) return;
if (!player.ship.weaponsOnline && !target.hasHostileTarget && target.alertCondition !== 3) return; // don't auto-scan when weapons are offline, unless target won't react (has a hostile target or is in red alert)
// if the scanner mode is set to automatically scan, and we haven't started scanning this ship, start it now
if (((this._scannerMode === 1 && target.bounty > 0 && this._overrideMode === false) || (this._scannerMode === 1 && this._overrideMode === true) || this._scannerMode === 2) && ts.hasOwnProperty("_warrantScanPosition") === false) { // removed player.ship.script._warrantScannerRange restriction
this.$startScan();
return;
}
// if we're already partway through scanning the target, automatically continue now
if (ts.hasOwnProperty("_warrantScanPosition") === true && ts._warrantScanPosition >= 0 && ts._warrantScanPosition < player.ship.script._warrantScannerTime) {
this.$startScan();
}
}
//-------------------------------------------------------------------------------------------------------------
this.activated = function $activated() {
var that = $activated; // pointer to this function
var s = (that.s = that.s || worldScripts.BountySystem_WarrantScanner); // cache reference to worldScript in local property on this function
if (s._warrantScannerTimer && s._warrantScannerTimer.isRunning) {
s._warrantScannerTimer.stop();
if (s._outputMode === 0) s.$turnOffMFD();
player.consoleMessage("Warrant scanner disengaged.");
return;
}
// is the equipment OK?
// theoretically the player can only have the standard scanner, but just in case the rules change later...
if (player.ship.equipmentStatus("EQ_WARRANT_SCANNER") != "EQUIPMENT_OK" && player.ship.equipmentStatus("EQ_WARRANT_SCANNER_POLICE") != "EQUIPMENT_OK" &&
player.ship.equipmentStatus("EQ_WARRANT_SCANNER_PASSIVE") != "EQUIPMENT_OK" && player.ship.equipmentStatus("EQ_WARRANT_SCANNER_POLICE_PASSIVE") != "EQUIPMENT_OK") return;
// do we have a station target and is it a main station?
if (s.$targetIsValid(player.ship) === false) return;
// automatically switch to Non-MFD mode if there are no available slots
if (s._outputMode === 0 && s.$isMFDSlotAvailable() === false) s._outputMode = 1;
// TWEAK: automatically switch to MFD mode if there is an available slot (thanks to Nite Owl)
if (s._outputMode === 1 && s.$isMFDSlotAvailable() === true) s._outputMode = 0;
var p = player.ship;
// have we started scanning this ship already?
var checkScan = s.$existingShipScanPosition(p.target);
if (checkScan >= p.script._warrantScannerTime) {
if (s._outputMode === 1) player.consoleMessage("Ship already scanned.");
if (s._outputMode === 0) {
s.$updateMFD("Warrant Scanner:\nShip already scanned.");
if (s._hideMFDTimer && s._hideMFDTimer.isRunning) s._hideMFDTimer.stop();
s._hideMFDTimer = new Timer(s, s.$turnOffMFD, 5, 0);
}
return;
}
if (s._outputMode === 1) player.consoleMessage("Scanning started.");
s._warrantScannerTimer = new Timer(s, s.$scanProcess, 1, 1);
s._lastTarget = p.target;
if (s._hideMFDTimer && s._hideMFDTimer.isRunning) s._hideMFDTimer.stop();
if (s._outputMode === 0) s.$updateMFD("Warrant Scanner:\nInitialising...\n");
}
//-------------------------------------------------------------------------------------------------------------
this.mode = function $mode() {
var that = $mode; // pointer to this function
var s = (that.s = that.s || worldScripts.BountySystem_WarrantScanner); // cache reference to worldScript in local property on this function
if (s._outputMode === 0) {
s._outputMode = 1;
player.consoleMessage("Switched to Non-MFD mode.");
return;
}
if (s._outputMode === 1) {
s._outputMode = 0;
player.consoleMessage("Switched to MFD mode.");
return;
}
}
//-------------------------------------------------------------------------------------------------------------
this.$addScannerRoutines = function $addScannerRoutines(newship) {
var that = $addScannerRoutines; // pointer to this function
var w = (that.w = that.w || worldScripts.BountySystem_NPCScan); // cache reference to worldScript in local property on this function
newship.script.$initialiseTimer = w.$initialiseTimer;
newship.script.$checkScannerForTarget = w.$checkScannerForTarget;
newship.script.$scanTarget = w.$scanTarget;
newship.script.$initialiseTimer();
}
//-------------------------------------------------------------------------------------------------------------
this.$startScan = function () {
if (this._hideMFDTimer && this._hideMFDTimer.isRunning) this._hideMFDTimer.stop();
if (this._warrantScannerTimer && this._warrantScannerTimer.isRunning) this._warrantScannerTimer.stop();
this.activated();
}
//-------------------------------------------------------------------------------------------------------------
this.$scanProcess = function $scanProcess() {
var that = $scanProcess; // pointer to this function
var w = (that.w = that.w || worldScripts.BountySystem_WarrantScanner); // cache reference to worldScript in local property on this function
var p = player.ship;
// player switched target while scanning or target isn't valid anymore (jumped out/destroyed) - auto-off triggered
if (p.target != this._lastTarget || this.$targetIsValid(p) === false) {
player.consoleMessage("Warrant scanner disengaged.");
if (this._outputMode === 0) this.$turnOffMFD();
this._warrantScannerTimer.stop();
return;
}
// add this ship to the array
var scanPos = this.$existingShipScanPosition(p.target);
//if (scanPos === 0) this._scannedShips.push({ship:p.target, scanPosition:0});
var mfdText = "Warrant Scanner:\n";
var outOfRange = false;
// make sure target is still in range - but put scan on hold until it is
if (this.$targetInRange(p) === false) {
mfdText += "Ship out of range.\n";
outOfRange = true;
} else {
scanPos += 1;
}
if (this._outputMode === 1 && outOfRange === false) player.consoleMessage(((scanPos / p.script._warrantScannerTime) * 100).toFixed(0) + "% complete");
if (scanPos === p.script._warrantScannerTime) {
mfdText += "Scan complete.\n";
} else {
mfdText += "Scanning: " + ((scanPos / p.script._warrantScannerTime) * 100).toFixed(0) + "% complete\n";
}
if (scanPos >= this._scanTimeMidPoint) {
var viewrole = this.$translateRole(p.target.primaryRole);
mfdText += "\nPilot: " + this.$extractPilotName(p.target) + "\n" + (viewrole != "Unknown" ? viewrole + "\n" : "");
// only display the message once for consoleMessage mode
if (this._outputMode === 1 && scanPos === this._scanTimeMidPoint && outOfRange === false) {
player.consoleMessage("Pilot is " + this.$extractPilotName(p.target) + (viewrole != "Unknown" ? " (" + viewrole + ")" : ""));
}
}
p.target.script._warrantScanPosition = scanPos;
// update the scan position for this ship
/*for (var i = 0; i < this._scannedShips.length; i++) {
if (this._scannedShips[i].ship === p.target) this._scannedShips[i].scanPosition = scanPos;
}*/
// NPC reaction after 2 seconds
if (scanPos === 2) {
// decide if they will flee, attack or ignore
this.$npcReaction(p.target, p);
}
// finish the scan
if (scanPos >= p.script._warrantScannerTime) {
if (this._outputMode === 1) player.consoleMessage("Scan complete.");
this._warrantScannerTimer.stop();
// will this ship get a bounty?
var check = w.$checkBounty(p.target, true, p);
if (check > 0) {
mfdText += "\nAdditional warrants of " + formatCredits(check, false, true) + "\napplied to target.";
if (this._outputMode === 1) player.consoleMessage("Additional warrants of " + formatCredits(check, false, true) + " applied to target.");
p.target.bounty += check;
} else {
if (this._outputMode === 1) player.consoleMessage("No additional warrants found for target.");
mfdText += "\nNo additional warrants\nfound for target.";
}
if (this._outputMode === 0) {
if (this._hideMFDTimer && this._hideMFDTimer.isRunning) this._hideMFDTimer.stop();
this._hideMFDTimer = new Timer(this, this.$turnOffMFD, 10, 0);
}
}
if (this._outputMode === 0) this.$updateMFD(mfdText);
}
//-------------------------------------------------------------------------------------------------------------
// checks if we have an MFD slot available (a blank spot or a slot currently allocated to this OXP.
// Returns true if a spot is found, otherwise false
this.$isMFDSlotAvailable = function () {
var p = player.ship;
var result = false;
for (var i = 0; i < p.multiFunctionDisplayList.length; i++) {
if (!p.multiFunctionDisplayList[i] || (p.multiFunctionDisplayList[i] === "" || p.multiFunctionDisplayList[i] === this.name)) {
result = true;
}
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
this.$updateMFD = function (text) {
var p = player.ship;
// set the text in the MFD
p.setMultiFunctionText(this.name, text, false);
// if the hud is hidden don't try an update - it will get confusing as to which mfd slot is open or not.
if (p.hudHidden === false) {
// find the slot currently set for this MFD
this.$findMFDID();
// if we haven't got a set slot (this._mfdID === -1) or the set slot we had is now unavailable...
if (this._mfdID === -1 ||
(p.multiFunctionDisplayList[this._mfdID] && p.multiFunctionDisplayList[this._mfdID] != "" && p.multiFunctionDisplayList[this._mfdID] != this.name)) {
// find a free slot
// first, make sure we reset our slot id marker (in the case where the previous one is in use)
this._mfdID = -1;
// search for a free slot
for (var i = 0; i < p.multiFunctionDisplayList.length; i++) {
if (!p.multiFunctionDisplayList[i] || p.multiFunctionDisplayList[i] === "") {
this._mfdID = i;
break;
}
}
}
// we have a free slot, so force the mfd to display
if (this._mfdID != -1) p.setMultiFunctionDisplay(this._mfdID, this.name);
}
}
//-------------------------------------------------------------------------------------------------------------
// records the index of the MFD that currently holds the warrant scanner mfd
this.$findMFDID = function () {
var p = player.ship;
if (p.isValid === false || !p.multiFunctionDisplayList) return;
for (var i = 0; i < p.multiFunctionDisplayList.length; i++) {
if (p.multiFunctionDisplayList[i] === this.name) this._mfdID = i;
}
}
//-------------------------------------------------------------------------------------------------------------
// hides all instances of the warrant scanner MFD
this.$turnOffMFD = function $turnOffMFD() {
var p = player.ship;
if (p.isValid === false || !p.multiFunctionDisplayList) return;
for (var i = 0; i < p.multiFunctionDisplayList.length; i++) {
if (p.multiFunctionDisplayList[i] === this.name) {
p.setMultiFunctionDisplay(i, "");
}
}
}
//-------------------------------------------------------------------------------------------------------------
// gets a readable form of the pilot's name
this.$extractPilotName = function (ship) {
var pilotName = "";
var pilot = ship.crew[0];
pilotName = pilot.name + (this._outputMode === 1 ? ", " : "\n") + pilot.description;
return pilotName;
}
//-------------------------------------------------------------------------------------------------------------
// returns the scan position (ie. how far through the scan we have gotten) for a particular ship
this.$existingShipScanPosition = function (ship) {
if (ship.script.hasOwnProperty("_warrantScanPosition") === false) ship.script._warrantScanPosition = 0;
return ship.script._warrantScanPosition;
/*
for (var i = 0; i < this._scannedShips.length; i++) {
if (this._scannedShips[i].ship === ship) return this._scannedShips[i].scanPosition;
}
return 0;
*/
}
//-------------------------------------------------------------------------------------------------------------
// checks the target of the source ship to ensure it is still valid. If so, returns true.
// when false, scanning process will stop
this.$targetIsValid = function (source) {
var ship = source.target;
var result = true;
// do we have a station target and is it a main station?
if (!ship || ship.isValid === false) {
if (source.isPlayer) player.consoleMessage("No target selected.");
result = false;
}
if (result === true && ship.isStation) {
if (source.isPlayer) player.consoleMessage("Scanner will not work on stations.");
result = false;
}
if (result === true && (ship.isPiloted === false || ship.isThargoid || ship.hasRole("escape-capsule"))) {
if (source.isPlayer) player.consoleMessage("No valid target selected.");
result = false;
}
if (result === true && (source.injectorsEngaged || (source.isPlayer && this._ficcInstalled && source.script._ficcEngaged === true) || source.torusEngaged === true)) {
if (source.isPlayer) player.consoleMessage("Unable to scan at injector or torus speed.");
result = false;
}
if (result === true && source.isCloaked) {
if (source.isPlayer) player.consoleMessage("Scanner will not work when cloaked.");
result = false;
}
if (result === true && ship.isCloaked) {
if (source.isPlayer) player.consoleMessage("Scanner unable to target cloaked ship.");
result = false;
}
return result;
}
//-------------------------------------------------------------------------------------------------------------
// checks range to source's target. when in range, returns true
// otherwise false. When false, scan will continue but be on hold.
this.$targetInRange = function (source) {
var dist = source.position.distanceTo(source.target);
if (source.script._debugNPCScan === true) log(this.name, "dist to target = " + dist + " for " + source);
// are we too far away for a good scan?
if (dist > source.script._warrantScannerRange) {
if (source.isPlayer) {
if (this._outputMode === 1) player.consoleMessage("Ship out of range.");
}
return false;
}
return true;
}
//-------------------------------------------------------------------------------------------------------------
// checks the hidden bounty for a particular ship. doRemove will do an "official" search, in which case the ship will be removed from the list
// basically, once a ship has been scanned with the warrant scanner we don't want the ship to get scanned again and increase their bounty multiple times.
// so we remove it for an official scan.
this.$checkBounty = function $checkBounty (checkship, doRemove, source) {
var bounty = 0;
if (checkship.isPlayer) {
// uncover the player's bounties
var that = $checkBounty; // pointer to this function
var w = (that.w = that.w || worldScripts.BountySystem_Core); // cache reference to worldScript in local property on this function
w.$uncoverBounties(source);
w.shipExitedWitchspace();
} else {
var idx = -1;
bounty = checkship.script._hiddenBounty;
// if this is an official scan, reset the ships hiddenBounty value so they don't get multiple bounty increases
if (doRemove === true && bounty > 0) checkship.script._hiddenBounty = 0;
}
return bounty;
}
//-------------------------------------------------------------------------------------------------------------
// updates the hidden bounty for a particular ship, or adds it if the ship isn't in the list already
this.$setBounty = function (checkship, newbounty) {
checkship.script._hiddenBounty = newbounty;
}
//-------------------------------------------------------------------------------------------------------------
this.$npcReaction = function (ship, source) {
// don't do anything if the ship is under attack or at condition red - they're too busy to notice
if (ship.hasHostileTarget || ship.alertCondition === 3) return;
// check if they've got something to hide
var check = this.$checkBounty(ship, false, source);
if (check === 0) return;
// count up the number of ships in range that might be doing the scan
var ships = ship.checkScanner(true);
var inRange = 0;
if (ships) {
for (var i = 0; i < ships.length; i++) {
var groupMbr = false;
// check if this ship is actually a member of the same group as the target
if (ships[i].group && ships[i].group.containsShip(ship)) groupMbr = true;
if (ships[i].isPiloted === true && ships[i].isStation === false && ships[i].isThargoid === false && groupMbr === false &&
ship.position.distanceTo(ships[i]) <= source.script._warrantScannerRange) inRange += 1;
}
}
if (ship.equipmentStatus("EQ_CLOAKING_DEVICE") === "EQUIPMENT_OK") {
// turn on the cloak to evade detection
if (this._debug) log(this.name, "cloaking " + ship);
ship.isCloaked = true;
}
// if there's only one ship in range, then it's obvious who the scanner is
if (inRange === 1) {
ship.target = source;
if (source.isPolice === false && ship.threatAssessment(false) > source.threatAssessment(false) && ship.withinStationAegis === false) {
if (this._debug) log(this.name, "attack mode(1) engaged for " + ship + " against " + source);
ship.performAttack();
return;
} else {
if (this._debug) log(this.name, "flee mode(1) engaged for " + ship + " against " + source);
ship.performFlee();
return;
}
}
// won't know who the perpetrator is if more than one ship in range
if (inRange > 1) return;
// otherwise, they'll know exactly who it is
// they're clear, but it's still not friendly
// police will ignore
// pirates will most likely attack
// traders will sometimes attack or sometimes flee
// assassins will attack
// hunters will sometimes attack
// if the one scanning is a police vessel, don't do anything.
if (source.isPolice) return;
if (Ship.roleIsInCategory(ship.primaryRole, "oolite-pirate") && Math.random() > 0.8) {
if (this._debug) log(this.name, "attack mode(2) engaged for " + ship + " against " + source);
ship.target = source;
ship.performAttack();
return;
}
if (Ship.roleIsInCategory(ship.primaryRole, "oolite-assassin") && ship.withinStationAegis === false && Math.random() > 0.8) {
if (this._debug) log(this.name, "attack mode(3) engaged for " + ship + " against " + source);
ship.target = source;
ship.performAttack();
return;
}
if (Ship.roleIsInCategory(ship.primaryRole, "oolite-trader") && ship.withinStationAegis === false && Math.random() > 0.9 && ship.threatAssessment(false) > source.threatAssessment(false)) {
if (this._debug) log(this.name, "attack mode(4) engaged for " + ship + " against " + source);
ship.target = source;
ship.performAttack();
return;
}
if (Ship.roleIsInCategory(ship.primaryRole, "oolite-trader") && ship.withinStationAegis === false && Math.random() > 0.3) {
if (this._debug) log(this.name, "flee mode(2) engaged for " + ship + " against " + source);
ship.target = source;
ship.performFlee();
return;
}
if (Ship.roleIsInCategory(ship.primaryRole, "oolite-bounty-hunter") && ship.withinStationAegis === false && Math.random() > 0.98) {
if (this._debug) log(this.name, "attack mode(5) engaged for " + ship + " against " + source);
ship.target = source;
ship.performAttack();
return;
}
}
//-------------------------------------------------------------------------------------------------------------
this.$translateRole = function (role) {
switch (role) {
case "hunter":
case "hunter-medium":
case "hunter-heavy":
return "Known bounty hunter";
case "pirate":
case "pirate-light-fighter":
case "pirate-medium-fighter":
case "pirate-heavy-fighter":
case "pirate-light-freighter":
case "pirate-medium-freighter":
case "pirate-heavy-freighter":
case "pirate-aegis-raider":
case "pirate-interceptor":
case "ftzpirate":
return "Known pirate";
case "trader":
case "trader-courier":
case "trader-courier+":
case "trader-smuggler":
return "Known trader";
case "assassin-light":
case "assassin-medium":
case "assassin-heavy":
return "Known assassin";
case "police":
case "police-station-patrol":
case "police-witchpoint-patrol":
return "Known police officer";
}
return "Unknown";
}
//-------------------------------------------------------------------------------------------------------------
this.$bounty_shipExitedWormhole = function () {
if (this.ship.script.$bounty_ovr_shipExitedWormhole) this.ship.script.$bounty_ovr_shipExitedWormhole;
if (this.ship.script.hasOwnProperty("_hiddenBounty") === false) return;
// if this ship got scanned and had its hidden bounty applied, remove and reset when we exit a wormhole
this.ship.script._warrantScanPosition = 0;
if (this.ship.script._storedHiddenBounty > 0 && this.ship.script._hiddenBounty === 0) {
this.ship.bounty -= this.ship.script._storedHiddenBounty;
if (this.ship.bounty > 0) {
// reset back to zero - assume any bounty in that system was local
this.ship.bounty = 0;
// then we need to determine if this ship has a local bounty in the new system as well
if (Math.random() > 0.4) {
var sys = System.infoForSystem(galaxyNumber, this.ship.destinationSystem);
switch (this.ship.primaryRole) {
case "trader":
if (Math.random() > 0.6) this.ship.setBounty(Math.ceil(Math.random() * 20), "setup actions");
break;
case "trader-smuggler":
case "trader-smuggler+":
this.ship.setBounty(Math.ceil(Math.random() * 20), "setup actions");
if (this.ship.bounty > this.ship.cargoSpaceCapacity * 2) {
this.ship.bounty = this.ship.cargoSpaceCapacity * 2;
}
break;
case "pirate":
this.ship.setBounty(20 + sys.government + (this.ship.group ? this.ship.group.count : 0) + Math.floor(Math.random() * 8), "setup actions");
break;
case "pirate-interceptor":
this.ship.setBounty(50 + sys.government + Math.floor(Math.random() * 36), "setup actions");
break;
case "pirate-light-fighter":
case "pirate-medium-fighter":
case "pirate-heavy-fighter":
this.ship.setBounty(20 + sys.government + Math.floor(Math.random() * 12), "setup actions");
break;
case "pirate-light-freighter":
case "pirate-medium-freighter":
case "pirate-heavy-freighter":
this.ship.setBounty(60 + sys.government + Math.floor(Math.random() * 8), "setup actions");
break;
case "pirate-aegis-raider":
this.ship.setBounty(50 + sys.government + Math.floor(Math.random() * 36), "setup actions");
break;
}
}
}
this.ship.script._hiddenBounty = this.ship.script._storedHiddenBounty;
}
}
//-------------------------------------------------------------------------------------------------------------
this.$bounty_shipDied = function (whom, why) {
if (this.ship.script.$bounty_ovr_shipDied) this.ship.script.$bounty_ovr_shipDied(whom, why);
// clean up timers
if (this.ship.script._checkTimer && this.ship.script._checkTimer.isRunning) {
this.ship.script._checkTimer.stop();
delete this.ship.script._checkTimer;
}
if (this.ship.script._warrantScannerTimer && this.ship.script._warrantScannerTimer.isRunning) {
this.ship.script._warrantScannerTimer.stop();
delete this.ship.script._warrantScannerTimer;
}
}
//-------------------------------------------------------------------------------------------------------------
this.$bounty_shipRemoved = function (suppressDeathEvent) {
if (this.ship.script.$bounty_ovr_shipRemoved) this.ship.script.$bounty_ovr_shipRemoved(suppressDeathEvent);
// clean up timers
if (this.ship.script._checkTimer && this.ship.script._checkTimer.isRunning) {
this.ship.script._checkTimer.stop();
delete this.ship.script._checkTimer;
}
if (this.ship.script._warrantScannerTimer && this.ship.script._warrantScannerTimer.isRunning) {
this.ship.script._warrantScannerTimer.stop();
delete this.ship.script._warrantScannerTimer;
}
}
//-------------------------------------------------------------------------------------------------------------
this.$bounty_shipWillEnterWormhole = function () {
if (this.ship.script.$bounty_ovr_shipWillEnterWormhole) this.ship.script.$bounty_ovr_shipWillEnterWormhole();
// clean up timers
if (this.ship.script._checkTimer && this.ship.script._checkTimer.isRunning) {
this.ship.script._checkTimer.stop();
delete this.ship.script._checkTimer;
}
if (this.ship.script._warrantScannerTimer && this.ship.script._warrantScannerTimer.isRunning) {
this.ship.script._warrantScannerTimer.stop();
delete this.ship.script._warrantScannerTimer;
}
}
Re: [WIP] Bounty system OXP
I noticed that the time necessary to be possible to pay a fine for a given offence doesn't start counting from the offence date, but from the date the player leaves the system where the offence was commited.
I think that's a huge in-universe story inconsistency: since it's GalCop that keeps tab of those dates and when the fine becomes payable, I ask: how does GalCop _knows_ when an offender leaves a given system? The offender knows, but how could anyone know for sure, always?
The only date GalCop knows, for sure, is the date the offence was commited... why not start counting the days till the fine is payable from that?
I think that's a huge in-universe story inconsistency: since it's GalCop that keeps tab of those dates and when the fine becomes payable, I ask: how does GalCop _knows_ when an offender leaves a given system? The offender knows, but how could anyone know for sure, always?
The only date GalCop knows, for sure, is the date the offence was commited... why not start counting the days till the fine is payable from that?
Last edited by dybal on Sun Jul 19, 2020 9:44 pm, edited 1 time in total.
- phkb
- Impressively Grand Sub-Admiral
- Posts: 4830
- Joined: Tue Jan 21, 2014 10:37 pm
- Location: Writing more OXPs, because the world needs more OXPs.
Re: [WIP] Bounty system OXP
Thanks Dybal, that does make more sense. I’ll add something along these lines into the pending release.
- phkb
- Impressively Grand Sub-Admiral
- Posts: 4830
- Joined: Tue Jan 21, 2014 10:37 pm
- Location: Writing more OXPs, because the world needs more OXPs.
Re: [WIP] Bounty system OXP
Version 0.9 has been released. Changes since 0.7:
- Date applied to any offences is the date of the first offence (was previously the date the player left the system).
- Bug fixes for appeal processing.
- Warrant Scanner in auto-scan mode will now open MFD even if target is out of range.
- Performance improvements for the scanning process.
- If player is scanned in a system and bounties uncovered, and they are forced to deal with those bounties at the station, subsequent scans will not reapply bounty.
- Code refactoring.
Re: [WIP] Bounty system OXP
Did you not include the Broadcast Comms integration or just left it out of the change log?