Use enum class for player visibility

This commit is contained in:
Kp 2019-06-20 04:02:27 +00:00
parent 5ab50520b7
commit af166735cc
9 changed files with 289 additions and 207 deletions

View file

@ -132,7 +132,7 @@ void create_path_to_station(vmobjptridx_t objp, int max_length);
#else
#undef ai_follow_path
#endif
void ai_follow_path(vmobjptridx_t objp, int player_visibility, const vms_vector *vec_to_player);
void ai_follow_path(vmobjptridx_t objp, const player_visibility_state player_visibility, const vms_vector *vec_to_player);
void ai_turn_towards_vector(const vms_vector &vec_to_player, object_base &obj, fix rate);
extern void init_ai_objects(void);
void create_n_segment_path(vmobjptridx_t objp, unsigned path_length, imsegidx_t avoid_seg);
@ -147,6 +147,9 @@ static inline vms_vector make_random_vector()
vms_vector v;
return make_random_vector(v), v;
}
extern player_visibility_state Control_center_player_been_seen;
}
#ifdef dsx
namespace dsx {
@ -168,15 +171,15 @@ int ai_door_is_openable(
player_flags,
#endif
const shared_segment &segp, unsigned sidenum);
int player_is_visible_from_object(vmobjptridx_t objp, vms_vector &pos, fix field_of_view, const vms_vector &vec_to_player);
player_visibility_state player_is_visible_from_object(vmobjptridx_t objp, vms_vector &pos, fix field_of_view, const vms_vector &vec_to_player);
extern void ai_reset_all_paths(void); // Reset all paths. Call at the start of a level.
int ai_multiplayer_awareness(vmobjptridx_t objp, int awareness_level);
#if defined(DXX_BUILD_DESCENT_II)
// In escort.c
void do_escort_frame(vmobjptridx_t objp, const object &plrobj, fix dist_to_player, int player_visibility);
void do_snipe_frame(vmobjptridx_t objp, fix dist_to_player, int player_visibility, const vms_vector &vec_to_player);
void do_thief_frame(vmobjptridx_t objp, fix dist_to_player, int player_visibility, const vms_vector &vec_to_player);
void do_escort_frame(vmobjptridx_t objp, const object &plrobj, fix dist_to_player, player_visibility_state player_visibility);
void do_snipe_frame(vmobjptridx_t objp, fix dist_to_player, player_visibility_state player_visibility, const vms_vector &vec_to_player);
void do_thief_frame(vmobjptridx_t objp, fix dist_to_player, player_visibility_state player_visibility, const vms_vector &vec_to_player);
#endif
}

View file

@ -52,6 +52,18 @@ enum class player_awareness_type_t : uint8_t
PA_WEAPON_ROBOT_COLLISION = 4, // Level of robot awareness after player weapon hits nearby robot
};
enum class player_visibility_state : int8_t
{
no_line_of_sight,
visible_not_in_field_of_view,
visible_and_in_field_of_view,
};
static inline unsigned player_is_visible(const player_visibility_state s)
{
return static_cast<unsigned>(s) > 0;
}
}
// Constants indicating currently moving forward or backward through
@ -190,7 +202,7 @@ struct ai_local : public prohibit_void_ptr<ai_local>
player_awareness_type_t player_awareness_type; // type of awareness of player
uint8_t retry_count; // number of retries in physics last time this object got moved.
uint8_t consecutive_retries; // number of retries in consecutive frames (ie, without a retry_count of 0)
uint8_t previous_visibility; // Visibility of player last time we checked.
player_visibility_state previous_visibility; // Visibility of player last time we checked.
uint8_t rapidfire_count; // number of shots fired rapidly
ai_mode mode; // current mode within behavior
segnum_t goal_segment; // goal segment for current path

View file

