- Added Gez's A_Blast submission.

SVN r1886 (trunk)
This commit is contained in:
Christoph Oelckers 2009-09-28 15:55:57 +00:00
parent f2c77c5f08
commit 6d357b84b4
7 changed files with 142 additions and 146 deletions

View file

@ -1,3 +1,6 @@
September 28, 2009 (Changes by Graf Zahl)
- Added Gez's A_Blast submission.
September 27, 2009 (Changes by Graf Zahl) September 27, 2009 (Changes by Graf Zahl)
- Fixed: Floor and ceiling huggers' velocity was wrong when used with - Fixed: Floor and ceiling huggers' velocity was wrong when used with
P_SpawnPlayerMissile. P_SpawnPlayerMissile.

View file

@ -8,87 +8,21 @@
#include "s_sound.h" #include "s_sound.h"
*/ */
/* For reference, the default values:
#define BLAST_RADIUS_DIST 255*FRACUNIT #define BLAST_RADIUS_DIST 255*FRACUNIT
#define BLAST_SPEED 20*FRACUNIT #define BLAST_SPEED 20*FRACUNIT
#define BLAST_FULLSTRENGTH 255 #define BLAST_FULLSTRENGTH 255
*/
// Disc of Repulsion -------------------------------------------------------- // Disc of Repulsion --------------------------------------------------------
class AArtiBlastRadius : public AInventory
{
DECLARE_CLASS (AArtiBlastRadius, AInventory)
public:
bool Use (bool pickup);
protected:
void BlastActor (AActor *victim, fixed_t strength);
};
IMPLEMENT_CLASS (AArtiBlastRadius)
//==========================================================================
//
// AArtiBlastRadius :: Activate
//
// Blast all actors away
//
//==========================================================================
bool AArtiBlastRadius::Use (bool pickup)
{
AActor *mo;
TThinkerIterator<AActor> iterator;
fixed_t dist;
S_Sound (Owner, CHAN_AUTO, "BlastRadius", 1, ATTN_NORM);
P_NoiseAlert (Owner, Owner);
while ( (mo = iterator.Next ()) )
{
if ((mo == Owner) || (mo->flags2 & MF2_BOSS))
{ // Not a valid monster
continue;
}
if ((mo->flags & MF_ICECORPSE) || (mo->flags3 & MF3_CANBLAST))
{
// Let these special cases go
}
else if ((mo->flags3 & MF3_ISMONSTER) && (mo->health <= 0))
{
continue;
}
else if (!(mo->flags3 & MF3_ISMONSTER) &&
!(mo->player) &&
!(mo->flags & MF_MISSILE) &&
!(mo->flags3 & MF3_CANBLAST) &&
!(mo->flags6 & MF6_TOUCHY))
{ // Must be monster, player, missile, or touchy
continue;
}
if (mo->flags2 & MF2_DORMANT)
{
continue; // no dormant creatures
}
if (mo->flags3 & MF3_DONTBLAST)
{ // A few things that would normally be blastable should not be blasted
continue;
}
dist = P_AproxDistance (Owner->x - mo->x, Owner->y - mo->y);
if (dist > BLAST_RADIUS_DIST)
{ // Out of range
continue;
}
BlastActor (mo, BLAST_FULLSTRENGTH);
}
return true;
}
//========================================================================== //==========================================================================
// //
// AArtiBlastRadius :: BlastActor // AArtiBlastRadius :: BlastActor
// //
//========================================================================== //==========================================================================
void AArtiBlastRadius::BlastActor (AActor *victim, fixed_t strength) void BlastActor (AActor *victim, fixed_t strength, fixed_t speed, AActor * Owner, const PClass * blasteffect)
{ {
angle_t angle,ang; angle_t angle,ang;
AActor *mo; AActor *mo;
@ -101,72 +35,116 @@ void AArtiBlastRadius::BlastActor (AActor *victim, fixed_t strength)
angle = R_PointToAngle2 (Owner->x, Owner->y, victim->x, victim->y); angle = R_PointToAngle2 (Owner->x, Owner->y, victim->x, victim->y);
angle >>= ANGLETOFINESHIFT; angle >>= ANGLETOFINESHIFT;
if (strength < BLAST_FULLSTRENGTH) victim->velx = FixedMul (speed, finecosine[angle]);
victim->vely = FixedMul (speed, finesine[angle]);
// Spawn blast puff
ang = R_PointToAngle2 (victim->x, victim->y, Owner->x, Owner->y);
ang >>= ANGLETOFINESHIFT;
x = victim->x + FixedMul (victim->radius+FRACUNIT, finecosine[ang]);
y = victim->y + FixedMul (victim->radius+FRACUNIT, finesine[ang]);
z = victim->z - victim->floorclip + (victim->height>>1);
mo = Spawn (blasteffect, x, y, z, ALLOW_REPLACE);
if (mo)
{ {
victim->velx = FixedMul (strength, finecosine[angle]); mo->velx = victim->velx;
victim->vely = FixedMul (strength, finesine[angle]); mo->vely = victim->vely;
if (victim->player) }
if (victim->flags & MF_MISSILE)
{
// [RH] Floor and ceiling huggers should not be blasted vertically.
if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER)))
{ {
// Players handled automatically victim->velz = 8*FRACUNIT;
} mo->velz = victim->velz;
else
{
victim->flags2 |= MF2_BLASTED;
} }
} }
else // full strength blast from artifact else
{ {
if (victim->flags & MF_MISSILE) victim->velz = (1000 / victim->Mass) << FRACBITS;
{ }
#if 0 if (victim->player)
if (victim->IsKindOf (RUNTIME_CLASS(AMageStaffFX2))) {
{ // Reflect to originator // Players handled automatically
victim->special1 = (int)victim->target; }
victim->target = Owner; else
} {
#endif victim->flags2 |= MF2_BLASTED;
} }
victim->velx = FixedMul (BLAST_SPEED, finecosine[angle]); if (victim->flags6 & MF6_TOUCHY)
victim->vely = FixedMul (BLAST_SPEED, finesine[angle]); { // Touchy objects die when blasted
victim->flags6 &= ~MF6_ARMED; // Disarm
// Spawn blast puff P_DamageMobj(victim, Owner, Owner, victim->health, NAME_Melee, DMG_FORCED);
ang = R_PointToAngle2 (victim->x, victim->y, Owner->x, Owner->y); }
ang >>= ANGLETOFINESHIFT; }
x = victim->x + FixedMul (victim->radius+FRACUNIT, finecosine[ang]);
y = victim->y + FixedMul (victim->radius+FRACUNIT, finesine[ang]); enum
z = victim->z - victim->floorclip + (victim->height>>1); {
mo = Spawn ("BlastEffect", x, y, z, ALLOW_REPLACE); BF_USEAMMO = 1,
if (mo) BF_DONTWARN = 2,
{ BF_AFFECTBOSSES = 4,
mo->velx = victim->velx; };
mo->vely = victim->vely;
} //==========================================================================
//
if (victim->flags & MF_MISSILE) // AArtiBlastRadius :: Activate
{ //
// [RH] Floor and ceiling huggers should not be blasted vertically. // Blast all actors away
if (!(victim->flags3 & (MF3_FLOORHUGGER|MF3_CEILINGHUGGER))) //
{ //==========================================================================
victim->velz = 8*FRACUNIT;
mo->velz = victim->velz; DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
} {
} ACTION_PARAM_START(6);
else ACTION_PARAM_INT (blastflags, 0);
{ ACTION_PARAM_FIXED(strength, 1);
victim->velz = (1000 / victim->Mass) << FRACBITS; ACTION_PARAM_FIXED(radius, 2);
} ACTION_PARAM_FIXED(speed, 3);
if (victim->player) ACTION_PARAM_CLASS(blasteffect, 4);
{ ACTION_PARAM_SOUND(blastsound, 5);
// Players handled automatically
} AActor *mo;
else TThinkerIterator<AActor> iterator;
{ fixed_t dist;
victim->flags2 |= MF2_BLASTED;
} if (self->player && (blastflags & BF_USEAMMO))
if (victim->flags6 & MF6_TOUCHY) {
{ // Touchy objects die when blasted AWeapon * weapon = self->player->ReadyWeapon;
victim->flags6 &= ~MF6_ARMED; // Disarm if (!weapon->DepleteAmmo(weapon->bAltFire))
P_DamageMobj(victim, Owner, Owner, victim->health, NAME_Melee, DMG_FORCED); return;
} }
S_Sound (self, CHAN_AUTO, blastsound, 1, ATTN_NORM);
if (!(blastflags & BF_DONTWARN)) P_NoiseAlert (self, self);
while ( (mo = iterator.Next ()) )
{
if ((mo == self) || ((mo->flags2 & MF2_BOSS) && !(blastflags & BF_AFFECTBOSSES))
|| (mo->flags2 & MF2_DORMANT) || (mo->flags3 & MF3_DONTBLAST))
{ // Not a valid monster: originator, boss, dormant, or otherwise protected
continue;
}
if ((mo->flags & MF_ICECORPSE) || (mo->flags3 & MF3_CANBLAST))
{
// Let these special cases go
}
else if ((mo->flags3 & MF3_ISMONSTER) && (mo->health <= 0))
{
continue;
}
else if (!(mo->player) &&
!(mo->flags & MF_MISSILE) &&
!(mo->flags3 & (MF3_ISMONSTER|MF3_CANBLAST)) &&
!(mo->flags6 & (MF6_TOUCHY|MF6_VULNERABLE)))
{ // Must be monster, player, missile, touchy or vulnerable
continue;
}
dist = P_AproxDistance (self->x - mo->x, self->y - mo->y);
if (dist > radius)
{ // Out of range
continue;
}
BlastActor (mo, strength, speed, self, blasteffect);
} }
} }

