- Converted ExplosiveBarrel, BulletPuff and DoomUnusedStates to DECORATE.

- Added VSpeed DECORATE property so that an actor can be given an initial
  vertical speed.
- Removed the barrel check in P_DamageMobj. AActor::Die is doing the same
  operation unconditionally so this is redundant.
- Added A_BarrelDestroy to the list of DECORATE code pointers so that
  the same effect can be recreated for other items as well.
- Renamed A_BarrelRespawn to A_Respawn, changed it so that it works for
  monsters and added it to the list of DECORATE code pointers. Now Quake-style
  zombies should be possible. ;)
- Changed handling of MF4_RANDOMIZE so that it applies to all actors being
  spawned and not just projectiles.
- Converted Berserk and Megasphere to DECORATE.
- Fixed: HealThing should respect the stamina a player has and the Dehacked
  health compatibility flag if max is 0. To do that it calls P_GiveBody now.


SVN r373 (trunk)
This commit is contained in:
Christoph Oelckers 2006-11-04 13:06:42 +00:00
parent c745c635db
commit 29195a913c
25 changed files with 907 additions and 947 deletions

View file

@ -1,3 +1,20 @@
November 4, 2006 (Changes by Graf Zahl)
- Converted ExplosiveBarrel, BulletPuff and DoomUnusedStates to DECORATE.
- Added VSpeed DECORATE property so that an actor can be given an initial
vertical speed.
- Removed the barrel check in P_DamageMobj. AActor::Die is doing the same
operation unconditionally so this is redundant.
- Added A_BarrelDestroy to the list of DECORATE code pointers so that
the same effect can be recreated for other items as well.
- Renamed A_BarrelRespawn to A_Respawn, changed it so that it works for
monsters and added it to the list of DECORATE code pointers. Now Quake-style
zombies should be possible. ;)
- Changed handling of MF4_RANDOMIZE so that it applies to all actors being
spawned and not just projectiles.
- Converted Berserk and Megasphere to DECORATE.
- Fixed: HealThing should respect the stamina a player has and the Dehacked
health compatibility flag if max is 0. To do that it calls P_GiveBody now.
November 1, 2006 (Changes by Graf Zahl)
- Fixed: The Cacodemon had a FastSpeed definition even though it shouldn't.
- Fixed: FastSpeed was used unconditionally when defined.

View file

