Add pirate interceptor AI, fix some bugs in pirate freighter AI

This commit is contained in:
cim 2013-08-09 18:00:18 +01:00
parent b00b1bb550
commit 9edbe45d63
5 changed files with 204 additions and 47 deletions

View File

@ -51,6 +51,12 @@ this.aiStarted = function() {
behaviour: ai.behaviourDestroyCurrentTarget,
reconsider: 5
},
/* Follow leader to witchspace */
{
condition: ai.conditionWitchspaceEntryRequested,
behaviour: ai.behaviourEnterWitchspace,
reconsider: 15
},
/* Check for distress calls */
{
condition: ai.conditionHasReceivedDistressCall,

View File

@ -126,11 +126,11 @@ this.aiStarted = function() {
specific = [
{
condition: ai.conditionGroupHasEnoughLoot,
truebranch: ai.templateWitchspaceJumpOutbound()
truebranch: ai.templateWitchspaceJumpInbound()
},
{
condition: ai.conditionGroupAttritionReached,
truebranch: ai.templateWitchspaceJumpOutbound()
truebranch: ai.templateWitchspaceJumpInbound()
},
{
condition: ai.conditionInInterstellarSpace,

View File

@ -0,0 +1,139 @@
/*
pirateInterceptorAI.js
Priority-based AI for pirate interceptors (fly defense for
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 Pirate Interceptor AI";
this.version = "1.79";
this.aiStarted = function() {
this.ai = new worldScripts["oolite-libPriorityAI"].AILib(this.ship);
ai.setParameter("oolite_flag_surrendersLate",true);
// to hunt the hunters, go where they go
ai.setWaypointGenerator(ai.waypointsSpacelanePatrol);
ai.setCommunicationsRole("pirate");
var common = [
/* Combat */
{
condition: ai.conditionLosingCombat,
behaviour: ai.behaviourFleeCombat,
reconsider: 5
},
{
condition: ai.conditionInCombat,
configuration: ai.configurationAcquireCombatTarget,
behaviour: ai.behaviourDestroyCurrentTarget,
reconsider: 10
},
{
/* don't check odds first, make sure we get at least a little
* weapons fire */
preconfiguration: ai.configurationCheckScanner,
condition: ai.conditionScannerContainsHunters,
configuration: ai.configurationAcquireScannedTarget,
behaviour: ai.behaviourDestroyCurrentTarget,
reconsider: 20
}
];
var specific;
if (this.ship.homeSystem == this.ship.destinationSystem)
{
/* Patrol waypoints for a bit, then return */
specific = [
{
condition: ai.conditionHasWaypoint,
configuration: ai.configurationSetDestinationToWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
},
{
condition: ai.conditionPatrolIsOver,
truebranch: ai.templateReturnToBaseOrPlanet()
},
{
configuration: ai.configurationSetWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
}
];
}
else if (this.ship.homeSystem == system.ID && this.ship.fuel == 7)
{
// jump to destination system independently of freighters
// (since interceptors are just added *with* them, not to
// their group)
specific = ai.templateWitchspaceJumpOutbound().concat(ai.templateReturnToBaseOrPlanet);
}
else if (this.ship.homeSystem == system.ID)
{
// if not at full fuel, we're probably returning home. Or
// something went wrong when trying to enter witchspace that
// needed injectors to fix.
specific = ai.templateReturnToBaseOrPlanet();
}
else
{
/* Patrol waypoints for a bit, then return */
specific = [
{
condition: ai.conditionHasWaypoint,
configuration: ai.configurationSetDestinationToWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
},
{
condition: ai.conditionPatrolIsOver,
truebranch: ai.templateWitchspaceJumpOutbound()
},
{
configuration: ai.configurationSetWaypoint,
behaviour: ai.behaviourApproachDestination,
reconsider: 30
}
];
}
var fallback = [
{
// stuck in system and no friendly stations
configuration: ai.configurationSetDestinationToWitchpoint,
// TODO: behaviour search for wormholes
behaviour: ai.behaviourApproachDestination,
reconsider: 30
}
];
var priorities = common.concat(specific).concat(fallback);
ai.setPriorities(priorities);
}

View File

@ -409,6 +409,8 @@ this.AILib = function(ship)
this.setCommunicationsRole = function(role)
{
commsRole = role;
// TODO: if personality is generic, pick a new one from the
// allowed list. If possible use the same as the group leader.
}
@ -514,14 +516,22 @@ AILib.prototype.checkScannerWithPredicate = function(predicate)
{
return false;
}
// if current target matches, use that
if (this.ship.target && predicate.call(this,this.ship.target))
{
this.setParameter("oolite_scanResultSpecific",this.ship.target);
return true;
}
var sl = scan.length;
// scan upwards; lower indices tend to be closer, though this is
// not guaranteed
// use a random offset so if several ships make the same scan
// they don't all pick the same target
var offset = Math.floor(Math.random()*sl);
for (var i = 0 ; i < sl ; i++)
{
if (predicate.call(this,scan[i]))
var io = (i+offset)%sl;
if (predicate.call(this,scan[io]))
{
this.setParameter("oolite_scanResultSpecific",scan[i]);
this.setParameter("oolite_scanResultSpecific",scan[io]);
return true;
}
}
@ -630,7 +640,7 @@ AILib.prototype.friendlyStation = function(station)
return false;
}
// this will do until we have a proper friendliness system for stations
if (this.ship.primaryRole == "pirate" && station.bounty == 0)
if (this.ship.primaryRole.match(/^pirate/) && station.bounty == 0)
{
return false;
}
@ -1616,7 +1626,7 @@ AILib.prototype.conditionScannerContainsSeriousOffender = function()
AILib.prototype.conditionScannerContainsHunters = function()
{
return this.checkScannerWithPredicate(function(s) {
return s.primaryRole == "hunter" || s.scanClass == "CLASS_POLICE" || (s.isStation && s.isMainStation);
return (s.primaryRole && s.primaryRole.match(/^hunter/)) || s.scanClass == "CLASS_POLICE" || (s.isStation && s.isMainStation);
});
}
@ -4617,6 +4627,7 @@ AILib.prototype.templateLeadPirateMission = function()
{
return [
{
label: "Pirate mission",
preconfiguration: this.configurationForgetCargoDemand,
condition: this.conditionScannerContainsPirateVictims,
configuration: this.configurationAcquireScannedTarget,
@ -4644,6 +4655,7 @@ AILib.prototype.templateReturnToBase = function()
{
return [
{
label: "Return to base",
condition: this.conditionHasSelectedStation,
truebranch: [
{
@ -4687,6 +4699,7 @@ AILib.prototype.templateReturnToBaseOrPlanet = function()
{
return [
{
label: "Return to base or planet",
condition: this.conditionFriendlyStationNearby,
configuration: this.configurationSetNearbyFriendlyStationForDocking,
behaviour: this.behaviourDockWithStation,
@ -4731,6 +4744,7 @@ AILib.prototype.templateWitchspaceJumpInbound = function()
{
return [
{
label: "Jump inbound",
preconfiguration: this.configurationSelectWitchspaceDestinationInbound,
condition: this.conditionCanWitchspaceOnRoute,
behaviour: this.behaviourEnterWitchspace,
@ -4756,6 +4770,7 @@ AILib.prototype.templateWitchspaceJumpOutbound = function()
{
return [
{
label: "Jump outbound",
preconfiguration: this.configurationSelectWitchspaceDestinationOutbound,
condition: this.conditionCanWitchspaceOnRoute,
behaviour: this.behaviourEnterWitchspace,

View File

@ -1120,21 +1120,26 @@ this._addPirateAssistant = function(role,lead)
{
var asst = system.addShips("pirate",1,lead.position,4E3);
}
asst[0].setBounty(20+system.government+Math.floor(Math.random()*12),"setup actions");
asst[0].group = lead.group;
lead.group.addShip(asst[0]);
/* if (role == "pirate-interceptor")
asst[0].homeSystem = lead.homeSystem;
asst[0].destinationSystem = lead.destinationSystem;
if (role == "pirate-interceptor")
{
asst[0].switchAI("pirateInterceptorAI.js");
asst[0].setBounty(50+system.government+Math.floor(Math.random()*36),"setup actions");
// interceptors not actually part of group: they just get the
// same destinations
}
else
{ */
{
asst[0].group = lead.group;
lead.group.addShip(asst[0]);
asst[0].switchAI("pirateFighterAI.js");
// }
asst[0].setBounty(20+system.government+Math.floor(Math.random()*12),"setup actions");
}
}
this._addPiratePack = function(pos,leader,lf,mf,hf,thug)
this._addPiratePack = function(pos,leader,lf,mf,hf,thug,home,destination)
{
if (this._roleExists(leader))
{
@ -1146,6 +1151,9 @@ this._addPiratePack = function(pos,leader,lf,mf,hf,thug)
var lead = system.addShips("pirate",1,pos,0);
}
lead[0].setBounty(60+system.government+Math.floor(Math.random()*8),"setup actions");
lead[0].homeSystem = home;
lead[0].destinationSystem = destination;
var group = new ShipGroup("pirate pack",lead[0]);
lead[0].group = group;
for (var i = Math.floor(lf+(0.5+Math.random()-Math.random())); i > 0; i--)
@ -1176,76 +1184,65 @@ this._addPiratePack = function(pos,leader,lf,mf,hf,thug)
}
// next line is temporary for debugging!
lead[0].displayName = lead[0].name + " - FLAGSHIP";
this._setFuel(lead[0]);
lead[0].switchAI("pirateFreighterAI.js");
return lead[0];
}
this._addLightPirateLocal = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
lead.homeSystem = system.ID;
lead.destinationSystem = system.ID;
lead.switchAI("pirateFreighterAI.js");
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0,system.ID,system.ID);
}
this._addLightPirateRemote = function(pos)
{
pos.z = pos.z % 100000;
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
this._setFuel(lead);
lead.destinationSystem = system.ID;
lead.switchAI("pirateFreighterAI.js");
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0,this._nearbyDangerousSystem(system.info.government-1),system.ID);
}
this._addLightPirateOutbound = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
lead.destinationSystem = this._nearbySafeSystem(system.info.government+1);
lead.fuel = 7
lead.homeSystem = system.ID;
lead.switchAI("pirateFreighterAI.js");
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0,system.ID,this._nearbySafeSystem(system.info.government+1));
}
this._addMediumPirateLocal = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1);
lead.homeSystem = system.ID;
lead.destinationSystem = system.ID;
lead.switchAI("pirateFreighterAI.js");
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1,system.ID,system.ID);
}
this._addMediumPirateRemote = function(pos)
{
pos.z = pos.z % 100000;
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1);
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
this._setFuel(lead);
lead.destinationSystem = system.ID;
lead.switchAI("pirateFreighterAI.js");
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1,this._nearbyDangerousSystem(Math.min(system.info.government-1,3)),system.ID);
}
this._addMediumPirateOutbound = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1,system.ID,this._nearbySafeSystem(system.info.government+1));
}
this._addHeavyPirateLocal = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2);
lead.homeSystem = system.ID;
lead.destinationSystem = system.ID;
lead.switchAI("pirateFreighterAI.js");
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2,system.ID,system.ID);
}
this._addHeavyPirateRemote = function(pos)
{
pos.z = pos.z % 100000;
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2);
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
this._setFuel(lead);
lead.destinationSystem = system.ID;
lead.switchAI("pirateFreighterAI.js");
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2,this._nearbyDangerousSystem(Math.min(system.info.government-1,1)),system.ID);
}
this._addHeavyPirateOutbound = function(pos)
{
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2,system.ID,this._nearbySafeSystem(system.info.government+1));
}