- scriptified APlayerPawn::Die and fixed a few things I encountered while doing it.

This commit is contained in:
Christoph Oelckers 2018-11-24 20:32:12 +01:00
parent cf9cd58310
commit fb91982da2
16 changed files with 117 additions and 102 deletions

View file

@ -1690,7 +1690,7 @@ static int PatchWeapon (int weapNum)
}
else if (stricmp (Line1, "Min ammo") == 0)
{
info->MinAmmo1 = val;
info->MinSelAmmo1 = val;
}
else
{

View file

@ -94,7 +94,6 @@ public:
virtual bool UseInventory (AInventory *item) override;
virtual void MarkPrecacheSounds () const override;
virtual void BeginPlay () override;
virtual void Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOfDeath) override;
virtual bool UpdateWaterLevel (bool splash) override;
bool ResetAirSupply (bool playgasp = true);

View file

@ -119,9 +119,9 @@ public:
TObjPtr<AWeapon*> SisterWeapon;
float FOVScale;
int Crosshair; // 0 to use player's crosshair
bool GivenAsMorphWeapon;
bool GivenAsMorphWeapon; // *** only accessed from ZScript.
bool bAltFire; // Set when this weapon's alternate fire is used.
bool bAltFire; // *** only accessed from ZScript. Set when this weapon's alternate fire is used.
virtual void MarkPrecacheSounds() const;

View file

@ -1513,6 +1513,7 @@ void G_InitLevelLocals ()
level.fogdensity = info->fogdensity;
level.outsidefogdensity = info->outsidefogdensity;
level.skyfog = info->skyfog;
level.deathsequence = info->deathsequence;
level.pixelstretch = info->pixelstretch;
@ -2238,6 +2239,7 @@ DEFINE_FIELD(FLevelLocals, fogdensity)
DEFINE_FIELD(FLevelLocals, outsidefogdensity)
DEFINE_FIELD(FLevelLocals, skyfog)
DEFINE_FIELD(FLevelLocals, pixelstretch)
DEFINE_FIELD(FLevelLocals, deathsequence)
DEFINE_FIELD_BIT(FLevelLocals, flags, noinventorybar, LEVEL_NOINVENTORYBAR)
DEFINE_FIELD_BIT(FLevelLocals, flags, monsterstelefrag, LEVEL_MONSTERSTELEFRAG)
DEFINE_FIELD_BIT(FLevelLocals, flags, actownspecial, LEVEL_ACTOWNSPECIAL)
@ -2304,3 +2306,12 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, ChangeSky)
R_InitSkyMap();
return 0;
}
DEFINE_ACTION_FUNCTION(FLevelLocals, StartIntermission)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_NAME(seq);
PARAM_INT(state);
F_StartIntermission(seq, (uint8_t)state);
return 0;
}

View file

@ -175,6 +175,7 @@ struct FLevelLocals
int outsidefogdensity;
int skyfog;
FName deathsequence;
float pixelstretch;
float MusicVolume;

View file

@ -872,7 +872,6 @@ void F_StartIntermission(FName seq, uint8_t state)
}
}
//==========================================================================
//
// Called by main loop.

View file

@ -4512,8 +4512,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_DropItem)
PARAM_INT(amount);
PARAM_INT(chance);
P_DropItem(self, spawntype, amount, chance);
return 0;
ACTION_RETURN_OBJECT(P_DropItem(self, spawntype, amount, chance));
}
//===========================================================================

View file

@ -3225,7 +3225,7 @@ void ModifyDropAmount(AInventory *inv, int dropamount)
CVAR(Int, sv_dropstyle, 0, CVAR_SERVERINFO | CVAR_ARCHIVE);
AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int chance)
AActor *P_DropItem (AActor *source, PClassActor *type, int dropamount, int chance)
{
if (type != NULL && pr_dropitem() <= chance)
{
@ -3276,9 +3276,8 @@ AInventory *P_DropItem (AActor *source, PClassActor *type, int dropamount, int c
return NULL;
}
}
return inv;
}
// we can't really return an AInventory pointer to a non-inventory item here, can we?
return mo;
}
}
return NULL;

View file

@ -53,7 +53,7 @@ bool P_CheckMeleeRange2 (AActor *actor);
bool P_Move (AActor *actor);
bool P_TryWalk (AActor *actor);
void P_NewChaseDir (AActor *actor);
AInventory *P_DropItem (AActor *source, PClassActor *type, int special, int chance);
AActor *P_DropItem (AActor *source, PClassActor *type, int special, int chance);
void P_TossItem (AActor *item);
bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params);
void A_Weave(AActor *self, int xyspeed, int zspeed, double xydist, double zdist);

View file

