diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 751e8dde4..9840c776e 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,7 @@ +August 2, 2008 (Changes by Graf Zahl) +- Added DECORATE conversions for Hexen's Cleric Mace, Firedemon and fog by + Karate Chris. + July 31, 2008 - Fixed: Attempting to load 0-length sounds caused a crash. - Removed filename-lowercasing from zipdir. @@ -6,6 +10,13 @@ July 31, 2008 - Fixed: Mace SpawnID was assigned to the MacePowered actor instead. - Fixed: Sorcerer2FX1's SpawnID was not restricted to Heretic. +July 27, 2008 (Changes by Graf Zahl) +- Added several type checks to the weapon slot code. + +July 26, 2008 (Changes by Graf Zahl) +- Changed: Players no longer respawn in instant death sectors with + the 'Respawn where died' flag on. + July 24, 2008 - Applied Blzut3's 5:4 SBARINFO patch. (At least I think that's what it's for.) diff --git a/src/codepointers.h b/src/codepointers.h index 08da4328f..1bb9075e9 100644 --- a/src/codepointers.h +++ b/src/codepointers.h @@ -152,6 +152,14 @@ ACTOR(FireCrossbowPL1) ACTOR(FireCrossbowPL2) ACTOR(GauntletAttack) +WEAPON(CMaceAttack) +ACTOR(FiredRocks) +ACTOR(FiredChase) +ACTOR(FiredAttack) +ACTOR(FiredSplotch) +ACTOR(SmBounce) +ACTOR(FogSpawn) +ACTOR(FogMove) // Special code pointers for Strife's player - not to be used elsewhere! ACTOR(ItBurnsItBurns) diff --git a/src/g_hexen/a_clericmace.cpp b/src/g_hexen/a_clericmace.cpp index ce19eebb2..848186783 100644 --- a/src/g_hexen/a_clericmace.cpp +++ b/src/g_hexen/a_clericmace.cpp @@ -1,73 +1,11 @@ -#include "actor.h" -#include "gi.h" #include "m_random.h" -#include "s_sound.h" -#include "d_player.h" -#include "a_action.h" #include "p_local.h" -#include "p_enemy.h" -#include "a_action.h" -#include "p_pspr.h" -#include "gstrings.h" #include "a_hexenglobal.h" extern void AdjustPlayerAngle (AActor *pmo, AActor *linetarget); static FRandom pr_atk ("CMaceAttack"); -void A_CMaceAttack (AActor *actor); - -// The Cleric's Mace -------------------------------------------------------- - -class ACWeapMace : public AClericWeapon -{ - DECLARE_ACTOR (ACWeapMace, AClericWeapon) -}; - -FState ACWeapMace::States[] = -{ -#define S_CMACEREADY 0 - S_NORMAL (CMCE, 'A', 1, A_WeaponReady , &States[S_CMACEREADY]), - -#define S_CMACEDOWN (S_CMACEREADY+1) - S_NORMAL (CMCE, 'A', 1, A_Lower , &States[S_CMACEDOWN]), - -#define S_CMACEUP (S_CMACEDOWN+1) - S_NORMAL (CMCE, 'A', 1, A_Raise , &States[S_CMACEUP]), - -#define S_CMACEATK (S_CMACEUP+1) - S_NORMAL2 (CMCE, 'B', 2, NULL , &States[S_CMACEATK+1], 60, 20), - S_NORMAL2 (CMCE, 'B', 1, NULL , &States[S_CMACEATK+2], 30, 33), - S_NORMAL2 (CMCE, 'B', 2, NULL , &States[S_CMACEATK+3], 8, 45), - S_NORMAL2 (CMCE, 'C', 1, NULL , &States[S_CMACEATK+4], 8, 45), - S_NORMAL2 (CMCE, 'D', 1, NULL , &States[S_CMACEATK+5], 8, 45), - S_NORMAL2 (CMCE, 'E', 1, NULL , &States[S_CMACEATK+6], 8, 45), - S_NORMAL2 (CMCE, 'E', 1, A_CMaceAttack , &States[S_CMACEATK+7], -11, 58), - S_NORMAL2 (CMCE, 'F', 1, NULL , &States[S_CMACEATK+8], 8, 45), - S_NORMAL2 (CMCE, 'F', 2, NULL , &States[S_CMACEATK+9], -8, 74), - S_NORMAL2 (CMCE, 'F', 1, NULL , &States[S_CMACEATK+10], -20, 96), - S_NORMAL2 (CMCE, 'F', 8, NULL , &States[S_CMACEATK+11], -33, 160), - S_NORMAL2 (CMCE, 'A', 2, A_ReFire , &States[S_CMACEATK+12], 8, 75), - S_NORMAL2 (CMCE, 'A', 1, NULL , &States[S_CMACEATK+13], 8, 65), - S_NORMAL2 (CMCE, 'A', 2, NULL , &States[S_CMACEATK+14], 8, 60), - S_NORMAL2 (CMCE, 'A', 1, NULL , &States[S_CMACEATK+15], 8, 55), - S_NORMAL2 (CMCE, 'A', 2, NULL , &States[S_CMACEATK+16], 8, 50), - S_NORMAL2 (CMCE, 'A', 1, NULL , &States[S_CMACEREADY], 8, 45), -}; - - -IMPLEMENT_ACTOR (ACWeapMace, Hexen, -1, 0) - PROP_Weapon_SelectionOrder (3500) - PROP_Flags5 (MF5_BLOODSPLATTER) - PROP_Weapon_Flags (WIF_BOT_MELEE) - PROP_Weapon_UpState (S_CMACEUP) - PROP_Weapon_DownState (S_CMACEDOWN) - PROP_Weapon_ReadyState (S_CMACEREADY) - PROP_Weapon_AtkState (S_CMACEATK) - PROP_Weapon_Kickback (150) - PROP_Weapon_YAdjust (0-8) -END_DEFAULTS - //=========================================================================== // // A_CMaceAttack diff --git a/src/g_hexen/a_firedemon.cpp b/src/g_hexen/a_firedemon.cpp index c42baa18b..87310f368 100644 --- a/src/g_hexen/a_firedemon.cpp +++ b/src/g_hexen/a_firedemon.cpp @@ -27,303 +27,6 @@ void A_FiredChase (AActor *); void A_FiredAttack (AActor *); void A_FiredSplotch (AActor *); -// FireDemon ---------------------------------------------------------------- - -class AFireDemon : public AActor -{ - DECLARE_ACTOR (AFireDemon, AActor) -}; - -FState AFireDemon::States[] = -{ -#define S_FIRED_SPAWN1 0 - S_BRIGHT (FDMN, 'X', 5, NULL , &States[S_FIRED_SPAWN1+1]), - -#define S_FIRED_LOOK1 (S_FIRED_SPAWN1+1) - S_BRIGHT (FDMN, 'E', 10, A_Look , &States[S_FIRED_LOOK1+1]), - S_BRIGHT (FDMN, 'F', 10, A_Look , &States[S_FIRED_LOOK1+2]), - S_BRIGHT (FDMN, 'G', 10, A_Look , &States[S_FIRED_LOOK1+0]), - - S_BRIGHT (FDMN, 'E', 8, NULL , &States[S_FIRED_LOOK1+4]), - S_BRIGHT (FDMN, 'F', 6, NULL , &States[S_FIRED_LOOK1+5]), - S_BRIGHT (FDMN, 'G', 5, NULL , &States[S_FIRED_LOOK1+6]), - S_BRIGHT (FDMN, 'F', 8, NULL , &States[S_FIRED_LOOK1+7]), - S_BRIGHT (FDMN, 'E', 6, NULL , &States[S_FIRED_LOOK1+8]), - S_BRIGHT (FDMN, 'F', 7, A_FiredRocks , &States[S_FIRED_LOOK1+9]), - S_BRIGHT (FDMN, 'H', 5, NULL , &States[S_FIRED_LOOK1+10]), - S_BRIGHT (FDMN, 'I', 5, NULL , &States[S_FIRED_LOOK1+11]), - S_BRIGHT (FDMN, 'J', 5, A_UnSetInvulnerable , &States[S_FIRED_LOOK1+12]), - -#define S_FIRED_WALK1 (S_FIRED_LOOK1+12) - S_BRIGHT (FDMN, 'A', 5, A_FiredChase , &States[S_FIRED_WALK1+1]), - S_BRIGHT (FDMN, 'B', 5, A_FiredChase , &States[S_FIRED_WALK1+2]), - S_BRIGHT (FDMN, 'C', 5, A_FiredChase , &States[S_FIRED_WALK1+0]), - -#define S_FIRED_PAIN1 (S_FIRED_WALK1+3) - S_BRIGHT (FDMN, 'D', 6, A_Pain , &States[S_FIRED_WALK1]), - -#define S_FIRED_ATTACK1 (S_FIRED_PAIN1+1) - S_BRIGHT (FDMN, 'K', 3, A_FaceTarget , &States[S_FIRED_ATTACK1+1]), - S_BRIGHT (FDMN, 'K', 5, A_FiredAttack , &States[S_FIRED_ATTACK1+2]), - S_BRIGHT (FDMN, 'K', 5, A_FiredAttack , &States[S_FIRED_ATTACK1+3]), - S_BRIGHT (FDMN, 'K', 5, A_FiredAttack , &States[S_FIRED_WALK1]), - -#define S_FIRED_DEATH1 (S_FIRED_ATTACK1+4) - S_BRIGHT (FDMN, 'D', 4, A_FaceTarget , &States[S_FIRED_DEATH1+1]), - S_BRIGHT (FDMN, 'L', 4, A_Scream , &States[S_FIRED_DEATH1+2]), - S_BRIGHT (FDMN, 'L', 4, A_NoBlocking , &States[S_FIRED_DEATH1+3]), - S_BRIGHT (FDMN, 'L', 200, NULL , NULL), - -#define S_FIRED_XDEATH1 (S_FIRED_DEATH1+4) - S_NORMAL (FDMN, 'M', 5, A_FaceTarget , &States[S_FIRED_XDEATH1+1]), - S_NORMAL (FDMN, 'N', 5, A_NoBlocking , &States[S_FIRED_XDEATH1+2]), - S_NORMAL (FDMN, 'O', 5, A_FiredSplotch , NULL), - -#define S_FIRED_ICE1 (S_FIRED_XDEATH1+3) - S_NORMAL (FDMN, 'R', 5, A_FreezeDeath , &States[S_FIRED_ICE1+1]), - S_NORMAL (FDMN, 'R', 1, A_FreezeDeathChunks , &States[S_FIRED_ICE1+1]) -}; - -IMPLEMENT_ACTOR (AFireDemon, Hexen, 10060, 5) - PROP_SpawnHealth (80) - PROP_ReactionTime (8) - PROP_PainChance (1) - PROP_SpeedFixed (13) - PROP_RadiusFixed (20) - PROP_HeightFixed (68) - PROP_Mass (75) - PROP_Damage (1) - PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL|MF_DROPOFF|MF_NOGRAVITY|MF_FLOAT) - PROP_Flags2 (MF2_FLOORCLIP|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_INVULNERABLE|MF2_MCROSS|MF2_TELESTOMP) - - PROP_SpawnState (S_FIRED_SPAWN1) - PROP_SeeState (S_FIRED_LOOK1+3) - PROP_PainState (S_FIRED_PAIN1) - PROP_MissileState (S_FIRED_ATTACK1) - PROP_CrashState (S_FIRED_XDEATH1) - PROP_DeathState (S_FIRED_DEATH1) - PROP_XDeathState (S_FIRED_XDEATH1) - PROP_IDeathState (S_FIRED_ICE1) - - PROP_SeeSound ("FireDemonSpawn") - PROP_PainSound ("FireDemonPain") - PROP_DeathSound ("FireDemonDeath") - PROP_ActiveSound ("FireDemonActive") - PROP_Obituary("$OB_FIREDEMON") -END_DEFAULTS - -// AFireDemonSplotch1 ------------------------------------------------------- - -class AFireDemonSplotch1 : public AActor -{ - DECLARE_ACTOR (AFireDemonSplotch1, AActor) -}; - -FState AFireDemonSplotch1::States[] = -{ - S_NORMAL (FDMN, 'P', 3, NULL , &States[1]), - S_NORMAL (FDMN, 'P', 6, A_QueueCorpse , &States[2]), - S_NORMAL (FDMN, 'Y', -1, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonSplotch1, Hexen, -1, 0) - PROP_SpawnHealth (1000) - PROP_ReactionTime (8) - PROP_PainChance (0) - PROP_SpeedFixed (0) - PROP_RadiusFixed (3) - PROP_HeightFixed (16) - PROP_Mass (100) - PROP_Damage (0) - PROP_Flags (MF_DROPOFF|MF_CORPSE) - PROP_Flags2 (MF2_NOTELEPORT|MF2_FLOORCLIP) - - PROP_SpawnState (0) -END_DEFAULTS - -// AFireDemonSplotch2 ------------------------------------------------------- - -class AFireDemonSplotch2 : public AFireDemonSplotch1 -{ - DECLARE_ACTOR (AFireDemonSplotch2, AFireDemonSplotch1) -}; - -FState AFireDemonSplotch2::States[] = -{ - S_NORMAL (FDMN, 'Q', 3, NULL , &States[1]), - S_NORMAL (FDMN, 'Q', 6, A_QueueCorpse , &States[2]), - S_NORMAL (FDMN, 'Z', -1, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonSplotch2, Hexen, -1, 0) - PROP_SpawnState (0) -END_DEFAULTS - -// AFireDemonRock1 ------------------------------------------------------------ - -class AFireDemonRock1 : public AActor -{ - DECLARE_ACTOR (AFireDemonRock1, AActor) -}; - -FState AFireDemonRock1::States[] = -{ -#define S_FIRED_RDROP1 0 - S_NORMAL (FDMN, 'S', 4, NULL , &States[S_FIRED_RDROP1]), - -#define S_FIRED_RDEAD1 (S_FIRED_RDROP1+1) - S_NORMAL (FDMN, 'S', 5, A_SmBounce , &States[S_FIRED_RDEAD1+1]), - S_NORMAL (FDMN, 'S', 200, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonRock1, Hexen, -1, 0) - PROP_SpawnHealth (1000) - PROP_ReactionTime (8) - PROP_PainChance (0) - PROP_SpeedFixed (0) - PROP_RadiusFixed (3) - PROP_HeightFixed (5) - PROP_Mass (16) - PROP_Damage (0) - PROP_Flags (MF_NOBLOCKMAP|MF_DROPOFF|MF_MISSILE) - PROP_Flags2 (MF2_NOTELEPORT) - - PROP_SpawnState (S_FIRED_RDROP1) - PROP_DeathState (S_FIRED_RDEAD1) - PROP_XDeathState (S_FIRED_RDEAD1+1) -END_DEFAULTS - -// AFireDemonRock2 ------------------------------------------------------------ - -class AFireDemonRock2 : public AFireDemonRock1 -{ - DECLARE_ACTOR (AFireDemonRock2, AActor) -}; - -FState AFireDemonRock2::States[] = -{ -#define S_FIRED_RDROP2 0 - S_NORMAL (FDMN, 'T', 4, NULL , &States[S_FIRED_RDROP2]), - -#define S_FIRED_RDEAD2 (S_FIRED_RDROP2+1) - S_NORMAL (FDMN, 'T', 5, A_SmBounce , &States[S_FIRED_RDEAD2+1]), - S_NORMAL (FDMN, 'T', 200, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonRock2, Hexen, -1, 0) - PROP_SpawnState (S_FIRED_RDROP2) - PROP_DeathState (S_FIRED_RDEAD2) - PROP_XDeathState (S_FIRED_RDEAD2+1) -END_DEFAULTS - -// AFireDemonRock3 ------------------------------------------------------------ - -class AFireDemonRock3 : public AFireDemonRock1 -{ - DECLARE_ACTOR (AFireDemonRock3, AFireDemonRock1) -}; - -FState AFireDemonRock3::States[] = -{ -#define S_FIRED_RDROP3 0 - S_NORMAL (FDMN, 'U', 4, NULL , &States[S_FIRED_RDROP3]), - -#define S_FIRED_RDEAD3 (S_FIRED_RDROP3+1) - S_NORMAL (FDMN, 'U', 5, A_SmBounce , &States[S_FIRED_RDEAD3+1]), - S_NORMAL (FDMN, 'U', 200, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonRock3, Hexen, -1, 0) - PROP_SpawnState (S_FIRED_RDROP3) - PROP_DeathState (S_FIRED_RDEAD3) - PROP_XDeathState (S_FIRED_RDEAD3+1) -END_DEFAULTS - -// AFireDemonRock4 ------------------------------------------------------------ - -class AFireDemonRock4 : public AFireDemonRock1 -{ - DECLARE_ACTOR (AFireDemonRock4, AFireDemonRock1) -}; - -FState AFireDemonRock4::States[] = -{ -#define S_FIRED_RDROP4 0 - S_NORMAL (FDMN, 'V', 4, NULL , &States[S_FIRED_RDROP4]), - -#define S_FIRED_RDEAD4 (S_FIRED_RDROP4+1) - S_NORMAL (FDMN, 'V', 5, A_SmBounce , &States[S_FIRED_RDEAD4+1]), - S_NORMAL (FDMN, 'V', 200, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonRock4, Hexen, -1, 0) - PROP_SpawnState (S_FIRED_RDROP4) - PROP_DeathState (S_FIRED_RDEAD4) - PROP_XDeathState (S_FIRED_RDEAD4+1) -END_DEFAULTS - -// AFireDemonRock5 ------------------------------------------------------------ - -class AFireDemonRock5 : public AFireDemonRock1 -{ - DECLARE_ACTOR (AFireDemonRock5, AActor) -}; - -FState AFireDemonRock5::States[] = -{ -#define S_FIRED_RDROP5 0 - S_NORMAL (FDMN, 'W', 4, NULL , &States[S_FIRED_RDROP5]), - -#define S_FIRED_RDEAD5 (S_FIRED_RDROP5+1) - S_NORMAL (FDMN, 'W', 5, A_SmBounce , &States[S_FIRED_RDEAD5+1]), - S_NORMAL (FDMN, 'W', 200, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonRock5, Hexen, -1, 0) - PROP_SpawnState (S_FIRED_RDROP5) - PROP_DeathState (S_FIRED_RDEAD5) - PROP_XDeathState (S_FIRED_RDEAD5+1) -END_DEFAULTS - -// AFireDemonMissile ----------------------------------------------------------- - -class AFireDemonMissile : public AActor -{ - DECLARE_ACTOR (AFireDemonMissile, AActor) -}; - -FState AFireDemonMissile::States[] = -{ -#define S_FIRED_FX6_1 0 - S_BRIGHT (FDMB, 'A', 5, NULL , &States[S_FIRED_FX6_1]), - -#define S_FIRED_FX6_2 (S_FIRED_FX6_1+1) - S_BRIGHT (FDMB, 'B', 5, NULL , &States[S_FIRED_FX6_2+1]), - S_BRIGHT (FDMB, 'C', 5, NULL , &States[S_FIRED_FX6_2+2]), - S_BRIGHT (FDMB, 'D', 5, NULL , &States[S_FIRED_FX6_2+3]), - S_BRIGHT (FDMB, 'E', 5, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AFireDemonMissile, Hexen, -1, 0) - PROP_SpawnHealth (1000) - PROP_ReactionTime (8) - PROP_PainChance (0) - PROP_SpeedFixed (10) - PROP_RadiusFixed (10) - PROP_HeightFixed (6) - PROP_Mass (15) - PROP_Damage (1) - PROP_DamageType (NAME_Fire) - PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE) - PROP_Flags2 (MF2_NOTELEPORT|MF2_IMPACT|MF2_PCROSS|MF2_FLOORCLIP) - PROP_RenderStyle (STYLE_Add) - - PROP_SpawnState (S_FIRED_FX6_1) - PROP_DeathState (S_FIRED_FX6_2) - - PROP_DeathSound ("FireDemonMissileHit") -END_DEFAULTS - //============================================================================ // // A_FiredRocks @@ -354,20 +57,20 @@ void A_FiredSpawnRock (AActor *actor) switch (pr_firedemonrock() % 5) { case 0: - rtype = RUNTIME_CLASS (AFireDemonRock1); + rtype = PClass::FindClass ("FireDemonRock1"); break; case 1: - rtype = RUNTIME_CLASS (AFireDemonRock2); + rtype = PClass::FindClass ("FireDemonRock2"); break; case 2: - rtype = RUNTIME_CLASS (AFireDemonRock3); + rtype = PClass::FindClass ("FireDemonRock3"); break; case 3: - rtype = RUNTIME_CLASS (AFireDemonRock4); + rtype = PClass::FindClass ("FireDemonRock4"); break; case 4: default: - rtype = RUNTIME_CLASS (AFireDemonRock5); + rtype = PClass::FindClass ("FireDemonRock5"); break; } @@ -414,7 +117,7 @@ void A_FiredAttack (AActor *actor) { if (actor->target == NULL) return; - AActor *mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(AFireDemonMissile)); + AActor *mo = P_SpawnMissile (actor, actor->target, PClass::FindClass ("FireDemonMissile")); if (mo) S_Sound (actor, CHAN_BODY, "FireDemonAttack", 1, ATTN_NORM); } @@ -520,14 +223,14 @@ void A_FiredSplotch (AActor *actor) { AActor *mo; - mo = Spawn (actor->x, actor->y, actor->z, ALLOW_REPLACE); + mo = Spawn ("FireDemonSplotch1", actor->x, actor->y, actor->z, ALLOW_REPLACE); if (mo) { mo->momx = (pr_firedemonsplotch() - 128) << 11; mo->momy = (pr_firedemonsplotch() - 128) << 11; mo->momz = (pr_firedemonsplotch() << 10) + FRACUNIT*3; } - mo = Spawn (actor->x, actor->y, actor->z, ALLOW_REPLACE); + mo = Spawn ("FireDemonSplotch2", actor->x, actor->y, actor->z, ALLOW_REPLACE); if (mo) { mo->momx = (pr_firedemonsplotch() - 128) << 11; diff --git a/src/g_hexen/a_fog.cpp b/src/g_hexen/a_fog.cpp index 1567f2025..8369273dd 100644 --- a/src/g_hexen/a_fog.cpp +++ b/src/g_hexen/a_fog.cpp @@ -1,135 +1,8 @@ -#include "actor.h" -#include "info.h" #include "m_random.h" #include "p_local.h" static FRandom pr_fogspawn ("FogSpawn"); -void A_FogSpawn (AActor *); -void A_FogMove (AActor *); - -// Fog Spawner -------------------------------------------------------------- - -class AFogSpawner : public AActor -{ - DECLARE_ACTOR (AFogSpawner, AActor) -}; - -FState AFogSpawner::States[] = -{ -#define S_SPAWNFOG1 0 - S_NORMAL (TNT1, 'A', 20, A_FogSpawn , &States[S_SPAWNFOG1]), -}; - -IMPLEMENT_ACTOR (AFogSpawner, Hexen, 10000, 0) - PROP_Flags (MF_NOSECTOR|MF_NOBLOCKMAP) - PROP_Flags2 (MF2_FLOATBOB) - PROP_RenderFlags (RF_INVISIBLE) - - PROP_SpawnState (S_SPAWNFOG1) -END_DEFAULTS - -// Small Fog Patch ---------------------------------------------------------- - -class AFogPatchSmall : public AActor -{ - DECLARE_ACTOR (AFogPatchSmall, AActor) -}; - -FState AFogPatchSmall::States[] = -{ -#define S_FOGPATCHS1 0 - S_NORMAL (FOGS, 'A', 7, A_FogMove , &States[S_FOGPATCHS1+1]), - S_NORMAL (FOGS, 'B', 7, A_FogMove , &States[S_FOGPATCHS1+2]), - S_NORMAL (FOGS, 'C', 7, A_FogMove , &States[S_FOGPATCHS1+3]), - S_NORMAL (FOGS, 'D', 7, A_FogMove , &States[S_FOGPATCHS1+4]), - S_NORMAL (FOGS, 'E', 7, A_FogMove , &States[S_FOGPATCHS1]), - -#define S_FOGPATCHS0 (S_FOGPATCHS1+5) - S_NORMAL (FOGS, 'E', 5, NULL , NULL), -}; - -IMPLEMENT_ACTOR (AFogPatchSmall, Hexen, 10001, 0) - PROP_SpeedFixed (1) - PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_FLOAT) - PROP_Flags2 (MF2_NOTELEPORT) - PROP_RenderStyle (STYLE_Translucent) - PROP_Alpha (HX_SHADOW) - - PROP_SpawnState (S_FOGPATCHS1) - PROP_DeathState (S_FOGPATCHS0) -END_DEFAULTS - -// Medium Fog Patch --------------------------------------------------------- - -class AFogPatchMedium : public AActor -{ - DECLARE_ACTOR (AFogPatchMedium, AActor) -}; - -FState AFogPatchMedium::States[] = -{ -#define S_FOGPATCHM1 0 - S_NORMAL (FOGM, 'A', 7, A_FogMove , &States[S_FOGPATCHM1+1]), - S_NORMAL (FOGM, 'B', 7, A_FogMove , &States[S_FOGPATCHM1+2]), - S_NORMAL (FOGM, 'C', 7, A_FogMove , &States[S_FOGPATCHM1+3]), - S_NORMAL (FOGM, 'D', 7, A_FogMove , &States[S_FOGPATCHM1+4]), - S_NORMAL (FOGM, 'E', 7, A_FogMove , &States[S_FOGPATCHM1]), - -#define S_FOGPATCHM0 (S_FOGPATCHM1+5) - S_NORMAL (FOGS, 'A', 5, NULL , &States[S_FOGPATCHM0+1]), - S_NORMAL (FOGS, 'B', 5, NULL , &States[S_FOGPATCHM0+2]), - S_NORMAL (FOGS, 'C', 5, NULL , &States[S_FOGPATCHM0+3]), - S_NORMAL (FOGS, 'D', 5, NULL , &States[S_FOGPATCHM0+4]), - S_NORMAL (FOGS, 'E', 5, NULL , &AFogPatchSmall::States[S_FOGPATCHS0]), -}; - -IMPLEMENT_ACTOR (AFogPatchMedium, Hexen, 10002, 0) - PROP_SpeedFixed (1) - PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_FLOAT) - PROP_Flags2 (MF2_NOTELEPORT) - PROP_RenderStyle (STYLE_Translucent) - PROP_Alpha (HX_SHADOW) - - PROP_SpawnState (S_FOGPATCHM1) - PROP_DeathState (S_FOGPATCHM0) -END_DEFAULTS - -// Large Fog Patch ---------------------------------------------------------- - -class AFogPatchLarge : public AActor -{ - DECLARE_ACTOR (AFogPatchLarge, AActor) -}; - -FState AFogPatchLarge::States[] = -{ -#define S_FOGPATCHL1 0 - S_NORMAL (FOGL, 'A', 7, A_FogMove , &States[S_FOGPATCHL1+1]), - S_NORMAL (FOGL, 'B', 7, A_FogMove , &States[S_FOGPATCHL1+2]), - S_NORMAL (FOGL, 'C', 7, A_FogMove , &States[S_FOGPATCHL1+3]), - S_NORMAL (FOGL, 'D', 7, A_FogMove , &States[S_FOGPATCHL1+4]), - S_NORMAL (FOGL, 'E', 7, A_FogMove , &States[S_FOGPATCHL1]), - -#define S_FOGPATCHL0 (S_FOGPATCHL1+5) - S_NORMAL (FOGM, 'A', 4, NULL , &States[S_FOGPATCHL0+1]), - S_NORMAL (FOGM, 'B', 4, NULL , &States[S_FOGPATCHL0+2]), - S_NORMAL (FOGM, 'C', 4, NULL , &States[S_FOGPATCHL0+3]), - S_NORMAL (FOGM, 'D', 4, NULL , &States[S_FOGPATCHL0+4]), - S_NORMAL (FOGM, 'E', 4, NULL , &AFogPatchMedium::States[S_FOGPATCHM0]), -}; - -IMPLEMENT_ACTOR (AFogPatchLarge, Hexen, 10003, 0) - PROP_SpeedFixed (1) - PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_FLOAT) - PROP_Flags2 (MF2_NOTELEPORT) - PROP_RenderStyle (STYLE_Translucent) - PROP_Alpha (HX_SHADOW) - - PROP_SpawnState (S_FOGPATCHL1) - PROP_DeathState (S_FOGPATCHL0) -END_DEFAULTS - //========================================================================== // Fog Variables: // @@ -153,9 +26,9 @@ void A_FogSpawn (AActor *actor) { static const PClass *fogs[3] = { - RUNTIME_CLASS(AFogPatchSmall), - RUNTIME_CLASS(AFogPatchMedium), - RUNTIME_CLASS(AFogPatchLarge) + PClass::FindClass ("FogPatchSmall"), + PClass::FindClass ("FogPatchMedium"), + PClass::FindClass ("FogPatchLarge") }; AActor *mo=NULL; diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 1571ec694..d0260f881 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -335,7 +335,7 @@ AWeapon *AWeapon::AddWeapon (const PClass *weapontype) { AWeapon *weap; - if (weapontype == NULL) + if (weapontype == NULL || !weapontype->IsDescendantOf(RUNTIME_CLASS(AWeapon))) { return NULL; } @@ -604,6 +604,17 @@ bool FWeaponSlot::AddWeapon (const char *type) bool FWeaponSlot::AddWeapon (const PClass *type) { int i; + + if (type == NULL) + { + return false; + } + + if (!type->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + { + Printf("Can't add non-weapon %s to weapon slots\n", type->TypeName.GetChars()); + return false; + } for (i = 0; i < MAX_WEAPONS_PER_SLOT; i++) { @@ -639,7 +650,7 @@ AWeapon *FWeaponSlot::PickWeapon (player_t *player) { AWeapon *weap = static_cast (player->mo->FindInventory (Weapons[j])); - if (weap != NULL && weap->CheckAmmo (AWeapon::EitherFire, false)) + if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo (AWeapon::EitherFire, false)) { return weap; } @@ -651,7 +662,7 @@ AWeapon *FWeaponSlot::PickWeapon (player_t *player) { AWeapon *weap = static_cast (player->mo->FindInventory (Weapons[i])); - if (weap != NULL && weap->CheckAmmo (AWeapon::EitherFire, false)) + if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo (AWeapon::EitherFire, false)) { return weap; } diff --git a/src/g_shared/sbarinfo_display.cpp b/src/g_shared/sbarinfo_display.cpp index 23583c923..07c95c220 100644 --- a/src/g_shared/sbarinfo_display.cpp +++ b/src/g_shared/sbarinfo_display.cpp @@ -1168,18 +1168,18 @@ void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yO y -= (texture->GetHeight()/2)-texture->TopOffset; } - // I'll handle the conversion from fixed to int myself for more control - fixed_t fx = (x + ST_X + xOffset) << FRACBITS; - fixed_t fy = (y + ST_Y + yOffset) << FRACBITS; - fixed_t fw = texture->GetScaledWidth() << FRACBITS; - fixed_t fh = texture->GetScaledHeight() << FRACBITS; + // I'll handle the conversion from fixed to int myself for more control + fixed_t fx = (x + ST_X + xOffset) << FRACBITS; + fixed_t fy = (y + ST_Y + yOffset) << FRACBITS; + fixed_t fw = texture->GetScaledWidth() << FRACBITS; + fixed_t fh = texture->GetScaledHeight() << FRACBITS; if(Scaled) - screen->VirtualToRealCoords(fx, fy, fw, fh, 320, 200, true); - x = fx >> FRACBITS; - y = fy >> FRACBITS; - // Round to nearest - int w = (fw + (FRACUNIT>>1)) >> FRACBITS; - int h = (fh + (FRACUNIT>>1)) >> FRACBITS; + screen->VirtualToRealCoords(fx, fy, fw, fh, 320, 200, true); + x = fx >> FRACBITS; + y = fy >> FRACBITS; + // Round to nearest + int w = (fw + (FRACUNIT>>1)) >> FRACBITS; + int h = (fh + (FRACUNIT>>1)) >> FRACBITS; screen->DrawTexture(texture, x, y, DTA_DestWidth, w, DTA_DestHeight, h, diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 52ebae852..580931502 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3538,7 +3538,8 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer) ( p->playerstate == PST_REBORN ) && ( deathmatch == false ) && ( gameaction != ga_worlddone ) && - ( p->mo != NULL )) + ( p->mo != NULL ) && + ( (p->mo->Sector->special & 255) != Damage_InstantDeath )) { spawn_x = p->mo->x; spawn_y = p->mo->y; diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 859379c48..6e0dad09c 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -1,642 +1,642 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-1996 by id Software, Inc. -// -// This source is available for distribution and/or modification -// only under the terms of the DOOM Source Code License as -// published by id Software. All rights reserved. -// -// The source is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License -// for more details. -// -// $Log:$ -// -// DESCRIPTION: -// -//----------------------------------------------------------------------------- - - -#include -#include -#include -#include -#include - -#include -#include +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1993-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// +//----------------------------------------------------------------------------- + + +#include +#include +#include +#include +#include + +#include +#include #include -#ifndef NO_GTK -#include +#ifndef NO_GTK +#include #include -#endif - -#include "doomerrors.h" -#include - -#include "SDL.h" -#include "doomtype.h" -#include "version.h" -#include "doomdef.h" -#include "cmdlib.h" -#include "m_argv.h" -#include "m_misc.h" -#include "i_video.h" -#include "i_sound.h" -#include "i_music.h" - -#include "d_main.h" -#include "d_net.h" -#include "g_game.h" -#include "i_system.h" -#include "c_dispatch.h" -#include "templates.h" - -#include "stats.h" -#include "hardware.h" -#include "zstring.h" -#include "gameconfigfile.h" - -EXTERN_CVAR (String, language) - -#ifdef USEASM -extern "C" void STACK_ARGS CheckMMX (CPUInfo *cpu); -#endif - -extern "C" -{ - double SecondsPerCycle = 1e-8; - double CyclesPerSecond = 1e8; - CPUInfo CPU; -} +#endif -#ifndef NO_GTK -extern bool GtkAvailable; -#endif - -void CalculateCPUSpeed (); - -DWORD LanguageIDs[4] = -{ - MAKE_ID ('e','n','u',0), - MAKE_ID ('e','n','u',0), - MAKE_ID ('e','n','u',0), - MAKE_ID ('e','n','u',0) -}; - -int (*I_GetTime) (bool saveMS); -int (*I_WaitForTic) (int); - -void I_Tactile (int on, int off, int total) -{ - // UNUSED. - on = off = total = 0; -} - -ticcmd_t emptycmd; -ticcmd_t *I_BaseTiccmd(void) -{ - return &emptycmd; -} - -void I_BeginRead(void) -{ -} - -void I_EndRead(void) -{ -} - -// [RH] Returns time in milliseconds -unsigned int I_MSTime (void) -{ - return SDL_GetTicks (); -} - -static DWORD TicStart; -static DWORD TicNext; - -// -// I_GetTime -// returns time in 1/35th second tics -// -int I_GetTimePolled (bool saveMS) -{ - DWORD tm = SDL_GetTicks (); - - if (saveMS) - { - TicStart = tm; - TicNext = Scale ((Scale (tm, TICRATE, 1000) + 1), 1000, TICRATE); - } - return Scale (tm, TICRATE, 1000); -} - -int I_WaitForTicPolled (int prevtic) -{ - int time; - - while ((time = I_GetTimePolled(false)) <= prevtic) - ; - - return time; -} - -// Returns the fractional amount of a tic passed since the most recent tic -fixed_t I_GetTimeFrac (uint32 *ms) -{ - DWORD now = SDL_GetTicks (); - if (ms) *ms = TicNext; - DWORD step = TicNext - TicStart; - if (step == 0) - { - return FRACUNIT; - } - else - { - fixed_t frac = clamp ((now - TicStart)*FRACUNIT/step, 0, FRACUNIT); - return frac; - } -} - -void I_WaitVBL (int count) -{ - // I_WaitVBL is never used to actually synchronize to the - // vertical blank. Instead, it's used for delay purposes. - usleep (1000000 * count / 70); -} - -// -// SetLanguageIDs -// -void SetLanguageIDs () -{ -} - -// -// I_Init -// -void I_Init (void) -{ -#ifndef USEASM - memset (&CPU, 0, sizeof(CPU)); -#else - CheckMMX (&CPU); - CalculateCPUSpeed (); - - // Why does Intel right-justify this string? - char *f = CPU.CPUString, *t = f; - - while (*f == ' ') - { - ++f; - } - if (f != t) - { - while (*f != 0) - { - *t++ = *f++; - } - } -#endif - if (CPU.VendorID[0]) - { - Printf ("CPU Vendor ID: %s\n", CPU.VendorID); - if (CPU.CPUString[0]) - { - Printf (" Name: %s\n", CPU.CPUString); - } - if (CPU.bIsAMD) - { - Printf (" Family %d (%d), Model %d, Stepping %d\n", - CPU.Family, CPU.AMDFamily, CPU.AMDModel, CPU.AMDStepping); - } - else - { - Printf (" Family %d, Model %d, Stepping %d\n", - CPU.Family, CPU.Model, CPU.Stepping); - } - Printf (" Features:"); - if (CPU.bMMX) Printf (" MMX"); - if (CPU.bMMXPlus) Printf (" MMX+"); - if (CPU.bSSE) Printf (" SSE"); - if (CPU.bSSE2) Printf (" SSE2"); - if (CPU.bSSE3) Printf (" SSE3"); - if (CPU.b3DNow) Printf (" 3DNow!"); - if (CPU.b3DNowPlus) Printf (" 3DNow!+"); - Printf ("\n"); - } - - I_GetTime = I_GetTimePolled; - I_WaitForTic = I_WaitForTicPolled; - I_InitSound (); -} - -void CalculateCPUSpeed () -{ - timeval start, stop, now; - cycle_t ClockCycles; - DWORD usec; - - if (CPU.bRDTSC) - { - ClockCycles = 0; - clock (ClockCycles); - gettimeofday (&start, NULL); - - // Count cycles for at least 100 milliseconds. - // We don't have the same accuracy we can get with the Win32 - // performance counters, so we have to time longer. - stop.tv_usec = start.tv_usec + 100000; - stop.tv_sec = start.tv_sec; - if (stop.tv_usec >= 1000000) - { - stop.tv_usec -= 1000000; - stop.tv_sec += 1; - } - do - { - gettimeofday (&now, NULL); - } while (timercmp (&now, &stop, <)); - - unclock (ClockCycles); - gettimeofday (&now, NULL); - usec = now.tv_usec - start.tv_usec; - - CyclesPerSecond = (double)ClockCycles * 1e6 / (double)usec; - SecondsPerCycle = 1.0 / CyclesPerSecond; - } - Printf (PRINT_HIGH, "CPU Speed: ~%f MHz\n", CyclesPerSecond / 1e6); -} - -// -// I_Quit -// -static int has_exited; - -void I_Quit (void) -{ - has_exited = 1; /* Prevent infinitely recursive exits -- killough */ - - if (demorecording) - G_CheckDemoStatus(); - G_ClearSnapshots (); -} - - -// -// I_Error -// -extern FILE *Logfile; -bool gameisdead; - -void STACK_ARGS I_FatalError (const char *error, ...) -{ - static bool alreadyThrown = false; - gameisdead = true; - - if (!alreadyThrown) // ignore all but the first message -- killough - { - alreadyThrown = true; - char errortext[MAX_ERRORTEXT]; - int index; - va_list argptr; - va_start (argptr, error); - index = vsprintf (errortext, error, argptr); - va_end (argptr); - - // Record error to log (if logging) - if (Logfile) - fprintf (Logfile, "\n**** DIED WITH FATAL ERROR:\n%s\n", errortext); -// throw CFatalError (errortext); - fprintf (stderr, "%s\n", errortext); - exit (-1); - } - - if (!has_exited) // If it hasn't exited yet, exit now -- killough - { - has_exited = 1; // Prevent infinitely recursive exits -- killough - exit(-1); - } -} - -void STACK_ARGS I_Error (const char *error, ...) -{ - va_list argptr; - char errortext[MAX_ERRORTEXT]; - - va_start (argptr, error); - vsprintf (errortext, error, argptr); - va_end (argptr); - - throw CRecoverableError (errortext); -} - -void I_SetIWADInfo (const IWADInfo *info) -{ -} - -void I_PrintStr (const char *cp) -{ - fputs (cp, stdout); - fflush (stdout); -} - -#ifndef NO_GTK -// GtkTreeViews eats return keys. I want this to be like a Windows listbox -// where pressing Return can still activate the default button. -gint AllowDefault(GtkWidget *widget, GdkEventKey *event, gpointer func_data) -{ - if (event->type == GDK_KEY_PRESS && event->keyval == GDK_Return) - { - gtk_window_activate_default (GTK_WINDOW(func_data)); - } - return FALSE; -} - -// Double-clicking an entry in the list is the same as pressing OK. -gint DoubleClickChecker(GtkWidget *widget, GdkEventButton *event, gpointer func_data) -{ - if (event->type == GDK_2BUTTON_PRESS) - { - *(int *)func_data = 1; - gtk_main_quit(); - } - return FALSE; -} - -// When the user presses escape, that should be the same as canceling the dialog. -gint CheckEscape (GtkWidget *widget, GdkEventKey *event, gpointer func_data) -{ - if (event->type == GDK_KEY_PRESS && event->keyval == GDK_Escape) - { - gtk_main_quit(); - } - return FALSE; -} - -void ClickedOK(GtkButton *button, gpointer func_data) -{ - *(int *)func_data = 1; - gtk_main_quit(); -} - -EXTERN_CVAR (Bool, queryiwad); +#include "doomerrors.h" +#include -int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad) -{ - GtkWidget *window; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *bbox; - GtkWidget *widget; - GtkWidget *tree; - GtkWidget *check; - GtkListStore *store; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkTreeSelection *selection; - GtkTreeIter iter, defiter; - int close_style = 0; - int i; - - // Create the dialog window. - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW(window), GAMESIG " " DOTVERSIONSTR ": Select an IWAD to use"); - gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER); - gtk_container_set_border_width (GTK_CONTAINER(window), 10); - g_signal_connect (window, "delete_event", G_CALLBACK(gtk_main_quit), NULL); - g_signal_connect (window, "key_press_event", G_CALLBACK(CheckEscape), NULL); - - // Create the vbox container. - vbox = gtk_vbox_new (FALSE, 10); - gtk_container_add (GTK_CONTAINER(window), vbox); - - // Create the top label. - widget = gtk_label_new ("ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"); - gtk_box_pack_start (GTK_BOX(vbox), widget, false, false, 0); - gtk_misc_set_alignment (GTK_MISC(widget), 0, 0); - - // Create a list store with all the found IWADs. - store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT); - for (i = 0; i < numwads; ++i) - { - const char *filepart = strrchr (wads[i].Path, '/'); - if (filepart == NULL) - filepart = wads[i].Path; - else - filepart++; - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, filepart, - 1, IWADInfos[wads[i].Type].Name, - 2, i, - -1); - if (i == defaultiwad) - { - defiter = iter; - } - } - - // Create the tree view control to show the list. - tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store)); - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("IWAD", renderer, "text", 0, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column); - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes ("Game", renderer, "text", 1, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column); - gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(tree), true, true, 0); - g_signal_connect(G_OBJECT(tree), "button_press_event", G_CALLBACK(DoubleClickChecker), &close_style); - g_signal_connect(G_OBJECT(tree), "key_press_event", G_CALLBACK(AllowDefault), window); - - // Select the default IWAD. - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree)); - gtk_tree_selection_select_iter (selection, &defiter); - - // Create the hbox for the bottom row. - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_end (GTK_BOX(vbox), hbox, false, false, 0); - - // Create the "Don't ask" checkbox. - check = gtk_check_button_new_with_label ("Don't ask me this again"); - gtk_box_pack_start (GTK_BOX(hbox), check, false, false, 0); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(check), !showwin); - - // Create the OK/Cancel button box. - bbox = gtk_hbutton_box_new (); - gtk_button_box_set_layout (GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing (GTK_BOX(bbox), 10); - gtk_box_pack_end (GTK_BOX(hbox), bbox, false, false, 0); - - // Create the OK button. - widget = gtk_button_new_from_stock (GTK_STOCK_OK); - gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0); - GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT); - gtk_widget_grab_default (widget); - g_signal_connect (widget, "clicked", G_CALLBACK(ClickedOK), &close_style); - g_signal_connect (widget, "activate", G_CALLBACK(ClickedOK), &close_style); - - // Create the cancel button. - widget = gtk_button_new_from_stock (GTK_STOCK_CANCEL); - gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0); - g_signal_connect (widget, "clicked", G_CALLBACK(gtk_main_quit), &window); - - // Finally we can show everything. - gtk_widget_show_all (window); - - gtk_main (); - - if (close_style == 1) - { - GtkTreeModel *model; - GValue value = { 0, }; - - // Find out which IWAD was selected. - gtk_tree_selection_get_selected (selection, &model, &iter); - gtk_tree_model_get_value (GTK_TREE_MODEL(model), &iter, 2, &value); - i = g_value_get_int (&value); - g_value_unset (&value); - - // Set state of queryiwad based on the checkbox. - queryiwad = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(check)); - } - else - { - i = -1; - } - - if (GTK_IS_WINDOW(window)) - { - gtk_widget_destroy (window); - // If we don't do this, then the X window might not actually disappear. - while (g_main_context_iteration (NULL, FALSE)) {} - } - - return i; +#include "SDL.h" +#include "doomtype.h" +#include "version.h" +#include "doomdef.h" +#include "cmdlib.h" +#include "m_argv.h" +#include "m_misc.h" +#include "i_video.h" +#include "i_sound.h" +#include "i_music.h" + +#include "d_main.h" +#include "d_net.h" +#include "g_game.h" +#include "i_system.h" +#include "c_dispatch.h" +#include "templates.h" + +#include "stats.h" +#include "hardware.h" +#include "zstring.h" +#include "gameconfigfile.h" + +EXTERN_CVAR (String, language) + +#ifdef USEASM +extern "C" void STACK_ARGS CheckMMX (CPUInfo *cpu); +#endif + +extern "C" +{ + double SecondsPerCycle = 1e-8; + double CyclesPerSecond = 1e8; + CPUInfo CPU; } -#endif - -int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) -{ - int i; - - if (!showwin) - { - return defaultiwad; - } -#ifndef NO_GTK - if (GtkAvailable) - { - return I_PickIWad_Gtk (wads, numwads, showwin, defaultiwad); +#ifndef NO_GTK +extern bool GtkAvailable; +#endif + +void CalculateCPUSpeed (); + +DWORD LanguageIDs[4] = +{ + MAKE_ID ('e','n','u',0), + MAKE_ID ('e','n','u',0), + MAKE_ID ('e','n','u',0), + MAKE_ID ('e','n','u',0) +}; + +int (*I_GetTime) (bool saveMS); +int (*I_WaitForTic) (int); + +void I_Tactile (int on, int off, int total) +{ + // UNUSED. + on = off = total = 0; +} + +ticcmd_t emptycmd; +ticcmd_t *I_BaseTiccmd(void) +{ + return &emptycmd; +} + +void I_BeginRead(void) +{ +} + +void I_EndRead(void) +{ +} + +// [RH] Returns time in milliseconds +unsigned int I_MSTime (void) +{ + return SDL_GetTicks (); +} + +static DWORD TicStart; +static DWORD TicNext; + +// +// I_GetTime +// returns time in 1/35th second tics +// +int I_GetTimePolled (bool saveMS) +{ + DWORD tm = SDL_GetTicks (); + + if (saveMS) + { + TicStart = tm; + TicNext = Scale ((Scale (tm, TICRATE, 1000) + 1), 1000, TICRATE); } -#endif - - printf ("Please select a game wad (or 0 to exit):\n"); - for (i = 0; i < numwads; ++i) - { - const char *filepart = strrchr (wads[i].Path, '/'); - if (filepart == NULL) - filepart = wads[i].Path; - else - filepart++; - printf ("%d. %s (%s)\n", i+1, IWADInfos[wads[i].Type].Name, filepart); - } - printf ("Which one? "); - scanf ("%d", &i); - if (i > numwads) - return -1; - return i-1; -} - -bool I_WriteIniFailed () -{ - printf ("The config file %s could not be saved:\n%s\n", GameConfig->GetPathName(), strerror(errno)); - return false; - // return true to retry -} - -static const char *pattern; - -#ifdef OSF1 -static int matchfile (struct dirent *ent) -#else -static int matchfile (const struct dirent *ent) -#endif -{ - return fnmatch (pattern, ent->d_name, FNM_NOESCAPE) == 0; -} - -void *I_FindFirst (const char *filespec, findstate_t *fileinfo) -{ - FString dir; - - char *slash = strrchr (filespec, '/'); - if (slash) - { - pattern = slash+1; - dir = FString(filespec, slash-filespec+1); - } - else - { - pattern = filespec; - dir = "."; - } - - fileinfo->current = 0; - fileinfo->count = scandir (dir.GetChars(), &fileinfo->namelist, - matchfile, alphasort); - if (fileinfo->count > 0) - { - return fileinfo; - } - return (void*)-1; -} - -int I_FindNext (void *handle, findstate_t *fileinfo) -{ - findstate_t *state = (findstate_t *)handle; - if (state->current < fileinfo->count) - { - return ++state->current < fileinfo->count ? 0 : -1; - } - return -1; -} - -int I_FindClose (void *handle) -{ - findstate_t *state = (findstate_t *)handle; - if (handle != (void*)-1 && state->count > 0) - { - state->count = 0; - free (state->namelist); - state->namelist = NULL; - } - return 0; -} - -int I_FindAttr (findstate_t *fileinfo) -{ - struct dirent *ent = fileinfo->namelist[fileinfo->current]; - -#ifdef OSF1 - return 0; // I don't know how to detect dirs under OSF/1 -#else - return (ent->d_type == DT_DIR) ? FA_DIREC : 0; -#endif -} - -// No clipboard support for Linux -void I_PutInClipboard (const char *str) -{ -} - -char *I_GetFromClipboard () -{ - return NULL; -} + return Scale (tm, TICRATE, 1000); +} + +int I_WaitForTicPolled (int prevtic) +{ + int time; + + while ((time = I_GetTimePolled(false)) <= prevtic) + ; + + return time; +} + +// Returns the fractional amount of a tic passed since the most recent tic +fixed_t I_GetTimeFrac (uint32 *ms) +{ + DWORD now = SDL_GetTicks (); + if (ms) *ms = TicNext; + DWORD step = TicNext - TicStart; + if (step == 0) + { + return FRACUNIT; + } + else + { + fixed_t frac = clamp ((now - TicStart)*FRACUNIT/step, 0, FRACUNIT); + return frac; + } +} + +void I_WaitVBL (int count) +{ + // I_WaitVBL is never used to actually synchronize to the + // vertical blank. Instead, it's used for delay purposes. + usleep (1000000 * count / 70); +} + +// +// SetLanguageIDs +// +void SetLanguageIDs () +{ +} + +// +// I_Init +// +void I_Init (void) +{ +#ifndef USEASM + memset (&CPU, 0, sizeof(CPU)); +#else + CheckMMX (&CPU); + CalculateCPUSpeed (); + + // Why does Intel right-justify this string? + char *f = CPU.CPUString, *t = f; + + while (*f == ' ') + { + ++f; + } + if (f != t) + { + while (*f != 0) + { + *t++ = *f++; + } + } +#endif + if (CPU.VendorID[0]) + { + Printf ("CPU Vendor ID: %s\n", CPU.VendorID); + if (CPU.CPUString[0]) + { + Printf (" Name: %s\n", CPU.CPUString); + } + if (CPU.bIsAMD) + { + Printf (" Family %d (%d), Model %d, Stepping %d\n", + CPU.Family, CPU.AMDFamily, CPU.AMDModel, CPU.AMDStepping); + } + else + { + Printf (" Family %d, Model %d, Stepping %d\n", + CPU.Family, CPU.Model, CPU.Stepping); + } + Printf (" Features:"); + if (CPU.bMMX) Printf (" MMX"); + if (CPU.bMMXPlus) Printf (" MMX+"); + if (CPU.bSSE) Printf (" SSE"); + if (CPU.bSSE2) Printf (" SSE2"); + if (CPU.bSSE3) Printf (" SSE3"); + if (CPU.b3DNow) Printf (" 3DNow!"); + if (CPU.b3DNowPlus) Printf (" 3DNow!+"); + Printf ("\n"); + } + + I_GetTime = I_GetTimePolled; + I_WaitForTic = I_WaitForTicPolled; + I_InitSound (); +} + +void CalculateCPUSpeed () +{ + timeval start, stop, now; + cycle_t ClockCycles; + DWORD usec; + + if (CPU.bRDTSC) + { + ClockCycles = 0; + clock (ClockCycles); + gettimeofday (&start, NULL); + + // Count cycles for at least 100 milliseconds. + // We don't have the same accuracy we can get with the Win32 + // performance counters, so we have to time longer. + stop.tv_usec = start.tv_usec + 100000; + stop.tv_sec = start.tv_sec; + if (stop.tv_usec >= 1000000) + { + stop.tv_usec -= 1000000; + stop.tv_sec += 1; + } + do + { + gettimeofday (&now, NULL); + } while (timercmp (&now, &stop, <)); + + unclock (ClockCycles); + gettimeofday (&now, NULL); + usec = now.tv_usec - start.tv_usec; + + CyclesPerSecond = (double)ClockCycles * 1e6 / (double)usec; + SecondsPerCycle = 1.0 / CyclesPerSecond; + } + Printf (PRINT_HIGH, "CPU Speed: ~%f MHz\n", CyclesPerSecond / 1e6); +} + +// +// I_Quit +// +static int has_exited; + +void I_Quit (void) +{ + has_exited = 1; /* Prevent infinitely recursive exits -- killough */ + + if (demorecording) + G_CheckDemoStatus(); + G_ClearSnapshots (); +} + + +// +// I_Error +// +extern FILE *Logfile; +bool gameisdead; + +void STACK_ARGS I_FatalError (const char *error, ...) +{ + static bool alreadyThrown = false; + gameisdead = true; + + if (!alreadyThrown) // ignore all but the first message -- killough + { + alreadyThrown = true; + char errortext[MAX_ERRORTEXT]; + int index; + va_list argptr; + va_start (argptr, error); + index = vsprintf (errortext, error, argptr); + va_end (argptr); + + // Record error to log (if logging) + if (Logfile) + fprintf (Logfile, "\n**** DIED WITH FATAL ERROR:\n%s\n", errortext); +// throw CFatalError (errortext); + fprintf (stderr, "%s\n", errortext); + exit (-1); + } + + if (!has_exited) // If it hasn't exited yet, exit now -- killough + { + has_exited = 1; // Prevent infinitely recursive exits -- killough + exit(-1); + } +} + +void STACK_ARGS I_Error (const char *error, ...) +{ + va_list argptr; + char errortext[MAX_ERRORTEXT]; + + va_start (argptr, error); + vsprintf (errortext, error, argptr); + va_end (argptr); + + throw CRecoverableError (errortext); +} + +void I_SetIWADInfo (const IWADInfo *info) +{ +} + +void I_PrintStr (const char *cp) +{ + fputs (cp, stdout); + fflush (stdout); +} + +#ifndef NO_GTK +// GtkTreeViews eats return keys. I want this to be like a Windows listbox +// where pressing Return can still activate the default button. +gint AllowDefault(GtkWidget *widget, GdkEventKey *event, gpointer func_data) +{ + if (event->type == GDK_KEY_PRESS && event->keyval == GDK_Return) + { + gtk_window_activate_default (GTK_WINDOW(func_data)); + } + return FALSE; +} + +// Double-clicking an entry in the list is the same as pressing OK. +gint DoubleClickChecker(GtkWidget *widget, GdkEventButton *event, gpointer func_data) +{ + if (event->type == GDK_2BUTTON_PRESS) + { + *(int *)func_data = 1; + gtk_main_quit(); + } + return FALSE; +} + +// When the user presses escape, that should be the same as canceling the dialog. +gint CheckEscape (GtkWidget *widget, GdkEventKey *event, gpointer func_data) +{ + if (event->type == GDK_KEY_PRESS && event->keyval == GDK_Escape) + { + gtk_main_quit(); + } + return FALSE; +} + +void ClickedOK(GtkButton *button, gpointer func_data) +{ + *(int *)func_data = 1; + gtk_main_quit(); +} + +EXTERN_CVAR (Bool, queryiwad); + +int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad) +{ + GtkWidget *window; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *bbox; + GtkWidget *widget; + GtkWidget *tree; + GtkWidget *check; + GtkListStore *store; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *selection; + GtkTreeIter iter, defiter; + int close_style = 0; + int i; + + // Create the dialog window. + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW(window), GAMESIG " " DOTVERSIONSTR ": Select an IWAD to use"); + gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_container_set_border_width (GTK_CONTAINER(window), 10); + g_signal_connect (window, "delete_event", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect (window, "key_press_event", G_CALLBACK(CheckEscape), NULL); + + // Create the vbox container. + vbox = gtk_vbox_new (FALSE, 10); + gtk_container_add (GTK_CONTAINER(window), vbox); + + // Create the top label. + widget = gtk_label_new ("ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:"); + gtk_box_pack_start (GTK_BOX(vbox), widget, false, false, 0); + gtk_misc_set_alignment (GTK_MISC(widget), 0, 0); + + // Create a list store with all the found IWADs. + store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT); + for (i = 0; i < numwads; ++i) + { + const char *filepart = strrchr (wads[i].Path, '/'); + if (filepart == NULL) + filepart = wads[i].Path; + else + filepart++; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, filepart, + 1, IWADInfos[wads[i].Type].Name, + 2, i, + -1); + if (i == defaultiwad) + { + defiter = iter; + } + } + + // Create the tree view control to show the list. + tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store)); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("IWAD", renderer, "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Game", renderer, "text", 1, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW(tree), column); + gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(tree), true, true, 0); + g_signal_connect(G_OBJECT(tree), "button_press_event", G_CALLBACK(DoubleClickChecker), &close_style); + g_signal_connect(G_OBJECT(tree), "key_press_event", G_CALLBACK(AllowDefault), window); + + // Select the default IWAD. + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree)); + gtk_tree_selection_select_iter (selection, &defiter); + + // Create the hbox for the bottom row. + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_end (GTK_BOX(vbox), hbox, false, false, 0); + + // Create the "Don't ask" checkbox. + check = gtk_check_button_new_with_label ("Don't ask me this again"); + gtk_box_pack_start (GTK_BOX(hbox), check, false, false, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(check), !showwin); + + // Create the OK/Cancel button box. + bbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing (GTK_BOX(bbox), 10); + gtk_box_pack_end (GTK_BOX(hbox), bbox, false, false, 0); + + // Create the OK button. + widget = gtk_button_new_from_stock (GTK_STOCK_OK); + gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0); + GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT); + gtk_widget_grab_default (widget); + g_signal_connect (widget, "clicked", G_CALLBACK(ClickedOK), &close_style); + g_signal_connect (widget, "activate", G_CALLBACK(ClickedOK), &close_style); + + // Create the cancel button. + widget = gtk_button_new_from_stock (GTK_STOCK_CANCEL); + gtk_box_pack_start (GTK_BOX(bbox), widget, false, false, 0); + g_signal_connect (widget, "clicked", G_CALLBACK(gtk_main_quit), &window); + + // Finally we can show everything. + gtk_widget_show_all (window); + + gtk_main (); + + if (close_style == 1) + { + GtkTreeModel *model; + GValue value = { 0, }; + + // Find out which IWAD was selected. + gtk_tree_selection_get_selected (selection, &model, &iter); + gtk_tree_model_get_value (GTK_TREE_MODEL(model), &iter, 2, &value); + i = g_value_get_int (&value); + g_value_unset (&value); + + // Set state of queryiwad based on the checkbox. + queryiwad = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(check)); + } + else + { + i = -1; + } + + if (GTK_IS_WINDOW(window)) + { + gtk_widget_destroy (window); + // If we don't do this, then the X window might not actually disappear. + while (g_main_context_iteration (NULL, FALSE)) {} + } + + return i; +} +#endif + +int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) +{ + int i; + + if (!showwin) + { + return defaultiwad; + } + +#ifndef NO_GTK + if (GtkAvailable) + { + return I_PickIWad_Gtk (wads, numwads, showwin, defaultiwad); + } +#endif + + printf ("Please select a game wad (or 0 to exit):\n"); + for (i = 0; i < numwads; ++i) + { + const char *filepart = strrchr (wads[i].Path, '/'); + if (filepart == NULL) + filepart = wads[i].Path; + else + filepart++; + printf ("%d. %s (%s)\n", i+1, IWADInfos[wads[i].Type].Name, filepart); + } + printf ("Which one? "); + scanf ("%d", &i); + if (i > numwads) + return -1; + return i-1; +} + +bool I_WriteIniFailed () +{ + printf ("The config file %s could not be saved:\n%s\n", GameConfig->GetPathName(), strerror(errno)); + return false; + // return true to retry +} + +static const char *pattern; + +#ifdef OSF1 +static int matchfile (struct dirent *ent) +#else +static int matchfile (const struct dirent *ent) +#endif +{ + return fnmatch (pattern, ent->d_name, FNM_NOESCAPE) == 0; +} + +void *I_FindFirst (const char *filespec, findstate_t *fileinfo) +{ + FString dir; + + char *slash = strrchr (filespec, '/'); + if (slash) + { + pattern = slash+1; + dir = FString(filespec, slash-filespec+1); + } + else + { + pattern = filespec; + dir = "."; + } + + fileinfo->current = 0; + fileinfo->count = scandir (dir.GetChars(), &fileinfo->namelist, + matchfile, alphasort); + if (fileinfo->count > 0) + { + return fileinfo; + } + return (void*)-1; +} + +int I_FindNext (void *handle, findstate_t *fileinfo) +{ + findstate_t *state = (findstate_t *)handle; + if (state->current < fileinfo->count) + { + return ++state->current < fileinfo->count ? 0 : -1; + } + return -1; +} + +int I_FindClose (void *handle) +{ + findstate_t *state = (findstate_t *)handle; + if (handle != (void*)-1 && state->count > 0) + { + state->count = 0; + free (state->namelist); + state->namelist = NULL; + } + return 0; +} + +int I_FindAttr (findstate_t *fileinfo) +{ + struct dirent *ent = fileinfo->namelist[fileinfo->current]; + +#ifdef OSF1 + return 0; // I don't know how to detect dirs under OSF/1 +#else + return (ent->d_type == DT_DIR) ? FA_DIREC : 0; +#endif +} + +// No clipboard support for Linux +void I_PutInClipboard (const char *str) +{ +} + +char *I_GetFromClipboard () +{ + return NULL; +} diff --git a/wadsrc/static/actors/hexen/clericmace.txt b/wadsrc/static/actors/hexen/clericmace.txt new file mode 100644 index 000000000..a45d9da02 --- /dev/null +++ b/wadsrc/static/actors/hexen/clericmace.txt @@ -0,0 +1,44 @@ + +// The Cleric's Mace -------------------------------------------------------- + +ACTOR CWeapMace : ClericWeapon +{ + Weapon.SelectionOrder 3500 + Weapon.KickBack 150 + Weapon.YAdjust -8 + +BLOODSPLATTER + + action native A_CMaceAttack(); + + States + { + Select: + CMCE A 1 A_Raise + Loop + Deselect: + CMCE A 1 A_Lower + Loop + Ready: + CMCE A 1 A_WeaponReady + Loop + Fire: + CMCE B 2 Offset (60, 20) + CMCE B 1 Offset (30, 33) + CMCE B 2 Offset (8, 45) + CMCE C 1 Offset (8, 45) + CMCE D 1 Offset (8, 45) + CMCE E 1 Offset (8, 45) + CMCE E 1 Offset (-11, 58) A_CMaceAttack + CMCE F 1 Offset (8, 45) + CMCE F 2 Offset (-8, 74) + CMCE F 1 Offset (-20, 96) + CMCE F 8 Offset (-33, 160) + CMCE A 2 Offset (8, 75) A_ReFire + CMCE A 1 Offset (8, 65) + CMCE A 2 Offset (8, 60) + CMCE A 1 Offset (8, 55) + CMCE A 2 Offset (8, 50) + CMCE A 1 Offset (8, 45) + Goto Ready + } +} diff --git a/wadsrc/static/actors/hexen/firedemon.txt b/wadsrc/static/actors/hexen/firedemon.txt new file mode 100644 index 000000000..855bfc747 --- /dev/null +++ b/wadsrc/static/actors/hexen/firedemon.txt @@ -0,0 +1,236 @@ + +// FireDemon ---------------------------------------------------------------- + +ACTOR FireDemon 10060 +{ + SpawnID 5 + Health 80 + ReactionTime 8 + PainChance 1 + Speed 13 + Radius 20 + Height 68 + Mass 75 + Damage 1 + Monster + +DROPOFF +NOGRAVITY +FLOAT + +FLOORCLIP +INVULNERABLE +TELESTOMP + -CANUSEWALLS + SeeSound "FireDemonSpawn" + PainSound "FireDemonPain" + DeathSound "FireDemonDeath" + ActiveSound "FireDemonActive" + Obituary "$OB_FIREDEMON" + + action native A_FiredRocks(); + action native A_FiredChase(); + action native A_FiredAttack(); + action native A_FiredSplotch(); + + States + { + Spawn: + FDMN X 5 Bright + FDMN EFG 10 Bright A_Look + Goto Spawn + 1 + See: + FDMN E 8 Bright + FDMN F 6 Bright + FDMN G 5 Bright + FDMN F 8 Bright + FDMN E 6 Bright + FDMN G 7 Bright A_FiredRocks + FDMN HI 5 Bright + FDMN J 5 Bright A_UnSetInvulnerable + Chase: + FDMN ABC 5 Bright A_FiredChase + Loop + Pain: + FDMN D 6 Bright A_Pain + Goto Chase + Missile: + FDMN K 3 Bright A_FaceTarget + FDMN KKK 5 Bright A_FiredAttack + Goto Chase + Crash: + XDeath: + FDMN M 5 A_FaceTarget + FDMN N 5 A_NoBlocking + FDMN O 5 A_FiredSplotch + Stop + Death: + FDMN D 4 Bright A_FaceTarget + FDMN L 4 Bright A_Scream + FDMN L 4 Bright A_NoBlocking + FDMN L 200 Bright + Stop + Ice: + FDMN R 5 A_FreezeDeath + FDMN R 1 A_FreezeDeathChunks + Wait + } +} + +// FireDemonSplotch1 ------------------------------------------------------- + +ACTOR FireDemonSplotch1 +{ + Game Hexen + Health 1000 + ReactionTime 8 + Radius 3 + Height 16 + Mass 100 + +DROPOFF +CORPSE + +NOTELEPORT +FLOORCLIP + States + { + Spawn: + FDMN P 3 + FDMN P 6 A_QueueCorpse + FDMN Y -1 + Stop + } +} + +// FireDemonSplotch2 ------------------------------------------------------- + +ACTOR FireDemonSplotch2 : FireDemonSplotch1 +{ + States + { + Spawn: + FDMN Q 3 + FDMN Q 6 A_QueueCorpse + FDMN Z -1 + Stop + } +} + +// FireDemonRock1 ------------------------------------------------------------ + +ACTOR FireDemonRock1 +{ + Game Hexen + Health 1000 + ReactionTime 8 + Radius 3 + Height 5 + Mass 16 + +NOBLOCKMAP +DROPOFF +MISSILE + +NOTELEPORT + + action native A_SmBounce(); + + States + { + Spawn: + FDMN S 4 + Loop + Death: + FDMN S 5 A_SmBounce + XDeath: + FDMN S 200 + Stop + } +} + +// FireDemonRock2 ------------------------------------------------------------ + +ACTOR FireDemonRock2 : FireDemonRock1 +{ + Game Hexen + States + { + Spawn: + FDMN T 4 + Loop + Death: + FDMN T 5 A_SmBounce + XDeath: + FDMN T 200 + Stop + } +} + +// FireDemonRock3 ------------------------------------------------------------ + +ACTOR FireDemonRock3 : FireDemonRock1 +{ + Game Hexen + States + { + Spawn: + FDMN U 4 + Loop + Death: + FDMN U 5 A_SmBounce + XDeath: + FDMN U 200 + Stop + } +} + +// FireDemonRock4 ------------------------------------------------------------ + +ACTOR FireDemonRock4 : FireDemonRock1 +{ + Game Hexen + States + { + Spawn: + FDMN V 4 + Loop + Death: + FDMN V 5 A_SmBounce + XDeath: + FDMN V 200 + Stop + } +} + +// FireDemonRock5 ------------------------------------------------------------ + +ACTOR FireDemonRock5 : FireDemonRock1 +{ + Game Hexen + States + { + Spawn: + FDMN W 4 + Loop + Death: + FDMN W 5 A_SmBounce + XDeath: + FDMN W 200 + Stop + } +} + +// FireDemonMissile ----------------------------------------------------------- + +ACTOR FireDemonMissile +{ + Health 1000 + ReactionTime 8 + Speed 10 + Radius 10 + Height 6 + Mass 5 + Damage 1 + DamageType "Fire" + Projectile + +FLOORCLIP + -BLOODSPLATTER + RenderStyle Add + DeathSound "FireDemonMissileHit" + States + { + Spawn: + FDMB A 5 Bright + Loop + Death: + FDMB BCDE 5 Bright + Stop + } +} diff --git a/wadsrc/static/actors/hexen/flame.txt b/wadsrc/static/actors/hexen/flame.txt index 276e55768..17d283df0 100644 --- a/wadsrc/static/actors/hexen/flame.txt +++ b/wadsrc/static/actors/hexen/flame.txt @@ -1,6 +1,6 @@ // Temp Small Flame -------------------------------------------------------- -ACTOR AFlameSmallTemp 10500 +ACTOR FlameSmallTemp 10500 { Game Hexen SpawnID 96 @@ -21,7 +21,7 @@ ACTOR AFlameSmallTemp 10500 // Temp Large Flame --------------------------------------------------------- -ACTOR AFlameLargeTemp 10502 +ACTOR FlameLargeTemp 10502 { Game Hexen SpawnID 98 diff --git a/wadsrc/static/actors/hexen/fog.txt b/wadsrc/static/actors/hexen/fog.txt new file mode 100644 index 000000000..9711bae36 --- /dev/null +++ b/wadsrc/static/actors/hexen/fog.txt @@ -0,0 +1,73 @@ + +// Fog Spawner -------------------------------------------------------------- + +ACTOR FogSpawner 10000 +{ + Game Hexen + +NOSECTOR +NOBLOCKMAP + +FLOATBOB + +INVISIBLE + + action native A_FogSpawn(); + + States + { + Spawn: + TNT1 A 20 A_FogSpawn + Loop + } +} + +// Small Fog Patch ---------------------------------------------------------- + +ACTOR FogPatchSmall 10001 +{ + Game Hexen + Speed 1 + +NOBLOCKMAP +NOGRAVITY +NOCLIP +FLOAT + +NOTELEPORT + RenderStyle Translucent + Alpha 0.6 + + action native A_FogMove(); + + States + { + Spawn: + FOGS ABCDE 7 A_FogMove + Loop + Death: + FOGS E 5 + Stop + } +} + +// Medium Fog Patch --------------------------------------------------------- + +ACTOR FogPatchMedium : FogPatchSmall 10002 +{ + States + { + Spawn: + FOGM ABCDE 7 A_FogMove + Loop + Death: + FOGS ABCDE 5 + Goto Super::Death + } +} + +// Large Fog Patch ---------------------------------------------------------- + +ACTOR FogPatchLarge : FogPatchMedium 10003 +{ + States + { + Spawn: + FOGL ABCDE 7 A_FogMove + Loop + Death: + FOGM ABCDEF 4 + Goto Super::Death + } +} diff --git a/wadsrc/static/decorate.txt b/wadsrc/static/decorate.txt index ea1c9cc09..e50dc6434 100644 --- a/wadsrc/static/decorate.txt +++ b/wadsrc/static/decorate.txt @@ -77,6 +77,9 @@ #include "actors/hexen/ettin.txt" #include "actors/hexen/centaur.txt" #include "actors/hexen/demons.txt" +#include "actors/hexen/clericmace.txt" +#include "actors/hexen/firedemon.txt" +#include "actors/hexen/fog.txt" #include "actors/strife/strifeplayer.txt" #include "actors/strife/beggars.txt"