- Update scripting branch to trunk.
SVN r3758 (scripting)
This commit is contained in:
commit
562cf04db2
614 changed files with 63691 additions and 31256 deletions
381
src/p_user.cpp
381
src/p_user.cpp
|
|
@ -30,7 +30,6 @@
|
|||
#include "doomstat.h"
|
||||
#include "s_sound.h"
|
||||
#include "i_system.h"
|
||||
#include "r_draw.h"
|
||||
#include "gi.h"
|
||||
#include "m_random.h"
|
||||
#include "p_pspr.h"
|
||||
|
|
@ -44,7 +43,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "cmdlib.h"
|
||||
#include "sbar.h"
|
||||
#include "f_finale.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "c_console.h"
|
||||
#include "doomdef.h"
|
||||
#include "c_dispatch.h"
|
||||
|
|
@ -52,6 +51,9 @@
|
|||
#include "thingdef/thingdef.h"
|
||||
#include "g_level.h"
|
||||
#include "d_net.h"
|
||||
#include "gstrings.h"
|
||||
#include "farchive.h"
|
||||
#include "r_renderer.h"
|
||||
|
||||
static FRandom pr_skullpop ("SkullPop");
|
||||
|
||||
|
|
@ -95,40 +97,57 @@ bool FPlayerClass::CheckSkin (int skin)
|
|||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// GetDisplayName
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FString GetPrintableDisplayName(PClassPlayerPawn *cls)
|
||||
{
|
||||
// Fixme; This needs a decent way to access the string table without creating a mess.
|
||||
// [RH] ????
|
||||
return cls->DisplayName;
|
||||
}
|
||||
|
||||
bool ValidatePlayerClass(PClassActor *ti, const char *name)
|
||||
{
|
||||
if (ti == NULL)
|
||||
{
|
||||
Printf("Unknown player class '%s'\n", name);
|
||||
return false;
|
||||
}
|
||||
else if (!ti->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)))
|
||||
{
|
||||
Printf("Invalid player class '%s'\n", name);
|
||||
return false;
|
||||
}
|
||||
else if (static_cast<PClassPlayerPawn *>(ti)->DisplayName.IsEmpty())
|
||||
{
|
||||
Printf ("Missing displayname for player class '%s'\n", name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetupPlayerClasses ()
|
||||
{
|
||||
FPlayerClass newclass;
|
||||
|
||||
newclass.Flags = 0;
|
||||
|
||||
if (gameinfo.gametype == GAME_Doom)
|
||||
PlayerClasses.Clear();
|
||||
for (unsigned i = 0; i < gameinfo.PlayerClasses.Size(); i++)
|
||||
{
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(PClass::FindClass(NAME_DoomPlayer));
|
||||
PlayerClasses.Push(newclass);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Heretic)
|
||||
{
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(PClass::FindClass(NAME_HereticPlayer));
|
||||
PlayerClasses.Push(newclass);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(PClass::FindClass(NAME_FighterPlayer));
|
||||
PlayerClasses.Push(newclass);
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(PClass::FindClass(NAME_ClericPlayer));
|
||||
PlayerClasses.Push(newclass);
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(PClass::FindClass(NAME_MagePlayer));
|
||||
PlayerClasses.Push(newclass);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(PClass::FindClass(NAME_StrifePlayer));
|
||||
PlayerClasses.Push(newclass);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Chex)
|
||||
{
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(PClass::FindClass(NAME_ChexPlayer));
|
||||
PlayerClasses.Push(newclass);
|
||||
PClassActor *cls = PClass::FindActor(gameinfo.PlayerClasses[i]);;
|
||||
if (ValidatePlayerClass(cls, gameinfo.PlayerClasses[i]))
|
||||
{
|
||||
newclass.Flags = 0;
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(cls);
|
||||
if ((GetDefaultByType(cls)->flags6 & MF6_NOMENU))
|
||||
{
|
||||
newclass.Flags |= PCF_NOMENU;
|
||||
}
|
||||
PlayerClasses.Push(newclass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -144,25 +163,17 @@ CCMD (addplayerclass)
|
|||
{
|
||||
if (ParsingKeyConf && argv.argc () > 1)
|
||||
{
|
||||
PClassPlayerPawn *ti = dyn_cast<PClassPlayerPawn>(PClass::FindClass(argv[1]));
|
||||
PClassActor *ti = PClass::FindActor(argv[1]);
|
||||
|
||||
if (ti == NULL)
|
||||
{
|
||||
Printf ("Unknown player class '%s'\n", argv[1]);
|
||||
}
|
||||
else if (ti->DisplayName.IsEmpty())
|
||||
{
|
||||
Printf ("Missing displayname for player class '%s'\n", argv[1]);
|
||||
}
|
||||
else
|
||||
if (ValidatePlayerClass(ti, argv[1]))
|
||||
{
|
||||
FPlayerClass newclass;
|
||||
|
||||
newclass.Type = ti;
|
||||
newclass.Type = static_cast<PClassPlayerPawn *>(ti);
|
||||
newclass.Flags = 0;
|
||||
|
||||
int arg = 2;
|
||||
while (arg < argv.argc ())
|
||||
while (arg < argv.argc())
|
||||
{
|
||||
if (!stricmp (argv[arg], "nomenu"))
|
||||
{
|
||||
|
|
@ -184,7 +195,9 @@ CCMD (playerclasses)
|
|||
{
|
||||
for (unsigned int i = 0; i < PlayerClasses.Size (); i++)
|
||||
{
|
||||
Printf("% 3d %s\n", i, PlayerClasses[i].Type->DisplayName.GetChars());
|
||||
Printf ("%3d: Class = %s, Name = %s\n", i,
|
||||
PlayerClasses[i].Type->TypeName.GetChars(),
|
||||
PlayerClasses[i].Type->DisplayName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,6 +211,11 @@ CCMD (playerclasses)
|
|||
|
||||
bool onground;
|
||||
|
||||
FArchive &operator<< (FArchive &arc, player_t *&p)
|
||||
{
|
||||
return arc.SerializePointer (players, (BYTE **)&p, sizeof(*players));
|
||||
}
|
||||
|
||||
// The player_t constructor. Since LogText is not a POD, we cannot just
|
||||
// memset it all to 0.
|
||||
player_t::player_t()
|
||||
|
|
@ -228,6 +246,7 @@ player_t::player_t()
|
|||
ReadyWeapon(0),
|
||||
PendingWeapon(0),
|
||||
cheats(0),
|
||||
timefreezer(0),
|
||||
refire(0),
|
||||
inconsistant(0),
|
||||
killcount(0),
|
||||
|
|
@ -250,8 +269,6 @@ player_t::player_t()
|
|||
respawn_time(0),
|
||||
camera(0),
|
||||
air_finished(0),
|
||||
accuracy(0),
|
||||
stamina(0),
|
||||
savedyaw(0),
|
||||
savedpitch(0),
|
||||
angle(0),
|
||||
|
|
@ -309,21 +326,25 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep)
|
|||
{
|
||||
APlayerPawn *replacement = static_cast<APlayerPawn *>(rep);
|
||||
size_t changed = 0;
|
||||
if (mo == old) mo = replacement, changed++;
|
||||
if (poisoner == old) poisoner = replacement, changed++;
|
||||
if (attacker == old) attacker = replacement, changed++;
|
||||
if (camera == old) camera = replacement, changed++;
|
||||
if (dest == old) dest = replacement, changed++;
|
||||
if (prev == old) prev = replacement, changed++;
|
||||
if (enemy == old) enemy = replacement, changed++;
|
||||
if (missile == old) missile = replacement, changed++;
|
||||
if (mate == old) mate = replacement, changed++;
|
||||
if (last_mate == old) last_mate = replacement, changed++;
|
||||
if (ReadyWeapon == old) ReadyWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (PendingWeapon == old) PendingWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (ConversationNPC == old) ConversationNPC = replacement, changed++;
|
||||
if (ConversationPC == old) ConversationPC = replacement, changed++;
|
||||
|
||||
// The construct *& is used in several of these to avoid the read barriers
|
||||
// that would turn the pointer we want to check to NULL if the old object
|
||||
// is pending deletion.
|
||||
if (mo == old) mo = replacement, changed++;
|
||||
if (*&poisoner == old) poisoner = replacement, changed++;
|
||||
if (*&attacker == old) attacker = replacement, changed++;
|
||||
if (*&camera == old) camera = replacement, changed++;
|
||||
if (*&dest == old) dest = replacement, changed++;
|
||||
if (*&prev == old) prev = replacement, changed++;
|
||||
if (*&enemy == old) enemy = replacement, changed++;
|
||||
if (*&missile == old) missile = replacement, changed++;
|
||||
if (*&mate == old) mate = replacement, changed++;
|
||||
if (*&last_mate == old) last_mate = replacement, changed++;
|
||||
if (ReadyWeapon == old) ReadyWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (PendingWeapon == old) PendingWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (*&PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (*&ConversationNPC == old) ConversationNPC = replacement, changed++;
|
||||
if (*&ConversationPC == old) ConversationPC = replacement, changed++;
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
|
@ -450,6 +471,25 @@ void PClassPlayerPawn::EnumColorSets(TArray<int> *out)
|
|||
qsort(&(*out)[0], out->Size(), sizeof(int), intcmp);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// player_t :: SendPitchLimits
|
||||
//
|
||||
// Ask the local player's renderer what pitch restrictions should be imposed
|
||||
// and let everybody know. Only sends data for the consoleplayer, since the
|
||||
// local player is the only one our data is valid for.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void player_t::SendPitchLimits() const
|
||||
{
|
||||
if (this - players == consoleplayer)
|
||||
{
|
||||
Net_WriteByte(DEM_SETPITCHLIMIT);
|
||||
Net_WriteByte(Renderer->GetMaxViewPitch(false)); // up
|
||||
Net_WriteByte(Renderer->GetMaxViewPitch(true)); // down
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
@ -481,11 +521,8 @@ void APlayerPawn::Serialize (FArchive &arc)
|
|||
<< InvSel
|
||||
<< MorphWeapon
|
||||
<< DamageFade
|
||||
<< PlayerFlags;
|
||||
if (SaveVersion < 2435)
|
||||
{
|
||||
DamageFade.a = 255;
|
||||
}
|
||||
<< PlayerFlags
|
||||
<< FlechetteType;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -558,6 +595,7 @@ void APlayerPawn::Tick()
|
|||
|
||||
void APlayerPawn::PostBeginPlay()
|
||||
{
|
||||
Super::PostBeginPlay();
|
||||
SetupWeaponSlots();
|
||||
|
||||
// Voodoo dolls: restore original floorz/ceilingz logic
|
||||
|
|
@ -565,9 +603,13 @@ void APlayerPawn::PostBeginPlay()
|
|||
{
|
||||
dropoffz = floorz = Sector->floorplane.ZatPoint(x, y);
|
||||
ceilingz = Sector->ceilingplane.ZatPoint(x, y);
|
||||
P_FindFloorCeiling(this, true);
|
||||
P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS);
|
||||
z = floorz;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->SendPitchLimits();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -585,11 +627,21 @@ void APlayerPawn::SetupWeaponSlots()
|
|||
if (player != NULL && player->mo == this)
|
||||
{
|
||||
player->weapons.StandardSetup(GetClass());
|
||||
if (player - players == consoleplayer)
|
||||
{ // If we're the local player, then there's a bit more work to do.
|
||||
// If we're the local player, then there's a bit more work to do.
|
||||
// This also applies if we're a bot and this is the net arbitrator.
|
||||
if (player - players == consoleplayer ||
|
||||
(player->isbot && consoleplayer == Net_Arbitrator))
|
||||
{
|
||||
FWeaponSlots local_slots(player->weapons);
|
||||
local_slots.LocalSetup(GetClass());
|
||||
local_slots.SendDifferences(player->weapons);
|
||||
if (player->isbot)
|
||||
{ // Bots only need weapons from KEYCONF, not INI modifications.
|
||||
P_PlaybackKeyConfWeapons(&local_slots);
|
||||
}
|
||||
else
|
||||
{
|
||||
local_slots.LocalSetup(GetClass());
|
||||
}
|
||||
local_slots.SendDifferences(int(player - players), player->weapons);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -683,7 +735,7 @@ bool APlayerPawn::UseInventory (AInventory *item)
|
|||
{ // You can't use items if you're totally frozen
|
||||
return false;
|
||||
}
|
||||
if (( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE )))
|
||||
if ((level.flags2 & LEVEL2_FROZEN) && (player == NULL || player->timefreezer == 0))
|
||||
{
|
||||
// Time frozen
|
||||
return false;
|
||||
|
|
@ -712,13 +764,13 @@ bool APlayerPawn::UseInventory (AInventory *item)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
AWeapon *APlayerPawn::BestWeapon (const PClass *ammotype)
|
||||
AWeapon *APlayerPawn::BestWeapon(PClassAmmo *ammotype)
|
||||
{
|
||||
AWeapon *bestMatch = NULL;
|
||||
int bestOrder = INT_MAX;
|
||||
AInventory *item;
|
||||
AWeapon *weap;
|
||||
bool tomed = NULL != FindInventory (RUNTIME_CLASS(APowerWeaponLevel2));
|
||||
bool tomed = NULL != FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true);
|
||||
|
||||
// Find the best weapon the player has.
|
||||
for (item = Inventory; item != NULL; item = item->Inventory)
|
||||
|
|
@ -768,7 +820,7 @@ AWeapon *APlayerPawn::BestWeapon (const PClass *ammotype)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
AWeapon *APlayerPawn::PickNewWeapon (const PClass *ammotype)
|
||||
AWeapon *APlayerPawn::PickNewWeapon(PClassAmmo *ammotype)
|
||||
{
|
||||
AWeapon *best = BestWeapon (ammotype);
|
||||
|
||||
|
|
@ -796,7 +848,7 @@ AWeapon *APlayerPawn::PickNewWeapon (const PClass *ammotype)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void APlayerPawn::CheckWeaponSwitch(const PClass *ammotype)
|
||||
void APlayerPawn::CheckWeaponSwitch(PClassAmmo *ammotype)
|
||||
{
|
||||
if (!player->userinfo.neverswitch &&
|
||||
player->PendingWeapon == WP_NOCHANGE &&
|
||||
|
|
@ -969,6 +1021,7 @@ void APlayerPawn::FilterCoopRespawnInventory (APlayerPawn *oldplayer)
|
|||
const char *APlayerPawn::GetSoundClass ()
|
||||
{
|
||||
if (player != NULL &&
|
||||
(player->mo == NULL || !(player->mo->flags4 &MF4_NOSKIN)) &&
|
||||
(unsigned int)player->userinfo.skin >= PlayerClasses.Size () &&
|
||||
(size_t)player->userinfo.skin < numskins)
|
||||
{
|
||||
|
|
@ -1208,15 +1261,15 @@ void APlayerPawn::ActivateMorphWeapon ()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
||||
void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags)
|
||||
{
|
||||
Super::Die (source, inflictor);
|
||||
Super::Die (source, inflictor, dmgflags);
|
||||
|
||||
if (player != NULL && player->mo == this) player->bonuscount = 0;
|
||||
|
||||
if (player != NULL && player->mo != this)
|
||||
{ // Make the real player die, too
|
||||
player->mo->Die (source, inflictor);
|
||||
player->mo->Die (source, inflictor, dmgflags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1227,6 +1280,22 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
|||
{
|
||||
AInventory *item;
|
||||
|
||||
// kgDROP - start - modified copy from a_action.cpp
|
||||
DDropItem *di = weap->GetDropItems();
|
||||
|
||||
if (di != NULL)
|
||||
{
|
||||
while (di != NULL)
|
||||
{
|
||||
if (di->Name != NAME_None)
|
||||
{
|
||||
PClassActor *ti = PClass::FindActor(di->Name);
|
||||
if (ti) P_DropItem (player->mo, ti, di->Amount, di->Probability);
|
||||
}
|
||||
di = di->Next;
|
||||
}
|
||||
} else
|
||||
// kgDROP - end
|
||||
if (weap->SpawnState != NULL &&
|
||||
weap->SpawnState != ::GetDefault<AActor>()->SpawnState)
|
||||
{
|
||||
|
|
@ -1261,9 +1330,9 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!multiplayer && (level.flags2 & LEVEL2_DEATHSLIDESHOW))
|
||||
if (!multiplayer && level.info->deathsequence != NAME_None)
|
||||
{
|
||||
F_StartSlideshow ();
|
||||
F_StartIntermission(level.info->deathsequence, FSTATE_EndingGame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1483,7 +1552,6 @@ void P_CheckPlayerSprites()
|
|||
// Set the crouch sprite
|
||||
if (player->crouchfactor < FRACUNIT*3/4)
|
||||
{
|
||||
|
||||
if (mo->sprite == mo->SpawnState->sprite || mo->sprite == mo->crouchsprite)
|
||||
{
|
||||
crouchspriteno = mo->crouchsprite;
|
||||
|
|
@ -1512,13 +1580,16 @@ void P_CheckPlayerSprites()
|
|||
}
|
||||
else // Set the normal sprite
|
||||
{
|
||||
if (mo->sprite == mo->crouchsprite)
|
||||
if (mo->sprite != 0)
|
||||
{
|
||||
mo->sprite = mo->SpawnState->sprite;
|
||||
}
|
||||
else if (mo->sprite == skins[player->userinfo.skin].crouchsprite)
|
||||
{
|
||||
mo->sprite = skins[player->userinfo.skin].sprite;
|
||||
if (mo->sprite == mo->crouchsprite)
|
||||
{
|
||||
mo->sprite = mo->SpawnState->sprite;
|
||||
}
|
||||
else if (mo->sprite != 0 && mo->sprite == skins[player->userinfo.skin].crouchsprite)
|
||||
{
|
||||
mo->sprite = skins[player->userinfo.skin].sprite;
|
||||
}
|
||||
}
|
||||
mo->scaleY = defscaleY;
|
||||
}
|
||||
|
|
@ -2136,9 +2207,7 @@ void P_PlayerThink (player_t *player)
|
|||
player->mo->flags &= ~MF_JUSTATTACKED;
|
||||
}
|
||||
|
||||
bool totallyfrozen = (player->cheats & CF_TOTALLYFROZEN || gamestate == GS_TITLELEVEL ||
|
||||
(( level.flags2 & LEVEL2_FROZEN ) && ( player == NULL || !( player->cheats & CF_TIMEFREEZE )))
|
||||
);
|
||||
bool totallyfrozen = P_IsPlayerTotallyFrozen(player);
|
||||
|
||||
// [RH] Being totally frozen zeros out most input parameters.
|
||||
if (totallyfrozen)
|
||||
|
|
@ -2210,9 +2279,13 @@ void P_PlayerThink (player_t *player)
|
|||
P_DeathThink (player);
|
||||
return;
|
||||
}
|
||||
if (player->jumpTics)
|
||||
if (player->jumpTics != 0)
|
||||
{
|
||||
player->jumpTics--;
|
||||
if (onground && player->jumpTics < -18)
|
||||
{
|
||||
player->jumpTics = 0;
|
||||
}
|
||||
}
|
||||
if (player->morphTics && !(player->cheats & CF_PREDICTING))
|
||||
{
|
||||
|
|
@ -2236,22 +2309,47 @@ void P_PlayerThink (player_t *player)
|
|||
{
|
||||
if (look == -32768 << 16)
|
||||
{ // center view
|
||||
player->mo->pitch = 0;
|
||||
player->centering = true;
|
||||
}
|
||||
else
|
||||
else if (!player->centering)
|
||||
{
|
||||
fixed_t oldpitch = player->mo->pitch;
|
||||
player->mo->pitch -= look;
|
||||
if (look > 0)
|
||||
{ // look up
|
||||
player->mo->pitch = MAX(player->mo->pitch, screen->GetMaxViewPitch(false));
|
||||
player->mo->pitch = MAX(player->mo->pitch, player->MinPitch);
|
||||
if (player->mo->pitch > oldpitch)
|
||||
{
|
||||
player->mo->pitch = player->MinPitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // look down
|
||||
player->mo->pitch = MIN(player->mo->pitch, screen->GetMaxViewPitch(true));
|
||||
player->mo->pitch = MIN(player->mo->pitch, player->MaxPitch);
|
||||
if (player->mo->pitch < oldpitch)
|
||||
{
|
||||
player->mo->pitch = player->MaxPitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (player->centering)
|
||||
{
|
||||
if (abs(player->mo->pitch) > 2*ANGLE_1)
|
||||
{
|
||||
player->mo->pitch = FixedMul(player->mo->pitch, FRACUNIT*2/3);
|
||||
}
|
||||
else
|
||||
{
|
||||
player->mo->pitch = 0;
|
||||
player->centering = false;
|
||||
if (player - players == consoleplayer)
|
||||
{
|
||||
LocalViewPitch = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Check for fast turn around
|
||||
if (cmd->ucmd.buttons & BT_TURN180 && !(player->oldbuttons & BT_TURN180))
|
||||
|
|
@ -2271,7 +2369,7 @@ void P_PlayerThink (player_t *player)
|
|||
// [RH] check for jump
|
||||
if (cmd->ucmd.buttons & BT_JUMP)
|
||||
{
|
||||
if (player->crouchoffset!=0)
|
||||
if (player->crouchoffset != 0)
|
||||
{
|
||||
// Jumping while crouching will force an un-crouch but not jump
|
||||
player->crouching = 1;
|
||||
|
|
@ -2285,7 +2383,7 @@ void P_PlayerThink (player_t *player)
|
|||
{
|
||||
player->mo->velz = 3*FRACUNIT;
|
||||
}
|
||||
else if (level.IsJumpingAllowed() && onground && !player->jumpTics)
|
||||
else if (level.IsJumpingAllowed() && onground && player->jumpTics == 0)
|
||||
{
|
||||
fixed_t jumpvelz = player->mo->JumpZ * 35 / TICRATE;
|
||||
|
||||
|
|
@ -2295,7 +2393,7 @@ void P_PlayerThink (player_t *player)
|
|||
player->mo->velz += jumpvelz;
|
||||
S_Sound (player->mo, CHAN_BODY, "*jump", 1, ATTN_NORM);
|
||||
player->mo->flags2 &= ~MF2_ONMOBJ;
|
||||
player->jumpTics = 18*TICRATE/35;
|
||||
player->jumpTics = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2414,15 +2512,6 @@ void P_PlayerThink (player_t *player)
|
|||
P_PoisonDamage (player, player->poisoner, 1, true);
|
||||
}
|
||||
|
||||
// [BC] Apply regeneration.
|
||||
if (( level.time & 31 ) == 0 && ( player->cheats & CF_REGENERATION ) && ( player->health ))
|
||||
{
|
||||
if ( P_GiveBody( player->mo, 5 ))
|
||||
{
|
||||
S_Sound(player->mo, CHAN_ITEM, "*regenerate", 1, ATTN_NORM );
|
||||
}
|
||||
}
|
||||
|
||||
// Apply degeneration.
|
||||
if (dmflags2 & DF2_YES_DEGENERATION)
|
||||
{
|
||||
|
|
@ -2604,33 +2693,9 @@ void player_t::Serialize (FArchive &arc)
|
|||
<< poisoncount
|
||||
<< poisoner
|
||||
<< attacker
|
||||
<< extralight;
|
||||
if (SaveVersion < 1858)
|
||||
{
|
||||
int fixedmap;
|
||||
arc << fixedmap;
|
||||
fixedcolormap = NOFIXEDCOLORMAP;
|
||||
fixedlightlevel = -1;
|
||||
if (fixedmap >= NUMCOLORMAPS)
|
||||
{
|
||||
fixedcolormap = fixedmap - NUMCOLORMAPS;
|
||||
}
|
||||
else if (fixedmap > 0)
|
||||
{
|
||||
fixedlightlevel = fixedmap;
|
||||
}
|
||||
}
|
||||
else if (SaveVersion < 1893)
|
||||
{
|
||||
int ll;
|
||||
arc << fixedcolormap << ll;
|
||||
fixedlightlevel = ll;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << fixedcolormap << fixedlightlevel;
|
||||
}
|
||||
arc << morphTics
|
||||
<< extralight
|
||||
<< fixedcolormap << fixedlightlevel
|
||||
<< morphTics
|
||||
<< MorphedPlayerClass
|
||||
<< MorphStyle
|
||||
<< MorphExitFlash
|
||||
|
|
@ -2645,9 +2710,18 @@ void player_t::Serialize (FArchive &arc)
|
|||
<< BlendR
|
||||
<< BlendG
|
||||
<< BlendB
|
||||
<< BlendA
|
||||
<< accuracy << stamina
|
||||
<< LogText
|
||||
<< BlendA;
|
||||
if (SaveVersion < 3427)
|
||||
{
|
||||
WORD oldaccuracy, oldstamina;
|
||||
arc << oldaccuracy << oldstamina;
|
||||
if (mo != NULL)
|
||||
{
|
||||
mo->accuracy = oldaccuracy;
|
||||
mo->stamina = oldstamina;
|
||||
}
|
||||
}
|
||||
arc << LogText
|
||||
<< ConversationNPC
|
||||
<< ConversationPC
|
||||
<< ConversationNPCAngle
|
||||
|
|
@ -2667,6 +2741,29 @@ void player_t::Serialize (FArchive &arc)
|
|||
<< original_cmd
|
||||
<< original_oldbuttons;
|
||||
|
||||
if (SaveVersion >= 3475)
|
||||
{
|
||||
arc << poisontype << poisonpaintype;
|
||||
}
|
||||
else if (poisoner != NULL)
|
||||
{
|
||||
poisontype = poisoner->DamageType;
|
||||
poisonpaintype = poisoner->PainType != NAME_None ? poisoner->PainType : poisoner->DamageType;
|
||||
}
|
||||
|
||||
if (SaveVersion >= 3599)
|
||||
{
|
||||
arc << timefreezer;
|
||||
}
|
||||
else
|
||||
{
|
||||
cheats &= ~(1 << 15); // make sure old CF_TIMEFREEZE bit is cleared
|
||||
}
|
||||
if (SaveVersion < 3640)
|
||||
{
|
||||
cheats &= ~(1 << 17); // make sure old CF_REGENERATION bit is cleared
|
||||
}
|
||||
|
||||
if (isbot)
|
||||
{
|
||||
arc << angle
|
||||
|
|
@ -2702,3 +2799,11 @@ void player_t::Serialize (FArchive &arc)
|
|||
original_oldbuttons = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
bool P_IsPlayerTotallyFrozen(const player_t *player)
|
||||
{
|
||||
return
|
||||
gamestate == GS_TITLELEVEL ||
|
||||
player->cheats & CF_TOTALLYFROZEN ||
|
||||
((level.flags2 & LEVEL2_FROZEN) && player->timefreezer == 0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue