- scriptified P_MorphPlayer and dependencies.

It still needs its counterpart scriptified as well before it can work.

# Conflicts:
#	src/gi.cpp
#	wadsrc/static/zscript/base.txt
This commit is contained in:
Christoph Oelckers 2018-11-24 07:45:49 +01:00 committed by drfrag
parent 8669dbdcfe
commit 395413fc9a
7 changed files with 250 additions and 16 deletions

View file

@ -178,18 +178,6 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassActor *spawntype, in
return true;
}
DEFINE_ACTION_FUNCTION(_PlayerInfo, MorphPlayer)
{
PARAM_SELF_STRUCT_PROLOGUE(player_t);
PARAM_POINTER(activator, player_t);
PARAM_CLASS(spawntype, APlayerPawn);
PARAM_INT(duration);
PARAM_INT(style);
PARAM_CLASS(enter_flash, AActor);
PARAM_CLASS(exit_flash, AActor);
ACTION_RETURN_BOOL(P_MorphPlayer(activator, self, spawntype, duration, style, enter_flash, exit_flash));
}
//----------------------------------------------------------------------------
//
// FUNC P_UndoPlayerMorph

View file

@ -65,6 +65,7 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_coop)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, statusscreen_dm)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mSliderColor)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, defaultbloodcolor)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight)
const char *GameNames[17] =
{

View file

@ -303,6 +303,13 @@ CCMD (playerclasses)
}
}
DEFINE_ACTION_FUNCTION(APlayerPawn, Substitute)
{
PARAM_SELF_PROLOGUE(APlayerPawn);
PARAM_OBJECT(replace, APlayerPawn);
DObject::StaticPointerSubstitution(self, replace);
return 0;
}
//
// Movement.

View file

@ -805,7 +805,6 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo
void FFunctionBuildList::Build()
{
int errorcount = 0;
int codesize = 0;
int datasize = 0;
FILE *dump = nullptr;
@ -914,7 +913,8 @@ void FFunctionBuildList::Build()
}
VMFunction::CreateRegUseInfo();
FScriptPosition::StrictErrors = false;
if (Args->CheckParm("-dumpjit")) DumpJit();
if (FScriptPosition::ErrorCounter == 0 && Args->CheckParm("-dumpjit")) DumpJit();
mItems.Clear();
mItems.ShrinkToFit();
FxAlloc.FreeAllBlocks();

View file

@ -361,6 +361,7 @@ struct GameInfoStruct native
native bool intermissioncounter;
native Name mSliderColor;
native Color defaultbloodcolor;
native double telefogheight;
}
class Object native

View file

