Some AI changes and related tidying:

1) Make pirates with full holds (and other offenders using route1traderAI) less likely to go to main station, especially not fugitives. (Expansion of changes from r4770)
2) Experimentally ensure always at least one rock hermit in all non-nova systems. If normal generation does not place a hermit, one is added well away from all spacelanes.
3) New "ATTACKER_MISSED" AI event for when a ship tried to shoot a laser at its target but narrowly missed. Many stock AIs modified to treat this as a hostile action.
4) Tidy function/property names in docking code
5) Add checks for cloaking in some AI routines
6) Use weak refs rather than universal ID for targeting, and clean up


git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@5144 127b21dd-08f5-0310-b4b7-95ae10353056
master
Chris Morris 2012-07-29 20:21:11 +00:00
parent 267276263e
commit ae84915d19
31 changed files with 654 additions and 370 deletions

View File

@ -6,6 +6,7 @@
LOOT =
{
ENTER = (performCollect);
"ATTACKER_MISSED" = ("exitAIWithMessage: ATTACKED");
ATTACKED = ("exitAIWithMessage: ATTACKED");
"COLLISION" = (exitAI);
"FRUSTRATED" = ("setSpeedTo: 0.0", performIdle, exitAI);

View File

@ -79,6 +79,7 @@
"RESTART_DOCKING" = ("setStateTo: GLOBAL");
"REACHED_SAFETY" = (performIdle, "setStateTo: GLOBAL");
"DESIRED_RANGE_ACHIEVED" = (performIdle, "setStateTo: GLOBAL");
"ATTACKER_MISSED" = ("setStateTo: ATTACK_SHIP");
ATTACKED = ("setStateTo: ATTACK_SHIP");
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", "setStateTo: ATTACK_SHIP");
"GROUP_ATTACK_TARGET" = ("setStateTo: ATTACK_SHIP");

View File

@ -12,6 +12,7 @@
"INCOMING_MISSILE" = ("messageMother: INCOMING_MISSILE");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"ATTACKED" = ("messageMother: ATTACKED", "messageMother: ESCORT_ATTACKED");
"ATTACKER_MISSED" = ("messageMother: ATTACKER_MISSED", "messageMother: ESCORT_ATTACKED");
"ATTACKED_BY_CLOAKED" = ("messageMother: ATTACKED_BY_CLOAKED");
"NOT_ESCORTING" = ("setStateTo: LOOK_FOR_BUSINESS");
"TARGET_LOST" = ("setStateTo: LOOK_FOR_BUSINESS");
@ -77,7 +78,8 @@
ENTER = (scanForFormationLeader);
RESTARTED = ("setStateTo: BEGIN_BUSINESS");
"LAUNCHED OKAY" = ("setStateTo: CLEAR_STATION");
ATTACKED = (setTargetToPrimaryAggressor, );
ATTACKED = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
ATTACKER_MISSED = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
ESCORTING = ("setDesiredRangeTo: 0.0", "setStateTo: FLYING_ESCORT");
"NOT_ESCORTING" = ("rollD: 10");

View File

@ -10,6 +10,7 @@
"DESIRED_RANGE_ACHIEVED" = ("setSpeedFactorTo: 0.7", "setStateTo: APPROACH");
"AEGIS_LEAVING_DOCKING_RANGE" = ("setStateTo: APPROACH");
"LAUNCHED OKAY" = ("setStateTo: CLEAR_STATION");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, broadcastDistressMessage);
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage);
"INCOMING_MISSILE" = (fireECM);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
@ -21,6 +22,7 @@
"WAYPOINT_SET" = ("setDesiredRangeTo: 50.0", checkCourseToDestination);
"APPROACHING_SURFACE" = ("setStateTo: LANDING");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: FLY_HOME");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, broadcastDistressMessage);
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"AEGIS_LEAVING_DOCKING_RANGE" = ("setStateTo: APPROACH");
@ -37,6 +39,7 @@
ENTER = (setCourseToPlanet, performFlyToRangeFromDestination);
"APPROACHING_SURFACE" = ("setStateTo: LANDING");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: LANDING");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, broadcastDistressMessage);
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage);
"INCOMING_MISSILE" = (fireECM, "setSpeedFactorTo: 1.0");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");

View File

@ -8,6 +8,7 @@
ENTER = ("setSpeedFactorTo: 0.75");
"WAYPOINT_SET" = ("setStateTo: NEW_WAYPOINT");
"DESIRED_RANGE_ACHIEVED" = ("setDesiredRangeTo: 1000.0", exitAI);
"ATTACKER_MISSED" = ("exitAIWithMessage: ATTACKED");
ATTACKED = ("exitAIWithMessage: ATTACKED");
"ATTACKED_BY_CLOAKED" = ("exitAIWithMessage: ATTACKED_BY_CLOAKED");
"CASCADE_WEAPON_DETECTED" = ("exitAIWithMessage: CASCADE_WEAPON_DETECTED");
@ -28,6 +29,7 @@
"FRUSTRATED" = ("setSpeedFactorTo: 0.1", "setDesiredRangeTo: 1000.0", exitAI);
"LAUNCHED OKAY" = ("exitAIWithMessage: LAUNCHED OKAY");
ATTACKED = ("exitAIWithMessage: ATTACKED");
"ATTACKER_MISSED" = ("exitAIWithMessage: ATTACKED");
"ATTACKED_BY_CLOAKED" = ("exitAIWithMessage: ATTACKED_BY_CLOAKED");
"CASCADE_WEAPON_DETECTED" = ("exitAIWithMessage: CASCADE_WEAPON_DETECTED");
"DESIRED_RANGE_ACHIEVED" = ("setDesiredRangeTo: 1000.0", exitAI);

View File

