// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // // //----------------------------------------------------------------------------- #ifndef __D_PLAYER_H__ #define __D_PLAYER_H__ // Finally, for odd reasons, the player input // is buffered within the player data struct, // as commands per game tick. #include "d_ticcmd.h" #include "doomstat.h" #include "a_artifacts.h" // The player data structure depends on a number // of other structs: items (internal inventory), // animation states (closely tied to the sprites // used to represent them, unfortunately). #include "p_pspr.h" // In addition, the player is just a special // case of the generic moving object/actor. #include "actor.h" //Added by MC: #include "b_bot.h" enum { APMETA_BASE = 0x95000, APMETA_DisplayName, // display name (used in menus etc.) APMETA_SoundClass, // sound class APMETA_Face, // doom status bar face (when used) APMETA_ColorRange, // skin color range APMETA_InvulMode, APMETA_HealingRadius, APMETA_Portrait, APMETA_Hexenarmor0, APMETA_Hexenarmor1, APMETA_Hexenarmor2, APMETA_Hexenarmor3, APMETA_Hexenarmor4, APMETA_Slot0, APMETA_Slot1, APMETA_Slot2, APMETA_Slot3, APMETA_Slot4, APMETA_Slot5, APMETA_Slot6, APMETA_Slot7, APMETA_Slot8, APMETA_Slot9, }; FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum); void P_EnumPlayerColorSets(FName classname, TArray *out); const char *GetPrintableDisplayName(const PClass *cls); class APlayerPawn : public AActor { DECLARE_CLASS (APlayerPawn, AActor) HAS_OBJECT_POINTERS public: virtual void Serialize (FArchive &arc); virtual void PostBeginPlay(); virtual void Tick(); virtual void AddInventory (AInventory *item); virtual void RemoveInventory (AInventory *item); virtual bool UseInventory (AInventory *item); virtual void MarkPrecacheSounds () const; virtual void PlayIdle (); virtual void PlayRunning (); virtual void ThrowPoisonBag (); virtual void TweakSpeeds (int &forwardmove, int &sidemove); virtual void MorphPlayerThink (); virtual void ActivateMorphWeapon (); AWeapon *PickNewWeapon (const PClass *ammotype); AWeapon *BestWeapon (const PClass *ammotype); void CheckWeaponSwitch(const PClass *ammotype); virtual void GiveDeathmatchInventory (); virtual void FilterCoopRespawnInventory (APlayerPawn *oldplayer); void SetupWeaponSlots (); void GiveDefaultInventory (); void PlayAttacking (); void PlayAttacking2 (); const char *GetSoundClass () const; enum EInvulState { INVUL_Start, INVUL_Active, INVUL_Stop, INVUL_GetAlpha }; void BeginPlay (); void Die (AActor *source, AActor *inflictor, int dmgflags); int crouchsprite; int MaxHealth; int MugShotMaxHealth; int RunHealth; int PlayerFlags; TObjPtr InvFirst; // first inventory item displayed on inventory bar TObjPtr InvSel; // selected inventory item // [GRB] Player class properties fixed_t JumpZ; fixed_t GruntSpeed; fixed_t FallingScreamMinSpeed, FallingScreamMaxSpeed; fixed_t ViewHeight; fixed_t ForwardMove1, ForwardMove2; fixed_t SideMove1, SideMove2; FTextureID ScoreIcon; int SpawnMask; FNameNoInit MorphWeapon; fixed_t AttackZOffset; // attack height, relative to player center fixed_t UseRange; // [NS] Distance at which player can +use fixed_t AirCapacity; // Multiplier for air supply underwater. const PClass *FlechetteType; // [CW] Fades for when you are being damaged. PalEntry DamageFade; bool UpdateWaterLevel (fixed_t oldz, bool splash); bool ResetAirSupply (bool playgasp = true); int GetMaxHealth() const; }; class APlayerChunk : public APlayerPawn { DECLARE_CLASS (APlayerChunk, APlayerPawn) }; // // PlayerPawn flags // enum { PPF_NOTHRUSTWHENINVUL = 1, // Attacks do not thrust the player if they are invulnerable. PPF_CANSUPERMORPH = 2, // Being remorphed into this class can give you a Tome of Power PPF_CROUCHABLEMORPH = 4, // This morphed player can crouch }; // // Player states. // typedef enum { PST_LIVE, // Playing or camping. PST_DEAD, // Dead on the ground, view follows killer. PST_REBORN, // Ready to restart/respawn??? PST_ENTER, // [BC] Entered the game PST_GONE // Player has left the game } playerstate_t; // // Player internal flags, for cheats and debug. // typedef enum { CF_NOCLIP = 1 << 0, // No clipping, walk through barriers. CF_GODMODE = 1 << 1, // No damage, no health loss. CF_NOVELOCITY = 1 << 2, // Not really a cheat, just a debug aid. CF_NOTARGET = 1 << 3, // [RH] Monsters don't target CF_FLY = 1 << 4, // [RH] Flying player CF_CHASECAM = 1 << 5, // [RH] Put camera behind player CF_FROZEN = 1 << 6, // [RH] Don't let the player move CF_REVERTPLEASE = 1 << 7, // [RH] Stick camera in player's head if (s)he moves CF_STEPLEFT = 1 << 9, // [RH] Play left footstep sound next time CF_FRIGHTENING = 1 << 10, // [RH] Scare monsters away CF_INSTANTWEAPSWITCH= 1 << 11, // [RH] Switch weapons instantly CF_TOTALLYFROZEN = 1 << 12, // [RH] All players can do is press +use CF_PREDICTING = 1 << 13, // [RH] Player movement is being predicted CF_INTERPVIEW = 1 << 14, // [RH] view was changed outside of input, so interpolate one frame CF_DRAIN = 1 << 16, // Player owns a drain powerup CF_HIGHJUMP = 1 << 18, // more Skulltag flags. Implementation not guaranteed though. ;) CF_REFLECTION = 1 << 19, CF_PROSPERITY = 1 << 20, CF_DOUBLEFIRINGSPEED= 1 << 21, // Player owns a double firing speed artifact CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths. CF_INFINITEAMMO = 1 << 23, // Player owns an infinite ammo artifact CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die CF_NOCLIP2 = 1 << 30, // [RH] More Quake-like noclip } cheat_t; enum { WF_WEAPONREADY = 1 << 0, // [RH] Weapon is in the ready state and can fire its primary attack WF_WEAPONBOBBING = 1 << 1, // [HW] Bob weapon while the player is moving WF_WEAPONREADYALT = 1 << 2, // Weapon can fire its secondary attack WF_WEAPONSWITCHOK = 1 << 3, // It is okay to switch away from this weapon WF_DISABLESWITCH = 1 << 4, // Disable weapon switching completely WF_WEAPONRELOADOK = 1 << 5, // [XA] Okay to reload this weapon. WF_WEAPONZOOMOK = 1 << 6, // [XA] Okay to use weapon zoom function. WF_REFIRESWITCHOK = 1 << 7, // Mirror WF_WEAPONSWITCHOK for A_ReFire }; #define WPIECE1 1 #define WPIECE2 2 #define WPIECE3 4 #define WP_NOCHANGE ((AWeapon*)~0) #define MAXPLAYERNAME 15 // [GRB] Custom player classes enum { PCF_NOMENU = 1, // Hide in new game menu }; class FPlayerClass { public: FPlayerClass (); FPlayerClass (const FPlayerClass &other); ~FPlayerClass (); bool CheckSkin (int skin); const PClass *Type; DWORD Flags; TArray Skins; }; extern TArray PlayerClasses; // User info (per-player copies of each CVAR_USERINFO cvar) enum { GENDER_MALE, GENDER_FEMALE, GENDER_NEUTER }; struct userinfo_t : TMap { ~userinfo_t(); int GetAimDist() const { if (dmflags2 & DF2_NOAUTOAIM) { return 0; } float aim = *static_cast(*CheckKey(NAME_Autoaim)); if (aim > 35 || aim < 0) { return ANGLE_1*35; } else { return xs_RoundToInt(fabs(aim * ANGLE_1)); } } const char *GetName() const { return *static_cast(*CheckKey(NAME_Name)); } int GetTeam() const { return *static_cast(*CheckKey(NAME_Team)); } int GetColorSet() const { return *static_cast(*CheckKey(NAME_ColorSet)); } uint32 GetColor() const { return *static_cast(*CheckKey(NAME_Color)); } bool GetNeverSwitch() const { return *static_cast(*CheckKey(NAME_NeverSwitchOnPickup)); } fixed_t GetMoveBob() const { return FLOAT2FIXED(*static_cast(*CheckKey(NAME_MoveBob))); } fixed_t GetStillBob() const { return FLOAT2FIXED(*static_cast(*CheckKey(NAME_StillBob))); } int GetPlayerClassNum() const { return *static_cast(*CheckKey(NAME_PlayerClass)); } const PClass *GetPlayerClassType() const { return PlayerClasses[GetPlayerClassNum()].Type; } int GetSkin() const { return *static_cast(*CheckKey(NAME_Skin)); } int GetGender() const { return *static_cast(*CheckKey(NAME_Gender)); } bool GetNoAutostartMap() const { return *static_cast(*CheckKey(NAME_Wi_NoAutostartMap)); } void Reset(); int TeamChanged(int team); int SkinChanged(const char *skinname, int playerclass); int SkinNumChanged(int skinnum); int GenderChanged(const char *gendername); int PlayerClassChanged(const char *classname); int PlayerClassNumChanged(int classnum); uint32 ColorChanged(const char *colorname); uint32 ColorChanged(uint32 colorval); int ColorSetChanged(int setnum); }; void ReadUserInfo(FArchive &arc, userinfo_t &info, FString &skin); void WriteUserInfo(FArchive &arc, userinfo_t &info); // // Extended player object info: player_t // class player_t { public: player_t(); player_t &operator= (const player_t &p); void Serialize (FArchive &arc); size_t FixPointers (const DObject *obj, DObject *replacement); size_t PropagateMark(); void SetLogNumber (int num); void SetLogText (const char *text); void SendPitchLimits() const; APlayerPawn *mo; BYTE playerstate; ticcmd_t cmd; usercmd_t original_cmd; DWORD original_oldbuttons; userinfo_t userinfo; // [RH] who is this? const PClass *cls; // class of associated PlayerPawn float DesiredFOV; // desired field of vision float FOV; // current field of vision fixed_t viewz; // focal origin above r.z fixed_t viewheight; // base height above floor for viewz fixed_t deltaviewheight; // squat speed. fixed_t bob; // bounded/scaled total velocity // killough 10/98: used for realistic bobbing (i.e. not simply overall speed) // mo->velx and mo->vely represent true velocity experienced by player. // This only represents the thrust that the player applies himself. // This avoids anomalies with such things as Boom ice and conveyors. fixed_t velx, vely; // killough 10/98 bool centering; BYTE turnticks; bool attackdown; bool usedown; DWORD oldbuttons; int health; // only used between levels, mo->health // is used during levels int inventorytics; BYTE CurrentPlayerClass; // class # for this player instance int frags[MAXPLAYERS]; // kills of other players int fragcount; // [RH] Cumulative frags for this player int lastkilltime; // [RH] For multikills BYTE multicount; BYTE spreecount; // [RH] Keep track of killing sprees BYTE WeaponState; AWeapon *ReadyWeapon; AWeapon *PendingWeapon; // WP_NOCHANGE if not changing int cheats; // bit flags int timefreezer; // Player has an active time freezer short refire; // refired shots are less accurate short inconsistant; bool waiting; int killcount, itemcount, secretcount; // for intermission int damagecount, bonuscount;// for screen flashing int hazardcount; // for delayed Strife damage int poisoncount; // screen flash for poison damage FName poisontype; // type of poison damage to apply FName poisonpaintype; // type of Pain state to enter for poison damage TObjPtr poisoner; // NULL for non-player actors TObjPtr attacker; // who did damage (NULL for floors) int extralight; // so gun flashes light up areas short fixedcolormap; // can be set to REDCOLORMAP, etc. short fixedlightlevel; pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc) int morphTics; // player is a chicken/pig if > 0 const PClass *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed int MorphStyle; // which effects to apply for this player instance when morphed const PClass *MorphExitFlash; // flash to apply when demorphing (cache of value given to P_MorphPlayer) TObjPtr PremorphWeapon; // ready weapon before morphing int chickenPeck; // chicken peck countdown int jumpTics; // delay the next jump for a moment bool onground; // Identifies if this player is on the ground or other object int respawn_time; // [RH] delay respawning until this tic TObjPtr camera; // [RH] Whose eyes this player sees through int air_finished; // [RH] Time when you start drowning FName LastDamageType; // [RH] For damage-specific pain and death sounds //Added by MC: FBot Bot; bool settings_controller; // Player can control game settings. float BlendR; // [RH] Final blending values float BlendG; float BlendB; float BlendA; FString LogText; // [RH] Log for Strife int MinPitch; // Viewpitch limits (negative is up, positive is down) int MaxPitch; SBYTE crouching; SBYTE crouchdir; fixed_t crouchfactor; fixed_t crouchoffset; fixed_t crouchviewdelta; FWeaponSlots weapons; // [CW] I moved these here for multiplayer conversation support. TObjPtr ConversationNPC, ConversationPC; angle_t ConversationNPCAngle; bool ConversationFaceTalker; fixed_t GetDeltaViewHeight() const { return (mo->ViewHeight + crouchviewdelta - viewheight) >> 3; } void Uncrouch() { crouchfactor = FRACUNIT; crouchoffset = 0; crouchdir = 0; crouching = 0; crouchviewdelta = 0; } bool CanCrouch() const { return morphTics == 0 || mo->PlayerFlags & PPF_CROUCHABLEMORPH; } int GetSpawnClass(); }; // Bookkeeping on players - state. extern player_t players[MAXPLAYERS]; FArchive &operator<< (FArchive &arc, player_t *&p); void P_CheckPlayerSprite(AActor *mo, int &spritenum, fixed_t &scalex, fixed_t &scaley); inline void AActor::SetFriendPlayer(player_t *player) { if (player == NULL) { FriendPlayer = 0; } else { FriendPlayer = int(player - players) + 1; } } inline bool AActor::IsNoClip2() const { if (player != NULL && player->mo == this) { return (player->cheats & CF_NOCLIP2) != 0; } return false; } #define CROUCHSPEED (FRACUNIT/12) bool P_IsPlayerTotallyFrozen(const player_t *player); #endif // __D_PLAYER_H__