View file

@ -227,6 +227,7 @@ ACTOR Actor native //: Thinker
action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true); action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true);
action native A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true); action native A_CustomComboAttack(class<Actor> missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true);
action native A_Burst(class<Actor> chunktype); action native A_Burst(class<Actor> chunktype);
action native A_Blast(int flags = 0, int strength = 255, int radius = 255, float speed = 20, class<Actor> blasteffect = "BlastEffect", sound blastsound = "BlastRadius");
action native A_RadiusThrust(int force = 128, int distance = -1, bool affectsource = true); action native A_RadiusThrust(int force = 128, int distance = -1, bool affectsource = true);
action native A_Explode(int damage = -1, int distance = -1, bool hurtsource = true, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10); action native A_Explode(int damage = -1, int distance = -1, bool hurtsource = true, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10);
action native A_Stop(); action native A_Stop();

View file

@ -71,6 +71,11 @@ const int RGF_NOPIERCING = 2;
const int MSF_Standard = 0; const int MSF_Standard = 0;
const int MSF_Classic = 1; const int MSF_Classic = 1;
// Flags for A_Blast
const int BF_USEAMMO = 1;
const int BF_DONTWARN = 2;
const int BF_AFFECTBOSSES = 4;
// Activation flags // Activation flags
enum enum
{ {
@ -82,6 +87,14 @@ enum
THINGSPEC_MissileTrigger = 16, THINGSPEC_MissileTrigger = 16,
THINGSPEC_ClearSpecial = 32, THINGSPEC_ClearSpecial = 32,
}; };
// Shorter aliases for same
const int AF_Default = 0;
const int AF_ThingActs = 1;
const int AF_ThingTargets = 2;
const int AF_TriggerTargets = 4;
const int AF_MonsterTrigger = 8;
const int AF_MissileTrigger = 16;
const int AF_ClearSpecial = 32;
// constants for A_PlaySound // constants for A_PlaySound
enum enum