@ -1656,7 +1656,8 @@ static int PatchMisc (int dummy)
}
}
// Update default item properties
// Update default item properties by patching the affected items
// Note: This won't have any effect on DECORATE derivates of these items!
ABasicArmorPickup *armor;
armor = static_cast<ABasicArmorPickup *> (GetDefaultByName ("GreenArmor"));
@ -1693,6 +1694,12 @@ static int PatchMisc (int dummy)
health->MaxAmount = deh.MaxSoulsphere;
}
health = static_cast<AHealth *> (GetDefaultByName ("MegasphereHealth"));
if (health!=NULL)
{
health->Amount = health->MaxAmount = deh.MegasphereHealth;
}
APlayerPawn *player = static_cast<APlayerPawn *> (GetDefaultByName ("DoomPlayer"));
if (player != NULL)
{

View file

@ -1,95 +0,0 @@
#include "info.h"
#include "a_pickups.h"
#include "d_player.h"
#include "p_local.h"
#include "gi.h"
#include "gstrings.h"
#include "s_sound.h"
#include "m_random.h"
#include "p_local.h"
#include "p_spec.h"
#include "p_lnspec.h"
#include "p_enemy.h"
#include "p_effect.h"
// Mega sphere --------------------------------------------------------------
class AMegasphere : public APowerupGiver
{
DECLARE_ACTOR (AMegasphere, APowerupGiver)
public:
virtual bool Use (bool pickup)
{
player_t *player = Owner->player;
ABasicArmorPickup *armor = static_cast<ABasicArmorPickup *> (Spawn ("BlueArmor", 0,0,0, NO_REPLACE));
if (!armor->TryPickup (Owner))
{
armor->Destroy ();
}
if (player->health < deh.MegasphereHealth)
{
player->health = deh.MegasphereHealth;
player->mo->health = deh.MegasphereHealth;
}
return true;
}
};
FState AMegasphere::States[] =
{
S_BRIGHT (MEGA, 'A', 6, NULL , &States[1]),
S_BRIGHT (MEGA, 'B', 6, NULL , &States[2]),
S_BRIGHT (MEGA, 'C', 6, NULL , &States[3]),
S_BRIGHT (MEGA, 'D', 6, NULL , &States[0])
};
IMPLEMENT_ACTOR (AMegasphere, Doom, 83, 132)
PROP_Flags (MF_SPECIAL|MF_COUNTITEM)
PROP_Inventory_FlagsSet (IF_AUTOACTIVATE|IF_ALWAYSPICKUP)
PROP_Inventory_MaxAmount (0)
PROP_SpawnState (0)
PROP_Inventory_PickupMessage("$GOTMSPHERE")
END_DEFAULTS
// Berserk ------------------------------------------------------------------
class ABerserk : public APowerupGiver
{
DECLARE_ACTOR (ABerserk, APowerupGiver)
public:
virtual bool Use (bool pickup)
{
P_GiveBody (Owner, 100);
if (Super::Use (pickup))
{
const PClass *fistType = PClass::FindClass ("Fist");
if (Owner->player->ReadyWeapon == NULL ||
Owner->player->ReadyWeapon->GetClass() != fistType)
{
AInventory *fist = Owner->FindInventory (fistType);
if (fist != NULL)
{
Owner->player->PendingWeapon = static_cast<AWeapon *> (fist);
}
}
return true;
}
return false;
}
};
FState ABerserk::States[] =
{
S_BRIGHT (PSTR, 'A', -1, NULL , NULL)
};
IMPLEMENT_ACTOR (ABerserk, Doom, 2023, 134)
PROP_Flags (MF_SPECIAL|MF_COUNTITEM)
PROP_SpawnState (0)
PROP_Inventory_FlagsSet (IF_AUTOACTIVATE|IF_ALWAYSPICKUP)
PROP_Inventory_MaxAmount (0)
PROP_PowerupGiver_Powerup ("PowerStrength")
PROP_Inventory_PickupMessage("$GOTBERSERK")
END_DEFAULTS

View file

@ -10,18 +10,6 @@ class ABossBrain : public AActor
DECLARE_ACTOR (ABossBrain, AActor)
};
class AExplosiveBarrel : public AActor
{
DECLARE_ACTOR (AExplosiveBarrel, AActor)
};
class ABulletPuff : public AActor
{
DECLARE_ACTOR (ABulletPuff, AActor)
public:
void BeginPlay ();
};
class ARocket : public AActor
{
DECLARE_ACTOR (ARocket, AActor)

View file

@ -9,46 +9,8 @@
#include "doomstat.h"
#include "gstrings.h"
static FRandom pr_spawnpuffx ("SpawnPuffX");
// The barrel of green goop ------------------------------------------------
void A_BarrelDestroy (AActor *);
void A_BarrelRespawn (AActor *);
FState AExplosiveBarrel::States[] =
{
#define S_BAR 0
S_NORMAL (BAR1, 'A', 6, NULL , &States[S_BAR+1]),
S_NORMAL (BAR1, 'B', 6, NULL , &States[S_BAR+0]),
#define S_BEXP (S_BAR+2)
S_BRIGHT (BEXP, 'A', 5, NULL , &States[S_BEXP+1]),
S_BRIGHT (BEXP, 'B', 5, A_Scream , &States[S_BEXP+2]),
S_BRIGHT (BEXP, 'C', 5, NULL , &States[S_BEXP+3]),
S_BRIGHT (BEXP, 'D', 10, A_Explode , &States[S_BEXP+4]),
S_BRIGHT (BEXP, 'E', 10, NULL , &States[S_BEXP+5]),
S_BRIGHT (BEXP, 'E', 1050, A_BarrelDestroy , &States[S_BEXP+6]),
S_BRIGHT (BEXP, 'E', 5, A_BarrelRespawn , &States[S_BEXP+6])
};
IMPLEMENT_ACTOR (AExplosiveBarrel, Doom, 2035, 125)
PROP_SpawnHealth (20)
PROP_RadiusFixed (10)
PROP_HeightFixed (34)
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD)
PROP_Flags2 (MF2_MCROSS)
PROP_Flags3 (MF3_DONTGIB)
PROP_Flags4 (MF4_NOICEDEATH)
PROP_Flags5 (MF5_OLDRADIUSDMG)
PROP_SpawnState (S_BAR)
PROP_DeathState (S_BEXP)
PROP_DeathSound ("world/barrelx")
PROP_Obituary("$OB_BARREL")
END_DEFAULTS
void A_BarrelDestroy (AActor *actor)
{
if ((dmflags2 & DF2_BARRELS_RESPAWN) &&
@ -64,86 +26,3 @@ void A_BarrelDestroy (AActor *actor)
}
}
void A_BarrelRespawn (AActor *actor)
{
fixed_t x = actor->SpawnPoint[0] << FRACBITS;
fixed_t y = actor->SpawnPoint[1] << FRACBITS;
sector_t *sec;
actor->flags |= MF_SOLID;
sec = R_PointInSubsector (x, y)->sector;
actor->SetOrigin (x, y, sec->floorplane.ZatPoint (x, y));
if (P_TestMobjLocation (actor))
{
AActor *defs = actor->GetDefault();
actor->health = defs->health;
actor->flags = defs->flags;
actor->flags2 = defs->flags2;
actor->SetState (actor->SpawnState);
actor->renderflags &= ~RF_INVISIBLE;
Spawn<ATeleportFog> (x, y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE);
}
else
{
actor->flags &= ~MF_SOLID;
}
}
// Bullet puff -------------------------------------------------------------
FState ABulletPuff::States[] =
{
S_BRIGHT (PUFF, 'A', 4, NULL , &States[1]),
S_NORMAL (PUFF, 'B', 4, NULL , &States[2]),
S_NORMAL (PUFF, 'C', 4, NULL , &States[3]),
S_NORMAL (PUFF, 'D', 4, NULL , NULL)
};
IMPLEMENT_ACTOR (ABulletPuff, Doom, -1, 131)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY)
PROP_Flags4 (MF4_ALLOWPARTICLES)
PROP_RenderStyle (STYLE_Translucent)
PROP_Alpha (TRANSLUC50)
PROP_SpawnState (0)
PROP_MeleeState (2)
PROP_Mass(5)
END_DEFAULTS
void ABulletPuff::BeginPlay ()
{
Super::BeginPlay ();
momz = FRACUNIT;
tics -= pr_spawnpuffx() & 3;
if (tics < 1)
tics = 1;
}
// Container for an unused state -------------------------------------------
/* Doom defined the states S_STALAG, S_DEADTORSO, and S_DEADBOTTOM but never
* actually used them. For compatibility with DeHackEd patches, they still
* need to be kept around. This actor serves that purpose.
*/
class ADoomUnusedStates : public AActor
{
DECLARE_ACTOR (ADoomUnusedStates, AActor)
};
FState ADoomUnusedStates::States[] =
{
#define S_STALAG 0
S_NORMAL (SMT2, 'A', -1, NULL , NULL),
#define S_DEADTORSO (S_STALAG+1)
S_NORMAL (PLAY, 'N', -1, NULL , NULL),
#define S_DEADBOTTOM (S_DEADTORSO+1)
S_NORMAL (PLAY, 'S', -1, NULL , NULL)
};
IMPLEMENT_ACTOR (ADoomUnusedStates, Doom, -1, 0)
PROP_DeathState (S_DEADTORSO)
END_DEFAULTS

View file

@ -89,7 +89,7 @@ void A_Punch (AActor *actor)
angle += pr_punch.Random2() << 18;
pitch = P_AimLineAttack (actor, angle, MELEERANGE);
P_LineAttack (actor, angle, MELEERANGE, pitch, damage, NAME_None, RUNTIME_CLASS(ABulletPuff));
P_LineAttack (actor, angle, MELEERANGE, pitch, damage, NAME_None, NAME_BulletPuff);
// turn to face target
if (linetarget)
@ -183,7 +183,7 @@ void A_FirePistol (AActor *actor)
S_Sound (actor, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
P_BulletSlope (actor);
P_GunShot (actor, accurate, RUNTIME_CLASS(ABulletPuff));
P_GunShot (actor, accurate, PClass::FindClass(NAME_BulletPuff));
}
// Chainsaw -----------------------------------------------------------------
@ -273,7 +273,7 @@ void A_Saw (AActor *actor)
fullsound = S_FindSound("weapons/sawfull");
hitsound = S_FindSound("weapons/sawhit");
}
if (pufftype == NULL) pufftype = RUNTIME_CLASS(ABulletPuff);
if (pufftype == NULL) pufftype = PClass::FindClass(NAME_BulletPuff);
if (damage == 0) damage = 2;
damage *= (pr_saw()%10+1);
@ -399,7 +399,7 @@ void A_FireShotgun (AActor *actor)
P_BulletSlope (actor);
for (i=0 ; i<7 ; i++)
P_GunShot (actor, false, RUNTIME_CLASS(ABulletPuff));
P_GunShot (actor, false, PClass::FindClass(NAME_BulletPuff));
}
// Super Shotgun ------------------------------------------------------------
@ -515,7 +515,7 @@ void A_FireShotgun2 (AActor *actor)
angle,
PLAYERMISSILERANGE,
bulletpitch + (pr_fireshotgun2.Random2() * 332063), damage,
NAME_None, RUNTIME_CLASS(ABulletPuff));
NAME_None, NAME_BulletPuff);
}
}
@ -629,7 +629,7 @@ void A_FireCGun (AActor *actor)
player->mo->PlayAttacking2 ();
P_BulletSlope (actor);
P_GunShot (actor, !player->refire, RUNTIME_CLASS(ABulletPuff));
P_GunShot (actor, !player->refire, PClass::FindClass(NAME_BulletPuff));
}
// Rocket launcher ---------------------------------------------------------

