- scriptified ArtiTeleport.

- shortened ArtiEgg and ArtiPork's use state to a single function.
This commit is contained in:
Christoph Oelckers 2016-11-25 19:52:35 +01:00
parent 0d6f37835f
commit 6e1c6c4b33
10 changed files with 104 additions and 77 deletions

View file

@ -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

View file

@ -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
//

View file

@ -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;
}

View file

@ -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;

View file

@ -306,6 +306,7 @@ class Actor : Thinker native
native Actor OldSpawnMissile(Actor dest, class<Actor> type, Actor owner = null);
native Actor SpawnPuff(class<Actor> 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();

View file

@ -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();
}

View file

@ -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,
};

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;
}
}