Adjust AIs

traderAI for courier and smuggler variants
bountyHunterAI to limit patrol length
This commit is contained in:
cim 2013-08-08 16:00:20 +01:00
parent 7a42c59c90
commit 14d4bb555a
4 changed files with 247 additions and 59 deletions

View File

@ -26,6 +26,7 @@ MA 02110-1301, USA.
"use strict";
// this is the AI version for a local patrol
this.name = "Oolite Bounty Hunter AI";
this.version = "1.79";
@ -56,6 +57,16 @@ this.aiStarted = function() {
behaviour: ai.behaviourRespondToDistressCall,
reconsider: 20
},
/* Regroup if necessary, but act relatively
* independently. Bounty hunters are not like police
* patrols. */
{
preconfiguration: ai.configurationAppointGroupLeader,
condition: ai.conditionGroupIsSeparated,
configuration: ai.configurationSetDestinationToGroupLeader,
behaviour: ai.behaviourApproachDestination,
reconsider: 15
},
/* Check for profitable targets */
{
preconfiguration: ai.configurationCheckScanner,
@ -91,18 +102,70 @@ this.aiStarted = function() {
behaviour: ai.behaviourEnterWitchspace,
reconsider: 20
},
/* Nothing interesting here. Patrol for a bit */
{
condition: ai.conditionHasWaypoint,
configuration: ai.configurationSetDestinationToWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
},
/* No patrol route set up. Make one */
{
configuration: ai.configurationSetWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
condition: ai.conditionIsGroupLeader,
truebranch: [
/* Nothing interesting here. Patrol for a bit. Patrol
* until away from planet; on return to planet,
* dock */
{
condition: ai.conditionHasWaypoint,
configuration: ai.configurationSetDestinationToWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
},
{
condition: ai.conditionHasSelectedStation,
truebranch: [
{
condition: ai.conditionSelectedStationNearby,
configuration: ai.configurationSetSelectedStationForDocking,
behaviour: ai.behaviourDockWithStation,
reconsider: 30
},
{
condition: ai.conditionSelectedStationNearMainPlanet,
truebranch: [
{
notcondition: ai.conditionMainPlanetNearby,
configuration: ai.configurationSetDestinationToMainPlanet,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
}
]
},
// either the station isn't near the planet, or we are
{
configuration: ai.configurationSetDestinationToSelectedStation,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
}
]
},
{
condition: ai.conditionMainPlanetNearby,
truebranch: [
{
condition: ai.conditionPatrolIsOver,
configuration: ai.configurationSelectRandomTradeStation,
behaviour: ai.behaviourReconsider
}
]
},
/* No patrol route set up. Make one */
{
configuration: ai.configurationSetWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
}
],
/* then follow the group leader */
falsebranch: [
{
behaviour: ai.behaviourFollowGroupLeader,
reconsider: 15
}
],
}
]);
]);
}

View File