View file

@ -32,7 +32,7 @@ void A_PosAttack (AActor *self)
S_Sound (self, CHAN_WEAPON, "grunt/attack", 1, ATTN_NORM);
angle += pr_posattack.Random2() << 20;
damage = ((pr_posattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_None, RUNTIME_CLASS(ABulletPuff));
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_None, NAME_BulletPuff);
}
static void A_SPosAttack2 (AActor *self)
@ -49,7 +49,7 @@ static void A_SPosAttack2 (AActor *self)
{
int angle = bangle + (pr_sposattack.Random2() << 20);
int damage = ((pr_sposattack()%5)+1)*3;
P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_None, RUNTIME_CLASS(ABulletPuff));
P_LineAttack(self, angle, MISSILERANGE, slope, damage, NAME_None, NAME_BulletPuff);
}
}
@ -96,7 +96,7 @@ void A_CPosAttack (AActor *self)
angle = bangle + (pr_cposattack.Random2() << 20);
damage = ((pr_cposattack()%5)+1)*3;
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_None, RUNTIME_CLASS(ABulletPuff));
P_LineAttack (self, angle, MISSILERANGE, slope, damage, NAME_None, NAME_BulletPuff);
}
void A_CPosRefire (AActor *self)

View file

@ -204,7 +204,7 @@ void A_Tracer (AActor *self)
return;
// spawn a puff of smoke behind the rocket
P_SpawnPuff (RUNTIME_CLASS(ABulletPuff), self->x, self->y, self->z, 0, 3);
P_SpawnPuff (PClass::FindClass(NAME_BulletPuff), self->x, self->y, self->z, 0, 3);
smoke = Spawn<ARevenantTracerSmoke> (self->x - self->momx,
self->y - self->momy, self->z, ALLOW_REPLACE);

View file

