- Added two new AI commands: 'storeTarget' and 'recallStoredTarget'

- Used both commands in pirate and missile AI for a better reaction on cloaked targets.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@4941 127b21dd-08f5-0310-b4b7-95ae10353056
master
Eric Walch 2012-05-16 12:46:14 +00:00
parent 9147f844bc
commit 27bb46cacd
8 changed files with 252 additions and 179 deletions

View File

@ -21,13 +21,24 @@
};
"FLY_AHEAD" =
{
ENTER = (setDestinationToTarget, "setSpeedFactorTo: 1", "setThrustFactorTo: 0", performFlyToRangeFromDestination);
ENTER = (storeTarget,
setDestinationToTarget,
"setSpeedFactorTo: 1",
"setThrustFactorTo: 0",
performFlyToRangeFromDestination
);
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: DETONATE");
"GONE_BEYOND_RANGE" = ("setStateTo: EXPLODE");
ECM = ("rollD: 40");
"ROLL_1" = ("setStateTo: DETONATE");
"ROLL_2" = ("setStateTo: EXPLODE");
UPDATE = ("setDesiredRangeTo: 30000.0", checkDistanceTravelled, "setDesiredRangeTo: 175.0", "pauseAI: 0.5");
"TARGET_FOUND" = (setTargetToFoundTarget, "setThrustFactorTo: 1", "setStateTo: ATTACK_SHIP");
UPDATE = (recallStoredTarget,
"setDesiredRangeTo: 30000.0",
checkDistanceTravelled,
"setDesiredRangeTo: 175.0",
"pauseAI: 0.5"
);
};
DETONATE =
{

View File

@ -12,10 +12,30 @@
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: DETONATE");
"TARGET_DESTROYED" = ("setStateTo: EXPLODE");
"TARGET_LOST" = ("setStateTo: EXPLODE");
"TARGET_CLOAKED" = ("setStateTo: FLY_AHEAD");
ECM = ("setStateTo: EXPLODE");
"GONE_BEYOND_RANGE" = ("setStateTo: EXPLODE");
UPDATE = ("setDesiredRangeTo: 30000.0", checkDistanceTravelled, "setDesiredRangeTo: 25.0", "pauseAI: 5.0");
};
"FLY_AHEAD" =
{
ENTER = (storeTarget,
setDestinationToTarget,
"setSpeedFactorTo: 1",
"setThrustFactorTo: 0",
performFlyToRangeFromDestination
);
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: DETONATE");
"GONE_BEYOND_RANGE" = ("setStateTo: EXPLODE");
ECM = ("setStateTo: EXPLODE");
"TARGET_FOUND" = (setTargetToFoundTarget, "setThrustFactorTo: 1", "setStateTo: ATTACK_SHIP");
UPDATE = (recallStoredTarget,
"setDesiredRangeTo: 30000.0",
checkDistanceTravelled,
"setDesiredRangeTo: 175.0",
"pauseAI: 0.5"
);
};
DETONATE =
{
ENTER = ("sendScriptMessage: detonate");

View File

@ -43,7 +43,7 @@
ENTER = ("setDesiredRangeTo: 25600", performFlee);
"ENERGY_FULL" = ("setStateTo: COLLECT_LOOT");
"TARGET_LOST" = ("setStateTo: RECOVER");
"TARGET_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED"); // added
"TARGET_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: RECOVER");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
@ -54,14 +54,20 @@
RESTARTED = ("setStateTo: RECOVER");
};
"FLEE_FOR_CLOAKED" = {
ENTER = (setDestinationToCurrentLocation, "setDesiredRangeTo: 7500", performFlyToRangeFromDestination);
ENTER = (storeTarget,
setDestinationToCurrentLocation,
"setDesiredRangeTo: 25600",
performFlyToRangeFromDestination
);
"ENERGY_FULL" = ("setStateTo: LURK");
"ENERGY_LOW" = ("setStateTo: FLEE");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: RECOVER");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"TARGET_FOUND" = (setTargetToFoundTarget, "setStateTo: ATTACK_SHIP");
RESTARTED = ("setStateTo: RECOVER");
UPDATE = (recallStoredTarget, "pauseAI: 2.0");
};
RECOVER = {
ENTER = ("setSpeedTo: 0.0", performIdle, "pauseAI: 5.0");

View File

@ -208,6 +208,8 @@
"addFoundTargetAsDefenseTarget",
"findNewDefenseTarget",
"clearDefenseTargets",
"storeTarget",
"recallStoredTarget",
// StationEntity.m/stubs in ShipEntityAI.m
"increaseAlertLevel",
"decreaseAlertLevel",

View File

@ -1,36 +1,36 @@
/*
ShipEntity.h
Entity subclass representing a ship, or various other flying things like cargo
pods and stations (a subclass).
Oolite
Copyright (C) 2004-2012 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.
*/
ShipEntity.h
Entity subclass representing a ship, or various other flying things like cargo
pods and stations (a subclass).
Oolite
Copyright (C) 2004-2012 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.
*/
#import "OOEntityWithDrawable.h"
#import "OOPlanetEntity.h"
#import "OOJSPropID.h"
@class OOColor, StationEntity, WormholeEntity, AI, Octree, OOMesh, OOScript,
OOJSScript, OORoleSet, OOShipGroup, OOEquipmentType;
OOJSScript, OORoleSet, OOShipGroup, OOEquipmentType;
#ifdef OO_BRAIN_AI
@class OOBrain;
@ -125,7 +125,7 @@ MA 02110-1301, USA.
typedef enum OOBehaviour
{
#include "OOBehaviour.tbl"
#include "OOBehaviour.tbl"
} OOBehaviour;
#undef ENTRY
@ -158,7 +158,7 @@ typedef enum
typedef enum
{
#define DIFF_STRING_ENTRY(label, string) label,
#include "OOShipDamageType.tbl"
#include "OOShipDamageType.tbl"
#undef DIFF_STRING_ENTRY
kOOShipDamageTypeDefault = kOODamageTypeEnergy
@ -225,36 +225,36 @@ typedef enum
// TODO: stick all equipment in a list, and move list from playerEntity to shipEntity. -- Ahruman
unsigned military_jammer_active: 1, // military_jammer
docking_match_rotation: 1,
docking_match_rotation: 1,
pitching_over: 1, // set to YES if executing a sharp loop
reportAIMessages: 1, // normally NO, suppressing AI message reporting
pitching_over: 1, // set to YES if executing a sharp loop
reportAIMessages: 1, // normally NO, suppressing AI message reporting
being_mined: 1, // normally NO, set to Yes when fired on by mining laser
being_mined: 1, // normally NO, set to Yes when fired on by mining laser
being_fined: 1,
being_fined: 1,
isHulk: 1, // This is used to distinguish abandoned ships from cargo
trackCloseContacts: 1,
isHulk: 1, // This is used to distinguish abandoned ships from cargo
trackCloseContacts: 1,
isNearPlanetSurface: 1, // check for landing on planet
isFrangible: 1, // frangible => subEntities can be damaged individually
cloaking_device_active: 1, // cloaking_device
cloakPassive: 1, // cloak deactivates when main weapons or missiles are fired
cloakAutomatic: 1, // cloak activates itself automatic during attack
canFragment: 1, // Can it break into wreckage?
suppressExplosion: 1, // Avoid exploding on death (script hook)
suppressAegisMessages: 1, // No script/AI messages sent by -checkForAegis,
isMissile: 1, // Whether this was launched by fireMissile (used to track submunitions).
isUnpiloted: 1, // Is meant to not have crew
hasScoopMessage: 1, // suppress scoop messages when false.
isNearPlanetSurface: 1, // check for landing on planet
isFrangible: 1, // frangible => subEntities can be damaged individually
cloaking_device_active: 1, // cloaking_device
cloakPassive: 1, // cloak deactivates when main weapons or missiles are fired
cloakAutomatic: 1, // cloak activates itself automatic during attack
canFragment: 1, // Can it break into wreckage?
suppressExplosion: 1, // Avoid exploding on death (script hook)
suppressAegisMessages: 1, // No script/AI messages sent by -checkForAegis,
isMissile: 1, // Whether this was launched by fireMissile (used to track submunitions).
isUnpiloted: 1, // Is meant to not have crew
hasScoopMessage: 1, // suppress scoop messages when false.
// scripting
scripted_misjump: 1,
haveExecutedSpawnAction: 1,
noRocks: 1,
_lightsActive: 1;
scripted_misjump: 1,
haveExecutedSpawnAction: 1,
noRocks: 1,
_lightsActive: 1;
OOFuelQuantity fuel; // witch-space fuel
GLfloat fuel_accumulator;
@ -300,8 +300,8 @@ typedef enum
OOUniversalID primaryAggressor; // recorded after an attack
OOUniversalID targetStation; // for docking
OOUniversalID found_target; // from scans
NSMutableArray *defenseTargets; // defense targets
NSMutableArray *defenseTargets; // defense targets
OOUInteger _subIdx; // serialisation index - used only if this ship is a subentity
OOUInteger _maxShipSubIdx; // serialisation index - the number of ship subentities inside the shipdata
double launch_time; // time at which launched
@ -309,7 +309,7 @@ typedef enum
OOUniversalID planetForLanding; // for landing
GLfloat frustration, // degree of dissatisfaction with the current behavioural state, factor used to test this
success_factor;
success_factor;
int patrol_counter; // keeps track of where the ship is along a patrol route
@ -322,10 +322,10 @@ typedef enum
double cargo_dump_time; // time cargo was last dumped
NSMutableArray *cargo; // cargo containers go in here
OOCommodityType commodity_type; // type of commodity in a container
OOCargoQuantity commodity_amount; // 1 if unit is TONNES (0), possibly more if precious metals KILOGRAMS (1)
// or gem stones GRAMS (2)
// or gem stones GRAMS (2)
// navigation
GLfloat flightSpeed; // current speed
@ -337,21 +337,22 @@ typedef enum
float pitch_tolerance;
OOAegisStatus aegis_status; // set to YES when within the station's protective zone
double messageTime; // counts down the seconds a radio message is active for
double next_spark_time; // time of next spark when throwing sparks
OOUniversalID thanked_ship_id; // last ship thanked
OOUniversalID remembered_ship; // ship being remembered
Vector collision_vector; // direction of colliding thing.
//position of gun ports
Vector forwardWeaponOffset,
aftWeaponOffset,
portWeaponOffset,
starboardWeaponOffset;
aftWeaponOffset,
portWeaponOffset,
starboardWeaponOffset;
// crew (typically one OOCharacter - the pilot)
NSArray *crew;
@ -828,10 +829,10 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (void) resetExhaustPlumes;
/*-----------------------------------------
AI piloting methods
-----------------------------------------*/
AI piloting methods
-----------------------------------------*/
- (void) checkScanner;
- (ShipEntity**) scannedShips;
@ -934,8 +935,8 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (BOOL) witchspaceLeavingEffects;
/*
Mark this ship as an offender, this is different to setBounty as some ships such as police
are not markable. The final bounty may not be equal to existing bounty plus offence_value.
Mark this ship as an offender, this is different to setBounty as some ships such as police
are not markable. The final bounty may not be equal to existing bounty plus offence_value.
*/
- (void) markAsOffender:(int)offence_value;
- (void) markAsOffender:(int)offence_value withReason:(OOLegalStatusReason)reason;
@ -1005,9 +1006,9 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (Entity *)entityForShaderProperties;
/* *** Script events.
For NPC ships, these call doEvent: on the ship script.
For the player, they do that and also call doWorldScriptEvent:.
*/
For NPC ships, these call doEvent: on the ship script.
For the player, they do that and also call doWorldScriptEvent:.
*/
- (void) doScriptEvent:(jsid)message;
- (void) doScriptEvent:(jsid)message withArgument:(id)argument;
- (void) doScriptEvent:(jsid)message withArgument:(id)argument1 andArgument:(id)argument2;
@ -1016,18 +1017,18 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (void) doScriptEvent:(jsid)message inContext:(JSContext *)context withArguments:(jsval *)argv count:(uintN)argc;
/* Convenience to send an event with raw JS values, for example:
ShipScriptEventNoCx(ship, "doSomething", INT_TO_JSVAL(42));
*/
ShipScriptEventNoCx(ship, "doSomething", INT_TO_JSVAL(42));
*/
#define ShipScriptEvent(context, ship, event, ...) do { \
jsval argv[] = { __VA_ARGS__ }; \
uintN argc = sizeof argv / sizeof *argv; \
[ship doScriptEvent:OOJSID(event) inContext:context withArguments:argv count:argc]; \
jsval argv[] = { __VA_ARGS__ }; \
uintN argc = sizeof argv / sizeof *argv; \
[ship doScriptEvent:OOJSID(event) inContext:context withArguments:argv count:argc]; \
} while (0)
#define ShipScriptEventNoCx(ship, event, ...) do { \
jsval argv[] = { __VA_ARGS__ }; \
uintN argc = sizeof argv / sizeof *argv; \
[ship doScriptEvent:OOJSID(event) withArguments:argv count:argc]; \
jsval argv[] = { __VA_ARGS__ }; \
uintN argc = sizeof argv / sizeof *argv; \
[ship doScriptEvent:OOJSID(event) withArguments:argv count:argc]; \
} while (0)
- (void) reactToAIMessage:(NSString *)message context:(NSString *)debugContext; // Immediate message