View file

@ -1,5 +1,5 @@
ACTOR ArtiBlastRadius : Inventory 10110 native ACTOR ArtiBlastRadius : CustomInventory 10110
{ {
Game Hexen Game Hexen
SpawnID 74 SpawnID 74
@ -15,6 +15,8 @@ ACTOR ArtiBlastRadius : Inventory 10110 native
Spawn: Spawn:
BLST ABCDEFGH 4 Bright BLST ABCDEFGH 4 Bright
Loop Loop
Use:
TNT1 A 0 A_Blast
} }
} }

View file

@ -1,20 +1,19 @@
ACTOR MBFHelperDog 888 ACTOR MBFHelperDog 888
{ {
Game Doom
Health 500 Health 500
Speed 10 Speed 10
PainChance 180 PainChance 180
Radius 12 Radius 12
Height 28 Height 28
Mass 100 Mass 100
Monster Monster
+JUMPDOWN +JUMPDOWN
ActiveSound "dog/active" ActiveSound "dog/active"
AttackSound "dog/attack" AttackSound "dog/attack"
DeathSound "dog/death" DeathSound "dog/death"
PainSound "dog/pain" PainSound "dog/pain"
SeeSound "dog/sight" SeeSound "dog/sight"
Obituary "$OB_DOG" Obituary "$OB_DOG"
States States
{ {
Spawn: Spawn:

View file

@ -28,6 +28,7 @@
#include "actors/shared/setcolor.txt" #include "actors/shared/setcolor.txt"
#include "actors/shared/sectoraction.txt" #include "actors/shared/sectoraction.txt"
#include "actors/shared/action.txt" #include "actors/shared/action.txt"
#include "actors/shared/dog.txt"
#include "actors/doom/doomplayer.txt" #include "actors/doom/doomplayer.txt"
#include "actors/doom/possessed.txt" #include "actors/doom/possessed.txt"
@ -45,7 +46,6 @@
#include "actors/doom/spidermaster.txt" #include "actors/doom/spidermaster.txt"
#include "actors/doom/keen.txt" #include "actors/doom/keen.txt"
#include "actors/doom/bossbrain.txt" #include "actors/doom/bossbrain.txt"
#include "actors/doom/dog.txt"
#include "actors/doom/deadthings.txt" #include "actors/doom/deadthings.txt"
#include "actors/doom/doomammo.txt" #include "actors/doom/doomammo.txt"