WC1 Demo including Source Code ???

delMar

Rear Admiral
I just downloaded the WC1 demo from here:
https://www.wcnews.com/wcpedia/Category:Downloads#wcks

I haven't played it yet, but in wc1demo2.zip I found a file called brains.c
And it is what the file extension promised: a source file. The comment at the start of the file says NPC PILOT INTELLIGENCE CODE MODULE
As the search function on the forums did not yield any previous threads on this, I thought sharing it with you won't hurt. Most interesting bit for me: all the different mission types are now known for sure (escort, etc)

Code:
/*
  ==========================================================================
  |                                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,&center);

    if (no_goal(obj))
        if (range > radius-750)
            if (range > radius)
                point_ship_at_point(obj,&center);
            else
                point_perpendicular_to_point(obj,&center);

    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() */

I especially like the
// PAUL! what is this garbage!!! -RKLD (pci) Testing capital ship firing
on bottom :-D


Has anybody played this? What missions are in there?
 
Last edited by a moderator:
That code is cleaner than I'd expect for such an old title, but it's still it's setting off my OCD
 
Very nice. It's funny to see the Confederation being called "Imperial".
Ha, also one of the first things I recognized.

This is pretty old, they are still calling it "Wingleader"!
Yes, and it's also still incomplete, as the patrol case in method capital_ship_intelligence still holds no implementation.

That code is cleaner than I'd expect for such an old title
Definitely! I was also quite surprised at how readable it really is.


Ideas who KLD and pci are, anyone?
 
Nice, give me a pot of coffee and several hundred lines of source and i am happy. Yes i know, i am just a simple man. ^^ I hope my wife will never find this forum... :-D

Have they forgot to remove this file from the demo?
 
Nice, give me a pot of coffee and several hundred lines of source and i am happy. Yes i know, i am just a simple man. ^^ I hope my wife will never find this forum... :-D

Have they forgot to remove this file from the demo?

Haha, I definitely agree on every single word!

No idea how that file slipped in. I just wish there was more of that...
 
Has anybody played this? What missions are in there?

It's pretty easy to get the demo running, but like the WC2 demo, it's not playable. Just unzip both parts into a folder, fire up DOSBox and launch wing.exe. It'll turn into a five minute scripted set of events, which you can also watch via YouTube:
 
Probably not as it includes the game.h header file which is missing from the archive.
That would just be the headers for all the functions, unless some specific algorithms are in there, and can be easily recreated if so. Only one way to find out though...

[edit]Yup, lots of function's and variable's missing from the code.[/edit]

Hopes, dashed... :(
 
Last edited:
Back
Top