- scriptified P_MorphPlayer and dependencies.

It still needs its counterpart scriptified as well before it can work.
This commit is contained in:
Christoph Oelckers 2018-11-24 07:45:49 +01:00
parent 4e2cc1f144
commit 192104aea2
7 changed files with 250 additions and 16 deletions

View file

@ -173,18 +173,6 @@ bool P_MorphPlayer (player_t *activator, player_t *p, PClassActor *spawntype, in
return true; 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 // FUNC P_UndoPlayerMorph

View file

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

View file

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

View file

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

View file

@ -366,6 +366,7 @@ struct GameInfoStruct native
native double gibfactor; native double gibfactor;
native bool intermissioncounter; native bool intermissioncounter;
native Name mSliderColor; native Name mSliderColor;
native double telefogheight;
} }
class Object native 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 class MorphProjectile : Actor
{ {

View file

@ -15,6 +15,7 @@ class PlayerPawn : Actor native
const CROUCHSPEED = (1./12); const CROUCHSPEED = (1./12);
// [RH] # of ticks to complete a turn180 // [RH] # of ticks to complete a turn180
const TURN180_TICKS = ((TICRATE / 4) + 1); const TURN180_TICKS = ((TICRATE / 4) + 1);
const DEFMORPHTICS = 40 * TICRATE;
native int crouchsprite; native int crouchsprite;
native int MaxHealth; native int MaxHealth;
@ -1261,6 +1262,7 @@ class PlayerPawn : Actor native
player.mo.CheckAirSupply(); player.mo.CheckAirSupply();
} }
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// //
@ -1278,6 +1280,7 @@ class PlayerPawn : Actor native
native void CheckWeaponButtons(); native void CheckWeaponButtons();
native Weapon BestWeapon(class<Ammo> ammotype); native Weapon BestWeapon(class<Ammo> ammotype);
native Weapon PickNewWeapon(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 Class<PlayerPawn>MorphedPlayerClass;
native int MorphStyle; native int MorphStyle;
native Class<Actor> MorphExitFlash; native Class<Actor> MorphExitFlash;
native Class<Weapon> PremorphWeapon; native Weapon PremorphWeapon;
native int chickenPeck; native int chickenPeck;
native int jumpTics; native int jumpTics;
native bool onground; 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 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 UndoPlayerMorph(playerinfo player, int unmorphflag = 0, bool force = false);
native bool PoisonPlayer(Actor poisoner, Actor source, int poison); native bool PoisonPlayer(Actor poisoner, Actor source, int poison);
native void PoisonDamage(Actor source, int damage, bool playPainSound); 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; return allfrags;
} }
double GetDeltaViewHeight()
{
return (mo.ViewHeight + crouchviewdelta - viewheight) / 8;
}
} }
struct PlayerClass native struct PlayerClass native