From 27bb46cacd09edbe600fc8bf3e9f13502b559788 Mon Sep 17 00:00:00 2001 From: Eric Walch Date: Wed, 16 May 2012 12:46:14 +0000 Subject: [PATCH] - 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 --- Resources/AIs/hardMissileAI.plist | 15 ++- Resources/AIs/missileAI.plist | 20 +++ Resources/AIs/pirateAI.plist | 10 +- Resources/Config/whitelist.plist | 2 + src/Core/Entities/ShipEntity.h | 153 ++++++++++----------- src/Core/Entities/ShipEntityAI.m | 213 ++++++++++++++++++------------ src/Core/Entities/StationEntity.m | 16 +-- tools/BBC keys/keyconfig.plist | 2 + 8 files changed, 252 insertions(+), 179 deletions(-) diff --git a/Resources/AIs/hardMissileAI.plist b/Resources/AIs/hardMissileAI.plist index aac0c17f..f057bcf2 100644 --- a/Resources/AIs/hardMissileAI.plist +++ b/Resources/AIs/hardMissileAI.plist @@ -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 = { diff --git a/Resources/AIs/missileAI.plist b/Resources/AIs/missileAI.plist index 669ef254..5868fb60 100644 --- a/Resources/AIs/missileAI.plist +++ b/Resources/AIs/missileAI.plist @@ -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"); diff --git a/Resources/AIs/pirateAI.plist b/Resources/AIs/pirateAI.plist index 0750bbb1..d25d7fc8 100644 --- a/Resources/AIs/pirateAI.plist +++ b/Resources/AIs/pirateAI.plist @@ -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"); diff --git a/Resources/Config/whitelist.plist b/Resources/Config/whitelist.plist index 4ef27060..3ff3aec4 100644 --- a/Resources/Config/whitelist.plist +++ b/Resources/Config/whitelist.plist @@ -208,6 +208,8 @@ "addFoundTargetAsDefenseTarget", "findNewDefenseTarget", "clearDefenseTargets", + "storeTarget", + "recallStoredTarget", // StationEntity.m/stubs in ShipEntityAI.m "increaseAlertLevel", "decreaseAlertLevel", diff --git a/src/Core/Entities/ShipEntity.h b/src/Core/Entities/ShipEntity.h index 992e09b0..dbeb658e 100644 --- a/src/Core/Entities/ShipEntity.h +++ b/src/Core/Entities/ShipEntity.h @@ -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 diff --git a/src/Core/Entities/ShipEntityAI.m b/src/Core/Entities/ShipEntityAI.m index e848df4b..fa307502 100644 --- a/src/Core/Entities/ShipEntityAI.m +++ b/src/Core/Entities/ShipEntityAI.m @@ -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 *nearest = [self findNearestStellarBody]; + + if([nearest isSun]) { - Entity *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 diff --git a/src/Core/Entities/StationEntity.m b/src/Core/Entities/StationEntity.m index b82b615f..c1bf8b4f 100644 --- a/src/Core/Entities/StationEntity.m +++ b/src/Core/Entities/StationEntity.m @@ -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]) { diff --git a/tools/BBC keys/keyconfig.plist b/tools/BBC keys/keyconfig.plist index 2969855a..ee766753 100644 --- a/tools/BBC keys/keyconfig.plist +++ b/tools/BBC keys/keyconfig.plist @@ -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";