@ -106,7 +106,6 @@ static inline reactor &get_reactor_definition(int id)
namespace dcx {
//@@extern int N_controlcen_guns;
extern int Control_center_been_hit;
extern int Control_center_player_been_seen;
extern int Control_center_next_fire_time;
extern int Control_center_present;
extern objnum_t Dead_controlcen_object_num;

View file

@ -1100,14 +1100,15 @@ static void do_buddy_dude_stuff(void)
// -----------------------------------------------------------------------------
// Called every frame (or something).
void do_escort_frame(const vmobjptridx_t objp, const object &plrobj, fix dist_to_player, int player_visibility)
void do_escort_frame(const vmobjptridx_t objp, const object &plrobj, const fix dist_to_player, const player_visibility_state player_visibility)
{
auto &BuddyState = LevelUniqueObjectState.BuddyState;
ai_static *aip = &objp->ctype.ai_info;
ai_local *ailp = &objp->ctype.ai_info.ail;
auto &player_info = plrobj.ctype.player_info;
if (player_visibility) {
if (player_is_visible(player_visibility))
{
BuddyState.Buddy_last_seen_player = GameTime64;
if (player_info.powerup_flags & PLAYER_FLAGS_HEADLIGHT_ON) // DAMN! MK, stupid bug, fixed 12/08/95, changed PLAYER_FLAGS_HEADLIGHT to PLAYER_FLAGS_HEADLIGHT_ON
{
@ -1143,13 +1144,14 @@ void do_escort_frame(const vmobjptridx_t objp, const object &plrobj, fix dist_to
// It means the object has been told to get lost and has come to the end of its path.
// If the player is now visible, then create a path.
if (ailp->mode == ai_mode::AIM_WANDER)
if (player_visibility) {
if (player_is_visible(player_visibility))
{
create_n_segment_path(objp, 16 + d_rand() * 16, segment_none);
aip->path_length = polish_path(objp, &Point_segs[aip->hide_index], aip->path_length);
}
if (BuddyState.Escort_special_goal == ESCORT_GOAL_SCRAM) {
if (player_visibility)
if (player_is_visible(player_visibility))
if (BuddyState.Escort_last_path_created + F1_0*3 < GameTime64) {
BuddyState.Escort_last_path_created = GameTime64;
create_n_segment_path(objp, 10 + d_rand() * 16, ConsoleObject->segnum);
@ -1170,7 +1172,8 @@ void do_escort_frame(const vmobjptridx_t objp, const object &plrobj, fix dist_to
BuddyState.Buddy_last_player_path_created = GameTime64;
ailp->mode = ai_mode::AIM_GOTO_PLAYER;
if (!player_visibility) {
if (!player_is_visible(player_visibility))
{
if (BuddyState.Last_come_back_message_time + F1_0 < GameTime64)
{
BuddyState.Last_come_back_message_time = GameTime64;
@ -1220,7 +1223,7 @@ void invalidate_escort_goal(d_unique_buddy_state &BuddyState)
}
// -------------------------------------------------------------------------------------------------
void do_snipe_frame(const vmobjptridx_t objp, fix dist_to_player, int player_visibility, const vms_vector &vec_to_player)
void do_snipe_frame(const vmobjptridx_t objp, const fix dist_to_player, const player_visibility_state player_visibility, const vms_vector &vec_to_player)
{
ai_local *ailp = &objp->ctype.ai_info.ail;
fix connected_distance;
@ -1248,7 +1251,9 @@ void do_snipe_frame(const vmobjptridx_t objp, fix dist_to_player, int player_vis
if (ailp->next_action_time < 0) {
ailp->mode = ai_mode::AIM_SNIPE_WAIT;
ailp->next_action_time = SNIPE_WAIT_TIME;
} else if ((player_visibility == 0) || (ailp->next_action_time > SNIPE_ABORT_RETREAT_TIME)) {
}
else if (player_visibility == player_visibility_state::no_line_of_sight || ailp->next_action_time > SNIPE_ABORT_RETREAT_TIME)
{
ai_follow_path(objp, player_visibility, &vec_to_player);
ailp->mode = ai_mode::AIM_SNIPE_RETREAT_BACKWARDS;
} else {
@ -1263,7 +1268,8 @@ void do_snipe_frame(const vmobjptridx_t objp, fix dist_to_player, int player_vis
ailp->next_action_time = SNIPE_WAIT_TIME;
} else {
ai_follow_path(objp, player_visibility, &vec_to_player);
if (player_visibility) {
if (player_is_visible(player_visibility))
{
ailp->mode = ai_mode::AIM_SNIPE_FIRE;
ailp->next_action_time = SNIPE_FIRE_TIME;
} else
@ -1344,7 +1350,7 @@ constexpr array<fix, NDL> Thief_wait_times = {{
}};
// -------------------------------------------------------------------------------------------------
void do_thief_frame(const vmobjptridx_t objp, fix dist_to_player, int player_visibility, const vms_vector &vec_to_player)
void do_thief_frame(const vmobjptridx_t objp, const fix dist_to_player, const player_visibility_state player_visibility, const vms_vector &vec_to_player)
{
auto &Robot_info = LevelSharedRobotInfoState.Robot_info;
ai_local *ailp = &objp->ctype.ai_info.ail;
@ -1370,7 +1376,9 @@ void do_thief_frame(const vmobjptridx_t objp, fix dist_to_player, int player_vis
ailp->mode = ai_mode::AIM_THIEF_ATTACK;
ailp->next_action_time = THIEF_ATTACK_TIME/2;
return;
} else if (player_visibility) {
}
else if (player_is_visible(player_visibility))
{
create_n_segment_path(objp, 15, ConsoleObject->segnum);
ailp->mode = ai_mode::AIM_THIEF_RETREAT;
return;
@ -1394,7 +1402,9 @@ void do_thief_frame(const vmobjptridx_t objp, fix dist_to_player, int player_vis
if (ailp->next_action_time < 0) {
ailp->mode = ai_mode::AIM_THIEF_WAIT;
ailp->next_action_time = Thief_wait_times[Difficulty_level];
} else if ((dist_to_player < F1_0*100) || player_visibility || (ailp->player_awareness_type >= player_awareness_type_t::PA_PLAYER_COLLISION)) {
}
else if (dist_to_player < F1_0 * 100 || player_is_visible(player_visibility) || ailp->player_awareness_type >= player_awareness_type_t::PA_PLAYER_COLLISION)
{
ai_follow_path(objp, player_visibility, &vec_to_player);
if ((dist_to_player < F1_0*100) || (ailp->player_awareness_type >= player_awareness_type_t::PA_PLAYER_COLLISION)) {
ai_static *aip = &objp->ctype.ai_info;
@ -1438,7 +1448,8 @@ void do_thief_frame(const vmobjptridx_t objp, fix dist_to_player, int player_vis
create_path_to_player(objp, 100, create_path_safety_flag::unsafe);
ailp->mode = ai_mode::AIM_THIEF_ATTACK;
} else {
if (player_visibility && (dist_to_player < F1_0*100)) {
if (player_is_visible(player_visibility) && dist_to_player < F1_0*100)
{
// If the player is close to looking at the thief, thief shall run away.
// No more stupid thief trying to sneak up on you when you're looking right at him!
if (dist_to_player > F1_0*60) {

File diff suppressed because it is too large Load diff

View file

@ -62,7 +62,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
namespace dsx {
static void ai_path_set_orient_and_vel(const vmobjptr_t objp, const vms_vector &goal_point
#if defined(DXX_BUILD_DESCENT_II)
, int player_visibility, const vms_vector *vec_to_player
, player_visibility_state player_visibility, const vms_vector *vec_to_player
#endif
);
static void maybe_ai_path_garbage_collect(void);
@ -820,7 +820,8 @@ void create_n_segment_path(const vmobjptridx_t objp, unsigned path_length, const
#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 (ailp->previous_visibility) {
if (player_is_visible(ailp->previous_visibility))
{
if (aip->path_length) {
int t_num_points = aip->path_length;
move_towards_outside(LevelSharedSegmentState, &Point_segs[aip->hide_index], t_num_points, objp, create_path_random_flag::random);
@ -917,7 +918,7 @@ static void create_path(const vmobjptridx_t objp)
// ----------------------------------------------------------------------------------------------------------
// Optimization: If current velocity will take robot near goal, don't change velocity
void ai_follow_path(const vmobjptridx_t objp, int player_visibility, const vms_vector *vec_to_player)
void ai_follow_path(const vmobjptridx_t objp, const player_visibility_state player_visibility, const vms_vector *const vec_to_player)
{
ai_static *aip = &objp->ctype.ai_info;
@ -1004,7 +1005,8 @@ void ai_follow_path(const vmobjptridx_t objp, int player_visibility, const vms_v
// If running from player, only run until can't be seen.
if (ailp->mode == ai_mode::AIM_RUN_FROM_OBJECT) {
if ((player_visibility == 0) && (ailp->player_awareness_type == player_awareness_type_t::PA_NONE)) {
if (player_visibility == player_visibility_state::no_line_of_sight && ailp->player_awareness_type == player_awareness_type_t::PA_NONE)
{
fix vel_scale;
vel_scale = F1_0 - FrameTime/2;
@ -1035,7 +1037,8 @@ void ai_follow_path(const vmobjptridx_t objp, int player_visibility, const vms_v
break;
}
}
if (player_visibility) {
if (player_is_visible(player_visibility))
{
ailp->player_awareness_type = player_awareness_type_t::PA_NEARBY_ROBOT_FIRED;
ailp->player_awareness_time = F1_0;
}
@ -1083,7 +1086,8 @@ void ai_follow_path(const vmobjptridx_t objp, int player_visibility, const vms_v
if (robot_is_companion(robptr)) {
if (BuddyState.Escort_special_goal == ESCORT_GOAL_SCRAM)
{
if (player_visibility) {
if (player_is_visible(player_visibility))
{
create_n_segment_path(objp, 16 + d_rand() * 16, segment_none);
aip->path_length = polish_path(objp, &Point_segs[aip->hide_index], aip->path_length);
Assert(aip->path_length != 0);
@ -1244,7 +1248,7 @@ namespace dsx {
// Set orientation matrix and velocity for objp based on its desire to get to a point.
void ai_path_set_orient_and_vel(const vmobjptr_t objp, const vms_vector &goal_point
#if defined(DXX_BUILD_DESCENT_II)
, int player_visibility, const vms_vector *vec_to_player
, const player_visibility_state player_visibility, const vms_vector *const vec_to_player
#endif
)
{
@ -1310,7 +1314,7 @@ void ai_path_set_orient_and_vel(const vmobjptr_t objp, const vms_vector &goal_po
) {
#if defined(DXX_BUILD_DESCENT_II)
if (ailp->mode == ai_mode::AIM_SNIPE_RETREAT_BACKWARDS) {
if ((player_visibility) && (vec_to_player != NULL))
if (player_is_visible(player_visibility) && vec_to_player)
norm_vec_to_goal = *vec_to_player;
else
vm_vec_negate(norm_vec_to_goal);

View file

@ -70,7 +70,7 @@ control_center_triggers ControlCenterTriggers;
namespace dcx {
int Control_center_been_hit;
int Control_center_player_been_seen;
player_visibility_state Control_center_player_been_seen;
int Control_center_next_fire_time;
int Control_center_present;
@ -332,7 +332,8 @@ void do_controlcen_frame(const vmobjptridx_t obj)
#endif
auto &plrobj = get_local_plrobj();
if (!(Control_center_been_hit || Control_center_player_been_seen)) {
if (!(Control_center_been_hit || player_is_visible(Control_center_player_been_seen)))
{
if (!(d_tick_count % 8)) { // Do every so often...
// This is a hack. Since the control center is not processed by
// ai_do_frame, it doesn't know to deal with cloaked dudes. It
@ -364,7 +365,8 @@ void do_controlcen_frame(const vmobjptridx_t obj)
#if defined(DXX_BUILD_DESCENT_II)
// Periodically, make the reactor fall asleep if player not visible.
if (Control_center_been_hit || Control_center_player_been_seen) {
if (Control_center_been_hit || player_is_visible(Control_center_player_been_seen))
{
if ((Last_time_cc_vis_check + F1_0*5 < GameTime64) || (Last_time_cc_vis_check > GameTime64)) {
fix dist_to_player;
@ -373,7 +375,7 @@ void do_controlcen_frame(const vmobjptridx_t obj)
Last_time_cc_vis_check = GameTime64;
if (dist_to_player < F1_0*120) {
Control_center_player_been_seen = player_is_visible_from_object(obj, obj->pos, 0, vec_to_player);
if (!Control_center_player_been_seen)
if (!player_is_visible(Control_center_player_been_seen))
Control_center_been_hit = 0;
}
}
@ -404,7 +406,7 @@ void do_controlcen_frame(const vmobjptridx_t obj)
if (dist_to_player > F1_0*300)
{
Control_center_been_hit = 0;
Control_center_player_been_seen = 0;
Control_center_player_been_seen = player_visibility_state::no_line_of_sight;
return;
}
@ -519,7 +521,7 @@ void init_controlcen_for_level(void)
// Say the control center has not yet been hit.
Control_center_been_hit = 0;
Control_center_player_been_seen = 0;
Control_center_player_been_seen = player_visibility_state::no_line_of_sight;
Control_center_next_fire_time = 0;
Dead_controlcen_object_num = object_none;

View file

@ -2330,7 +2330,7 @@ void wake_up_rendered_objects(const object &viewer, window_rendered_data &window
objp->ctype.ai_info.SUB_FLAGS |= SUB_FLAGS_CAMERA_AWAKE;
ailp->player_awareness_type = player_awareness_type_t::PA_WEAPON_ROBOT_COLLISION;
ailp->player_awareness_time = F1_0*3;
ailp->previous_visibility = 2;
ailp->previous_visibility = player_visibility_state::visible_and_in_field_of_view;
}
}
}

View file

@ -1198,7 +1198,10 @@ int state_save_all_sub(const char *filename, const char *desc)
// Save the control cen info
PHYSFS_write(fp, &Control_center_been_hit, sizeof(int), 1);
PHYSFS_write(fp, &Control_center_player_been_seen, sizeof(int), 1);
{
const auto cc = static_cast<int>(Control_center_player_been_seen);
PHYSFS_write(fp, &cc, sizeof(int), 1);
}
PHYSFS_write(fp, &Control_center_next_fire_time, sizeof(int), 1);
PHYSFS_write(fp, &Control_center_present, sizeof(int), 1);
int dead_controlcen_object_num = Dead_controlcen_object_num == object_none ? -1 : Dead_controlcen_object_num;
@ -1808,7 +1811,10 @@ int state_restore_all_sub(const d_level_shared_destructible_light_state &LevelSh
// Restore the control cen info
Control_center_been_hit = PHYSFSX_readSXE32(fp, swap);
Control_center_player_been_seen = PHYSFSX_readSXE32(fp, swap);
{
const int cc = PHYSFSX_readSXE32(fp, swap);
Control_center_player_been_seen = static_cast<player_visibility_state>(cc);
}
Control_center_next_fire_time = PHYSFSX_readSXE32(fp, swap);
Control_center_present = PHYSFSX_readSXE32(fp, swap);
Dead_controlcen_object_num = PHYSFSX_readSXE32(fp, swap);