diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 215e88b52..bca0e9371 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1147,7 +1147,6 @@ set (PCH_SOURCES wi_stuff.cpp zstrformat.cpp g_hexen/a_hexenmisc.cpp - g_raven/a_artitele.cpp g_raven/a_minotaur.cpp g_strife/a_strifestuff.cpp g_strife/strife_sbar.cpp diff --git a/src/g_game.cpp b/src/g_game.cpp index 810a29da1..9af9b4532 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1536,6 +1536,23 @@ static FPlayerStart *SelectRandomDeathmatchSpot (int playernum, unsigned int sel return &deathmatchstarts[i]; } +DEFINE_ACTION_FUNCTION(DObject, G_PickDeathmatchStart) +{ + PARAM_PROLOGUE; + unsigned int selections = deathmatchstarts.Size(); + unsigned int i = pr_dmspawn() % selections; + if (numret > 1) + { + ret[1].SetInt(deathmatchstarts[i].angle); + numret = 2; + } + if (numret > 0) + { + ret[0].SetVector(deathmatchstarts[i].pos); + } + return numret; +} + void G_DeathMatchSpawnPlayer (int playernum) { unsigned int selections; @@ -1577,6 +1594,7 @@ void G_DeathMatchSpawnPlayer (int playernum) if (mo != NULL) P_PlayerStartStomp(mo); } + // // G_PickPlayerStart // @@ -1614,6 +1632,24 @@ FPlayerStart *G_PickPlayerStart(int playernum, int flags) return &playerstarts[playernum]; } +DEFINE_ACTION_FUNCTION(DObject, G_PickPlayerStart) +{ + PARAM_PROLOGUE; + PARAM_INT(playernum); + PARAM_INT_DEF(flags); + auto ps = G_PickPlayerStart(playernum, flags); + if (numret > 1) + { + ret[1].SetInt(ps? ps->angle : 0); + numret = 2; + } + if (numret > 0) + { + ret[0].SetVector(ps ? ps->pos : DVector3(0, 0, 0)); + } + return numret; +} + // // G_QueueBody // diff --git a/src/g_raven/a_artitele.cpp b/src/g_raven/a_artitele.cpp deleted file mode 100644 index 76c0bc402..000000000 --- a/src/g_raven/a_artitele.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "info.h" -#include "a_pickups.h" -#include "a_artifacts.h" -#include "gstrings.h" -#include "p_local.h" -#include "p_spec.h" -#include "gi.h" -#include "s_sound.h" -#include "m_random.h" -#include "doomstat.h" -#include "g_game.h" -#include "d_player.h" -#include "a_morph.h" - -static FRandom pr_tele ("TeleportSelf"); - -// Teleport (self) ---------------------------------------------------------- - -class AArtiTeleport : public AInventory -{ - DECLARE_CLASS (AArtiTeleport, AInventory) -public: - bool Use (bool pickup); -}; - -IMPLEMENT_CLASS(AArtiTeleport, false, false) - -bool AArtiTeleport::Use (bool pickup) -{ - DVector3 dest; - int destAngle; - - if (deathmatch) - { - unsigned int selections = deathmatchstarts.Size (); - unsigned int i = pr_tele() % selections; - dest = deathmatchstarts[i].pos; - destAngle = deathmatchstarts[i].angle; - } - else - { - FPlayerStart *start = G_PickPlayerStart(int(Owner->player - players)); - dest = start->pos; - destAngle = start->angle; - } - dest.Z = ONFLOORZ; - P_Teleport (Owner, dest, (double)destAngle, TELF_SOURCEFOG | TELF_DESTFOG); - bool canlaugh = true; - if (Owner->player->morphTics && (Owner->player->MorphStyle & MORPH_UNDOBYCHAOSDEVICE)) - { // Teleporting away will undo any morph effects (pig) - if (!P_UndoPlayerMorph (Owner->player, Owner->player, MORPH_UNDOBYCHAOSDEVICE) - && (Owner->player->MorphStyle & MORPH_FAILNOLAUGH)) - { - canlaugh = false; - } - } - if (canlaugh) - { // Full volume laugh - S_Sound (Owner, CHAN_VOICE, "*evillaugh", 1, ATTN_NONE); - } - return true; -} - diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 14055202a..e9752ee53 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -238,6 +238,17 @@ bool P_Teleport (AActor *thing, DVector3 pos, DAngle angle, int flags) return true; } +DEFINE_ACTION_FUNCTION(AActor, Teleport) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(z); + PARAM_ANGLE(an); + PARAM_INT(flags); + ACTION_RETURN_BOOL(P_Teleport(self, DVector3(x, y, z), an, flags)); +} + static AActor *SelectTeleDest (int tid, int tag, bool norandom) { AActor *searcher; diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 1b13d05ff..45b44f767 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -306,6 +306,7 @@ class Actor : Thinker native native Actor OldSpawnMissile(Actor dest, class type, Actor owner = null); native Actor SpawnPuff(class pufftype, vector3 pos, double hitdir, double particledir, int updown, int flags = 0, Actor vict = null); + native bool Teleport(Vector3 pos, double angle, int flags); native void TraceBleed(int damage, Actor missile); native bool CheckMeleeRange(); native int DamageMobj(Actor inflictor, Actor source, int damage, Name mod, int flags = 0, double angle = 0); @@ -318,7 +319,7 @@ class Actor : Thinker native native void NewChaseDir(); native bool CheckMissileRange(); native bool SetState(state st, bool nofunction = false); - native state FindState(statelabel st, bool exact = false); // do we need exact later? + native state FindState(statelabel st, bool exact = false); bool SetStateLabel(statelabel st, bool nofunction = false) { return SetState(FindState(st), nofunction); } native action state ResolveState(statelabel st); // this one, unlike FindState, is context aware. native void LinkToWorld(); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 13aa480a9..6d0e77795 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -5,6 +5,8 @@ class Object native // These really should be global functions... native static int G_SkillPropertyInt(int p); native static double G_SkillPropertyFloat(int p); + native static vector3, int G_PickDeathmatchStart(); + native static vector3, int G_PickPlayerStart(int pnum, int flags = 0); /*virtual*/ native void Destroy(); } diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index 70f8abed0..d87ad338a 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -982,3 +982,14 @@ enum EFindFloorCeiling FFCF_RESTRICTEDPORTAL = 128, // current values in the iterator's return are through a restricted portal type (i.e. some features are blocked.) FFCF_NODROPOFF = 256, // Caller does not need a dropoff (saves some time when checking portals) }; + +enum ETeleport +{ + TELF_DESTFOG = 1, + TELF_SOURCEFOG = 2, + TELF_KEEPORIENTATION = 4, + TELF_KEEPVELOCITY = 8, + TELF_KEEPHEIGHT = 16, + TELF_ROTATEBOOM = 32, + TELF_ROTATEBOOMINVERSE = 64, +}; diff --git a/wadsrc/static/zscript/heretic/dsparil.txt b/wadsrc/static/zscript/heretic/dsparil.txt index e2cfca558..54931b65e 100644 --- a/wadsrc/static/zscript/heretic/dsparil.txt +++ b/wadsrc/static/zscript/heretic/dsparil.txt @@ -345,7 +345,7 @@ class Sorcerer2 : Actor { return; } - A_PlaySound (AttackSound, CHAN_BODY); + A_PlaySound (AttackSound, CHAN_BODY, 1, false, ATTN_NONE); if (CheckMeleeRange()) { int damage = random[Srcr2Atk](1, 8) * 20; diff --git a/wadsrc/static/zscript/raven/artiegg.txt b/wadsrc/static/zscript/raven/artiegg.txt index ef3c6e2be..f0287048e 100644 --- a/wadsrc/static/zscript/raven/artiegg.txt +++ b/wadsrc/static/zscript/raven/artiegg.txt @@ -47,11 +47,10 @@ class ArtiEgg : CustomInventory EGGC ABCB 6; Loop; Use: - TNT1 A 0 A_FireCustomMissile("EggFX", -15, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("EggFX", -7.5, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("EggFX", 0, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("EggFX", 7.5, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("EggFX", 15, 0, 0, 0, 1); + TNT1 A 0 + { + for (double i = -15; i <= 15; i += 7.5) A_FireCustomMissile("EggFX", i, 0, 0, 0, 1); + } Stop; } } @@ -103,11 +102,10 @@ class ArtiPork : CustomInventory PORK ABCDEFGH 5; Loop; Use: - TNT1 A 0 A_FireCustomMissile("PorkFX", -15, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("PorkFX", -7.5, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("PorkFX", 0, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("PorkFX", 7.5, 0, 0, 0, 1); - TNT1 A 0 A_FireCustomMissile("PorkFX", 15, 0, 0, 0, 1); + TNT1 A 0 + { + for (double i = -15; i <= 15; i += 7.5) A_FireCustomMissile("PorkFX", i, 0, 0, 0, 1); + } Stop; } } diff --git a/wadsrc/static/zscript/raven/artitele.txt b/wadsrc/static/zscript/raven/artitele.txt index 9f21bd733..3242db92e 100644 --- a/wadsrc/static/zscript/raven/artitele.txt +++ b/wadsrc/static/zscript/raven/artitele.txt @@ -1,7 +1,7 @@ // Teleport (self) ---------------------------------------------------------- -class ArtiTeleport : Inventory native +class ArtiTeleport : Inventory { Default { @@ -22,6 +22,38 @@ class ArtiTeleport : Inventory native ATLP ABCB 4; Loop; } + + override bool Use (bool pickup) + { + Vector3 dest; + int destAngle; + + if (deathmatch) + { + [dest, destAngle] = G_PickDeathmatchStart(); + } + else + { + [dest, destAngle] = G_PickPlayerStart(Owner.PlayerNumber()); + } + dest.Z = ONFLOORZ; + Owner.Teleport (dest, destAngle, TELF_SOURCEFOG | TELF_DESTFOG); + bool canlaugh = true; + Playerinfo p = Owner.player; + if (p && p.morphTics && (p.MorphStyle & MRF_UNDOBYCHAOSDEVICE)) + { // Teleporting away will undo any morph effects (pig) + if (!p.UndoPlayerMorph (p, MRF_UNDOBYCHAOSDEVICE) && (p.MorphStyle & MRF_FAILNOLAUGH)) + { + canlaugh = false; + } + } + if (canlaugh) + { // Full volume laugh + A_PlaySound ("*evillaugh", CHAN_VOICE, 1, false, ATTN_NONE); + } + return true; + } + }