scummvm/engines/icb/player.h
2021-12-26 21:19:38 +01:00

423 lines
12 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1999-2000 Revolution Software Ltd.
* This code is based on source code created by Revolution Software,
* used with permission.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ICB_PLAYER
#define ICB_PLAYER
#include "engines/icb/common/px_common.h"
#include "engines/icb/debug.h"
#include "engines/icb/object_structs.h"
#include "engines/icb/common/px_route_barriers.h"
#include "engines/icb/common/px_scriptengine.h"
#include "engines/icb/animation_mega_set.h"
#include "engines/icb/fn_routines.h"
#include "engines/icb/bone.h"
namespace ICB {
extern int32 armedChangesMode;
extern int32 animToggles;
extern PXreal REPEL_TURN;
extern PXreal REPULSE_DISTANCE;
extern int32 CAMERA_SMOOTH_CYCLES;
// How deep the player control mode stack is !
#define CONTROL_MODE_STACK_DEPTH 4
// The maximum number of ammo clips the player can carry
static const uint32 MAX_AMMO_CLIPS = 5;
// The maximum number of hit points the player has
static const uint32 MAX_HITS = 10;
// the player service is not tied to the session but exists as a global engine service
enum _player_stat {
STOOD, // 1
WALKING, // 2
CROUCH_WALK, // 3
RUNNING, // 4
CROUCH_TO_PUNCH, // 5
CROUCH_TO_STAND_UNARMED, // 6
CROUCH_TO_STAND_ARMED, // 7
CROUCHING, // 8
NEW_AIM, // 9
CROUCH_AIM, // 10
PUTTING_AWAY_GUN, // 11
PUTTING_AWAY_CROUCH_GUN, // 12
LINKING, // 13
GUN_LINKING, // 14
FAST_LINKING, // 15
EASY_LINKING, // 16
REVERSE_LINKING, // 17
FAST_REVERSE_LINKING, // 18
STILL_LINKING, // 19
INVENTORY, // 20
REMORA, // 21
STRIKING, // 22
ON_STAIRS, // 23
RUNNING_ON_STAIRS, // 24
STOOD_ON_STAIRS, // 25
REVERSE_ON_STAIRS, // 26
ON_LADDER, // 27
BEGIN_DOWN_LADDER, // 28
LEAVE_LADDER, // 29
LEAVE_LADDER_BOTTOM, // 30
SLIP_SLIDIN_AWAY, // 31
FINISHED_RELOADING, // 32
FIN_NORMAL_RELOAD, // 33
FIN_NORMAL_CROUCH_RELOAD, // 34
STILL_REVERSE_LINKING, // 35
__TOTAL_PLAYER_MODES
};
// routines called from gateway return one of these
enum __mode_return { __FINISHED_THIS_CYCLE, __MORE_THIS_CYCLE };
// these are the raw input device states that the player control interface is derived from
enum __player_momentum {
__STILL,
__BACKWARD_1,
__FORWARD_1,
__FORWARD_2, // only analogue device
__FORWARD_3
};
enum __player_turn {
__NO_TURN,
__LEFT,
__RIGHT,
// psx and pc analogue devices only
__HARD_LEFT, // analogue controllers only - will stop forward momentum and instigate a turn on spot
__HARD_RIGHT // as above
};
enum __player_button {
// PlayStation PC Default Use
__BUTTON_1, // X ctrl fire
__BUTTON_2, // O space interact
__BUTTON_3, // Rshift unused
__BUTTON_4, // /\ enter inventory
__BUTTON_5, // delete unused
__BUTTON_6, // R2 Lshift remora
__BUTTON_7, // L1 Ralt sidestep
__NO_BUTTON
};
// Powers of two bit-flag settings
enum ButtonEnums {
__INTERACT = 1,
__ATTACK = 2, // fire or punch
__INVENTORY = 4,
__ARMUNARM = 8,
__REMORA = 16,
__CROUCH = 32,
__SIDESTEP = 64, // this is a movement modifier button
__WALKBACK = 64, // this is a movement modifier button
__JOG = 128, // RUN !
__UNUSEDBUTTON = 256
}; // Note, __EXAMINE was never used
struct _input {
__player_momentum momentum;
__player_turn turn;
int32 bitflag;
void SetButton(const enum ButtonEnums b) { bitflag |= b; }
void UnSetButton(const enum ButtonEnums b) { bitflag &= ~b; }
uint32 IsButtonSet(const enum ButtonEnums b) const {
return (bitflag & b);
}
};
typedef struct {
PXreal x, z;
bool8 stepped_on_step;
} _step_sample;
#define MAX_stair_length 40
#define TOP_stair_num (MAX_stair_length - 1)
enum __pc_input { __KEYS, __OTHER_DI_DEVICE };
// What type of control system is being by the player
enum __Actor_control_mode { ACTOR_RELATIVE, SCREEN_RELATIVE };
class _player {
public:
void ___init();
void Set_player_id(uint32 id);
uint32 Fetch_player_id();
mcodeFunctionReturnCodes Gateway();
void Update_input_state();
void DrawCompass();
void Find_current_player_interact_object();
void Render_crude_interact_highlight();
uint32 Fetch_player_interact_id();
bool8 Fetch_player_interact_status();
bool8 Player_exists();
void Reset_player();
_input *Fetch_input_state();
uint32 GetBulletsPerClip();
uint32 GetMaxClips();
int32 GetNoBullets();
void SetBullets(uint32 num);
void UseBullets(uint32 num);
int32 GetNoAmmoClips();
void AddAmmoClips(uint32 num, bool8 bFlashIcons);
void UseAmmoClips(uint32 num);
int32 GetNoMediPacks();
void AddMediPacks(uint32 num, bool8 bFlashIcons);
void UseMediPacks(uint32 num);
__mode_return Player_walking();
__mode_return Player_crouch_walk();
__mode_return Player_running();
__mode_return Player_stood();
__mode_return Player_crouching();
__mode_return Player_aiming();
__mode_return Player_new_aim();
__mode_return Player_crouch_aim();
__mode_return Process_strike();
__mode_return Player_stairs();
__mode_return Player_running_on_stairs();
__mode_return Player_stood_on_stairs();
__mode_return Player_ladder();
__mode_return Player_slide_on_ladder();
void Leave_stair();
__mode_return Process_link();
__mode_return Process_fast_link();
__mode_return Process_reverse_link();
__mode_return Process_easy_link();
__mode_return Process_still_link();
__mode_return Process_reverse_still_link();
__mode_return Player_interact();
__mode_return Player_press_fire_button();
__mode_return Player_press_inv_button();
__mode_return Player_press_strike_button();
__mode_return Player_press_remora_button();
void Add_to_interact_history();
void Set_to_first_frame(__mega_set_names opt_link);
void Set_to_last_frame(__mega_set_names opt_link);
void Start_new_mode(_player_stat new_mode);
void Soft_start_new_mode_no_link(_player_stat new_mode, __mega_set_names type);
void Soft_start_new_mode(_player_stat new_mode, __mega_set_names opt_link);
void Soft_start_new_mode(_player_stat new_mode, __mega_set_names opt_link, __mega_set_names opt_link2);
void Hard_start_new_mode(_player_stat new_mode, __mega_set_names opt_link);
void Fast_hard_start_new_mode(_player_stat new_mode, __mega_set_names opt_link);
void Hard_start_reverse_new_mode(_player_stat new_mode, __mega_set_names opt_link);
void Easy_start_new_mode(_player_stat new_mode, __mega_set_names opt_link);
void Still_start_new_mode(_player_stat new_mode, __mega_set_names link);
void Still_reverse_start_new_mode(_player_stat new_mode, __mega_set_names link);
bool8 Advance_frame_motion_and_pan(__mega_set_names anim_type);
bool8 Reverse_frame_motion_and_pan(__mega_set_names anim_type);
void Set_player_status(_player_stat new_mode);
inline void Push_control_mode(__Actor_control_mode newMode);
inline void Pop_control_mode();
inline void Set_control_mode(__Actor_control_mode newMode);
inline __Actor_control_mode Get_control_mode();
void Push_player_stat();
void Pop_player_stat();
// the master high level switch
uint32 player_id; // number of object file of the player object - set this for fast access to structs in sub-modules
_logic *log; // for the objects logic structure
// high level master mode switch
_player_stat player_status;
// player status to switch to after link animation has finished
_player_stat stat_after_link;
// pushed stat
_player_stat previous_stat;
// input device state calculated at start of each cycle
_input cur_state;
uint32 inv_cycle_count;
uint32 cur_interact_id; // id number of nico - which has same name as game object
uint32 look_at_id; // when no interact id exists we may look-at a more distant prop
// __Actor_control_mode control_mode_stack[CONTROL_MODE_STACK_DEPTH];
__Actor_control_mode focus_mode;
__Actor_control_mode master_mode;
PXfloat lastCameraPan;
PXfloat deltaCameraPan;
PXfloat scrnPan;
PXfloat aim_turn_amount; // ANGLE_UNITS_PER_GAME_CYCLE
PXfloat stood_turn_amount; // ANGLE_UNITS_PER_GAME_CYCLE
PXfloat stood_fast_turn_amount; // ANGLE_UNITS_PER_GAME_CYCLE
PXfloat walk_turn_amount; // ANGLE_UNITS_PER_GAME_CYCLE
PXfloat run_turn_amount; // ANGLE_UNITS_PER_GAME_CYCLE
PXfloat crouch_turn_amount; // ANGLE_UNITS_PER_GAME_CYCLE
// yes, its that stair drift correction system
_step_sample step_samples[MAX_stair_length];
BoneDeformation shotDeformation;
// Note these are at the end of the structure to keep DWORD alignment
uint8 panCycle;
bool8 crouch;
bool8 backward_lock; // set to TRUE to stop repeating backward steps
bool8 forward_lock;
bool8 remora_lock;
bool8 interact_lock;
bool8 fire_lock;
bool8 inv_lock;
bool8 has_weapon;
bool8 interact_selected; // is there a current player interact object?
bool8 look_at_selected; // sometimes when there is no interact
bool8 dead_mega; // is the target dead or not - if a mega
// set to true when
bool8 player_exists;
bool8 haveCamera;
bool8 hunting;
// stairway stuff
uint8 stair_num; // stair number we're on
uint8 stair_dir; // 1 up, 0 down
uint8 stair_unit; // how many cycles into stair are we
uint8 left_right; // 1 left / 0 right
uint8 was_climbing; // 1 yes, 0 no - used to see if first stand
uint8 begun_at_bottom; // used when deciding to write history
int8 being_shot;
int8 shot_by_id;
int32 step_sample_num;
int8 walk_count; // counts up as you walk - used to alert guards of non creeping player
bool8 stood_on_lift; // are we stood on a lift
// armed menu
uint8 padding[2];
// SORTED PADDING AGAIN. MAYBE IT'S NOT IMPORTANT, 'COS EVERY TIME I GO TO WELL-USED CLASSES
// LIKE PLAYER, THE ALLIGNMENT IS ALL OVER THE PLACE.
};
inline bool8 _player::Player_exists() {
// return id of player object
return (player_exists);
}
inline uint32 _player::Fetch_player_id() {
// return id of player object
if (!player_exists)
Fatal_error("no live player - must stop");
return (player_id);
}
inline uint32 _player::Fetch_player_interact_id() {
// return id of player object
return (cur_interact_id);
}
inline bool8 _player::Fetch_player_interact_status() {
// return id of player object
return (interact_selected);
}
inline _input *_player::Fetch_input_state() {
// return id of player object
return (&cur_state);
}
inline void _player::Push_control_mode(__Actor_control_mode newMode) { focus_mode = newMode; }
inline void _player::Set_control_mode(__Actor_control_mode newMode) {
focus_mode = newMode;
master_mode = newMode;
}
inline void _player::Pop_control_mode() {}
inline __Actor_control_mode _player::Get_control_mode() { return focus_mode; }
extern uint32 fire_key;
extern uint32 interact_key;
extern uint32 inventory_key;
extern uint32 arm_key;
extern uint32 remora_key;
extern uint32 crouch_key;
extern uint32 sidestep_key;
extern uint32 run_key;
extern uint32 pause_key;
extern uint32 up_key;
extern uint32 down_key;
extern uint32 left_key;
extern uint32 right_key;
} // End of namespace ICB
#endif