View File

@ -1,26 +1,26 @@
/*
ShipEntityAI.m
Oolite
Copyright (C) 2004-2012 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.
*/
ShipEntityAI.m
Oolite
Copyright (C) 2004-2012 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.
*/
#import "ShipEntityAI.h"
#import "OOMaths.h"
@ -212,6 +212,9 @@ MA 02110-1301, USA.
- (void) markTargetForOffence:(NSString *) valueString;
- (void) storeTarget;
- (void) recallStoredTarget;
- (void) scanForRocks;
- (void) performMining;
@ -364,7 +367,7 @@ MA 02110-1301, USA.
{
NSArray* tokens = ScanTokensFromString(intervalString);
double start, end;
if ([tokens count] != 2)
{
OOLog(@"ai.syntax.randomPauseAI", @"***** ERROR: cannot read min and max value for randomPauseAI:, needs 2 values: '%@'.", intervalString);
@ -467,7 +470,7 @@ MA 02110-1301, USA.
return;
if (primaryTarget == primaryAggressor)
return;
// a more considered approach here:
// if we're already busy attacking a target we don't necessarily want to break off
//
@ -476,11 +479,11 @@ MA 02110-1301, USA.
case BEHAVIOUR_ATTACK_FLY_FROM_TARGET:
case BEHAVIOUR_ATTACK_FLY_TO_TARGET:
if (randf() < 0.75) // if I'm attacking, ignore 75% of new aggressor's attacks
// but add them as a secondary target anyway
// but add them as a secondary target anyway
[self addDefenseTarget:primaryAggressor];
return;
return;
break;
default:
break;
}
@ -510,7 +513,7 @@ MA 02110-1301, USA.
return;
if ([self isDefenseTarget:primaryAggressor])
return;
if ([primeAggressor isShip] && ![(ShipEntity *)primeAggressor isFriendlyTo:self])
{
[self addDefenseTarget:primaryAggressor];
@ -766,8 +769,8 @@ MA 02110-1301, USA.
//
StationEntity *station = nil;
station = [UNIVERSE nearestShipMatchingPredicate:IsStationPredicate
parameter:nil
relativeToEntity:self];
parameter:nil
relativeToEntity:self];
if (station && distance2([station position], position) < SCANNER_MAX_RANGE2) // there is a station in range.
{
@ -840,7 +843,7 @@ MA 02110-1301, USA.
[self addTarget:missile];
[self addDefenseTarget:[missile universalID]];
// Notify own ship script that we are being attacked.
ShipEntity *hunter = [missile owner];
[self doScriptEvent:OOJSID("shipBeingAttacked") withArgument:hunter];
@ -913,7 +916,7 @@ MA 02110-1301, USA.
if (the_planet)
{
destination = vector_add([the_planet position], vector_multiply_scalar(
vector_normal(vector_subtract([the_planet position],position)),-10000.0-the_planet->collision_radius));// 10km straight up
vector_normal(vector_subtract([the_planet position],position)),-10000.0-the_planet->collision_radius));// 10km straight up
desired_range = 50.0;
}
else
@ -1064,27 +1067,27 @@ MA 02110-1301, USA.
[shipAI message:@"AEGIS_CLOSE_TO_PLANET"]; // fires only for main planets, keep for compatibility with pre-1.72 AI plists.
break;
case AEGIS_CLOSE_TO_ANY_PLANET:
{
Entity<OOStellarBody> *nearest = [self findNearestStellarBody];
if([nearest isSun])
{
Entity<OOStellarBody> *nearest = [self findNearestStellarBody];
if([nearest isSun])
[shipAI message:@"CLOSE_TO_SUN"];
}
else
{
[shipAI message:@"CLOSE_TO_PLANET"];
if ([nearest planetType] == STELLAR_TYPE_MOON)
{
[shipAI message:@"CLOSE_TO_SUN"];
[shipAI message:@"CLOSE_TO_MOON"];
}
else
{
[shipAI message:@"CLOSE_TO_PLANET"];
if ([nearest planetType] == STELLAR_TYPE_MOON)
{
[shipAI message:@"CLOSE_TO_MOON"];
}
else
{
[shipAI message:@"CLOSE_TO_SECONDARY_PLANET"];
}
[shipAI message:@"CLOSE_TO_SECONDARY_PLANET"];
}
break;
}
break;
}
case AEGIS_IN_DOCKING_RANGE:
[shipAI message:@"AEGIS_IN_DOCKING_RANGE"];
break;
@ -1119,7 +1122,7 @@ MA 02110-1301, USA.
- (void) checkHeatInsulation
{
float minInsulation = 1000 / [self maxFlightSpeed] + 1;
if ([self heatInsulation] < minInsulation)
{
[shipAI message:@"INSULATION_POOR"];
@ -1158,7 +1161,7 @@ MA 02110-1301, USA.
gov_factor = 1.0;
//
found_target = NO_TARGET;
// find the worst offender on the scanner
//
[self checkScanner];
@ -1257,7 +1260,7 @@ MA 02110-1301, USA.
// We now have no escorts..
[_escortGroup release];
_escortGroup = nil;
}
@ -1300,7 +1303,7 @@ MA 02110-1301, USA.
- (void) broadcastDistressMessage
{
/*-- Locates all the stations, bounty hunters and police ships in range and tells them that you are under attack --*/
[self checkScanner];
found_target = NO_TARGET;
@ -1319,7 +1322,7 @@ MA 02110-1301, USA.
for (i = 0; i < n_scanned_ships; i++)
{
ShipEntity* ship = scanned_ships[i];
// tell it!
if (ship->isPlayer)
{
@ -1478,7 +1481,7 @@ MA 02110-1301, USA.
- (void) fightOrFleeHostiles
{
[self addDefenseTarget:found_target];
if ([self hasEscorts])
{
if (found_target == last_escort_target)
@ -1541,7 +1544,7 @@ MA 02110-1301, USA.
int extra = 1 | (ranrot_rand() & 15);
[mother setBounty: [mother legalStatus] + extra withReason:kOOLegalStatusReasonAssistingOffender];
[self setBounty:(bounty+extra) withReason:kOOLegalStatusReasonAssistingOffender];
// bounty += extra; // obviously we're dodgier than we thought!
// bounty += extra; // obviously we're dodgier than we thought!
}
[self setOwner:mother];
@ -1556,7 +1559,7 @@ MA 02110-1301, USA.
OOLog(@"ai.suggestEscort.refused", @"DEBUG: %@ refused by %@", self, mother);
}
#endif
}
[self setOwner:self];
[shipAI message:@"NOT_ESCORTING"];
@ -1681,7 +1684,7 @@ MA 02110-1301, USA.
[self setPrimaryRole:@"police"]; // other wingman can now select this ship as leader.
}
}
}
@ -1894,10 +1897,52 @@ MA 02110-1301, USA.
}
- (void) storeTarget
{
Entity *target = [UNIVERSE entityForUniversalID:primaryTarget];
if (target)
{
remembered_ship = primaryTarget;
}
else
{
remembered_ship = NO_TARGET;
}
}
- (void) recallStoredTarget
{
ShipEntity *oldTarget = [UNIVERSE entityForUniversalID:remembered_ship];
BOOL found = NO;
if (oldTarget && ![oldTarget isCloaked])
{
GLfloat range2 = distance2([oldTarget position], position);
if (range2 <= scannerRange * scannerRange && range2 <= SCANNER_MAX_RANGE2)
{
found = YES;
}
}
if (found)
{
found_target = remembered_ship;
[shipAI message:@"TARGET_FOUND"];
}
else
{
if (oldTarget == nil) remembered_ship = NO_TARGET; // ship no longer exists
[shipAI message:@"NOTHING_FOUND"];
}
}
- (void) scanForRocks
{
/*-- Locates the all boulders and asteroids in range and selects nearest --*/
// find boulders then asteroids within range
//
found_target = NO_TARGET;
@ -1933,7 +1978,7 @@ MA 02110-1301, USA.
}
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
}
@ -1992,7 +2037,7 @@ MA 02110-1301, USA.
}
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
}
@ -2083,19 +2128,19 @@ MA 02110-1301, USA.
- (void) scanForNearestShipMatchingPredicate:(NSString *)predicateExpression
{
/* Takes a boolean-valued JS expression where "ship" is the ship being
evaluated and "this" is our ship's ship script. the expression is
turned into a JS function of the form:
function _oo_AIScanPredicate(ship)
{
return $expression;
}
Examples of expressions:
ship.isWeapon
this.someComplicatedPredicate(ship)
function (ship) { ...do something complicated... } ()
*/
evaluated and "this" is our ship's ship script. the expression is
turned into a JS function of the form:
function _oo_AIScanPredicate(ship)
{
return $expression;
}
Examples of expressions:
ship.isWeapon
this.someComplicatedPredicate(ship)
function (ship) { ...do something complicated... } ()
*/
static NSMutableDictionary *scriptCache = nil;
NSString *aiName = nil;
@ -2110,10 +2155,10 @@ MA 02110-1301, USA.
aiName = [[self getAI] name];
#ifndef NDEBUG
/* In debug/test release builds, scripts are cached per AI in order to be
able to report errors correctly. For end-user releases, we only cache
one copy of each predicate, potentially leading to error messages for
the wrong AI.
*/
able to report errors correctly. For end-user releases, we only cache
one copy of each predicate, potentially leading to error messages for
the wrong AI.
*/
key = [NSString stringWithFormat:@"%@\n%@", aiName, predicateExpression];
#else
key = predicateExpression;
@ -2185,7 +2230,7 @@ MA 02110-1301, USA.
NSString* xString = nil;
NSString* yString = nil;
NSString* zString = nil;
if ([tokens count] != 4)
{
OOLog(@"ai.syntax.setCoordinates", @"***** ERROR: cannot setCoordinates: '%@'.",system_x_y_z);
@ -2279,14 +2324,14 @@ MA 02110-1301, USA.
[shipAI message:@"NO_STATION_FOUND"];
targetStation = NO_TARGET;
}
}
- (void) requestDockingCoordinates
{
/*- requests coordinates from the target station
if the target station can't be found
then use the nearest it can find (which may be a rock hermit) -*/
if the target station can't be found
then use the nearest it can find (which may be a rock hermit) -*/
StationEntity *station = nil;
Entity *targStation = nil;
@ -2301,8 +2346,8 @@ MA 02110-1301, USA.
else
{
station = [UNIVERSE nearestShipMatchingPredicate:IsStationPredicate
parameter:nil
relativeToEntity:self];
parameter:nil
relativeToEntity:self];
}
distanceToStation2 = distance2([station position], [self position]);
@ -2326,7 +2371,7 @@ MA 02110-1301, USA.
message = [dockingInstructions objectForKey:@"comms_message"];
if (message != nil) [station sendExpandedMessage:message toShip:self];
}
}
else
{
@ -2372,7 +2417,7 @@ MA 02110-1301, USA.
WormholeEntity *whole = nil;
ShipEntity *targEnt = [self primaryTarget];
double found_d2 = scannerRange * scannerRange;
if (targEnt && (distance2(position, [targEnt position]) < found_d2))
{
if ([targEnt isWormhole])
@ -2708,7 +2753,7 @@ MA 02110-1301, USA.
context = [NSString stringWithFormat:@"%@ broadcastDistressMessage", [other shortDescription]];
#endif
[shipAI reactToMessage:@"ACCEPT_DISTRESS_CALL" context:context];
}
@end

View File

@ -406,7 +406,6 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
if (![shipsOnHold objectForKey:shipID])
[self sendExpandedMessage: @"[station-acknowledges-hold-position]" toShip: ship];
[shipsOnHold setObject: shipID forKey: shipID];
//[self performStop]; // This should be handled by "DOCKING_REQUESTED" in the AI itself.
return instructions(universalID, ship->position, 0, 100, @"HOLD_POSITION", nil, NO);
}
@ -415,7 +414,6 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
if (![shipsOnHold objectForKey:shipID])
[self sendExpandedMessage: @"[station-acknowledges-hold-position]" toShip: ship];
[shipsOnHold setObject: shipID forKey: shipID];
//[self performStop];
return instructions(universalID, ship->position, 0, 100, @"HOLD_POSITION", nil, NO);
}
@ -431,7 +429,6 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
if (![shipsOnHold objectForKey:shipID])
[self sendExpandedMessage: @"[station-acknowledges-hold-position]" toShip: ship];
[shipsOnHold setObject: shipID forKey: shipID];
//[self performStop];
return instructions(universalID, ship->position, 0, 100, @"HOLD_POSITION", nil, NO);
}
}
@ -1368,18 +1365,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
{
if (![ship isShip]) return NO;
// [ship totalBoundingBox] is not yet defined for 'launching npc ships', so calculate this size.
BoundingBox bb = [ship boundingBox];
ShipEntity *se = nil;
foreach (se, [ship subEntities])
{
if ([se isShip])
{
BoundingBox sebb = [se findSubentityBoundingBox];
bounding_box_add_vector(&bb, sebb.max);
bounding_box_add_vector(&bb, sebb.min);
}
}
BoundingBox bb = [ship totalBoundingBox];
if ((port_dimensions.x < (bb.max.x - bb.min.x) || port_dimensions.y < (bb.max.y - bb.min.y)) &&
(port_dimensions.y < (bb.max.x - bb.min.x) || port_dimensions.x < (bb.max.y - bb.min.y)) && ![ship isPlayer])
{

View File

@ -18,6 +18,7 @@
key_prime_equipment = "N";
key_activate_equipment = "n";
key_mode_equipment = "b";
key_target_incoming_missile = "T";
key_target_missile = "t";
@ -54,6 +55,7 @@
key_hud_toggle = "o";
key_comms_log = "`";
key_prev_compass_mode = "|";
key_next_compass_mode = "\\";
key_cloaking_device = "0";