Add pirate interceptor AI, fix some bugs in pirate freighter AI
This commit is contained in:
parent
b00b1bb550
commit
9edbe45d63
@ -51,6 +51,12 @@ this.aiStarted = function() {
|
|||||||
behaviour: ai.behaviourDestroyCurrentTarget,
|
behaviour: ai.behaviourDestroyCurrentTarget,
|
||||||
reconsider: 5
|
reconsider: 5
|
||||||
},
|
},
|
||||||
|
/* Follow leader to witchspace */
|
||||||
|
{
|
||||||
|
condition: ai.conditionWitchspaceEntryRequested,
|
||||||
|
behaviour: ai.behaviourEnterWitchspace,
|
||||||
|
reconsider: 15
|
||||||
|
},
|
||||||
/* Check for distress calls */
|
/* Check for distress calls */
|
||||||
{
|
{
|
||||||
condition: ai.conditionHasReceivedDistressCall,
|
condition: ai.conditionHasReceivedDistressCall,
|
||||||
|
@ -126,11 +126,11 @@ this.aiStarted = function() {
|
|||||||
specific = [
|
specific = [
|
||||||
{
|
{
|
||||||
condition: ai.conditionGroupHasEnoughLoot,
|
condition: ai.conditionGroupHasEnoughLoot,
|
||||||
truebranch: ai.templateWitchspaceJumpOutbound()
|
truebranch: ai.templateWitchspaceJumpInbound()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
condition: ai.conditionGroupAttritionReached,
|
condition: ai.conditionGroupAttritionReached,
|
||||||
truebranch: ai.templateWitchspaceJumpOutbound()
|
truebranch: ai.templateWitchspaceJumpInbound()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
condition: ai.conditionInInterstellarSpace,
|
condition: ai.conditionInInterstellarSpace,
|
||||||
|
139
Resources/AIs/pirateInterceptorAI.js
Normal file
139
Resources/AIs/pirateInterceptorAI.js
Normal 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);
|
||||||
|
|
||||||
|
}
|
@ -409,6 +409,8 @@ this.AILib = function(ship)
|
|||||||
this.setCommunicationsRole = function(role)
|
this.setCommunicationsRole = function(role)
|
||||||
{
|
{
|
||||||
commsRole = 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;
|
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;
|
var sl = scan.length;
|
||||||
// scan upwards; lower indices tend to be closer, though this is
|
// use a random offset so if several ships make the same scan
|
||||||
// not guaranteed
|
// they don't all pick the same target
|
||||||
|
var offset = Math.floor(Math.random()*sl);
|
||||||
for (var i = 0 ; i < sl ; i++)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,7 +640,7 @@ AILib.prototype.friendlyStation = function(station)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// this will do until we have a proper friendliness system for stations
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1616,7 +1626,7 @@ AILib.prototype.conditionScannerContainsSeriousOffender = function()
|
|||||||
AILib.prototype.conditionScannerContainsHunters = function()
|
AILib.prototype.conditionScannerContainsHunters = function()
|
||||||
{
|
{
|
||||||
return this.checkScannerWithPredicate(function(s) {
|
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 [
|
return [
|
||||||
{
|
{
|
||||||
|
label: "Pirate mission",
|
||||||
preconfiguration: this.configurationForgetCargoDemand,
|
preconfiguration: this.configurationForgetCargoDemand,
|
||||||
condition: this.conditionScannerContainsPirateVictims,
|
condition: this.conditionScannerContainsPirateVictims,
|
||||||
configuration: this.configurationAcquireScannedTarget,
|
configuration: this.configurationAcquireScannedTarget,
|
||||||
@ -4644,6 +4655,7 @@ AILib.prototype.templateReturnToBase = function()
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
label: "Return to base",
|
||||||
condition: this.conditionHasSelectedStation,
|
condition: this.conditionHasSelectedStation,
|
||||||
truebranch: [
|
truebranch: [
|
||||||
{
|
{
|
||||||
@ -4687,6 +4699,7 @@ AILib.prototype.templateReturnToBaseOrPlanet = function()
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
label: "Return to base or planet",
|
||||||
condition: this.conditionFriendlyStationNearby,
|
condition: this.conditionFriendlyStationNearby,
|
||||||
configuration: this.configurationSetNearbyFriendlyStationForDocking,
|
configuration: this.configurationSetNearbyFriendlyStationForDocking,
|
||||||
behaviour: this.behaviourDockWithStation,
|
behaviour: this.behaviourDockWithStation,
|
||||||
@ -4731,6 +4744,7 @@ AILib.prototype.templateWitchspaceJumpInbound = function()
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
label: "Jump inbound",
|
||||||
preconfiguration: this.configurationSelectWitchspaceDestinationInbound,
|
preconfiguration: this.configurationSelectWitchspaceDestinationInbound,
|
||||||
condition: this.conditionCanWitchspaceOnRoute,
|
condition: this.conditionCanWitchspaceOnRoute,
|
||||||
behaviour: this.behaviourEnterWitchspace,
|
behaviour: this.behaviourEnterWitchspace,
|
||||||
@ -4756,6 +4770,7 @@ AILib.prototype.templateWitchspaceJumpOutbound = function()
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
label: "Jump outbound",
|
||||||
preconfiguration: this.configurationSelectWitchspaceDestinationOutbound,
|
preconfiguration: this.configurationSelectWitchspaceDestinationOutbound,
|
||||||
condition: this.conditionCanWitchspaceOnRoute,
|
condition: this.conditionCanWitchspaceOnRoute,
|
||||||
behaviour: this.behaviourEnterWitchspace,
|
behaviour: this.behaviourEnterWitchspace,
|
||||||
|
@ -1120,21 +1120,26 @@ this._addPirateAssistant = function(role,lead)
|
|||||||
{
|
{
|
||||||
var asst = system.addShips("pirate",1,lead.position,4E3);
|
var asst = system.addShips("pirate",1,lead.position,4E3);
|
||||||
}
|
}
|
||||||
asst[0].setBounty(20+system.government+Math.floor(Math.random()*12),"setup actions");
|
asst[0].homeSystem = lead.homeSystem;
|
||||||
asst[0].group = lead.group;
|
asst[0].destinationSystem = lead.destinationSystem;
|
||||||
lead.group.addShip(asst[0]);
|
if (role == "pirate-interceptor")
|
||||||
/* if (role == "pirate-interceptor")
|
|
||||||
{
|
{
|
||||||
asst[0].switchAI("pirateInterceptorAI.js");
|
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
|
else
|
||||||
{ */
|
{
|
||||||
|
asst[0].group = lead.group;
|
||||||
|
lead.group.addShip(asst[0]);
|
||||||
asst[0].switchAI("pirateFighterAI.js");
|
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))
|
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);
|
var lead = system.addShips("pirate",1,pos,0);
|
||||||
}
|
}
|
||||||
lead[0].setBounty(60+system.government+Math.floor(Math.random()*8),"setup actions");
|
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]);
|
var group = new ShipGroup("pirate pack",lead[0]);
|
||||||
lead[0].group = group;
|
lead[0].group = group;
|
||||||
for (var i = Math.floor(lf+(0.5+Math.random()-Math.random())); i > 0; i--)
|
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!
|
// next line is temporary for debugging!
|
||||||
lead[0].displayName = lead[0].name + " - FLAGSHIP";
|
lead[0].displayName = lead[0].name + " - FLAGSHIP";
|
||||||
|
this._setFuel(lead[0]);
|
||||||
|
lead[0].switchAI("pirateFreighterAI.js");
|
||||||
return lead[0];
|
return lead[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
this._addLightPirateLocal = function(pos)
|
this._addLightPirateLocal = function(pos)
|
||||||
{
|
{
|
||||||
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
|
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0,system.ID,system.ID);
|
||||||
lead.homeSystem = system.ID;
|
|
||||||
lead.destinationSystem = system.ID;
|
|
||||||
lead.switchAI("pirateFreighterAI.js");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this._addLightPirateRemote = function(pos)
|
this._addLightPirateRemote = function(pos)
|
||||||
{
|
{
|
||||||
pos.z = pos.z % 100000;
|
pos.z = pos.z % 100000;
|
||||||
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
|
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0,this._nearbyDangerousSystem(system.info.government-1),system.ID);
|
||||||
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
|
|
||||||
this._setFuel(lead);
|
|
||||||
lead.destinationSystem = system.ID;
|
|
||||||
lead.switchAI("pirateFreighterAI.js");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this._addLightPirateOutbound = function(pos)
|
this._addLightPirateOutbound = function(pos)
|
||||||
{
|
{
|
||||||
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0);
|
var lead = this._addPiratePack(pos,"pirate-light-freighter",2,1,-1,0,system.ID,this._nearbySafeSystem(system.info.government+1));
|
||||||
lead.destinationSystem = this._nearbySafeSystem(system.info.government+1);
|
|
||||||
lead.fuel = 7
|
|
||||||
lead.homeSystem = system.ID;
|
|
||||||
lead.switchAI("pirateFreighterAI.js");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this._addMediumPirateLocal = function(pos)
|
this._addMediumPirateLocal = function(pos)
|
||||||
{
|
{
|
||||||
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1);
|
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1,system.ID,system.ID);
|
||||||
lead.homeSystem = system.ID;
|
|
||||||
lead.destinationSystem = system.ID;
|
|
||||||
lead.switchAI("pirateFreighterAI.js");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this._addMediumPirateRemote = function(pos)
|
this._addMediumPirateRemote = function(pos)
|
||||||
{
|
{
|
||||||
pos.z = pos.z % 100000;
|
pos.z = pos.z % 100000;
|
||||||
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1);
|
var lead = this._addPiratePack(pos,"pirate-medium-freighter",3,2,0,1,this._nearbyDangerousSystem(Math.min(system.info.government-1,3)),system.ID);
|
||||||
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
|
}
|
||||||
this._setFuel(lead);
|
|
||||||
lead.destinationSystem = system.ID;
|
|
||||||
lead.switchAI("pirateFreighterAI.js");
|
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)
|
this._addHeavyPirateLocal = function(pos)
|
||||||
{
|
{
|
||||||
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2);
|
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2,system.ID,system.ID);
|
||||||
lead.homeSystem = system.ID;
|
|
||||||
lead.destinationSystem = system.ID;
|
|
||||||
lead.switchAI("pirateFreighterAI.js");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this._addHeavyPirateRemote = function(pos)
|
this._addHeavyPirateRemote = function(pos)
|
||||||
{
|
{
|
||||||
pos.z = pos.z % 100000;
|
pos.z = pos.z % 100000;
|
||||||
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2);
|
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2,this._nearbyDangerousSystem(Math.min(system.info.government-1,1)),system.ID);
|
||||||
lead.homeSystem = this._nearbyDangerousSystem(system.info.government-1);
|
}
|
||||||
this._setFuel(lead);
|
|
||||||
lead.destinationSystem = system.ID;
|
|
||||||
lead.switchAI("pirateFreighterAI.js");
|
this._addHeavyPirateOutbound = function(pos)
|
||||||
|
{
|
||||||
|
var lead = this._addPiratePack(pos,"pirate-heavy-freighter",4,4,2,2,system.ID,this._nearbySafeSystem(system.info.government+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user