- Converted the mace and all related actors to DECORATE and generalized

the spawn function that only spawns one mace per level.
- Moved Mace respawning code into AInventory so that it works properly
  for replacement actors.


SVN r1107 (trunk)
This commit is contained in:
Christoph Oelckers 2008-08-03 19:10:48 +00:00
parent 11fbfc5b1f
commit affd0e5034
11 changed files with 291 additions and 282 deletions

View file

@ -1,4 +1,8 @@
August 3, 2008 (Changes by Graf Zahl)
- Converted the mace and all related actors to DECORATE and generalized
the spawn function that only spawns one mace per level.
- Moved Mace respawning code into AInventory so that it works properly
for replacement actors.
- Added more DECORATE conversions by Karate Chris.
- Cleaned up the new bridge code and exported all related actors to
DECORATE so that the exported code pointers can be used.

View file

@ -107,6 +107,7 @@ ACTOR(DamageChildren)
ACTOR(CheckForReload)
ACTOR(ResetReloadCounter)
ACTOR(ClearReFire)
ACTOR(SpawnSingleItem)
// Heretic stuff
ACTOR(Feathers)
@ -151,6 +152,13 @@ ACTOR(FireGoldWandPL2)
ACTOR(FireCrossbowPL1)
ACTOR(FireCrossbowPL2)
ACTOR(GauntletAttack)
ACTOR(FireMacePL1)
ACTOR(FireMacePL2)
ACTOR(MacePL1Check)
ACTOR(MaceBallImpact)
ACTOR(MaceBallImpact2)
ACTOR(DeathBallImpact)
WEAPON(CMaceAttack)
ACTOR(FiredRocks)

View file

