diff --git a/common/main/ai.h b/common/main/ai.h index 455308b3d..f85f18d0d 100644 --- a/common/main/ai.h +++ b/common/main/ai.h @@ -270,7 +270,6 @@ extern void special_reactor_stuff(void); #endif #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) -extern ai_local Ai_local_info[MAX_OBJECTS]; extern point_seg Point_segs[MAX_POINT_SEGS]; #endif extern point_seg *Point_segs_free_ptr; diff --git a/common/main/aistruct.h b/common/main/aistruct.h index cfd2f1466..7969691b2 100644 --- a/common/main/aistruct.h +++ b/common/main/aistruct.h @@ -159,6 +159,45 @@ enum player_awareness_type_t // This is the stuff that is permanent for an AI object. #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II) +// Rather temporal AI stuff. +struct ai_local +{ +// These used to be bytes, changed to ints so I could set watchpoints on them. +#if defined(DXX_BUILD_DESCENT_I) + sbyte player_awareness_type; // type of awareness of player + sbyte retry_count; // number of retries in physics last time this object got moved. + sbyte consecutive_retries; // number of retries in consecutive frames (ie, without a retry_count of 0) + sbyte mode; // current mode within behavior + sbyte previous_visibility; // Visibility of player last time we checked. + sbyte rapidfire_count; // number of shots fired rapidly + short goal_segment; // goal segment for current path + fix last_see_time, last_attack_time; // For sound effects, time at which player last seen, attacked + fix wait_time; // time in seconds until something happens, mode dependent +#elif defined(DXX_BUILD_DESCENT_II) + int player_awareness_type; // type of awareness of player + int retry_count; // number of retries in physics last time this object got moved. + int consecutive_retries; // number of retries in consecutive frames (ie, without a retry_count of 0) + int mode; // current mode within behavior + int previous_visibility; // Visibility of player last time we checked. + int rapidfire_count; // number of shots fired rapidly + int goal_segment; // goal segment for current path + fix next_action_time; // time in seconds until something happens, mode dependent +#endif + fix next_fire; // time in seconds until can fire again +#if defined(DXX_BUILD_DESCENT_II) + fix next_fire2; // time in seconds until can fire again from second weapon +#endif + fix player_awareness_time; // time in seconds robot will be aware of player, 0 means not aware of player + fix time_since_processed; // time since this robot last processed in do_ai_frame + fix64 time_player_seen; // absolute time in seconds at which player was last seen, might cause to go into follow_path mode + fix64 time_player_sound_attacked; // absolute time in seconds at which player was last seen with visibility of 2. + fix64 next_misc_sound_time; // absolute time in seconds at which this robot last made an angry or lurking sound. + vms_angvec goal_angles[MAX_SUBMODELS]; // angles for each subobject + vms_angvec delta_angles[MAX_SUBMODELS]; // angles for each subobject + sbyte goal_state[MAX_SUBMODELS]; // Goal state for this sub-object + sbyte achieved_state[MAX_SUBMODELS]; // Last achieved state +}; + struct ai_static { ubyte behavior; // @@ -180,6 +219,7 @@ struct ai_static int danger_laser_signature; fix64 dying_start_time; // Time at which this robot started dying. #endif + ai_local ail; }; // Same as above but structure Savegames/Multiplayer objects expect @@ -205,46 +245,6 @@ struct ai_static_rw #endif } __pack__; -// Rather temporal AI stuff. -struct ai_local -{ -// These used to be bytes, changed to ints so I could set watchpoints on them. -#if defined(DXX_BUILD_DESCENT_I) - sbyte player_awareness_type; // type of awareness of player - sbyte retry_count; // number of retries in physics last time this object got moved. - sbyte consecutive_retries; // number of retries in consecutive frames (ie, without a retry_count of 0) - sbyte mode; // current mode within behavior - sbyte previous_visibility; // Visibility of player last time we checked. - sbyte rapidfire_count; // number of shots fired rapidly - short goal_segment; // goal segment for current path - fix last_see_time, last_attack_time; // For sound effects, time at which player last seen, attacked - - fix wait_time; // time in seconds until something happens, mode dependent -#elif defined(DXX_BUILD_DESCENT_II) - int player_awareness_type; // type of awareness of player - int retry_count; // number of retries in physics last time this object got moved. - int consecutive_retries; // number of retries in consecutive frames (ie, without a retry_count of 0) - int mode; // current mode within behavior - int previous_visibility; // Visibility of player last time we checked. - int rapidfire_count; // number of shots fired rapidly - int goal_segment; // goal segment for current path - fix next_action_time; // time in seconds until something happens, mode dependent -#endif - fix next_fire; // time in seconds until can fire again -#if defined(DXX_BUILD_DESCENT_II) - fix next_fire2; // time in seconds until can fire again from second weapon -#endif - fix player_awareness_time; // time in seconds robot will be aware of player, 0 means not aware of player - fix64 time_player_seen; // absolute time in seconds at which player was last seen, might cause to go into follow_path mode - fix64 time_player_sound_attacked; // absolute time in seconds at which player was last seen with visibility of 2. - fix64 next_misc_sound_time; // absolute time in seconds at which this robot last made an angry or lurking sound. - fix time_since_processed; // time since this robot last processed in do_ai_frame - vms_angvec goal_angles[MAX_SUBMODELS]; // angles for each subobject - vms_angvec delta_angles[MAX_SUBMODELS]; // angles for each subobject - sbyte goal_state[MAX_SUBMODELS]; // Goal state for this sub-object - sbyte achieved_state[MAX_SUBMODELS]; // Last achieved state -}; - // Same as above but structure Savegames expect struct ai_local_rw { diff --git a/d2x-rebirth/main/escort.cpp b/d2x-rebirth/main/escort.cpp index 9f4739b0e..529a10811 100644 --- a/d2x-rebirth/main/escort.cpp +++ b/d2x-rebirth/main/escort.cpp @@ -699,9 +699,8 @@ void say_escort_goal(int goal_num) static void escort_create_path_to_goal(object *objp) { int goal_seg = -1; - int objnum = objp-Objects; ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &objp->ctype.ai_info.ail; if (Escort_special_goal != -1) Escort_goal_object = Escort_special_goal; @@ -991,9 +990,8 @@ static void do_buddy_dude_stuff(void) // Called every frame (or something). void do_escort_frame(object *objp, fix dist_to_player, int player_visibility) { - int objnum = objp-Objects; ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &objp->ctype.ai_info.ail; Buddy_objnum = objp-Objects; @@ -1101,8 +1099,7 @@ void invalidate_escort_goal(void) // ------------------------------------------------------------------------------------------------- void do_snipe_frame(object *objp, fix dist_to_player, int player_visibility, vms_vector *vec_to_player) { - int objnum = objp-Objects; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &objp->ctype.ai_info.ail; fix connected_distance; if (dist_to_player > F1_0*500) @@ -1224,8 +1221,7 @@ static const fix Thief_wait_times[NDL] = {F1_0*30, F1_0*25, F1_0*20, F1_0*15, F1 // ------------------------------------------------------------------------------------------------- void do_thief_frame(object *objp, fix dist_to_player, int player_visibility, vms_vector *vec_to_player) { - int objnum = objp-Objects; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &objp->ctype.ai_info.ail; fix connected_distance; if ((Current_level_num < 0) && (Re_init_thief_time < GameTime64)) { @@ -1307,8 +1303,9 @@ void do_thief_frame(object *objp, fix dist_to_player, int player_visibility, vms ailp->player_awareness_type = 0; if (d_rand() > 8192) { create_n_segment_path(objp, 10, ConsoleObject->segnum); - Ai_local_info[objp-Objects].next_action_time = Thief_wait_times[Difficulty_level]/2; - Ai_local_info[objp-Objects].mode = AIM_THIEF_RETREAT; + ai_local *ailp = &objp->ctype.ai_info.ail; + ailp->next_action_time = Thief_wait_times[Difficulty_level]/2; + ailp->mode = AIM_THIEF_RETREAT; } } else if (ailp->next_action_time < 0) { // This forces him to create a new path every second. @@ -1323,8 +1320,9 @@ void do_thief_frame(object *objp, fix dist_to_player, int player_visibility, vms fix dot = vm_vec_dot(vec_to_player, &ConsoleObject->orient.fvec); if (dot < -F1_0/2) { // Looking at least towards thief, so thief will run! create_n_segment_path(objp, 10, ConsoleObject->segnum); - Ai_local_info[objp-Objects].next_action_time = Thief_wait_times[Difficulty_level]/2; - Ai_local_info[objp-Objects].mode = AIM_THIEF_RETREAT; + ai_local *ailp = &objp->ctype.ai_info.ail; + ailp->next_action_time = Thief_wait_times[Difficulty_level]/2; + ailp->mode = AIM_THIEF_RETREAT; } } ai_turn_towards_vector(vec_to_player, objp, F1_0/4); @@ -1472,7 +1470,8 @@ static int attempt_to_steal_item_3(object *objp, int player_num) { int i; - if (Ai_local_info[objp-Objects].mode != AIM_THIEF_ATTACK) + ai_local *ailp = &objp->ctype.ai_info.ail; + if (ailp->mode != AIM_THIEF_ATTACK) return 0; // First, try to steal equipped items. @@ -1560,8 +1559,9 @@ int attempt_to_steal_item(object *objp, int player_num) break; } create_n_segment_path(objp, 10, ConsoleObject->segnum); - Ai_local_info[objp-Objects].next_action_time = Thief_wait_times[Difficulty_level]/2; - Ai_local_info[objp-Objects].mode = AIM_THIEF_RETREAT; + ai_local *ailp = &objp->ctype.ai_info.ail; + ailp->next_action_time = Thief_wait_times[Difficulty_level]/2; + ailp->mode = AIM_THIEF_RETREAT; if (rval) { PALETTE_FLASH_ADD(30, 15, -20); update_laser_weapon_info(); diff --git a/similar/main/ai.cpp b/similar/main/ai.cpp index 3584e1530..4ca4fa7e8 100644 --- a/similar/main/ai.cpp +++ b/similar/main/ai.cpp @@ -136,7 +136,6 @@ boss_gate_segment_array_t Boss_gate_segs; // ---------- John: These variables must be saved as part of gamesave. -------- int Ai_initialized = 0; int Overall_agitation; -ai_local Ai_local_info[MAX_OBJECTS]; point_seg Point_segs[MAX_POINT_SEGS]; point_seg *Point_segs_free_ptr = Point_segs; ai_cloak_info Ai_cloak_info[MAX_AI_CLOAK_INFO]; @@ -413,9 +412,8 @@ void ai_init_boss_for_ship(void) // initial_mode == -1 means leave mode unchanged. void init_ai_object(object *objp, int behavior, int hide_segment) { - int objnum = objp-Objects; ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &objp->ctype.ai_info.ail; memset(ailp, 0, sizeof(ai_local)); @@ -695,12 +693,10 @@ int player_is_visible_from_object(object *objp, vms_vector *pos, fix field_of_vi // Return 1 if animates, else return 0 static int do_silly_animation(object *objp) { - int objnum = objp-Objects; const jointpos *jp_list; int robot_type, gun_num, robot_state, num_joint_positions; polyobj_info *pobj_info = &objp->rtype.pobj_info; ai_static *aip = &objp->ctype.ai_info; - // ai_local *ailp = &Ai_local_info[objnum]; int num_guns, at_goal; int attack_type; int flinch_attack_scale = 1; @@ -742,7 +738,8 @@ static int do_silly_animation(object *objp) if (jp->p != pobjp->p) { if (gun_num == 0) at_goal = 0; - Ai_local_info[objnum].goal_angles[jointnum].p = jp->p; + ai_local *ailp = &objp->ctype.ai_info.ail; + ailp->goal_angles[jointnum].p = jp->p; delta_angle = jp->p - pobjp->p; if (delta_angle >= F1_0/2) @@ -757,13 +754,14 @@ static int do_silly_animation(object *objp) if (flinch_attack_scale != 1) delta_2 *= flinch_attack_scale; - Ai_local_info[objnum].delta_angles[jointnum].p = delta_2/DELTA_ANG_SCALE; // complete revolutions per second + ailp->delta_angles[jointnum].p = delta_2/DELTA_ANG_SCALE; // complete revolutions per second } if (jp->b != pobjp->b) { if (gun_num == 0) at_goal = 0; - Ai_local_info[objnum].goal_angles[jointnum].b = jp->b; + ai_local *ailp = &objp->ctype.ai_info.ail; + ailp->goal_angles[jointnum].b = jp->b; delta_angle = jp->b - pobjp->b; if (delta_angle >= F1_0/2) @@ -778,13 +776,14 @@ static int do_silly_animation(object *objp) if (flinch_attack_scale != 1) delta_2 *= flinch_attack_scale; - Ai_local_info[objnum].delta_angles[jointnum].b = delta_2/DELTA_ANG_SCALE; // complete revolutions per second + ailp->delta_angles[jointnum].b = delta_2/DELTA_ANG_SCALE; // complete revolutions per second } if (jp->h != pobjp->h) { if (gun_num == 0) at_goal = 0; - Ai_local_info[objnum].goal_angles[jointnum].h = jp->h; + ai_local *ailp = &objp->ctype.ai_info.ail; + ailp->goal_angles[jointnum].h = jp->h; delta_angle = jp->h - pobjp->h; if (delta_angle >= F1_0/2) @@ -799,13 +798,13 @@ static int do_silly_animation(object *objp) if (flinch_attack_scale != 1) delta_2 *= flinch_attack_scale; - Ai_local_info[objnum].delta_angles[jointnum].h = delta_2/DELTA_ANG_SCALE; // complete revolutions per second + ailp->delta_angles[jointnum].h = delta_2/DELTA_ANG_SCALE; // complete revolutions per second } } if (at_goal) { //ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; ailp->achieved_state[gun_num] = ailp->goal_state[gun_num]; if (ailp->achieved_state[gun_num] == AIS_RECO) ailp->goal_state[gun_num] = AIS_FIRE; @@ -829,7 +828,6 @@ static int do_silly_animation(object *objp) // Delta orientation of object is at: ai_info.delta_angles static void ai_frame_animation(object *objp) { - int objnum = objp-Objects; int joint; int num_joints; @@ -839,8 +837,9 @@ static void ai_frame_animation(object *objp) fix delta_to_goal; fix scaled_delta_angle; vms_angvec *curangp = &objp->rtype.pobj_info.anim_angles[joint]; - vms_angvec *goalangp = &Ai_local_info[objnum].goal_angles[joint]; - vms_angvec *deltaangp = &Ai_local_info[objnum].delta_angles[joint]; + ai_local *ailp = &objp->ctype.ai_info.ail; + vms_angvec *goalangp = &ailp->goal_angles[joint]; + vms_angvec *deltaangp = &ailp->delta_angles[joint]; delta_to_goal = goalangp->p - curangp->p; if (delta_to_goal > 32767) @@ -934,7 +933,7 @@ static void set_next_fire_time(object *objp, ai_local *ailp, robot_info *robptr, // If player is cloaked, then robot probably didn't actually collide, deal with that here. void do_ai_robot_hit_attack(object *robot, object *playerobj, vms_vector *collision_point) { - ai_local *ailp = &Ai_local_info[robot-Objects]; + ai_local *ailp = &robot->ctype.ai_info.ail; robot_info *robptr = &Robot_info[get_robot_id(robot)]; //#ifndef NDEBUG @@ -1064,7 +1063,7 @@ static int lead_player(object *objp, vms_vector *fire_point, vms_vector *believe static void ai_fire_laser_at_player(object *obj, vms_vector *fire_point, int gun_num, vms_vector *believed_player_pos) { int objnum = obj-Objects; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &obj->ctype.ai_info.ail; robot_info *robptr = &Robot_info[get_robot_id(obj)]; vms_vector fire_vec; vms_vector bpp_diff; @@ -1573,7 +1572,7 @@ static void do_firing_stuff(object *obj, int player_visibility, vms_vector *vec_ fix dot = vm_vec_dot(&obj->orient.fvec, vec_to_player); if ((dot >= 7*F1_0/8) || (Players[Player_num].flags & PLAYER_FLAGS_CLOAKED)) { ai_static *aip = &obj->ctype.ai_info; - ai_local *ailp = &Ai_local_info[obj-Objects]; + ai_local *ailp = &obj->ctype.ai_info.ail; switch (aip->GOAL_STATE) { case AIS_NONE: @@ -1612,7 +1611,7 @@ void do_ai_robot_hit(object *objp, int type) objp->ctype.ai_info.SUBMODE = AISM_GOHIDE; break; case AIM_STILL: - Ai_local_info[objp-Objects].mode = AIM_CHASE_OBJECT; + objp->ctype.ai_info.ail.mode = AIM_CHASE_OBJECT; break; #elif defined(DXX_BUILD_DESCENT_II) case AIB_STILL: @@ -1624,14 +1623,15 @@ void do_ai_robot_hit(object *objp, int type) r = d_rand(); // 1/8 time, charge player, 1/4 time create path, rest of time, do nothing + ai_local *ailp = &objp->ctype.ai_info.ail; if (r < 4096) { create_path_to_player(objp, 10, 1); objp->ctype.ai_info.behavior = AIB_STATION; objp->ctype.ai_info.hide_segment = objp->segnum; - Ai_local_info[objp-Objects].mode = AIM_CHASE_OBJECT; + ailp->mode = AIM_CHASE_OBJECT; } else if (r < 4096+8192) { create_n_segment_path(objp, d_rand()/8192 + 2, -1); - Ai_local_info[objp-Objects].mode = AIM_FOLLOW_PATH; + ailp->mode = AIM_FOLLOW_PATH; } break; } @@ -1824,9 +1824,9 @@ int ai_door_is_openable(object *objp, segment *segp, int sidenum) // It's only valid to think that if the player is going to get him through. But if he's // going to the player, the player is probably on the opposite side. if (objp == NULL) - ailp_mode = Ai_local_info[Buddy_objnum].mode; + ailp_mode = Objects[Buddy_objnum].ctype.ai_info.ail.mode; else - ailp_mode = Ai_local_info[objp-Objects].mode; + ailp_mode = objp->ctype.ai_info.ail.mode; // -- if (Buddy_got_stuck) { if (ailp_mode == AIM_GOTO_PLAYER) { @@ -2244,11 +2244,12 @@ static void teleport_boss(object *objp) digi_kill_sound_linked_to_object( objp-Objects); // After a teleport, boss can fire right away. - Ai_local_info[objp-Objects].next_fire = 0; + ai_local *ailp = &objp->ctype.ai_info.ail; + ailp->next_fire = 0; #if defined(DXX_BUILD_DESCENT_I) digi_link_sound_to_object2( SOUND_BOSS_SHARE_SEE, objp-Objects, 1, F1_0, F1_0*512 ); // F1_0*512 means play twice as loud #elif defined(DXX_BUILD_DESCENT_II) - Ai_local_info[objp-Objects].next_fire2 = 0; + ailp->next_fire2 = 0; digi_link_sound_to_object2( Robot_info[get_robot_id(objp)].see_sound, objp-Objects, 1, F1_0, F1_0*512 ); // F1_0*512 means play twice as loud #endif @@ -2925,7 +2926,7 @@ static void make_nearby_robot_snipe(void) if ((objp->type == OBJ_ROBOT) && (get_robot_id(objp) != ROBOT_BRAIN)) { if ((objp->ctype.ai_info.behavior != AIB_SNIPE) && (objp->ctype.ai_info.behavior != AIB_RUN_FROM) && !Robot_info[get_robot_id(objp)].boss_flag && !robot_is_companion(robptr)) { objp->ctype.ai_info.behavior = AIB_SNIPE; - Ai_local_info[objnum].mode = AIM_SNIPE_ATTACK; + objp->ctype.ai_info.ail.mode = AIM_SNIPE_ATTACK; return; } } @@ -2956,7 +2957,7 @@ void do_ai_frame(object *obj) { int objnum = obj-Objects; ai_static *aip = &obj->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &obj->ctype.ai_info.ail; fix dist_to_player; vms_vector vec_to_player; fix dot; @@ -4271,14 +4272,15 @@ static void set_player_awareness_all(void) for (i=0; i<=Highest_object_index; i++) if (Objects[i].type == OBJ_ROBOT && Objects[i].control_type == CT_AI) { - if (New_awareness[Objects[i].segnum] > Ai_local_info[i].player_awareness_type) { - Ai_local_info[i].player_awareness_type = New_awareness[Objects[i].segnum]; - Ai_local_info[i].player_awareness_time = PLAYER_AWARENESS_INITIAL_TIME; + ai_local *ailp = &Objects[i].ctype.ai_info.ail; + if (New_awareness[Objects[i].segnum] > ailp->player_awareness_type) { + ailp->player_awareness_type = New_awareness[Objects[i].segnum]; + ailp->player_awareness_time = PLAYER_AWARENESS_INITIAL_TIME; } #if defined(DXX_BUILD_DESCENT_II) // Clear the bit that says this robot is only awake because a camera woke it up. - if (New_awareness[Objects[i].segnum] > Ai_local_info[i].player_awareness_type) + if (New_awareness[Objects[i].segnum] > ailp->player_awareness_type) Objects[i].ctype.ai_info.SUB_FLAGS &= ~SUB_FLAGS_CAMERA_AWAKE; #endif } @@ -4316,7 +4318,7 @@ static void dump_ai_objects_all() for (objnum=0; objnum <= Highest_object_index; objnum++) { object *objp = &Objects[objnum]; ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &objp->ctype.ai_info.ail; fix dist_to_player; dist_to_player = vm_vec_dist(&objp->pos, &ConsoleObject->pos); @@ -4476,11 +4478,11 @@ int ai_save_state(PHYSFS_file *fp) PHYSFS_write(fp, &Ai_initialized, sizeof(int), 1); PHYSFS_write(fp, &Overall_agitation, sizeof(int), 1); - //PHYSFS_write(fp, Ai_local_info, sizeof(ai_local) * MAX_OBJECTS, 1); for (i = 0; i < MAX_OBJECTS; i++) { ai_local_rw ail_rw; - state_ai_local_to_ai_local_rw(&Ai_local_info[i], &ail_rw); + ai_local *ailp = &Objects[i].ctype.ai_info.ail; + state_ai_local_to_ai_local_rw(ailp, &ail_rw); PHYSFS_write(fp, &ail_rw, sizeof(ail_rw), 1); } PHYSFS_write(fp, Point_segs, sizeof(point_seg) * MAX_POINT_SEGS, 1); @@ -4655,8 +4657,8 @@ int ai_restore_state(PHYSFS_file *fp, int version, int swap) Ai_initialized = PHYSFSX_readSXE32(fp, swap); Overall_agitation = PHYSFSX_readSXE32(fp, swap); - range_for (ai_local &ail, Ai_local_info) - ai_local_read_swap(&ail, swap, fp); + range_for (object &obj, Objects) + ai_local_read_swap(&obj.ctype.ai_info.ail, swap, fp); point_seg_read_n_swap(Point_segs, MAX_POINT_SEGS, swap, fp); ai_cloak_info_read_n_swap(Ai_cloak_info, MAX_AI_CLOAK_INFO, swap, fp); tmptime32 = PHYSFSX_readSXE32(fp, swap); diff --git a/similar/main/aipath.cpp b/similar/main/aipath.cpp index 30de323b8..38371a665 100644 --- a/similar/main/aipath.cpp +++ b/similar/main/aipath.cpp @@ -625,7 +625,6 @@ void validate_all_paths(void) if (Objects[i].type == OBJ_ROBOT) { object *objp = &Objects[i]; ai_static *aip = &objp->ctype.ai_info; - //ai_local *ailp = &Ai_local_info[i]; if (objp->control_type == CT_AI) { if ((aip->hide_index != -1) && (aip->path_length > 0)) @@ -653,7 +652,7 @@ void validate_all_paths(void) void create_path_to_player(object *objp, int max_length, int safety_flag) { ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; int start_seg, end_seg; if (max_length == -1) @@ -709,7 +708,7 @@ void create_path_to_player(object *objp, int max_length, int safety_flag) void create_path_to_segment(object *objp, int goalseg, int max_length, int safety_flag) { ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; int start_seg, end_seg; if (max_length == -1) @@ -752,7 +751,7 @@ void create_path_to_segment(object *objp, int goalseg, int max_length, int safet void create_path_to_station(object *objp, int max_length) { ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; int start_seg, end_seg; if (max_length == -1) @@ -802,7 +801,7 @@ void create_path_to_station(object *objp, int max_length) void create_n_segment_path(object *objp, int path_length, int avoid_seg) { ai_static *aip=&objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; if (create_path_points(objp, objp->segnum, -2, Point_segs_free_ptr, &aip->path_length, path_length, 1, 0, avoid_seg) == -1) { Point_segs_free_ptr += aip->path_length; @@ -832,7 +831,7 @@ void create_n_segment_path(object *objp, int path_length, int avoid_seg) #if defined(DXX_BUILD_DESCENT_II) // If this robot is visible (player_visibility is not available) and it's running away, move towards outside with // randomness to prevent a stream of bots from going away down the center of a corridor. - if (Ai_local_info[objp-Objects].previous_visibility) { + if (ailp->previous_visibility) { if (aip->path_length) { int t_num_points = aip->path_length; move_towards_outside(&Point_segs[aip->hide_index], &t_num_points, objp, 1); @@ -893,7 +892,7 @@ void create_n_segment_path_to_door(object *objp, int path_length, int avoid_seg) static void create_path(object *objp) { ai_static *aip = &objp->ctype.ai_info; - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; int start_seg, end_seg; start_seg = objp->segnum; @@ -939,7 +938,7 @@ void ai_follow_path(object *objp, int player_visibility, vms_vector *vec_to_play robot_info *robptr = &Robot_info[get_robot_id(objp)]; #endif int forced_break, original_dir, original_index; - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; fix threshold_distance; @@ -1268,7 +1267,8 @@ void ai_path_set_orient_and_vel(object *objp, vms_vector *goal_point // If evading player, use highest difficulty level speed, plus something based on diff level max_speed = robptr->max_speed[Difficulty_level]; - if ((Ai_local_info[objp-Objects].mode == AIM_RUN_FROM_OBJECT) + ai_local *ailp = &objp->ctype.ai_info.ail; + if ((ailp->mode == AIM_RUN_FROM_OBJECT) #if defined(DXX_BUILD_DESCENT_II) || (objp->ctype.ai_info.behavior == AIB_SNIPE) #endif @@ -1316,13 +1316,13 @@ void ai_path_set_orient_and_vel(object *objp, vms_vector *goal_point vm_vec_scale(&norm_cur_vel, speed_scale); objp->mtype.phys_info.velocity = norm_cur_vel; - if ((Ai_local_info[objp-Objects].mode == AIM_RUN_FROM_OBJECT) + if ((ailp->mode == AIM_RUN_FROM_OBJECT) #if defined(DXX_BUILD_DESCENT_II) || (robot_is_companion(robptr) == 1) || (objp->ctype.ai_info.behavior == AIB_SNIPE) #endif ) { #if defined(DXX_BUILD_DESCENT_II) - if (Ai_local_info[objp-Objects].mode == AIM_SNIPE_RETREAT_BACKWARDS) { + if (ailp->mode == AIM_SNIPE_RETREAT_BACKWARDS) { if ((player_visibility) && (vec_to_player != NULL)) norm_vec_to_goal = *vec_to_player; else @@ -1470,7 +1470,7 @@ void attempt_to_resume_path(object *objp) #endif ) if (d_rand() > 8192) { - ai_local *ailp = &Ai_local_info[objp-Objects]; + ai_local *ailp = &objp->ctype.ai_info.ail; aip->hide_segment = objp->segnum; ailp->mode = AIM_STILL; @@ -1575,7 +1575,8 @@ static void player_path_set_orient_and_vel(object *objp, vms_vector *goal_point) dot = vm_vec_dot(&norm_vec_to_goal, &norm_fvec); #if defined(DXX_BUILD_DESCENT_II) - if (Ai_local_info[objp-Objects].mode == AIM_SNIPE_RETREAT_BACKWARDS) { + ai_local *ailp = &objp->ctype.ai_info.ail; + if (ailp->mode == AIM_SNIPE_RETREAT_BACKWARDS) { dot = -dot; } #endif diff --git a/similar/main/collide.cpp b/similar/main/collide.cpp index 0ff6fc975..e88084f5a 100644 --- a/similar/main/collide.cpp +++ b/similar/main/collide.cpp @@ -114,7 +114,7 @@ static void collide_robot_and_wall( object * robot, fix hitspeed, short hitseg, } #if defined(DXX_BUILD_DESCENT_II) else if ((robot_is_companion(robptr) == 1) && (Walls[wall_num].type == WALL_DOOR)) { - ai_local *ailp = &Ai_local_info[robot-Objects]; + ai_local *ailp = &robot->ctype.ai_info.ail; if ((ailp->mode == AIM_GOTO_PLAYER) || (Escort_special_goal == ESCORT_GOAL_SCRAM)) { if (Walls[wall_num].keys != KEY_NONE) { if (Walls[wall_num].keys & Players[Player_num].flags) @@ -1049,7 +1049,8 @@ static void collide_robot_and_player( object * robot, object * playerobj, vms_ve if (robot_is_thief(robptr)) { static fix64 Last_thief_hit_time; - if (Ai_local_info[robot-Objects].mode == AIM_THIEF_ATTACK) { + ai_local *ailp = &robot->ctype.ai_info.ail; + if (ailp->mode == AIM_THIEF_ATTACK) { Last_thief_hit_time = GameTime64; attempt_to_steal_item(robot, get_player_id(playerobj)); steal_attempt = 1; diff --git a/similar/main/fireball.cpp b/similar/main/fireball.cpp index a222f9214..a78c1ca20 100644 --- a/similar/main/fireball.cpp +++ b/similar/main/fireball.cpp @@ -941,8 +941,9 @@ int drop_powerup(int type, int id, int num, vms_vector *init_vel, vms_vector *po obj->shields = Robot_info[get_robot_id(obj)].strength; obj->ctype.ai_info.behavior = AIB_NORMAL; - Ai_local_info[obj-Objects].player_awareness_type = PA_WEAPON_ROBOT_COLLISION; - Ai_local_info[obj-Objects].player_awareness_time = F1_0*3; + ai_local *ailp = &obj->ctype.ai_info.ail; + ailp->player_awareness_type = PA_WEAPON_ROBOT_COLLISION; + ailp->player_awareness_time = F1_0*3; obj->ctype.ai_info.CURRENT_STATE = AIS_LOCK; obj->ctype.ai_info.GOAL_STATE = AIS_LOCK; obj->ctype.ai_info.REMOTE_OWNER = -1; diff --git a/similar/main/fuelcen.cpp b/similar/main/fuelcen.cpp index c1841fc31..cd6f3ed8b 100644 --- a/similar/main/fuelcen.cpp +++ b/similar/main/fuelcen.cpp @@ -353,9 +353,9 @@ object * create_morph_robot( segment *segp, vms_vector *object_pos, int object_i #if defined(DXX_BUILD_DESCENT_I) if (default_behavior == AIB_RUN_FROM) - Ai_local_info[objnum].mode = AIM_RUN_FROM_OBJECT; + obj->ctype.ai_info.ail.mode = AIM_RUN_FROM_OBJECT; #elif defined(DXX_BUILD_DESCENT_II) - Ai_local_info[objnum].mode = ai_behavior_to_mode(default_behavior); + obj->ctype.ai_info.ail.mode = ai_behavior_to_mode(default_behavior); #endif return obj; diff --git a/similar/main/multibot.cpp b/similar/main/multibot.cpp index 06d0e49e2..69a660df8 100644 --- a/similar/main/multibot.cpp +++ b/similar/main/multibot.cpp @@ -1045,7 +1045,8 @@ multi_do_boss_actions(const ubyte *buf) digi_link_sound_to_pos( Vclip[VCLIP_MORPHING_ROBOT].sound_num, teleport_segnum, 0, &boss_obj->pos, 0 , F1_0); digi_kill_sound_linked_to_object( boss_obj-Objects); digi_link_sound_to_object2( SOUND_BOSS_SHARE_SEE, boss_obj-Objects, 1, F1_0, F1_0*512 ); // F1_0*512 means play twice as loud - Ai_local_info[boss_obj-Objects].next_fire = 0; + ai_local *ailp = &boss_obj->ctype.ai_info.ail; + ailp->next_fire = 0; if (boss_obj->ctype.ai_info.REMOTE_OWNER == Player_num) { diff --git a/similar/main/object.cpp b/similar/main/object.cpp index aa7190e21..3ed60553c 100644 --- a/similar/main/object.cpp +++ b/similar/main/object.cpp @@ -498,7 +498,8 @@ static void draw_polygon_object(object *obj) #if defined(DXX_BUILD_DESCENT_II) // Snipers get bright when they fire. - if (Ai_local_info[obj-Objects].next_fire < F1_0/8) { + ai_local *ailp = &obj->ctype.ai_info.ail; + if (ailp->next_fire < F1_0/8) { if (obj->ctype.ai_info.behavior == AIB_SNIPE) { light.r = 2*light.r + F1_0; @@ -2210,7 +2211,7 @@ void wake_up_rendered_objects(object *viewer, int window_num) if (objp->type == OBJ_ROBOT) { if (vm_vec_dist_quick(&viewer->pos, &objp->pos) < F1_0*100) { - ai_local *ailp = &Ai_local_info[objnum]; + ai_local *ailp = &objp->ctype.ai_info.ail; if (ailp->player_awareness_type == 0) { objp->ctype.ai_info.SUB_FLAGS |= SUB_FLAGS_CAMERA_AWAKE; ailp->player_awareness_type = PA_WEAPON_ROBOT_COLLISION; diff --git a/similar/main/physics.cpp b/similar/main/physics.cpp index eb890b035..a9684b7aa 100644 --- a/similar/main/physics.cpp +++ b/similar/main/physics.cpp @@ -712,7 +712,7 @@ void do_physics_sim(object *obj) // Pass retry count info to AI. if (obj->control_type == CT_AI) { if (count > 0) { - Ai_local_info[objnum].retry_count = count-1; + obj->ctype.ai_info.ail.retry_count = count-1; #ifndef NDEBUG Total_retries += count-1; Total_sims++;