@ -398,7 +398,7 @@ void A_M_Saw (AActor *self)
P_LineAttack (self, angle, MELEERANGE+1,
P_AimLineAttack (self, angle, MELEERANGE+1), damage,
NAME_Melee, RUNTIME_CLASS(ABulletPuff));
NAME_Melee, NAME_BulletPuff);
if (!linetarget)
{
@ -451,7 +451,7 @@ void A_M_Punch (AActor *self)
A_FaceTarget (self);
angle = self->angle + (pr_m_punch.Random2() << 18);
pitch = P_AimLineAttack (self, angle, MELEERANGE);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, RUNTIME_CLASS(ABulletPuff));
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff);
// turn to face target
if (linetarget)
@ -481,7 +481,7 @@ void A_M_BerserkPunch (AActor *self)
A_FaceTarget (self);
angle = self->angle + (pr_m_punch.Random2() << 18);
pitch = P_AimLineAttack (self, angle, MELEERANGE);
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, RUNTIME_CLASS(ABulletPuff));
P_LineAttack (self, angle, MELEERANGE, pitch, damage, NAME_Melee, NAME_BulletPuff);
// turn to face target
if (linetarget)
@ -527,7 +527,7 @@ void A_M_FirePistol (AActor *self)
S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, true, P_AimLineAttack (self, self->angle, MISSILERANGE),
RUNTIME_CLASS(ABulletPuff));
PClass::FindClass(NAME_BulletPuff));
}
//============================================================================
@ -544,7 +544,7 @@ void A_M_FirePistolInaccurate (AActor *self)
S_Sound (self, CHAN_WEAPON, "weapons/pistol", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, false, P_AimLineAttack (self, self->angle, MISSILERANGE),
RUNTIME_CLASS(ABulletPuff));
PClass::FindClass(NAME_BulletPuff));
}
//============================================================================
@ -565,7 +565,7 @@ void A_M_FireShotgun (AActor *self)
pitch = P_AimLineAttack (self, self->angle, MISSILERANGE);
for (int i = 0; i < 7; ++i)
{
P_GunShot2 (self, false, pitch, RUNTIME_CLASS(ABulletPuff));
P_GunShot2 (self, false, pitch, PClass::FindClass(NAME_BulletPuff));
}
self->special1 = level.maptime + 27;
}
@ -611,7 +611,7 @@ void A_M_FireShotgun2 (AActor *self)
P_LineAttack (self, angle, MISSILERANGE,
pitch + (pr_m_fireshotgun2.Random2() * 332063), damage,
NAME_None, RUNTIME_CLASS(ABulletPuff));
NAME_None, PClass::FindClass(NAME_BulletPuff));
}
self->special1 = level.maptime;
}
@ -630,7 +630,7 @@ void A_M_FireCGunAccurate (AActor *self)
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, true, P_AimLineAttack (self, self->angle, MISSILERANGE),
RUNTIME_CLASS(ABulletPuff));
PClass::FindClass(NAME_BulletPuff));
}
//============================================================================
@ -647,7 +647,7 @@ void A_M_FireCGun (AActor *self)
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
A_FaceTarget (self);
P_GunShot2 (self, false, P_AimLineAttack (self, self->angle, MISSILERANGE),
RUNTIME_CLASS(ABulletPuff));
PClass::FindClass(NAME_BulletPuff));
}
//============================================================================

View file

@ -26,9 +26,9 @@ void A_MakePod (AActor *);
// Pod ----------------------------------------------------------------------
class APod : public AExplosiveBarrel
class APod : public AActor
{
DECLARE_ACTOR (APod, AExplosiveBarrel)
DECLARE_ACTOR (APod, AActor)
HAS_OBJECT_POINTERS
public:
void BeginPlay ();

View file

@ -1762,6 +1762,7 @@ void AHexenArmor::AbsorbDamage (int damage, FName damageType, int &newdamage)
}
IMPLEMENT_STATELESS_ACTOR (AHealth, Any, -1, 0)
PROP_Inventory_Amount (1)
PROP_Inventory_MaxAmount (0)
PROP_Inventory_PickupSound ("misc/health_pkup")
END_DEFAULTS

View file

@ -342,7 +342,7 @@ void cht_DoCheat (player_t *player, int cheat)
// a very very cheap kill.
P_LineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE,
P_AimLineAttack (player->mo, player->mo->angle, PLAYERMISSILERANGE), 1000000,
NAME_None, RUNTIME_CLASS(ABulletPuff));
NAME_None, NAME_BulletPuff);
}
break;

View file

@ -32,6 +32,8 @@ xx(DoorCreak)
xx(DoorMetal2)
xx(Wind)
xx(BulletPuff)
// Special bosses A_BossDeath knows about
xx(Fatso)
xx(Arachnotron)

View file

