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



SVN r388 (trunk)
This commit is contained in:
Christoph Oelckers 2006-11-25 12:25:05 +00:00
parent 824fa1a557
commit 49422188f2
18 changed files with 943 additions and 1193 deletions

View File

@ -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 November 24, 2006
- Fixed: The backpack didn't give extra ammo in baby and nightmare modes. - Fixed: The backpack didn't give extra ammo in baby and nightmare modes.
- Fixed: When P_SpawnPlayer() calls DObject::PointerSubstitution() to - Fixed: When P_SpawnPlayer() calls DObject::PointerSubstitution() to

View File

@ -109,47 +109,48 @@ enum
{ {
// --- mobj.flags --- // --- mobj.flags ---
MF_SPECIAL = 0x00000001, // call P_SpecialThing when touched MF_SPECIAL = 0x00000001, // call P_SpecialThing when touched
MF_SOLID = 0x00000002, MF_SOLID = 0x00000002,
MF_SHOOTABLE = 0x00000004, MF_SHOOTABLE = 0x00000004,
MF_NOSECTOR = 0x00000008, // don't use the sector links MF_NOSECTOR = 0x00000008, // don't use the sector links
// (invisible but touchable) // (invisible but touchable)
MF_NOBLOCKMAP = 0x00000010, // don't use the blocklinks MF_NOBLOCKMAP = 0x00000010, // don't use the blocklinks
// (inert but displayable) // (inert but displayable)
MF_AMBUSH = 0x00000020, // not activated by sound; deaf monster MF_AMBUSH = 0x00000020, // not activated by sound; deaf monster
MF_JUSTHIT = 0x00000040, // try to attack right back MF_JUSTHIT = 0x00000040, // try to attack right back
MF_JUSTATTACKED = 0x00000080, // take at least one step before attacking MF_JUSTATTACKED = 0x00000080, // take at least one step before attacking
MF_SPAWNCEILING = 0x00000100, // hang from ceiling instead of floor MF_SPAWNCEILING = 0x00000100, // hang from ceiling instead of floor
MF_NOGRAVITY = 0x00000200, // don't apply gravity every tic MF_NOGRAVITY = 0x00000200, // don't apply gravity every tic
// movement flags // movement flags
MF_DROPOFF = 0x00000400, // allow jumps from high places MF_DROPOFF = 0x00000400, // allow jumps from high places
MF_PICKUP = 0x00000800, // for players to pick up items MF_PICKUP = 0x00000800, // for players to pick up items
MF_NOCLIP = 0x00001000, // player cheat MF_NOCLIP = 0x00001000, // player cheat
MF_INCHASE = 0x00002000, // [RH] used by A_Chase and A_Look to avoid recursion 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_FLOAT = 0x00004000, // allow moves to any height, no gravity
MF_TELEPORT = 0x00008000, // don't cross lines or look at heights MF_TELEPORT = 0x00008000, // don't cross lines or look at heights
MF_MISSILE = 0x00010000, // don't hit same species, explode on block MF_MISSILE = 0x00010000, // don't hit same species, explode on block
MF_DROPPED = 0x00020000, // dropped by a demon, not level spawned MF_DROPPED = 0x00020000, // dropped by a demon, not level spawned
MF_SHADOW = 0x00040000, // actor is hard for monsters to see MF_SHADOW = 0x00040000, // actor is hard for monsters to see
MF_NOBLOOD = 0x00080000, // don't bleed when shot (use puff) MF_NOBLOOD = 0x00080000, // don't bleed when shot (use puff)
MF_CORPSE = 0x00100000, // don't stop moving halfway off a step MF_CORPSE = 0x00100000, // don't stop moving halfway off a step
MF_INFLOAT = 0x00200000, // floating to a height for a move, don't MF_INFLOAT = 0x00200000, // floating to a height for a move, don't
// auto float to target's height // auto float to target's height
MF_INBOUNCE = 0x00200000, // used by Heretic bouncing missiles MF_INBOUNCE = 0x00200000, // used by Heretic bouncing missiles
MF_COUNTKILL = 0x00400000, // count towards intermission kill total MF_COUNTKILL = 0x00400000, // count towards intermission kill total
MF_COUNTITEM = 0x00800000, // count towards intermission item total MF_COUNTITEM = 0x00800000, // count towards intermission item total
MF_SKULLFLY = 0x01000000, // skull in flight MF_SKULLFLY = 0x01000000, // skull in flight
MF_NOTDMATCH = 0x02000000, // don't spawn in death match (key cards) MF_NOTDMATCH = 0x02000000, // don't spawn in death match (key cards)
MF_FRIENDLY = 0x08000000, // [RH] Friendly monsters for Strife (and MBF) MF_SPAWNSOUNDSOURCE = 0x04000000, // Plays missile's see sound at spawning object.
MF_UNMORPHED = 0x10000000, // [RH] Actor is the unmorphed version of something else MF_FRIENDLY = 0x08000000, // [RH] Friendly monsters for Strife (and MBF)
MF_NOLIFTDROP = 0x20000000, // [RH] Used with MF_NOGRAVITY to avoid dropping with lifts MF_UNMORPHED = 0x10000000, // [RH] Actor is the unmorphed version of something else
MF_STEALTH = 0x40000000, // [RH] Andy Baker's stealth monsters MF_NOLIFTDROP = 0x20000000, // [RH] Used with MF_NOGRAVITY to avoid dropping with lifts
MF_ICECORPSE = 0x80000000, // a frozen corpse (for blasting) [RH] was 0x800000 MF_STEALTH = 0x40000000, // [RH] Andy Baker's stealth monsters
MF_ICECORPSE = 0x80000000, // a frozen corpse (for blasting) [RH] was 0x800000
// --- mobj.flags2 --- // --- mobj.flags2 ---

View File

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

View File

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

View File

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

View File

@ -2,13 +2,6 @@
#define __RAVENSHARED_H__ #define __RAVENSHARED_H__
class AActor; 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 class AMinotaur : public AActor
{ {

View File

@ -11,6 +11,13 @@ struct side_s;
extern void P_SpawnDirt (AActor *actor, fixed_t radius); 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 class AUnknown : public AActor
{ {
DECLARE_ACTOR (AUnknown, AActor) DECLARE_ACTOR (AUnknown, AActor)

View File

@ -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_HitFloor (AActor *thing);
bool P_HitWater (AActor *thing, sector_t *sec); bool P_HitWater (AActor *thing, sector_t *sec);
bool P_CheckMissileSpawn (AActor *missile); bool P_CheckMissileSpawn (AActor *missile);
void P_PlaySpawnSound(AActor *missile, AActor *spawner);
// [RH] Position the chasecam // [RH] Position the chasecam
void P_AimCamera (AActor *t1); void P_AimCamera (AActor *t1);

View File

@ -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 // 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); AActor *th = Spawn (type, x, y, z, ALLOW_REPLACE);
if (th->SeeSound) P_PlaySpawnSound(th, source);
S_SoundID (th, CHAN_VOICE, th->SeeSound, 1, ATTN_NORM);
th->target = source; // record missile's originator th->target = source; // record missile's originator
vec3_t velocity; vec3_t velocity;
@ -4424,10 +4453,7 @@ AActor *P_SpawnMissileAngleZSpeed (AActor *source, fixed_t z,
z -= source->floorclip; z -= source->floorclip;
} }
mo = Spawn (type, source->x, source->y, z, ALLOW_REPLACE); mo = Spawn (type, source->x, source->y, z, ALLOW_REPLACE);
if (mo->SeeSound) P_PlaySpawnSound(mo, source);
{
S_SoundID (mo, CHAN_VOICE, mo->SeeSound, 1, ATTN_NORM);
}
mo->target = owner != NULL ? owner : source; // Originator mo->target = owner != NULL ? owner : source; // Originator
mo->angle = angle; mo->angle = angle;
angle >>= ANGLETOFINESHIFT; 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); z += 4*8*FRACUNIT - source->floorclip + (source->player? source->player->crouchoffset : 0);
} }
MissileActor = Spawn (type, x, y, z, ALLOW_REPLACE); MissileActor = Spawn (type, x, y, z, ALLOW_REPLACE);
P_PlaySpawnSound(MissileActor, source);
if (MissileActor->SeeSound)
{
S_SoundID (MissileActor, CHAN_VOICE, MissileActor->SeeSound, 1, ATTN_NORM);
}
MissileActor->target = source; MissileActor->target = source;
MissileActor->angle = an; MissileActor->angle = an;

View File

@ -238,10 +238,7 @@ bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_na
{ {
mobj->tid = newtid; mobj->tid = newtid;
mobj->AddToHash (); mobj->AddToHash ();
if (mobj->SeeSound) P_PlaySpawnSound(mobj, spot);
{
S_SoundID (mobj, CHAN_VOICE, mobj->SeeSound, 1, ATTN_NORM);
}
if (gravity) if (gravity)
{ {
mobj->flags &= ~MF_NOGRAVITY; mobj->flags &= ~MF_NOGRAVITY;

View File

@ -124,6 +124,7 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(MF, COUNTITEM, AActor, flags), DEFINE_FLAG(MF, COUNTITEM, AActor, flags),
DEFINE_FLAG(MF, SKULLFLY, AActor, flags), DEFINE_FLAG(MF, SKULLFLY, AActor, flags),
DEFINE_FLAG(MF, NOTDMATCH, AActor, flags), DEFINE_FLAG(MF, NOTDMATCH, AActor, flags),
DEFINE_FLAG(MF, SPAWNSOUNDSOURCE, AActor, flags),
DEFINE_FLAG(MF, FRIENDLY, AActor, flags), DEFINE_FLAG(MF, FRIENDLY, AActor, flags),
DEFINE_FLAG(MF, NOLIFTDROP, AActor, flags), DEFINE_FLAG(MF, NOLIFTDROP, AActor, flags),
DEFINE_FLAG(MF, STEALTH, AActor, flags), DEFINE_FLAG(MF, STEALTH, AActor, flags),
@ -726,7 +727,7 @@ AFuncDesc AFTable[]=
FUNC(A_GiveToTarget, "Mx" ) FUNC(A_GiveToTarget, "Mx" )
FUNC(A_TakeFromTarget, "Mx" ) FUNC(A_TakeFromTarget, "Mx" )
FUNC(A_CountdownArg, "X") FUNC(A_CountdownArg, "X")
FUNC(A_CustomMeleeAttack, "Xsty" ) FUNC(A_CustomMeleeAttack, "Xssty" )
FUNC(A_Burst, "M") FUNC(A_Burst, "M")
FUNC(A_RadiusThrust, "xxy") FUNC(A_RadiusThrust, "xxy")
{"A_Explode", A_ExplodeParms, "xxy" }, {"A_Explode", A_ExplodeParms, "xxy" },

View File

@ -645,6 +645,13 @@ inline static bool isMissile(AActor * self, bool precise=true)
// The ultimate code pointer: Fully customizable missiles! // The ultimate code pointer: Fully customizable missiles!
// //
//========================================================================== //==========================================================================
enum CM_Flags
{
CMF_AIMMODE = 3,
CMF_TRACKOWNER = 4,
CMF_CHECKTARGETDEAD = 8,
};
void A_CustomMissile(AActor * self) void A_CustomMissile(AActor * self)
{ {
int index=CheckIndex(6); int index=CheckIndex(6);
@ -654,8 +661,9 @@ void A_CustomMissile(AActor * self)
fixed_t SpawnHeight=fixed_t(EvalExpressionF (StateParameters[index+1], self) * FRACUNIT); fixed_t SpawnHeight=fixed_t(EvalExpressionF (StateParameters[index+1], self) * FRACUNIT);
int Spawnofs_XY=EvalExpressionI (StateParameters[index+2], self); int Spawnofs_XY=EvalExpressionI (StateParameters[index+2], self);
angle_t Angle=angle_t(EvalExpressionF (StateParameters[index+3], self) * ANGLE_1); 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); angle_t pitch=angle_t(EvalExpressionF (StateParameters[index+5], self) * ANGLE_1);
int aimmode = flags & CMF_AIMMODE;
AActor * targ; AActor * targ;
AActor * missile; AActor * missile;
@ -670,7 +678,7 @@ void A_CustomMissile(AActor * self)
fixed_t y = Spawnofs_XY * finesine[ang]; fixed_t y = Spawnofs_XY * finesine[ang];
fixed_t z = SpawnHeight - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0); fixed_t z = SpawnHeight - 32*FRACUNIT + (self->player? self->player->crouchoffset : 0);
switch (aimmode&3) switch (aimmode)
{ {
case 0: case 0:
default: default:
@ -724,10 +732,10 @@ void A_CustomMissile(AActor * self)
// handle projectile shooting projectiles - track the // handle projectile shooting projectiles - track the
// links back to a real owner // links back to a real owner
if (isMissile(self, !!(aimmode&4))) if (isMissile(self, !!(flags & CMF_TRACKOWNER)))
{ {
AActor * owner=self ;//->target; 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; targ=owner;
missile->target=owner; missile->target=owner;
// automatic handling of seeker missiles // 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) void A_CustomMeleeAttack (AActor *self)
{ {
int index=CheckIndex(4); int index=CheckIndex(5);
if (index<0) return; if (index<0) return;
int damage = EvalExpressionI (StateParameters[index], self); int damage = EvalExpressionI (StateParameters[index], self);
int MeleeSound=StateParameters[index+1]; int MeleeSound = StateParameters[index+1];
ENamedName DamageType = (ENamedName)StateParameters[index+2]; int MissSound = StateParameters[index+2];
bool bleed = EvalExpressionN (StateParameters[index+3], self); 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 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); P_DamageMobj (self->target, self, self, damage, DamageType);
if (bleed) P_TraceBleed (damage, self->target, self); 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; int pitch = self->pitch;
P_PlaySpawnSound(bo, self);
if (xymom) bo->Speed=xymom; if (xymom) bo->Speed=xymom;
bo->angle = self->angle+(((pr_grenade()&7)-4)<<24); bo->angle = self->angle+(((pr_grenade()&7)-4)<<24);
bo->momz = zmom + 2*finesine[pitch>>ANGLETOFINESHIFT]; bo->momz = zmom + 2*finesine[pitch>>ANGLETOFINESHIFT];

View File

@ -32,6 +32,7 @@
#include "actors/raven/artiegg.txt" #include "actors/raven/artiegg.txt"
#include "actors/raven/ravenartifacts.txt" #include "actors/raven/ravenartifacts.txt"
#include "actors/raven/ravenhealth.txt" #include "actors/raven/ravenhealth.txt"
#include "actors/raven/ravenambient.txt"
#include "actors/heretic/hereticplayer.txt" #include "actors/heretic/hereticplayer.txt"
#include "actors/heretic/hereticammo.txt" #include "actors/heretic/hereticammo.txt"
@ -39,6 +40,8 @@
#include "actors/heretic/hereticartifacts.txt" #include "actors/heretic/hereticartifacts.txt"
#include "actors/heretic/heretickeys.txt" #include "actors/heretic/heretickeys.txt"
#include "actors/heretic/hereticdecorations.txt" #include "actors/heretic/hereticdecorations.txt"
#include "actors/heretic/clink.txt"
#include "actors/heretic/snake.txt"
#include "actors/hexen/fighterplayer.txt" #include "actors/hexen/fighterplayer.txt"
#include "actors/hexen/clericplayer.txt" #include "actors/hexen/clericplayer.txt"

View File

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

View File

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

View File

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

View File

@ -275,6 +275,7 @@ actors/doom/stealthmonsters.txt decorate/doom/stealthmonsters.txt
actors/raven/artiegg.txt decorate/raven/artiegg.txt actors/raven/artiegg.txt decorate/raven/artiegg.txt
actors/raven/ravenartifacts.txt decorate/raven/ravenartifacts.txt actors/raven/ravenartifacts.txt decorate/raven/ravenartifacts.txt
actors/raven/ravenhealth.txt decorate/raven/ravenhealth.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/hereticplayer.txt decorate/heretic/hereticplayer.txt
actors/heretic/hereticammo.txt decorate/heretic/hereticammo.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/hereticartifacts.txt decorate/heretic/hereticartifacts.txt
actors/heretic/heretickeys.txt decorate/heretic/heretickeys.txt actors/heretic/heretickeys.txt decorate/heretic/heretickeys.txt
actors/heretic/hereticdecorations.txt decorate/heretic/hereticdecorations.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/fighterplayer.txt decorate/hexen/fighterplayer.txt
actors/hexen/clericplayer.txt decorate/hexen/clericplayer.txt actors/hexen/clericplayer.txt decorate/hexen/clericplayer.txt

File diff suppressed because it is too large Load Diff