home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD Player 1994 January
/
CdPlayer94-01.iso
/
demos
/
wing
/
brains.c
next >
Wrap
Text File
|
1990-08-17
|
30KB
|
1,243 lines
/*
==========================================================================
| WINGLEADER |
| The 3D space combar simulator |
| |
| A game of interstellar fighter conflict. |
| |
| (c)1989,1990 Chris Roberts. All rights reserved. |
==========================================================================
** NPC PILOT INTELLIGENCE CODE MODULE **
*/
// #define PCI_DEBUG
#define DEBUG_BEGIN if(DEBUG_INFO!=off){select_text_window(&main_screen);
#define DEBUG_END }
#include <game.h>
extern change_mission_type (int obj, objectives new_obj);
/*-------------------------------------------------------------------------*/
#define DETERMINATION (70-max(0,min(fanatical,pilot_level[obj]))*20)
/*
------------------------------------------------------------------------------
coming_home()
------------------------------------------------------------------------------
*/
#define NEAR_NAV (700)
#define NEAR_BASE (2000)
void cruise_home(int obj)
{
int range;
if( abandoned(obj,your_ship) )
return;
if ((ship_turn[obj]&7) == 5)
{
if (no_goal(obj))
point_ship_at_point(obj,&destination[obj]);
range = distance_from_point(obj,&destination[obj]);
if (equ_vector(&destination[obj],&ship_mission_spot[obj]))
{
if( range<NEAR_BASE )
{
reset_tactic(obj,head_home);
set_special(obj,kill_engines);
zero_vector(&velocity_vec[obj]);
MissionShips[ship_list_index[obj]].Status = SHIP_PARK;
}
}
else
if( range<NEAR_NAV )
{
visit(Flight_path[ship_tmp_index[obj]]);
get_follow_point(obj,&destination[obj]);
}
}
}
void fail(int obj)
{
report(" => Failure in #%d",obj);
}
void coming_home (int obj)
{
switch( ship_tactic[obj] )
{
case cruise: cruise_home(obj); break;
case head_home:
if (no_goal(obj))
point_parallel(obj,find_ship_index(MissionInfo.Carrier));
break;
case NONE:
reset_tactic(obj,cruise);
get_first_follow_point(obj,&destination[obj]);
break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
run_away()
------------------------------------------------------------------------------
*/
run_away (int obj)
{
vec_3D vec;
#define ROUT_RANGE (16000)
if (isactive(ship_wingleader[obj]))
if (ship_mission_type[ship_wingleader[obj]] == rout)
{
maintain_formation(obj);
return;
}
if (side[obj] == Imperial)
coming_home(obj);
else
{
// All Kilrathi flee straight down.
zero_vector(&vec);
vec.y = IntFract(1);
if (obj&1)
vec.y = -vec.y;
point_ship(obj,0,&vec);
if( normal_speed(obj) && random(100)<5 )
fire_afterburner(obj,STD_BURN*2);
else
approach_full_speed(obj);
// This really ought to do some dodging maneuvers during the rout. -KLD
// WARNING: is this remove_object() good enough to kick ship shapes out
// if necessary?? -RKLD
if (distance_from_object(obj,your_ship) > ROUT_RANGE)
remove_object(obj);
}
}
/*
------------------------------------------------------------------------------
*/
int check_engage_target(int obj) // for combat in general...
{
int new_target;
if( (new_target=detect_enemy_tail(obj)) != NONE && new_target!=ship_target[obj] )
ship_target[obj] = new_target;
else
if( !target_valid(obj) )
select_target(obj);
return( ship_target[obj] );
}
int check_destroy_target(int obj)
{
int destroy_target = find_ship_index(ship_mission_ship[obj]);
int test_target;
if( class[destroy_target]==futurion || gone_ship(ship_mission_ship[obj]) )
check_engage_target(obj);
else
if( evaluate_damage(obj)>DETERMINATION )
{
ship_target[obj] = destroy_target;
if( side[destroy_target]==side[obj] )
warn("KS");
}
else
if( (target_valid(obj) && random(100)>3) )
check_engage_target(obj);
else
ship_target[obj]=destroy_target;
return( ship_target[obj] );
}
void maneuvering(int obj, int new_target)
{
ship_target[obj] = new_target;
intelligence_events(obj);
perform_maneuver(obj);
}
/*
------------------------------------------------------------------------------
formation_burst()
------------------------------------------------------------------------------
*/
#define BURST_TIMER 9
void formation_burst (int obj)
{
vec_3D vec;
int leader = ship_wingleader[obj];
approach_full_speed(obj);
if (no_goal(obj))
point_ship(obj,0,&destination[obj]);
if (++ship_count[obj] > BURST_TIMER)
if( ship_mission_type[obj]==strike )
engage(obj,ship_target[obj],destroy_ship);
else
engage(obj,ship_target[obj],engage_enemy);
}
/*
------------------------------------------------------------------------------
capital_combat()
------------------------------------------------------------------------------
*/
capital_combat (int obj)
{
} /* capital_combat() */
/*
------------------------------------------------------------------------------
imperial_formation()
------------------------------------------------------------------------------
*/
int enemy_sighting = NO_SIGHTINGS;
imperial_formation (int obj)
{
int leader = ship_wingleader[obj];
int target;
vec_3D dest;
int closest;
maintain_formation(obj);
#define THREATENING (11000)
#define VISUAL (14000)
if (attacker_in_range(leader,THREATENING))
{
if (auto_engage_timer != NONE)
if (--auto_engage_timer == 0)
allow_engage();
if( allowed_to_engage(obj) ) // target ship is pulled out of the blue! -RKLD
engage(obj,target_ship,engage_enemy);
else
if (obj == your_wingman)
if (
(ship_turn[obj]&15)==0 &&
(auto_engage_timer == NONE)
)
{
send_message(obj, COM_atk_request);
auto_engage_timer = 25;
}
}
else
{
if( obj==your_wingman && enemy_sighting!=current_wave && any_enemy(obj,VISUAL) )
if( !message_showing() && cockpit_view==front )
{
send_message(obj,COM_i_see_enemy);
enemy_sighting = current_wave;
}
}
#define FAR_AWAY (9000)
#define TOWARD (85)
if (special_maneuver[obj] == NONE)
if (distance_from_object(obj,leader) > FAR_AWAY)
if ((facing_to_object(obj,leader) > TOWARD)
&& (real_velocity(obj) < 110 ))
fire_afterburner(obj,STD_BURN);
else
{
point_ship_at_object(obj,leader);
approach_ship_speed(obj,leader);
}
} /* imperial_formation() */
/*
------------------------------------------------------------------------------
formation_break()
------------------------------------------------------------------------------
*/
formation_break (int obj)
{
/*
WHENEVER SOMEBODY DESIGNS THE FORMATIONS SOME SCRIPTS
WILL HAVE TO BE SET UP FOR THE WINGMEN TO BREAK AWAY
FROM THE FORMATION IN A VISUALLY EXCITING MANNER...
*/
switch (ship_seq[obj])
{
case 0:
steady_object(obj);
yaw_goal[obj] = -30;
roll_goal[obj] = -45;
pitch_goal[obj] = -20;
++ship_seq[obj];
break;
case 1:
if (no_goal(obj))
engage(obj,ship_target[obj],engage_enemy);
break;
default: ship_seq[obj] = 0;
}
}
/*
------------------------------------------------------------------------------
imperial_wingman()
routine for a WINGMAN on the Player's Side on a PATROL mission
------------------------------------------------------------------------------
*/
void imperial_wingman (int obj)
{
int target;
int leader = ship_wingleader[obj];
switch (ship_objective[obj])
{
case hold_formation: imperial_formation(obj); break;
case break_formation: formation_break(obj); break;
case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
case destroy_ship: maneuvering(obj,check_destroy_target(obj)); break;
case NONE: reset_objective(obj,hold_formation); break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
kilrathi_wingman()
------------------------------------------------------------------------------
*/
void kilrathi_wingman(int obj)
{
int leader = ship_wingleader[obj];
if (leader == NONE)
{
change_mission_type(obj,patrol);
return;
}
else
if( unactive(leader) )
{
inherit_leader(obj);
return;
}
if( ship_objective[leader]==engage_enemy || ship_objective[leader]==destroy_ship )
if( ship_objective[obj]!=ship_objective[leader] )
engage(obj,ship_target[obj],ship_objective[leader]);
switch( ship_objective[obj] )
{
case hold_formation: maintain_formation(obj); break;
case break_formation: formation_burst(obj); break;
case destroy_ship: // protect your wingleader!
case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
case NONE: reset_objective(obj,hold_formation); break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
wingman_mission()
------------------------------------------------------------------------------
*/
void wingman_mission(int obj)
{
if( side[obj]==Imperial )
imperial_wingman(obj);
else
kilrathi_wingman(obj);
}
/*
------------------------------------------------------------------------------
*/
int dist_from_home(int obj)
{
return( distance_from_point(obj,&ship_mission_spot[obj]) );
}
/*
------------------------------------------------------------------------------
kilrathi_patrol()
------------------------------------------------------------------------------
*/
#define PATROL_RADIUS (8000) // when this far out, must get closer.
#define WANDER_RADIUS (3000) // when this close to patrol pt, can wander.
#define APPROACH_BEHIND (490)
#define NORMAL_SCANNER (14000)
#define APPROACH_RANGE (10000) // break form now.
int scan_and_lock(int obj, int scan_range, tactics new_tactic)
{
int new_target;
ship_target[obj] = scan_for_enemy(obj,NORMAL_SCANNER);
if( ship_target[obj]!=NONE )
ship_tactic[obj] = new_tactic;
return( ship_target[obj]!=NONE );
}
void patrol_area(int obj)
{
int target = ship_target[obj];
unsigned int range;
vec_3D spot;
switch (ship_tactic[obj])
{
case look_out:
approach_cruise_speed(obj);
if( !scan_and_lock(obj,NORMAL_SCANNER,approach_target) )
if( dist_from_home(obj) > PATROL_RADIUS )
reset_tactic(obj,head_home);
break;
case head_home:
approach_cruise_speed(obj);
if( !scan_and_lock(obj,NORMAL_SCANNER,approach_target) )
{
ship_vs_point(obj,&ship_mission_spot[obj]);
if( target_range<WANDER_RADIUS )
reset_tactic(obj,look_out);
else
{
// what exactly does this do? -KLD
point_ship_at_point(obj,&ship_mission_spot[obj]);
trim_goals(obj,7);
}
}
break;
case approach_target:
approach_full_speed(obj);
if( unactive(target) )
{
if( !scan_and_lock(obj,NORMAL_SCANNER,approach_target) )
alter_tactic(obj,look_out);
}
else
{
ship_vs_ship(obj,target);
if( target_range<APPROACH_RANGE )
init_formation_burst(obj);
else
if( no_goal(obj) )
point_ship_at_object(obj,target);
}
break;
case NONE: reset_tactic(obj,approach_target); break;
default: fail(obj);
}
}
void kilrathi_patrol (int obj)
{
switch( ship_objective[obj] )
{
case break_formation: formation_burst(obj); break;
case hold_formation:
case wander: patrol_area(obj); break;
case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
case NONE:
ship_objective[obj] = wander;
ship_tactic[obj] = approach_target;
break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
imperial_wingleader()
------------------------------------------------------------------------------
*/
imperial_wingleader (int obj)
{
kilrathi_patrol(obj); // there is no specialized Impeial leader
// intelligence yet... it may not be needed?
} /* imperial_wingleader() */
/*
------------------------------------------------------------------------------
reach_warp()
------------------------------------------------------------------------------
*/
#define TOWARD (65)
void cruise_to_destination(int obj)
{
int range;
// Don't move if you're too far away:
if( abandoned(obj,your_ship) ) return;
// Set speed according to presence of enemies:
if( (ship_turn[obj]&7)==6 )
ship_target[obj] = scan_for_enemy(obj,CAPITAL_SCANNER_RANGE);
if (ship_target[obj] == NONE)
approach_cruise_speed(obj);
else
{
get_facing_range_from_object(obj,ship_target[obj]);
if (facing_to_target > TOWARD)
approach_half_speed(obj); // slow when approaching enemies.
else
approach_full_speed(obj); // accelerate out from them.
}
// Check destination:
if ((ship_turn[obj]&7) == 2)
{
if (no_goal(obj))
point_ship_at_point(obj,&destination[obj]);
range = distance_from_point(obj,&destination[obj]);
if( range < NEAR_NAV )
{
flag_reached(Flight_path[ship_tmp_index[obj]]);
if (equ_vector(&destination[obj],&ship_mission_spot[obj]))
{
reset_tactic(obj,sit_still);
set_special(obj,kill_engines);
}
else
get_follow_point(obj,&destination[obj]);
}
}
}
#define WARP_OUT_RANGE (4000)
#define PREPARE_WARP_TIMER 10
void prepare_for_jump(int obj)
{
if( speed[obj]!=0 )
set_special(obj,stop_drift);
else
if (object_nearby(obj,your_ship,WARP_OUT_RANGE))
if (++ship_count[obj] > PREPARE_WARP_TIMER)
{
reset_tactic(obj,warp_out);
fire_afterburner(obj,STD_BURN);
}
}
#define ACCELERATION_TIMER 3
void accelerate_and_jump(int obj)
{
approach_full_speed(obj);
if (ship_count[obj]++ == ACCELERATION_TIMER)
warp(obj);
}
/////////////////////////////////////////////////////
void reach_warp (int obj)
{
switch (ship_tactic[obj])
{
case cruise: cruise_to_destination(obj); break;
case sit_still: prepare_for_jump(obj); break;
case warp_out: accelerate_and_jump(obj); break;
case NONE:
reset_tactic(obj,cruise);
get_first_follow_point(obj,&destination[obj]);
break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
warp_arrival()
------------------------------------------------------------------------------
*/
void arrive_from_warp(int obj)
{
int index = find_objective(nav_point,Current_action_sphere);
if (index != NONE) // Don't really need to go to that Nav Point...
{
visit(index);
if (Current_Objective == index)
set_next_destination();
}
unwarp(obj);
speed[obj] = IntToIntFract(data[type[obj]].max_velocity);
fix_velocity(obj);
reset_mission_type(obj,patrol);
}
void warp_arrival(int obj)
{
if( ship_tactic[obj]==warp_in )
arrive_from_warp(obj);
else
reset_tactic(obj,warp_in);
}
/*
------------------------------------------------------------------------------
escort_mission()
------------------------------------------------------------------------------
*/
#define ESCORT_RESUMED (1000)
void return_to_buddy(int obj, int buddy)
{
approach_cruise_speed(obj);
if( no_goal(obj) )
point_ship_at_object(obj,buddy);
if( distance_from_object(obj,buddy)<ESCORT_RESUMED )
{
reset_objective(obj,wander);
point_parallel(obj,buddy);
}
}
void escort_buddy(int obj, int buddy)
{
approach_ship_speed(obj,buddy);
if (no_goal(obj))
point_parallel(obj,buddy);
}
#define ESCORT_DANGER (3000)
#define ESCORT_DRIFT (5000) // This should be more than ESCORT_DANGER
#define ESCORT_RADIUS (1200)
void escort_mission(int obj)
{
int buddy = find_ship_index(ship_mission_ship[obj]);
if (unactive(buddy))
{
change_mission_type(obj,patrol);
return;
}
if( !(ship_turn[obj]&3) )
if( in_danger(buddy) )
if( target_range < ESCORT_DANGER )
engage(obj,target_ship,engage_enemy);
if (ship_objective[obj] != home_base)
if( (ship_turn[obj]&7)==4 )
if (distance_from_object(obj,buddy) > ESCORT_DRIFT)
reset_objective(obj,home_base);
switch( ship_objective[obj] )
{
case wander: escort_buddy(obj,buddy); break;
case home_base: return_to_buddy(obj,buddy); break;
case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
case NONE: reset_objective(obj,wander); break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
strike_mission()
------------------------------------------------------------------------------
*/
void check_goal(int obj)
{
vec_3D xyz;
if( gone_ship(ship_mission_ship[obj]) )
reset_mission_type(obj,rout);
else
{
warn("This shouldn't happen!",0);
locate_ship(ship_mission_ship[obj],&xyz);
if (no_goal(obj))
point_ship_at_point(obj,&xyz);
approach_full_speed(obj);
}
}
void streak_toward(int obj, int goal, int range)
{
if( no_goal(obj) )
if( random(100)<95 )
point_ship_at_object(obj,goal);
else
veer_random(obj,20);
if( range>2000 && normal_speed(obj) )
fire_afterburner(obj,STD_BURN);
else
approach_full_speed(obj);
}
#define ENGAGE_RANGE (5000) // just a bit shorter than normal...
void approach_and_engage(int obj, int goal)
{
unsigned int range, possible_range;
int possible_target;
range = distance_from_object(obj,goal);
if( class[goal]!=futurion && evaluate_damage(obj)>DETERMINATION && range>ENGAGE_RANGE )
streak_toward(obj,goal,range);
else
{
possible_target = scan_for_enemy(obj,10000);
possible_range = target_range;
if( possible_target!=NONE && (possible_range*3<range || class[goal]==futurion) )
{
init_formation_burst(obj);
ship_target[obj] = possible_target;
}
else
if( range<ENGAGE_RANGE )
engage(obj,goal,destroy_ship);
else
streak_toward(obj,goal,range);
}
}
void strike_mission (int obj)
{
int goal = find_ship_index(ship_mission_ship[obj]);
// Check status of STRIKE objective ship...
if( goal==NONE && class[goal]!=futurion )
check_goal(obj);
switch( ship_objective[obj] ) {
case break_formation: formation_burst(obj); break;
case hold_formation:
case home_base: approach_and_engage(obj,goal); break;
case engage_enemy: maneuvering(obj,check_destroy_target(obj)); break;
case destroy_ship: maneuvering(obj,check_destroy_target(obj)); break;
case NONE:reset_objective(obj,home_base); break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
defend_mission()
------------------------------------------------------------------------------
*/
#define DEFEND_RADIUS (6000)
#define DEFEND_RESUMED (5000) // must be less than the defend radius.
void return_to_master(int obj, int master)
{
int range = distance_from_object(obj,master);
streak_toward(obj,master,range);
if( range<DEFEND_RESUMED )
{
reset_objective(obj,wander);
point_perpendicular(obj,master);
}
}
void defend_mission (int obj)
{
int master = find_ship_index(ship_mission_ship[obj]);
if( master==NONE )
{
change_mission_type(obj,patrol);
return;
}
if( ship_turn[obj]%10 == 0 )
if( in_danger(master) )
if( target_range<DEFEND_RADIUS )
{
if( ship_objective[obj]!=engage_enemy)
engage(obj,target_ship,engage_enemy);
}
if( ship_objective[obj]!=home_base )
if ((ship_turn[obj]&7) == 4)
if (distance_from_object(obj,master) > 10000)
reset_objective(obj,home_base);
switch( ship_objective[obj] )
{
case wander:
ship_target[obj] = scan_for_enemy(obj,7000);
if( ship_target[obj]!=NONE )
engage(obj,ship_target[obj],engage_enemy);
else
{
approach_half_speed(obj);
if (no_goal(obj))
point_perpendicular(obj,master);
}
break;
case home_base: return_to_master(obj,master); break;
case engage_enemy: maneuvering(obj,check_engage_target(obj)); break;
case NONE: reset_objective(obj,wander); break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
rendezvous_mission()
RENDEZVOUS missions are for Ships travelling to another Ship, usually
a Capital Ship, that it will be set to DEFEND as a new mission type...
------------------------------------------------------------------------------
*/
rendezvous_mission (int obj)
{
int goal = find_ship_index(ship_mission_ship[obj]);
if (unactive(goal))
{
change_mission_type(obj,patrol);
return;
}
switch (ship_objective[obj])
{
case (reach_ship):
if (attacker_in_range(obj,3500)) // only very close attackers
engage(obj,target_ship,engage_enemy);
if (IS_NEAR(obj,goal,2500))
{
reset_mission_type(obj,defend);
return;
}
if (attacker_in_range(goal,9000))
approach_full_speed(obj);
else
approach_cruise_speed(obj);
if (no_goal(obj))
point_ship_at_object(obj,goal);
break;
case (engage_enemy): maneuvering(obj,check_engage_target(obj)); break;
default: reset_objective(obj,reach_ship);
}
} /* rendezvous_mission() */
/*
------------------------------------------------------------------------------
ship_intelligence()
------------------------------------------------------------------------------
*/
void ship_intelligence (int obj)
{
int target;
if( regulate_turn(obj) ) return;
switch (ship_mission_type[obj])
{
case (patrol):
if( side==Imperial )
imperial_wingleader(obj);
else
kilrathi_patrol(obj);
break;
case (escort): escort_mission(obj); break;
case (strike): strike_mission(obj); break;
case (defend): defend_mission(obj); break;
case (wingman): wingman_mission(obj); break;
case (rendezvous): rendezvous_mission(obj); break;
case (rout): run_away(obj); break;
case NONE: inherit_leader_mission(obj); break;
default: fail(obj);
}
}
/*
------------------------------------------------------------------------------
capital_ship_intelligence()
------------------------------------------------------------------------------
*/
void mega_ship (int obj) // only used for the ralari. -KLD
{
int radius = MissionSpheres[Current_action_sphere].Radius>>1;
vec_3D center = MissionSpheres[Current_action_sphere].Center;
int range;
if (fire_turrets(obj))
{
ship_target[obj] = NONE;
approach_half_speed(obj);
}
else
approach_cruise_speed(obj);
range = distance_from_point(obj,¢er);
if (no_goal(obj))
if (range > radius-750)
if (range > radius)
point_ship_at_point(obj,¢er);
else
point_perpendicular_to_point(obj,¢er);
trim_goals(obj,5);
} /* mega_ship() */
void capital_ship_intelligence (int obj)
{
if (regulate_turn(obj))
return;
switch (ship_mission_type[obj])
{
case goto_warp: reach_warp(obj); break;
case warp_arrive: warp_arrival(obj); break;
case come_home: coming_home(obj); break;
case rout: run_away(obj); break;
case patrol: // well...? -KLD
default :
if (
type[obj] == Ralari ||
type[obj] == Fralthi
)
{
mega_ship(obj); // just testing for now... (pci)
return;
}
if (unactive( target_ship = ship_target[obj] ))
scan_for_enemy(obj,CAPITAL_SCANNER_RANGE);
switch (ship_tactic[obj])
{
case (self_defense):
approach_full_speed(obj);
if( unactive(ship_target[obj]) )
{
select_target(obj);
if( unactive(ship_target[obj]) )
reset_tactic(obj,NONE); // seems reasonable, but... -KLD
}
else
fire_turrets(obj);
break;
default :
// How would target_ship ever be set to anything here? -KLD
if (target_ship != NONE)
{
approach_full_speed(obj);
ship_tactic[obj] = self_defense;
ship_target[obj] = target_ship;
fire_turrets(obj);
}
else // follow Bee Line in
approach_cruise_speed(obj); // ship's current dir
}
}
}
/*
------------------------------------------------------------------------------
futurion_intelligence()
this routine holds off an object from taking on its true
class until your_ship is nearby and looking toward it...
the proper class should be stored in object_counter[un_obj]
------------------------------------------------------------------------------
*/
futurion_intelligence (int un_obj)
{
#define MUST_ARRIVE 49
ship_vs_ship(your_ship,un_obj); // Velveteen Rabbit...
if (
(++action_count[un_obj] > MUST_ARRIVE) ||
(target_range < 7000) && (facing_to_target > 80)
)
if (one_in(8))
class[un_obj] = object_counter[un_obj]; // become a REAL class
} /* futurion_intelligence() */
/*
------------------------------------------------------------------------------
mine_intelligence()
------------------------------------------------------------------------------
*/
void mine_intelligence (int obj)
{
int target_ship;
int distance;
if (object_counter[obj] != 0) /* can't explode until active! */
return;
/*-- Check to see if any ships are in the vincinity of the mine --*/
for (target_ship = your_ship; target_ship <= last_ship; target_ship++)
{
if (obj != target_ship)
{
if (class[target_ship] == ship)
{
if (distance_from_object(obj, target_ship) < MINE_DETONATION_RANGE)
{
/*-- If ship is too close to mine, it explodes --*/
explode(obj);
return;
}
}
}
}
} /* mine_intelligence() */
/*
------------------------------------------------------------------------------
heat_seeking_missile_intelligence()
------------------------------------------------------------------------------
*/
void heat_seeking_missile_intelligence (int obj)
{
int exhaust_heat, target_ship, targ;
/*--------Intelligence used for heat seeking missiles ---------*/
// This is implemented wrong. Heat seekers need enemy to be facing away... -KLD
if (facing_to_target < 0 || ship_target[obj] == NONE)
{
/*-- If lock is lost on the target, look for closest "hotest" target --*/
ship_target[obj] = NONE;
viable_target_index = 0;
for (target_ship = your_ship; target_ship <= last_ship; target_ship++)
{
if( obj!=target_ship && class[target_ship]==ship )
{
get_facing_range_from_object(obj, target_ship);
if( target_range<MISSILE_SCAN_RANGE && facing_to_target>0 && target_facing<0 )
{
/*-- If ship's engines are in missile's lock arc --*/
viable_target[viable_target_index] = target_ship;
viable_target_dist[viable_target_index++] = target_range;
}
}
}
sort_viable_target_list();
if (viable_target_index >0)
{
for (exhaust_heat = hot; exhaust_heat > cold; exhaust_heat--)
{
for (targ=0;targ<viable_target_index;targ++)
{
if (exhaust_hot[viable_target[targ]] == exhaust_heat)
{
/*-- Found a new target to lock onto --*/
ship_target[obj] = viable_target[targ];
exhaust_heat = cold;
break;
}
}
}
}
if (ship_target[obj] == NONE)
explode(obj);
}
else
{
point_ship(obj, 0, &to_target);
speed[obj] = IntToIntFract(data[type[obj]].max_velocity+10);
}
} /* heat_seeking_missile_intelligence() */
/*
------------------------------------------------------------------------------
FF_missile_intelligence()
------------------------------------------------------------------------------
*/
void FF_missile_intelligence (int obj)
{
int target_ship;
if (ship_tactic[obj] == ram)
{
/*-- Missile is set to ram, after rockets have been ignited --*/
if (ship_target[obj] == NONE)
{
/*-- Aquire a target for missile --*/
/*-- Find the closest foe for the FF_missile to lock onto --*/
viable_target_index = 0;
for (target_ship = your_ship; target_ship <= last_ship; target_ship++)
{
if (obj != target_ship)
{
if (class[target_ship] == ship)
{
if (side[target_ship] != side[parent[obj]] || communicator[target_ship] == BAD)
{
target_range = distance_from_object(obj, target_ship);
if (target_range < MISSILE_SCAN_RANGE)
{
/*-- If ship is close enough for missile to lock onto --*/
viable_target[viable_target_index] = target_ship;
viable_target_dist[viable_target_index++] = target_range;
}
}
}
}
}
sort_viable_target_list();
if (viable_target_index >0)
{
/*-- lock onto closest possible target --*/
ship_target[obj] = viable_target[0];
}
/* If to target aquired, repeat process next turn, until missile
self destructs */
}
else
{
point_ship(obj, 0, &to_target);
speed[obj] = IntToIntFract(data[type[obj]].max_velocity+10);
}
}
} /* FF_missile_intelligence() */
/* ------------------------ */
// PAUL! what is this garbage!!! -RKLD (pci) Testing capital ship firing
x ()
{
int it;
for (it=0; it<=ships; it++)
if (type[it] == Tigers_claw)
{
reset_mission_type(it,patrol);
ship_target[it] = your_ship;
side[it] = Kilrathi;
}
} /* x() */