@ -1045,11 +1045,6 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
if (target->health <= 0)
{ // Death
target->special1 = damage;
if (source && target->IsKindOf (RUNTIME_CLASS(AExplosiveBarrel))
&& !source->IsKindOf (RUNTIME_CLASS(AExplosiveBarrel)))
{ // Make sure players get frags for chain-reaction kills
target->target = source;
}
// check for special fire damage or ice damage deaths
if (mod == NAME_Fire)
{

View file

@ -978,7 +978,8 @@ FUNC(LS_HealThing)
if (max == 0 || it->player == NULL)
{
max = it->GetDefault()->health;
P_GiveBody(it, arg0);
return true;
}
else if (max == 1)
{

View file

@ -300,6 +300,7 @@ extern AActor *PuffSpawned; // points to last puff spawned
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, fixed_t vrange=0);
void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype);
void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype);
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version

View file

@ -2838,6 +2838,20 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
}
}
void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
int pitch, int damage, FName damageType, FName pufftype)
{
const PClass * type = PClass::FindClass(pufftype);
if (type == NULL)
{
Printf("Attempt to spawn unknown actor type '%s'\n", pufftype.GetChars());
}
else
{
P_LineAttack(t1, angle, distance, pitch, damage, damageType, type);
}
}
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *actor, angle_t angle, int pitch)
{
if (!cl_bloodsplats)
@ -3061,7 +3075,7 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
}
if (trace.CrossedWater)
{
AActor *puff = Spawn<ABulletPuff> (0, 0, 0, ALLOW_REPLACE);
AActor *puff = Spawn ("BulletPuff", 0, 0, 0, ALLOW_REPLACE);
if (puff != NULL)
{
SpawnDeepSplash (source, trace, puff, vx, vy, vz);
@ -3083,7 +3097,7 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
if ((RailHits[i].HitActor->flags & MF_NOBLOOD) ||
(RailHits[i].HitActor->flags2 & (MF2_DORMANT|MF2_INVULNERABLE)))
{
P_SpawnPuff (RUNTIME_CLASS(ABulletPuff), x, y, z, source->angle - ANG180, 1, true);
P_SpawnPuff (PClass::FindClass(NAME_BulletPuff), x, y, z, source->angle - ANG180, 1, true);
}
else
{

View file

@ -3106,6 +3106,15 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
FState *st = actor->SpawnState;
actor->state = st;
actor->tics = st->GetTics();
// [RH] Don't decrement tics if they are already less than 1
if ((actor->flags4 & MF4_RANDOMIZE) && actor->tics > 0)
{
actor->tics -= pr_checkmissilespawn() & 3;
if (actor->tics < 1)
actor->tics = 1;
}
actor->sprite = st->sprite.index;
actor->frame = st->GetFrame();
actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | st->GetFullbright();
@ -4194,14 +4203,6 @@ bool P_HitFloor (AActor *thing)
bool P_CheckMissileSpawn (AActor* th)
{
// [RH] Don't decrement tics if they are already less than 1
if ((th->flags4 & MF4_RANDOMIZE) && th->tics > 0)
{
th->tics -= pr_checkmissilespawn() & 3;
if (th->tics < 1)
th->tics = 1;
}
// move a little forward so an angle can be computed if it immediately explodes
if (th->Speed >= 100*FRACUNIT)
{ // Ultra-fast ripper spawning missile

View file

@ -511,6 +511,8 @@ ACTOR(CheckSkullDone)
ACTOR(RadiusThrust)
ACTOR(Stop)
ACTOR(SPosAttackUseAtkSound)
ACTOR(Respawn)
ACTOR(BarrelDestroy)
#include "d_dehackedactions.h"
@ -725,6 +727,8 @@ AFuncDesc AFTable[]=
FUNC(A_RadiusThrust, "xxy")
{"A_Explode", A_ExplodeParms, "xxy" },
FUNC(A_Stop, NULL)
FUNC(A_Respawn, "y")
FUNC(A_BarrelDestroy, NULL)
};
//==========================================================================
@ -3254,6 +3258,15 @@ static void ActorCameraheight (AActor *defaults, Baggage &bag)
bag.Info->Class->Meta.SetMetaFixed (AMETA_CameraHeight, fixed_t(sc_Float*FRACUNIT));
}
//==========================================================================
//
//==========================================================================
static void ActorVSpeed (AActor *defaults, Baggage &bag)
{
SC_MustGetFloat();
defaults->momz = fixed_t(sc_Float*FRACUNIT);
}
//==========================================================================
//
//==========================================================================
@ -4107,6 +4120,7 @@ static const ActorProps props[] =
{ "states", ActorStates, RUNTIME_CLASS(AActor) },
{ "tag", ActorTag, RUNTIME_CLASS(AActor) },
{ "translation", ActorTranslation, RUNTIME_CLASS(AActor) },
{ "vspeed", ActorVSpeed, RUNTIME_CLASS(AActor) },
{ "weapon.ammogive", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) },
{ "weapon.ammogive1", (apf)WeaponAmmoGive1, RUNTIME_CLASS(AWeapon) },
{ "weapon.ammogive2", (apf)WeaponAmmoGive2, RUNTIME_CLASS(AWeapon) },

View file

@ -369,7 +369,7 @@ void A_BulletAttack (AActor *self)
int angle = bangle + (pr_cabullet.Random2() << 20);
int damage = ((pr_cabullet()%5)+1)*3;
P_LineAttack(self, angle, MISSILERANGE, slope, damage,
GetDefaultByType(RUNTIME_CLASS(ABulletPuff))->DamageType, RUNTIME_CLASS(ABulletPuff));
NAME_None, NAME_BulletPuff);
}
}
@ -752,7 +752,7 @@ void A_CustomBulletAttack (AActor *self)
bangle = self->angle;
pufftype = PClass::FindClass(PuffType);
if (!pufftype) pufftype=RUNTIME_CLASS(ABulletPuff);
if (!pufftype) pufftype = PClass::FindClass(NAME_BulletPuff);
bslope = P_AimLineAttack (self, bangle, MISSILERANGE);
@ -855,7 +855,7 @@ void A_FireBullets (AActor *self)
bslope = bulletpitch;
PuffType = PClass::FindClass(PuffTypeName);
if (!PuffType) PuffType=RUNTIME_CLASS(ABulletPuff);
if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff);
S_SoundID (self, CHAN_WEAPON, weapon->AttackSound, 1, ATTN_NORM);
@ -977,7 +977,7 @@ void A_CustomPunch (AActor *self)
}
PuffType = PClass::FindClass(PuffTypeName);
if (!PuffType) PuffType=RUNTIME_CLASS(ABulletPuff);
if (!PuffType) PuffType = PClass::FindClass(NAME_BulletPuff);
P_LineAttack (self, angle, Range, pitch, Damage, GetDefaultByType(PuffType)->DamageType, PuffType);
@ -1383,6 +1383,7 @@ void A_SelectWeapon(AActor * actor)
else if (pStateCall != NULL) pStateCall->Result=false;
}
//===========================================================================
//
// A_Print
@ -1782,3 +1783,44 @@ void A_Stop (AActor *self)
{
self->momx = self->momy = self->momz = 0;
}
//===========================================================================
//
// A_Respawn
//
//===========================================================================
void A_Respawn (AActor *actor)
{
fixed_t x = actor->SpawnPoint[0] << FRACBITS;
fixed_t y = actor->SpawnPoint[1] << FRACBITS;
sector_t *sec;
actor->flags |= MF_SOLID;
sec = R_PointInSubsector (x, y)->sector;
actor->SetOrigin (x, y, sec->floorplane.ZatPoint (x, y));
actor->height = actor->GetDefault()->height;
if (P_TestMobjLocation (actor))
{
AActor *defs = actor->GetDefault();
actor->health = defs->health;
actor->flags = (defs->flags & ~MF_FRIENDLY) | (actor->flags & MF_FRIENDLY);
actor->flags2 = defs->flags2;
actor->flags3 = (defs->flags3 & ~(MF3_NOSIGHTCHECK | MF3_HUNTPLAYERS)) | (actor->flags3 & (MF3_NOSIGHTCHECK | MF3_HUNTPLAYERS));
actor->flags4 = (defs->flags4 & ~MF4_NOHATEPLAYERS) | (actor->flags4 & MF4_NOHATEPLAYERS);
actor->flags5 = defs->flags5;
actor->SetState (actor->SpawnState);
actor->renderflags &= ~RF_INVISIBLE;
int index=CheckIndex(1, NULL);
if (index<0 || EvalExpressionN (StateParameters[index+2], actor))
{
Spawn<ATeleportFog> (x, y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE);
}
}
else
{
actor->flags &= ~MF_SOLID;
}
}

View file

@ -15,6 +15,7 @@
#include "actors/doom/doomartifacts.txt"
#include "actors/doom/doomhealth.txt"
#include "actors/doom/doomkeys.txt"
#include "actors/doom/doommisc.txt"
#include "actors/doom/doomdecorations.txt"
#include "actors/doom/stealthmonsters.txt"

View file

@ -42,6 +42,34 @@ ACTOR Soulsphere : Health 2013
}
}
// Mega sphere --------------------------------------------------------------
ACTOR MegasphereHealth : Health // for manipulation by Dehacked
{
Inventory.Amount 200
Inventory.MaxAmount 200
+INVENTORY.ALWAYSPICKUP
}
ACTOR Megasphere : CustomInventory 83
{
Game Doom
SpawnID 132
+COUNTITEM
+INVENTORY.ALWAYSPICKUP
Inventory.PickupMessage "$GOTMSPHERE"
States
{
Spawn:
MEGA ABCD 6 BRIGHT
Loop
Pickup:
TNT1 A 0 A_GiveInventory("BlueArmor", 1)
TNT1 A 0 A_GiveInventory("MegasphereHealth", 1)
Stop
}
}
// Invisibility -------------------------------------------------------------
ACTOR BlurSphere : PowerupGiver 2024
@ -126,3 +154,25 @@ ACTOR Allmap : MapRevealer 2026
}
}
// Berserk ------------------------------------------------------------------
ACTOR Berserk : CustomInventory 2023
{
Game Doom
SpawnID 134
+COUNTITEM
+INVENTORY.ALWAYSPICKUP
Inventory.PickupMessage "$GOTBERSERK"
States
{
Spawn:
PSTR A -1
Stop
Pickup:
TNT1 A 0 A_GiveInventory("PowerStrength")
TNT1 A 0 HealThing(100, 0)
TNT1 A 0 A_SelectWeapon("Fist")
Stop
}
}

View file

@ -0,0 +1,77 @@
// The barrel of green goop ------------------------------------------------
ACTOR ExplosiveBarrel 2035
{
Game Doom
SpawnID 125
Health 20
Radius 10
Height 34
+SOLID
+SHOOTABLE
+NOBLOOD
+ACTIVATEMCROSS
+DONTGIB
+NOICEDEATH
+OLDRADIUSDMG
DeathSound "world/barrelx"
Obituary "$OB_BARREL"
States
{
Spawn:
BAR1 AB 6
Loop
Death:
BEXP A 5 BRIGHT
BEXP B 5 BRIGHT A_Scream
BEXP C 5 BRIGHT
BEXP D 5 BRIGHT A_Explode
BEXP E 10 BRIGHT
BEXP E 1050 BRIGHT A_BarrelDestroy
BEXP E 5 A_Respawn
Wait
}
}
// Bullet puff -------------------------------------------------------------
ACTOR BulletPuff
{
Game Doom
SpawnID 131
+NOBLOCKMAP
+NOGRAVITY
+ALLOWPARTICLES
+RANDOMIZE
RenderStyle Translucent
Alpha 0.5
VSpeed 1
Mass 5
States
{
Spawn:
PUFF A 4 Bright
PUFF B 4
Melee:
PUFF CD 4
Stop
}
}
// Container for an unused state -------------------------------------------
/* Doom defined the states S_STALAG, S_DEADTORSO, and S_DEADBOTTOM but never
* actually used them. For compatibility with DeHackEd patches, they still
* need to be kept around. This actor serves that purpose.
*/
ACTOR DoomUnusedStates
{
States
{
SMT2 A -1
Death:
PLAY N -1
PLAY S -1
}
}

View file

@ -258,6 +258,7 @@ actors/doom/doomarmor.txt decorate/doom/doomarmor.txt
actors/doom/doomartifacts.txt decorate/doom/doomartifacts.txt
actors/doom/doomhealth.txt decorate/doom/doomhealth.txt
actors/doom/doomkeys.txt decorate/doom/doomkeys.txt
actors/doom/doommisc.txt decorate/doom/doommisc.txt
actors/doom/doomdecorations.txt decorate/doom/doomdecorations.txt
actors/doom/stealthmonsters.txt decorate/doom/stealthmonsters.txt

File diff suppressed because it is too large Load diff