@ -972,6 +972,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload)
("level.fogdensity", level.fogdensity)
("level.outsidefogdensity", level.outsidefogdensity)
("level.skyfog", level.skyfog)
("level.deathsequence", level.deathsequence)
("level.bodyqueslot", level.bodyqueslot)
.Array("level.bodyque", level.bodyque, level.BODYQUESIZE);

View file

@ -1351,88 +1351,6 @@ void APlayerPawn::GiveDefaultInventory ()
}
}
//===========================================================================
//
// APlayerPawn :: Die
//
//===========================================================================
void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOfDeath)
{
Super::Die (source, inflictor, dmgflags, MeansOfDeath);
if (player != NULL && player->mo == this) player->bonuscount = 0;
if (player != NULL && player->mo != this)
{ // Make the real player die, too
player->mo->CallDie (source, inflictor, dmgflags, MeansOfDeath);
}
else
{
if (player != NULL && (dmflags2 & DF2_YES_WEAPONDROP))
{ // Voodoo dolls don't drop weapons
AWeapon *weap = player->ReadyWeapon;
if (weap != NULL)
{
AInventory *item;
// kgDROP - start - modified copy from a_action.cpp
auto 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)
{
item = P_DropItem (this, weap->GetClass(), -1, 256);
if (item != NULL && item->IsKindOf(NAME_Weapon))
{
if (weap->AmmoGive1 && weap->Ammo1)
{
static_cast<AWeapon *>(item)->AmmoGive1 = weap->Ammo1->Amount;
}
if (weap->AmmoGive2 && weap->Ammo2)
{
static_cast<AWeapon *>(item)->AmmoGive2 = weap->Ammo2->Amount;
}
item->ItemFlags |= IF_IGNORESKILL;
}
}
else
{
item = P_DropItem (this, weap->AmmoType1, -1, 256);
if (item != NULL)
{
item->Amount = weap->Ammo1->Amount;
item->ItemFlags |= IF_IGNORESKILL;
}
item = P_DropItem (this, weap->AmmoType2, -1, 256);
if (item != NULL)
{
item->Amount = weap->Ammo2->Amount;
item->ItemFlags |= IF_IGNORESKILL;
}
}
}
}
if (!multiplayer && level.info->deathsequence != NAME_None)
{
F_StartIntermission(level.info->deathsequence, FSTATE_EndingGame);
}
}
}
//===========================================================================
//
// A_PlayerScream

View file

@ -1070,7 +1070,7 @@ class Actor : Thinker native
native void A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake");
native void A_QuakeEx(int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, sound sfx = "world/quake", int flags = 0, double mulWaveX = 1, double mulWaveY = 1, double mulWaveZ = 1, int falloff = 0, int highpoint = 0, double rollIntensity = 0, double rollWave = 0);
action native void A_SetTics(int tics);
native void A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);
native Actor A_DropItem(class<Actor> item, int dropamount = -1, int chance = 256);
native void A_DamageSelf(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = null, name species = "None", int src = AAPTR_DEFAULT, int inflict = AAPTR_DEFAULT);
native void A_DamageTarget(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = null, name species = "None", int src = AAPTR_DEFAULT, int inflict = AAPTR_DEFAULT);
native void A_DamageMaster(int amount, name damagetype = "none", int flags = 0, class<Actor> filter = null, name species = "None", int src = AAPTR_DEFAULT, int inflict = AAPTR_DEFAULT);

View file

@ -655,6 +655,7 @@ struct LevelLocals native
native readonly int outsidefogdensity;
native readonly int skyfog;
native readonly float pixelstretch;
native name deathsequence;
// level_info_t *info cannot be done yet.
native String GetUDMFString(int type, int index, Name key);
@ -670,6 +671,7 @@ struct LevelLocals native
native bool IsJumpingAllowed() const;
native bool IsCrouchingAllowed() const;
native bool IsFreelookAllowed() const;
native void StartIntermission(Name type, int state) const;
native static clearscope bool IsPointInMap(vector3 p);

View file

@ -1257,3 +1257,11 @@ enum RadiusDamageFlags
RADF_THRUSTZ = 16,
RADF_OLDRADIUSDAMAGE = 32
};
enum IntermissionSequenceType
{
FSTATE_EndingGame = 0,
FSTATE_ChangingLevel = 1,
FSTATE_InLevel = 2
};

View file

