diff --git a/source/game/player_control.c b/source/game/player_control.c index 3adfabad..9293213c 100644 --- a/source/game/player_control.c +++ b/source/game/player_control.c @@ -187,8 +187,11 @@ symbols in this file: #include "items/weapons.h" #include "objects/objects.h" +#include "saved games/game_state.h" #include "units/unit_definitions.h" #include "units/units.h" +#include "units/vehicle_definitions.h" +#include "units/vehicles.h" #include "real_math.h" @@ -196,6 +199,14 @@ symbols in this file: /* ---------- macros */ +#define valid_euler_angles2d(angles) ( \ + valid_real((angles)->pitch) && \ + (angles)->pitch <= DEGREES_TO_RADIANS(85.5f) && \ + (angles)->pitch >= -DEGREES_TO_RADIANS(85.5f) && \ + valid_real((angles)->yaw) && \ + (angles)->yaw <= _pi * 2.f && \ + (angles)->yaw >= 0.f) + /* ---------- structures */ /* ---------- prototypes */ @@ -215,6 +226,16 @@ struct player_control_globals_data *bss_0043ee30; /* ---------- public code */ +void player_control_initialize( + void) +{ + player_control_globals = game_state_malloc( + "player control globals", + NULL, + sizeof(*player_control_globals)); + return; +} + struct player_control *player_control_get( short local_player_index) { @@ -310,6 +331,53 @@ real player_control_get_field_of_view( return field_of_view; } +void player_control_get_unit_camera_info( + short local_player_index, + struct player_control_unit_camera_info *camera_info) +{ + struct player_control *control; + struct unit_datum *unit; + + match_assert("c:\\halo\\SOURCE\\game\\player_control.c", 0x402, camera_info); + camera_info->camera = NULL; + control = player_control_get(local_player_index); + camera_info->unit_index = control->unit_index; + camera_info->seat_index = NONE; + + if (camera_info->unit_index != NONE) + { + unit = unit_get(camera_info->unit_index); + unit_get_camera_position(camera_info->unit_index, &camera_info->position); + + if (unit->object.parent_object_index != NONE) + { + struct unit_datum *vehicle = vehicle_try_and_get( + unit->object.parent_object_index); + + if (vehicle) + { + struct unit_definition *definition = vehicle_definition_get( + vehicle->definition_index); + struct unit_seat *seat = TAG_BLOCK_GET_ELEMENT( + &definition->unit.seats, + unit->unit.parent_seat_index, + struct unit_seat); + + camera_info->unit_index = unit->object.parent_object_index; + camera_info->camera = &seat->camera; + camera_info->seat_index = unit->unit.parent_seat_index; + unit = unit_get(camera_info->unit_index); + } + } + + if (camera_info->seat_index == NONE) + { + camera_info->camera = &unit_definition_get(unit->definition_index)->unit.camera; + } + } + return; +} + long player_control_get_unit_index( short local_player_index) { @@ -389,6 +457,18 @@ void player_control_unzoom( return; } +real_euler_angles2d const *player_control_get_facing_angles( + short local_player_index) +{ + struct player_control *player = player_control_get(local_player_index); + + match_assert( + "c:\\halo\\SOURCE\\game\\player_control.c", + 0x3C0, + valid_euler_angles2d(&player->desired_angles)); + return &player->desired_angles; +} + real_vector3d *player_control_get_facing_direction( short local_player_index, real_vector3d *facing_direction) @@ -419,6 +499,66 @@ void player_control_set_desired_weapon( return; } +void player_control_set_facing( + short local_player_index, + real_vector3d const *facing_direction) +{ + struct player_control *player_control = player_control_get(local_player_index); + + euler_angles2d_from_vector3d( + &player_control->desired_angles, + facing_direction); + match_assert_valid_real( + "c:\\halo\\SOURCE\\game\\player_control.c", + 0xBB, + player_control->desired_angles.pitch); + match_assert_valid_real( + "c:\\halo\\SOURCE\\game\\player_control.c", + 0xBC, + player_control->desired_angles.yaw); + if (player_control->desired_angles.yaw < 0.f) + { + player_control->desired_angles.yaw += _pi * 2.f; + } + return; +} + +void player_control_new_unit( + short local_player_index, + long unit_index) +{ + struct player_control *control = player_control_get(local_player_index); + + csmemset(control, 0, sizeof(*control)); + control->unit_index = unit_index; + control->desired_weapon_index = NONE; + control->desired_grenade_index = NONE; + control->zoom_level = NONE; + control->unknown26 = FALSE; + control->target_object_index = NONE; + control->pitch_maximum = DEGREES_TO_RADIANS(85.5f); + control->pitch_minimum = -DEGREES_TO_RADIANS(85.5f); + control->inhibited_action_flags = 0; + control->persistent_inhibited_action_flags = 0; + + if (unit_index != NONE) + { + struct unit_datum *unit = unit_get(unit_index); + + euler_angles2d_from_vector3d( + &control->desired_angles, + &unit->unit.desired_facing_vector); + if (control->desired_angles.yaw < 0.f) + { + control->desired_angles.yaw += _pi * 2.f; + } + control->desired_weapon_index = unit->unit.desired_weapon_index; + control->desired_grenade_index = unit->unit.desired_grenade_index; + control->zoom_level = unit->unit.desired_zoom_level; + } + return; +} + void player_control_action_test_reset( void) { diff --git a/source/game/player_control.h b/source/game/player_control.h index 66ecb74f..58a6ddbf 100644 --- a/source/game/player_control.h +++ b/source/game/player_control.h @@ -30,14 +30,24 @@ enum /* ---------- structures */ +struct unit_camera; + +struct player_control_unit_camera_info +{ + long unit_index; + short seat_index; + short pad6; + struct unit_camera const *camera; + real_point3d position; +}; + struct player_control { long unit_index; long unknown04; short inhibited_action_flags; short persistent_inhibited_action_flags; - float desired_yaw; - float desired_pitch; + real_euler_angles2d desired_angles; byte unknown14[0xC]; short desired_weapon_index; short desired_grenade_index; @@ -46,7 +56,9 @@ struct player_control byte unknown27; long target_object_index; float autoaim_level; - byte unknown30[0x10]; + byte unknown30[8]; + real pitch_minimum; + real pitch_maximum; }; struct player_control_globals_data @@ -65,9 +77,9 @@ typedef char player_control_unit_index_offset_assert[ typedef char player_control_inhibited_action_flags_offset_assert[ offsetof(struct player_control, inhibited_action_flags) == 0x8 ? 1 : -1]; typedef char player_control_desired_yaw_offset_assert[ - offsetof(struct player_control, desired_yaw) == 0xC ? 1 : -1]; + offsetof(struct player_control, desired_angles.yaw) == 0xC ? 1 : -1]; typedef char player_control_desired_pitch_offset_assert[ - offsetof(struct player_control, desired_pitch) == 0x10 ? 1 : -1]; + offsetof(struct player_control, desired_angles.pitch) == 0x10 ? 1 : -1]; typedef char player_control_desired_weapon_index_offset_assert[ offsetof(struct player_control, desired_weapon_index) == 0x20 ? 1 : -1]; typedef char player_control_desired_grenade_index_offset_assert[ @@ -78,6 +90,12 @@ typedef char player_control_target_object_index_offset_assert[ offsetof(struct player_control, target_object_index) == 0x28 ? 1 : -1]; typedef char player_control_autoaim_level_offset_assert[ offsetof(struct player_control, autoaim_level) == 0x2C ? 1 : -1]; +typedef char player_control_pitch_minimum_offset_assert[ + offsetof(struct player_control, pitch_minimum) == 0x38 ? 1 : -1]; +typedef char player_control_pitch_maximum_offset_assert[ + offsetof(struct player_control, pitch_maximum) == 0x3C ? 1 : -1]; +typedef char player_control_unit_camera_info_size_assert[ + sizeof(struct player_control_unit_camera_info) == 0x18 ? 1 : -1]; typedef char player_control_globals_size_assert[ sizeof(struct player_control_globals_data) == 0x110 ? 1 : -1]; typedef char player_control_globals_players_offset_assert[ @@ -91,6 +109,8 @@ typedef char player_control_globals_flags_offset_assert[ /* ---------- prototypes */ +void player_control_initialize( + void); void player_control_dispose( void); void player_control_dispose_from_old_map( @@ -105,6 +125,9 @@ long player_control_get_target_object_index( short local_player_index); real player_control_get_field_of_view( short local_player_index); +void player_control_get_unit_camera_info( + short local_player_index, + struct player_control_unit_camera_info *camera_info); long player_control_get_unit_index( short local_player_index); long player_control_get_desired_weapon( @@ -126,6 +149,12 @@ real_vector3d *player_control_get_facing_direction( void player_control_set_desired_weapon( long unit_index, short desired_weapon_index); +void player_control_set_facing( + short local_player_index, + real_vector3d const *facing_direction); +void player_control_new_unit( + short local_player_index, + long unit_index); boolean scripted_player_control_set_camera_control( boolean camera_control); void player_control_action_test_reset(