diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 828c7fc34..42dc50f98 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -855,8 +855,6 @@ set( NOT_COMPILED_SOURCE_FILES ${OTHER_SYSTEM_SOURCES} sc_man_scanner.h sc_man_scanner.re - g_hexen/a_clericmace.cpp - g_hexen/a_clericstaff.cpp g_hexen/a_fighteraxe.cpp g_hexen/a_fighterhammer.cpp g_hexen/a_fighterplayer.cpp diff --git a/src/g_hexen/a_clericmace.cpp b/src/g_hexen/a_clericmace.cpp deleted file mode 100644 index a15196cf8..000000000 --- a/src/g_hexen/a_clericmace.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -#include "m_random.h" -#include "p_local.h" -#include "a_hexenglobal.h" -#include "vm.h" -*/ - -static FRandom pr_maceatk ("CMaceAttack"); - -//=========================================================================== -// -// A_CMaceAttack -// -//=========================================================================== - -DEFINE_ACTION_FUNCTION(AActor, A_CMaceAttack) -{ - PARAM_ACTION_PROLOGUE(AActor); - - DAngle angle; - int damage; - DAngle slope; - int i; - player_t *player; - FTranslatedLineTarget t; - - if (NULL == (player = self->player)) - { - return 0; - } - - PClassActor *hammertime = PClass::FindActor("HammerPuff"); - - damage = 25+(pr_maceatk()&15); - for (i = 0; i < 16; i++) - { - for (int j = 1; j >= -1; j -= 2) - { - angle = player->mo->Angles.Yaw + j*i*(45. / 16); - slope = P_AimLineAttack(player->mo, angle, 2 * MELEERANGE, &t); - if (t.linetarget) - { - P_LineAttack(player->mo, angle, 2 * MELEERANGE, slope, damage, NAME_Melee, hammertime, true, &t); - if (t.linetarget != NULL) - { - AdjustPlayerAngle(player->mo, &t); - return 0; - } - } - } - } - // didn't find any creatures, so try to strike any walls - player->mo->weaponspecial = 0; - - angle = player->mo->Angles.Yaw; - slope = P_AimLineAttack (player->mo, angle, MELEERANGE); - P_LineAttack (player->mo, angle, MELEERANGE, slope, damage, NAME_Melee, hammertime); - return 0; -} diff --git a/src/g_hexen/a_clericstaff.cpp b/src/g_hexen/a_clericstaff.cpp deleted file mode 100644 index ef7beaffa..000000000 --- a/src/g_hexen/a_clericstaff.cpp +++ /dev/null @@ -1,199 +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 "p_local.h" -#include "a_action.h" -#include "p_pspr.h" -#include "gstrings.h" -#include "a_hexenglobal.h" -#include "vm.h" -*/ - -static FRandom pr_staffcheck ("CStaffCheck"); -static FRandom pr_blink ("CStaffBlink"); - -// Serpent Staff Missile ---------------------------------------------------- - -class ACStaffMissile : public AActor -{ - DECLARE_CLASS (ACStaffMissile, AActor) -public: - int DoSpecialDamage (AActor *target, int damage, FName damagetype); -}; - -IMPLEMENT_CLASS(ACStaffMissile, false, false) - -int ACStaffMissile::DoSpecialDamage (AActor *target, int damage, FName damagetype) -{ - // Cleric Serpent Staff does poison damage - if (target->player) - { - P_PoisonPlayer (target->player, this, this->target, 20); - damage >>= 1; - } - return damage; -} - -//============================================================================ -// -// A_CStaffCheck -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck) -{ - PARAM_ACTION_PROLOGUE(AActor); - - APlayerPawn *pmo; - int damage; - int newLife, max; - DAngle angle; - DAngle slope; - int i; - player_t *player; - FTranslatedLineTarget t; - PClassActor *puff; - - if (nullptr == (player = self->player)) - { - return 0; - } - AWeapon *weapon = self->player->ReadyWeapon; - - pmo = player->mo; - damage = 20 + (pr_staffcheck() & 15); - max = pmo->GetMaxHealth(); - puff = PClass::FindActor("CStaffPuff"); - for (i = 0; i < 3; i++) - { - for (int j = 1; j >= -1; j -= 2) - { - angle = pmo->Angles.Yaw + j*i*(45. / 16); - slope = P_AimLineAttack(pmo, angle, 1.5 * MELEERANGE, &t, 0., ALF_CHECK3D); - if (t.linetarget) - { - P_LineAttack(pmo, angle, 1.5 * MELEERANGE, slope, damage, NAME_Melee, puff, false, &t); - if (t.linetarget != nullptr) - { - pmo->Angles.Yaw = t.angleFromSource; - if (((t.linetarget->player && (!t.linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || t.linetarget->flags3&MF3_ISMONSTER) - && (!(t.linetarget->flags2&(MF2_DORMANT | MF2_INVULNERABLE)))) - { - newLife = player->health + (damage >> 3); - newLife = newLife > max ? max : newLife; - if (newLife > player->health) - { - pmo->health = player->health = newLife; - } - if (weapon != nullptr) - { - FState * newstate = weapon->FindState("Drain"); - if (newstate != nullptr) P_SetPsprite(player, PSP_WEAPON, newstate); - } - } - if (weapon != nullptr) - { - weapon->DepleteAmmo(weapon->bAltFire, false); - } - } - return 0; - } - } - } - return 0; -} - -//============================================================================ -// -// A_CStaffAttack -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_CStaffAttack) -{ - PARAM_ACTION_PROLOGUE(AActor); - - AActor *mo; - player_t *player; - - if (NULL == (player = self->player)) - { - return 0; - } - - AWeapon *weapon = self->player->ReadyWeapon; - if (weapon != NULL) - { - if (!weapon->DepleteAmmo (weapon->bAltFire)) - return 0; - } - mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw - 3.0); - if (mo) - { - mo->WeaveIndexXY = 32; - } - mo = P_SpawnPlayerMissile (self, RUNTIME_CLASS(ACStaffMissile), self->Angles.Yaw + 3.0); - if (mo) - { - mo->WeaveIndexXY = 0; - } - S_Sound (self, CHAN_WEAPON, "ClericCStaffFire", 1, ATTN_NORM); - return 0; -} - -//============================================================================ -// -// A_CStaffMissileSlither -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_CStaffMissileSlither) -{ - PARAM_SELF_PROLOGUE(AActor); - - A_Weave(self, 3, 0, 1., 0.); - return 0; -} - -//============================================================================ -// -// A_CStaffInitBlink -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_CStaffInitBlink) -{ - PARAM_ACTION_PROLOGUE(AActor); - - self->weaponspecial = (pr_blink()>>1)+20; - return 0; -} - -//============================================================================ -// -// A_CStaffCheckBlink -// -//============================================================================ - -DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink) -{ - PARAM_ACTION_PROLOGUE(AActor); - - if (self->player && self->player->ReadyWeapon) - { - if (!--self->weaponspecial) - { - P_SetPsprite(self->player, PSP_WEAPON, self->player->ReadyWeapon->FindState ("Blink")); - self->weaponspecial = (pr_blink()+50)>>2; - } - else - { - DoReadyWeapon(self); - } - } - return 0; -} diff --git a/src/g_hexen/a_hexenmisc.cpp b/src/g_hexen/a_hexenmisc.cpp index 3fb334cb1..101bcf145 100644 --- a/src/g_hexen/a_hexenmisc.cpp +++ b/src/g_hexen/a_hexenmisc.cpp @@ -24,8 +24,6 @@ #include "serializer.h" // Include all the Hexen stuff here to reduce compile time -#include "a_clericmace.cpp" -#include "a_clericstaff.cpp" #include "a_fighteraxe.cpp" #include "a_fighterhammer.cpp" #include "a_fighterplayer.cpp" diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 8c28c46b3..040e05ce0 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1734,6 +1734,15 @@ bool P_PoisonPlayer (player_t *player, AActor *poisoner, AActor *source, int poi return true; } +DEFINE_ACTION_FUNCTION(_PlayerInfo, PoisonPlayer) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + PARAM_OBJECT(poisoner, AActor); + PARAM_OBJECT(source, AActor); + PARAM_INT(poison); + ACTION_RETURN_BOOL(P_PoisonPlayer(self, poisoner, source, poison)); +} + //========================================================================== // // P_PoisonDamage - Similar to P_DamageMobj diff --git a/src/p_user.cpp b/src/p_user.cpp index f28bf9f42..eadbda10e 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1207,6 +1207,12 @@ int APlayerPawn::GetMaxHealth() const return MaxHealth > 0? MaxHealth : ((i_compatflags&COMPATF_DEHHEALTH)? 100 : deh.MaxHealth); } +DEFINE_ACTION_FUNCTION(APlayerPawn, GetMaxHealth) +{ + PARAM_SELF_PROLOGUE(APlayerPawn); + ACTION_RETURN_INT(self->GetMaxHealth()); +} + //=========================================================================== // // APlayerPawn :: UpdateWaterLevel diff --git a/src/scripting/zscript/zcc_parser.cpp b/src/scripting/zscript/zcc_parser.cpp index 401a15c25..9d24d0cb1 100644 --- a/src/scripting/zscript/zcc_parser.cpp +++ b/src/scripting/zscript/zcc_parser.cpp @@ -406,10 +406,12 @@ void ParseScripts() int lump, lastlump = 0; FScriptPosition::ResetErrorCounter(); + while ((lump = Wads.FindLump("ZSCRIPT", &lastlump)) != -1) { DoParse(lump); } + } /* diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index ccf3fb374..2b1ba6a5a 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -592,7 +592,6 @@ class Actor : Thinker native native void A_FreezeDeathChunks(); native void A_GenericFreezeDeath(); native void A_IceGuyDie(); - native void A_CStaffMissileSlither(); native void A_PlayerScream(); native void A_SkullPop(class skulltype = "BloodySkull"); native void A_CheckPlayerDone(); diff --git a/wadsrc/static/zscript/hexen/clericmace.txt b/wadsrc/static/zscript/hexen/clericmace.txt index 5e00b9c3b..b6f42c7e4 100644 --- a/wadsrc/static/zscript/hexen/clericmace.txt +++ b/wadsrc/static/zscript/hexen/clericmace.txt @@ -13,8 +13,6 @@ class CWeapMace : ClericWeapon Tag "$TAG_CWEAPMACE"; } - action native void A_CMaceAttack(); - States { Select: @@ -46,4 +44,44 @@ class CWeapMace : ClericWeapon CMCE A 1 Offset (8, 45); Goto Ready; } + + //=========================================================================== + // + // A_CMaceAttack + // + //=========================================================================== + + action void A_CMaceAttack() + { + FTranslatedLineTarget t; + + if (player == null) + { + return; + } + + int damage = 25+(random[MaceAtk]()&15); + for (int i = 0; i < 16; i++) + { + for (int j = 1; j >= -1; j -= 2) + { + double ang = angle + j*i*(45. / 16); + double slope = AimLineAttack(ang, 2 * MELEERANGE, t); + if (t.linetarget) + { + LineAttack(ang, 2 * MELEERANGE, slope, damage, 'Melee', "HammerPuff", true, t); + if (t.linetarget != null) + { + AdjustPlayerAngle(t); + return; + } + } + } + } + // didn't find any creatures, so try to strike any walls + weaponspecial = 0; + + double slope = AimLineAttack (angle, MELEERANGE); + LineAttack (angle, MELEERANGE, slope, damage, 'Melee', "HammerPuff"); + } } diff --git a/wadsrc/static/zscript/hexen/clericstaff.txt b/wadsrc/static/zscript/hexen/clericstaff.txt index 7ae0e9da3..0d7ca0a99 100644 --- a/wadsrc/static/zscript/hexen/clericstaff.txt +++ b/wadsrc/static/zscript/hexen/clericstaff.txt @@ -16,11 +16,6 @@ class CWeapStaff : ClericWeapon Tag "$TAG_CWEAPSTAFF"; } - action native void A_CStaffInitBlink(); - action native void A_CStaffCheckBlink(); - action native void A_CStaffCheck(); - action native void A_CStaffAttack(); - States { Spawn: @@ -55,11 +50,132 @@ class CWeapStaff : ClericWeapon CSSF K 10 Offset (0, 36); Goto Ready + 2; } + + //============================================================================ + // + // A_CStaffCheck + // + //============================================================================ + + action void A_CStaffCheck() + { + FTranslatedLineTarget t; + + if (player == null) + { + return; + } + Weapon weapon = player.ReadyWeapon; + + int damage = 20 + (random[StaffCheck]() & 15); + int max = player.mo.GetMaxHealth(); + for (int i = 0; i < 3; i++) + { + for (int j = 1; j >= -1; j -= 2) + { + double ang = angle + j*i*(45. / 16); + double slope = AimLineAttack(ang, 1.5 * MELEERANGE, t, 0., ALF_CHECK3D); + if (t.linetarget) + { + LineAttack(ang, 1.5 * MELEERANGE, slope, damage, 'Melee', "CStaffPuff", false, t); + if (t.linetarget != null) + { + angle = t.angleFromSource; + if (((t.linetarget.player && (!t.linetarget.IsTeammate(self) || level.teamdamage != 0)) || t.linetarget.bIsMonster) + && (!t.linetarget.bDormant && !bInvulnerable)) + { + int newLife = player.health + (damage >> 3); + newLife = newLife > max ? max : newLife; + if (newLife > player.health) + { + health = player.health = newLife; + } + if (weapon != null) + { + State newstate = weapon.FindState("Drain"); + if (newstate != null) player.SetPsprite(PSP_WEAPON, newstate); + } + } + if (weapon != null) + { + weapon.DepleteAmmo(weapon.bAltFire, false); + } + } + return; + } + } + } + } + + //============================================================================ + // + // A_CStaffAttack + // + //============================================================================ + + action void A_CStaffAttack() + { + if (player == null) + { + return; + } + + Weapon weapon = player.ReadyWeapon; + if (weapon != null) + { + if (!weapon.DepleteAmmo (weapon.bAltFire)) + return; + } + Actor mo = SpawnPlayerMissile ("CStaffMissile", angle - 3.0); + if (mo) + { + mo.WeaveIndexXY = 32; + } + mo = SpawnPlayerMissile ("CStaffMissile", angle + 3.0); + if (mo) + { + mo.WeaveIndexXY = 0; + } + A_PlaySound ("ClericCStaffFire", CHAN_WEAPON); + } + + //============================================================================ + // + // A_CStaffInitBlink + // + //============================================================================ + + action void A_CStaffInitBlink() + { + weaponspecial = (random[CStaffBlink]() >> 1) + 20; + } + + //============================================================================ + // + // A_CStaffCheckBlink + // + //============================================================================ + + action void A_CStaffCheckBlink() + { + if (player && player.ReadyWeapon) + { + if (!--weaponspecial) + { + player.SetPsprite(PSP_WEAPON, player.ReadyWeapon.FindState ("Blink")); + weaponspecial = (random[CStaffBlink]() + 50) >> 2; + } + else + { + A_WeaponReady(); + } + } + } } // Serpent Staff Missile ---------------------------------------------------- -class CStaffMissile : Actor native +class CStaffMissile : Actor { Default { @@ -82,6 +198,34 @@ class CStaffMissile : Actor native CSSF HI 3 Bright; Stop; } + + override int DoSpecialDamage (Actor target, int damage, Name damagetype) + { + // Cleric Serpent Staff does poison damage + if (target.player) + { + target.player.PoisonPlayer (self, self.target, 20); + damage >>= 1; + } + return damage; + } + +} + +extend class Actor +{ + + //============================================================================ + // + // A_CStaffMissileSlither + // + //============================================================================ + + void A_CStaffMissileSlither() + { + A_Weave(3, 0, 1., 0.); + } + } // Serpent Staff Puff ------------------------------------------------------- diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index e76e637fe..48d62688b 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -78,7 +78,8 @@ class PlayerPawn : Actor native virtual void MorphPlayerThink() { } - + + native int GetMaxHealth(); } class PlayerChunk : PlayerPawn native @@ -214,6 +215,7 @@ FWeaponSlots weapons; native bool UndoPlayerMorph(playerinfo player, int unmorphflag = 0, bool force = false); + native bool PoisonPlayer(Actor poisoner, Actor source, int poison); native void SetPsprite(int id, State stat, bool pending = false); native void SetSafeFlash(Weapon weap, State flashstate, int index); native PSprite GetPSprite(int id);