@ -560,7 +560,7 @@ extend class PlayerPawn
override Actor, int, int MorphedDeath()
{
// Voodoo dolls should not unmorph the real player here.
if ((player.mo == self) &&
if (player && (player.mo == self) &&
(player.morphTics) &&
(player.MorphStyle & MRF_UNDOBYDEATH) &&
(alternative))

View file

@ -154,7 +154,7 @@ class PlayerPawn : Actor native
let invul = Powerup(Spawn("PowerInvulnerable"));
invul.EffectTics = 3 * TICRATE;
invul.BlendColor = 0; // don't mess with the view
invul.bUndroppable = true; // Don't drop this
invul.bUndroppable = true; // Don't drop self
bRespawnInvul = true; // [RH] special effect
}
}
@ -363,7 +363,7 @@ class PlayerPawn : Actor native
//
// PROC P_CheckWeaponChange
//
// The player can change to another weapon at this time.
// The player can change to another weapon at self time.
// [GZ] This was cut from P_CheckWeaponFire.
//
//---------------------------------------------------------------------------
@ -537,6 +537,84 @@ class PlayerPawn : Actor native
}
}
//===========================================================================
//
// APlayerPawn :: Die
//
//===========================================================================
override void Die (Actor source, Actor inflictor, int dmgflags, Name MeansOfDeath)
{
Super.Die (source, inflictor, dmgflags, MeansOfDeath);
if (player != NULL && player.mo == self) player.bonuscount = 0;
if (player != NULL && player.mo != self)
{ // Make the real player die, too
player.mo.Die (source, inflictor, dmgflags, MeansOfDeath);
}
else
{
if (player != NULL && sv_weapondrop)
{ // Voodoo dolls don't drop weapons
let weap = player.ReadyWeapon;
if (weap != NULL)
{
// kgDROP - start - modified copy from a_action.cpp
let di = weap.GetDropItems();
if (di != NULL)
{
while (di != NULL)
{
if (di.Name != 'None')
{
class<Actor> ti = di.Name;
if (ti) A_DropItem (ti, di.Amount, di.Probability);
}
di = di.Next;
}
}
else if (weap.SpawnState != NULL &&
weap.SpawnState != GetDefaultByType('Actor').SpawnState)
{
let weapitem = Weapon(A_DropItem (weap.GetClass(), -1, 256));
if (weapitem)
{
if (weap.AmmoGive1 && weap.Ammo1)
{
weapitem.AmmoGive1 = weap.Ammo1.Amount;
}
if (weap.AmmoGive2 && weap.Ammo2)
{
weapitem.AmmoGive2 = weap.Ammo2.Amount;
}
weapitem.bIgnoreSkill = true;
}
}
else
{
let item = Inventory(A_DropItem (weap.AmmoType1, -1, 256));
if (item != NULL)
{
item.Amount = weap.Ammo1.Amount;
item.bIgnoreSkill = true;
}
item = Inventory(A_DropItem (weap.AmmoType2, -1, 256));
if (item != NULL)
{
item.Amount = weap.Ammo2.Amount;
item.bIgnoreSkill = true;
}
}
}
}
if (!multiplayer && level.deathsequence != 'None')
{
level.StartIntermission(level.deathsequence, FSTATE_EndingGame);
}
}
}
//----------------------------------------------------------------------------
//
// PROC P_CheckFOV
@ -1244,7 +1322,7 @@ class PlayerPawn : Actor native
CheckUse();
CheckUndoMorph();
// Cycle psprites.
// Note that after this point the PlayerPawn may have changed due to getting unmorphed so 'self' is no longer safe to use.
// Note that after self point the PlayerPawn may have changed due to getting unmorphed so 'self' is no longer safe to use.
player.mo.TickPSprites();
// Other Counters
if (player.damagecount) player.damagecount--;
@ -1285,7 +1363,7 @@ class PlayerPawn : Actor native
let weapon = player.PendingWeapon;
// If the player has a tome of power, use this weapon's powered up
// If the player has a tome of power, use self weapon's powered up
// version, if one is available.
if (weapon != null &&
weapon.SisterWeapon &&
@ -1345,7 +1423,7 @@ class PlayerPawn : Actor native
weap.Ammo1.GetClass() != ammotype))
continue;
// Don't select it if the Tome is active and this isn't the powered-up version.
// Don't select it if the Tome is active and self isn't the powered-up version.
if (tomed && weap.SisterWeapon != NULL && weap.SisterWeapon.bPowered_Up)
continue;
@ -1400,7 +1478,7 @@ class PlayerPawn : Actor native
//
// APlayerPawn :: PickNewWeapon
//
// Picks a new weapon for this player. Used mostly for running out of ammo,
// Picks a new weapon for self player. Used mostly for running out of ammo,
// but it also works when an ACS script explicitly takes the ready weapon
// away or the player picks up some ammo they had previously run out of.
//
@ -1632,7 +1710,7 @@ enum EPlayerGender
GENDER_OTHER
}
struct PlayerInfo native play // this is what internally is known as player_t
struct PlayerInfo native play // self is what internally is known as player_t
{
// technically engine constants but the only part of the playsim using them is the player.
const NOFIXEDCOLORMAP = -1;