mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-14 08:31:23 +00:00
- scriptified Chicken and Pig - not tested yet, because other things have priority.
This commit is contained in:
parent
3db712cd73
commit
bbb0778fd4
16 changed files with 309 additions and 357 deletions
|
@ -867,7 +867,6 @@ set( NOT_COMPILED_SOURCE_FILES
|
||||||
sc_man_scanner.h
|
sc_man_scanner.h
|
||||||
sc_man_scanner.re
|
sc_man_scanner.re
|
||||||
g_doom/a_painelemental.cpp
|
g_doom/a_painelemental.cpp
|
||||||
g_heretic/a_chicken.cpp
|
|
||||||
g_heretic/a_dsparil.cpp
|
g_heretic/a_dsparil.cpp
|
||||||
g_heretic/a_hereticartifacts.cpp
|
g_heretic/a_hereticartifacts.cpp
|
||||||
g_heretic/a_hereticweaps.cpp
|
g_heretic/a_hereticweaps.cpp
|
||||||
|
@ -892,7 +891,6 @@ set( NOT_COMPILED_SOURCE_FILES
|
||||||
g_hexen/a_magecone.cpp
|
g_hexen/a_magecone.cpp
|
||||||
g_hexen/a_magelightning.cpp
|
g_hexen/a_magelightning.cpp
|
||||||
g_hexen/a_magestaff.cpp
|
g_hexen/a_magestaff.cpp
|
||||||
g_hexen/a_pig.cpp
|
|
||||||
g_hexen/a_serpent.cpp
|
g_hexen/a_serpent.cpp
|
||||||
g_hexen/a_spike.cpp
|
g_hexen/a_spike.cpp
|
||||||
g_hexen/a_summon.cpp
|
g_hexen/a_summon.cpp
|
||||||
|
|
|
@ -100,6 +100,7 @@ FString GetPrintableDisplayName(PClassPlayerPawn *cls);
|
||||||
class APlayerPawn : public AActor
|
class APlayerPawn : public AActor
|
||||||
{
|
{
|
||||||
DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn)
|
DECLARE_CLASS_WITH_META(APlayerPawn, AActor, PClassPlayerPawn)
|
||||||
|
HAS_FIELDS
|
||||||
HAS_OBJECT_POINTERS
|
HAS_OBJECT_POINTERS
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ public:
|
||||||
virtual void PlayRunning ();
|
virtual void PlayRunning ();
|
||||||
virtual void ThrowPoisonBag ();
|
virtual void ThrowPoisonBag ();
|
||||||
virtual void TweakSpeeds (double &forwardmove, double &sidemove);
|
virtual void TweakSpeeds (double &forwardmove, double &sidemove);
|
||||||
virtual void MorphPlayerThink ();
|
void MorphPlayerThink ();
|
||||||
virtual void ActivateMorphWeapon ();
|
virtual void ActivateMorphWeapon ();
|
||||||
AWeapon *PickNewWeapon (PClassAmmo *ammotype);
|
AWeapon *PickNewWeapon (PClassAmmo *ammotype);
|
||||||
AWeapon *BestWeapon (PClassAmmo *ammotype);
|
AWeapon *BestWeapon (PClassAmmo *ammotype);
|
||||||
|
|
|
@ -1,233 +0,0 @@
|
||||||
/*
|
|
||||||
#include "actor.h"
|
|
||||||
#include "gi.h"
|
|
||||||
#include "m_random.h"
|
|
||||||
#include "s_sound.h"
|
|
||||||
#include "d_player.h"
|
|
||||||
#include "a_action.h"
|
|
||||||
#include "a_pickups.h"
|
|
||||||
#include "p_local.h"
|
|
||||||
#include "a_sharedglobal.h"
|
|
||||||
#include "p_enemy.h"
|
|
||||||
#include "d_event.h"
|
|
||||||
#include "gstrings.h"
|
|
||||||
#include "vm.h"
|
|
||||||
*/
|
|
||||||
|
|
||||||
void P_UpdateBeak (AActor *actor);
|
|
||||||
|
|
||||||
static FRandom pr_chickenplayerthink ("ChickenPlayerThink");
|
|
||||||
static FRandom pr_chicattack ("ChicAttack");
|
|
||||||
static FRandom pr_feathers ("Feathers");
|
|
||||||
static FRandom pr_beakatkpl1 ("BeakAtkPL1");
|
|
||||||
static FRandom pr_beakatkpl2 ("BeakAtkPL2");
|
|
||||||
|
|
||||||
class AChickenPlayer : public APlayerPawn
|
|
||||||
{
|
|
||||||
DECLARE_CLASS (AChickenPlayer, APlayerPawn)
|
|
||||||
public:
|
|
||||||
void MorphPlayerThink ();
|
|
||||||
};
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(AChickenPlayer, false, false, false, false)
|
|
||||||
|
|
||||||
void AChickenPlayer::MorphPlayerThink ()
|
|
||||||
{
|
|
||||||
if (health > 0)
|
|
||||||
{ // Handle beak movement
|
|
||||||
P_UpdateBeak (this);
|
|
||||||
}
|
|
||||||
if (player->morphTics & 15)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Vel.X == 0 && Vel.Y == 0 && pr_chickenplayerthink () < 160)
|
|
||||||
{ // Twitch view angle
|
|
||||||
Angles.Yaw += pr_chickenplayerthink.Random2() * (360. / 256. / 32.);
|
|
||||||
}
|
|
||||||
if ((Z() <= floorz) && (pr_chickenplayerthink() < 32))
|
|
||||||
{ // Jump and noise
|
|
||||||
Vel.Z += JumpZ;
|
|
||||||
|
|
||||||
FState * painstate = FindState(NAME_Pain);
|
|
||||||
if (painstate != NULL) SetState (painstate);
|
|
||||||
}
|
|
||||||
if (pr_chickenplayerthink () < 48)
|
|
||||||
{ // Just noise
|
|
||||||
S_Sound (this, CHAN_VOICE, "chicken/active", 1, ATTN_NORM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC A_ChicAttack
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_ChicAttack)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
if (!self->target)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (self->CheckMeleeRange())
|
|
||||||
{
|
|
||||||
int damage = 1 + (pr_chicattack() & 1);
|
|
||||||
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
|
|
||||||
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC A_Feathers
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
int count;
|
|
||||||
AActor *mo;
|
|
||||||
|
|
||||||
if (self->health > 0)
|
|
||||||
{ // Pain
|
|
||||||
count = pr_feathers() < 32 ? 2 : 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Death
|
|
||||||
count = 5 + (pr_feathers()&3);
|
|
||||||
}
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
mo = Spawn("Feather", self->PosPlusZ(20.), NO_REPLACE);
|
|
||||||
mo->target = self;
|
|
||||||
mo->Vel.X = pr_feathers.Random2() / 256.;
|
|
||||||
mo->Vel.Y = pr_feathers.Random2() / 256.;
|
|
||||||
mo->Vel.Z = 1. + pr_feathers() / 128.;
|
|
||||||
mo->SetState (mo->SpawnState + (pr_feathers()&7));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC P_UpdateBeak
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void P_UpdateBeak (AActor *self)
|
|
||||||
{
|
|
||||||
DPSprite *pspr;
|
|
||||||
if (self->player != nullptr && (pspr = self->player->FindPSprite(PSP_WEAPON)) != nullptr)
|
|
||||||
{
|
|
||||||
pspr->y = WEAPONTOP + self->player->chickenPeck / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC A_BeakRaise
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise)
|
|
||||||
{
|
|
||||||
PARAM_ACTION_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
player_t *player;
|
|
||||||
|
|
||||||
if (nullptr == (player = self->player))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP;
|
|
||||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC P_PlayPeck
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void P_PlayPeck (AActor *chicken)
|
|
||||||
{
|
|
||||||
S_Sound (chicken, CHAN_VOICE, "chicken/peck", 1, ATTN_NORM);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC A_BeakAttackPL1
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
|
|
||||||
{
|
|
||||||
PARAM_ACTION_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
DAngle angle;
|
|
||||||
int damage;
|
|
||||||
DAngle slope;
|
|
||||||
player_t *player;
|
|
||||||
FTranslatedLineTarget t;
|
|
||||||
|
|
||||||
if (NULL == (player = self->player))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
damage = 1 + (pr_beakatkpl1()&3);
|
|
||||||
angle = player->mo->Angles.Yaw;
|
|
||||||
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
|
|
||||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t);
|
|
||||||
if (t.linetarget)
|
|
||||||
{
|
|
||||||
player->mo->Angles.Yaw = t.angleFromSource;
|
|
||||||
}
|
|
||||||
P_PlayPeck (player->mo);
|
|
||||||
player->chickenPeck = 12;
|
|
||||||
player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl1() & 7;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC A_BeakAttackPL2
|
|
||||||
//
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
|
|
||||||
{
|
|
||||||
PARAM_ACTION_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
DAngle angle;
|
|
||||||
int damage;
|
|
||||||
DAngle slope;
|
|
||||||
player_t *player;
|
|
||||||
FTranslatedLineTarget t;
|
|
||||||
|
|
||||||
if (NULL == (player = self->player))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
damage = pr_beakatkpl2.HitDice (4);
|
|
||||||
angle = player->mo->Angles.Yaw;
|
|
||||||
slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
|
|
||||||
P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "BeakPuff", true, &t);
|
|
||||||
if (t.linetarget)
|
|
||||||
{
|
|
||||||
player->mo->Angles.Yaw = t.angleFromSource;
|
|
||||||
}
|
|
||||||
P_PlayPeck (player->mo);
|
|
||||||
player->chickenPeck = 12;
|
|
||||||
player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl2()&3;
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
|
||||||
// Include all the other Heretic stuff here to reduce compile time
|
// Include all the other Heretic stuff here to reduce compile time
|
||||||
#include "a_chicken.cpp"
|
|
||||||
#include "a_dsparil.cpp"
|
#include "a_dsparil.cpp"
|
||||||
#include "a_hereticartifacts.cpp"
|
#include "a_hereticartifacts.cpp"
|
||||||
#include "a_hereticweaps.cpp"
|
#include "a_hereticweaps.cpp"
|
||||||
|
|
|
@ -49,6 +49,13 @@ void AdjustPlayerAngle (AActor *pmo, FTranslatedLineTarget *t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(AActor, AdjustPlayerAngle)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
PARAM_POINTER(t, FTranslatedLineTarget);
|
||||||
|
AdjustPlayerAngle(self, t);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// TryPunch
|
// TryPunch
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
#include "a_magecone.cpp"
|
#include "a_magecone.cpp"
|
||||||
#include "a_magelightning.cpp"
|
#include "a_magelightning.cpp"
|
||||||
#include "a_magestaff.cpp"
|
#include "a_magestaff.cpp"
|
||||||
#include "a_pig.cpp"
|
|
||||||
#include "a_serpent.cpp"
|
#include "a_serpent.cpp"
|
||||||
#include "a_spike.cpp"
|
#include "a_spike.cpp"
|
||||||
#include "a_summon.cpp"
|
#include "a_summon.cpp"
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
#include "actor.h"
|
|
||||||
#include "gi.h"
|
|
||||||
#include "m_random.h"
|
|
||||||
#include "s_sound.h"
|
|
||||||
#include "d_player.h"
|
|
||||||
#include "a_action.h"
|
|
||||||
#include "a_pickups.h"
|
|
||||||
#include "p_local.h"
|
|
||||||
#include "a_sharedglobal.h"
|
|
||||||
#include "p_enemy.h"
|
|
||||||
#include "d_event.h"
|
|
||||||
#include "gstrings.h"
|
|
||||||
#include "vm.h"
|
|
||||||
*/
|
|
||||||
|
|
||||||
static FRandom pr_snoutattack ("SnoutAttack");
|
|
||||||
static FRandom pr_pigattack ("PigAttack");
|
|
||||||
static FRandom pr_pigplayerthink ("PigPlayerThink");
|
|
||||||
|
|
||||||
// Pig player ---------------------------------------------------------------
|
|
||||||
|
|
||||||
class APigPlayer : public APlayerPawn
|
|
||||||
{
|
|
||||||
DECLARE_CLASS (APigPlayer, APlayerPawn)
|
|
||||||
public:
|
|
||||||
void MorphPlayerThink ();
|
|
||||||
};
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(APigPlayer, false, false, false, false)
|
|
||||||
|
|
||||||
void APigPlayer::MorphPlayerThink ()
|
|
||||||
{
|
|
||||||
if (player->morphTics & 15)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(Vel.X == 0 && Vel.Y == 0 && pr_pigplayerthink() < 64)
|
|
||||||
{ // Snout sniff
|
|
||||||
if (player->ReadyWeapon != nullptr)
|
|
||||||
{
|
|
||||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Grunt"));
|
|
||||||
}
|
|
||||||
S_Sound (this, CHAN_VOICE, "PigActive1", 1, ATTN_NORM); // snort
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (pr_pigplayerthink() < 48)
|
|
||||||
{
|
|
||||||
S_Sound (this, CHAN_VOICE, "PigActive", 1, ATTN_NORM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_SnoutAttack
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_SnoutAttack)
|
|
||||||
{
|
|
||||||
PARAM_ACTION_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
DAngle angle;
|
|
||||||
int damage;
|
|
||||||
DAngle slope;
|
|
||||||
player_t *player;
|
|
||||||
AActor *puff;
|
|
||||||
FTranslatedLineTarget t;
|
|
||||||
|
|
||||||
if (NULL == (player = self->player))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
damage = 3+(pr_snoutattack()&3);
|
|
||||||
angle = player->mo->Angles.Yaw;
|
|
||||||
slope = P_AimLineAttack(player->mo, angle, MELEERANGE);
|
|
||||||
puff = P_LineAttack(player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, "SnoutPuff", true, &t);
|
|
||||||
S_Sound(player->mo, CHAN_VOICE, "PigActive", 1, ATTN_NORM);
|
|
||||||
if(t.linetarget)
|
|
||||||
{
|
|
||||||
AdjustPlayerAngle(player->mo, &t);
|
|
||||||
if(puff != NULL)
|
|
||||||
{ // Bit something
|
|
||||||
S_Sound(player->mo, CHAN_VOICE, "PigAttack", 1, ATTN_NORM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//============================================================================
|
|
||||||
//
|
|
||||||
// A_PigPain
|
|
||||||
//
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, A_PigPain)
|
|
||||||
{
|
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
|
||||||
|
|
||||||
CALL_ACTION(A_Pain, self);
|
|
||||||
if (self->Z() <= self->floorz)
|
|
||||||
{
|
|
||||||
self->Vel.Z = 3.5;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -109,8 +109,29 @@ IMPLEMENT_POINTERS_END
|
||||||
void DPSprite::InitNativeFields()
|
void DPSprite::InitNativeFields()
|
||||||
{
|
{
|
||||||
auto meta = RUNTIME_CLASS(DPSprite);
|
auto meta = RUNTIME_CLASS(DPSprite);
|
||||||
|
PType *TypeActor = NewPointer(RUNTIME_CLASS(AActor));
|
||||||
|
PType *TypePSP = NewPointer(RUNTIME_CLASS(DPSprite));
|
||||||
|
PType *TypePlayer = NewPointer(NewNativeStruct("Player", nullptr));
|
||||||
|
|
||||||
meta->AddNativeField("State", TypeState, myoffsetof(DPSprite, State), VARF_ReadOnly);
|
meta->AddNativeField("State", TypeState, myoffsetof(DPSprite, State), VARF_ReadOnly);
|
||||||
|
meta->AddNativeField("Caller", TypeActor, myoffsetof(DPSprite, Caller), VARF_ReadOnly);
|
||||||
|
meta->AddNativeField("Next", TypePSP, myoffsetof(DPSprite, Next), VARF_ReadOnly);
|
||||||
|
meta->AddNativeField("Owner", TypePlayer, myoffsetof(DPSprite, Owner), VARF_ReadOnly);
|
||||||
|
meta->AddNativeField("Sprite", TypeSpriteID, myoffsetof(DPSprite, Sprite));
|
||||||
|
meta->AddNativeField("Frame", TypeSInt32, myoffsetof(DPSprite, Frame));
|
||||||
|
meta->AddNativeField("ID", TypePlayer, myoffsetof(DPSprite, ID), VARF_ReadOnly);
|
||||||
|
meta->AddNativeField("processPending", TypeBool, myoffsetof(DPSprite, processPending));
|
||||||
|
meta->AddNativeField("x", TypeFloat64, myoffsetof(DPSprite, x));
|
||||||
|
meta->AddNativeField("y", TypeFloat64, myoffsetof(DPSprite, y));
|
||||||
|
meta->AddNativeField("oldx", TypeFloat64, myoffsetof(DPSprite, oldx));
|
||||||
|
meta->AddNativeField("oldy", TypeFloat64, myoffsetof(DPSprite, oldy));
|
||||||
|
meta->AddNativeField("firstTic", TypeBool, myoffsetof(DPSprite, firstTic));
|
||||||
|
meta->AddNativeField("Tics", TypeSInt32, myoffsetof(DPSprite, Tics));
|
||||||
|
meta->AddNativeField("bAddWeapon", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_ADDWEAPON);
|
||||||
|
meta->AddNativeField("bAddBob", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_ADDBOB);
|
||||||
|
meta->AddNativeField("bPowDouble", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_POWDOUBLE);
|
||||||
|
meta->AddNativeField("bCVarFast", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_CVARFAST);
|
||||||
|
meta->AddNativeField("bFlip", TypeSInt32, myoffsetof(DPSprite, Flags), 0, PSPF_FLIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
@ -179,6 +200,14 @@ DPSprite *player_t::FindPSprite(int layer)
|
||||||
return pspr;
|
return pspr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_Player, FindPSprite) // the underscore is needed to get past the name mangler which removes the first clas name character to match the class representation (needs to be fixed in a later commit)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(player_t);
|
||||||
|
PARAM_INT(id);
|
||||||
|
ACTION_RETURN_OBJECT(self->FindPSprite((PSPLayers)id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -161,6 +161,12 @@ bool ValidatePlayerClass(PClassActor *ti, const char *name)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APlayerPawn::InitNativeFields()
|
||||||
|
{
|
||||||
|
auto meta = RUNTIME_CLASS(APlayerPawn);
|
||||||
|
meta->AddNativeField("JumpZ", TypeFloat64, myoffsetof(APlayerPawn, JumpZ));
|
||||||
|
}
|
||||||
|
|
||||||
void SetupPlayerClasses ()
|
void SetupPlayerClasses ()
|
||||||
{
|
{
|
||||||
FPlayerClass newclass;
|
FPlayerClass newclass;
|
||||||
|
@ -622,7 +628,7 @@ void player_t::SendPitchLimits() const
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
IMPLEMENT_CLASS(APlayerPawn, false, true, false, true)
|
IMPLEMENT_CLASS(APlayerPawn, false, true, true, true)
|
||||||
|
|
||||||
IMPLEMENT_POINTERS_START(APlayerPawn)
|
IMPLEMENT_POINTERS_START(APlayerPawn)
|
||||||
IMPLEMENT_POINTER(InvFirst)
|
IMPLEMENT_POINTER(InvFirst)
|
||||||
|
@ -1381,6 +1387,10 @@ void APlayerPawn::GiveDefaultInventory ()
|
||||||
|
|
||||||
void APlayerPawn::MorphPlayerThink ()
|
void APlayerPawn::MorphPlayerThink ()
|
||||||
{
|
{
|
||||||
|
VINDEX(APlayerPawn, MorphPlayerThink);
|
||||||
|
VMValue params[1] = { (DObject*)this };
|
||||||
|
VMFrameStack stack;
|
||||||
|
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void APlayerPawn::ActivateMorphWeapon ()
|
void APlayerPawn::ActivateMorphWeapon ()
|
||||||
|
|
|
@ -2543,7 +2543,15 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left->IsVector() && right->IsVector())
|
if (left->ValueType == TypeState && right->IsInteger() && Operator == '+' && !left->isConstant())
|
||||||
|
{
|
||||||
|
// This is the only special case of pointer addition that will be accepted - because it is used quite often in the existing game code.
|
||||||
|
ValueType = TypeState;
|
||||||
|
right = new FxMulDiv('*', right, new FxConstant((int)sizeof(FState), ScriptPosition)); // multiply by size here, so that constants can be better optimized.
|
||||||
|
right = right->Resolve(ctx);
|
||||||
|
ABORT(right);
|
||||||
|
}
|
||||||
|
else if (left->IsVector() && right->IsVector())
|
||||||
{
|
{
|
||||||
// a vector2 can be added to or subtracted from a vector 3 but it needs to be the right operand.
|
// a vector2 can be added to or subtracted from a vector 3 but it needs to be the right operand.
|
||||||
if (left->ValueType == right->ValueType || (left->ValueType == TypeVector3 && right->ValueType == TypeVector2))
|
if (left->ValueType == right->ValueType || (left->ValueType == TypeVector3 && right->ValueType == TypeVector2))
|
||||||
|
@ -2616,6 +2624,16 @@ ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit op2 = right->Emit(build);
|
ExpEmit op2 = right->Emit(build);
|
||||||
if (Operator == '+')
|
if (Operator == '+')
|
||||||
{
|
{
|
||||||
|
if (op1.RegType == REGT_POINTER)
|
||||||
|
{
|
||||||
|
assert(!op1.Konst);
|
||||||
|
assert(op2.RegType == REGT_INT);
|
||||||
|
op1.Free(build);
|
||||||
|
op2.Free(build);
|
||||||
|
ExpEmit opout(build, REGT_POINTER);
|
||||||
|
build->Emit(op2.Konst? OP_ADDA_RK : OP_ADDA_RR, opout.RegNum, op1.RegNum, op2.RegNum);
|
||||||
|
return opout;
|
||||||
|
}
|
||||||
// Since addition is commutative, only the second operand may be a constant.
|
// Since addition is commutative, only the second operand may be a constant.
|
||||||
if (op1.Konst)
|
if (op1.Konst)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,7 @@ class Actor : Thinker native
|
||||||
virtual native void Activate(Actor activator);
|
virtual native void Activate(Actor activator);
|
||||||
virtual native void Deactivate(Actor activator);
|
virtual native void Deactivate(Actor activator);
|
||||||
|
|
||||||
|
native void AdjustPlayerAngle(FTranslatedLineTarget t);
|
||||||
native static readonly<Actor> GetDefaultByType(class<Actor> cls);
|
native static readonly<Actor> GetDefaultByType(class<Actor> cls);
|
||||||
native static double deltaangle(double ang1, double ang2);
|
native static double deltaangle(double ang1, double ang2);
|
||||||
native static double absangle(double ang1, double ang2);
|
native static double absangle(double ang1, double ang2);
|
||||||
|
@ -467,7 +468,6 @@ class Actor : Thinker native
|
||||||
native void A_DeQueueCorpse();
|
native void A_DeQueueCorpse();
|
||||||
native void A_ClearLastHeard();
|
native void A_ClearLastHeard();
|
||||||
native bool A_SelectWeapon(class<Weapon> whichweapon, int flags = 0);
|
native bool A_SelectWeapon(class<Weapon> whichweapon, int flags = 0);
|
||||||
native void A_Feathers();
|
|
||||||
native void A_ClassBossHealth();
|
native void A_ClassBossHealth();
|
||||||
native void A_ShootGun();
|
native void A_ShootGun();
|
||||||
native void A_RocketInFlight();
|
native void A_RocketInFlight();
|
||||||
|
@ -476,7 +476,6 @@ class Actor : Thinker native
|
||||||
native void A_GiveQuestItem(int itemno);
|
native void A_GiveQuestItem(int itemno);
|
||||||
native void A_RemoveForcefield();
|
native void A_RemoveForcefield();
|
||||||
native void A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
|
native void A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
|
||||||
native void A_PigPain ();
|
|
||||||
native void A_SetAngle(double angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetAngle(double angle = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
native void A_SetPitch(double pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetPitch(double pitch, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
native void A_SetRoll(double roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
native void A_SetRoll(double roll, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||||
|
|
|
@ -948,3 +948,8 @@ enum EFSkillProperty // floating point properties
|
||||||
SKILLP_FriendlyHealth,
|
SKILLP_FriendlyHealth,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EWeaponPos
|
||||||
|
{
|
||||||
|
WEAPONBOTTOM = 128,
|
||||||
|
WEAPONTOP = 32
|
||||||
|
}
|
|
@ -26,8 +26,6 @@ class Beak : Weapon
|
||||||
Weapon.SisterWeapon "BeakPowered";
|
Weapon.SisterWeapon "BeakPowered";
|
||||||
}
|
}
|
||||||
|
|
||||||
action native void A_BeakRaise ();
|
|
||||||
action native void A_BeakAttackPL1();
|
|
||||||
|
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
|
@ -44,9 +42,56 @@ class Beak : Weapon
|
||||||
BEAK A 18 A_BeakAttackPL1;
|
BEAK A 18 A_BeakAttackPL1;
|
||||||
Goto Ready;
|
Goto Ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// PROC A_BeakRaise
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
action void A_BeakRaise ()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
player.GetPSprite(PSP_WEAPON).y = WEAPONTOP;
|
||||||
|
player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.GetReadyState());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// PROC A_BeakAttackPL1
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
action void A_BeakAttackPL1()
|
||||||
|
{
|
||||||
|
FTranslatedLineTarget t;
|
||||||
|
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int damage = random[BeakAtk](1,3);
|
||||||
|
double ang = angle;
|
||||||
|
double slope = AimLineAttack (ang, MELEERANGE);
|
||||||
|
LineAttack (ang, MELEERANGE, slope, damage, 'Melee', "BeakPuff", true, t);
|
||||||
|
if (t.linetarget)
|
||||||
|
{
|
||||||
|
angle = t.angleFromSource;
|
||||||
|
}
|
||||||
|
A_PlaySound ("chicken/peck", CHAN_VOICE);
|
||||||
|
player.chickenPeck = 12;
|
||||||
|
player.GetPSprite(PSP_WEAPON).Tics -= random[BeakAtk](0,7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// BeakPowered ---------------------------------------------------------------------
|
||||||
|
|
||||||
class BeakPowered : Beak
|
class BeakPowered : Beak
|
||||||
{
|
{
|
||||||
Default
|
Default
|
||||||
|
@ -55,7 +100,6 @@ class BeakPowered : Beak
|
||||||
Weapon.SisterWeapon "Beak";
|
Weapon.SisterWeapon "Beak";
|
||||||
}
|
}
|
||||||
|
|
||||||
action native void A_BeakAttackPL2();
|
|
||||||
|
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
|
@ -63,11 +107,40 @@ class BeakPowered : Beak
|
||||||
BEAK A 12 A_BeakAttackPL2;
|
BEAK A 12 A_BeakAttackPL2;
|
||||||
Goto Ready;
|
Goto Ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// PROC A_BeakAttackPL2
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
action void A_BeakAttackPL2()
|
||||||
|
{
|
||||||
|
FTranslatedLineTarget t;
|
||||||
|
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int damage = random[BeakAtk](1,8) * 4;
|
||||||
|
double ang = angle;
|
||||||
|
double slope = AimLineAttack (ang, MELEERANGE);
|
||||||
|
LineAttack (ang, MELEERANGE, slope, damage, 'Melee', "BeakPuff", true, t);
|
||||||
|
if (t.linetarget)
|
||||||
|
{
|
||||||
|
angle = t.angleFromSource;
|
||||||
|
}
|
||||||
|
A_PlaySound ("chicken/peck", CHAN_VOICE);
|
||||||
|
player.chickenPeck = 12;
|
||||||
|
player.GetPSprite(PSP_WEAPON).Tics -= random[BeakAtk](0,3);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chicken player -----------------------------------------------------------
|
// Chicken player -----------------------------------------------------------
|
||||||
|
|
||||||
class ChickenPlayer : PlayerPawn native
|
class ChickenPlayer : PlayerPawn
|
||||||
{
|
{
|
||||||
Default
|
Default
|
||||||
{
|
{
|
||||||
|
@ -118,6 +191,44 @@ class ChickenPlayer : PlayerPawn native
|
||||||
CHKN L -1;
|
CHKN L -1;
|
||||||
Stop;
|
Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// PROC P_UpdateBeak
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
override void MorphPlayerThink ()
|
||||||
|
{
|
||||||
|
if (health > 0)
|
||||||
|
{ // Handle beak movement
|
||||||
|
PSprite pspr;
|
||||||
|
if (player != null && (pspr = player.FindPSprite(PSP_WEAPON)) != null)
|
||||||
|
{
|
||||||
|
pspr.y = WEAPONTOP + player.chickenPeck / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (player.morphTics & 15)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Vel.X == 0 && Vel.Y == 0 && random[ChickenPlayerThink]() < 160)
|
||||||
|
{ // Twitch view ang
|
||||||
|
angle += Random2[ChickenPlayerThink]() * (360. / 256. / 32.);
|
||||||
|
}
|
||||||
|
if ((pos.z <= floorz) && (random[ChickenPlayerThink]() < 32))
|
||||||
|
{ // Jump and noise
|
||||||
|
Vel.Z += JumpZ;
|
||||||
|
|
||||||
|
State painstate = FindState('Pain');
|
||||||
|
if (painstate != null) SetState (painstate);
|
||||||
|
}
|
||||||
|
if (random[ChickenPlayerThink]() < 48)
|
||||||
|
{ // Just noise
|
||||||
|
A_PlaySound ("chicken/active", CHAN_VOICE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,3 +310,37 @@ class Feather : Actor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extend class Actor
|
||||||
|
{
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// PROC A_Feathers
|
||||||
|
// This is used by both the chicken player and monster and must be in the
|
||||||
|
// common base class to be accessible by both
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void A_Feathers()
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (health > 0)
|
||||||
|
{ // Pain
|
||||||
|
count = random[Feathers]() < 32 ? 2 : 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Death
|
||||||
|
count = 5 + (random[Feathers]()&3);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
Actor mo = Spawn("Feather", pos + (0, 0, 20), NO_REPLACE);
|
||||||
|
mo.target = self;
|
||||||
|
mo.Vel.X = Random2[Feathers]() / 256.;
|
||||||
|
mo.Vel.Y = Random2[Feathers]() / 256.;
|
||||||
|
mo.Vel.Z = 1. + random[Feathers]() / 128.;
|
||||||
|
mo.SetState (mo.SpawnState + (random[Feathers]()&7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -34,8 +34,6 @@ class Snout : Weapon
|
||||||
Weapon.YAdjust 10;
|
Weapon.YAdjust 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
action native void A_SnoutAttack ();
|
|
||||||
|
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
Ready:
|
Ready:
|
||||||
|
@ -54,12 +52,43 @@ class Snout : Weapon
|
||||||
WPIG B 8;
|
WPIG B 8;
|
||||||
Goto Ready;
|
Goto Ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_SnoutAttack
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
action void A_SnoutAttack ()
|
||||||
|
{
|
||||||
|
FTranslatedLineTarget t;
|
||||||
|
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int damage = random[SnoutAttack](3, 6);
|
||||||
|
double ang = angle;
|
||||||
|
double slope = AimLineAttack(ang, MELEERANGE);
|
||||||
|
Actor puff = LineAttack(ang, MELEERANGE, slope, damage, 'Melee', "SnoutPuff", true, t);
|
||||||
|
A_PlaySound("PigActive", CHAN_VOICE);
|
||||||
|
if(t.linetarget)
|
||||||
|
{
|
||||||
|
AdjustPlayerAngle(t);
|
||||||
|
if(puff != null)
|
||||||
|
{ // Bit something
|
||||||
|
A_PlaySound("PigAttack", CHAN_VOICE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Pig player ---------------------------------------------------------------
|
// Pig player ---------------------------------------------------------------
|
||||||
|
|
||||||
class PigPlayer : PlayerPawn native
|
class PigPlayer : PlayerPawn
|
||||||
{
|
{
|
||||||
Default
|
Default
|
||||||
{
|
{
|
||||||
|
@ -112,6 +141,30 @@ class PigPlayer : PlayerPawn native
|
||||||
PIGY M 1 A_FreezeDeathChunks;
|
PIGY M 1 A_FreezeDeathChunks;
|
||||||
Wait;
|
Wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override void MorphPlayerThink ()
|
||||||
|
{
|
||||||
|
if (player.morphTics & 15)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(Vel.X == 0 && Vel.Y == 0 && random[PigPlayerThink]() < 64)
|
||||||
|
{ // Snout sniff
|
||||||
|
if (player.ReadyWeapon != null)
|
||||||
|
{
|
||||||
|
player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.FindState('Grunt'));
|
||||||
|
}
|
||||||
|
A_PlaySound ("PigActive1", CHAN_VOICE); // snort
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (random[PigPlayerThink]() < 48)
|
||||||
|
{
|
||||||
|
A_PlaySound ("PigActive", CHAN_VOICE); // snort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,3 +221,21 @@ class Pig : MorphedMonster
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extend class Actor
|
||||||
|
{
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// A_PigPain
|
||||||
|
//
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
void A_PigPain ()
|
||||||
|
{
|
||||||
|
A_Pain();
|
||||||
|
if (pos.z <= floorz)
|
||||||
|
{
|
||||||
|
Vel.Z = 3.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -457,6 +457,12 @@ class Weapon : StateProvider native
|
||||||
|
|
||||||
native bool DepleteAmmo(bool altFire, bool checkEnough = true, int ammouse = -1);
|
native bool DepleteAmmo(bool altFire, bool checkEnough = true, int ammouse = -1);
|
||||||
|
|
||||||
|
virtual State GetReadyState ()
|
||||||
|
{
|
||||||
|
return FindState('Ready');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
native action void A_ZoomFactor(double scale = 1, int flags = 0);
|
native action void A_ZoomFactor(double scale = 1, int flags = 0);
|
||||||
native action void A_SetCrosshair(int xhair);
|
native action void A_SetCrosshair(int xhair);
|
||||||
const ZOOM_INSTANT = 1;
|
const ZOOM_INSTANT = 1;
|
||||||
|
|
|
@ -49,6 +49,10 @@ class PlayerPawn : Actor native
|
||||||
if (MeleeState != null) SetState (MeleeState);
|
if (MeleeState != null) SetState (MeleeState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void MorphPlayerThink()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlayerChunk : PlayerPawn native
|
class PlayerChunk : PlayerPawn native
|
||||||
|
@ -78,4 +82,5 @@ struct Player native
|
||||||
native void SetPsprite(int id, State stat, bool pending = false);
|
native void SetPsprite(int id, State stat, bool pending = false);
|
||||||
native void SetSafeFlash(Weapon weap, State flashstate, int index);
|
native void SetSafeFlash(Weapon weap, State flashstate, int index);
|
||||||
native PSprite GetPSprite(int id);
|
native PSprite GetPSprite(int id);
|
||||||
|
native PSprite FindPSprite(int id);
|
||||||
}
|
}
|
Loading…
Reference in a new issue