- scriptified the remaining PlayerPawn methods.

This commit is contained in:
Christoph Oelckers 2019-01-03 14:35:17 +01:00
parent 2258a71c36
commit 3314a1efe5
6 changed files with 166 additions and 166 deletions

View file

@ -87,22 +87,6 @@ public:
virtual void Serialize(FSerializer &arc); virtual void Serialize(FSerializer &arc);
virtual void PostBeginPlay() override;
virtual void Tick() override;
virtual void BeginPlay () override;
virtual bool UpdateWaterLevel (bool splash) override;
enum EInvulState
{
INVUL_Start,
INVUL_Active,
INVUL_Stop,
INVUL_GetAlpha
};
int crouchsprite;
int BonusHealth; int BonusHealth;
int MugShotMaxHealth; int MugShotMaxHealth;
@ -122,6 +106,7 @@ public:
double UseRange; // [NS] Distance at which player can +use double UseRange; // [NS] Distance at which player can +use
// Everything below this point is only used by scripted code or through the scripted variable interface. // Everything below this point is only used by scripted code or through the scripted variable interface.
int crouchsprite;
int MaxHealth; int MaxHealth;
int RunHealth; int RunHealth;
TObjPtr<AActor*> InvFirst; // first inventory item displayed on inventory bar TObjPtr<AActor*> InvFirst; // first inventory item displayed on inventory bar
@ -492,11 +477,6 @@ public:
} }
} }
bool CanCrouch() const
{
return morphTics == 0 || mo->PlayerFlags & PPF_CROUCHABLEMORPH;
}
int GetSpawnClass(); int GetSpawnClass();
// PSprite layers // PSprite layers

View file

@ -1042,6 +1042,7 @@ xx(SoundClass)
xx(ViewBob) xx(ViewBob)
xx(DamageFade) xx(DamageFade)
xx(MaxHealth) xx(MaxHealth)
xx(crouchsprite)
xx(BlueCard) xx(BlueCard)
xx(YellowCard) xx(YellowCard)

View file

@ -4267,79 +4267,98 @@ bool AActor::UpdateWaterLevel(bool dosplash)
double fh = -FLT_MAX; double fh = -FLT_MAX;
bool reset = false; bool reset = false;
int oldlevel = waterlevel;
waterlevel = 0; waterlevel = 0;
if (Sector == NULL) if (Sector != nullptr)
{ {
return false; if (Sector->MoreFlags & SECMF_UNDERWATER) // intentionally not SECMF_UNDERWATERMASK
}
if (Sector->MoreFlags & SECMF_UNDERWATER) // intentionally not SECMF_UNDERWATERMASK
{
waterlevel = 3;
}
else
{
const sector_t *hsec = Sector->GetHeightSec();
if (hsec != NULL)
{ {
fh = hsec->floorplane.ZatPoint(this); waterlevel = 3;
if (hsec->MoreFlags & SECMF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors
{
if (Z() < fh)
{
waterlevel = 1;
if (Center() < fh)
{
waterlevel = 2;
if ((player && Z() + player->viewheight <= fh) ||
(Top() <= fh))
{
waterlevel = 3;
}
}
}
else if (!(hsec->MoreFlags & SECMF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this)))
{
waterlevel = 3;
}
else
{
waterlevel = 0;
}
}
} }
else else
{ {
// Check 3D floors as well! const sector_t *hsec = Sector->GetHeightSec();
for (auto rover : Sector->e->XFloor.ffloors) if (hsec != NULL)
{ {
if (!(rover->flags & FF_EXISTS)) continue; fh = hsec->floorplane.ZatPoint(this);
if (rover->flags & FF_SOLID) continue; if (hsec->MoreFlags & SECMF_UNDERWATERMASK) // also check Boom-style non-swimmable sectors
if (!(rover->flags & FF_SWIMMABLE)) continue;
double ff_bottom = rover->bottom.plane->ZatPoint(this);
double ff_top = rover->top.plane->ZatPoint(this);
if (ff_top <= Z() || ff_bottom > (Center())) continue;
fh = ff_top;
if (Z() < fh)
{ {
waterlevel = 1; if (Z() < fh)
if (Center() < fh)
{ {
waterlevel = 2; waterlevel = 1;
if ((player && Z() + player->viewheight <= fh) || if (Center() < fh)
(Top() <= fh))
{ {
waterlevel = 3; waterlevel = 2;
if ((player && Z() + player->viewheight <= fh) ||
(Top() <= fh))
{
waterlevel = 3;
}
} }
} }
else if (!(hsec->MoreFlags & SECMF_FAKEFLOORONLY) && (Top() > hsec->ceilingplane.ZatPoint(this)))
{
waterlevel = 3;
}
else
{
waterlevel = 0;
}
} }
}
else
{
// Check 3D floors as well!
for (auto rover : Sector->e->XFloor.ffloors)
{
if (!(rover->flags & FF_EXISTS)) continue;
if (rover->flags & FF_SOLID) continue;
if (!(rover->flags & FF_SWIMMABLE)) continue;
break; double ff_bottom = rover->bottom.plane->ZatPoint(this);
double ff_top = rover->top.plane->ZatPoint(this);
if (ff_top <= Z() || ff_bottom > (Center())) continue;
fh = ff_top;
if (Z() < fh)
{
waterlevel = 1;
if (Center() < fh)
{
waterlevel = 2;
if ((player && Z() + player->viewheight <= fh) ||
(Top() <= fh))
{
waterlevel = 3;
}
}
}
break;
}
}
}
// Play surfacing and diving sounds, as appropriate.
if (player != nullptr)
{
if (oldlevel < 3 && waterlevel == 3)
{
// Our head just went under.
S_Sound(this, CHAN_VOICE, "*dive", 1, ATTN_NORM);
}
else if (oldlevel == 3 && waterlevel < 3)
{
// Our head just came up.
if (player->air_finished > level.time)
{
// We hadn't run out of air yet.
S_Sound(this, CHAN_VOICE, "*surface", 1, ATTN_NORM);
}
// If we were running out of air, then ResetAirSupply() will play *gasp.
} }
} }
} }

View file

@ -634,6 +634,13 @@ void player_t::SendPitchLimits() const
} }
} }
DEFINE_ACTION_FUNCTION(_PlayerInfo, SendPitchLimits)
{
PARAM_SELF_STRUCT_PROLOGUE(player_t);
self->SendPitchLimits();
return 0;
}
bool player_t::HasWeaponsInSlot(int slot) const bool player_t::HasWeaponsInSlot(int slot) const
{ {
@ -830,11 +837,8 @@ void APlayerPawn::Serialize(FSerializer &arc)
// //
//=========================================================================== //===========================================================================
void APlayerPawn::BeginPlay () static int SetupCrouchSprite(AActor *self, int crouchsprite)
{ {
Super::BeginPlay ();
ChangeStatNum (STAT_PLAYER);
FullHeight = Height;
// Check whether a PWADs normal sprite is to be combined with the base WADs // Check whether a PWADs normal sprite is to be combined with the base WADs
// crouch sprite. In such a case the sprites normally don't match and it is // crouch sprite. In such a case the sprites normally don't match and it is
// best to disable the crouch sprite. // best to disable the crouch sprite.
@ -843,110 +847,44 @@ void APlayerPawn::BeginPlay ()
// This assumes that player sprites always exist in rotated form and // This assumes that player sprites always exist in rotated form and
// that the front view is always a separate sprite. So far this is // that the front view is always a separate sprite. So far this is
// true for anything that exists. // true for anything that exists.
FString normspritename = sprites[SpawnState->sprite].name; FString normspritename = sprites[self->SpawnState->sprite].name;
FString crouchspritename = sprites[crouchsprite].name; FString crouchspritename = sprites[crouchsprite].name;
int spritenorm = Wads.CheckNumForName(normspritename + "A1", ns_sprites); int spritenorm = Wads.CheckNumForName(normspritename + "A1", ns_sprites);
if (spritenorm==-1) if (spritenorm == -1)
{ {
spritenorm = Wads.CheckNumForName(normspritename + "A0", ns_sprites); spritenorm = Wads.CheckNumForName(normspritename + "A0", ns_sprites);
} }
int spritecrouch = Wads.CheckNumForName(crouchspritename + "A1", ns_sprites); int spritecrouch = Wads.CheckNumForName(crouchspritename + "A1", ns_sprites);
if (spritecrouch==-1) if (spritecrouch == -1)
{ {
spritecrouch = Wads.CheckNumForName(crouchspritename + "A0", ns_sprites); spritecrouch = Wads.CheckNumForName(crouchspritename + "A0", ns_sprites);
} }
if (spritenorm==-1 || spritecrouch ==-1) if (spritenorm == -1 || spritecrouch == -1)
{ {
// Sprites do not exist so it is best to disable the crouch sprite. // Sprites do not exist so it is best to disable the crouch sprite.
crouchsprite = 0; return false;
return;
} }
int wadnorm = Wads.GetLumpFile(spritenorm); int wadnorm = Wads.GetLumpFile(spritenorm);
int wadcrouch = Wads.GetLumpFile(spritenorm); int wadcrouch = Wads.GetLumpFile(spritenorm);
if (wadnorm > Wads.GetIwadNum() && wadcrouch <= Wads.GetIwadNum()) if (wadnorm > Wads.GetIwadNum() && wadcrouch <= Wads.GetIwadNum())
{ {
// Question: Add an option / disable crouching or do what? // Question: Add an option / disable crouching or do what?
crouchsprite = 0; return false;
} }
} }
return true;
} }
//=========================================================================== DEFINE_ACTION_FUNCTION_NATIVE(APlayerPawn, SetupCrouchSprite, SetupCrouchSprite)
//
// APlayerPawn :: Tick
//
//===========================================================================
void APlayerPawn::Tick()
{ {
if (player != NULL && player->mo == this && player->CanCrouch() && player->playerstate != PST_DEAD) PARAM_SELF_PROLOGUE(AActor);
{ PARAM_INT(crouchsprite);
Height = FullHeight * player->crouchfactor; ACTION_RETURN_INT(SetupCrouchSprite(self, crouchsprite));
}
else
{
if (health > 0) Height = FullHeight;
}
Super::Tick();
}
//===========================================================================
//
// APlayerPawn :: PostBeginPlay
//
//===========================================================================
void APlayerPawn::PostBeginPlay()
{
Super::PostBeginPlay();
FWeaponSlots::SetupWeaponSlots(this);
// Voodoo dolls: restore original floorz/ceilingz logic
if (player == NULL || player->mo != this)
{
P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS|FFCF_NOPORTALS);
SetZ(floorz);
P_FindFloorCeiling(this, FFCF_ONLYSPAWNPOS);
}
else
{
player->SendPitchLimits();
}
}
//===========================================================================
//
// APlayerPawn :: UpdateWaterLevel
//
// Plays surfacing and diving sounds, as appropriate.
//
//===========================================================================
bool APlayerPawn::UpdateWaterLevel (bool splash)
{
int oldlevel = waterlevel;
bool retval = Super::UpdateWaterLevel (splash);
if (player != NULL)
{
if (oldlevel < 3 && waterlevel == 3)
{ // Our head just went under.
S_Sound (this, CHAN_VOICE, "*dive", 1, ATTN_NORM);
}
else if (oldlevel == 3 && waterlevel < 3)
{ // Our head just came up.
if (player->air_finished > level.time)
{ // We hadn't run out of air yet.
S_Sound (this, CHAN_VOICE, "*surface", 1, ATTN_NORM);
}
// If we were running out of air, then ResetAirSupply() will play *gasp.
}
}
return retval;
} }
//=========================================================================== //===========================================================================
@ -1068,9 +1006,10 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, DVector2 &scale)
// Set the crouch sprite? // Set the crouch sprite?
if (player->crouchfactor < 0.75) if (player->crouchfactor < 0.75)
{ {
if (spritenum == actor->SpawnState->sprite || spritenum == player->mo->crouchsprite) int crouchsprite = player->mo->IntVar(NAME_crouchsprite);
if (spritenum == actor->SpawnState->sprite || spritenum == crouchsprite)
{ {
crouchspriteno = player->mo->crouchsprite; crouchspriteno = crouchsprite;
} }
else if (!(actor->flags4 & MF4_NOSKIN) && else if (!(actor->flags4 & MF4_NOSKIN) &&
(spritenum == Skins[player->userinfo.GetSkin()].sprite || (spritenum == Skins[player->userinfo.GetSkin()].sprite ||

View file

@ -1585,11 +1585,11 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, crouchsprite, S, PlayerPawn)
PROP_STRING_PARM(z, 0); PROP_STRING_PARM(z, 0);
if (strlen(z) == 4) if (strlen(z) == 4)
{ {
defaults->crouchsprite = GetSpriteIndex (z); defaults->IntVar(NAME_crouchsprite) = GetSpriteIndex (z);
} }
else if (*z == 0) else if (*z == 0)
{ {
defaults->crouchsprite = 0; defaults->IntVar(NAME_crouchsprite) = 0;
} }
else else
{ {

View file

@ -116,6 +116,65 @@ class PlayerPawn : Actor native
Obituary "$OB_MPDEFAULT"; Obituary "$OB_MPDEFAULT";
} }
//===========================================================================
//
// APlayerPawn :: Tick
//
//===========================================================================
override void Tick()
{
if (player != NULL && player.mo == self && CanCrouch() && player.playerstate != PST_DEAD)
{
Height = FullHeight * player.crouchfactor;
}
else
{
if (health > 0) Height = FullHeight;
}
Super.Tick();
}
//===========================================================================
//
//
//
//===========================================================================
override void BeginPlay()
{
Super.BeginPlay ();
ChangeStatNum (STAT_PLAYER);
FullHeight = Height;
if (!SetupCrouchSprite(crouchsprite)) crouchsprite = 0;
}
//===========================================================================
//
// APlayerPawn :: PostBeginPlay
//
//===========================================================================
override void PostBeginPlay()
{
Super.PostBeginPlay();
WeaponSlots.SetupWeaponSlots(self);
// Voodoo dolls: restore original floorz/ceilingz logic
if (player == NULL || player.mo != self)
{
FindFloorCeiling(FFCF_ONLYSPAWNPOS|FFCF_NOPORTALS);
SetZ(floorz);
FindFloorCeiling(FFCF_ONLYSPAWNPOS);
}
else
{
player.SendPitchLimits();
}
}
//=========================================================================== //===========================================================================
// //
// APlayerPawn :: MarkPrecacheSounds // APlayerPawn :: MarkPrecacheSounds
@ -2391,6 +2450,7 @@ class PlayerPawn : Actor native
native void CheckUse(); native void CheckUse();
native void CheckWeaponButtons(); native void CheckWeaponButtons();
native void MarkPlayerSounds(); native void MarkPlayerSounds();
private native int SetupCrouchSprite(int c);
private native clearscope Color GetPainFlashForType(Name type); private native clearscope Color GetPainFlashForType(Name type);
} }
@ -2659,6 +2719,7 @@ struct PlayerInfo native play // self is what internally is known as player_t
native double GetStillBob() const; native double GetStillBob() const;
native void SetFOV(float fov); native void SetFOV(float fov);
native bool GetClassicFlight() const; native bool GetClassicFlight() const;
native void SendPitchLimits();
native clearscope bool HasWeaponsInSlot(int slot) const; native clearscope bool HasWeaponsInSlot(int slot) const;
// The actual implementation is on PlayerPawn where it can be overridden. Use that directly in the future. // The actual implementation is on PlayerPawn where it can be overridden. Use that directly in the future.