@ -1,3 +1,221 @@
extend class PlayerPawn
{
//===========================================================================
//
// EndAllPowerupEffects
//
// Calls EndEffect() on every Powerup in the inventory list.
//
//===========================================================================
void InitAllPowerupEffects()
{
let item = Inv;
while (item != null)
{
let power = Powerup(item);
if (power != null)
{
power.InitEffect();
}
item = item.Inv;
}
}
//===========================================================================
//
// EndAllPowerupEffects
//
// Calls EndEffect() on every Powerup in the inventory list.
//
//===========================================================================
void EndAllPowerupEffects()
{
let item = Inv;
while (item != null)
{
let power = Powerup(item);
if (power != null)
{
power.EndEffect();
}
item = item.Inv;
}
}
//===========================================================================
//
//
//
//===========================================================================
virtual void ActivateMorphWeapon ()
{
class<Weapon> morphweaponcls = MorphWeapon;
player.PendingWeapon = WP_NOCHANGE;
if (player.ReadyWeapon != null)
{
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP;
}
if (morphweaponcls == null || !(morphweaponcls is 'Weapon'))
{ // No weapon at all while morphed!
player.ReadyWeapon = null;
}
else
{
player.ReadyWeapon = Weapon(FindInventory (morphweaponcls));
if (player.ReadyWeapon == null)
{
player.ReadyWeapon = Weapon(GiveInventoryType (morphweaponcls));
if (player.ReadyWeapon != null)
{
player.ReadyWeapon.GivenAsMorphWeapon = true; // flag is used only by new beastweap semantics in P_UndoPlayerMorph
}
}
if (player.ReadyWeapon != null)
{
player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.GetReadyState());
}
}
if (player.ReadyWeapon != null)
{
player.SetPsprite(PSP_FLASH, null);
}
player.PendingWeapon = WP_NOCHANGE;
}
//---------------------------------------------------------------------------
//
// FUNC P_MorphPlayer
//
// Returns true if the player gets turned into a chicken/pig.
//
// TODO: Allow morphed players to receive weapon sets (not just one weapon),
// since they have their own weapon slots now.
//
//---------------------------------------------------------------------------
virtual bool MorphPlayer(playerinfo activator, Class<PlayerPawn> spawntype, int duration, int style, Class<Actor> enter_flash = null, Class<Actor> exit_flash = null)
{
if (bDontMorph)
{
return false;
}
if (bInvulnerable && (player != activator || !(style & MRF_WHENINVULNERABLE)))
{ // Immune when invulnerable unless this is a power we activated
return false;
}
if (player.morphTics)
{ // Player is already a beast
if ((GetClass() == spawntype) && bCanSuperMorph
&& (player.morphTics < (((duration) ? duration : DEFMORPHTICS) - TICRATE))
&& FindInventory('PowerWeaponLevel2', true) == null)
{ // Make a super chicken
GiveInventoryType ('PowerWeaponLevel2');
}
return false;
}
if (health <= 0)
{ // Dead players cannot morph
return false;
}
if (spawntype == null)
{
return false;
}
if (!(spawntype is 'PlayerPawn'))
{
return false;
}
if (spawntype == GetClass())
{
return false;
}
let morphed = PlayerPawn(Spawn (spawntype, Pos, NO_REPLACE));
EndAllPowerupEffects();
Substitute(morphed);
if ((style & MRF_TRANSFERTRANSLATION) && !morphed.bDontTranslate)
{
morphed.Translation = Translation;
}
if (tid != 0 && (style & MRF_NEWTIDBEHAVIOUR))
{
morphed.ChangeTid(tid);
ChangeTid(0);
}
morphed.Angle = Angle;
morphed.target = target;
morphed.tracer = tracer;
morphed.alternative = self;
morphed.FriendPlayer = FriendPlayer;
morphed.DesignatedTeam = DesignatedTeam;
morphed.Score = Score;
player.PremorphWeapon = player.ReadyWeapon;
morphed.special2 = bSolid * 2 + bShootable * 4 + bInvisible * 0x40; // The factors are for savegame compatibility
morphed.player = player;
if (morphed.ViewHeight > player.viewheight && player.deltaviewheight == 0)
{ // If the new view height is higher than the old one, start moving toward it.
player.deltaviewheight = player.GetDeltaViewHeight();
}
morphed.bShadow |= bShadow;
morphed.bNoGravity |= bNoGravity;
morphed.bFly |= bFly;
morphed.bGhost |= bGhost;
if (enter_flash == null) enter_flash = 'TeleportFog';
let eflash = Spawn(enter_flash, Pos + (0, 0, gameinfo.telefogheight), ALLOW_REPLACE);
let p = player;
player = null;
alternative = morphed;
bSolid = false;
bShootable = false;
bUnmorphed = true;
bInvisible = true;
p.morphTics = (duration) ? duration : DEFMORPHTICS;
// [MH] Used by SBARINFO to speed up face drawing
p.MorphedPlayerClass = spawntype;
p.MorphStyle = style;
if (exit_flash == null) exit_flash = 'TeleportFog';
p.MorphExitFlash = exit_flash;
p.health = morphed.health;
p.mo = morphed;
p.vel = (0, 0);
morphed.ObtainInventory (self);
// Remove all armor
for (Inventory item = morphed.Inv; item != null; )
{
let next = item.Inv;
if (item is 'Armor')
{
item.DepleteOrDestroy();
}
item = next;
}
morphed.InitAllPowerupEffects();
morphed.ActivateMorphWeapon ();
if (p.camera == self) // can this happen?
{
p.camera = morphed;
}
morphed.ScoreIcon = ScoreIcon; // [GRB]
if (eflash)
eflash.target = morphed;
return true;
}
}
class MorphProjectile : Actor
{

View file

@ -15,6 +15,7 @@ class PlayerPawn : Actor native
const CROUCHSPEED = (1./12);
// [RH] # of ticks to complete a turn180
const TURN180_TICKS = ((TICRATE / 4) + 1);
const DEFMORPHTICS = 40 * TICRATE;
native int crouchsprite;
native int MaxHealth;
@ -1261,6 +1262,7 @@ class PlayerPawn : Actor native
player.mo.CheckAirSupply();
}
}
//----------------------------------------------------------------------------
//
@ -1278,6 +1280,7 @@ class PlayerPawn : Actor native
native void CheckWeaponButtons();
native Weapon BestWeapon(class<Ammo> ammotype);
native Weapon PickNewWeapon(class<Ammo> ammotype);
native void Substitute(PlayerPawn replacement);
}
@ -1434,7 +1437,7 @@ struct PlayerInfo native play // this is what internally is known as player_t
native Class<PlayerPawn>MorphedPlayerClass;
native int MorphStyle;
native Class<Actor> MorphExitFlash;
native Class<Weapon> PremorphWeapon;
native Weapon PremorphWeapon;
native int chickenPeck;
native int jumpTics;
native bool onground;
@ -1467,7 +1470,16 @@ struct PlayerInfo native play // this is what internally is known as player_t
native readonly @UserCmd original_cmd;
native bool MorphPlayer(playerinfo p, Class<PlayerPawn> spawntype, int duration, int style, Class<Actor> enter_flash = null, Class<Actor> exit_flash = null);
bool MorphPlayer(playerinfo p, Class<PlayerPawn> spawntype, int duration, int style, Class<Actor> enter_flash = null, Class<Actor> exit_flash = null)
{
if (mo != null)
{
// The actual implementation is on PlayerPawn where it can be overridden.
return mo.MorphPlayer(p, spawntype, duration, style, enter_flash, exit_flash);
}
return false;
}
native bool UndoPlayerMorph(playerinfo player, int unmorphflag = 0, bool force = false);
native bool PoisonPlayer(Actor poisoner, Actor source, int poison);
native void PoisonDamage(Actor source, int damage, bool playPainSound);
@ -1538,6 +1550,13 @@ struct PlayerInfo native play // this is what internally is known as player_t
return allfrags;
}
double GetDeltaViewHeight()
{
return (mo.ViewHeight + crouchviewdelta - viewheight) / 8;
}
}
struct PlayerClass native