50@interface ShipEntity (OOAIPrivate)
54- (BOOL)performHyperSpaceExitReplace:(BOOL)replace;
55- (BOOL)performHyperSpaceExitReplace:(BOOL)replace toSystem:(
OOSystemID)systemID;
58- (void)scanForNearestShipWithNegatedPredicate:(
EntityFilterPredicate)predicate parameter:(
void *)parameter;
60- (void) acceptDistressMessageFrom:(
ShipEntity *)other;
65@interface StationEntity (OOAIPrivate)
67- (void) acceptDistressMessageFrom:(
ShipEntity *)other;
72@interface ShipEntity (PureAI)
76- (void) setStateTo:(NSString *)state;
78- (void) pauseAI:(NSString *)intervalString;
80- (void) randomPauseAI:(NSString *)intervalString;
82- (void) dropMessages:(NSString *)messageString;
88- (void) setDesiredRangeTo:(NSString *)rangeString;
92- (void) setSpeedTo:(NSString *)speedString;
94- (void) setSpeedFactorTo:(NSString *)speedString;
98- (void) setThrustFactorTo:(NSString *)thrustFactorString;
128- (void) exitAIWithMessage:(NSString *)message;
151- (void) commsMessage:(NSString *)valueString;
152- (void) commsMessageByUnpiloted:(NSString *)valueString;
173- (void) messageMother:(NSString *)msgString;
187- (void) sendTargetCommsMessage:(NSString *)message;
191- (void) markTargetForOffence:(NSString *)valueString;
202- (void) rollD:(NSString *)die_number;
204- (void) scanForNearestShipWithPrimaryRole:(NSString *)scanRole;
205- (void) scanForNearestShipHavingRole:(NSString *)scanRole;
206- (void) scanForNearestShipWithAnyPrimaryRole:(NSString *)scanRoles;
207- (void) scanForNearestShipHavingAnyRole:(NSString *)scanRoles;
208- (void) scanForNearestShipWithScanClass:(NSString *)scanScanClass;
210- (void) scanForNearestShipWithoutPrimaryRole:(NSString *)scanRole;
211- (void) scanForNearestShipNotHavingRole:(NSString *)scanRole;
212- (void) scanForNearestShipWithoutAnyPrimaryRole:(NSString *)scanRoles;
213- (void) scanForNearestShipNotHavingAnyRole:(NSString *)scanRoles;
214- (void) scanForNearestShipWithoutScanClass:(NSString *)scanScanClass;
216- (void) setCoordinates:(NSString *)system_x_y_z;
223- (void) addFuel:(NSString *) fuel_number;
225- (void) scriptActionOnTarget:(NSString *) action;
227- (void) sendScriptMessage:(NSString *)message;
233- (void) ai_debugMessage:(NSString *)message;
236- (void) targetFirstBeaconWithCode:(NSString *) code;
237- (void) targetNextBeaconWithCode:(NSString *) code;
249@implementation ShipEntity (AI)
252- (void) setAITo:(NSString *)aiString
255 if (![
PLAYER scriptsLoaded])
257 aiString =
@"oolite-nullAI.js";
259 if ([aiString hasSuffix:
@".plist"])
264 else if ([aiString hasSuffix:
@".js"])
252- (void) setAITo:(NSString *)aiString {
…}
284- (void) setAIScript:(NSString *)aiString
286 NSMutableDictionary *properties =
nil;
295 OOLog(
@"ai.load.failed.unknownAI",
@"Unable to load JS AI %@ for ship %@ (%@ for role %@)",aiString,
self,[
self shipDataKey],[
self primaryRole]);
300 aiScriptWakeTime = 0;
301 haveStartedJSAI = NO;
284- (void) setAIScript:(NSString *)aiString {
…}
307- (void) switchAITo:(NSString *)aiString
307- (void) switchAITo:(NSString *)aiString {
…}
321 GLfloat found_d2 = scannerRange * scannerRange;
322 for (i = 0; i < n_scanned_ships ; i++)
325 GLfloat d2 = distance2_scanned_ships[
i];
327 && ([thing isThargoid] || (([thing primaryTarget] ==
self) && [thing hasHostileTarget]) || [thing isDefenseTarget:
self])
328 && ![thing isCloaked])
341 NSEnumerator *shipEnum =
nil;
346 if (target ==
nil)
return;
348 if ([
self group] ==
nil)
351 [
shipAI reactToMessage:@"GROUP_ATTACK_TARGET" context:@"groupAttackTarget"];
356 for (shipEnum = [[
self group] mutationSafeEnumerator]; (ship = [
shipEnum nextObject]); )
358 [
ship setFoundTarget:target];
359 [
ship reactToAIMessage:@"GROUP_ATTACK_TARGET" context:@"groupAttackTarget"];
360 [
ship doScriptEvent:OOJSID("helpRequestReceived") withArgument:
self andArgument:target];
362 if ([ship escortGroup] != [ship group] && [[ship escortGroup]
count] > 1)
365 NSEnumerator *shipEnum =
nil;
366 NSArray *escortMembers = [[
ship escortGroup] memberArrayExcludingLeader];
367 for (shipEnum = [escortMembers objectEnumerator]; (escort = [
shipEnum nextObject]); )
380 if (behaviour != BEHAVIOUR_EVASIVE_ACTION)
382 behaviour = BEHAVIOUR_ATTACK_TARGET;
383 desired_range = 1250 *
randf() + 750;
391 behaviour = BEHAVIOUR_COLLECT_TARGET;
398 if(behaviour != BEHAVIOUR_FORMATION_FORM_UP)
400 behaviour = BEHAVIOUR_FORMATION_FORM_UP;
408 behaviour = BEHAVIOUR_FACE_DESTINATION;
415 if (behaviour != BEHAVIOUR_FLEE_EVASIVE_ACTION)
417 behaviour = BEHAVIOUR_FLEE_TARGET;
423 if ([
self approachAspectToPrimaryTarget] > 0.9995)
425 behaviour =
randf() < 0.15 ? BEHAVIOUR_EVASIVE_ACTION : BEHAVIOUR_FLEE_EVASIVE_ACTION;
434 behaviour = BEHAVIOUR_FLY_RANGE_FROM_DESTINATION;
442 behaviour = BEHAVIOUR_TRACK_TARGET;
449 behaviour = BEHAVIOUR_IDLE;
456 behaviour = BEHAVIOUR_INTERCEPT_TARGET;
464 if (isNearPlanetSurface)
466 _destination = [
nearest position];
467 behaviour = BEHAVIOUR_LAND_ON_PLANET;
468 planetForLanding = [
nearest universalID];
472 behaviour = BEHAVIOUR_IDLE;
473 [
shipAI message:@"NO_PLANET_NEARBY"];
484 if (target && [target scanClass] == CLASS_ROCK)
486 behaviour = BEHAVIOUR_ATTACK_MINING_TARGET;
498 behaviour = BEHAVIOUR_SCRIPTED_AI;
505 behaviour = BEHAVIOUR_SCRIPTED_ATTACK_AI;
514 behaviour = BEHAVIOUR_TUMBLE;
521 behaviour = BEHAVIOUR_STOP_STILL;
529 stick_roll = max_flight_roll*2.0*(
randf() - 0.5);
530 stick_pitch = max_flight_pitch*2.0*(
randf() - 0.5);
531 behaviour = BEHAVIOUR_TUMBLE;
536- (BOOL) performHyperSpaceToSpecificSystem:(
OOSystemID)systemID
536- (BOOL) performHyperSpaceToSpecificSystem:(
OOSystemID)systemID {
…}
550 NSString *message =
nil;
551 double distanceToStation2 = 0.0;
554 if ([targStation isStation])
560 station = [UNIVERSE nearestShipMatchingPredicate:IsStationPredicate
562 relativeToEntity:
self];
565 distanceToStation2 = HPdistance2([station position], [
self position]);
577 if (dockingInstructions !=
nil)
582 if (message !=
nil) [
shipAI message:message];
592 if (dockingInstructions ==
nil)
594 [
shipAI message:@"NO_STATION_FOUND"];
601 if (dockingInstructions !=
nil)
604 desired_speed = fmin([dockingInstructions oo_floatForKey:
@"speed"], maxFlightSpeed);
606 if ([dockingInstructions objectForKey:
@"station"])
609 if (targetStation !=
nil)
643 double found_d2 = scannerRange * scannerRange;
645 if (targEnt && (HPdistance2(position, [targEnt position]) < found_d2))
647 if ([targEnt isWormhole])
649 else if ([targEnt isPlayer])
650 whole = [PLAYER wormhole];
656 int ent_count =
UNIVERSE->n_entities;
661 for (i = 0; i < ent_count; i++)
662 if (uni_entities[i]->isWormhole)
666 for (i = 0; i < wh_count ; i++)
669 double d2 = HPdistance2(position, wh->
position);
686 NSEnumerator *shipEnum =
nil;
688 NSString *context =
nil;
692 if (![whole isWormhole])
return;
695 context = [
NSString stringWithFormat:@"%@ wormholeEscorts", [
self shortDescription]];
698 for (shipEnum = [
self escortEnumerator]; (ship = [
shipEnum nextObject]); )
725 if (reportAIMessages)
727 OOLog(
@"ai.suggestEscort",
@"DEBUG: %@ suggests escorting %@",
self, mother);
731 if ([mother acceptAsEscort:
self])
734 if (([mother legalStatus] > 0)&&(bounty <= 0))
744 [
shipAI message:@"ESCORTING"];
749 if (reportAIMessages)
751 OOLog(
@"ai.suggestEscort.refused",
@"DEBUG: %@ refused by %@",
self, mother);
757 [
shipAI message:@"NOT_ESCORTING"];
769- (void) broadcastDistressMessageWithDumping:(BOOL)dumpCargo
775 if (aggressor_ship ==
nil)
return;
778 if (messageTime > 2.0 *
randf())
return;
780 NSString *distress_message =
nil;
781 BOOL is_buoy = (scanClass == CLASS_BUOY);
782 if (is_buoy) distress_message =
@"[buoy-distress-call]";
783 else distress_message =
@"[distress-call]";
786 for (i = 0; i < n_scanned_ships; i++)
791 if (dumpCargo && !is_buoy && [
self primaryAggressor] == ship && energy < 0.375 * maxEnergy)
799 if (ship->
isPlayer && ![
self hasNewAI])
803 if (!is_buoy && [
self primaryAggressor] == ship && energy < 0.375 * maxEnergy)
807 else if ([
self bounty] == 0)
817 else if ([
self bounty] == 0 && [ship crew])
827 if (![
self hasNewAI])
830 if (ship->
isStation || [ship hasPrimaryRole:
@"police"] || [ship hasPrimaryRole:
@"hunter"])
769- (void) broadcastDistressMessageWithDumping:(BOOL)dumpCargo {
…}
843@implementation ShipEntity (PureAI)
845- (void) setStateTo:(NSString *)state
845- (void) setStateTo:(NSString *)state {
…}
851- (void) pauseAI:(NSString *)intervalString
851- (void) pauseAI:(NSString *)intervalString {
…}
857- (void) randomPauseAI:(NSString *)intervalString
862 if ([tokens
count] != 2)
864 OOLog(
@"ai.syntax.randomPauseAI",
@"***** ERROR: cannot read min and max value for randomPauseAI:, needs 2 values: '%@'.", intervalString);
868 start = [
tokens oo_doubleAtIndex:0];
869 end = [
tokens oo_doubleAtIndex:1];
871 [
shipAI setNextThinkTime:[UNIVERSE getTime] + (start + (end - start)*randf())];
857- (void) randomPauseAI:(NSString *)intervalString {
…}
875- (void) dropMessages:(NSString *)messageString
877 NSArray *messages =
nil;
878 NSEnumerator *messageEnum =
nil;
879 NSString *message =
nil;
880 NSCharacterSet *whiteSpace = [
NSCharacterSet whitespaceCharacterSet];
883 for (messageEnum = [messages objectEnumerator]; (message = [
messageEnum nextObject]); )
885 [
shipAI dropMessage:[
message stringByTrimmingCharactersInSet:whiteSpace]];
875- (void) dropMessages:(NSString *)messageString {
…}
892 [
shipAI debugDumpPendingMessages];
905 Vector front = vector_multiply_scalar([
self forwardVector], flightSpeed / max_flight_pitch * 2);
906 _destination = HPvector_add(position, vectorToHPVector(vector_add(front,
OOVectorRandomSpatial(100))));
911- (void) setDesiredRangeTo:(NSString *)rangeString
911- (void) setDesiredRangeTo:(NSString *)rangeString {
…}
918 desired_range = fmax(maxFlightSpeed / max_flight_pitch / 6, 50.0);
921- (void) setSpeedTo:(NSString *)speedString
921- (void) setSpeedTo:(NSString *)speedString {
…}
927- (void) setSpeedFactorTo:(NSString *)speedString
929 desired_speed = maxFlightSpeed * [
speedString doubleValue];
927- (void) setSpeedFactorTo:(NSString *)speedString {
…}
934 desired_speed = cruiseSpeed;
937- (void) setThrustFactorTo:(NSString *)thrustFactorString
939 thrust = OOClamp_0_1_f([thrustFactorString doubleValue]) * max_thrust;
937- (void) setThrustFactorTo:(NSString *)thrustFactorString {
…}
948 if ([
self primaryTarget] == primeAggressor)
954 if ([
self hasHostileTarget] &&
randf() < 0.75)
961 if ([primeAggressor isShip] && ![(
ShipEntity *)primeAggressor isFriendlyTo:
self])
966 if ((primeTarget)&&(primeTarget->
isShip))
984 if ([
self isDefenseTarget:primeAggressor])
987 if ([primeAggressor isShip] && ![(
ShipEntity*)primeAggressor isFriendlyTo:
self])
1003 found_d2 = scannerRange * scannerRange;
1006 for (i = 0; i < n_scanned_ships ; i++)
1008 ship = scanned_ships[
i];
1009 if ([ship isPirateVictim] && ([ship status] != STATUS_DEAD) && ([ship status] != STATUS_DOCKED) && ![ship isCloaked])
1011 d2 = distance2_scanned_ships[
i];
1016 else d2 = distance2_scanned_ships[
i];
1030 unsigned n_found, i;
1038 for (i = 0; i < n_scanned_ships ; i++)
1041 if (([ship status] != STATUS_DEAD) && ([ship status] != STATUS_DOCKED) && [ship isPirateVictim] && ![ship isCloaked])
1046 [
shipAI message:@"NOTHING_FOUND"];
1052 [
shipAI message:@"TARGET_FOUND"];
1062 if (![
self hasCargoScoop])
1064 [
shipAI message:@"NOTHING_FOUND"];
1067 if ([cargo
count] >= [
self maxAvailableCargoSpace])
1069 if (max_cargo) [
shipAI message:@"HOLD_FULL"];
1070 [
shipAI message:@"NOTHING_FOUND"];
1076 if (magnitude2([
self velocity]))
1078 [
shipAI message:@"NOTHING_FOUND"];
1085 double found_d2 = scannerRange * scannerRange;
1088 for (i = 0; i < n_scanned_ships; i++)
1091 if ([other scanClass] == CLASS_CARGO && [other cargoType] !=
CARGO_NOT_CARGO && [other status] != STATUS_BEING_SCOOPED)
1093 if ((![
self isPolice]) || ([[other commodityType] isEqualToString:
@"slaves"]))
1095 GLfloat d2 = distance2_scanned_ships[
i];
1111 if (![
self isStation] && ![
self hasCargoScoop])
1113 [
shipAI message:@"NOTHING_FOUND"];
1120 unsigned things_found = 0;
1123 for (i = 0; (i < n_scanned_ships)&&(things_found < 16) ; i++)
1126 if ([other scanClass] == CLASS_CARGO && [other cargoType] !=
CARGO_NOT_CARGO && [other status] != STATUS_BEING_SCOOPED)
1132 if (things_found != 0)
1134 [
self setFoundTarget:thing_uids_found[ranrot_rand() % things_found]];
1135 [
shipAI message:@"TARGET_FOUND"];
1138 [
shipAI message:@"NOTHING_FOUND"];
1144 if ([
self foundTarget] !=
nil)
1150 [
shipAI message:@"TARGET_LOST"];
1160 if ([fTarget isShip] && ![(
ShipEntity *)fTarget isFriendlyTo:
self])
1171 [
shipAI message:@"NO_CARGO_BAY"];
1173 else if ([cargo
count] >= [
self maxAvailableCargoSpace])
1175 [
shipAI message:@"HOLD_FULL"];
1179 [
shipAI message:@"HOLD_NOT_FULL"];
1192 Vector vr = vector_multiply_scalar(v_forward, maxFlightSpeed * 10.0);
1193 coordinates = HPvector_add(position, vectorToHPVector(vr));
1202 station = [UNIVERSE nearestShipMatchingPredicate:IsStationPredicate
1204 relativeToEntity:
self];
1208 Vector vr = vector_multiply_scalar([station rightVector], 10000);
1209 coordinates = HPvector_add([station position], vectorToHPVector(vr));
1213 Vector vr = vector_multiply_scalar(v_forward, maxFlightSpeed * 10.0);
1214 coordinates = HPvector_add(position, vectorToHPVector(vr));
1221 _destination = coordinates;
1227 coordinates = position;
1237 NSEnumerator *escortEnum =
nil;
1242 for (i = 0; (i < n_scanned_ships)&&(missile ==
nil); i++)
1255 for (escortEnum = [
self escortEnumerator]; (escort = [
escortEnum nextObject]); )
1257 if (target == escort)
1266 if (missile ==
nil)
return;
1276 if ([
self isPolice])
1280 NSEnumerator *policeEnum =
nil;
1283 for (policeEnum = [[
self group] mutationSafeEnumerator]; (police = [
policeEnum nextObject]); )
1305 desired_range = 10000;
1307 [
shipAI message:@"FLEEING"];
1317 double variation = (aegis_status ==
AEGIS_NONE ? 0.5 : 0.2);
1318 HPVector p_pos = the_planet->position;
1319 double p_cr = the_planet->collision_radius;
1320 HPVector p1 = HPvector_between(p_pos, position);
1321 p1 = HPvector_normal(p1);
1322 p1.x += variation * (
randf() - variation);
1323 p1.y += variation * (
randf() - variation);
1324 p1.z += variation * (
randf() - variation);
1325 p1 = HPvector_normal(p1);
1326 _destination = HPvector_add(p_pos, HPvector_multiply_scalar(p1, p_cr));
1327 desired_range = collision_radius + 100.0;
1331 [
shipAI message:@"NO_PLANET_FOUND"];
1342 _destination = HPvector_add([the_planet position], HPvector_multiply_scalar(
1343 HPvector_normal(HPvector_subtract([the_planet position],position)),-10000.0-the_planet->collision_radius));
1344 desired_range = 50.0;
1348 OOLog(
@"ai.setTakeOffFromPlanet.noPlanet",
@"%@",
@"***** Error. Planet not found during take off!");
1365 [
shipAI message:@"NO_TARGET"];
1373 [
shipAI message:@"TARGET_FUGITIVE"];
1378 [
shipAI message:@"TARGET_OFFENDER"];
1383 [
shipAI message:@"TARGET_MINOR_OFFENDER"];
1386 [
shipAI message:@"TARGET_CLEAN"];
1393 if (scanClass == CLASS_THARGOID)
1395 [
shipAI message:@"SELF_THARGOID"];
1401 [
shipAI message:@"SELF_FUGITIVE"];
1406 [
shipAI message:@"SELF_OFFENDER"];
1411 [
shipAI message:@"SELF_MINOR_OFFENDER"];
1414 [
shipAI message:@"SELF_CLEAN"];
1418- (void) exitAIWithMessage:(NSString *)message
1420 if ([message length] == 0) message =
@"RESTARTED";
1421 [
shipAI exitStateMachineWithMessage:message];
1418- (void) exitAIWithMessage:(NSString *)message {
…}
1429 _destination = the_target->
position;
1438 HPVector pos = the_target->
position;
1442 _destination = make_HPvector(pos.x + d * v.x, pos.y + d * v.y, pos.z + d * v.z);
1449 Entity *hazard = [UNIVERSE hazardOnRouteFromEntity:
self toDistance: desired_range fromPoint: _destination];
1451 if (hazard ==
nil || ([hazard isShip] && HPdistance(position, [hazard position]) > scannerRange) || ([hazard isPlanet] && aegis_status ==
AEGIS_NONE))
1452 [
shipAI message:@"COURSE_OK"];
1455 if ([hazard isShip] && (weapon_damage * 24.0 > [hazard energy]))
1457 [
shipAI reactToMessage:@"HAZARD_CAN_BE_DESTROYED" context:@"checkCourseToDestination"];
1460 _destination = [UNIVERSE getSafeVectorFromEntity:
self toDistance:desired_range fromPoint:_destination];
1461 [
shipAI message:@"WAYPOINT_SET"];
1468 switch (aegis_status)
1471 [
shipAI message:@"AEGIS_CLOSE_TO_MAIN_PLANET"];
1481 [
shipAI message:@"CLOSE_TO_SUN"];
1485 [
shipAI message:@"CLOSE_TO_PLANET"];
1488 [
shipAI message:@"CLOSE_TO_MOON"];
1492 [
shipAI message:@"CLOSE_TO_SECONDARY_PLANET"];
1498 [
shipAI message:@"AEGIS_IN_DOCKING_RANGE"];
1501 [
shipAI message:@"AEGIS_NONE"];
1505 NSLog(
@"Aegis status for %@ has taken on invalid value %i. This is an internal error, please report it.",
self, aegis_status);
1507 [
shipAI message:@"AEGIS_NONE"];
1513 if (energy == maxEnergy)
1515 [
shipAI message:@"ENERGY_FULL"];
1518 if (energy >= maxEnergy * 0.75)
1520 [
shipAI message:@"ENERGY_HIGH"];
1523 if (energy <= maxEnergy * 0.25)
1525 [
shipAI message:@"ENERGY_LOW"];
1528 [
shipAI message:@"ENERGY_MEDIUM"];
1535 if ([
self heatInsulation] < minInsulation)
1537 [
shipAI message:@"INSULATION_POOR"];
1540 [
shipAI message:@"INSULATION_OK"];
1548 for (i = 0; i < n_scanned_ships ; i++)
1551 if (![ship isCloaked] && (([ship primaryTarget] ==
self && [ship hasHostileTarget]) || [ship isMine] || ([ship isThargoid] != [
self isThargoid])))
1553 if (![
self isDefenseTarget:ship])
1566 NSDictionary *systeminfo = [UNIVERSE currentSystemData];
1567 float gov_factor = 0.4 * [(
NSNumber *)[
systeminfo objectForKey:KEY_GOVERNMENT] intValue];
1578 float worst_legal_factor = 0;
1579 GLfloat found_d2 = scannerRange * scannerRange;
1581 for (i = 0; i < n_scanned_ships ; i++)
1584 if ((ship->
scanClass != CLASS_CARGO)&&([ship status] != STATUS_DEAD)&&([ship status] != STATUS_DOCKED)&& ![ship isCloaked])
1586 GLfloat d2 = distance2_scanned_ships[
i];
1589 if ((d2 < found_d2)&&(random_factor < legal_factor)&&(legal_factor > worst_legal_factor))
1591 if (group ==
nil || group != [ship group])
1594 worst_legal_factor = legal_factor;
1608 _destination = [UNIVERSE getWitchspaceExitPosition];
1609 desired_range = 10000.0;
1616 _destination = [UNIVERSE getWitchspaceExitPosition];
1624 _destination = [[UNIVERSE station] beaconPosition];
1643 OOLogERR(
@"ai.invalid.notPlayer",
@"Error in %@:%@, AI method endAutoPilot is only applicable to the player.", [shipAI name], [shipAI state]);
1649 NSEnumerator *shipEnum =
nil;
1654 if (![whole isWormhole])
return;
1656 for (shipEnum = [[
self group] mutationSafeEnumerator]; (ship = [
shipEnum nextObject]); )
1665- (void) commsMessage:(NSString *)valueString
1665- (void) commsMessage:(NSString *)valueString {
…}
1671- (void) commsMessageByUnpiloted:(NSString *)valueString
1671- (void) commsMessageByUnpiloted:(NSString *)valueString {
…}
1680 while (cargo_to_go > 15)
1685 for (i = 1; i < cargo_to_go; i++)
1687 [
self performSelector:@selector(dumpCargo) withObject:nil afterDelay:0.75 * i];
1705 GLfloat found_d2 = scannerRange * scannerRange;
1706 for (i = 0; i < n_scanned_ships ; i++)
1709 GLfloat d2 = distance2_scanned_ships[
i];
1710 if (([thing scanClass] != CLASS_CARGO) && ([thing status] != STATUS_DOCKED) && ![thing isThargoid] && ![thing isCloaked] && (d2 < found_d2))
1713 if ([thing isPlayer]) d2 = 0.0;
1725 if (mother ==
nil && [
self group]) mother = [[
self group]
leader];
1727 double maxRange2 = scannerRange * scannerRange;
1729 if (mother && mother !=
self && HPdistance2(mother->
position, position) < maxRange2)
1731 [
shipAI message:@"TARGET_FOUND"];
1737 if ([
self foundTarget] !=
nil)
1741 if ([mother group] != [mother escortGroup])
1752 int ent_count =
UNIVERSE->n_entities;
1755 for (i = 0; i < ent_count; i++)
if (uni_entities[i]->isShip)
1758 if ([other primaryTarget] ==
self)
1762 if ([other isDefenseTarget:
self])
1768 scanClass = CLASS_CARGO;
1769 reportAIMessages = NO;
1770 [
self setAITo:@"dumbAI.plist"];
1779 if (distanceTravelled > desired_range)
1780 [
shipAI message:@"GONE_BEYOND_RANGE"];
1788 if ([
self hasEscorts])
1791 if (leTarget !=
nil)
1794 [
shipAI message:@"FLEEING"];
1801 [
shipAI message:@"DEPLOYING_ESCORTS"];
1802 [
shipAI message:@"FLEEING"];
1814 [
shipAI message:@"FLEEING"];
1820 if (energy > maxEnergy * 0.80)
1824 [
shipAI message:@"FIGHTING"];
1828 [
shipAI message:@"FLEEING"];
1844 if ([mother acceptAsEscort:
self])
1848 [
shipAI message:@"ESCORTING"];
1853 if ([
self group] == [mother escortGroup]) [
self setGroup:nil];
1854 [
shipAI message:@"NOT_ESCORTING"];
1864 if (ownGroupCount == targetGroupCount)
1866 [
shipAI message:@"ODDS_LEVEL"];
1868 else if (ownGroupCount > targetGroupCount)
1870 [
shipAI message:@"ODDS_GOOD"];
1874 [
shipAI message:@"ODDS_BAD"];
1887 GLfloat found_d2 = scannerRange * scannerRange;
1888 for (i = 0; i < n_scanned_ships; i++)
1891 if ((ship !=
self) && (!ship->
isPlayer) && (ship->
scanClass == scanClass) && [ship primaryTarget] !=
self && ![ship isCloaked])
1893 GLfloat d2 = distance2_scanned_ships[
i];
1894 if ((d2 < found_d2) && [ship canAcceptEscort:
self])
1902 if ([
self foundTarget] !=
nil) [
shipAI message:@"TARGET_FOUND"];
1905 [
shipAI message:@"NOTHING_FOUND"];
1906 if ([
self hasPrimaryRole:
@"wingman"])
1909 [
self setAITo:@"route1patrolAI.plist"];
1917- (void) messageMother:(NSString *)msgString
1920 if (mother !=
nil && mother !=
self)
1922 NSString *context =
nil;
1924 context = [
NSString stringWithFormat:@"%@ messageMother", [
self shortDescription]];
1917- (void) messageMother:(NSString *)msgString {
…}
1931- (void) messageSelf:(NSString *)msgString
1931- (void) messageSelf:(NSString *)msgString {
…}
1940 HPVector r_pos = HPvector_subtract(position, coordinates);
1941 if (HPmagnitude2(r_pos) < 1000000 || patrol_counter == 0)
1943 Entity *the_sun = [UNIVERSE sun];
1945 if(!the_station || ![the_station isStation]) the_station = [UNIVERSE station];
1946 if ((!the_sun)||(!the_station))
1948 HPVector sun_pos = the_sun->
position;
1949 HPVector stn_pos = the_station->
position;
1950 HPVector sun_dir = HPvector_subtract(sun_pos,stn_pos);
1951 Vector vSun = make_vector(0, 0, 1);
1952 if (sun_dir.x||sun_dir.y||sun_dir.z)
1953 vSun = HPVectorToVector(HPvector_normal(sun_dir));
1955 Vector v1 = cross_product(v0, vSun);
1956 Vector v2 = cross_product(v0, v1);
1957 switch (patrol_counter)
1960 coordinates = make_HPvector(stn_pos.x + 5000 * v0.x, stn_pos.y + 5000 * v0.y, stn_pos.z + 5000 * v0.z);
1961 desired_range = 250.0;
1964 coordinates = make_HPvector(stn_pos.x + 25000 * v1.x, stn_pos.y + 25000 * v1.y, stn_pos.z + 25000 * v1.z);
1965 desired_range = 250.0;
1968 coordinates = make_HPvector(stn_pos.x + 25000 * v2.x, stn_pos.y + 25000 * v2.y, stn_pos.z + 25000 * v2.z);
1969 desired_range = 250.0;
1972 coordinates = make_HPvector(stn_pos.x - 25000 * v1.x, stn_pos.y - 25000 * v1.y, stn_pos.z - 25000 * v1.z);
1973 desired_range = 250.0;
1976 coordinates = make_HPvector(stn_pos.x - 25000 * v2.x, stn_pos.y - 25000 * v2.y, stn_pos.z - 25000 * v2.z);
1977 desired_range = 250.0;
1980 coordinates = make_HPvector(stn_pos.x + 5000 * v0.x, stn_pos.y + 5000 * v0.y, stn_pos.z + 5000 * v0.z);
1981 desired_range = 250.0;
1985 if (patrol_counter > 4)
1991 [
self setAITo:@"dockingAI.plist"];
2001 [
shipAI message:@"APPROACH_COORDINATES"];
2009 [
shipAI message:@"NO_SUN_FOUND"];
2013 HPVector v0 = [UNIVERSE getSunSkimStartPositionForShip:
self];
2018 [
shipAI message:@"APPROACH_COORDINATES"];
2022 [
shipAI message:@"WAIT_FOR_SUN"];
2031 [
shipAI message:@"NO_SUN_FOUND"];
2035 coordinates = [UNIVERSE getSunSkimEndPositionForShip:
self];
2036 [
shipAI message:@"APPROACH_COORDINATES"];
2042 Entity *the_sun = [UNIVERSE sun];
2043 if (the_sun ==
nil)
return;
2044 HPVector v1 = [UNIVERSE getSunSkimEndPositionForShip:
self];
2046 HPVector vout = HPvector_subtract(v1,vs);
2047 if (vout.x||vout.y||vout.z)
2048 vout = HPvector_normal(vout);
2051 v1.x += 10000 * vout.x; v1.y += 10000 * vout.y; v1.z += 10000 * vout.z;
2053 [
shipAI message:@"APPROACH_COORDINATES"];
2061 if(!the_station || ![the_station isStation]) the_station = [UNIVERSE station];
2069 if ((!motherStation) || (!(motherStation->
isStation)))
2071 [
shipAI message:@"NOTHING_FOUND"];
2074 double found_d2 = scannerRange * scannerRange;
2075 HPVector v0 = motherStation->
position;
2076 if (HPdistance2(v0,position) > found_d2)
2078 [
shipAI message:@"NOTHING_FOUND"];
2081 [
shipAI message:@"STATION_FOUND"];
2085- (void) sendTargetCommsMessage:(NSString*) message
2088 if ((ship ==
nil) || ([ship status] == STATUS_DEAD) || ([ship status] == STATUS_DOCKED))
2085- (void) sendTargetCommsMessage:(NSString*) message {
…}
2100 if ((ship ==
nil) || ([ship status] == STATUS_DEAD) || ([ship status] == STATUS_DOCKED))
2105 if ([ship markForFines]) [
shipAI message:@"TARGET_MARKED"];
2109- (void) markTargetForOffence:(NSString *)valueString
2111 if ((isStation)||(scanClass == CLASS_POLICE))
2114 if ((ship ==
nil) || ([ship status] == STATUS_DEAD) || ([ship status] == STATUS_DOCKED))
2119 NSString *finalValue =
OOExpand(valueString);
2109- (void) markTargetForOffence:(NSString *)valueString {
…}
2145 if (oldTarget && ![oldTarget isCloaked])
2147 GLfloat range2 = HPdistance2([oldTarget position], position);
2157 [
shipAI message:@"TARGET_FOUND"];
2161 if (oldTarget ==
nil)
DESTROY(_rememberedShip);
2162 [
shipAI message:@"NOTHING_FOUND"];
2176 GLfloat found_d2 = scannerRange * scannerRange;
2177 for (i = 0; i < n_scanned_ships; i++)
2180 if ([thing isBoulder])
2182 GLfloat d2 = distance2_scanned_ships[
i];
2190 if ([
self foundTarget] ==
nil)
2192 for (i = 0; i < n_scanned_ships; i++)
2195 if ([thing hasRole:
@"asteroid"])
2197 GLfloat d2 = distance2_scanned_ships[
i];
2217 the_target = [UNIVERSE station];
2219 double bo_distance = 8000;
2220 HPVector v0 = position;
2222 v0.x += (
randf() - 0.5)*collision_radius; v0.y += (
randf() - 0.5)*collision_radius; v0.z += (
randf() - 0.5)*collision_radius;
2223 v0.x -= d0.x; v0.y -= d0.y; v0.z -= d0.z;
2224 v0 = HPvector_normal_or_fallback(v0, make_HPvector(0, 0, -1));
2226 v0.x *= bo_distance; v0.y *= bo_distance; v0.z *= bo_distance;
2227 v0.x += d0.x; v0.y += d0.y; v0.z += d0.z;
2238 [
shipAI message:@"MOTHER_LOST"];
2246 GLfloat found_d2 = scannerRange * scannerRange;
2248 for (i = 0; i < n_scanned_ships ; i++)
2251 GLfloat d2 = distance2_scanned_ships[
i];
2253 if ((d2 < found_d2) && ![thing isCloaked] && (([thing isThargoid] && ![mother isThargoid]) || (([thing primaryTarget] == mother) && [thing hasHostileTarget])))
2267- (void) rollD:(NSString *)die_number
2273 NSString* result = [
NSString stringWithFormat:@"ROLL_%d", die_roll];
2274 [
shipAI reactToMessage:result context:@"rollD:"];
2278 OOLog(
@"ai.rollD.invalidValue",
@"***** ERROR: invalid value supplied to rollD: '%@'.", die_number);
2267- (void) rollD:(NSString *)die_number {
…}
2283- (void) scanForNearestShipWithPrimaryRole:(NSString *)scanRole
2283- (void) scanForNearestShipWithPrimaryRole:(NSString *)scanRole {
…}
2289- (void) scanForNearestShipHavingRole:(NSString *)scanRole
2289- (void) scanForNearestShipHavingRole:(NSString *)scanRole {
…}
2295- (void) scanForNearestShipWithAnyPrimaryRole:(NSString *)scanRoles
2297 NSSet *
set = [
NSSet setWithArray:ScanTokensFromString(scanRoles)];
2295- (void) scanForNearestShipWithAnyPrimaryRole:(NSString *)scanRoles {
…}
2302- (void) scanForNearestShipHavingAnyRole:(NSString *)scanRoles
2304 NSSet *
set = [
NSSet setWithArray:ScanTokensFromString(scanRoles)];
2302- (void) scanForNearestShipHavingAnyRole:(NSString *)scanRoles {
…}
2309- (void) scanForNearestShipWithScanClass:(NSString *)scanScanClass
2311 NSNumber *parameter = [
NSNumber numberWithInt:OOScanClassFromString(scanScanClass)];
2309- (void) scanForNearestShipWithScanClass:(NSString *)scanScanClass {
…}
2316- (void) scanForNearestShipWithoutPrimaryRole:(NSString *)scanRole
2316- (void) scanForNearestShipWithoutPrimaryRole:(NSString *)scanRole {
…}
2322- (void) scanForNearestShipNotHavingRole:(NSString *)scanRole
2322- (void) scanForNearestShipNotHavingRole:(NSString *)scanRole {
…}
2328- (void) scanForNearestShipWithoutAnyPrimaryRole:(NSString *)scanRoles
2330 NSSet *
set = [
NSSet setWithArray:ScanTokensFromString(scanRoles)];
2328- (void) scanForNearestShipWithoutAnyPrimaryRole:(NSString *)scanRoles {
…}
2335- (void) scanForNearestShipNotHavingAnyRole:(NSString *)scanRoles
2337 NSSet *
set = [
NSSet setWithArray:ScanTokensFromString(scanRoles)];
2335- (void) scanForNearestShipNotHavingAnyRole:(NSString *)scanRoles {
…}
2342- (void) scanForNearestShipWithoutScanClass:(NSString *)scanScanClass
2344 NSNumber *parameter = [
NSNumber numberWithInt:OOScanClassFromString(scanScanClass)];
2342- (void) scanForNearestShipWithoutScanClass:(NSString *)scanScanClass {
…}
2349- (void) scanForNearestShipMatchingPredicate:(NSString *)predicateExpression
2366 static NSMutableDictionary *scriptCache =
nil;
2367 NSString *aiName =
nil;
2368 NSString *key =
nil;
2370 JSContext *context = NULL;
2374 if (predicateExpression ==
nil) predicateExpression =
@"false";
2383 key = [
NSString stringWithFormat:@"%@\n%@", aiName, predicateExpression];
2385 key = predicateExpression;
2390 if (
function ==
nil)
2392 NSString *predicateCode =
nil;
2393 const char *argNames[] = {
"ship" };
2396 predicateCode = [
NSString stringWithFormat:@"return %@;", predicateExpression];
2397 function = [[
OOJSFunction alloc] initWithName:@"_oo_AIScanPredicate"
2401 argumentNames:argNames
2408 if (
function !=
nil)
2415 if (
function !=
nil)
2420 .function = [
function functionValue],
2428 static NSMutableSet *errorCache =
nil;
2430 if (![errorCache containsObject:key])
2432 OOLog(
@"ai.scanForNearestShipMatchingPredicate.compile.failed",
@"Could not compile JavaScript predicate \"%@\
" for AI %@.", predicateExpression, [[
self getAI] name]);
2442 JS_ReportPendingException(context);
2349- (void) scanForNearestShipMatchingPredicate:(NSString *)predicateExpression {
…}
2447- (void) setCoordinates:(NSString *)system_x_y_z
2450 NSString* systemString =
nil;
2451 NSString* xString =
nil;
2452 NSString* yString =
nil;
2453 NSString* zString =
nil;
2455 if ([tokens
count] != 4)
2457 OOLog(
@"ai.syntax.setCoordinates",
@"***** ERROR: cannot setCoordinates: '%@'.",system_x_y_z);
2461 systemString = (NSString *)[tokens objectAtIndex:0];
2462 xString = (NSString *)[tokens objectAtIndex:1];
2463 if ([xString hasPrefix:
@"rand:"])
2464 xString = [
NSString stringWithFormat:@"%.3f", bellf([(
NSString*)[[
xString componentsSeparatedByString:@":"] objectAtIndex:1] intValue])];
2465 yString = (NSString *)[tokens objectAtIndex:2];
2466 if ([yString hasPrefix:
@"rand:"])
2467 yString = [
NSString stringWithFormat:@"%.3f", bellf([(
NSString*)[[
yString componentsSeparatedByString:@":"] objectAtIndex:1] intValue])];
2468 zString = (NSString *)[tokens objectAtIndex:3];
2469 if ([zString hasPrefix:
@"rand:"])
2470 zString = [
NSString stringWithFormat:@"%.3f", bellf([(
NSString*)[[
zString componentsSeparatedByString:@":"] objectAtIndex:1] intValue])];
2472 HPVector posn = make_HPvector([xString floatValue], [yString floatValue], [zString floatValue]);
2473 GLfloat scalar = 1.0;
2475 coordinates = [UNIVERSE coordinatesForPosition:posn withCoordinateSystem:systemString returningScalar:&scalar];
2477 [
shipAI message:@"APPROACH_COORDINATES"];
2447- (void) setCoordinates:(NSString *)system_x_y_z {
…}
2484 [
shipAI message:@"NORMAL_SPACE"];
2486 [
shipAI message:@"INTERSTELLAR_SPACE"];
2493 int ent_count =
UNIVERSE->n_entities;
2497 double maxRange2 = desired_range * desired_range;
2499 int station_count = 0;
2501 for (i = 0; i < ent_count; i++)
2504 if (uni_entities[i]->isStation)
2507 if ([my_station maxFlightSpeed] == 0 && [my_station hasNPCTraffic] && HPdistance2(position, [my_station position]) < maxRange2)
2514 if (station_count != 0)
2519 if (station == [
UNIVERSE station] && station_count > 1)
2521 while (station == [
UNIVERSE station])
2528 for (i = 0; i < station_count; i++)
2529 [my_entities[i] release];
2535 [
shipAI message:@"STATION_FOUND"];
2539 [
shipAI message:@"NO_STATION_IN_RANGE"];
2547 if (station !=
nil && [station isStation])
2553 [
shipAI message:@"NO_STATION_FOUND"];
2560- (void) addFuel:(NSString*) fuel_number
2560- (void) addFuel:(NSString*) fuel_number {
…}
2567- (void) scriptActionOnTarget:(NSString *)action
2574 static BOOL deprecationWarning = NO;
2576 if (!deprecationWarning)
2578 deprecationWarning = YES;
2579 OOLog(
@"script.deprecated.scriptActionOnTarget",
@"----- WARNING in AI %@: the AI method scriptActionOnTarget: is deprecated and should not be used. It is slow and has unpredictable side effects. The recommended alternative is to use sendScriptMessage: to call a function in a ship's JavaScript ship script instead. scriptActionOnTarget: should not be used at all from scripts. An alternative is safeScriptActionOnTarget:, which is similar to scriptActionOnTarget: but has less side effects.", [
AI currentlyRunningAIDescription]);
2583 OOLog(
@"script.deprecated.scriptActionOnTarget.repeat",
@"----- WARNING in AI %@: the AI method scriptActionOnTarget: is deprecated and should not be used.", [
AI currentlyRunningAIDescription]);
2587 if ([targEnt isShip])
2567- (void) scriptActionOnTarget:(NSString *)action {
…}
2601- (void) safeScriptActionOnTarget:(NSString *)action
2607 if ([targEnt isShip])
2601- (void) safeScriptActionOnTarget:(NSString *)action {
…}
2621- (void) sendScriptMessage:(NSString *)message
2625 if ([components
count] == 1)
2631 NSString *
function = [
components objectAtIndex:0];
2621- (void) sendScriptMessage:(NSString *)message {
…}
2650- (void) ai_debugMessage:(NSString *)message
2653 if ([
self isPlayer]) desc =
@"player autopilot";
2654 OOLog(
@"ai.takeAction.debugMessage",
@"DEBUG: AI MESSAGE from %@: %@", desc, message);
2650- (void) ai_debugMessage:(NSString *)message {
…}
2660- (void) targetFirstBeaconWithCode:(NSString*) code
2662 NSArray *all_beacons = [UNIVERSE listBeaconsWithCode: code];
2663 if ([all_beacons
count])
2666 [
shipAI message:@"TARGET_FOUND"];
2669 [
shipAI message:@"NOTHING_FOUND"];
2660- (void) targetFirstBeaconWithCode:(NSString*) code {
…}
2673- (void) targetNextBeaconWithCode:(NSString*) code
2675 NSArray *all_beacons = [UNIVERSE listBeaconsWithCode: code];
2678 if ((!current_beacon)||(![current_beacon isBeacon]))
2680 [
shipAI message:@"NO_CURRENT_BEACON"];
2681 [
shipAI message:@"NOTHING_FOUND"];
2686 NSUInteger i = [
all_beacons indexOfObject:current_beacon];
2688 if (i == NSNotFound)
2690 [
shipAI message:@"NOTHING_FOUND"];
2696 if (i < [all_beacons
count])
2700 [
shipAI message:@"TARGET_FOUND"];
2704 [
shipAI message:@"LAST_BEACON"];
2705 [
shipAI message:@"NOTHING_FOUND"];
2673- (void) targetNextBeaconWithCode:(NSString*) code {
…}
2716 [
shipAI message:@"NOTHING_FOUND"];
2722 navpoints[0] = make_HPvector(o.x - c * k.x, o.y - c * k.y, o.z - c * k.z);
2723 navpoints[1] = make_HPvector(o.x + c * k.x, o.y + c * k.y, o.z + c * k.z);
2724 navpoints[2] = make_HPvector(o.x + 2.0 * c * k.x, o.y + 2.0 * c * k.y, o.z + 2.0 * c * k.z);
2725 number_of_navpoints = 2;
2726 next_navpoint_index = 0;
2727 _destination = navpoints[0];
2728 [
shipAI message:@"RACEPOINTS_SET"];
2734 next_navpoint_index = 0;
2735 desired_range = collision_radius;
2736 behaviour = BEHAVIOUR_FLY_THRU_NAVPOINTS;
2742@implementation ShipEntity (OOAIPrivate)
2747 if ([
self foundTarget] !=
nil)
2749 [
shipAI message:@"TARGET_FOUND"];
2753 [
shipAI message:@"NOTHING_FOUND"];
2758- (BOOL) performHyperSpaceExitReplace:(BOOL)replace
2758- (BOOL) performHyperSpaceExitReplace:(BOOL)replace {
…}
2764- (BOOL) performHyperSpaceExitReplace:(BOOL)replace toSystem:(
OOSystemID)systemID
2766 if(![
self hasHyperspaceMotor])
2768 [
shipAI reactToMessage:@"WITCHSPACE UNAVAILABLE" context:@"performHyperSpaceExit"];
2771 if([
self status] == STATUS_ENTERING_WITCHSPACE)
2777 NSArray *sDests =
nil;
2782 sDests = [UNIVERSE nearbyDestinationsWithinRange: 0.1f * fuel];
2783 NSUInteger n_dests = [
sDests count];
2788 [
shipAI reactToMessage:@"WITCHSPACE UNAVAILABLE" context:@"performHyperSpaceExit"];
2800 [
shipAI reactToMessage:@"WITCHSPACE BLOCKED" context:@"performHyperSpaceExit"];
2815 targetSystem = [[
sDests oo_dictionaryAtIndex:i] oo_intForKey:@"sysID"];
2819 targetSystem = systemID;
2821 for (i = 0; i < n_dests; i++)
2823 if (systemID == [[sDests oo_dictionaryAtIndex:i] oo_intForKey:
@"sysID"])
break;
2831 float dist = [[
sDests oo_dictionaryAtIndex:i] oo_floatForKey:@"distance"];
2832 if (dist > [
self maxHyperspaceDistance] || dist > fuel/10.0f)
2834 OOLogWARN(
@"script.debug",
@"DEBUG: %@ Jumping %f which is further than allowed. I have %d fuel",
self, dist, fuel);
2840 [UNIVERSE addEntity: whole];
2764- (BOOL) performHyperSpaceExitReplace:(BOOL)replace toSystem:(
OOSystemID)systemID {
…}
2854 float d2, found_d2 = scannerRange * scannerRange;
2859 if (predicate == NULL)
return;
2861 for (i = 0; i < n_scanned_ships ; i++)
2863 candidate = scanned_ships[
i];
2864 d2 = distance2_scanned_ships[
i];
2865 if ((d2 < found_d2) && (candidate->
scanClass != CLASS_CARGO) && ([candidate status] != STATUS_DOCKED)
2866 && predicate(candidate, parameter) && ![candidate isCloaked])
2887 if ([
self isPolice])
2892 NSString *context =
nil;
2894 context = [
NSString stringWithFormat:@"%@ broadcastDistressMessage", [
other shortDescription]];
2896 [
shipAI reactToMessage:@"ACCEPT_DISTRESS_CALL" context:context];
2906@implementation StationEntity (OOAIPrivate)
2910 if (
self != [
UNIVERSE station])
return;
2916 _primaryTarget = old_target;
2923@implementation ShipEntity (OOAIStationStubs)
2927#define STATION_STUB_BASE(PROTO, NAME) PROTO { OOLog(@"ai.invalid.notAStation", @"Attempt to use station AI method \"%s\" on non-station %@.", NAME, self); }
2928#define STATION_STUB_NOARG(NAME) STATION_STUB_BASE(- (void) NAME, #NAME)
2929#define STATION_STUB_ARG(NAME) STATION_STUB_BASE(- (void) NAME (NSString *)param, #NAME)
2943 OOLog(
@"ai.invalid.notAStation",
@"Attempt to use station AI method \"%s\
" on non-station %@.",
"launchPatrol",
self);
#define SCANNER_MAX_RANGE2
BOOL HasScanClassPredicate(Entity *entity, void *parameter)
BOOL IsHostileAgainstTargetPredicate(Entity *ship, void *parameter)
const HPVector kZeroHPVector
HPVector OOHPVectorRandomSpatial(OOHPScalar maxLength)
JSObject * OOJSObjectFromNativeObject(JSContext *context, id object)
OOINLINE JSContext * OOJSAcquireContext(void)
OOINLINE void OOJSRelinquishContext(JSContext *context)
#define OOLogWARN(class, format,...)
#define OOLogERR(class, format,...)
#define NSLog(format,...)
#define OOLog(class, format,...)
Vector vector_forward_from_quaternion(Quaternion quat)
void quaternion_set_random(Quaternion *quat)
#define OOExpand(string,...)
NSMutableArray * ScanTokensFromString(NSString *values)
@ AEGIS_CLOSE_TO_MAIN_PLANET
@ AEGIS_CLOSE_TO_ANY_PLANET
Vector OOVectorRandomSpatial(OOScalar maxLength)
#define STATION_STUB_NOARG(NAME)
#define STATION_STUB_ARG(NAME)
#define COMBAT_AI_ISNT_AWFUL
#define PIRATES_PREFER_PLAYER
BOOL(* EntityFilterPredicate)(Entity *entity, void *parameter)
void broadcastDistressMessage()
void performFlyToRangeFromDestination()
void scanForNearestIncomingMissile()
void enterPlayerWormhole()
void performFaceDestination()
void enterTargetWormhole()
void performScriptedAttackAI()
void performLandOnPlanet()
void recallDockingInstructions()
void requestDockingCoordinates()
void wormholeEntireGroup()
void setSpeedToCruiseSpeed()
void setCourseToWitchpoint()
void checkHeatInsulation()
void setDesiredRangeForWaypoint()
void fightOrFleeMissile()
void performHyperSpaceExitWithoutReplacing()
void addFoundTargetAsDefenseTarget()
void checkForMotherStation()
void setDestinationToStationBeacon()
void setTargetToFoundTarget()
void scanForFormationLeader()
void markTargetForFines()
void setTargetToRandomStation()
void scanForRandomMerchantman()
void becomeUncontrolledThargon()
void checkOwnLegalStatus()
void setDestinationToTarget()
void setPlanetPatrolCoordinates()
void setSunSkimExitCoordinates()
void performFlyRacepoints()
void checkTargetLegalStatus()
void scanForNearestMerchantman()
void debugDumpPendingMessages()
void setCoordinatesFromPosition()
void setTargetToPrimaryAggressor()
void checkCourseToDestination()
void thargonCheckMother()
void setDestinationToJinkPosition()
void performHyperSpaceExit()
void recallStoredTarget()
void scanForNonThargoid()
void checkGroupOddsVersusTarget()
void setDestinationToCurrentLocation()
void setDestinationToDockingAbort()
void addPrimaryAggressorAsDefenseTarget()
void setSunSkimEndCoordinates()
void setDestinationToWitchpoint()
void checkForNormalSpace()
void checkDistanceTravelled()
void setDestinationWithinTarget()
void findNewDefenseTarget()
void fightOrFleeHostiles()
void setRacepointsFromTarget()
void setDestinationFromCoordinates()
void setTakeOffFromPlanet()
void setSunSkimStartCoordinates()
void getWitchspaceEntryCoordinates()
void setTargetToLastStation()
void disengageAutopilot()
void setStateMachine:withJSScript:(NSString *smName,[withJSScript] NSString *script)
void message:(NSString *ms)
void setState:(NSString *stateName)
OOUniversalID universalID
void setThrowSparks:(BOOL value)
id jsAIScriptFromFileNamed:properties:(NSString *fileName,[properties] NSDictionary *properties)
void runUnsanitizedScriptActions:allowingAIMethods:withContextName:forTarget:(NSArray *unsanitizedActions,[allowingAIMethods] BOOL allowAIMethods,[withContextName] NSString *contextName,[forTarget] ShipEntity *target)
void setScriptTarget:(ShipEntity *ship)
ShipEntity * scriptTarget()
NSString * pathForFileNamed:inFolder:(NSString *fileName,[inFolder] NSString *folderName)
void getDestroyedBy:damageType:(Entity *whom,[damageType] OOShipDamageType type)
void landOnPlanet:(OOPlanetEntity *planet)
void setTargetStation:(Entity *targetEntity)
void addTarget:(Entity *targetEntity)
void setPrimaryAggressor:(Entity *targetEntity)
void scanForNearestShipWithPredicate:parameter:(EntityFilterPredicate predicate,[parameter] void *parameter)
void setFuel:(OOFuelQuantity amount)
void removeTarget:(Entity *targetEntity)
BOOL addDefenseTarget:(Entity *target)
void setAIScript:(NSString *aiString)
void setEvasiveJink:(GLfloat z)
OOShipGroup * escortGroup()
void setSpeed:(double amount)
void scanForNearestShipWithPrimaryRole:(NSString *scanRole)
BOOL suggestEscortTo:(ShipEntity *mother)
int checkShipsInVicinityForWitchJumpExit()
void setGroup:(OOShipGroup *group)
void doScriptEvent:(jsid message)
Entity * primaryAggressor()
void setPrimaryRole:(NSString *role)
void broadcastDistressMessageWithDumping:(BOOL dumpCargo)
BOOL performHyperSpaceExitReplace:(BOOL replace)
void checkScannerIgnoringUnpowered()
StationEntity * targetStation()
ShipEntity * fireMissile()
void removeDefenseTarget:(Entity *target)
OOPlanetEntity * findNearestPlanet()
OOCommodityType dumpCargo()
void setAITo:(NSString *aiString)
void commsMessage:withUnpilotedOverride:(NSString *valueString,[withUnpilotedOverride] BOOL unpilotedOverride)
void scanForNearestShipHavingRole:(NSString *scanRole)
BOOL performHyperSpaceExitReplace:toSystem:(BOOL replace,[toSystem] OOSystemID systemID)
Entity< OOStellarBody > * findNearestStellarBody()
void sendExpandedMessage:toShip:(NSString *message_text,[toShip] ShipEntity *other_ship)
void scanForNearestShipWithNegatedPredicate:parameter:(EntityFilterPredicate predicate,[parameter] void *parameter)
void noteLostTargetAndGoIdle()
OOCargoQuantity maxAvailableCargoSpace()
void markAsOffender:withReason:(int offence_value,[withReason] OOLegalStatusReason reason)
void doScriptEvent:withArgument:(jsid message,[withArgument] id argument)
void setRememberedShip:(Entity *targetEntity)
void reactToAIMessage:context:(NSString *message,[context] NSString *debugContext)
void setFoundTarget:(Entity *targetEntity)
OOPlanetEntity * findNearestPlanetExcludingMoons()
void sendAIMessage:(NSString *message)
void acceptDistressMessageFrom:(ShipEntity *other)
void enterWormhole:replacing:(WormholeEntity *w_hole,[replacing] BOOL replacing)
void setOwner:(Entity *who_owns_entity)
Entity * lastEscortTarget()
void recallDockingInstructions()
void doScriptEvent:withArgument:andArgument:(jsid message,[withArgument] id argument1,[andArgument] id argument2)
void acceptPatrolReportFrom:(ShipEntity *patrol_ship)
ShipEntity * launchDefenseShip()
NSDictionary * dockingInstructionsForShip:(ShipEntity *ship)