mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-25 22:04:46 +01:00
1017 lines
25 KiB
C
1017 lines
25 KiB
C
/*
|
|
PLAYER_CONTROL.C
|
|
|
|
symbols in this file:
|
|
000A56F0 0050:
|
|
_player_control_get (0000)
|
|
000A5740 0020:
|
|
_player_control_initialize (0000)
|
|
000A5760 0010:
|
|
_player_control_dispose (0000)
|
|
000A5770 0010:
|
|
_player_control_dispose_from_old_map (0000)
|
|
000A5780 0020:
|
|
_player_control_camera_control_is_active (0000)
|
|
000A57A0 0030:
|
|
_scripted_player_control_set_camera_control (0000)
|
|
000A57D0 0060:
|
|
_player_control_inhibit_buttons (0000)
|
|
000A5830 00f0:
|
|
_evaluate_piecewise_linear_function (0000)
|
|
000A5920 0010:
|
|
_player_action_clear (0000)
|
|
000A5930 0060:
|
|
_player_control_get_aiming_unit_index (0000)
|
|
000A5990 0070:
|
|
_player_control_get_target_object_index (0000)
|
|
000A5A00 00b0:
|
|
_player_control_get_field_of_view (0000)
|
|
000A5AB0 0130:
|
|
_player_control_get_unit_camera_info (0000)
|
|
000A5BE0 0050:
|
|
_player_control_get_unit_index (0000)
|
|
000A5C30 0080:
|
|
_player_control_get_desired_weapon (0000)
|
|
000A5CB0 0050:
|
|
_player_control_get_autoaim_level (0000)
|
|
000A5D00 0040:
|
|
_unit_get_local_player_index (0000)
|
|
000A5D40 0050:
|
|
_players_unzoom_all (0000)
|
|
000A5D90 0050:
|
|
_player_control_unzoom (0000)
|
|
000A5DE0 0020:
|
|
_player_control_get_zoom_level (0000)
|
|
000A5E00 0020:
|
|
_player_control_action_test_reset (0000)
|
|
000A5E20 0020:
|
|
_player_control_action_test_accept (0000)
|
|
000A5E40 0020:
|
|
_player_control_action_test_back (0000)
|
|
000A5E60 0020:
|
|
_player_control_action_test_action (0000)
|
|
000A5E80 0010:
|
|
_player_control_action_test_jump (0000)
|
|
000A5E90 0010:
|
|
_player_control_action_test_primary_trigger (0000)
|
|
000A5EA0 0010:
|
|
_player_control_action_test_grenade_trigger (0000)
|
|
000A5EB0 0010:
|
|
_player_control_action_test_zoom (0000)
|
|
000A5EC0 0020:
|
|
_player_control_action_test_move_relative_all_directions (0000)
|
|
000A5EE0 0020:
|
|
_player_control_action_test_look_relative_all_directions (0000)
|
|
000A5F00 0010:
|
|
_player_control_action_test_look_relative_left (0000)
|
|
000A5F10 0010:
|
|
_player_control_action_test_look_relative_right (0000)
|
|
000A5F20 0010:
|
|
_player_control_action_test_look_relative_up (0000)
|
|
000A5F30 0010:
|
|
_player_control_action_test_look_relative_down (0000)
|
|
000A5F40 0200:
|
|
_player_control_action_test_check_reset_input_blob (0000)
|
|
000A6140 0040:
|
|
_signed_angular_difference (0000)
|
|
000A6180 0050:
|
|
_limit2d (0000)
|
|
000A61D0 0040:
|
|
_interpolate_scalar (0000)
|
|
000A6210 0120:
|
|
_player_control_set_facing (0000)
|
|
000A6330 00f0:
|
|
_player_control_new_unit (0000)
|
|
000A6420 0d80:
|
|
_get_local_player_input_blob (0000)
|
|
000A71A0 00e0:
|
|
_player_control_get_facing_angles (0000)
|
|
000A7280 0030:
|
|
_player_control_get_facing_direction (0000)
|
|
000A72B0 0050:
|
|
_player_control_set_desired_weapon (0000)
|
|
000A7300 0630:
|
|
_player_control_modify_desired_angles (0000)
|
|
000A7930 0090:
|
|
_player_control_initialize_for_new_map (0000)
|
|
000A79C0 0620:
|
|
_handle_one_player_input (0000)
|
|
000A7FE0 0080:
|
|
_player_control_update (0000)
|
|
000A8060 0040:
|
|
_player_control_permanent_impulse (0000)
|
|
0025C614 0016:
|
|
??_C@_0BG@KLOMMKO@player_control_update?$AA@ (0000)
|
|
0025C62C 000c:
|
|
_MOUSE_YAW_SCALE (0000)
|
|
_MOUSE_PITCH_SCALE (0004)
|
|
0025C638 0025:
|
|
??_C@_0CF@CDJDDDIC@c?3?2halo?2SOURCE?2game?2player_contr@ (0000)
|
|
0025C660 0017:
|
|
??_C@_0BH@GDMLDNGJ@player?5control?5globals?$AA@ (0000)
|
|
0025C678 0046:
|
|
??_C@_0EG@FFIEHMMD@function?5?$CG?$CG?5low_index?$DO?$DN0?5?$CG?$CG?5low_@ (0000)
|
|
0025C6C0 0004:
|
|
__real@3f9c61aa (0000)
|
|
0025C6C4 000c:
|
|
??_C@_0M@KHNJLLND@camera_info?$AA@ (0000)
|
|
0025C6D0 0004:
|
|
__real@c0490fdb (0000)
|
|
0025C6D4 0023:
|
|
??_C@_0CD@PHGHILFD@player_control?9?$DOdesired_angles?4y@ (0000)
|
|
0025C6F8 0025:
|
|
??_C@_0CF@JIDICGJ@player_control?9?$DOdesired_angles?4p@ (0000)
|
|
0025C720 0017:
|
|
??_C@_0BH@BJMHFMPG@input?9?$DOprimary_trigger?$AA@ (0000)
|
|
0025C738 0004:
|
|
__real@3f75dcc7 (0000)
|
|
0025C73C 0004:
|
|
__real@3d567750 (0000)
|
|
0025C740 0004:
|
|
__real@bd567750 (0000)
|
|
0025C744 0004:
|
|
__real@3dd67750 (0000)
|
|
0025C748 0004:
|
|
__real@bdd67750 (0000)
|
|
0025C74C 0027:
|
|
??_C@_0CH@OIFLGJJD@constants?9?$DOlook_acceleration_tim@ (0000)
|
|
0025C774 0021:
|
|
??_C@_0CB@KGNPCEEG@constants?9?$DOlook_function?4count?$DO1@ (0000)
|
|
0025C798 002e:
|
|
??_C@_0CO@HHADHJPE@valid_euler_angles2d?$CI?$CGplayer?9?$DOde@ (0000)
|
|
0025C7C8 0004:
|
|
__real@bfbf0243 (0000)
|
|
0025C7CC 0004:
|
|
__real@3fbf0243 (0000)
|
|
0025C7D0 0004:
|
|
__real@3c490fdb (0000)
|
|
0025C7D4 0004:
|
|
__real@bc490fdb (0000)
|
|
0025C7D8 0004:
|
|
__real@3da3d70a (0000)
|
|
0025C7DC 001d:
|
|
??_C@_0BN@JFNDAOJI@player?9?$DOdesired_angles?4pitch?$AA@ (0000)
|
|
0025C800 0008:
|
|
__real@3fe45f3060000000 (0000)
|
|
0025C808 001a:
|
|
??_C@_0BK@GKNPAGDI@action?4desired_facing?4yaw?$AA@ (0000)
|
|
0025C824 001c:
|
|
??_C@_0BM@BMIDFCCA@action?4desired_facing?4pitch?$AA@ (0000)
|
|
0025C840 0018:
|
|
??_C@_0BI@OPEALALJ@player?9?$DOprimary_trigger?$AA@ (0000)
|
|
0025C858 001b:
|
|
??_C@_0BL@MOACFICP@player?9?$DOdesired_angles?4yaw?$AA@ (0000)
|
|
0025C874 0006:
|
|
??_C@_05NCGEDJPM@delta?$AA@ (0000)
|
|
002DE808 0600:
|
|
_player_autoaim_flag (0000)
|
|
_player_magnetism_flag (0001)
|
|
_controls_swapped (0002)
|
|
_player_look_zoomed_scale (0004)
|
|
0043EE30 002b:
|
|
_player_control_globals (0000)
|
|
_debug_input_target (0004)
|
|
_player_look_yaw_rate (0008)
|
|
_player_look_pitch_rate (0018)
|
|
_controls_enable_crouch (0028)
|
|
_controls_enable_doubled_spin (0029)
|
|
_controls_swap_doubled_spin_state (002a)
|
|
*/
|
|
|
|
/* ---------- headers */
|
|
|
|
#include "cseries.h"
|
|
#define signed_angular_difference signed_angular_difference_inline
|
|
#define limit2d limit2d_inline
|
|
#define interpolate_scalar interpolate_scalar_inline
|
|
#include "game/game.h"
|
|
#undef interpolate_scalar
|
|
#undef limit2d
|
|
#undef signed_angular_difference
|
|
#include "game/player_control.h"
|
|
#include "game/player_control_runtime.h"
|
|
#include "players.h"
|
|
|
|
#include "game/game_globals.h"
|
|
#include "cseries/profile.h"
|
|
#include "items/weapons.h"
|
|
#include "objects/objects.h"
|
|
#include "saved games/game_state.h"
|
|
#include "scenario/scenario.h"
|
|
#include "units/unit_definitions.h"
|
|
#include "units/units.h"
|
|
#include "units/vehicle_definitions.h"
|
|
#include "units/vehicles.h"
|
|
|
|
#include "real_math.h"
|
|
|
|
/* ---------- constants */
|
|
|
|
/* ---------- 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 */
|
|
|
|
void player_aiming_vector_from_facing(
|
|
long player_index,
|
|
real_vector3d *facing_direction,
|
|
real_euler_angles2d const *facing_angles);
|
|
|
|
static void player_control_modify_desired_angles(
|
|
short local_player_index,
|
|
real delta_yaw,
|
|
real delta_pitch);
|
|
|
|
/* ---------- globals */
|
|
|
|
boolean player_autoaim_flag = TRUE;
|
|
boolean player_magnetism_flag = TRUE;
|
|
boolean controls_swapped = TRUE;
|
|
real player_look_zoomed_scale = 0.5f;
|
|
|
|
static struct profile_section player_control_update_section = {"player_control_update", NONE, TRUE};
|
|
|
|
struct player_control_globals_data *player_control_globals;
|
|
short debug_input_target;
|
|
real player_look_yaw_rate[MAXIMUM_NUMBER_OF_LOCAL_PLAYERS];
|
|
real player_look_pitch_rate[MAXIMUM_NUMBER_OF_LOCAL_PLAYERS];
|
|
boolean controls_enable_crouch;
|
|
boolean controls_enable_doubled_spin;
|
|
boolean controls_swap_doubled_spin_state;
|
|
|
|
/* ---------- public code */
|
|
|
|
short unit_get_local_player_index(
|
|
long unit_index)
|
|
{
|
|
long player_index = unit_get(unit_index)->unit.player_index;
|
|
|
|
if (player_index!=NONE)
|
|
return player_get(player_index)->local_player_index;
|
|
|
|
return NONE;
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
match_assert("c:\\halo\\SOURCE\\game\\player_control.c", 0xB1,
|
|
local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
|
|
return &player_control_globals->players[local_player_index];
|
|
}
|
|
|
|
void player_control_dispose(
|
|
void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
void player_control_dispose_from_old_map(
|
|
void)
|
|
{
|
|
return;
|
|
}
|
|
|
|
boolean player_control_camera_control_is_active(
|
|
void)
|
|
{
|
|
return (boolean)(!TEST_FLAG(
|
|
player_control_globals->flags,
|
|
_player_control_camera_control_disabled_bit) &&
|
|
!game_time_get_paused());
|
|
}
|
|
|
|
boolean scripted_player_control_set_camera_control(
|
|
boolean camera_control)
|
|
{
|
|
SET_FLAG(
|
|
player_control_globals->flags,
|
|
_player_control_camera_control_disabled_bit,
|
|
!camera_control);
|
|
return camera_control;
|
|
}
|
|
|
|
void player_control_inhibit_buttons(
|
|
short local_player_index,
|
|
word action_flags,
|
|
boolean persistent)
|
|
{
|
|
struct player_control *control = player_control_get(local_player_index);
|
|
|
|
control->inhibited_action_flags |= action_flags;
|
|
if (persistent)
|
|
{
|
|
control->persistent_inhibited_action_flags |= action_flags;
|
|
}
|
|
return;
|
|
}
|
|
|
|
long player_control_get_target_object_index(
|
|
short local_player_index)
|
|
{
|
|
struct player_control *control = player_control_get(local_player_index);
|
|
|
|
if (object_try_and_get(control->target_object_index))
|
|
{
|
|
return control->target_object_index;
|
|
}
|
|
return NONE;
|
|
}
|
|
|
|
real player_control_get_field_of_view(
|
|
short local_player_index)
|
|
{
|
|
struct player_control *control = player_control_get(local_player_index);
|
|
real field_of_view = DEGREES_TO_RADIANS(70.f);
|
|
|
|
if (control->unit_index != NONE)
|
|
{
|
|
struct unit_datum *unit = unit_get(control->unit_index);
|
|
struct unit_definition *definition = unit_definition_get(unit->definition_index);
|
|
long weapon_index = unit_inventory_get_weapon(
|
|
control->unit_index,
|
|
unit->unit.current_weapon_index);
|
|
|
|
if (weapon_index != NONE)
|
|
{
|
|
field_of_view = weapon_get_field_of_view(
|
|
weapon_index,
|
|
definition->unit.camera_field_of_view,
|
|
control->zoom_level);
|
|
}
|
|
else
|
|
{
|
|
field_of_view = definition->unit.camera_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;
|
|
}
|
|
|
|
real evaluate_piecewise_linear_function(
|
|
short count,
|
|
real const *function,
|
|
real input)
|
|
{
|
|
boolean negate = TRUE;
|
|
short low_index;
|
|
short high_index;
|
|
real result;
|
|
|
|
if (!(input < 0.f))
|
|
{
|
|
negate = FALSE;
|
|
}
|
|
input = PIN(fabs(input) * (count - 1), 0.0, (real)count - 1.f);
|
|
low_index = PIN((short)input, 0, count - 1);
|
|
high_index = MIN(low_index + 1, count - 1);
|
|
match_assert("c:\\halo\\SOURCE\\game\\player_control.c", 0x14B,
|
|
function && low_index>=0 && low_index<=high_index && high_index<count);
|
|
result = (function[high_index] - function[low_index]) *
|
|
(input - low_index) + function[low_index];
|
|
if (negate)
|
|
{
|
|
result = -result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
long player_control_get_aiming_unit_index(
|
|
short local_player_index)
|
|
{
|
|
struct player_control *control = player_control_get(local_player_index);
|
|
|
|
return unit_get_aiming_unit_index(control->unit_index);
|
|
}
|
|
|
|
long player_control_get_unit_index(
|
|
short local_player_index)
|
|
{
|
|
match_assert("c:\\halo\\SOURCE\\game\\player_control.c", 0xB1,
|
|
local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
|
|
return player_control_globals->players[local_player_index].unit_index;
|
|
}
|
|
|
|
short player_control_get_zoom_level(
|
|
short local_player_index)
|
|
{
|
|
short zoom_level = NONE;
|
|
|
|
if (local_player_index != NONE)
|
|
{
|
|
zoom_level = player_control_get(local_player_index)->zoom_level;
|
|
}
|
|
return zoom_level;
|
|
}
|
|
|
|
real player_control_get_autoaim_level(
|
|
short local_player_index)
|
|
{
|
|
match_assert("c:\\halo\\SOURCE\\game\\player_control.c", 0xB1,
|
|
local_player_index>=0 && local_player_index<MAXIMUM_NUMBER_OF_LOCAL_PLAYERS);
|
|
return player_control_globals->players[local_player_index].autoaim_level;
|
|
}
|
|
|
|
long player_control_get_desired_weapon(
|
|
short local_player_index,
|
|
long unit_index)
|
|
{
|
|
struct player_control *control = player_control_get(local_player_index);
|
|
long weapon_index = NONE;
|
|
|
|
if (control->unit_index != unit_index ||
|
|
(weapon_index = unit_inventory_get_weapon(
|
|
unit_index,
|
|
control->desired_weapon_index)) == NONE)
|
|
{
|
|
weapon_index = unit_inventory_get_weapon(
|
|
unit_index,
|
|
unit_get(unit_index)->unit.current_weapon_index);
|
|
}
|
|
return weapon_index;
|
|
}
|
|
|
|
void players_unzoom_all(
|
|
void)
|
|
{
|
|
short local_player_index;
|
|
|
|
for (local_player_index = 0;
|
|
local_player_index < MAXIMUM_NUMBER_OF_LOCAL_PLAYERS;
|
|
local_player_index++)
|
|
{
|
|
player_control_get(local_player_index)->zoom_level = NONE;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void player_control_unzoom(
|
|
long unit_index)
|
|
{
|
|
struct unit_datum *unit = unit_get(unit_index);
|
|
long player_index = unit->unit.player_index;
|
|
|
|
if (player_index != NONE)
|
|
{
|
|
struct player_datum *player = player_get(player_index);
|
|
|
|
if (player->local_player_index != NONE)
|
|
{
|
|
player_control_get(player->local_player_index)->zoom_level = NONE;
|
|
}
|
|
}
|
|
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)
|
|
{
|
|
player_aiming_vector_from_facing(
|
|
local_player_get_player_index(local_player_index),
|
|
facing_direction,
|
|
player_control_get_facing_angles(local_player_index));
|
|
return facing_direction;
|
|
}
|
|
|
|
void player_control_set_desired_weapon(
|
|
long unit_index,
|
|
short desired_weapon_index)
|
|
{
|
|
struct unit_datum *unit = unit_get(unit_index);
|
|
|
|
if (unit->unit.player_index != NONE)
|
|
{
|
|
struct player_datum *player = player_get(unit->unit.player_index);
|
|
|
|
if (player->local_player_index != NONE)
|
|
{
|
|
player_control_get(player->local_player_index)->desired_weapon_index =
|
|
desired_weapon_index;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
real signed_angular_difference(
|
|
real angle1,
|
|
real angle2)
|
|
{
|
|
real result = angle2 - angle1;
|
|
|
|
if (result >= _pi)
|
|
{
|
|
result -= _pi * 2.f;
|
|
}
|
|
|
|
if (result <= -_pi)
|
|
{
|
|
result += _pi * 2.f;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
boolean limit2d(
|
|
real_vector2d *vector,
|
|
real length)
|
|
{
|
|
real dot = vector->i * vector->i + vector->j * vector->j;
|
|
|
|
if (dot > length * length)
|
|
{
|
|
scale_vector2d(
|
|
vector,
|
|
length / square_root(dot),
|
|
vector);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void interpolate_scalar(
|
|
real *current,
|
|
real desired,
|
|
real maximum_speed)
|
|
{
|
|
real difference = desired - *current;
|
|
|
|
*current += PIN(
|
|
difference,
|
|
-maximum_speed,
|
|
maximum_speed);
|
|
|
|
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)
|
|
{
|
|
struct player_control_globals_data *globals = player_control_globals;
|
|
|
|
globals->action_flags = 0;
|
|
globals->action_test_flags = 0;
|
|
return;
|
|
}
|
|
|
|
boolean player_control_action_test_accept(
|
|
void)
|
|
{
|
|
struct player_control_globals_data *globals = player_control_globals;
|
|
|
|
globals->action_test_flags |= FLAG(_player_control_accept_bit);
|
|
globals->suppressed_action_flags |= FLAG(_player_control_accept_bit);
|
|
return TEST_FLAG(
|
|
globals->action_flags,
|
|
_player_control_accept_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_back(
|
|
void)
|
|
{
|
|
struct player_control_globals_data *globals = player_control_globals;
|
|
|
|
globals->action_test_flags |= FLAG(_player_control_back_bit);
|
|
globals->suppressed_action_flags |= FLAG(_player_control_back_bit);
|
|
return TEST_FLAG(
|
|
globals->action_flags,
|
|
_player_control_back_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_action(
|
|
void)
|
|
{
|
|
struct player_control_globals_data *globals = player_control_globals;
|
|
|
|
globals->action_test_flags |= FLAG(_player_control_action_bit);
|
|
globals->suppressed_action_flags |= FLAG(_player_control_action_bit);
|
|
return TEST_FLAG(
|
|
globals->action_flags,
|
|
_player_control_action_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_jump(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_jump_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_primary_trigger(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_primary_trigger_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_grenade_trigger(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_grenade_trigger_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_zoom(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_zoom_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_look_relative_left(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_look_relative_left_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_look_relative_right(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_look_relative_right_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_look_relative_up(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_look_relative_up_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_look_relative_down(
|
|
void)
|
|
{
|
|
return TEST_FLAG(
|
|
player_control_globals->action_flags,
|
|
_player_control_look_relative_down_bit);
|
|
}
|
|
|
|
boolean player_control_action_test_move_relative_all_directions(
|
|
void)
|
|
{
|
|
return !(~player_control_globals->action_flags &
|
|
_player_control_move_relative_all_directions_flags);
|
|
}
|
|
|
|
boolean player_control_action_test_look_relative_all_directions(
|
|
void)
|
|
{
|
|
return !(~player_control_globals->action_flags &
|
|
_player_control_look_relative_all_directions_flags);
|
|
}
|
|
|
|
void player_control_initialize_for_new_map(
|
|
void)
|
|
{
|
|
struct player_control_globals_data *globals = player_control_globals;
|
|
short local_player_index;
|
|
|
|
globals->action_flags = 0;
|
|
globals->action_test_flags = 0;
|
|
globals->suppressed_action_flags = 0;
|
|
globals->flags = 0;
|
|
|
|
for (local_player_index = 0;
|
|
local_player_index < MAXIMUM_NUMBER_OF_LOCAL_PLAYERS;
|
|
local_player_index++)
|
|
{
|
|
struct game_globals_player_control *constants = TAG_BLOCK_GET_ELEMENT(
|
|
&scenario_get_game_globals()->player_control,
|
|
0,
|
|
struct game_globals_player_control);
|
|
|
|
player_control_new_unit(local_player_index, NONE);
|
|
if (player_look_pitch_rate[local_player_index] == 0.f)
|
|
{
|
|
player_look_pitch_rate[local_player_index] =
|
|
constants->look_default_pitch_rate;
|
|
}
|
|
if (player_look_yaw_rate[local_player_index] == 0.f)
|
|
{
|
|
player_look_yaw_rate[local_player_index] =
|
|
constants->look_default_yaw_rate;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void player_control_permanent_impulse(
|
|
short local_player_index,
|
|
real_euler_angles2d const *delta)
|
|
{
|
|
match_assert("c:\\halo\\SOURCE\\game\\player_control.c", 0x467, delta);
|
|
player_control_modify_desired_angles(
|
|
local_player_index,
|
|
delta->yaw,
|
|
delta->pitch);
|
|
return;
|
|
}
|
|
|
|
/* ---------- private code */
|
|
|
|
static void player_control_modify_desired_angles(
|
|
short local_player_index,
|
|
real delta_yaw,
|
|
real delta_pitch)
|
|
{
|
|
struct player_control *player = player_control_get(local_player_index);
|
|
struct game_globals_player_control *constants = TAG_BLOCK_GET_ELEMENT(
|
|
&scenario_get_game_globals()->player_control,
|
|
0,
|
|
struct game_globals_player_control);
|
|
struct player_control_unit_camera_info camera_info;
|
|
real pitch_minimum = -DEGREES_TO_RADIANS(85.5f);
|
|
real pitch_maximum = DEGREES_TO_RADIANS(85.5f);
|
|
|
|
match_assert(
|
|
"c:\\halo\\SOURCE\\game\\player_control.c",
|
|
0x494,
|
|
valid_euler_angles2d(&player->desired_angles));
|
|
player_control_get_unit_camera_info(local_player_index, &camera_info);
|
|
|
|
player->desired_angles.yaw += delta_yaw;
|
|
if (camera_info.seat_index != NONE)
|
|
{
|
|
struct unit_datum *unit = unit_get(camera_info.unit_index);
|
|
struct unit_definition *definition = unit_definition_get(unit->definition_index);
|
|
struct unit_seat *seat = TAG_BLOCK_GET_ELEMENT(
|
|
&definition->unit.seats,
|
|
camera_info.seat_index,
|
|
struct unit_seat);
|
|
|
|
if (seat->yaw_minimum != 0.f || seat->yaw_maximum != 0.f)
|
|
{
|
|
struct object_marker marker;
|
|
real_euler_angles2d marker_angles;
|
|
real yaw_minimum;
|
|
real yaw_maximum;
|
|
real arc;
|
|
real to_maximum;
|
|
real to_minimum;
|
|
|
|
object_get_marker_by_name(
|
|
camera_info.unit_index,
|
|
seat->marker_name,
|
|
&marker,
|
|
1);
|
|
euler_angles2d_from_vector3d(&marker_angles, &marker.matrix.forward);
|
|
yaw_minimum = marker_angles.yaw + seat->yaw_minimum;
|
|
yaw_maximum = marker_angles.yaw + seat->yaw_maximum;
|
|
arc = signed_angular_difference(yaw_minimum, yaw_maximum);
|
|
to_maximum = signed_angular_difference(player->desired_angles.yaw, yaw_maximum);
|
|
to_minimum = signed_angular_difference(yaw_minimum, player->desired_angles.yaw);
|
|
if (arc < 0.f)
|
|
{
|
|
arc += _pi * 2.f;
|
|
}
|
|
|
|
if (!(to_maximum >= 0.f && to_maximum < arc) &&
|
|
!(to_minimum >= 0.f && to_minimum < arc))
|
|
{
|
|
if (fabs(to_minimum) < fabs(to_maximum))
|
|
{
|
|
player->desired_angles.yaw = yaw_minimum;
|
|
}
|
|
else
|
|
{
|
|
player->desired_angles.yaw = yaw_maximum;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
while (player->desired_angles.yaw < 0.f)
|
|
{
|
|
player->desired_angles.yaw += _pi * 2.f;
|
|
}
|
|
while (player->desired_angles.yaw > _pi * 2.f)
|
|
{
|
|
player->desired_angles.yaw -= _pi * 2.f;
|
|
}
|
|
|
|
if (camera_info.camera)
|
|
{
|
|
struct unit_datum *unit = unit_get(camera_info.unit_index);
|
|
real pitch_autolevel = camera_info.camera->pitch_autolevel;
|
|
|
|
if (camera_info.camera->pitch_maximum != 0.f ||
|
|
camera_info.camera->pitch_minimum != 0.f)
|
|
{
|
|
pitch_minimum = camera_info.camera->pitch_minimum;
|
|
pitch_maximum = camera_info.camera->pitch_maximum;
|
|
|
|
if (camera_info.seat_index != NONE && unit->object.up.k > 0.2f)
|
|
{
|
|
real_euler_angles2d look_angles;
|
|
real_vector3d look_vector;
|
|
real tilt;
|
|
|
|
look_angles.yaw = player->desired_angles.yaw;
|
|
look_angles.pitch = 0.f;
|
|
vector3d_from_euler_angles2d(&look_vector, &look_angles);
|
|
tilt = _pi / 2.f - angle_between_vectors3d(&look_vector, &unit->object.up);
|
|
pitch_minimum -= tilt;
|
|
pitch_maximum -= tilt;
|
|
pitch_autolevel -= tilt;
|
|
}
|
|
|
|
pitch_minimum = PIN(
|
|
pitch_minimum,
|
|
-DEGREES_TO_RADIANS(85.5f),
|
|
DEGREES_TO_RADIANS(85.5f));
|
|
pitch_maximum = PIN(
|
|
pitch_maximum,
|
|
-DEGREES_TO_RADIANS(85.5f),
|
|
DEGREES_TO_RADIANS(85.5f));
|
|
}
|
|
|
|
if (pitch_autolevel != 0.f || player->unknown26)
|
|
{
|
|
real error = fabs(player->desired_angles.pitch - pitch_autolevel) * 0.63661975f;
|
|
|
|
match_assert_valid_real(
|
|
"c:\\halo\\SOURCE\\game\\player_control.c",
|
|
0x4F2,
|
|
player->desired_angles.pitch);
|
|
if (pitch_autolevel != 0.f)
|
|
{
|
|
interpolate_scalar(
|
|
&player->desired_angles.pitch,
|
|
pitch_autolevel,
|
|
magnitude3d(&unit->object.translational_velocity) * error * 0.08f);
|
|
}
|
|
else
|
|
{
|
|
interpolate_scalar(
|
|
&player->desired_angles.pitch,
|
|
pitch_autolevel,
|
|
magnitude3d(&unit->object.translational_velocity) *
|
|
constants->look_autolevel_scale * error);
|
|
}
|
|
match_assert_valid_real(
|
|
"c:\\halo\\SOURCE\\game\\player_control.c",
|
|
0x4FD,
|
|
player->desired_angles.pitch);
|
|
}
|
|
}
|
|
|
|
interpolate_scalar(&player->pitch_minimum, pitch_minimum, _pi / 256.f);
|
|
interpolate_scalar(&player->pitch_maximum, pitch_maximum, _pi / 256.f);
|
|
|
|
player->desired_angles.pitch += delta_pitch;
|
|
player->desired_angles.pitch = PIN(
|
|
player->desired_angles.pitch,
|
|
player->pitch_minimum,
|
|
player->pitch_maximum);
|
|
|
|
return;
|
|
}
|