diff --git a/docs/rh-log.txt b/docs/rh-log.txt index d45604ade..bc7fb6a28 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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. diff --git a/src/codepointers.h b/src/codepointers.h index 7eb5f7e86..32ebbe808 100644 --- a/src/codepointers.h +++ b/src/codepointers.h @@ -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) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 21d835808..444c8728a 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -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 (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 (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 (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 (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; diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index 3e00bde64..46494ad8d 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -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; } diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 152821a28..cc063715b 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -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 diff --git a/src/g_shared/a_specialspot.cpp b/src/g_shared/a_specialspot.cpp index e8c91b6ce..65d08059f 100644 --- a/src/g_shared/a_specialspot.cpp +++ b/src/g_shared/a_specialspot.cpp @@ -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::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(spawned)->SpawnPointClass = RUNTIME_TYPE(self); + } + } +} + diff --git a/src/g_shared/a_specialspot.h b/src/g_shared/a_specialspot.h index 8efb35cfa..ffc083978 100644 --- a/src/g_shared/a_specialspot.h +++ b/src/g_shared/a_specialspot.h @@ -6,7 +6,7 @@ class ASpecialSpot : public AActor { - DECLARE_STATELESS_ACTOR (ASpecialSpot, AActor) + DECLARE_CLASS (ASpecialSpot, AActor) public: diff --git a/src/version.h b/src/version.h index 8878e17f5..6cb203d9e 100644 --- a/src/version.h +++ b/src/version.h @@ -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 diff --git a/wadsrc/static/actors/heretic/hereticweaps.txt b/wadsrc/static/actors/heretic/hereticweaps.txt index f6317fbde..f3c7056fa 100644 --- a/wadsrc/static/actors/heretic/hereticweaps.txt +++ b/wadsrc/static/actors/heretic/hereticweaps.txt @@ -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 + } +} + diff --git a/wadsrc/static/actors/shared/specialspot.txt b/wadsrc/static/actors/shared/specialspot.txt new file mode 100644 index 000000000..12803e597 --- /dev/null +++ b/wadsrc/static/actors/shared/specialspot.txt @@ -0,0 +1,5 @@ + +ACTOR SpecialSpot native +{ + action native A_SpawnSingleItem(class type, optional eval int fail_sp, optional eval int fail_co, optional eval int fail_dm); +} diff --git a/wadsrc/static/decorate.txt b/wadsrc/static/decorate.txt index cd53a92b6..57c3a0b88 100644 --- a/wadsrc/static/decorate.txt +++ b/wadsrc/static/decorate.txt @@ -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"