Add police lane patrol AI (acts as both lead and wingman)

This commit is contained in:
cim 2013-07-18 23:00:23 +01:00
parent 7c6f7b9a6e
commit 27e76f345f
4 changed files with 211 additions and 7 deletions

View File

@ -79,7 +79,7 @@ this.aiStarted = function() {
},
/* What about loot? */
{
condition: ai.conditionScannerContainsSalvage,
condition: ai.conditionScannerContainsSalvageForMe,
configuration: ai.configurationAcquireScannedTarget,
behaviour: ai.behaviourCollectSalvage,
reconsider: 20

View File

@ -34,7 +34,7 @@ this.aiStarted = function() {
ai.setParameter("oolite_flag_watchForCargo",true);
/* This communication is necessary but needs more variety and moving to descriptions.plist so it can be translated */
ai.setCommunication("oolite_piracyAlert","Your cargo or your life, [p1]! Give us [p2] containers and we'll let you go.");
ai.setCommunication("oolite_piracyAlert","You're outnumbered, [p1]! Power down your weapons, dump [p2] containers and we'll let you go.");
ai.setPriorities([

View File

@ -0,0 +1,128 @@
/*
policeLanePatrolAI.js
Priority-based AI for police
Oolite
Copyright © 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
"use strict";
this.name = "Oolite Police (lane patrol) AI";
this.version = "1.79";
this.aiStarted = function() {
var ai = new worldScripts["oolite-libPriorityAI"].AILib(this.ship);
ai.setParameter("oolite_flag_listenForDistressCall",true);
ai.setParameter("oolite_leaderRole","police");
ai.setParameter("oolite_escortRole","wingman");
/* Needs to use existing entries in descriptions.plist */
ai.setCommunication("oolite_markForFines","Attention, [p1]. Your offences will result in a fine if you dock at %H station..");
ai.setPriorities([
/* Fight */
{
condition: ai.conditionLosingCombat,
behaviour: ai.behaviourFleeCombat,
reconsider: 5
},
{
condition: ai.conditionInCombat,
configuration: ai.configurationAcquireCombatTarget,
behaviour: ai.behaviourDestroyCurrentTarget,
reconsider: 5
},
/* Check for distress calls */
{
condition: ai.conditionHasReceivedDistressCall,
behaviour: ai.behaviourRespondToDistressCall,
reconsider: 20
},
/* Check for profitable targets */
{
preconfiguration: ai.configurationCheckScanner,
condition: ai.conditionScannerContainsFugitive,
configuration: ai.configurationAcquireScannedTarget,
behaviour: ai.behaviourDestroyCurrentTarget,
reconsider: 1
},
{
condition: ai.conditionScannerContainsHuntableOffender,
configuration: ai.configurationAcquireScannedTarget,
behaviour: ai.behaviourDestroyCurrentTarget,
reconsider: 1
},
{
condition: ai.conditionScannerContainsFineableOffender,
configuration: ai.configurationAcquireScannedTarget,
behaviour: ai.behaviourFineCurrentTarget,
reconsider: 10
},
/* What about escape pods? */
{
condition: ai.conditionScannerContainsEscapePods,
configuration: ai.configurationAcquireScannedTarget,
behaviour: ai.behaviourCollectSalvage,
reconsider: 20
},
/* Regroup if necessary */
{
preconfiguration: ai.configurationAppointGroupLeader,
condition: ai.conditionGroupIsSeparated,
configuration: ai.configurationSetDestinationToGroupLeader,
behaviour: ai.behaviourApproachDestination,
reconsider: 15
},
{
condition: ai.conditionIsGroupLeader,
truebranch: [
/* Nothing interesting here. Patrol for a bit */
{
condition: ai.conditionHasPatrolRoute,
configuration: ai.configurationSetDestinationFromPatrolRoute,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
},
/* No patrol route set up. Make one */
{
configuration: ai.configurationMakeSpacelanePatrolRoute,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
}
],
falsebranch: [
{
preconfiguration: ai.configurationEscortGroupLeader,
condition: ai.conditionIsEscorting,
behaviour: ai.behaviourEscortMothership,
reconsider: 30
},
/* if we can't set up as an escort */
{
behaviour: ai.behaviourFollowGroupLeader,
reconsider: 15
}
]
}
]);
}

View File

@ -57,8 +57,7 @@ this.AILib = function(ship)
if (this.getParameter("oolite_flag_behaviourLogging"))
{
if (priority.label)
{
log(this.ship.name,"Considering: "+priority.label);
{ log(this.ship.name,"Considering: "+priority.label);
}
else
{
@ -619,6 +618,15 @@ this.AILib = function(ship)
return s.isInSpace && s.bounty > threshold;
});
}
this.conditionScannerContainsFineableOffender = function()
{
return this.checkScannerWithPredicate(function(s) {
var threshold = 50 - (system.info.government * 7);
return s.isInSpace && s.bounty <= threshold && s.bounty > 0 && !s.markedForFines && (s.scanClass == "CLASS_NEUTRAL" || s.isPlayer) && !s.isDerelict;
});
}
this.conditionScannerContainsSalvageForMe = function()
{
@ -627,6 +635,13 @@ this.AILib = function(ship)
});
}
this.conditionScannerContainsEscapePods = function()
{
return this.checkScannerWithPredicate(function(s) {
return s.primaryRole == "escape-capsule" && s.isInSpace && s.scanClass == "CLASS_CARGO" && s.velocity.magnitude() < this.ship.maxSpeed && this.conditionCanScoopCargo();
});
}
this.conditionScannerContainsSalvageForGroup = function()
{
var maxspeed = 0;
@ -768,13 +783,13 @@ this.AILib = function(ship)
if (this.ship.bounty == 0)
{
return this.checkScannerWithPredicate(function(s) {
return s.bounty == 0 && (!s.escortGroup || s.escortGroup.count <= s.maxEscorts);
return s.scanClass == this.ship.scanClass && s.bounty == 0 && (!s.escortGroup || s.escortGroup.count <= s.maxEscorts);
});
}
else
{
return this.checkScannerWithPredicate(function(s) {
return s.bounty > 0 && (!s.escortGroup || s.escortGroup.count <= s.maxEscorts);
return s.scanClass == this.ship.scanClass && s.bounty > 0 && (!s.escortGroup || s.escortGroup.count <= s.maxEscorts);
});
}
}
@ -853,6 +868,19 @@ this.AILib = function(ship)
return (this.ship.group.leader == this.ship);
}
this.conditionIsEscorting = function()
{
if (!this.ship.group || !this.ship.group.leader || this.ship.group.leader == this.ship)
{
return false;
}
if (this.ship.group.leader.escortGroup && this.ship.group.leader.escortGroup.containsShip(this.ship))
{
return true;
}
return false;
}
this.conditionAllEscortsInFlight = function()
{
if (!this.ship.escortGroup)
@ -1119,6 +1147,23 @@ this.AILib = function(ship)
}
this.behaviourFineCurrentTarget = function()
{
var handlers = {};
this.responsesAddStandard(handlers);
this.setUpHandlers(handlers);
if (this.ship.scanClass == "CLASS_POLICE" && this.ship.target)
{
this.communicate("oolite_markForFines",this.ship.target.displayName);
this.ship.markTargetForFines();
}
this.ship.performIdle();
}
this.behaviourCollectSalvage = function()
{
var handlers = {};
@ -2127,18 +2172,49 @@ this.AILib = function(ship)
{
if (this.ship.group && !this.ship.group.leader)
{
this.ship.group.leader = this.ship.group.ships[0];
for (var i = 0 ; i < this.ship.group.ships.length ; i++)
{
if (this.ship.group.ships[i].hasHyperspaceMotor)
{
// bias towards jump-capable ships
this.ship.group.leader = this.ship.group.ships[i];
break;
}
}
this.ship.group.leader = this.ship.group.ships[0];
var leadrole = this.getParameter("oolite_leaderRole")
if (leadrole != null)
{
this.ship.group.leader.primaryRole = leadrole;
}
}
}
this.configurationEscortGroupLeader = function()
{
if (!this.ship.group || !this.ship.group.leader || this.ship.group.leader == this.ship)
{
return;
}
if (this.ship.group.leader.escortGroup && this.ship.group.leader.escortGroup.containsShip(this.ship))
{
return;
}
var escrole = this.getParameter("oolite_escortRole")
if (escrole != null)
{
var oldrole = this.ship.primaryRole;
this.ship.primaryRole = escrole;
var accepted = this.ship.offerToEscort(this.ship.group.leader);
if (!accepted)
{
this.ship.primaryRole = oldrole;
}
}
}
this.configurationForgetCargoDemand = function()
{
/* if (this.ship.group && this.ship.group.leader && this.ship.group.leader.AIScript.oolite_intership.cargodemanded)