@ -14,7 +14,6 @@
#include "p_enemy.h"
#include "gi.h"
#include "r_translate.h"
#include "a_specialspot.h"
#include "thingdef/thingdef.h"
static FRandom pr_sap ("StaffAtkPL1");
@ -22,7 +21,6 @@ static FRandom pr_sap2 ("StaffAtkPL2");
static FRandom pr_fgw ("FireWandPL1");
static FRandom pr_fgw2 ("FireWandPL2");
static FRandom pr_boltspark ("BoltSpark");
static FRandom pr_spawnmace ("SpawnMace");
static FRandom pr_macerespawn ("MaceRespawn");
static FRandom pr_maceatk ("FireMacePL1");
static FRandom pr_gatk ("GauntletAttack");
@ -343,212 +341,16 @@ void A_GauntletAttack (AActor *actor)
#define MAGIC_JUNK 1234
void A_FireMacePL1B (AActor *);
void A_FireMacePL1 (AActor *);
void A_MacePL1Check (AActor *);
void A_MaceBallImpact (AActor *);
void A_MaceBallImpact2 (AActor *);
void A_FireMacePL2 (AActor *);
void A_DeathBallImpact (AActor *);
// The mace itself ----------------------------------------------------------
class AMace : public AHereticWeapon
{
DECLARE_ACTOR (AMace, AHereticWeapon)
protected:
bool DoRespawn ();
};
class AMacePowered : public AMace
{
DECLARE_STATELESS_ACTOR (AMacePowered, AMace)
};
FState AMace::States[] =
{
#define S_WMCE 0
S_NORMAL (WMCE, 'A', -1, NULL , NULL),
#define S_MACEREADY (S_WMCE+1)
S_NORMAL (MACE, 'A', 1, A_WeaponReady , &States[S_MACEREADY]),
#define S_MACEDOWN (S_MACEREADY+1)
S_NORMAL (MACE, 'A', 1, A_Lower , &States[S_MACEDOWN]),
#define S_MACEUP (S_MACEDOWN+1)
S_NORMAL (MACE, 'A', 1, A_Raise , &States[S_MACEUP]),
#define S_MACEATK1 (S_MACEUP+1)
S_NORMAL (MACE, 'B', 4, NULL , &States[S_MACEATK1+1]),
S_NORMAL (MACE, 'C', 3, A_FireMacePL1 , &States[S_MACEATK1+2]),
S_NORMAL (MACE, 'D', 3, A_FireMacePL1 , &States[S_MACEATK1+3]),
S_NORMAL (MACE, 'E', 3, A_FireMacePL1 , &States[S_MACEATK1+4]),
S_NORMAL (MACE, 'F', 3, A_FireMacePL1 , &States[S_MACEATK1+5]),
S_NORMAL (MACE, 'C', 4, A_ReFire , &States[S_MACEATK1+6]),
S_NORMAL (MACE, 'D', 4, NULL , &States[S_MACEATK1+7]),
S_NORMAL (MACE, 'E', 4, NULL , &States[S_MACEATK1+8]),
S_NORMAL (MACE, 'F', 4, NULL , &States[S_MACEATK1+9]),
S_NORMAL (MACE, 'B', 4, NULL , &States[S_MACEREADY]),
#define S_MACEATK2 (S_MACEATK1+10)
S_NORMAL (MACE, 'B', 4, NULL , &States[S_MACEATK2+1]),
S_NORMAL (MACE, 'D', 4, A_FireMacePL2 , &States[S_MACEATK2+2]),
S_NORMAL (MACE, 'B', 4, NULL , &States[S_MACEATK2+3]),
S_NORMAL (MACE, 'A', 8, A_ReFire , &States[S_MACEREADY])
};
IMPLEMENT_ACTOR (AMace, Heretic, -1, 31)
PROP_Flags (MF_SPECIAL)
PROP_SpawnState (0)
PROP_Weapon_SelectionOrder (1400)
PROP_Weapon_Flags (WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE)
PROP_Weapon_AmmoUse1 (USE_MACE_AMMO_1)
PROP_Weapon_AmmoGive1 (50)
PROP_Weapon_UpState (S_MACEUP)
PROP_Weapon_DownState (S_MACEDOWN)
PROP_Weapon_ReadyState (S_MACEREADY)
PROP_Weapon_AtkState (S_MACEATK1)
PROP_Weapon_HoldAtkState (S_MACEATK1+1)
PROP_Weapon_YAdjust (15)
PROP_Weapon_MoveCombatDist (27000000)
PROP_Weapon_AmmoType1 ("MaceAmmo")
PROP_Weapon_SisterType ("MacePowered")
PROP_Weapon_ProjectileType ("MaceFX2")
PROP_Inventory_PickupMessage("$TXT_WPNMACE")
END_DEFAULTS
IMPLEMENT_STATELESS_ACTOR (AMacePowered, Heretic, -1, 0)
PROP_Weapon_Flags (WIF_POWERED_UP|WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE)
PROP_Weapon_AmmoUse1 (USE_MACE_AMMO_2)
PROP_Weapon_AmmoGive1 (0)
PROP_Weapon_AtkState (S_MACEATK2)
PROP_Weapon_HoldAtkState (S_MACEATK2)
PROP_Weapon_SisterType ("Mace")
PROP_Weapon_ProjectileType ("MaceFX4")
END_DEFAULTS
// Mace FX1 -----------------------------------------------------------------
class AMaceFX1 : public AActor
{
DECLARE_ACTOR (AMaceFX1, AActor)
};
FState AMaceFX1::States[] =
{
#define S_MACEFX1 0
S_NORMAL (FX02, 'A', 4, A_MacePL1Check , &States[S_MACEFX1+1]),
S_NORMAL (FX02, 'B', 4, A_MacePL1Check , &States[S_MACEFX1+0]),
#define S_MACEFXI1 (S_MACEFX1+2)
S_BRIGHT (FX02, 'F', 4, A_MaceBallImpact , &States[S_MACEFXI1+1]),
S_BRIGHT (FX02, 'G', 4, NULL , &States[S_MACEFXI1+2]),
S_BRIGHT (FX02, 'H', 4, NULL , &States[S_MACEFXI1+3]),
S_BRIGHT (FX02, 'I', 4, NULL , &States[S_MACEFXI1+4]),
S_BRIGHT (FX02, 'J', 4, NULL , NULL)
};
IMPLEMENT_ACTOR (AMaceFX1, Heretic, -1, 154)
PROP_RadiusFixed (8)
PROP_HeightFixed (6)
PROP_SpeedFixed (20)
PROP_Damage (2)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
PROP_Flags2 (MF2_HERETICBOUNCE|MF2_THRUGHOST|MF2_NOTELEPORT|MF2_PCROSS|MF2_IMPACT)
PROP_Flags3 (MF3_WARNBOT)
PROP_SpawnState (S_MACEFX1)
PROP_DeathState (S_MACEFXI1)
PROP_SeeSound ("weapons/maceshoot")
END_DEFAULTS
// Mace FX2 -----------------------------------------------------------------
class AMaceFX2 : public AActor
{
DECLARE_ACTOR (AMaceFX2, AActor)
};
FState AMaceFX2::States[] =
{
#define S_MACEFX2 0
S_NORMAL (FX02, 'C', 4, NULL , &States[S_MACEFX2+1]),
S_NORMAL (FX02, 'D', 4, NULL , &States[S_MACEFX2+0]),
#define S_MACEFXI2 (S_MACEFX2+2)
S_BRIGHT (FX02, 'F', 4, A_MaceBallImpact2 , &AMaceFX1::States[S_MACEFXI1+1])
};
IMPLEMENT_ACTOR (AMaceFX2, Heretic, -1, 156)
PROP_RadiusFixed (8)
PROP_HeightFixed (6)
PROP_SpeedFixed (10)
PROP_Damage (6)
PROP_Gravity (FRACUNIT/8)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF)
PROP_Flags2 (MF2_HERETICBOUNCE|MF2_THRUGHOST|MF2_NOTELEPORT|MF2_PCROSS|MF2_IMPACT)
PROP_SpawnState (S_MACEFX2)
PROP_DeathState (S_MACEFXI2)
END_DEFAULTS
// Mace FX3 -----------------------------------------------------------------
class AMaceFX3 : public AMaceFX1
{
DECLARE_ACTOR (AMaceFX3, AMaceFX1)
};
FState AMaceFX3::States[] =
{
#define S_MACEFX3 0
S_NORMAL (FX02, 'A', 4, NULL , &States[S_MACEFX3+1]),
S_NORMAL (FX02, 'B', 4, NULL , &States[S_MACEFX3+0])
};
IMPLEMENT_ACTOR (AMaceFX3, Heretic, -1, 155)
PROP_SpeedFixed (7)
PROP_Damage (4)
PROP_Gravity (FRACUNIT/8)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF)
PROP_Flags2 (MF2_HERETICBOUNCE|MF2_THRUGHOST|MF2_NOTELEPORT|MF2_PCROSS|MF2_IMPACT)
PROP_SpawnState (S_MACEFX3)
END_DEFAULTS
// Mace FX4 -----------------------------------------------------------------
class AMaceFX4 : public AActor
{
DECLARE_ACTOR (AMaceFX4, AActor)
DECLARE_CLASS (AMaceFX4, AActor)
public:
int DoSpecialDamage (AActor *target, int damage);
};
FState AMaceFX4::States[] =
{
#define S_MACEFX4 0
S_NORMAL (FX02, 'E', 99, NULL , &States[S_MACEFX4+0]),
#define S_MACEFXI4 (S_MACEFX4+1)
S_BRIGHT (FX02, 'C', 4, A_DeathBallImpact , &AMaceFX1::States[S_MACEFXI1+1])
};
IMPLEMENT_ACTOR (AMaceFX4, Heretic, -1, 153)
PROP_RadiusFixed (8)
PROP_HeightFixed (6)
PROP_SpeedFixed (7)
PROP_Damage (18)
PROP_Gravity (FRACUNIT/8)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF)
PROP_Flags2 (MF2_HERETICBOUNCE|MF2_THRUGHOST|MF2_TELESTOMP|MF2_PCROSS|MF2_IMPACT)
PROP_SpawnState (S_MACEFX4)
PROP_DeathState (S_MACEFXI4)
END_DEFAULTS
IMPLEMENT_CLASS (AMaceFX4)
int AMaceFX4::DoSpecialDamage (AActor *target, int damage)
{
@ -570,79 +372,6 @@ int AMaceFX4::DoSpecialDamage (AActor *target, int damage)
return 1000000; // Something's gonna die
}
// Mace spawn spot ----------------------------------------------------------
void A_SpawnMace (AActor *);
class AMaceSpawner : public ASpecialSpot
{
DECLARE_ACTOR (AMaceSpawner, ASpecialSpot)
};
FState AMaceSpawner::States[] =
{
S_NORMAL (TNT1, 'A', 1, NULL, &States[1]),
S_NORMAL (TNT1, 'A', -1, A_SpawnMace, NULL)
};
IMPLEMENT_ACTOR (AMaceSpawner, Heretic, 2002, 0)
PROP_Flags (MF_NOSECTOR|MF_NOBLOCKMAP)
PROP_SpawnState (0)
END_DEFAULTS
// Every mace spawn spot will execute this action. The first one
// will build a list of all mace spots in the level and spawn a
// mace. The rest of the spots will do nothing.
void A_SpawnMace (AActor *self)
{
if (self->target != NULL)
{ // Another spot already did it
return;
}
AActor *spot = NULL;
DSpotState *state = DSpotState::GetSpotState();
if (state != NULL) spot = state->GetRandomSpot(RUNTIME_TYPE(self), true);
if (spot == NULL) return;
if (!deathmatch && pr_spawnmace() < 64)
{ // Sometimes doesn't show up if not in deathmatch
return;
}
AActor *mace = Spawn<AMace> (self->x, self->y, self->z, ALLOW_REPLACE);
if (mace)
{
mace->SetOrigin (spot->x, spot->y, spot->z);
mace->z = mace->floorz;
// We want this mace to respawn.
mace->flags &= ~MF_DROPPED;
}
}
// FIXME: Generalize this so that it doesn't depend on item specific implementation!
// AMace::DoRespawn
// Moves the mace to a different spot when it respawns
bool AMace::DoRespawn ()
{
AActor *spot = NULL;
DSpotState *state = DSpotState::GetSpotState();
if (state != NULL) spot = state->GetRandomSpot(RUNTIME_CLASS(AMaceSpawner));
if (spot != NULL)
{
SetOrigin (spot->x, spot->y, spot->z);
z = floorz;
}
return true;
}
//----------------------------------------------------------------------------
//
// PROC A_FireMacePL1B
@ -666,7 +395,7 @@ void A_FireMacePL1B (AActor *actor)
if (!weapon->DepleteAmmo (weapon->bAltFire))
return;
}
ball = Spawn<AMaceFX2> (actor->x, actor->y, actor->z + 28*FRACUNIT
ball = Spawn("MaceFX2", actor->x, actor->y, actor->z + 28*FRACUNIT
- actor->floorclip, ALLOW_REPLACE);
ball->momz = 2*FRACUNIT+/*((player->lookdir)<<(FRACBITS-5))*/
finetangent[FINEANGLES/4-(actor->pitch>>ANGLETOFINESHIFT)];
@ -710,7 +439,7 @@ void A_FireMacePL1 (AActor *actor)
}
player->psprites[ps_weapon].sx = ((pr_maceatk()&3)-2)*FRACUNIT;
player->psprites[ps_weapon].sy = WEAPONTOP+(pr_maceatk()&3)*FRACUNIT;
ball = P_SpawnPlayerMissile (actor, RUNTIME_CLASS(AMaceFX1),
ball = P_SpawnPlayerMissile (actor, PClass::FindClass("MaceFX1"),
actor->angle+(((pr_maceatk()&7)-4)<<24));
if (ball)
{
@ -812,7 +541,7 @@ void A_MaceBallImpact2 (AActor *ball)
ball->momz = (ball->momz * 192) >> 8;
ball->SetState (ball->SpawnState);
tiny = Spawn<AMaceFX3> (ball->x, ball->y, ball->z, ALLOW_REPLACE);
tiny = Spawn("MaceFX3", ball->x, ball->y, ball->z, ALLOW_REPLACE);
angle = ball->angle+ANG90;
tiny->target = ball->target;
tiny->angle = angle;
@ -824,7 +553,7 @@ void A_MaceBallImpact2 (AActor *ball)
tiny->momz = ball->momz;
P_CheckMissileSpawn (tiny);
tiny = Spawn<AMaceFX3> (ball->x, ball->y, ball->z, ALLOW_REPLACE);
tiny = Spawn("MaceFX3", ball->x, ball->y, ball->z, ALLOW_REPLACE);
angle = ball->angle-ANG90;
tiny->target = ball->target;
tiny->angle = angle;

View file

@ -14,6 +14,7 @@
#include "templates.h"
#include "a_strifeglobal.h"
#include "a_morph.h"
#include "a_specialspot.h"
static FRandom pr_restore ("RestorePos");
@ -489,7 +490,7 @@ void AInventory::Tick ()
void AInventory::Serialize (FArchive &arc)
{
Super::Serialize (arc);
arc << Owner << Amount << MaxAmount << RespawnTics << ItemFlags << Icon << PickupSound;
arc << Owner << Amount << MaxAmount << RespawnTics << ItemFlags << Icon << PickupSound << SpawnPointClass;
}
//===========================================================================
@ -1168,6 +1169,18 @@ END_DEFAULTS
bool AInventory::DoRespawn ()
{
if (SpawnPointClass != NULL)
{
AActor *spot = NULL;
DSpotState *state = DSpotState::GetSpotState();
if (state != NULL) spot = state->GetRandomSpot(SpawnPointClass);
if (spot != NULL)
{
SetOrigin (spot->x, spot->y, spot->z);
z = floorz;
}
}
return true;
}

View file

@ -117,7 +117,6 @@ public:
virtual bool ShouldRespawn ();
virtual bool ShouldStay ();
virtual void Hide ();
virtual bool DoRespawn ();
virtual bool TryPickup (AActor *toucher);
virtual void DoPickupSpecial (AActor *toucher);
virtual bool SpecialDropAction (AActor *dropper);
@ -127,6 +126,7 @@ public:
virtual const char *PickupMessage ();
virtual void PlayPickupSound (AActor *toucher);
bool DoRespawn ();
AInventory *PrevItem(); // Returns the item preceding this one in the list.
AInventory *PrevInv(); // Returns the previous item with IF_INVBAR set.
AInventory *NextInv(); // Returns the next item with IF_INVBAR set.
@ -137,6 +137,7 @@ public:
int RespawnTics; // Tics from pickup time to respawn time
FTextureID Icon; // Icon to show on status bar or HUD
int DropTime; // Countdown after dropping
const PClass *SpawnPointClass; // For respawning like Heretic's mace
DWORD ItemFlags;
const PClass *PickupFlash; // actor to spawn as pickup flash

View file

@ -37,12 +37,14 @@
#include "p_local.h"
#include "statnums.h"
#include "i_system.h"
#include "thingdef/thingdef.h"
static FRandom pr_spot ("SpecialSpot");
static FRandom pr_spawnmace ("SpawnMace");
IMPLEMENT_CLASS(DSpotState)
IMPLEMENT_ABSTRACT_ACTOR (ASpecialSpot)
IMPLEMENT_CLASS (ASpecialSpot)
TObjPtr<DSpotState> DSpotState::SpotState;
//----------------------------------------------------------------------------
@ -371,3 +373,65 @@ void ASpecialSpot::Destroy()
if (state != NULL) state->RemoveSpot(this);
Super::Destroy();
}
// Mace spawn spot ----------------------------------------------------------
// Every mace spawn spot will execute this action. The first one
// will build a list of all mace spots in the level and spawn a
// mace. The rest of the spots will do nothing.
void A_SpawnSingleItem (AActor *self)
{
AActor *spot = NULL;
DSpotState *state = DSpotState::GetSpotState();
if (state != NULL) spot = state->GetRandomSpot(RUNTIME_TYPE(self), true);
if (spot == NULL) return;
int index=CheckIndex(4);
if (index<0) return;
ENamedName SpawnType = (ENamedName)StateParameters[index];
int fail_sp = EvalExpressionI (StateParameters[index+1], self);
int fail_co = EvalExpressionI (StateParameters[index+2], self);
int fail_dm = EvalExpressionI (StateParameters[index+3], self);
if (!multiplayer && pr_spawnmace() < fail_sp)
{ // Sometimes doesn't show up if not in deathmatch
return;
}
if (multiplayer && !deathmatch && pr_spawnmace() < fail_co)
{
return;
}
if (deathmatch && pr_spawnmace() < fail_dm)
{
return;
}
const PClass *cls = PClass::FindClass(SpawnType);
if (cls == NULL)
{
return;
}
AActor *spawned = Spawn(cls, self->x, self->y, self->z, ALLOW_REPLACE);
if (spawned)
{
spawned->SetOrigin (spot->x, spot->y, spot->z);
spawned->z = spawned->floorz;
// We want this to respawn.
if (!(self->flags & MF_DROPPED))
{
spawned->flags &= ~MF_DROPPED;
}
if (spawned->IsKindOf(RUNTIME_CLASS(AInventory)))
{
static_cast<AInventory*>(spawned)->SpawnPointClass = RUNTIME_TYPE(self);
}
}
}

View file

@ -6,7 +6,7 @@
class ASpecialSpot : public AActor
{
DECLARE_STATELESS_ACTOR (ASpecialSpot, AActor)
DECLARE_CLASS (ASpecialSpot, AActor)
public:

View file

@ -75,7 +75,7 @@
// SAVESIG should match SAVEVER.
// MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 1075
#define MINSAVEVER 1107
#if SVN_REVISION_NUMBER < MINSAVEVER
// Never write a savegame with a version lower than what we need

View file

@ -474,3 +474,187 @@ ACTOR GauntletPuff2 : GauntletPuff1
}
// The mace itself ----------------------------------------------------------
ACTOR Mace : HereticWeapon
{
Game Heretic
SpawnID 31
Weapon.SelectionOrder 1400
Weapon.AmmoUse 1
Weapon.AmmoGive1 50
Weapon.YAdjust 15
Weapon.AmmoType "MaceAmmo"
Weapon.SisterWeapon "MacePowered"
Inventory.PickupMessage "$TxT_WPNMACE"
action native A_FireMacePL1();
States
{
Spawn:
WMCE A -1
Stop
Ready:
MACE A 1 A_WeaponReady
Loop
Deselect:
MACE A 1 A_Lower
Loop
Select:
MACE A 1 A_Raise
Loop
Fire:
MACE B 4
Hold:
MACE CDEF 3 A_FireMacePL1
MACE C 4 A_ReFire
MACE DEFB 4
Goto Ready
}
}
ACTOR MacePowered : Mace
{
+WEAPON.POWERED_UP
Weapon.AmmoUse 5
Weapon.AmmoGive 0
Weapon.SisterWeapon "Mace"
action native A_FireMacePL2();
States
{
Fire:
Hold:
MACE B 4
MACE D 4 A_FireMacePL2
MACE B 4
MACE A 8 A_ReFire
Goto Ready
}
}
// Mace FX1 -----------------------------------------------------------------
ACTOR MaceFX1
{
Game Heretic
SpawnID 154
Radius 8
Height 6
Speed 20
Damage 2
Projectile
+THRUGHOST
+HERETICBOUNCE
SeeSound "weapons/maceshoot"
action native A_MacePL1Check();
action native A_MaceBallImpact();
States
{
Spawn:
FX02 AB 4 A_MacePL1Check
Loop
Death:
FX02 F 4 BRIGHT A_MaceBallImpact
FX02 GHIJ 4 BRIGHT
Stop
}
}
// Mace FX2 -----------------------------------------------------------------
ACTOR MaceFX2 : MaceFX1
{
Game Heretic
SpawnID 156
Speed 10
Damage 6
Gravity 0.125
-NOGRAVITY
SeeSound ""
action native A_MaceBallImpact2();
States
{
Spawn:
FX02 CD 4
Loop
Death:
FX02 F 4 A_MaceBallImpact2
goto Super::Death+1
}
}
// Mace FX3 -----------------------------------------------------------------
ACTOR MaceFX3 : MaceFX1
{
Game Heretic
SpawnID 155
Speed 7
Damage 4
-NOGRAVITY
Gravity 0.125
States
{
Spawn:
FX02 AB 4
Loop
}
}
// Mace FX4 -----------------------------------------------------------------
ACTOR MaceFX4 native
{
Game Heretic
SpawnID 153
Radius 8
Height 6
Speed 7
Damage 18
Gravity 0.125
Projectile
-NOGRAVITY
+TELESTOMP
+THRUGHOST
+HERETICBOUNCE
SeeSound ""
action native A_DeathBallImpact();
States
{
Spawn:
FX02 E 99
Loop
Death:
FX02 C 4 A_DeathBallImpact
FX02 GHIJ 4 BRIGHT
Stop
}
}
// Mace spawn spot ----------------------------------------------------------
ACTOR MaceSpawner : SpecialSpot 2002
{
Game Heretic
+NOSECTOR
+NOBLOCKMAP
States
{
Spawn:
TNT1 A 1
TNT1 A -1 A_SpawnSingleItem("Mace", 64, 64, 0)
Stop
}
}

View file

@ -0,0 +1,5 @@
ACTOR SpecialSpot native
{
action native A_SpawnSingleItem(class<Actor> type, optional eval int fail_sp, optional eval int fail_co, optional eval int fail_dm);
}

View file

@ -10,6 +10,7 @@
#include "actors/shared/fountain.txt"
#include "actors/shared/soundsequence.txt"
#include "actors/shared/bridge.txt"
#include "actors/shared/specialspot.txt"
#include "actors/doom/doomplayer.txt"
#include "actors/doom/possessed.txt"