mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 23:21:41 +00:00
- scriptified P_MorphPlayer and dependencies.
It still needs its counterpart scriptified as well before it can work.
This commit is contained in:
parent
4e2cc1f144
commit
192104aea2
7 changed files with 250 additions and 16 deletions
|
@ -173,18 +173,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
|
||||
|
|
|
@ -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_dm)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mSliderColor)
|
||||
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, telefogheight)
|
||||
|
||||
|
||||
const char *GameNames[17] =
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -802,7 +802,6 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo
|
|||
|
||||
void FFunctionBuildList::Build()
|
||||
{
|
||||
int errorcount = 0;
|
||||
int codesize = 0;
|
||||
int datasize = 0;
|
||||
FILE *dump = nullptr;
|
||||
|
@ -911,7 +910,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();
|
||||
|
|
|
@ -366,6 +366,7 @@ struct GameInfoStruct native
|
|||
native double gibfactor;
|
||||
native bool intermissioncounter;
|
||||
native Name mSliderColor;
|
||||
native double telefogheight;
|
||||
}
|
||||
|
||||
class Object native
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue