- moved common code of Raven's fast projectiles into a base class

called FastProjectile. This base class doesn't have any effects attached
  so that it can be used for user defined fast projectiles.


SVN r1290 (trunk)
This commit is contained in:
Christoph Oelckers 2008-11-15 09:57:18 +00:00
parent 3b4479df44
commit 4d991de92d
11 changed files with 152 additions and 222 deletions

View file

@ -1,3 +1,8 @@
November 15, 2008 (Changes by Graf Zahl)
- moved common code of Raven's fast projectiles into a base class
called FastProjectile. This base class doesn't have any effects attached
so that it can be used for user defined fast projectiles.
November 14, 2008
- Removed GC barriers from the sound channels. If we must, we can always
do it the old way and scan every channel to see if it matches an actor/

View file

@ -695,15 +695,20 @@ boom:
// Blaster FX 1 -------------------------------------------------------------
class ABlasterFX1 : public AActor
//----------------------------------------------------------------------------
//
// Thinker for the ultra-fast blaster PL2 ripper-spawning missile.
//
//----------------------------------------------------------------------------
class ABlasterFX1 : public AFastProjectile
{
DECLARE_CLASS(ABlasterFX1, AActor)
DECLARE_CLASS(ABlasterFX1, AFastProjectile)
public:
void Tick ();
void Effect ();
int DoSpecialDamage (AActor *target, int damage);
};
int ABlasterFX1::DoSpecialDamage (AActor *target, int damage)
{
if (target->IsKindOf (PClass::FindClass ("Ironlich")))
@ -717,10 +722,19 @@ int ABlasterFX1::DoSpecialDamage (AActor *target, int damage)
return damage;
}
void ABlasterFX1::Effect ()
{
if (pr_bfx1t() < 64)
{
Spawn("BlasterSmoke", x, y, MAX<fixed_t> (z - 8 * FRACUNIT, floorz), ALLOW_REPLACE);
}
}
IMPLEMENT_CLASS(ABlasterFX1)
// Ripper -------------------------------------------------------------------
class ARipper : public AActor
{
DECLARE_CLASS (ARipper, AActor)
@ -802,77 +816,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnRippers)
}
}
//----------------------------------------------------------------------------
//
// PROC P_BlasterMobjThinker
//
// Thinker for the ultra-fast blaster PL2 ripper-spawning missile.
//
//----------------------------------------------------------------------------
void ABlasterFX1::Tick ()
{
int i;
fixed_t xfrac;
fixed_t yfrac;
fixed_t zfrac;
int changexy;
PrevX = x;
PrevY = y;
PrevZ = z;
// Handle movement
if (momx || momy || (z != floorz) || momz)
{
xfrac = momx>>3;
yfrac = momy>>3;
zfrac = momz>>3;
changexy = xfrac | yfrac;
for (i = 0; i < 8; i++)
{
if (changexy)
{
if (!P_TryMove (this, x + xfrac, y + yfrac, true))
{ // Blocked move
P_ExplodeMissile (this, BlockingLine, BlockingMobj);
return;
}
}
z += zfrac;
if (z <= floorz)
{ // Hit the floor
z = floorz;
P_HitFloor (this);
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (z + height > ceilingz)
{ // Hit the ceiling
z = ceilingz - height;
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (changexy && (pr_bfx1t() < 64))
{
Spawn("BlasterSmoke", x, y, MAX<fixed_t> (z - 8 * FRACUNIT, floorz), ALLOW_REPLACE);
}
}
}
// Advance the state
if (tics != -1)
{
tics--;
while (!tics)
{
if (!SetState (state->GetNextState ()))
{ // mobj was removed
return;
}
}
}
}
// --- Skull rod ------------------------------------------------------------

View file

@ -26,12 +26,12 @@ void A_CFlameMissile (AActor *);
// Flame Missile ------------------------------------------------------------
class ACFlameMissile : public AActor
class ACFlameMissile : public AFastProjectile
{
DECLARE_CLASS (ACFlameMissile, AActor)
DECLARE_CLASS (ACFlameMissile, AFastProjectile)
public:
void BeginPlay ();
void Tick ();
void Effect ();
};
IMPLEMENT_CLASS (ACFlameMissile)
@ -41,80 +41,22 @@ void ACFlameMissile::BeginPlay ()
special1 = 2;
}
void ACFlameMissile::Tick ()
void ACFlameMissile::Effect ()
{
int i;
fixed_t xfrac;
fixed_t yfrac;
fixed_t zfrac;
fixed_t newz;
bool changexy;
AActor *mo;
PrevX = x;
PrevY = y;
PrevZ = z;
// Handle movement
if (momx || momy || (z != floorz) || momz)
if (!--special1)
{
xfrac = momx>>3;
yfrac = momy>>3;
zfrac = momz>>3;
changexy = xfrac || yfrac;
for (i = 0; i < 8; i++)
special1 = 4;
newz = z-12*FRACUNIT;
if (newz < floorz)
{
if (changexy)
{
if (!P_TryMove (this, x+xfrac, y+yfrac, true))
{ // Blocked move
P_ExplodeMissile (this, BlockingLine, BlockingMobj);
return;
}
}
z += zfrac;
if (z <= floorz)
{ // Hit the floor
z = floorz;
P_HitFloor (this);
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (z+height > ceilingz)
{ // Hit the ceiling
z = ceilingz-height;
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (changexy)
{
if (!--special1)
{
special1 = 4;
newz = z-12*FRACUNIT;
if (newz < floorz)
{
newz = floorz;
}
mo = Spawn ("CFlameFloor", x, y, newz, ALLOW_REPLACE);
if (mo)
{
mo->angle = angle;
}
}
}
newz = floorz;
}
}
// Advance the state
if (tics != -1)
{
tics--;
while (!tics)
AActor *mo = Spawn ("CFlameFloor", x, y, newz, ALLOW_REPLACE);
if (mo)
{
if (!SetState (state->GetNextState ()))
{ // mobj was removed
return;
}
mo->angle = angle;
}
}
}

View file

@ -19,89 +19,27 @@ void A_MWandAttack (AActor *actor);
// Wand Missile -------------------------------------------------------------
class AMageWandMissile : public AActor
class AMageWandMissile : public AFastProjectile
{
DECLARE_CLASS(AMageWandMissile, AActor)
DECLARE_CLASS(AMageWandMissile, AFastProjectile)
public:
void Tick ();
void Effect ();
};
IMPLEMENT_CLASS (AMageWandMissile)
void AMageWandMissile::Tick ()
void AMageWandMissile::Effect ()
{
int i;
fixed_t xfrac;
fixed_t yfrac;
fixed_t zfrac;
fixed_t hitz;
bool changexy;
PrevX = x;
PrevY = y;
PrevZ = z;
// [RH] Ripping is a little different than it was in Hexen
FCheckPosition tm(!!(flags2 & MF2_RIP));
// Handle movement
if (momx || momy || (z != floorz) || momz)
//if (pr_smoke() < 128) // [RH] I think it looks better if it's consistent
{
xfrac = momx>>3;
yfrac = momy>>3;
zfrac = momz>>3;
changexy = xfrac || yfrac;
for (i = 0; i < 8; i++)
hitz = z-8*FRACUNIT;
if (hitz < floorz)
{
if (changexy)
{
tm.LastRipped = NULL; // [RH] Do rip damage each step, like Hexen
if (!P_TryMove (this, x+xfrac,y+yfrac, true, false, tm))
{ // Blocked move
P_ExplodeMissile (this, BlockingLine, BlockingMobj);
return;
}
}
z += zfrac;
if (z <= floorz)
{ // Hit the floor
z = floorz;
P_HitFloor (this);
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (z+height > ceilingz)
{ // Hit the ceiling
z = ceilingz-height;
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (changexy)
{
//if (pr_smoke() < 128) // [RH] I think it looks better if it's consistant
{
hitz = z-8*FRACUNIT;
if (hitz < floorz)
{
hitz = floorz;
}
Spawn ("MageWandSmoke", x, y, hitz, ALLOW_REPLACE);
}
}
}
}
// Advance the state
if (tics != -1)
{
tics--;
while (!tics)
{
if (!SetState (state->GetNextState()))
{ // actor was removed
return;
}
hitz = floorz;
}
Spawn ("MageWandSmoke", x, y, hitz, ALLOW_REPLACE);
}
}

View file

@ -0,0 +1,85 @@
#include "a_sharedglobal.h"
#include "p_local.h"
IMPLEMENT_CLASS(AFastProjectile)
//----------------------------------------------------------------------------
//
// AFastProjectile :: Tick
//
// Thinker for the ultra-fast projectiles used by Heretic and Hexen
//
//----------------------------------------------------------------------------
void AFastProjectile::Tick ()
{
int i;
fixed_t xfrac;
fixed_t yfrac;
fixed_t zfrac;
int changexy;
PrevX = x;
PrevY = y;
PrevZ = z;
// [RH] Ripping is a little different than it was in Hexen
FCheckPosition tm(!!(flags2 & MF2_RIP));
// Handle movement
if (momx || momy || (z != floorz) || momz)
{
xfrac = momx>>3;
yfrac = momy>>3;
zfrac = momz>>3;
changexy = xfrac || yfrac;
for (i = 0; i < 8; i++)
{
if (changexy)
{
tm.LastRipped = NULL; // [RH] Do rip damage each step, like Hexen
if (!P_TryMove (this, x + xfrac,y + yfrac, true, false, tm))
{ // Blocked move
P_ExplodeMissile (this, BlockingLine, BlockingMobj);
return;
}
}
z += zfrac;
if (z <= floorz)
{ // Hit the floor
z = floorz;
P_HitFloor (this);
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (z + height > ceilingz)
{ // Hit the ceiling
z = ceilingz - height;
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (changexy) Effect();
}
}
// Advance the state
if (tics != -1)
{
tics--;
while (!tics)
{
if (!SetState (state->GetNextState ()))
{ // mobj was removed
return;
}
}
}
}
void AFastProjectile::Effect()
{
}

View file

@ -179,4 +179,13 @@ public:
void Deactivate (AActor *activator);
};
class AFastProjectile : public AActor
{
DECLARE_CLASS(AFastProjectile, AActor)
public:
void Tick ();
virtual void Effect();
};
#endif //__A_SHAREDGLOBAL_H__

View file

@ -722,13 +722,12 @@ ACTOR BlasterPowered : Blaster
// Blaster FX 1 -------------------------------------------------------------
ACTOR BlasterFX1 native
ACTOR BlasterFX1 : FastProjectile native
{
Radius 12
Height 8
Speed 184
Damage 2
Projectile
SeeSound "weapons/blastershoot"
DeathSound "weapons/blasterhit"
+SPAWNSOUNDSOURCE

View file

@ -157,14 +157,13 @@ ACTOR CircleFlame
// Flame Missile ------------------------------------------------------------
ACTOR CFlameMissile native
ACTOR CFlameMissile : FastProjectile native
{
Speed 200
Radius 14
Height 8
Damage 8
DamageType "Fire"
Projectile
+INVISIBLE
RenderStyle Add

View file

@ -44,13 +44,12 @@ ACTOR MageWandSmoke
// Wand Missile -------------------------------------------------------------
ACTOR MageWandMissile native
ACTOR MageWandMissile : FastProjectile native
{
Speed 184
Radius 12
Height 8
Damage 2
Projectile
+RIPPER +CANNOTPUSH +NODAMAGETHRUST
SeeSound "MageWandFire"
States

View file

@ -139,4 +139,11 @@ ACTOR RandomSpawner native
+NOGRAVITY
}
// Fast projectiles -----------------------------------------------------------
ACTOR FastProjectile native
{
Projectile
}

View file

@ -2052,6 +2052,10 @@
RelativePath=".\src\g_shared\a_decals.cpp"
>
</File>
<File
RelativePath=".\src\g_shared\a_fastprojectile.cpp"
>
</File>
<File
RelativePath=".\src\g_shared\a_flashfader.cpp"
>