@ -36,6 +36,16 @@ this.aiStarted = function() {
ai.setParameter("oolite_flag_surrendersEarly",true);
ai.setCommunicationsRole("trader");
// same AI works for freighters, couriers and smugglers with minimal
// modification
if (this.ship.primaryRole == "trader-smuggler")
{
ai.setParameter("oolite_flag_fleesPreemptively",true);
}
else if (this.ship.primaryRole == "trader-courier")
{
ai.setParameter("oolite_flag_noDockingUntilDestination",true);
}
ai.setPriorities([
@ -102,8 +112,8 @@ this.aiStarted = function() {
// jump to another system if possible, sunskim if not
falsebranch: [
{
condition: ai.conditionCanWitchspaceOut,
configuration: ai.configurationSelectWitchspaceDestination,
preconfiguration: ai.configurationSelectWitchspaceDestinationOutbound,
condition: ai.conditionCanWitchspaceOnRoute,
behaviour: ai.behaviourEnterWitchspace,
reconsider: 20
},

View File

@ -91,6 +91,10 @@ this.AILib = function(ship)
function _reconsiderList(priorities) {
logging = this.getParameter("oolite_flag_behaviourLogging")
var pl = priorities.length;
if (logging)
{
log(this.ship.name,"Considering branch with "+pl+" entries");
}
for (var i = 0; i < pl; i++)
{
if (logging)
@ -385,7 +389,7 @@ this.AILib = function(ship)
/* Requests reconsideration of behaviour ahead of schedule. */
this.reconsiderNow = function()
{
_resetReconsideration.call(this,0.5);
_resetReconsideration.call(this,0.1);
}
@ -519,9 +523,14 @@ AILib.prototype.cruiseSpeed = function()
}
var cruise = this.ship.maxSpeed * 0.8;
var ignore = this.ship.maxSpeed / 4;
var grouped = false;
if (this.ship.group)
{
var gs = this.ship.group.ships;
if (gs.length > 1)
{
grouped = true;
}
for (var i = gs.length-1 ; i >= 0 ; i--)
{
var spd = gs[i].maxSpeed;
@ -534,6 +543,10 @@ AILib.prototype.cruiseSpeed = function()
if (this.ship.escortGroup)
{
var gs = this.ship.escortGroup.ships;
if (gs.length > 1)
{
grouped = true;
}
for (var i = gs.length-1 ; i >= 0 ; i--)
{
var spd = gs[i].maxSpeed;
@ -543,6 +556,11 @@ AILib.prototype.cruiseSpeed = function()
}
}
}
if (!grouped)
{
// not in a group, so don't need to slow down for others to catch up
cruise = this.ship.maxSpeed;
}
this.__ltcache.cruiseSpeed = cruise;
return cruise;
}
@ -806,6 +824,42 @@ AILib.prototype.respondToThargoids = function(whom,passon)
}
AILib.prototype.setWitchspaceRouteTo = function(dest)
{
if (!dest)
{
return this.configurationSelectWitchspaceDestination();
}
if (dest == system.ID)
{
this.setParameter("oolite_witchspaceDestination",-1);
return;
}
var info = System.infoForSystem(galaxyNumber,dest);
if (system.info.distanceToSystem(info) < this.ship.fuel)
{
this.setParameter("oolite_witchspaceDestination",dest);
return;
}
else
{
var route = system.info.routeToSystem(info);
if (!route)
{
this.setParameter("oolite_witchspaceDestination",-1);
return;
}
var next = route.route[1];
if (system.info.distanceToSystem(System.infoForSystem(galaxyNumber,next)) < this.ship.fuel)
{
this.setParameter("oolite_witchspaceDestination",next);
return;
}
this.setParameter("oolite_witchspaceDestination",null);
}
}
AILib.prototype.threatAssessment = function(ship,full)
{
return worldScripts["oolite-libPriorityAI"]._threatAssessment(ship,full);
@ -1000,6 +1054,12 @@ AILib.prototype.conditionLosingCombat = function()
{
return false;
}
if (this.getParameter("oolite_flag_fleesPreemptively") && this.ship.fuel > 0 && this.ship.equipmentStatus("EQ_FUEL_INJECTION") == "EQUIPMENT_OK")
{
// ships of this behaviour will run away from anything if they
// still have fuel
return true;
}
var lastThreat = this.getParameter("oolite_lastFleeing");
if (lastThreat != null && this.distance(lastThreat) < 25600)
{
@ -1153,6 +1213,21 @@ AILib.prototype.conditionMothershipUnderAttack = function()
/*** Navigation-related conditions ***/
AILib.prototype.conditionCanWitchspaceOnRoute = function()
{
if (!this.ship.hasHyperspaceMotor)
{
return false;
}
var dest = this.getParameter("oolite_witchspaceDestination");
if (dest == null || dest == -1)
{
return false;
}
return (system.info.distanceToSystem(System.infoForSystem(galaxyNumber,dest)) <= this.ship.fuel);
}
AILib.prototype.conditionCanWitchspaceOut = function()
{
if (!this.ship.hasHyperspaceMotor)
@ -1701,22 +1776,24 @@ AILib.prototype.conditionCanScoopCargo = function()
AILib.prototype.conditionCargoIsProfitableHere = function()
{
/* TODO: this should be handled in the trader AI itself rather
* than using this condition. This is a temporary hack to test
* other bits */
if (this.ship.AIScript.oolite_intership.dest_system && this.ship.AIScript.oolite_intership.dest_system == system.ID)
// cargo is always considered profitable in the designated
// destination system (assume they have a prepared buyer)
if (this.ship.destinationSystem && this.ship.destinationSystem == system.ID)
{
return true;
}
if (this.ship.AIScript.oolite_intership.source_system && this.ship.AIScript.oolite_intership.source_system == system.ID)
// cargo is never considered profitable in the designated source
// system (or you could get ships launching and immediately
// redocking)
if (this.ship.homeSystem && this.ship.homeSystem == system.ID)
{
return false;
}
// and allow ships to be given multi-system trips if wanted
if (this.getParameter("oolite_flag_noDockingUntilDestination"))
{
return false;
}
/* TODO: in the Mainly X systems, it's not impossible for
* PLENTIFUL_GOODS to generate a hold which is profitable in that
* system, and SCARCE_GOODS not to do so. Cargo should never be
* profitable in its origin system. */
if (!system.mainStation)
{
@ -1857,6 +1934,12 @@ AILib.prototype.conditionMissileOutOfFuel = function()
}
AILib.prototype.conditionPatrolIsOver = function()
{
return this.ship.distanceTravelled > 200000;
}
AILib.prototype.conditionWitchspaceEntryRequested = function()
{
return (this.getParameter("oolite_witchspaceWormhole") != null);
@ -3158,6 +3241,20 @@ AILib.prototype.configurationSelectWitchspaceDestination = function()
}
AILib.prototype.configurationSelectWitchspaceDestinationInbound = function()
{
var dest = this.ship.homeSystem;
this.setWitchspaceRouteTo(dest);
}
AILib.prototype.configurationSelectWitchspaceDestinationOutbound = function()
{
var dest = this.ship.destinationSystem;
this.setWitchspaceRouteTo(dest);
}
/*** Destination configuration ***/
AILib.prototype.configurationSetDestinationToNearestFriendlyStation = function()

View File

@ -922,9 +922,9 @@ this._addFreighter = function(pos)
{
t[0].bounty = 0;
}
t[0].AIScript.oolite_intership.source_system = this._weightedNearbyTradeSystem();
t[0].homeSystem = this._weightedNearbyTradeSystem();
this._setFuel(t[0]);
t[0].AIScript.oolite_intership.dest_system = system.ID;
t[0].destinationSystem = system.ID;
t[0].setCargoType("SCARCE_GOODS");
}
}
@ -941,6 +941,16 @@ this._addCourier = function(pos)
var t = system.addShips("trader",1,pos,0);
}
t[0].bounty = 0;
t[0].heatInsulation = 6;
if (t.escortGroup)
{
var gs = t.escortGroup.ships;
for (var i=gs.length=1; i>=0; i++)
{
gs[i].heatInsulation = 6;
gs[i].bounty = 0;
}
}
return t;
}
@ -951,9 +961,9 @@ this._addCourierShort = function(pos)
if (t[0])
{
// don't need to worry at this stage where it came from before that
t[0].AIScript.oolite_intership.source_system = this._nearbySystem(7);
t[0].homeSystem = this._nearbySystem(7);
this._setFuel(t[0]);
t[0].AIScript.oolite_intership.dest_system = system.ID;
t[0].destinationSystem = system.ID;
t[0].setCargoType("SCARCE_GOODS");
}
}
@ -965,9 +975,9 @@ this._addCourierLong = function(pos)
if (t[0])
{
// don't need to worry at this stage where it came from before that
t[0].AIScript.oolite_intership.source_system = this._nearbySystem(7);
t[0].homeSystem = this._nearbySystem(7);
this._setFuel(t[0]);
t[0].AIScript.oolite_intership.dest_system = this._nearbySystem(25);
t[0].destinationSystem = this._nearbySystem(25);
t[0].setCargoType("SCARCE_GOODS");
}
}
@ -986,9 +996,9 @@ this._addSmuggler = function(pos)
if (t[0])
{
t[0].bounty = Math.ceil(Math.random()*20);
t[0].AIScript.oolite_intership.source_system = this._nearbySystem(7);
t[0].homeSystem = this._nearbySystem(7);
this._setFuel(t[0]);
t[0].AIScript.oolite_intership.dest_system = system.ID;
t[0].destinationSystem = system.ID;
t[0].setCargoType("ILLEGAL_GOODS");
t[0].awardEquipment("EQ_FUEL_INJECTION"); // smugglers always have injectors
}
@ -1001,8 +1011,8 @@ this._addLightHunter = function(pos)
for (var i = 0 ; i < h.ships.length ; i++)
{
h.ships[i].bounty = 0;
h.ships[i].AIScript.oolite_intership.source_system = system.ID;
h.ships[i].AIScript.oolite_intership.dest_system = system.ID;
h.ships[i].homeSystem = system.ID;
h.ships[i].destinationSystem = system.ID;
h.ships[i].AIScript.oolite_intership.initial_group = h.ships.length;
}
}
@ -1021,9 +1031,13 @@ this._addMediumHunter = function(pos)
if (t[0])
{
t[0].bounty = 0;
t[0].AIScript.oolite_intership.source_system = this._nearbySafeSystem(6);
var s = this._nearbySafeSystem(6);
if (s)
{
t[0].homeSystem = s;
}
this._setFuel(t[0]);
t[0].AIScript.oolite_intership.dest_system = system.ID;
t[0].destinationSystem = system.ID;
}
}
@ -1041,9 +1055,13 @@ this._addHeavyHunter = function(pos)
if (t[0])
{
t[0].bounty = 0;
t[0].AIScript.oolite_intership.source_system = this._nearbySafeSystem(2);
var s = this._nearbySafeSystem(2);
if (s)
{
t[0].homeSystem = s;
}
this._setFuel(t[0]);
t[0].AIScript.oolite_intership.dest_system = system.ID;
t[0].destinationSystem = system.ID;
}
}
@ -1136,8 +1154,8 @@ this._addPiratePack = function(pos,leader,lf,mf,hf,thug)
this._addLightPirateLocal = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
lead.AIScript.oolite_intership.source_system = system.ID;
lead.AIScript.oolite_intership.dest_system = system.ID;
lead.homeSystem = system.ID;
lead.destinationSystem = system.ID;
}
@ -1145,17 +1163,17 @@ this._addLightPirateRemote = function(pos)
{
pos.z = pos.z % 100000;
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
lead.AIScript.oolite_intership.source_system = this._nearbyDangerousSystem(system.info.government-1);
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
this._setFuel(lead);
lead.AIScript.oolite_intership.dest_system = system.ID;
lead.destinationSystem = system.ID;
}
this._addMediumPirateLocal = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1);
lead.AIScript.oolite_intership.source_system = system.ID;
lead.AIScript.oolite_intership.dest_system = system.ID;
lead.homeSystem = system.ID;
lead.destinationSystem = system.ID;
}
@ -1163,17 +1181,17 @@ this._addMediumPirateRemote = function(pos)
{
pos.z = pos.z % 100000;
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1);
lead.AIScript.oolite_intership.source_system = this._nearbyDangerousSystem(system.info.government-1);
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
this._setFuel(lead);
lead.AIScript.oolite_intership.dest_system = system.ID;
lead.destinationSystem = system.ID;
}
this._addHeavyPirateLocal = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2);
lead.AIScript.oolite_intership.source_system = system.ID;
lead.AIScript.oolite_intership.dest_system = system.ID;
lead.homeSystem = system.ID;
lead.destinationSystem = system.ID;
}
@ -1181,9 +1199,9 @@ this._addHeavyPirateRemote = function(pos)
{
pos.z = pos.z % 100000;
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2);
lead.AIScript.oolite_intership.source_system = this._nearbyDangerousSystem(system.info.government-1);
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
this._setFuel(lead);
lead.AIScript.oolite_intership.dest_system = system.ID;
lead.destinationSystem = system.ID;
}
@ -1198,8 +1216,8 @@ this._addPolicePatrol = function(pos)
for (var i = 0 ; i < h.ships.length ; i++)
{
h.ships[i].bounty = 0;
h.ships[i].AIScript.oolite_intership.source_system = system.ID;
h.ships[i].AIScript.oolite_intership.dest_system = system.ID;
h.ships[i].homeSystem = system.ID;
h.ships[i].destinationSystem = system.ID;
h.ships[i].AIScript.oolite_intership.initial_group = h.ships.length;
}
}
@ -1212,8 +1230,8 @@ this._addInterceptors = function(pos)
{
h.ships[i].bounty = 0;
// h.ships[i].switchAI("policeWitchpointPatrolAI.js");
h.ships[i].AIScript.oolite_intership.source_system = system.ID;
h.ships[i].AIScript.oolite_intership.dest_system = system.ID;
h.ships[i].homeSystem = system.ID;
h.ships[i].destinationSystem = system.ID;
h.ships[i].AIScript.oolite_intership.initial_group = h.ships.length;
}
}
@ -1254,13 +1272,13 @@ this._roleExists = function(role)
this._setFuel = function(ship)
{
if (ship.AIScript.oolite_intership.source_system)
if (ship.homeSystem != system.ID)
{
ship.fuel = 7-system.info.distanceToSystem(System.infoForSystem(galaxyNumber,ship.AIScript.oolite_intership.source_system));
ship.fuel = 7-system.info.distanceToSystem(System.infoForSystem(galaxyNumber,ship.homeSystem));
}
else
else
{
ship.fuel = 0.2;
ship.fuel = 7;
}
}