@ -30,6 +30,7 @@
"TRAVEL_TO_LURK_AREA" =
{
ENTER = (setDestinationToCurrentLocation, "setDesiredRangeTo: 1500.0", performFlyToRangeFromDestination);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: LURK");
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setStateTo: ATTACK_SHIP");
@ -41,6 +42,7 @@
LURK =
{
ENTER = ("setSpeedTo: 0.0", performIdle);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");

View File

@ -6,6 +6,7 @@
"setDesiredRangeTo: 1500.0",
performFlyToRangeFromDestination
);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: LURK");
@ -74,6 +75,7 @@
ENTER = ("setSpeedTo: 0.0", performIdle, "pauseAI: 5.0");
"ENERGY_FULL" = ("setStateTo: COLLECT_LOOT");
"ENERGY_HIGH" = ("setStateTo: COLLECT_LOOT");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
@ -82,6 +84,7 @@
};
"COLLECT_LOOT" = {
ENTER = ("setSpeedTo: 0.0", performIdle);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"HOLD_FULL" = ("setStateTo: CONSIDER_DOCKING");
@ -95,6 +98,7 @@
};
LOOT = {
ENTER = (performCollect);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"CARGO_SCOOPED" = ("setStateTo: CHECK_CARGO");
@ -110,6 +114,7 @@
};
"CHECK_CARGO" = {
ENTER = ("setSpeedTo: 0.0", performIdle, checkForFullHold);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"HOLD_FULL" = ("setStateTo: CONSIDER_LEAVING");
@ -122,6 +127,7 @@
RESTARTED = ("setStateTo: RECOVER");
};
"CONSIDER_LEAVING" = {
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"NOTHING_FOUND" = ("setStateTo: EXIT_SYSTEM", "pauseAI: 5.0");
@ -145,6 +151,7 @@
"CONSIDER_DOCKING" = {
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"NOTHING_FOUND" = ("setStateTo: TRAVEL_TO_LURK_AREA");
"STATION_FOUND" = (dockEscorts, "setAITo: dockingAI.plist");
"CARGO_SCOOPED" = ("setStateTo: CHECK_CARGO");
@ -155,6 +162,7 @@
};
"DOCK_WITH_STATION" = {
ENTER = (checkForMotherStation);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
ATTACKED = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"NOTHING_FOUND" = ("setAITo: route1traderAI.plist");
@ -183,6 +191,7 @@
"COURSE_OK" = ("setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
"WAYPOINT_SET" = ("setAITo: gotoWaypointAI.plist");
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: LURK");
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setStateTo: ATTACK_SHIP");
@ -199,6 +208,7 @@
LURK = {
ENTER = ("setSpeedTo: 0.0", performIdle);
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setStateTo: ATTACK_SHIP");
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"TARGET_LOST" = ("setStateTo: TRAVEL_TO_LURK_AREA", "pauseAI: 0.5");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
@ -215,6 +225,7 @@
"SCAN_FOR_LOOT" = {
ENTER = ("setSpeedTo: 0.0", performIdle);
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKED_BY_CLOAKED" = ("setStateTo: FLEE_FOR_CLOAKED");
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setStateTo: ATTACK_SHIP");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");

View File

@ -27,6 +27,7 @@
"TARGET_OFFENDER" = ("sendTargetCommsMessage: [police-attack-warning]", "setAITo: interceptAI.plist", groupAttackTarget);
"TARGET_FUGITIVE" = ("setAITo: interceptAI.plist", groupAttackTarget);
ATTACKED = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, "setAITo: interceptAI.plist");
"ATTACKED_BY_CLOAKED" = ("setAITo: interceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
"INCOMING_MISSILE" = (setTargetToFoundTarget, "markTargetForOffence: 15",
"setAITo: delayedReactToAttackAI.plist");

View File

@ -22,6 +22,7 @@
"COURSE_OK" = ("setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
"DESIRED_RANGE_ACHIEVED" = (setTargetToNearestStation, "setAITo: dockingAI.plist");
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
UPDATE = (setTargetToNearestStation, "setDesiredRangeTo: 5000.0",
@ -37,6 +38,7 @@
"WAYPOINT_SET" = ("setAITo: gotoWaypointAI.plist");
"COURSE_OK" = ("setSpeedFactorTo: 1.0", performFlyToRangeFromDestination);
"DESIRED_RANGE_ACHIEVED" = (setTargetToSystemStation, "setAITo: dockingAI.plist");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
ATTACKED = (setTargetToPrimaryAggressor, broadcastDistressMessage, "setStateTo: FLEE");
"INCOMING_MISSILE" = (fightOrFleeMissile, "setStateTo: FLEE");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");

View File

@ -17,6 +17,7 @@
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKED_BY_CLOAKED" = ("setAITo: interceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setStateTo: INBOUND_LOOT", "setAITo: interceptAI.plist");
RESTARTED = (checkAegis);
@ -35,6 +36,7 @@
"TARGET_FOUND" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKED_BY_CLOAKED" = ("setAITo: interceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setStateTo: OUTBOUND_LOOT", "setAITo: interceptAI.plist");
@ -48,6 +50,7 @@
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"TARGET_FOUND" = (setTargetToFoundTarget, "setAITo: collectLootAI.plist");
@ -63,6 +66,7 @@
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"TARGET_FOUND" = (setTargetToFoundTarget, "setAITo: collectLootAI.plist");

View File

@ -4,12 +4,16 @@
ENTER = ("setStateTo: CHECK_STATUS");
};
"CHECK_STATUS" = {
ENTER = (checkOwnLegalStatus, "setDesiredRangeTo: 500000.0");
ENTER = (checkOwnLegalStatus, "setDesiredRangeTo: 1000000.0");
"SELF_CLEAN" = ("setStateTo: HEAD_FOR_PLANET");
"SELF_MINOR_OFFENDER" = (setTargetToRandomStation);
"SELF_OFFENDER" = (setTargetToRandomStation);
"SELF_MINOR_OFFENDER" = ("rollD: 2"); // head for main station 50%
"SELF_OFFENDER" = ("rollD: 4"); // head for main station 25%
"SELF_FUGITIVE" = (setTargetToRandomStation);
"SELF_THARGOID" = ("switchAITo: thargoidAI.plist");
"ROLL_1" = ("setStateTo: HEAD_FOR_PLANET");
"ROLL_2" = (setTargetToRandomStation);
"ROLL_3" = (setTargetToRandomStation);
"ROLL_4" = (setTargetToRandomStation);
"NO_STATION_IN_RANGE" = ("setStateTo: HEAD_FOR_PLANET");
"STATION_FOUND" = ("setStateTo: GO_TO_RANDOM_STATION");
};
@ -25,6 +29,7 @@
"TARGET_FOUND" = (setTargetToFoundTarget, "setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"INCOMING_MISSILE" = ("setAITo: traderInterceptAI.plist", "setStateTo: INCOMING_MISSILE", "randomPauseAI: 0.5 2.0");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"ATTACKER_MISSED" = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
ATTACKED = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"ATTACKED_BY_CLOAKED" = ("setAITo: traderInterceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
RESTARTED = (checkAegis);
@ -49,6 +54,7 @@
"TARGET_FOUND" = (setTargetToFoundTarget, "setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"INCOMING_MISSILE" = ("setAITo: traderInterceptAI.plist", "setStateTo: INCOMING_MISSILE", "randomPauseAI: 0.25 1.5");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"ATTACKER_MISSED" = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
ATTACKED = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"ATTACKED_BY_CLOAKED" = ("setAITo: traderInterceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
UPDATE =
@ -73,6 +79,7 @@
"TARGET_FOUND" = (setTargetToFoundTarget, "setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"INCOMING_MISSILE" = ("setAITo: traderInterceptAI.plist", "setStateTo: INCOMING_MISSILE", "randomPauseAI: 0.25 1.5");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"ATTACKER_MISSED" = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
ATTACKED = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"ATTACKED_BY_CLOAKED" = ("setAITo: traderInterceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
UPDATE =
@ -96,6 +103,7 @@
"TARGET_FOUND" = (setTargetToFoundTarget, "setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"INCOMING_MISSILE" = ("setAITo: traderInterceptAI.plist", "setStateTo: INCOMING_MISSILE", "randomPauseAI: 0.25 1.5");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"ATTACKER_MISSED" = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
ATTACKED = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"ATTACKED_BY_CLOAKED" = ("setAITo: traderInterceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
UPDATE =

View File

@ -12,6 +12,7 @@
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: HEAD_FOR_SUN");
"AEGIS_CLOSE_TO_MAIN_PLANET" = ("setStateTo: HEAD_FOR_SUN");
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKED_BY_CLOAKED" = ("setAITo: interceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
@ -30,6 +31,7 @@
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: HEAD_FOR_PLANET");
"AEGIS_CLOSE_TO_MAIN_PLANET" = ("setStateTo: HEAD_FOR_SUN");
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
@ -47,6 +49,7 @@
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: HEAD_FOR_PLANET");
"CLOSE_TO_SUN" = ("setStateTo: HEAD_FOR_PLANET");
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKED_BY_CLOAKED" = ("setAITo: interceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
@ -68,6 +71,7 @@
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");
};
@ -76,6 +80,7 @@
ENTER = ("setSpeedTo: 0.0", performIdle);
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);
@ -89,6 +94,7 @@
ENTER = ("setSpeedTo: 0.0", performIdle);
"GROUP_ATTACK_TARGET" = (setTargetToFoundTarget, "setAITo: interceptAI.plist");
ATTACKED = (setTargetToPrimaryAggressor, groupAttackTarget);
"ATTACKER_MISSED" = (setTargetToPrimaryAggressor, groupAttackTarget);
"ACCEPT_DISTRESS_CALL" = (setTargetToFoundTarget, deployEscorts, groupAttackTarget);
"OFFENCE_COMMITTED" = (setTargetToFoundTarget, "markTargetForOffence: 7", deployEscorts, groupAttackTarget);
"INCOMING_MISSILE" = (fightOrFleeMissile, setTargetToPrimaryAggressor, deployEscorts, groupAttackTarget);

View File

@ -18,6 +18,7 @@
"WAYPOINT_SET" = ("setAITo: gotoWaypointAI.plist");
"DESIRED_RANGE_ACHIEVED" = ("setStateTo: GO_TO_SKIM");
ATTACKED = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"ATTACKER_MISSED" = ("setAITo: traderInterceptAI.plist", fightOrFleeHostiles);
"ATTACKED_BY_CLOAKED" = ("setAITo: traderInterceptAI.plist", "setStateTo: FLEE_FOR_CLOAKED");
"INCOMING_MISSILE" = ("setAITo: traderInterceptAI.plist", "setStateTo: INCOMING_MISSILE", "randomPauseAI: 0.5 2.0");
"CASCADE_WEAPON_DETECTED" = ("setAITo: fleeQMineAI.plist");

View File

@ -399,14 +399,13 @@ static AIStackElement *sStack = NULL;
static unsigned recursionLimiter = 0;
AI *previousRunning = sCurrentlyRunningAI;
/* CRASH in _freedHandler when called via -setState: __NSFireDelayedPerform (1.69, OS X/x86).
Analysis: owner invalid.
Fix: make owner an OOWeakReference.
-- Ahruman, 20070706
*/
if (message == nil || owner == nil || [owner universalID] == NO_TARGET) return;
#ifndef NDEBUG
// Push debug stack frame.
if (debugContext == nil) debugContext = @"unspecified";

View File

@ -344,7 +344,7 @@ static NSArray *subregionsContainingPosition(Vector position, CollisionRegion *r
}
if (e1->isShip)
{
[(ShipEntity*)e1 setProximity_alert:nil];
[(ShipEntity*)e1 setProximityAlert:nil];
}
e1->collider = nil;
}
@ -386,8 +386,8 @@ static NSArray *subregionsContainingPosition(Vector position, CollisionRegion *r
{
if ((dist2 < PROXIMITY_WARN_DISTANCE2 * r2 * r2) || (dist2 < PROXIMITY_WARN_DISTANCE2 * r1 * r1))
{
[(ShipEntity*)e1 setProximity_alert:(ShipEntity*)e2];
[(ShipEntity*)e2 setProximity_alert:(ShipEntity*)e1];
[(ShipEntity*)e1 setProximityAlert:(ShipEntity*)e2];
[(ShipEntity*)e2 setProximityAlert:(ShipEntity*)e1];
}
}
if (dist2 < min_dist2)

View File

@ -44,7 +44,7 @@ MA 02110-1301, USA.
BOOL no_docking_while_launching;
BOOL allow_launching;
BOOL allow_docking;
BOOL allow_player_docking;
BOOL disallowed_docking_collides;
BOOL virtual_dock;
}
@ -53,7 +53,8 @@ MA 02110-1301, USA.
// Docking
- (BOOL) allowsDocking;
- (void) setAllowsDocking:(BOOL)allow;
- (BOOL) allowsPlayerDocking;
- (BOOL) disallowedDockingCollides;
- (void) setDisallowedDockingCollides:(BOOL)ddc;
- (unsigned) countOfShipsInDockingQueue;
- (NSDictionary *) dockingInstructionsForShip:(ShipEntity *)ship;
- (NSString *) canAcceptShipForDocking:(ShipEntity *)ship;
@ -77,7 +78,7 @@ MA 02110-1301, USA.
- (void) addShipToLaunchQueue:(ShipEntity *)ship withPriority:(BOOL)priority;
// Geometry
- (void) setDimensionsAndCorridor:(BOOL)docking :(BOOL)playerdocking :(BOOL)launching;
- (void) setDimensionsAndCorridor:(BOOL)docking :(BOOL)ddc :(BOOL)launching;
- (Vector) portUpVectorForShipsBoundingBox:(BoundingBox)bb;
- (BOOL) isOffCentre;
- (void) setVirtual;

View File

@ -190,9 +190,9 @@ MA 02110-1301, USA.
}
- (BOOL) allowsPlayerDocking
- (BOOL) disallowedDockingCollides
{
return allow_player_docking;
return disallowed_docking_collides;
}
@ -212,6 +212,12 @@ MA 02110-1301, USA.
}
- (void) setDisallowedDockingCollides:(BOOL)ddc
{
disallowed_docking_collides = ddc;
}
- (void) setVirtual
{
virtual_dock = YES;
@ -636,14 +642,10 @@ MA 02110-1301, USA.
if (![ship isShip]) return NO;
if ([ship isPlayer] && [ship status] == STATUS_DEAD) return NO;
BOOL allow_docking_thisship = allow_docking;
if (!allow_docking && allow_player_docking)
{
allow_docking_thisship = YES;
// ships can physically dock here, and this routine is mainly for
// collision detection, but will never be directed here by traffic
// control
}
BOOL allow_docking_thisship = allow_docking || !disallowed_docking_collides;
// ships can physically dock here, and this routine is mainly for
// collision detection, but will never be directed here by traffic
// control, if allow_docking is false but d_d_c is true
StationEntity *station = (StationEntity *)[self parentEntity];
@ -776,8 +778,8 @@ MA 02110-1301, USA.
- (void) pullInShipIfPermitted:(ShipEntity *)ship
{
// allow_docking: docking permitted and expected
// allow_player_docking: unauthorised docking does not result in explosion
if (allow_docking || allow_player_docking)
// disallowed_docking_collides: unauthorised docking does not result in explosion
if (allow_docking || !disallowed_docking_collides)
{
[ship enterDock:(StationEntity*)[self parentEntity]];
}
@ -1049,7 +1051,7 @@ MA 02110-1301, USA.
}
- (void)setDimensionsAndCorridor:(BOOL)docking :(BOOL)playerdocking :(BOOL)launching
- (void)setDimensionsAndCorridor:(BOOL)docking :(BOOL)ddc :(BOOL)launching
{
StationEntity *station = (StationEntity*)[self parentEntity];
if (virtual_dock)
@ -1075,7 +1077,7 @@ MA 02110-1301, USA.
port_corridor = start.z - position.z;
allow_docking = docking;
allow_player_docking = playerdocking;
disallowed_docking_collides = ddc;
allow_launching = launching;
}
@ -1099,7 +1101,7 @@ MA 02110-1301, USA.
shipsOnApproach = [[NSMutableDictionary alloc] init];
launchQueue = [[NSMutableArray alloc] init];
allow_docking = YES;
allow_player_docking = YES;
disallowed_docking_collides = NO;
allow_launching = YES;
virtual_dock = NO;
}

View File

@ -587,6 +587,7 @@ typedef enum
- (BOOL)setCommanderDataFromDictionary:(NSDictionary *) dict;
- (void) doBookkeeping:(double) delta_t;
- (BOOL) isValidTarget:(Entity*)target;
- (BOOL) massLocked;
- (BOOL) atHyperspeed;

View File

@ -123,7 +123,6 @@ static GLfloat sBaseMass = 0.0;
- (void) performDockingUpdates:(OOTimeDelta)delta_t;
- (void) performDeadUpdates:(OOTimeDelta)delta_t;
- (void) updateTargeting;
- (BOOL) isValidTarget:(Entity*)target;
- (void) showGameOver;
- (void) updateWormholes;
@ -1591,7 +1590,7 @@ static GLfloat sBaseMass = 0.0;
missile_entity[i] = [UNIVERSE newShipWithRole:@"EQ_MISSILE"]; // retain count = 1
}
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
[self safeAllMissiles];
[self setActiveMissile:0];
@ -2037,7 +2036,7 @@ static GLfloat sBaseMass = 0.0;
if ((status == STATUS_ESCAPE_SEQUENCE)&&(shot_time > ESCAPE_SEQUENCE_TIME))
{
UPDATE_STAGE(@"resetting after escape");
ShipEntity *doppelganger = [UNIVERSE entityForUniversalID:found_target];
ShipEntity *doppelganger = (ShipEntity*)[self foundTarget];
// reset legal status again! Could have changed if a previously launched missile hit a clean NPC while in the escape pod.
[self setBounty:0 withReason:kOOLegalStatusReasonEscapePod];
// legalStatus = 0;
@ -2062,7 +2061,7 @@ static GLfloat sBaseMass = 0.0;
[[UNIVERSE planet] update: 2.34375 * market_rnd]; // from 0..10 minutes
[[UNIVERSE station] update: 2.34375 * market_rnd]; // from 0..10 minutes
}
primaryTarget = _dockTarget; // main station in the original system, unless overridden.
[self addTarget:[UNIVERSE entityForUniversalID:_dockTarget]]; // main station in the original system, unless overridden.
[UNIVERSE setBlockJSPlayerShipProps:NO]; // re-enable player.ship!
if ([[self primaryTarget] isStation]) // also fails if primaryTarget is NO_TARGET
{
@ -2201,7 +2200,7 @@ static GLfloat sBaseMass = 0.0;
}
// scanner sanity check - lose any targets further than maximum scanner range
ShipEntity *primeTarget = [UNIVERSE entityForUniversalID:primaryTarget];
ShipEntity *primeTarget = [self primaryTarget];
if (primeTarget && distance2([primeTarget position], [self position]) > SCANNER_MAX_RANGE2 && !autopilot_engaged)
{
[UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
@ -2394,13 +2393,13 @@ static GLfloat sBaseMass = 0.0;
if (stationForDocking == nil) return NO;
if ([self isDocked]) return NO;
if (autopilot_engaged && targetStation == [stationForDocking universalID])
if (autopilot_engaged && [self targetStation] == stationForDocking)
{
return YES;
}
targetStation = [stationForDocking universalID];
primaryTarget = NO_TARGET;
[self setTargetStation:stationForDocking];
DESTROY(_primaryTarget);
autopilot_engaged = YES;
ident_engaged = NO;
[self safeAllMissiles];
@ -2431,8 +2430,8 @@ static GLfloat sBaseMass = 0.0;
behaviour = BEHAVIOUR_IDLE;
frustration = 0.0;
autopilot_engaged = NO;
primaryTarget = NO_TARGET;
targetStation = NO_TARGET;
DESTROY(_primaryTarget);
[self setTargetStation:nil];
[self setStatus:STATUS_IN_FLIGHT];
[self playAutopilotOff];
[self setDockingClearanceStatus:DOCKING_CLEARANCE_STATUS_NONE];
@ -2672,6 +2671,11 @@ static GLfloat sBaseMass = 0.0;
{
return NO;
}
OOEntityStatus tstatus = [targetShip status];
if (tstatus == STATUS_ENTERING_WITCHSPACE || tstatus == STATUS_IN_HOLD || tstatus == STATUS_DOCKED)
{ // checks for ships entering wormholes, docking, or been scooped
return NO;
}
return YES;
}
@ -2715,7 +2719,7 @@ static GLfloat sBaseMass = 0.0;
// check for lost ident target and ensure the ident system is actually scanning
UPDATE_STAGE(@"checking ident target");
if (ident_engaged && [self primaryTargetID] != NO_TARGET)
if (ident_engaged && [self primaryTarget] != nil)
{
if (![self isValidTarget:[self primaryTarget]])
{
@ -2730,7 +2734,7 @@ static GLfloat sBaseMass = 0.0;
suppressTargetLost = NO;
}
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
}
}
@ -2741,7 +2745,7 @@ static GLfloat sBaseMass = 0.0;
unsigned i;
for (i = 0; i < max_missiles; i++)
{
if ([missile_entity[i] primaryTargetID] != NO_TARGET &&
if ([missile_entity[i] primaryTarget] != nil &&
![self isValidTarget:[missile_entity[i] primaryTarget]])
{
[UNIVERSE addMessage:DESC(@"target-lost") forCount:3.0];
@ -2750,7 +2754,7 @@ static GLfloat sBaseMass = 0.0;
if (i == activeMissile)
{
[self noteLostTarget];
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
missile_status = MISSILE_STATUS_ARMED;
}
}
@ -2760,7 +2764,7 @@ static GLfloat sBaseMass = 0.0;
// if we don't have a primary target, and we're scanning, then check for a new
// target to lock on to
UPDATE_STAGE(@"looking for new target");
if ([self primaryTargetID] == NO_TARGET &&
if ([self primaryTarget] == nil &&
(ident_engaged || missile_status != MISSILE_STATUS_SAFE) &&
([self status] == STATUS_IN_FLIGHT || [self status] == STATUS_WITCHSPACE_COUNTDOWN))
{
@ -3652,7 +3656,7 @@ static GLfloat sBaseMass = 0.0;
- (NSString *) dialTargetName
{
Entity *target_entity = [UNIVERSE entityForUniversalID:primaryTarget];
Entity *target_entity = [self primaryTarget];
NSString *result = nil;
if (target_entity == nil)
@ -3686,7 +3690,7 @@ static GLfloat sBaseMass = 0.0;
unsigned i;
for (i = 0; i < max_missiles; i++)
{
if (missile_entity[i] && [missile_entity[i] primaryTarget] != NO_TARGET)
if (missile_entity[i] && [missile_entity[i] primaryTarget] != nil)
[missile_entity[i] removeTarget:nil];
}
missile_status = MISSILE_STATUS_SAFE;
@ -3742,19 +3746,19 @@ static GLfloat sBaseMass = 0.0;
if( [missile_entity[activeMissile] isMissile] )
{
if( [self hasEquipmentItem:@"EQ_MULTI_TARGET"] &&
([missile_entity[next_missile] primaryTargetID] != NO_TARGET))
([missile_entity[next_missile] primaryTarget] != nil))
{
// copy the missile's target
[self addTarget:[missile_entity[next_missile] primaryTarget]];
missile_status = MISSILE_STATUS_TARGET_LOCKED;
}
else if ([self primaryTargetID] != NO_TARGET)
else if ([self primaryTarget] != nil)
{
// never inherit target if we have EQ_MULTI_TARGET installed! [ Bug #16221 : Targeting enhancement regression ]
if([self hasEquipmentItem:@"EQ_MULTI_TARGET"])
{
[self noteLostTarget];
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
}
else
{
@ -3852,7 +3856,7 @@ static GLfloat sBaseMass = 0.0;
[UNIVERSE addMessage:DESC(@"autopilot-denied") forCount:4.5];
autopilot_engaged = NO;
[self resetAutopilotAI];
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
[self setStatus:STATUS_IN_FLIGHT];
[[OOMusicController sharedController] stopDockingMusic];
[self doScriptEvent:OOJSID("playerDockingRefused")];
@ -4456,7 +4460,7 @@ static GLfloat sBaseMass = 0.0;
}
- (OOUniversalID)launchEscapeCapsule
- (ShipEntity*)launchEscapeCapsule
{
ShipEntity *doppelganger = nil;
ShipEntity *escapePod = nil;
@ -4547,7 +4551,7 @@ static GLfloat sBaseMass = 0.0;
[escapePod release];
return result;
return doppelganger;
}
@ -4930,7 +4934,7 @@ static GLfloat sBaseMass = 0.0;
hyperspeed_engaged = NO;
hyperspeed_locked = NO;
[self safeAllMissiles];
primaryTarget = NO_TARGET; // must happen before showing break_pattern to supress active reticule.
DESTROY(_primaryTarget); // must happen before showing break_pattern to supress active reticule.
[self clearTargetMemory];
[hud setScannerZoom:1.0];
@ -5128,10 +5132,10 @@ static GLfloat sBaseMass = 0.0;
suppressAegisMessages=YES;
hyperspeed_engaged = NO;
if (primaryTarget != NO_TARGET)
if ([self primaryTarget] == nil)
{
[self noteLostTarget]; // losing target? Fire lost target event!
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
}
[hud setScannerZoom:1.0];
@ -8410,7 +8414,7 @@ static NSString *last_outfitting_key=nil;
// if targeted previously use that memory space
for (i = 0; i < PLAYER_TARGET_MEMORY_SIZE; i++)
{
if (primaryTarget == target_memory[i])
if ([[self primaryTarget] universalID] == target_memory[i])
{
target_memory_index = i;
foundSlot = YES;
@ -8425,7 +8429,7 @@ static NSString *last_outfitting_key=nil;
{
if (target_memory[target_memory_index] == NO_TARGET)
{
target_memory[target_memory_index] = primaryTarget;
target_memory[target_memory_index] = [[self primaryTarget] universalID];
foundSlot = YES;
break;
}
@ -8436,7 +8440,7 @@ static NSString *last_outfitting_key=nil;
{
// use the next memory space
target_memory_index = (target_memory_index + 1) % PLAYER_TARGET_MEMORY_SIZE;
target_memory[target_memory_index] = primaryTarget;
target_memory[target_memory_index] = [[self primaryTarget] universalID];
}
}

View File

@ -1027,8 +1027,8 @@ static NSTimeInterval time_last_frame;
if (!safety_pressed)
{
//targeting off in both cases!
if (primaryTarget != NO_TARGET) [self noteLostTarget];
primaryTarget = NO_TARGET;
if ([self primaryTarget] != nil) [self noteLostTarget];
DESTROY(_primaryTarget);
[self safeAllMissiles];
if (!ident_engaged && [self weaponsOnline])
{
@ -1101,7 +1101,9 @@ static NSTimeInterval time_last_frame;
}
}
if (goodToLaunch)
found_target = [self launchEscapeCapsule];
{
[self setFoundTarget:[self launchEscapeCapsule]];
}
}
exceptionContext = @"dump cargo";
@ -3664,7 +3666,7 @@ abort:
[self safeAllMissiles];
ident_engaged = YES;
if ([self primaryTargetID] == NO_TARGET)
if ([self primaryTarget] == nil)
{
[self playIdentOn];
[UNIVERSE addMessage:DESC(@"ident-on") forCount:2.0];
@ -3688,7 +3690,7 @@ abort:
// Clear current target if we're already in Missile Targeting mode
if (missile_status != MISSILE_STATUS_SAFE)
{
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
}
// Arm missile and check for missile lock

View File

@ -2727,15 +2727,12 @@ static int scriptRandomSeed = -1; // ensure proper random function
- (void) targetNearestHostile
{
[self scanForHostiles];
if (found_target != NO_TARGET)
Entity *ent = [self foundTarget];
if (ent != nil)
{
Entity *ent = [UNIVERSE entityForUniversalID:found_target];
if (ent != 0x00)
{
ident_engaged = YES;
missile_status = MISSILE_STATUS_TARGET_LOCKED;
[self addTarget:ent];
}
ident_engaged = YES;
missile_status = MISSILE_STATUS_TARGET_LOCKED;
[self addTarget:ent];
}
}
@ -2743,7 +2740,7 @@ static int scriptRandomSeed = -1; // ensure proper random function
- (void) targetNearestIncomingMissile
{
[self scanForNearestIncomingMissile];
Entity *ent = [UNIVERSE entityForUniversalID:found_target];
Entity *ent = [self foundTarget];
if (ent != nil)
{
ident_engaged = YES;

View File

@ -208,7 +208,7 @@ typedef enum
// variables which are controlled by instincts/AI
Vector destination; // for flying to/from a set point
OOUniversalID primaryTarget; // for combat or rendezvous
GLfloat desired_range; // range to which to journey/scan
GLfloat desired_speed; // speed at which to travel
// next three used to set desired attitude, flightRoll etc. gradually catch up to target
@ -231,8 +231,6 @@ typedef enum
//docking instructions
NSDictionary *dockingInstructions;
OOUniversalID last_escort_target; // last target an escort was deployed after
OOColor *laser_color;
OOColor *scanner_display_color1;
OOColor *scanner_display_color2;
@ -328,9 +326,6 @@ typedef enum
Vector jink; // x and y set factors for offsetting a pursuing ship's position
Vector coordinates; // for flying to/from a set point
Vector reference; // a direction vector of magnitude 1 (* turrets *)
OOUniversalID primaryAggressor; // recorded after an attack
OOUniversalID targetStation; // for docking
OOUniversalID found_target; // from scans
NSMutableArray *defenseTargets; // defense targets
OOUInteger _subIdx; // serialisation index - used only if this ship is a subentity
@ -344,7 +339,6 @@ typedef enum
int patrol_counter; // keeps track of where the ship is along a patrol route
OOUniversalID proximity_alert; // id of a ShipEntity within 2x collision_radius
NSMutableDictionary *previousCondition; // restored after collision avoidance
// derived variables
@ -375,9 +369,6 @@ typedef enum
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
@ -423,10 +414,23 @@ typedef enum
NSMutableArray *subEntities;
OOEquipmentType *missile_list[SHIPENTITY_MAX_MISSILES];
// various types of target
OOWeakReference *_primaryTarget; // for combat or rendezvous
OOWeakReference *_primaryAggressor; // recorded after attack
OOWeakReference *_targetStation; // for docking
OOWeakReference *_foundTarget; // from scans
OOWeakReference *_lastEscortTarget; // last target an escort was deployed after
OOWeakReference *_thankedShip; // last ship thanked
OOWeakReference *_rememberedShip; // ship being remembered
OOWeakReference *_proximityAlert; // a ShipEntity within 2x collision_radius
@private
OOWeakReference *_subEntityTakingDamage; // frangible => subEntities can be damaged individually
NSString *_shipKey;
NSMutableSet *_equipment;
@ -690,9 +694,6 @@ typedef enum
- (uint8_t) pendingEscortCount;
- (void) setPendingEscortCount:(uint8_t)count;
- (ShipEntity *) proximity_alert;
- (void) setProximity_alert:(ShipEntity*) other;
- (NSString *) name;
- (NSString *) displayName;
- (void) setName:(NSString *)inName;
@ -897,13 +898,24 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (ShipEntity**) scannedShips;
- (int) numberOfScannedShips;
- (Entity *)foundTarget;
- (Entity *)primaryAggressor;
- (Entity *)lastEscortTarget;
- (Entity *)thankedShip;
- (Entity *)rememberedShip;
- (Entity *)proximityAlert;
- (void) setFoundTarget:(Entity *) targetEntity;
- (void) setPrimaryAggressor:(Entity *) targetEntity;
- (void) setLastEscortTarget:(Entity *) targetEntity;
- (void) setThankedShip:(Entity *) targetEntity;
- (void) setRememberedShip:(Entity *) targetEntity;
- (void) setProximityAlert:(Entity *) targetEntity;
- (void) setTargetStation:(Entity *) targetEntity;
- (BOOL) isValidTarget:(Entity *) target;
- (void) addTarget:(Entity *) targetEntity;
- (void) removeTarget:(Entity *) targetEntity;
- (id) primaryTarget;
- (OOUniversalID) primaryTargetID;
- (StationEntity *) targetStation;
- (BOOL) isFriendlyTo:(ShipEntity *)otherShip;
@ -942,6 +954,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (double) rangeToPrimaryTarget;
- (double) approachAspectToPrimaryTarget;
- (double) rangeToSecondaryTarget:(Entity *)target;
- (BOOL) hasProximityAlertIgnoringTarget:(BOOL)ignore_target;
- (BOOL) onTarget:(OOViewID) direction withWeapon:(OOWeaponType)weapon;
- (OOTimeDelta) shotTime;
@ -973,7 +986,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (BOOL) activateCloakingDevice;
- (void) deactivateCloakingDevice;
- (BOOL) launchCascadeMine;
- (OOUniversalID) launchEscapeCapsule;
- (ShipEntity *) launchEscapeCapsule;
- (OOCommodityType) dumpCargo;
- (ShipEntity *) dumpCargoItem;
- (OOCargoType) dumpItem: (ShipEntity*) jetto;

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,8 @@
@interface ShipEntity (OOAIPrivate)
- (void) checkFoundTarget;
- (BOOL)performHyperSpaceExitReplace:(BOOL)replace;
- (BOOL)performHyperSpaceExitReplace:(BOOL)replace toSystem:(OOSystemID)systemID;
@ -289,7 +291,7 @@
- (void) scanForHostiles
{
/*-- Locates all the ships in range targeting the receiver and chooses the nearest --*/
found_target = NO_TARGET;
DESTROY(_foundTarget);
[self checkScanner];
unsigned i;
@ -302,13 +304,12 @@
&& ([thing isThargoid] || (([thing primaryTarget] == self) && [thing hasHostileTarget]) || [thing isDefenseTarget:self])
&& ![thing isCloaked])
{
found_target = [thing universalID];
[self setFoundTarget:thing];
found_d2 = d2;
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
[self checkFoundTarget];
}
@ -544,10 +545,10 @@
- (void) setTargetToPrimaryAggressor
{
Entity *primeAggressor = [UNIVERSE entityForUniversalID:primaryAggressor];
Entity *primeAggressor = [self primaryAggressor];
if (!primeAggressor)
return;
if (primaryTarget == primaryAggressor)
if ([self primaryTarget] == primeAggressor)
return;
// a more considered approach here:
@ -559,28 +560,27 @@
[self addDefenseTarget:(ShipEntity*)primeAggressor];
return;
}
// react only if the primary aggressor is not a friendly ship, else ignore it
if ([primeAggressor isShip] && ![(ShipEntity *)primeAggressor isFriendlyTo:self])
{
// inform our old target of our new target
//
Entity *primeTarget = [UNIVERSE entityForUniversalID:primaryTarget];
Entity *primeTarget = [self primaryTarget];
if ((primeTarget)&&(primeTarget->isShip))
{
ShipEntity *currentShip = [UNIVERSE entityForUniversalID:primaryTarget];
[[currentShip getAI] message:[NSString stringWithFormat:@"%@ %d %d", AIMS_AGGRESSOR_SWITCHED_TARGET, universalID, primaryAggressor]];
ShipEntity *currentShip = [self primaryTarget];
[[currentShip getAI] message:[NSString stringWithFormat:@"%@ %d %d", AIMS_AGGRESSOR_SWITCHED_TARGET, universalID, [[self primaryAggressor] universalID]]];
}
// okay, so let's now target the aggressor
[self addTarget:[UNIVERSE entityForUniversalID:primaryAggressor]];
[self addTarget:[self primaryAggressor]];
}
}
- (void) addPrimaryAggressorAsDefenseTarget
{
Entity *primeAggressor = [UNIVERSE entityForUniversalID:primaryAggressor];
Entity *primeAggressor = [self primaryAggressor];
if (!primeAggressor)
return;
if ([self isDefenseTarget:primeAggressor])
@ -619,7 +619,7 @@
[self checkScanner];
found_d2 = scannerRange * scannerRange;
found_target = NO_TARGET;
DESTROY(_foundTarget);
for (i = 0; i < n_scanned_ships ; i++)
{
@ -635,12 +635,11 @@
if (d2 < found_d2)
{
found_d2 = d2;
found_target = [ship universalID];
[self setFoundTarget:ship];
}
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
[self checkFoundTarget];
}
@ -650,15 +649,15 @@
//-- Locates one of the merchantman in range.
[self checkScanner];
OOUniversalID ids_found[n_scanned_ships];
ShipEntity* ids_found[n_scanned_ships];
n_found = 0;
found_target = NO_TARGET;
DESTROY(_foundTarget);
for (i = 0; i < n_scanned_ships ; i++)
{
ShipEntity *ship = scanned_ships[i];
if (([ship status] != STATUS_DEAD) && ([ship status] != STATUS_DOCKED) && [ship isPirateVictim] && ![ship isCloaked])
ids_found[n_found++] = ship->universalID;
ids_found[n_found++] = ship;
}
if (n_found == 0)
{
@ -667,7 +666,7 @@
else
{
i = ranrot_rand() % n_found; // pick a number from 0 -> (n_found - 1)
found_target = ids_found[i];
[self setFoundTarget:ids_found[i]];
[shipAI message:@"TARGET_FOUND"];
}
}
@ -702,7 +701,7 @@
[self checkScanner];
double found_d2 = scannerRange * scannerRange;
found_target = NO_TARGET;
DESTROY(_foundTarget);
unsigned i;
for (i = 0; i < n_scanned_ships; i++)
{
@ -715,19 +714,12 @@
if (d2 < found_d2)
{
found_d2 = d2;
found_target = other->universalID;
[self setFoundTarget:other];
}
}
}
}
if (found_target != NO_TARGET)
{
[shipAI message:@"TARGET_FOUND"];
}
else
{
[shipAI message:@"NOTHING_FOUND"];
}
[self checkFoundTarget];
}
@ -742,23 +734,22 @@
//
[self checkScanner];
//
OOUniversalID thing_uids_found[16];
ShipEntity* thing_uids_found[16];
unsigned things_found = 0;
found_target = NO_TARGET;
DESTROY(_foundTarget);
unsigned i;
for (i = 0; (i < n_scanned_ships)&&(things_found < 16) ; i++)
{
ShipEntity *other = scanned_ships[i];
if ([other scanClass] == CLASS_CARGO && [other cargoType] != CARGO_NOT_CARGO && [other status] != STATUS_BEING_SCOOPED)
{
found_target = [other universalID];
thing_uids_found[things_found++] = found_target;
thing_uids_found[things_found++] = other;
}
}
if (things_found != 0)
{
found_target = thing_uids_found[ranrot_rand() % things_found];
[self setFoundTarget:thing_uids_found[ranrot_rand() % things_found]];
[shipAI message:@"TARGET_FOUND"];
}
else
@ -768,17 +759,21 @@
- (void) setTargetToFoundTarget
{
if ([UNIVERSE entityForUniversalID:found_target])
[self addTarget:[UNIVERSE entityForUniversalID:found_target]];
if ([self foundTarget] != nil)
{
[self addTarget:[self foundTarget]];
}
else
[shipAI message:@"TARGET_LOST"]; // to prefent the ship going for a wrong, previous target. Should not be a reactToMessage.
{
[shipAI message:@"TARGET_LOST"]; // to prevent the ship going for a wrong, previous target. Should not be a reactToMessage.
}
}
- (void) addFoundTargetAsDefenseTarget
{
Entity* fTarget = [UNIVERSE entityForUniversalID:found_target];
if (!fTarget)
Entity* fTarget = [self foundTarget];
if (fTarget != nil)
{
if ([fTarget isShip] && ![(ShipEntity *)fTarget isFriendlyTo:self])
{
@ -946,7 +941,7 @@
// use the ECM and battle on
[self setPrimaryAggressor:hunter]; // lets get them now for that!
found_target = primaryAggressor;
[self setFoundTarget:hunter];
[self fireECM];
return;
@ -1029,7 +1024,7 @@
- (void) checkTargetLegalStatus
{
ShipEntity *other_ship = [UNIVERSE entityForUniversalID:primaryTarget];
ShipEntity *other_ship = [self primaryTarget];
if (!other_ship)
{
[shipAI message:@"NO_TARGET"];
@ -1094,7 +1089,7 @@
- (void) setDestinationToTarget
{
Entity *the_target = [UNIVERSE entityForUniversalID:primaryTarget];
Entity *the_target = [self primaryTarget];
if (the_target)
destination = the_target->position;
}
@ -1102,7 +1097,7 @@
- (void) setDestinationWithinTarget
{
Entity *the_target = [UNIVERSE entityForUniversalID:primaryTarget];
Entity *the_target = [self primaryTarget];
if (the_target)
{
Vector pos = the_target->position;
@ -1214,7 +1209,7 @@
for (i = 0; i < n_scanned_ships ; i++)
{
ShipEntity *ship = scanned_ships[i];
if (([ship primaryTarget] == self && [ship hasHostileTarget]) || [ship isMine] || ([ship isThargoid] != [self isThargoid]))
if (![ship isCloaked] && (([ship primaryTarget] == self && [ship hasHostileTarget]) || [ship isMine] || ([ship isThargoid] != [self isThargoid])))
{
if (![self isDefenseTarget:ship])
{
@ -1235,7 +1230,7 @@
if ([UNIVERSE sun] == nil)
gov_factor = 1.0;
//
found_target = NO_TARGET;
DESTROY(_foundTarget);
// find the worst offender on the scanner
//
@ -1247,7 +1242,7 @@
for (i = 0; i < n_scanned_ships ; i++)
{
ShipEntity *ship = scanned_ships[i];
if ((ship->scanClass != CLASS_CARGO)&&([ship status] != STATUS_DEAD)&&([ship status] != STATUS_DOCKED))
if ((ship->scanClass != CLASS_CARGO)&&([ship status] != STATUS_DEAD)&&([ship status] != STATUS_DOCKED)&& ![ship isCloaked])
{
GLfloat d2 = distance2_scanned_ships[i];
float legal_factor = [ship legalStatus] * gov_factor;
@ -1256,17 +1251,14 @@
{
if (group == nil || group != [ship group]) // fellows with bounty can't be offenders
{
found_target = [ship universalID];
[self setFoundTarget:ship];
worst_legal_factor = legal_factor;
}
}
}
}
if (found_target != NO_TARGET)
[shipAI message:@"TARGET_FOUND"];
else
[shipAI message:@"NOTHING_FOUND"];
[self checkFoundTarget];
}
@ -1354,9 +1346,9 @@
/*-- 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;
DESTROY(_foundTarget);
ShipEntity *aggressor_ship = [UNIVERSE entityForUniversalID:primaryAggressor];
ShipEntity *aggressor_ship = (ShipEntity*)[self primaryAggressor];
if (aggressor_ship == nil) return;
// don't send too many distress messages at once, space them out semi-randomly
@ -1373,7 +1365,7 @@
ShipEntity* ship = scanned_ships[i];
// dump cargo if energy is low
if (!is_buoy && primaryAggressor == [ship universalID] && energy < 0.375 * maxEnergy)
if (!is_buoy && [self primaryAggressor] == ship && energy < 0.375 * maxEnergy)
{
[self ejectCargo];
[self performFlee];
@ -1382,7 +1374,7 @@
// tell it!
if (ship->isPlayer)
{
if (!is_buoy && primaryAggressor == [ship universalID] && energy < 0.375 * maxEnergy)
if (!is_buoy && [self primaryAggressor] == ship && energy < 0.375 * maxEnergy)
{
[self sendExpandedMessage:ExpandDescriptionForCurrentSystem(@"[beg-for-mercy]") toShip:ship];
}
@ -1394,7 +1386,7 @@
}
// reset the thanked_ship_id
thanked_ship_id = NO_TARGET;
DESTROY(_thankedShip);
}
else if ([self bounty] == 0 && [ship crew]) // Only clean ships can have their distress calls accepted
{
@ -1402,6 +1394,8 @@
// we only can send distressMessages to ships that are known to have a "ACCEPT_DISTRESS_CALL" reaction
// in their AI, or they might react wrong on the added found_target.
// FIXME: this test only works with core AIs
if (ship->isStation || [ship hasPrimaryRole:@"police"] || [ship hasPrimaryRole:@"hunter"])
{
[ship acceptDistressMessageFrom:self];
@ -1450,7 +1444,7 @@
- (void) scanForNonThargoid
{
/*-- Locates all the non thargoid ships in range and chooses the nearest --*/
found_target = NO_TARGET;
DESTROY(_foundTarget);
[self checkScanner];
unsigned i;
@ -1461,14 +1455,13 @@
GLfloat d2 = distance2_scanned_ships[i];
if (([thing scanClass] != CLASS_CARGO) && ([thing status] != STATUS_DOCKED) && ![thing isThargoid] && ![thing isCloaked] && (d2 < found_d2))
{
found_target = [thing universalID];
[self setFoundTarget:thing];
if ([thing isPlayer]) d2 = 0.0; // prefer the player
found_d2 = d2;
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
[self checkFoundTarget];
}
@ -1487,9 +1480,9 @@
{
// we lost the old mother, search for a new one
[self scanForNearestShipHavingRole:@"thargoid-mothership"]; // the scan will send further AI messages.
if (found_target != NO_TARGET && [UNIVERSE entityForUniversalID:found_target])
if ([self foundTarget] != nil)
{
mother = [UNIVERSE entityForUniversalID:found_target];
mother = (ShipEntity*)[self foundTarget];
[self setOwner:mother];
if ([mother group] != [mother escortGroup]) // avoid adding thargon to an escort group.
{
@ -1521,7 +1514,7 @@
scanClass = CLASS_CARGO;
reportAIMessages = NO;
[shipAI setStateMachine:@"dumbAI.plist"];
primaryTarget = NO_TARGET;
DESTROY(_primaryTarget);
[self setSpeed: 0.0];
[self setGroup:nil];
}
@ -1536,18 +1529,20 @@
- (void) fightOrFleeHostiles
{
[self addDefenseTarget:[UNIVERSE entityForUniversalID:found_target]];
[self addDefenseTarget:[self foundTarget]];
if ([self hasEscorts])
{
if (found_target == last_escort_target)
Entity *leTarget = [self lastEscortTarget];
if (leTarget != nil)
{
[self setFoundTarget:leTarget];
[shipAI message:@"FLEEING"];
return;
}
primaryAggressor = found_target;
primaryTarget = found_target;
[self setPrimaryAggressor:[self foundTarget]];
[self addTarget:[self foundTarget]];
[self deployEscorts];
[shipAI message:@"DEPLOYING_ESCORTS"];
[shipAI message:@"FLEEING"];
@ -1559,8 +1554,8 @@
{
if (randf() < 0.50)
{
primaryAggressor = found_target;
primaryTarget = found_target;
[self setPrimaryAggressor:[self foundTarget]];
[self addTarget:[self foundTarget]];
[self fireMissile];
[shipAI message:@"FLEEING"];
return;
@ -1570,7 +1565,7 @@
// consider fighting
if (energy > maxEnergy * 0.80)
{
primaryAggressor = found_target;
[self setPrimaryAggressor:[self foundTarget]];
//[self performAttack];
[shipAI message:@"FIGHTING"];
return;
@ -1582,7 +1577,7 @@
- (void) suggestEscort
{
ShipEntity *mother = [UNIVERSE entityForUniversalID:primaryTarget];
ShipEntity *mother = [self primaryTarget];
if (mother)
{
#ifndef NDEBUG
@ -1676,11 +1671,11 @@
NSEnumerator *shipEnum = nil;
ShipEntity *target = nil, *ship = nil;
if (primaryTarget == NO_TARGET) return;
if ([self primaryTarget] == nil) return;
if ([self group] == nil) // ship is alone!
{
found_target = primaryTarget;
[self setFoundTarget:[self primaryTarget]];
[shipAI reactToMessage:@"GROUP_ATTACK_TARGET" context:@"groupAttackTarget"];
return;
}
@ -1711,25 +1706,25 @@
- (void) scanForFormationLeader
{
//-- Locates the nearest suitable formation leader in range --//
found_target = NO_TARGET;
DESTROY(_foundTarget);
[self checkScanner];
unsigned i;
GLfloat found_d2 = scannerRange * scannerRange;
for (i = 0; i < n_scanned_ships; i++)
{
ShipEntity *ship = scanned_ships[i];
if ((ship != self) && (!ship->isPlayer) && (ship->scanClass == scanClass) && [ship primaryTarget] != self) // look for alike
if ((ship != self) && (!ship->isPlayer) && (ship->scanClass == scanClass) && [ship primaryTarget] != self && ![ship isCloaked]) // look for alike
{
GLfloat d2 = distance2_scanned_ships[i];
if ((d2 < found_d2) && [ship canAcceptEscort:self])
{
found_d2 = d2;
found_target = ship->universalID;
[self setFoundTarget:ship];
}
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
if ([self foundTarget] != nil) [shipAI message:@"TARGET_FOUND"];
else
{
[shipAI message:@"NOTHING_FOUND"];
@ -1817,7 +1812,7 @@
if (randf() < .25)
{
// consider docking
targetStation = [the_station universalID];
[self setTargetStation:the_station];
[self setAITo:@"dockingAI.plist"];
return;
}
@ -1955,22 +1950,22 @@
- (void) storeTarget
{
Entity *target = [UNIVERSE entityForUniversalID:primaryTarget];
Entity *target = [self primaryTarget];
if (target)
{
remembered_ship = primaryTarget;
[self setRememberedShip:target];
}
else
{
remembered_ship = NO_TARGET;
DESTROY(_rememberedShip);
}
}
- (void) recallStoredTarget
{
ShipEntity *oldTarget = [UNIVERSE entityForUniversalID:remembered_ship];
ShipEntity *oldTarget = (ShipEntity*)[self rememberedShip];
BOOL found = NO;
if (oldTarget && ![oldTarget isCloaked])
@ -1984,12 +1979,12 @@
if (found)
{
found_target = remembered_ship;
[self setFoundTarget:oldTarget];
[shipAI message:@"TARGET_FOUND"];
}
else
{
if (oldTarget == nil) remembered_ship = NO_TARGET; // ship no longer exists
if (oldTarget == nil) DESTROY(_rememberedShip); // ship no longer exists
[shipAI message:@"NOTHING_FOUND"];
}
@ -2001,7 +1996,7 @@
// find boulders then asteroids within range
//
found_target = NO_TARGET;
DESTROY(_foundTarget);
[self checkScanner];
unsigned i;
GLfloat found_d2 = scannerRange * scannerRange;
@ -2013,12 +2008,12 @@
GLfloat d2 = distance2_scanned_ships[i];
if (d2 < found_d2)
{
found_target = thing->universalID;
[self setFoundTarget:thing];
found_d2 = d2;
}
}
}
if (found_target == NO_TARGET)
if ([self foundTarget] == nil)
{
for (i = 0; i < n_scanned_ships; i++)
{
@ -2028,15 +2023,14 @@
GLfloat d2 = distance2_scanned_ships[i];
if (d2 < found_d2)
{
found_target = thing->universalID;
[self setFoundTarget:thing];
found_d2 = d2;
}
}
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
[self checkFoundTarget];
}
@ -2083,7 +2077,7 @@
}
/*-- Locates all the ships in range targeting the mother ship and chooses the nearest/biggest --*/
found_target = NO_TARGET;
DESTROY(_foundTarget);
[self checkScanner];
unsigned i;
GLfloat found_d2 = scannerRange * scannerRange;
@ -2093,18 +2087,17 @@
ShipEntity *thing = scanned_ships[i];
GLfloat d2 = distance2_scanned_ships[i];
GLfloat e1 = [thing energy];
if ((d2 < found_d2) && (([thing isThargoid] && ![mother isThargoid]) || (([thing primaryTarget] == mother) && [thing hasHostileTarget])))
if ((d2 < found_d2) && ![thing isCloaked] && (([thing isThargoid] && ![mother isThargoid]) || (([thing primaryTarget] == mother) && [thing hasHostileTarget])))
{
if (e1 > max_e)
{
found_target = thing->universalID;
[self setFoundTarget:thing];
max_e = e1;
}
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
[self checkFoundTarget];
}
@ -2279,7 +2272,7 @@
}
// Select nothing
found_target = NO_TARGET;
DESTROY(_foundTarget);
[[self getAI] message:@"NOTHING_FOUND"];
}
@ -2359,6 +2352,14 @@
{
// select a random station
station = (StationEntity *)my_entities[ranrot_rand() % station_count];
// if more than one candidate do not select main station
if (station == [UNIVERSE station] && station_count > 1)
{
while (station == [UNIVERSE station])
{
station = (StationEntity *)my_entities[ranrot_rand() % station_count];
}
}
}
for (i = 0; i < station_count; i++)
@ -2366,8 +2367,8 @@
//
if (station)
{
primaryTarget = [station universalID];
targetStation = primaryTarget;
[self addTarget:station];
[self setTargetStation:station];
[shipAI message:@"STATION_FOUND"];
}
else
@ -2378,16 +2379,16 @@
- (void) setTargetToLastStation
{
Entity *station = [UNIVERSE entityForUniversalID:targetStation];
Entity *station = [self targetStation];
if ([station isStation])
if (station != nil && [station isStation])
{
primaryTarget = targetStation;
[self addTarget:station];
}
else
{
[shipAI message:@"NO_STATION_FOUND"];
targetStation = NO_TARGET;
[self setTargetStation:nil];
}
}
@ -2403,7 +2404,7 @@
NSString *message = nil;
double distanceToStation2 = 0.0;
targStation = [UNIVERSE entityForUniversalID:targetStation];
targStation = [self targetStation];
if ([targStation isStation])
{
station = (StationEntity*)targStation;
@ -2457,10 +2458,18 @@
destination = [dockingInstructions oo_vectorForKey:@"destination"];
desired_speed = fmin([dockingInstructions oo_floatForKey:@"speed"], maxFlightSpeed);
desired_range = [dockingInstructions oo_floatForKey:@"range"];
if ([dockingInstructions objectForKey:@"station_id"])
if ([dockingInstructions objectForKey:@"station"])
{
primaryTarget = [dockingInstructions oo_intForKey:@"station_id"];
targetStation = primaryTarget;
StationEntity *targetStation = [[dockingInstructions objectForKey:@"station"] weakRefUnderlyingObject];
if (targetStation != nil)
{
[self addTarget:targetStation];
[self setTargetStation:targetStation];
}
else
{
[self removeTarget:[self primaryTarget]];
}
}
docking_match_rotation = [dockingInstructions oo_boolForKey:@"match_rotation"];
}
@ -2569,7 +2578,7 @@
NSArray *all_beacons = [UNIVERSE listBeaconsWithCode: code];
if ([all_beacons count])
{
primaryTarget = [(ShipEntity*)[all_beacons objectAtIndex:0] universalID];
[self addTarget:(ShipEntity*)[all_beacons objectAtIndex:0]];
[shipAI message:@"TARGET_FOUND"];
}
else
@ -2580,7 +2589,7 @@
- (void) targetNextBeaconWithCode:(NSString*) code
{
NSArray *all_beacons = [UNIVERSE listBeaconsWithCode: code];
ShipEntity *current_beacon = [UNIVERSE entityForUniversalID:primaryTarget];
ShipEntity *current_beacon = [self primaryTarget];
if ((!current_beacon)||(![current_beacon isBeacon]))
{
@ -2603,7 +2612,7 @@
if (i < [all_beacons count])
{
// locate current target in list
primaryTarget = [(ShipEntity*)[all_beacons objectAtIndex:i] universalID];
[self addTarget:(ShipEntity*)[all_beacons objectAtIndex:i]];
[shipAI message:@"TARGET_FOUND"];
}
else
@ -2617,7 +2626,7 @@
- (void) setRacepointsFromTarget
{
// two point - one at z - cr one at z + cr
ShipEntity *ship = [UNIVERSE entityForUniversalID:primaryTarget];
ShipEntity *ship = [self primaryTarget];
if (ship == nil)
{
[shipAI message:@"NOTHING_FOUND"];
@ -2648,6 +2657,19 @@
@implementation ShipEntity (OOAIPrivate)
- (void) checkFoundTarget
{
if ([self foundTarget] != nil)
{
[shipAI message:@"TARGET_FOUND"];
}
else
{
[shipAI message:@"NOTHING_FOUND"];
}
}
- (BOOL) performHyperSpaceExitReplace:(BOOL)replace
{
return [self performHyperSpaceExitReplace:replace toSystem:-1];
@ -2689,7 +2711,7 @@
ShipEntity *blocker = [UNIVERSE entityForUniversalID:[self checkShipsInVicinityForWitchJumpExit]];
if (blocker)
{
found_target = [blocker universalID];
[self setFoundTarget:blocker];
[shipAI reactToMessage:@"WITCHSPACE BLOCKED" context:@"performHyperSpaceExit"];
return NO;
}
@ -2740,7 +2762,7 @@
ShipEntity *candidate;
float d2, found_d2 = scannerRange * scannerRange;
found_target = NO_TARGET;
DESTROY(_foundTarget);
[self checkScanner];
if (predicate == NULL) return;
@ -2752,13 +2774,12 @@
if ((d2 < found_d2) && (candidate->scanClass != CLASS_CARGO) && ([candidate status] != STATUS_DOCKED)
&& predicate(candidate, parameter) && ![candidate isCloaked])
{
found_target = candidate->universalID;
[self setFoundTarget:candidate];
found_d2 = d2;
}
}
if (found_target != NO_TARGET) [shipAI message:@"TARGET_FOUND"];
else [shipAI message:@"NOTHING_FOUND"];
[self checkFoundTarget];
}
@ -2771,10 +2792,10 @@
- (void) acceptDistressMessageFrom:(ShipEntity *)other
{
found_target = [[other primaryTarget] universalID];
[self setFoundTarget:[other primaryTarget]];
if ([self isPolice])
{
[[UNIVERSE entityForUniversalID:found_target] markAsOffender:8 withReason:kOOLegalStatusReasonDistressCall]; // you have been warned!!
[(ShipEntity*)[self foundTarget] markAsOffender:8 withReason:kOOLegalStatusReasonDistressCall]; // you have been warned!!
}
NSString *context = nil;
@ -2797,11 +2818,11 @@
{
if (self != [UNIVERSE station]) return;
int old_target = primaryTarget;
primaryTarget = [[other primaryTarget] universalID];
OOWeakReference *old_target = _primaryTarget;
_primaryTarget = [[[other primaryTarget] weakRetain] autorelease];
[(ShipEntity *)[other primaryTarget] markAsOffender:8 withReason:kOOLegalStatusReasonDistressCall]; // mark their card
[self launchDefenseShip];
primaryTarget = old_target;
_primaryTarget = old_target;
}

View File

@ -167,7 +167,14 @@ MA 02110-1301, USA.
PlayerEntity *player = PLAYER;
zero_distance = MAX_CLEAR_DEPTH * MAX_CLEAR_DEPTH;
cam_zero_distance = zero_distance;
if (player != nil) position = [player viewpointPosition];
if (player != nil)
{
position = [player viewpointPosition];
}
else
{
OOLog(@"sky.warning",@"PLAYER is nil");
}
}

View File

@ -348,7 +348,8 @@ NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, f
[acc setObject:[NSString stringWithFormat:@"%.2f %.2f %.2f", coords.x, coords.y, coords.z] forKey:@"destination"];
[acc oo_setFloat:speed forKey:@"speed"];
[acc oo_setFloat:range forKey:@"range"];
[acc oo_setInteger:[station universalID] forKey:@"station_id"];
[acc setObject:[station weakRetain] forKey:@"station"];
[acc oo_setInteger:[station universalID] forKey:@"station_id"]; // TODO: remove
[acc oo_setBool:match_rotation forKey:@"match_rotation"];
if (ai_message)
{
@ -1174,7 +1175,7 @@ NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, f
[(ShipEntity*)other markAsOffender:b withReason:kOOLegalStatusReasonAttackedMainStation];
[self setPrimaryAggressor:other];
found_target = primaryAggressor;
[self setFoundTarget:other];
[self launchPolice];
if (isEnergyMine) //don't blow up!
@ -1417,7 +1418,7 @@ NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, f
return [NSArray array];
}
OOUniversalID police_target = primaryTarget;
OOUniversalID police_target = [[self primaryTarget] universalID];
unsigned i;
NSMutableArray *result = nil;
OOTechLevelID techlevel = [self equivalentTechLevel];
@ -1482,7 +1483,7 @@ NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, f
return nil;
}
OOUniversalID defense_target = primaryTarget;
OOUniversalID defense_target = [[self primaryTarget] universalID];
ShipEntity *defense_ship = nil;
NSString *defense_ship_key = nil,
*defense_ship_role = nil,
@ -1681,7 +1682,7 @@ NSDictionary *OOMakeDockingInstructions(StationEntity *station, Vector coords, f
return nil;
}
//Pirate ships are launched from the same pool as defence ships.
OOUniversalID defense_target = primaryTarget;
OOUniversalID defense_target = [[self primaryTarget] universalID];
ShipEntity *pirate_ship = nil;
if (defenders_launched >= max_defense_ships) return nil; // shuttles are to rockhermits what police ships are to stations

View File

@ -2092,7 +2092,7 @@ static OOPolygonSprite *IconForMissileRole(NSString *role)
PlayerEntity *player = PLAYER;
GLfloat alpha = [info oo_nonNegativeFloatForKey:ALPHA_KEY defaultValue:1.0f] * overallAlpha;
if ([player primaryTargetID] != NO_TARGET)
if ([player primaryTarget] != nil)
{
hudDrawReticleOnTarget([player primaryTarget], player, z1, alpha, reticleTargetSensitive, propertiesReticleTargetSensitive);
[self drawDirectionCue:info];

View File

@ -174,7 +174,7 @@ MA 02110-1301, USA.
saved_desired_range = ship->desired_range;
saved_desired_speed = ship->desired_speed;
saved_behaviour = ship->behaviour;
saved_target_id = ship->primaryTarget;
saved_target_id = [[ship primaryTarget] universalID];
}
}
@ -186,7 +186,7 @@ MA 02110-1301, USA.
ship->desired_range = saved_desired_range;
ship->desired_speed = saved_desired_speed;
ship->behaviour = saved_behaviour;
ship->primaryTarget = saved_target_id;
[ship addTarget:[UNIVERSE entityForUniversalID:saved_target_id]];
}
}
@ -198,7 +198,7 @@ MA 02110-1301, USA.
ship->desired_range = desired_range;
ship->desired_speed = desired_speed;
ship->behaviour = behaviour;
ship->primaryTarget = target_id;
[ship addTarget:[UNIVERSE entityForUniversalID:target_id]];
}
}
@ -210,7 +210,7 @@ MA 02110-1301, USA.
desired_range = ship->desired_range;
desired_speed = ship->desired_speed;
behaviour = ship->behaviour;
target_id = ship->primaryTarget;
target_id = [[ship primaryTarget] universalID];
}
}

View File

@ -72,7 +72,7 @@ static JSPropertySpec sDockProperties[] =
{
// JS name ID flags
{ "allowsDocking", kDock_allowsDocking, OOJS_PROP_READWRITE_CB },
{ "disallowedDockingCollides", kDock_disallowedDockingCollides, OOJS_PROP_READONLY_CB },
{ "disallowedDockingCollides", kDock_disallowedDockingCollides, OOJS_PROP_READWRITE_CB },
{ "allowsLaunching", kDock_allowsLaunching, OOJS_PROP_READWRITE_CB },
{ "dockingQueueLength", kDock_dockingQueueLength, OOJS_PROP_READONLY_CB },
{ "launchingQueueLength", kDock_launchingQueueLength, OOJS_PROP_READONLY_CB },
@ -152,7 +152,7 @@ static JSBool DockGetProperty(JSContext *context, JSObject *this, jsid propID, j
return YES;
case kDock_disallowedDockingCollides:
*value = OOJSValueFromBOOL(![entity allowsPlayerDocking]);
*value = OOJSValueFromBOOL([entity disallowedDockingCollides]);
return YES;
case kDock_allowsLaunching:
@ -207,6 +207,14 @@ static JSBool DockSetProperty(JSContext *context, JSObject *this, jsid propID, J
}
break;
case kDock_disallowedDockingCollides:
if (JS_ValueToBoolean(context, *value, &bValue))
{
[entity setDisallowedDockingCollides:bValue];
return YES;
}
break;
default:
OOJSReportBadPropertySelector(context, this, propID, sDockProperties);
return NO;

View File

@ -531,7 +531,7 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsid propID, j
return YES;
case kShip_potentialCollider:
result = [entity proximity_alert];
result = [entity proximityAlert];
break;
case kShip_hasHostileTarget:

View File

@ -9402,7 +9402,7 @@ static void PreloadOneSound(NSString *soundName)
{
unsigned i, r, escortsWeight;
unsigned totalRocks = 0;
BOOL includeHermit;
BOOL includeHermit, includedHermit = NO;
unsigned clusterSize;
double asteroidLocation;
Vector launchPos;
@ -9663,6 +9663,8 @@ static void PreloadOneSound(NSString *soundName)
launchPos = OOVectorTowards(h1_pos, v_route1, asteroidLocation);
includeHermit = (Ranrot() & 31) <= clusterSize && r < total_clicks * 2 / 3 && !sunGoneNova;
includedHermit |= includeHermit;
totalRocks += [self scatterAsteroidsAt:launchPos
withVelocity:kZeroVector
includingRockHermit:includeHermit
@ -9827,6 +9829,8 @@ static void PreloadOneSound(NSString *soundName)
launchPos = OOVectorTowards(p1_pos, v_route2, asteroidLocation);
includeHermit = (Ranrot() & 31) <= clusterSize && asteroidLocation > 0.33 * maxLength && !sunGoneNova;
includedHermit |= includeHermit;
totalRocks += [self scatterAsteroidsAt:launchPos
withVelocity:kZeroVector
includingRockHermit:includeHermit
@ -9836,6 +9840,26 @@ static void PreloadOneSound(NSString *soundName)
[pool release];
}
if (!sunGoneNova && !includedHermit)
{
// if we haven't had a non-main station yet
// add a loose rock hermit for full pirates to dock with well out of the way
Vector v_route1_mid = vector_multiply_scalar(v_route1,0.5);
Vector v_off_plane = cross_product(v_route1,v_route2);
// make sure it is well out of sun/planet/wp plane to make sure
// player doesn't run across it accidentally
Vector v_hermit_area = vector_add(v_route1_mid,vector_multiply_scalar(v_off_plane,500000.0));
// if they manage to follow a pirate out there, fair enough.
// there are quicker ways to make money
Vector v_hermit_pos = vector_add(v_hermit_area,OOVectorRandomSpatial(200000.0));
[self scatterAsteroidsAt:v_hermit_pos
withVelocity:kZeroVector
includingRockHermit:YES
asCinders:NO
clusterSize:1 + (Ranrot() % 6)];
}
}
- (int) scatterAsteroidsAt:(Vector)spawnPos withVelocity:(Vector)spawnVel includingRockHermit:(BOOL)spawnHermit asCinders:(BOOL)asCinders