diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 452c97bff..62fd705eb 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,3 +1,14 @@
+November 25, 2006 (Changes by Graf Zahl)
+- Converted Heretic's Clink (Sabreclaw) to DECORATE.
+- Added MissSound parameter to A_CustomMeleeAttack.
+- Converted Heretic's Snake (Ophidian) to DECORATE.
+- Added an option to A_CustomMissile to jump to the see state if
+ the caller's target is dead.
+- Fixed: A_ThrowGrenade didn't play the missile's spawn sound.
+- Added MF_SPAWNSOUNDSOURCE flag so that Raven's missile spawning code
+ pointers can be recreated with DECORATE.
+- Converted a_ravenambient.cpp to DECORATE.
+
November 24, 2006
- Fixed: The backpack didn't give extra ammo in baby and nightmare modes.
- Fixed: When P_SpawnPlayer() calls DObject::PointerSubstitution() to
diff --git a/src/actor.h b/src/actor.h
index a6a43065b..4cf4c8658 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -109,47 +109,48 @@ enum
{
// --- mobj.flags ---
- MF_SPECIAL = 0x00000001, // call P_SpecialThing when touched
- MF_SOLID = 0x00000002,
- MF_SHOOTABLE = 0x00000004,
- MF_NOSECTOR = 0x00000008, // don't use the sector links
- // (invisible but touchable)
- MF_NOBLOCKMAP = 0x00000010, // don't use the blocklinks
- // (inert but displayable)
- MF_AMBUSH = 0x00000020, // not activated by sound; deaf monster
- MF_JUSTHIT = 0x00000040, // try to attack right back
- MF_JUSTATTACKED = 0x00000080, // take at least one step before attacking
- MF_SPAWNCEILING = 0x00000100, // hang from ceiling instead of floor
- MF_NOGRAVITY = 0x00000200, // don't apply gravity every tic
+ MF_SPECIAL = 0x00000001, // call P_SpecialThing when touched
+ MF_SOLID = 0x00000002,
+ MF_SHOOTABLE = 0x00000004,
+ MF_NOSECTOR = 0x00000008, // don't use the sector links
+ // (invisible but touchable)
+ MF_NOBLOCKMAP = 0x00000010, // don't use the blocklinks
+ // (inert but displayable)
+ MF_AMBUSH = 0x00000020, // not activated by sound; deaf monster
+ MF_JUSTHIT = 0x00000040, // try to attack right back
+ MF_JUSTATTACKED = 0x00000080, // take at least one step before attacking
+ MF_SPAWNCEILING = 0x00000100, // hang from ceiling instead of floor
+ MF_NOGRAVITY = 0x00000200, // don't apply gravity every tic
// movement flags
- MF_DROPOFF = 0x00000400, // allow jumps from high places
- MF_PICKUP = 0x00000800, // for players to pick up items
- MF_NOCLIP = 0x00001000, // player cheat
- MF_INCHASE = 0x00002000, // [RH] used by A_Chase and A_Look to avoid recursion
- MF_FLOAT = 0x00004000, // allow moves to any height, no gravity
- MF_TELEPORT = 0x00008000, // don't cross lines or look at heights
- MF_MISSILE = 0x00010000, // don't hit same species, explode on block
+ MF_DROPOFF = 0x00000400, // allow jumps from high places
+ MF_PICKUP = 0x00000800, // for players to pick up items
+ MF_NOCLIP = 0x00001000, // player cheat
+ MF_INCHASE = 0x00002000, // [RH] used by A_Chase and A_Look to avoid recursion
+ MF_FLOAT = 0x00004000, // allow moves to any height, no gravity
+ MF_TELEPORT = 0x00008000, // don't cross lines or look at heights
+ MF_MISSILE = 0x00010000, // don't hit same species, explode on block
- MF_DROPPED = 0x00020000, // dropped by a demon, not level spawned
- MF_SHADOW = 0x00040000, // actor is hard for monsters to see
- MF_NOBLOOD = 0x00080000, // don't bleed when shot (use puff)
- MF_CORPSE = 0x00100000, // don't stop moving halfway off a step
- MF_INFLOAT = 0x00200000, // floating to a height for a move, don't
- // auto float to target's height
- MF_INBOUNCE = 0x00200000, // used by Heretic bouncing missiles
+ MF_DROPPED = 0x00020000, // dropped by a demon, not level spawned
+ MF_SHADOW = 0x00040000, // actor is hard for monsters to see
+ MF_NOBLOOD = 0x00080000, // don't bleed when shot (use puff)
+ MF_CORPSE = 0x00100000, // don't stop moving halfway off a step
+ MF_INFLOAT = 0x00200000, // floating to a height for a move, don't
+ // auto float to target's height
+ MF_INBOUNCE = 0x00200000, // used by Heretic bouncing missiles
- MF_COUNTKILL = 0x00400000, // count towards intermission kill total
- MF_COUNTITEM = 0x00800000, // count towards intermission item total
+ MF_COUNTKILL = 0x00400000, // count towards intermission kill total
+ MF_COUNTITEM = 0x00800000, // count towards intermission item total
- MF_SKULLFLY = 0x01000000, // skull in flight
- MF_NOTDMATCH = 0x02000000, // don't spawn in death match (key cards)
+ MF_SKULLFLY = 0x01000000, // skull in flight
+ MF_NOTDMATCH = 0x02000000, // don't spawn in death match (key cards)
- MF_FRIENDLY = 0x08000000, // [RH] Friendly monsters for Strife (and MBF)
- MF_UNMORPHED = 0x10000000, // [RH] Actor is the unmorphed version of something else
- MF_NOLIFTDROP = 0x20000000, // [RH] Used with MF_NOGRAVITY to avoid dropping with lifts
- MF_STEALTH = 0x40000000, // [RH] Andy Baker's stealth monsters
- MF_ICECORPSE = 0x80000000, // a frozen corpse (for blasting) [RH] was 0x800000
+ MF_SPAWNSOUNDSOURCE = 0x04000000, // Plays missile's see sound at spawning object.
+ MF_FRIENDLY = 0x08000000, // [RH] Friendly monsters for Strife (and MBF)
+ MF_UNMORPHED = 0x10000000, // [RH] Actor is the unmorphed version of something else
+ MF_NOLIFTDROP = 0x20000000, // [RH] Used with MF_NOGRAVITY to avoid dropping with lifts
+ MF_STEALTH = 0x40000000, // [RH] Andy Baker's stealth monsters
+ MF_ICECORPSE = 0x80000000, // a frozen corpse (for blasting) [RH] was 0x800000
// --- mobj.flags2 ---
diff --git a/src/g_heretic/a_clink.cpp b/src/g_heretic/a_clink.cpp
deleted file mode 100644
index ac68944dd..000000000
--- a/src/g_heretic/a_clink.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "actor.h"
-#include "info.h"
-#include "m_random.h"
-#include "s_sound.h"
-#include "p_local.h"
-#include "p_enemy.h"
-#include "a_action.h"
-#include "gstrings.h"
-
-static FRandom pr_clinkattack ("ClinkAttack");
-
-void A_ClinkAttack (AActor *);
-
-// Clink --------------------------------------------------------------------
-
-class AClink : public AActor
-{
- DECLARE_ACTOR (AClink, AActor)
-public:
- void NoBlockingSet ();
-};
-
-FState AClink::States[] =
-{
-#define S_CLINK_LOOK 0
- S_NORMAL (CLNK, 'A', 10, A_Look , &States[S_CLINK_LOOK+1]),
- S_NORMAL (CLNK, 'B', 10, A_Look , &States[S_CLINK_LOOK+0]),
-
-#define S_CLINK_WALK (S_CLINK_LOOK+2)
- S_NORMAL (CLNK, 'A', 3, A_Chase , &States[S_CLINK_WALK+1]),
- S_NORMAL (CLNK, 'B', 3, A_Chase , &States[S_CLINK_WALK+2]),
- S_NORMAL (CLNK, 'C', 3, A_Chase , &States[S_CLINK_WALK+3]),
- S_NORMAL (CLNK, 'D', 3, A_Chase , &States[S_CLINK_WALK+0]),
-
-#define S_CLINK_ATK (S_CLINK_WALK+4)
- S_NORMAL (CLNK, 'E', 5, A_FaceTarget , &States[S_CLINK_ATK+1]),
- S_NORMAL (CLNK, 'F', 4, A_FaceTarget , &States[S_CLINK_ATK+2]),
- S_NORMAL (CLNK, 'G', 7, A_ClinkAttack , &States[S_CLINK_WALK+0]),
-
-#define S_CLINK_PAIN (S_CLINK_ATK+3)
- S_NORMAL (CLNK, 'H', 3, NULL , &States[S_CLINK_PAIN+1]),
- S_NORMAL (CLNK, 'H', 3, A_Pain , &States[S_CLINK_WALK+0]),
-
-#define S_CLINK_DIE (S_CLINK_PAIN+2)
- S_NORMAL (CLNK, 'I', 6, NULL , &States[S_CLINK_DIE+1]),
- S_NORMAL (CLNK, 'J', 6, NULL , &States[S_CLINK_DIE+2]),
- S_NORMAL (CLNK, 'K', 5, A_Scream , &States[S_CLINK_DIE+3]),
- S_NORMAL (CLNK, 'L', 5, A_NoBlocking , &States[S_CLINK_DIE+4]),
- S_NORMAL (CLNK, 'M', 5, NULL , &States[S_CLINK_DIE+5]),
- S_NORMAL (CLNK, 'N', 5, NULL , &States[S_CLINK_DIE+6]),
- S_NORMAL (CLNK, 'O', -1, NULL , NULL)
-};
-
-IMPLEMENT_ACTOR (AClink, Heretic, 90, 1)
- PROP_SpawnHealth (150)
- PROP_RadiusFixed (20)
- PROP_HeightFixed (64)
- PROP_Mass (75)
- PROP_SpeedFixed (14)
- PROP_PainChance (32)
- PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL|MF_NOBLOOD)
- PROP_Flags2 (MF2_MCROSS|MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_PUSHWALL)
-
- PROP_SpawnState (S_CLINK_LOOK)
- PROP_SeeState (S_CLINK_WALK)
- PROP_PainState (S_CLINK_PAIN)
- PROP_MeleeState (S_CLINK_ATK)
- PROP_DeathState (S_CLINK_DIE)
-
- PROP_SeeSound ("clink/sight")
- PROP_AttackSound ("clink/attack")
- PROP_PainSound ("clink/pain")
- PROP_DeathSound ("clink/death")
- PROP_ActiveSound ("clink/active")
- PROP_Obituary("$OB_CLINK")
-END_DEFAULTS
-
-void AClink::NoBlockingSet ()
-{
- P_DropItem (this, "SkullRodAmmo", 20, 84);
-}
-
-//----------------------------------------------------------------------------
-//
-// PROC A_ClinkAttack
-//
-//----------------------------------------------------------------------------
-
-void A_ClinkAttack (AActor *actor)
-{
- int damage;
-
- if (!actor->target)
- {
- return;
- }
- S_SoundID (actor, CHAN_BODY, actor->AttackSound, 1, ATTN_NORM);
- if (actor->CheckMeleeRange ())
- {
- damage = ((pr_clinkattack()%7)+3);
- P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee);
- P_TraceBleed (damage, actor->target, actor);
- }
-}
diff --git a/src/g_heretic/a_snake.cpp b/src/g_heretic/a_snake.cpp
deleted file mode 100644
index e8d3b043e..000000000
--- a/src/g_heretic/a_snake.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-#include "actor.h"
-#include "info.h"
-#include "m_random.h"
-#include "s_sound.h"
-#include "p_local.h"
-#include "p_enemy.h"
-#include "a_action.h"
-#include "gstrings.h"
-
-void A_SnakeAttack (AActor *);
-void A_SnakeAttack2 (AActor *);
-
-// Snake --------------------------------------------------------------------
-
-class ASnake : public AActor
-{
- DECLARE_ACTOR (ASnake, AActor)
-public:
- void NoBlockingSet ();
-};
-
-FState ASnake::States[] =
-{
-#define S_SNAKE_LOOK 0
- S_NORMAL (SNKE, 'A', 10, A_Look , &States[S_SNAKE_LOOK+1]),
- S_NORMAL (SNKE, 'B', 10, A_Look , &States[S_SNAKE_LOOK+0]),
-
-#define S_SNAKE_WALK (S_SNAKE_LOOK+2)
- S_NORMAL (SNKE, 'A', 4, A_Chase , &States[S_SNAKE_WALK+1]),
- S_NORMAL (SNKE, 'B', 4, A_Chase , &States[S_SNAKE_WALK+2]),
- S_NORMAL (SNKE, 'C', 4, A_Chase , &States[S_SNAKE_WALK+3]),
- S_NORMAL (SNKE, 'D', 4, A_Chase , &States[S_SNAKE_WALK+0]),
-
-#define S_SNAKE_ATK (S_SNAKE_WALK+4)
- S_NORMAL (SNKE, 'F', 5, A_FaceTarget , &States[S_SNAKE_ATK+1]),
- S_NORMAL (SNKE, 'F', 5, A_FaceTarget , &States[S_SNAKE_ATK+2]),
- S_NORMAL (SNKE, 'F', 4, A_SnakeAttack , &States[S_SNAKE_ATK+3]),
- S_NORMAL (SNKE, 'F', 4, A_SnakeAttack , &States[S_SNAKE_ATK+4]),
- S_NORMAL (SNKE, 'F', 4, A_SnakeAttack , &States[S_SNAKE_ATK+5]),
- S_NORMAL (SNKE, 'F', 5, A_FaceTarget , &States[S_SNAKE_ATK+6]),
- S_NORMAL (SNKE, 'F', 5, A_FaceTarget , &States[S_SNAKE_ATK+7]),
- S_NORMAL (SNKE, 'F', 5, A_FaceTarget , &States[S_SNAKE_ATK+8]),
- S_NORMAL (SNKE, 'F', 4, A_SnakeAttack2 , &States[S_SNAKE_WALK+0]),
-
-#define S_SNAKE_PAIN (S_SNAKE_ATK+9)
- S_NORMAL (SNKE, 'E', 3, NULL , &States[S_SNAKE_PAIN+1]),
- S_NORMAL (SNKE, 'E', 3, A_Pain , &States[S_SNAKE_WALK+0]),
-
-#define S_SNAKE_DIE (S_SNAKE_PAIN+2)
- S_NORMAL (SNKE, 'G', 5, NULL , &States[S_SNAKE_DIE+1]),
- S_NORMAL (SNKE, 'H', 5, A_Scream , &States[S_SNAKE_DIE+2]),
- S_NORMAL (SNKE, 'I', 5, NULL , &States[S_SNAKE_DIE+3]),
- S_NORMAL (SNKE, 'J', 5, NULL , &States[S_SNAKE_DIE+4]),
- S_NORMAL (SNKE, 'K', 5, NULL , &States[S_SNAKE_DIE+5]),
- S_NORMAL (SNKE, 'L', 5, NULL , &States[S_SNAKE_DIE+6]),
- S_NORMAL (SNKE, 'M', 5, A_NoBlocking , &States[S_SNAKE_DIE+7]),
- S_NORMAL (SNKE, 'N', 5, NULL , &States[S_SNAKE_DIE+8]),
- S_NORMAL (SNKE, 'O', 5, NULL , &States[S_SNAKE_DIE+9]),
- S_NORMAL (SNKE, 'P', -1, NULL , NULL)
-};
-
-IMPLEMENT_ACTOR (ASnake, Heretic, 92, 132)
- PROP_SpawnHealth (280)
- PROP_RadiusFixed (22)
- PROP_HeightFixed (70)
- PROP_SpeedFixed (10)
- PROP_PainChance (48)
- PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL)
- PROP_Flags2 (MF2_MCROSS|MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_PUSHWALL)
-
- PROP_SpawnState (S_SNAKE_LOOK)
- PROP_SeeState (S_SNAKE_WALK)
- PROP_PainState (S_SNAKE_PAIN)
- PROP_MissileState (S_SNAKE_ATK)
- PROP_DeathState (S_SNAKE_DIE)
-
- PROP_AttackSound ("snake/attack")
- PROP_SeeSound ("snake/sight")
- PROP_PainSound ("snake/pain")
- PROP_DeathSound ("snake/death")
- PROP_ActiveSound ("snake/active")
- PROP_Obituary("$OB_SNAKE")
-END_DEFAULTS
-
-// Snake projectile A -------------------------------------------------------
-
-class ASnakeProjA : public AActor
-{
- DECLARE_ACTOR (ASnakeProjA, AActor)
-};
-
-FState ASnakeProjA::States[] =
-{
-#define S_SNAKEPRO_A 0
- S_BRIGHT (SNFX, 'A', 5, NULL , &States[S_SNAKEPRO_A+1]),
- S_BRIGHT (SNFX, 'B', 5, NULL , &States[S_SNAKEPRO_A+2]),
- S_BRIGHT (SNFX, 'C', 5, NULL , &States[S_SNAKEPRO_A+3]),
- S_BRIGHT (SNFX, 'D', 5, NULL , &States[S_SNAKEPRO_A+0]),
-
-#define S_SNAKEPRO_AX (S_SNAKEPRO_A+4)
- S_BRIGHT (SNFX, 'E', 5, NULL , &States[S_SNAKEPRO_AX+1]),
- S_BRIGHT (SNFX, 'F', 5, NULL , &States[S_SNAKEPRO_AX+2]),
- S_BRIGHT (SNFX, 'G', 4, NULL , &States[S_SNAKEPRO_AX+3]),
- S_BRIGHT (SNFX, 'H', 3, NULL , &States[S_SNAKEPRO_AX+4]),
- S_BRIGHT (SNFX, 'I', 3, NULL , NULL)
-};
-
-IMPLEMENT_ACTOR (ASnakeProjA, Heretic, -1, 138)
- PROP_RadiusFixed (12)
- PROP_HeightFixed (8)
- PROP_SpeedFixed (14)
- PROP_Damage (1)
- PROP_Flags (MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
- PROP_Flags2 (MF2_WINDTHRUST|MF2_NOTELEPORT)
- PROP_RenderStyle (STYLE_Add)
-
- PROP_SpawnState (S_SNAKEPRO_A)
- PROP_DeathState (S_SNAKEPRO_AX)
-END_DEFAULTS
-
-AT_SPEED_SET (SnakeProjA, speed)
-{
- SimpleSpeedSetter (ASnakeProjA, 14*FRACUNIT, 20*FRACUNIT, speed);
-}
-
-void ASnake::NoBlockingSet ()
-{
- P_DropItem (this, "PhoenixRodAmmo", 5, 84);
-}
-
-// Snake projectile B -------------------------------------------------------
-
-class ASnakeProjB : public ASnakeProjA
-{
- DECLARE_ACTOR (ASnakeProjB, ASnakeProjA)
-};
-
-FState ASnakeProjB::States[] =
-{
-#define S_SNAKEPRO_B 0
- S_BRIGHT (SNFX, 'J', 6, NULL , &States[S_SNAKEPRO_B+1]),
- S_BRIGHT (SNFX, 'K', 6, NULL , &States[S_SNAKEPRO_B+0]),
-
-#define S_SNAKEPRO_BX (S_SNAKEPRO_B+2)
- S_BRIGHT (SNFX, 'L', 5, NULL , &States[S_SNAKEPRO_BX+1]),
- S_BRIGHT (SNFX, 'M', 5, NULL , &States[S_SNAKEPRO_BX+2]),
- S_BRIGHT (SNFX, 'N', 4, NULL , &States[S_SNAKEPRO_BX+3]),
- S_BRIGHT (SNFX, 'O', 3, NULL , NULL)
-};
-
-IMPLEMENT_ACTOR (ASnakeProjB, Heretic, -1, 139)
- PROP_RadiusFixed (12)
- PROP_HeightFixed (8)
- PROP_Damage (3)
- PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
- PROP_Flags2 (MF2_NOTELEPORT)
-
- PROP_SpawnState (S_SNAKEPRO_B)
- PROP_DeathState (S_SNAKEPRO_BX)
-END_DEFAULTS
-
-AT_SPEED_SET (SnakeProjB, speed)
-{
- SimpleSpeedSetter (ASnakeProjB, 14*FRACUNIT, 20*FRACUNIT, speed);
-}
-
-//----------------------------------------------------------------------------
-//
-// PROC A_SnakeAttack
-//
-//----------------------------------------------------------------------------
-
-void A_SnakeAttack (AActor *actor)
-{
- if (!actor->target)
- {
- actor->SetState (actor->SeeState);
- return;
- }
- S_SoundID (actor, CHAN_BODY, actor->AttackSound, 1, ATTN_NORM);
- A_FaceTarget (actor);
- P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ASnakeProjA));
-}
-
-//----------------------------------------------------------------------------
-//
-// PROC A_SnakeAttack2
-//
-//----------------------------------------------------------------------------
-
-void A_SnakeAttack2 (AActor *actor)
-{
- if (!actor->target)
- {
- actor->SetState (actor->SeeState);
- return;
- }
- S_SoundID (actor, CHAN_BODY, actor->AttackSound, 1, ATTN_NORM);
- A_FaceTarget (actor);
- P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ASnakeProjB));
-}
diff --git a/src/g_raven/a_ravenambient.cpp b/src/g_raven/a_ravenambient.cpp
deleted file mode 100644
index dcb1f92c3..000000000
--- a/src/g_raven/a_ravenambient.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "actor.h"
-#include "info.h"
-#include "s_sound.h"
-#include "gi.h"
-
-void A_WindSound (AActor *);
-void A_WaterfallSound (AActor *);
-
-// Wind ---------------------------------------------------------------------
-
-class ASoundWind : public AActor
-{
- DECLARE_ACTOR (ASoundWind, AActor)
-};
-
-FState ASoundWind::States[] =
-{
- S_NORMAL (TNT1, 'A', 2, A_WindSound, &States[0])
-};
-
-IMPLEMENT_ACTOR (ASoundWind, Raven, -1, 110)
- PROP_SpawnState (0)
- PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR)
-END_DEFAULTS
-
-AT_GAME_SET (SoundWind)
-{
- if (gameinfo.gametype == GAME_Heretic)
- {
- DOOMEDNUMOF(ASoundWind) = 42;
- }
- else if (gameinfo.gametype == GAME_Hexen)
- {
- DOOMEDNUMOF(ASoundWind) = 1410;
- }
-}
-
-// Waterfall ----------------------------------------------------------------
-
-class ASoundWaterfall : public AActor
-{
- DECLARE_ACTOR (ASoundWaterfall, AActor)
-};
-
-FState ASoundWaterfall::States[] =
-{
- S_NORMAL (TNT1, 'A', 2, A_WaterfallSound, &States[0])
-};
-
-// Interestingly, MT_SOUNDWATERFALL is present in both Heretic and Hexen
-// with doomednum 41. However, in Hexen, ZShroomLarge3 also has ednum 41
-// and comes before the waterfall, so it will never be possible to place
-// it in a map.
-
-IMPLEMENT_ACTOR (ASoundWaterfall, Heretic, 41, 111)
- PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR)
- PROP_SpawnState (0)
-END_DEFAULTS
-
-//----------------------------------------------------------------------------
-//
-// PROC A_WindSound
-//
-//----------------------------------------------------------------------------
-
-void A_WindSound (AActor *self)
-{
- if (!S_IsActorPlayingSomething (self, 6, -1))
- {
- S_LoopedSound (self, 6, "world/wind", 1, ATTN_NORM);
- }
-}
-
-//----------------------------------------------------------------------------
-//
-// PROC A_WaterfallSound
-//
-//----------------------------------------------------------------------------
-
-void A_WaterfallSound (AActor *self)
-{
- if (!S_IsActorPlayingSomething (self, 6, -1))
- {
- S_LoopedSound (self, 6, "world/waterfall", 1, ATTN_NORM);
- }
-}
diff --git a/src/g_raven/ravenshared.h b/src/g_raven/ravenshared.h
index 1352676c8..0f2e03094 100644
--- a/src/g_raven/ravenshared.h
+++ b/src/g_raven/ravenshared.h
@@ -2,13 +2,6 @@
#define __RAVENSHARED_H__
class AActor;
-class player_s;
-
-bool P_MorphPlayer (player_s *player);
-bool P_UndoPlayerMorph (player_s *player, bool force);
-
-bool P_MorphMonster (AActor *actor, const PClass *morphClass);
-bool P_UpdateMorphedMonster (AActor *actor);
class AMinotaur : public AActor
{
diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h
index 30190dda1..15d410b8e 100644
--- a/src/g_shared/a_sharedglobal.h
+++ b/src/g_shared/a_sharedglobal.h
@@ -11,6 +11,13 @@ struct side_s;
extern void P_SpawnDirt (AActor *actor, fixed_t radius);
+bool P_MorphPlayer (player_s *player);
+bool P_UndoPlayerMorph (player_s *player, bool force);
+
+bool P_MorphMonster (AActor *actor, const PClass *morphClass);
+bool P_UpdateMorphedMonster (AActor *actor);
+
+
class AUnknown : public AActor
{
DECLARE_ACTOR (AUnknown, AActor)
diff --git a/src/p_local.h b/src/p_local.h
index 5e254c3a3..3b73775b5 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -309,6 +309,7 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1 = 0, int c
bool P_HitFloor (AActor *thing);
bool P_HitWater (AActor *thing, sector_t *sec);
bool P_CheckMissileSpawn (AActor *missile);
+void P_PlaySpawnSound(AActor *missile, AActor *spawner);
// [RH] Position the chasecam
void P_AimCamera (AActor *t1);
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index e754d79ee..8e5455fe2 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -4251,6 +4251,37 @@ bool P_CheckMissileSpawn (AActor* th)
}
+//---------------------------------------------------------------------------
+//
+// FUNC P_PlaySpawnSound
+//
+// Plays a missiles spawn sound. Location depends on the
+// MF_SPAWNSOUNDSOURCE flag.
+//
+//---------------------------------------------------------------------------
+
+void P_PlaySpawnSound(AActor *missile, AActor *spawner)
+{
+ if (missile->SeeSound != 0)
+ {
+ if (!(missile->flags & MF_SPAWNSOUNDSOURCE))
+ {
+ S_SoundID (missile, CHAN_VOICE, missile->SeeSound, 1, ATTN_NORM);
+ }
+ else if (spawner != NULL)
+ {
+ S_SoundID (spawner, CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM);
+ }
+ else
+ {
+ // If there is no spawner use the spawn position.
+ // But not in a silenced sector.
+ if (!(missile->Sector->MoreFlags & SECF_SILENT))
+ S_SoundID (&missile->x, CHAN_WEAPON, missile->SeeSound, 1, ATTN_NORM);
+ }
+ }
+}
+
//---------------------------------------------------------------------------
//
// FUNC P_SpawnMissile
@@ -4297,9 +4328,7 @@ AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z,
AActor *th = Spawn (type, x, y, z, ALLOW_REPLACE);
- if (th->SeeSound)
- S_SoundID (th, CHAN_VOICE, th->SeeSound, 1, ATTN_NORM);
-
+ P_PlaySpawnSound(th, source);
th->target = source; // record missile's originator
vec3_t velocity;
@@ -4424,10 +4453,7 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z,
z -= source->floorclip;
}
mo = Spawn (type, source->x, source->y, z, ALLOW_REPLACE);
- if (mo->SeeSound)
- {
- S_SoundID (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM);
- }
+ P_PlaySpawnSound(mo, source);
mo->target = owner != NULL ? owner : source; // Originator
mo->angle = angle;
angle >>= ANGLETOFINESHIFT;
@@ -4499,11 +4525,7 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z,
z += 4*8*FRACUNIT - source->floorclip + (source->player? source->player->crouchoffset : 0);
}
MissileActor = Spawn (type, x, y, z, ALLOW_REPLACE);
-
- if (MissileActor->SeeSound)
- {
- S_SoundID (MissileActor, CHAN_VOICE, MissileActor->SeeSound, 1, ATTN_NORM);
- }
+ P_PlaySpawnSound(MissileActor, source);
MissileActor->target = source;
MissileActor->angle = an;
diff --git a/src/p_things.cpp b/src/p_things.cpp
index 0a89c9620..dacc24f4e 100644
--- a/src/p_things.cpp
+++ b/src/p_things.cpp
@@ -238,10 +238,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_na
{
mobj->tid = newtid;
mobj->AddToHash ();
- if (mobj->SeeSound)
- {
- S_SoundID (mobj, CHAN_VOICE, mobj->SeeSound, 1, ATTN_NORM);
- }
+ P_PlaySpawnSound(mobj, spot);
if (gravity)
{
mobj->flags &= ~MF_NOGRAVITY;
diff --git a/src/thingdef.cpp b/src/thingdef.cpp
index 857965679..d162e3bcf 100644
--- a/src/thingdef.cpp
+++ b/src/thingdef.cpp
@@ -124,6 +124,7 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(MF, COUNTITEM, AActor, flags),
DEFINE_FLAG(MF, SKULLFLY, AActor, flags),
DEFINE_FLAG(MF, NOTDMATCH, AActor, flags),
+ DEFINE_FLAG(MF, SPAWNSOUNDSOURCE, AActor, flags),
DEFINE_FLAG(MF, FRIENDLY, AActor, flags),
DEFINE_FLAG(MF, NOLIFTDROP, AActor, flags),
DEFINE_FLAG(MF, STEALTH, AActor, flags),
@@ -726,7 +727,7 @@ AFuncDesc AFTable[]=
FUNC(A_GiveToTarget, "Mx" )
FUNC(A_TakeFromTarget, "Mx" )
FUNC(A_CountdownArg, "X")
- FUNC(A_CustomMeleeAttack, "Xsty" )
+ FUNC(A_CustomMeleeAttack, "Xssty" )
FUNC(A_Burst, "M")
FUNC(A_RadiusThrust, "xxy")
{"A_Explode", A_ExplodeParms, "xxy" },
diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp
index 3c40dcd94..72280c567 100644
--- a/src/thingdef_codeptr.cpp
+++ b/src/thingdef_codeptr.cpp
@@ -645,6 +645,13 @@ inline static bool isMissile(AActor * self, bool precise=true)
// The ultimate code pointer: Fully customizable missiles!
//
//==========================================================================
+enum CM_Flags
+{
+ CMF_AIMMODE = 3,
+ CMF_TRACKOWNER = 4,
+ CMF_CHECKTARGETDEAD = 8,
+};
+
void A_CustomMissile(AActor * self)
{
int index=CheckIndex(6);
@@ -654,8 +661,9 @@ void A_CustomMissile(AActor * self)
fixed_t SpawnHeight=fixed_t(EvalExpressionF (StateParameters[index+1], self) * FRACUNIT);
int Spawnofs_XY=EvalExpressionI (StateParameters[index+2], self);
angle_t Angle=angle_t(EvalExpressionF (StateParameters[index+3], self) * ANGLE_1);
- int aimmode=EvalExpressionI (StateParameters[index+4], self);
+ int flags=EvalExpressionI (StateParameters[index+4], self);
angle_t pitch=angle_t(EvalExpressionF (StateParameters[index+5], self) * ANGLE_1);
+ int aimmode = flags & CMF_AIMMODE;
AActor * targ;
AActor * missile;
@@ -670,7 +678,7 @@ void A_CustomMissile(AActor * self)
fixed_t y = Spawnofs_XY * finesine[ang];
fixed_t z = SpawnHeight - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0);
- switch (aimmode&3)
+ switch (aimmode)
{
case 0:
default:
@@ -724,10 +732,10 @@ void A_CustomMissile(AActor * self)
// handle projectile shooting projectiles - track the
// links back to a real owner
- if (isMissile(self, !!(aimmode&4)))
+ if (isMissile(self, !!(flags & CMF_TRACKOWNER)))
{
AActor * owner=self ;//->target;
- while (isMissile(owner, !!(aimmode&4)) && owner->target) owner=owner->target;
+ while (isMissile(owner, !!(flags & CMF_TRACKOWNER)) && owner->target) owner=owner->target;
targ=owner;
missile->target=owner;
// automatic handling of seeker missiles
@@ -749,6 +757,11 @@ void A_CustomMissile(AActor * self)
}
}
}
+ else if (flags & CMF_CHECKTARGETDEAD)
+ {
+ // Target is dead and the attack shall be aborted.
+ if (self->SeeState != NULL) self->SetState(self->SeeState);
+ }
}
//==========================================================================
@@ -804,13 +817,14 @@ void A_CustomBulletAttack (AActor *self)
//==========================================================================
void A_CustomMeleeAttack (AActor *self)
{
- int index=CheckIndex(4);
+ int index=CheckIndex(5);
if (index<0) return;
int damage = EvalExpressionI (StateParameters[index], self);
- int MeleeSound=StateParameters[index+1];
- ENamedName DamageType = (ENamedName)StateParameters[index+2];
- bool bleed = EvalExpressionN (StateParameters[index+3], self);
+ int MeleeSound = StateParameters[index+1];
+ int MissSound = StateParameters[index+2];
+ ENamedName DamageType = (ENamedName)StateParameters[index+3];
+ bool bleed = EvalExpressionN (StateParameters[index+4], self);
if (DamageType==NAME_None) DamageType = NAME_Melee; // Melee is the default type
@@ -824,6 +838,10 @@ void A_CustomMeleeAttack (AActor *self)
P_DamageMobj (self->target, self, self, damage, DamageType);
if (bleed) P_TraceBleed (damage, self->target, self);
}
+ else
+ {
+ if (MissSound) S_SoundID (self, CHAN_WEAPON, MissSound, 1, ATTN_NORM);
+ }
}
//==========================================================================
@@ -1353,6 +1371,7 @@ void A_ThrowGrenade(AActor * self)
{
int pitch = self->pitch;
+ P_PlaySpawnSound(bo, self);
if (xymom) bo->Speed=xymom;
bo->angle = self->angle+(((pr_grenade()&7)-4)<<24);
bo->momz = zmom + 2*finesine[pitch>>ANGLETOFINESHIFT];
diff --git a/wadsrc/decorate/decorate.txt b/wadsrc/decorate/decorate.txt
index 206a41e96..27d763de7 100644
--- a/wadsrc/decorate/decorate.txt
+++ b/wadsrc/decorate/decorate.txt
@@ -32,6 +32,7 @@
#include "actors/raven/artiegg.txt"
#include "actors/raven/ravenartifacts.txt"
#include "actors/raven/ravenhealth.txt"
+#include "actors/raven/ravenambient.txt"
#include "actors/heretic/hereticplayer.txt"
#include "actors/heretic/hereticammo.txt"
@@ -39,6 +40,8 @@
#include "actors/heretic/hereticartifacts.txt"
#include "actors/heretic/heretickeys.txt"
#include "actors/heretic/hereticdecorations.txt"
+#include "actors/heretic/clink.txt"
+#include "actors/heretic/snake.txt"
#include "actors/hexen/fighterplayer.txt"
#include "actors/hexen/clericplayer.txt"
diff --git a/wadsrc/decorate/heretic/clink.txt b/wadsrc/decorate/heretic/clink.txt
new file mode 100644
index 000000000..087ca919e
--- /dev/null
+++ b/wadsrc/decorate/heretic/clink.txt
@@ -0,0 +1,48 @@
+
+ACTOR Clink 90
+{
+ Game Heretic
+ SpawnID 1
+ Health 150
+ Radius 20
+ Height 64
+ Mass 75
+ Speed 14
+ Painchance 32
+ Monster
+ +NOBLOOD
+ +FLOORCLIP
+ SeeSound "clink/sight"
+ AttackSound "clink/attack"
+ PainSound "clink/pain"
+ DeathSound "clink/death"
+ ActiveSound "clink/active"
+ Obituary "$OB_CLINK"
+ DropItem "SkullRodAmmo", 84, 20
+ States
+ {
+ Spawn:
+ CLNK AB 10 A_Look
+ Loop
+ See:
+ CLNK ABCD 3 A_Chase
+ Loop
+ Melee:
+ CLNK E 5 A_FaceTarget
+ CLNK F 4 A_FaceTarget
+ CLNK G 7 A_CustomMeleeAttack(random(3,9), "clink/attack", "clink/attack")
+ Goto See
+ Pain:
+ CLNK H 3
+ CLNK H 3 A_Pain
+ Goto See
+ Death:
+ CLNK IJ 6
+ CLNK K 5 A_Scream
+ CLNK L 5 A_NoBlocking
+ CLNK MN 5
+ CLNK O -1
+ Stop
+ }
+}
+
diff --git a/wadsrc/decorate/heretic/snake.txt b/wadsrc/decorate/heretic/snake.txt
new file mode 100644
index 000000000..0fb995096
--- /dev/null
+++ b/wadsrc/decorate/heretic/snake.txt
@@ -0,0 +1,101 @@
+
+ACTOR Snake 92
+{
+ Game Heretic
+ SpawnID 132
+ Health 280
+ Radius 22
+ Height 70
+ Speed 10
+ Painchance 48
+ Monster
+ +FLOORCLIP
+ AttackSound "snake/attack"
+ SeeSound "snake/sight"
+ PainSound "snake/pain"
+ DeathSound "snake/death"
+ ActiveSound "snake/active"
+ Obituary "$OB_SNAKE"
+ DropItem "PhoenixRodAmmo", 84, 5
+ States
+ {
+ Spawn:
+ SNKE AB 10 A_Look
+ Loop
+ See:
+ SNKE ABCD 4 A_Chase
+ Loop
+ Missile:
+ SNKE FF 5 A_FaceTarget
+ SNKE FFF 4 A_CustomMissile("SnakeProjA", 32, 0, 0, 8)
+ SNKE FFF 5 A_FaceTarget
+ SNKE F 4 A_CustomMissile("SnakeProjB", 32, 0, 0, 8)
+ Goto See
+ Pain:
+ SNKE E 3
+ SNKE E 3 A_Pain
+ Goto See
+ Death:
+ SNKE G 5
+ SNKE H 5 A_Scream
+ SNKE IJKL 5
+ SNKE M 5 A_NoBlocking
+ SNKE NO 5
+ SNKE P -1
+ Stop
+ }
+}
+
+// Snake projectile A -------------------------------------------------------
+
+ACTOR SnakeProjA
+{
+ Game Heretic
+ SpawnID 138
+ Radius 12
+ Height 8
+ Speed 14
+ FastSpeed 20
+ Damage 1
+ Projectile
+ -NOBLOCKMAP
+ -ACTIVATEIMPACT
+ -ACTIVATEPCROSS
+ +WINDTHRUST
+ +SPAWNSOUNDSOURCE
+ RenderStyle Add
+ SeeSound "snake/attack"
+ States
+ {
+ Spawn:
+ SNFX ABCD 5 Bright
+ Loop
+ Death:
+ SNFX EF 5 Bright
+ SNFX G 4 Bright
+ SNFX HI 3 Bright
+ Stop
+ }
+}
+
+// Snake projectile B -------------------------------------------------------
+
+ACTOR SnakeProjB : SnakeProjA
+{
+ Game Heretic
+ SpawnID 139
+ Damage 3
+ +NOBLOCKMAP
+ -WINDTHRUST
+ States
+ {
+ Spawn:
+ SNFX JK 6 Bright
+ Loop
+ Death:
+ SNFX LM 5 Bright
+ SNFX N 4 Bright
+ SNFX O 3 Bright
+ Stop
+ }
+}
diff --git a/wadsrc/decorate/raven/ravenambient.txt b/wadsrc/decorate/raven/ravenambient.txt
new file mode 100644
index 000000000..8489803e5
--- /dev/null
+++ b/wadsrc/decorate/raven/ravenambient.txt
@@ -0,0 +1,42 @@
+
+
+// Wind ---------------------------------------------------------------------
+
+ACTOR SoundWind 42
+{
+ Game Heretic
+ SpawnID 110
+ +NOBLOCKMAP
+ +NOSECTOR
+ +DONTSPLASH
+ States
+ {
+ Spawn:
+ TNT1 A 2 A_PlaySoundEx("world/wind", "SoundSlot6", 1)
+ Loop
+ }
+}
+
+ACTOR SoundWindHexen : SoundWind 1410
+{
+ Game Hexen
+ SpawnID 110
+}
+
+
+// Waterfall ----------------------------------------------------------------
+
+ACTOR SoundWaterfall 41
+{
+ Game Heretic
+ SpawnID 111
+ +NOBLOCKMAP
+ +NOSECTOR
+ +DONTSPLASH
+ States
+ {
+ Spawn:
+ TNT1 A 2 A_PlaySoundEx("world/waterfall", "SoundSlot6", 1)
+ Loop
+ }
+}
diff --git a/wadsrc/zdoom.lst b/wadsrc/zdoom.lst
index 2c5e44326..e8b80f010 100644
--- a/wadsrc/zdoom.lst
+++ b/wadsrc/zdoom.lst
@@ -275,6 +275,7 @@ actors/doom/stealthmonsters.txt decorate/doom/stealthmonsters.txt
actors/raven/artiegg.txt decorate/raven/artiegg.txt
actors/raven/ravenartifacts.txt decorate/raven/ravenartifacts.txt
actors/raven/ravenhealth.txt decorate/raven/ravenhealth.txt
+actors/raven/ravenambient.txt decorate/raven/ravenambient.txt
actors/heretic/hereticplayer.txt decorate/heretic/hereticplayer.txt
actors/heretic/hereticammo.txt decorate/heretic/hereticammo.txt
@@ -282,6 +283,8 @@ actors/heretic/hereticarmor.txt decorate/heretic/hereticarmor.txt
actors/heretic/hereticartifacts.txt decorate/heretic/hereticartifacts.txt
actors/heretic/heretickeys.txt decorate/heretic/heretickeys.txt
actors/heretic/hereticdecorations.txt decorate/heretic/hereticdecorations.txt
+actors/heretic/clink.txt decorate/heretic/clink.txt
+actors/heretic/snake.txt decorate/heretic/snake.txt
actors/hexen/fighterplayer.txt decorate/hexen/fighterplayer.txt
actors/hexen/clericplayer.txt decorate/hexen/clericplayer.txt
diff --git a/zdoom.vcproj b/zdoom.vcproj
index bac3a5d48..714ff9f4e 100644
--- a/zdoom.vcproj
+++ b/zdoom.vcproj
@@ -1,7 +1,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -2726,6 +2718,14 @@
GeneratePreprocessedFile="0"
/>
+
+
+
@@ -2748,7 +2748,7 @@
/>
-
-
-
@@ -4807,6 +4797,16 @@
Outputs="$(IntDir)/$(InputName).obj"
/>
+
+
+
@@ -4831,16 +4831,6 @@
Outputs="$(IntDir)/$(InputName).obj"
/>
-
-
-
@@ -4851,6 +4841,16 @@
Outputs="$(IntDir)/$(InputName).obj"
/>
+
+
+
@@ -4875,16 +4875,6 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
-
-
-
@@ -4895,6 +4885,16 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
@@ -4919,16 +4919,6 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
-
-
-
@@ -4939,6 +4929,16 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
@@ -4963,16 +4963,6 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
-
-
-
@@ -4983,6 +4973,16 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
@@ -5062,7 +5062,7 @@
/>
-
-
-
@@ -5405,6 +5397,14 @@
Outputs="$(IntDir)\$(InputName).obj"
/>
+
+
+
+
+
+
@@ -5627,14 +5635,6 @@
GeneratePreprocessedFile="0"
/>
-
-
-
@@ -5656,7 +5656,7 @@
/>
-
-
-
@@ -6995,26 +6987,6 @@
AdditionalOptions="" /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" "
/>
-
-
-
-
-
-
-
-
@@ -7023,14 +6995,6 @@
AdditionalOptions="" /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" "
/>
-
-
-
@@ -7060,7 +7024,7 @@
/>
-
-
-
@@ -7111,26 +7067,6 @@
AdditionalOptions="" /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" "
/>
-
-
-
-
-
-
-
-
@@ -7139,14 +7075,6 @@
AdditionalOptions="" /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" "
/>
-
-
-
@@ -7168,7 +7096,7 @@
/>
-
-
-
@@ -7475,26 +7395,6 @@
AdditionalOptions="" /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" "
/>
-
-
-
-
-
-
-
-
@@ -7503,14 +7403,6 @@
AdditionalOptions="" /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" " /I /fmod/api/inc" "
/>
-
-
-
@@ -7532,7 +7424,7 @@
/>
-
-
-
@@ -9509,6 +9393,14 @@
AdditionalIncludeDirectories="src\win32;$(NoInherit)"
/>
+
+
+
@@ -9683,7 +9575,7 @@
/>