mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-29 15:22:08 +00:00
- More things from Gez's experimental build:
* info CCMD to print extended actor information (not fully implemented yet) * summonmbf CCMD. * Beta BFG code pointer (but not the related missiles yet.) * PowerInvisibility enhancements. * ScoreItem with one significant change: Added a score variable that can be checked through ACS and DECORATE. The engine itself will do nothing with it. * Nailgun option for A_Explode. * A_PrintBold and A_Log. * A_SetSpecial. SVN r1819 (trunk)
This commit is contained in:
parent
914d993aa1
commit
238d4c3fac
34 changed files with 564 additions and 110 deletions
|
@ -1,5 +1,14 @@
|
|||
September 14, 2009 (Changes by Graf Zahl)
|
||||
- Added a few things from Gez's experimental build:
|
||||
* info CCMD to print extended actor information (not fully implemented yet)
|
||||
* summonmbf CCMD.
|
||||
* Beta BFG code pointer (but not the related missiles yet.)
|
||||
* PowerInvisibility enhancements.
|
||||
* ScoreItem with one significant change: Added a score variable that can be
|
||||
checked through ACS and DECORATE. The engine itself will do nothing with it.
|
||||
* Nailgun option for A_Explode.
|
||||
* A_PrintBold and A_Log.
|
||||
* A_SetSpecial.
|
||||
* Beta Lost Soul (added DoomEdNum 9037 to it)
|
||||
* A_Mushroom extensions
|
||||
* Vavoom compatible MAPINFO keynames.
|
||||
|
|
|
@ -107,7 +107,6 @@ DEFINE_SPECIAL(Light_Stop, 117, 1, 1, 1)
|
|||
DEFINE_SPECIAL(Thing_Damage, 119, 2, 3, 3)
|
||||
DEFINE_SPECIAL(Radius_Quake, 120, 5, 5, 5) // Earthquake
|
||||
DEFINE_SPECIAL(Line_SetIdentification, 121, -1, -1, 5)
|
||||
|
||||
#if 0 // Skull Tag specials that might be added later
|
||||
Thing_SetGravity, 122, -1, -1)
|
||||
Thing_ReverseGravity, 123, -1, -1)
|
||||
|
@ -140,7 +139,7 @@ DEFINE_SPECIAL(Teleport_NoStop, 154, 2, 3, 3)
|
|||
DEFINE_SPECIAL(FS_Execute, 158, 1, 4, 4)
|
||||
DEFINE_SPECIAL(Sector_SetPlaneReflection, 159, 3, 3, 3)
|
||||
DEFINE_SPECIAL(Sector_Set3DFloor, 160, -1, -1, 5)
|
||||
DEFINE_SPECIAL(Sector_SetContents, 161, -1, -1, 5) // It probably doesn't use 5 args. Oh well.
|
||||
DEFINE_SPECIAL(Sector_SetContents, 161, -1, -1, 3)
|
||||
|
||||
// [RH] Begin new specials for ZDoom
|
||||
DEFINE_SPECIAL(Generic_Crusher2, 169, 5, 5, 5)
|
||||
|
|
40
src/actor.h
40
src/actor.h
|
@ -262,6 +262,8 @@ enum
|
|||
MF4_FRIGHTENED = 0x40000000, // Monster runs away from player
|
||||
/* = 0x80000000, */
|
||||
|
||||
// --- mobj.flags5 ---
|
||||
|
||||
MF5_FASTER = 0x00000001, // moves faster when DF_FAST_MONSTERS or nightmare is on.
|
||||
MF5_FASTMELEE = 0x00000002, // has a faster melee attack when DF_FAST_MONSTERS or nightmare is on.
|
||||
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
|
||||
|
@ -296,6 +298,8 @@ enum
|
|||
MF5_PAINLESS = 0x40000000, // Actor always inflicts painless damage.
|
||||
MF5_MOVEWITHSECTOR = 0x80000000, // P_ChangeSector() will still process this actor if it has MF_NOBLOCKMAP
|
||||
|
||||
// --- mobj.flags6 ---
|
||||
|
||||
MF6_NOBOSSRIP = 0x00000001, // For rippermissiles: Don't rip through bosses.
|
||||
MF6_THRUSPECIES = 0x00000002, // Actors passes through other of the same species.
|
||||
MF6_MTHRUSPECIES = 0x00000004, // Missile passes through actors of its shooter's species.
|
||||
|
@ -369,7 +373,7 @@ enum replace_t
|
|||
ALLOW_REPLACE = 1
|
||||
};
|
||||
|
||||
enum EBounceType
|
||||
enum EBounceFlags
|
||||
{
|
||||
BOUNCE_Walls = 1<<0, // bounces off of walls
|
||||
BOUNCE_Floors = 1<<1, // bounces off of floors
|
||||
|
@ -377,7 +381,7 @@ enum EBounceType
|
|||
BOUNCE_Actors = 1<<3, // bounces off of some actors
|
||||
BOUNCE_AllActors = 1<<4, // bounces off of all actors (requires BOUNCE_Actors to be set, too)
|
||||
BOUNCE_AutoOff = 1<<5, // when bouncing off a floor, if the new Z velocity is below 3.0, disable further bouncing
|
||||
BOUNCE_HereticType = 1<<6, // only works with floors and ceilings; you probably don't want to use it
|
||||
BOUNCE_HereticType = 1<<6, // goes into Death state when bouncing on floors or ceilings
|
||||
|
||||
BOUNCE_UseSeeSound = 1<<7, // compatibility fallback. This will only be set by
|
||||
// the compatibility handlers for the old bounce flags.
|
||||
|
@ -385,6 +389,9 @@ enum EBounceType
|
|||
BOUNCE_Quiet = 1<<9, // Strife's grenades don't make a bouncing sound
|
||||
BOUNCE_ExplodeOnWater = 1<<10, // explodes when hitting a water surface
|
||||
BOUNCE_CanBounceWater = 1<<11, // can bounce on water
|
||||
// MBF bouncing is a bit different from other modes as Killough coded many special behavioral cases
|
||||
// for them that are not present in ZDoom, so it is necessary to identify it properly.
|
||||
BOUNCE_MBF = 1<<12, // This in itself is not a valid mode, but replaces MBF's MF_BOUNCE flag.
|
||||
|
||||
BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType,
|
||||
|
||||
|
@ -398,6 +405,9 @@ enum EBounceType
|
|||
BOUNCE_Heretic = BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_HereticType,
|
||||
BOUNCE_Doom = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff,
|
||||
BOUNCE_Hexen = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors,
|
||||
BOUNCE_Grenade = BOUNCE_MBF | BOUNCE_Doom, // Bounces on walls and flats like ZDoom bounce.
|
||||
BOUNCE_Classic = BOUNCE_MBF | BOUNCE_Floors | BOUNCE_Ceilings, // Bounces on flats only, but
|
||||
// does not die when bouncing.
|
||||
|
||||
// combined types
|
||||
BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound,
|
||||
|
@ -411,6 +421,20 @@ enum EBounceType
|
|||
// being "Doom" or "Hexen" and BOUNCE_AllActors was the separate
|
||||
// MF5_BOUNCEONACTORS, you must set BOUNCE_Actors for BOUNCE_AllActors to have
|
||||
// an effect.
|
||||
|
||||
|
||||
};
|
||||
|
||||
// Used to affect the logic for MF5_USESPECIAL and MF6_BUMPSPECIAL
|
||||
// "thing" refers to what has the flag and the special, "trigger" refers to what used or bumped it
|
||||
enum EThingSpecialActivationType
|
||||
{
|
||||
THINGSPEC_Default = 0, // Normal behavior: a player must be the trigger, and is the activator
|
||||
THINGSPEC_ThingActs = 1, // The thing itself is the activator of the special
|
||||
THINGSPEC_ThingTargets = 2, // The thing changes its target to the trigger
|
||||
THINGSPEC_TriggerTargets = 4, // The trigger changes its target to the thing
|
||||
THINGSPEC_MonsterTrigger = 8, // The thing can be triggered by a monster
|
||||
THINGSPEC_MissileTrigger = 16, // The thing can be triggered by a projectile
|
||||
};
|
||||
|
||||
// [RH] Like msecnode_t, but for the blockmap
|
||||
|
@ -680,6 +704,10 @@ public:
|
|||
|
||||
bool CanSeek(AActor *target) const;
|
||||
|
||||
fixed_t GetGravity() const;
|
||||
bool IsSentient() const;
|
||||
|
||||
|
||||
// info for drawing
|
||||
// NOTE: The first member variable *must* be x.
|
||||
fixed_t x,y,z;
|
||||
|
@ -726,7 +754,7 @@ public:
|
|||
SWORD movecount; // when 0, select a new dir
|
||||
TObjPtr<AActor> target; // thing being chased/attacked (or NULL)
|
||||
// also the originator for missiles
|
||||
TObjPtr<AActor> lastenemy; // Last known enemy -- killogh 2/15/98
|
||||
TObjPtr<AActor> lastenemy; // Last known enemy -- killough 2/15/98
|
||||
TObjPtr<AActor> LastHeard; // [RH] Last actor this one heard
|
||||
SDWORD reactiontime; // if non 0, don't attack yet; used by
|
||||
// player to freeze a bit after teleporting
|
||||
|
@ -738,7 +766,7 @@ public:
|
|||
WORD SpawnAngle;
|
||||
int skillrespawncount;
|
||||
int TIDtoHate; // TID of things to hate (0 if none)
|
||||
FNameNoInit Species;
|
||||
FNameNoInit Species; // For monster families
|
||||
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers
|
||||
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
|
||||
fixed_t floorclip; // value to use for floor clipping
|
||||
|
@ -766,6 +794,8 @@ public:
|
|||
int FastChaseStrafeCount;
|
||||
fixed_t pushfactor;
|
||||
int lastpush;
|
||||
int activationtype; // How the thing behaves when activated with USESPECIAL or BUMPSPECIAL
|
||||
int Score; // manipulated by score items, ACS or DECORATE. The engine doesn't use this itself for anything.
|
||||
|
||||
AActor *BlockingMobj; // Actor that blocked the last move
|
||||
line_t *BlockingLine; // Line that blocked the last move
|
||||
|
@ -941,6 +971,8 @@ inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
|
|||
return static_cast<T *>(AActor::StaticSpawn (RUNTIME_CLASS(T), x, y, z, allowreplacement));
|
||||
}
|
||||
|
||||
void PrintMiscActorInfo(AActor * query);
|
||||
|
||||
#define S_FREETARGMOBJ 1
|
||||
|
||||
#endif // __P_MOBJ_H__
|
||||
|
|
|
@ -778,10 +778,31 @@ CCMD(linetarget)
|
|||
linetarget->GetClass()->TypeName.GetChars(),
|
||||
linetarget->health,
|
||||
linetarget->SpawnHealth());
|
||||
PrintMiscActorInfo(linetarget);
|
||||
}
|
||||
else Printf("No target found\n");
|
||||
}
|
||||
|
||||
// As linetarget, but also give info about non-shootable actors
|
||||
CCMD(info)
|
||||
{
|
||||
AActor *linetarget;
|
||||
|
||||
if (CheckCheatmode () || players[consoleplayer].mo == NULL) return;
|
||||
P_AimLineAttack(players[consoleplayer].mo,players[consoleplayer].mo->angle,MISSILERANGE, &linetarget, 0,
|
||||
false, false, true);
|
||||
if (linetarget)
|
||||
{
|
||||
Printf("Target=%s, Health=%d, Spawnhealth=%d\n",
|
||||
linetarget->GetClass()->TypeName.GetChars(),
|
||||
linetarget->health,
|
||||
linetarget->SpawnHealth());
|
||||
PrintMiscActorInfo(linetarget);
|
||||
}
|
||||
else Printf("No target found. Info cannot find actors that have\
|
||||
the NOBLOCKMAP flag or have height/radius of 0.\n");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
|
@ -2094,6 +2094,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
case DEM_SUMMON:
|
||||
case DEM_SUMMONFRIEND:
|
||||
case DEM_SUMMONFOE:
|
||||
case DEM_SUMMONMBF:
|
||||
case DEM_SUMMON2:
|
||||
case DEM_SUMMONFRIEND2:
|
||||
case DEM_SUMMONFOE2:
|
||||
|
@ -2132,7 +2133,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
source->z + 8 * FRACUNIT, ALLOW_REPLACE);
|
||||
if (spawned != NULL)
|
||||
{
|
||||
if (type == DEM_SUMMONFRIEND || type == DEM_SUMMONFRIEND2)
|
||||
if (type == DEM_SUMMONFRIEND || type == DEM_SUMMONFRIEND2 || type == DEM_SUMMONMBF)
|
||||
{
|
||||
if (spawned->CountsAsKill())
|
||||
{
|
||||
|
@ -2142,6 +2143,8 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
spawned->flags |= MF_FRIENDLY;
|
||||
spawned->LastHeard = players[player].mo;
|
||||
spawned->health = spawned->SpawnHealth();
|
||||
if (type == DEM_SUMMONMBF)
|
||||
spawned->flags3 |= MF3_NOBLOCKMONST;
|
||||
}
|
||||
else if (type == DEM_SUMMONFOE || type == DEM_SUMMONFOE2)
|
||||
{
|
||||
|
@ -2440,6 +2443,7 @@ void Net_SkipCommand (int type, BYTE **stream)
|
|||
case DEM_SUMMON:
|
||||
case DEM_SUMMONFRIEND:
|
||||
case DEM_SUMMONFOE:
|
||||
case DEM_SUMMONMBF:
|
||||
case DEM_SPRAY:
|
||||
case DEM_MORPHEX:
|
||||
case DEM_KILLCLASSCHEAT:
|
||||
|
|
|
@ -839,5 +839,6 @@ CCMD (playerinfo)
|
|||
Printf ("PlayerClass: %s (%d)\n",
|
||||
ui->PlayerClass == -1 ? "Random" : PlayerClasses[ui->PlayerClass].Type->Meta.GetMetaString (APMETA_DisplayName),
|
||||
ui->PlayerClass);
|
||||
PrintMiscActorInfo(players[i].mo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,6 +154,7 @@ enum EDemoCommand
|
|||
DEM_ADDSLOTDEFAULT, // 55
|
||||
DEM_ADDSLOT, // 56
|
||||
DEM_SETSLOT, // 57
|
||||
DEM_SUMMONMBF,
|
||||
};
|
||||
|
||||
// The following are implemented by cht_DoCheat in m_cheat.cpp
|
||||
|
|
|
@ -21,6 +21,7 @@ static FRandom pr_fireshotgun2 ("FireSG2");
|
|||
static FRandom pr_fireplasma ("FirePlasma");
|
||||
static FRandom pr_firerail ("FireRail");
|
||||
static FRandom pr_bfgspray ("BFGSpray");
|
||||
static FRandom pr_oldbfg ("OldBFG");
|
||||
|
||||
//
|
||||
// A_Punch
|
||||
|
@ -553,3 +554,48 @@ DEFINE_ACTION_FUNCTION(AActor, A_BFGsound)
|
|||
S_Sound (self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM);
|
||||
}
|
||||
|
||||
//
|
||||
// A_FireOldBFG
|
||||
//
|
||||
// This function emulates Doom's Pre-Beta BFG
|
||||
// By Lee Killough 6/6/98, 7/11/98, 7/19/98, 8/20/98
|
||||
//
|
||||
// This code may not be used in other mods without appropriate credit given.
|
||||
// Code leeches will be telefragged.
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
|
||||
{
|
||||
const PClass * plasma[] = {PClass::FindClass("PlasmaBall1"), PClass::FindClass("PlasmaBall2")};
|
||||
AActor * mo = NULL;
|
||||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return;
|
||||
}
|
||||
self->player->extralight = 2;
|
||||
|
||||
// Save values temporarily
|
||||
angle_t SavedPlayerAngle = self->angle;
|
||||
fixed_t SavedPlayerPitch = self->pitch;
|
||||
bool doesautoaim = !(self->player->ReadyWeapon->WeaponFlags & WIF_NOAUTOAIM);
|
||||
self->player->ReadyWeapon->WeaponFlags |= WIF_NOAUTOAIM; // No autoaiming that gun
|
||||
for (int i = 0; i < 2; i++) // Spawn two plasma balls in sequence
|
||||
{
|
||||
self->angle += ((pr_oldbfg()&127) - 64) * (ANG90/768);
|
||||
self->pitch += ((pr_oldbfg()&127) - 64) * (ANG90/640);
|
||||
mo = P_SpawnPlayerMissile (self, plasma[i]);
|
||||
// Restore saved values
|
||||
self->angle = SavedPlayerAngle;
|
||||
self->pitch = SavedPlayerPitch;
|
||||
}
|
||||
if (doesautoaim) self->player->ReadyWeapon->WeaponFlags &= ~WIF_NOAUTOAIM; // Restore autoaim setting
|
||||
}
|
||||
|
|
|
@ -553,7 +553,7 @@ void APowerStrength::Tick ()
|
|||
|
||||
PalEntry APowerStrength::GetBlend ()
|
||||
{
|
||||
// slowly fade the berzerk out
|
||||
// slowly fade the berserk out
|
||||
int cnt = 12 - (EffectTics >> 6);
|
||||
|
||||
if (cnt > 0)
|
||||
|
@ -570,35 +570,10 @@ PalEntry APowerStrength::GetBlend ()
|
|||
IMPLEMENT_CLASS (APowerInvisibility)
|
||||
IMPLEMENT_CLASS (APowerShadow)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerInvisibility :: CommonInit
|
||||
//
|
||||
// stuff that's done for all subclasses
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerInvisibility::CommonInit()
|
||||
{
|
||||
if (Owner != NULL)
|
||||
{
|
||||
Owner->flags |= MF_SHADOW;
|
||||
fixed_t ts = MIN(Strength * (special1 + 1), FRACUNIT);
|
||||
Owner->alpha = clamp<fixed_t>((OPAQUE - ts), 0, OPAQUE);
|
||||
Owner->RenderStyle = (Mode == NAME_Fuzzy ? STYLE_OptFuzzy : STYLE_Translucent);
|
||||
// CommonInit() is called every tic by DoEffect, so the flag trick must happen only once!
|
||||
if (special2 == 0)
|
||||
{
|
||||
// transfer seeker missile blocking (but only if the owner does not already have this flag
|
||||
if (!(Owner->flags5 & MF5_CANTSEEK) && (flags5 & MF5_CANTSEEK)) Owner->flags5 |= MF5_CANTSEEK;
|
||||
else flags5 &= ~MF5_CANTSEEK;
|
||||
// transfer ghost flag likewise
|
||||
if (!(Owner->flags3 & MF3_GHOST) && (flags3 & MF3_GHOST)) Owner->flags3 |= MF3_GHOST;
|
||||
else flags3 &= ~MF3_GHOST;
|
||||
special2 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Invisibility flag combos
|
||||
#define INVISIBILITY_FLAGS1 (MF_SHADOW | MF_STEALTH)
|
||||
#define INVISIBILITY_FLAGS3 (MF3_GHOST)
|
||||
#define INVISIBILITY_FLAGS5 (MF5_CANTSEEK)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -608,7 +583,39 @@ void APowerInvisibility::CommonInit()
|
|||
|
||||
void APowerInvisibility::InitEffect ()
|
||||
{
|
||||
CommonInit();
|
||||
// This used to call CommonInit(), which used to contain all the code that's repeated every
|
||||
// tic, plus the following code that needs to happen once and only once.
|
||||
// The CommonInit() code has been moved to DoEffect(), so this now ends with a call to DoEffect(),
|
||||
// and DoEffect() no longer needs to call InitEffect(). CommonInit() has been removed for being redundant.
|
||||
if (Owner != NULL)
|
||||
{
|
||||
flags &= ~(Owner->flags & INVISIBILITY_FLAGS1);
|
||||
Owner->flags |= flags & INVISIBILITY_FLAGS1;
|
||||
flags3 &= ~(Owner->flags3 & INVISIBILITY_FLAGS3);
|
||||
Owner->flags3 |= flags3 & INVISIBILITY_FLAGS3;
|
||||
flags5 &= ~(Owner->flags5 & INVISIBILITY_FLAGS5);
|
||||
Owner->flags5 |= flags5 & INVISIBILITY_FLAGS5;
|
||||
|
||||
// Finds out what's the normal alpha and render style for the owner.
|
||||
// First assume it's what it currently is.
|
||||
//OwnersNormalStyle = Owner->RenderStyle;
|
||||
//OwnersNormalAlpha = Owner->alpha;
|
||||
// Then look if there aren't active invis powerups and look what they're saying.
|
||||
/*AInventory *item = Owner->Inventory;
|
||||
while (item != NULL)
|
||||
{
|
||||
if (item->IsKindOf(RUNTIME_CLASS(APowerInvisibility)) && item != this)
|
||||
{
|
||||
OwnersNormalStyle = static_cast<APowerInvisibility*>(item)->OwnersNormalStyle;
|
||||
OwnersNormalAlpha = static_cast<APowerInvisibility*>(item)->OwnersNormalAlpha;
|
||||
item = NULL; // No need to look further
|
||||
}
|
||||
else item = item->Inventory;
|
||||
}
|
||||
Printf("Owner's normal style is found to be %i, normal alpha is found to be %i.\n",
|
||||
OwnersNormalStyle, OwnersNormalAlpha>>FRACBITS);*/
|
||||
DoEffect();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -621,7 +628,31 @@ void APowerInvisibility::DoEffect ()
|
|||
Super::DoEffect();
|
||||
// Due to potential interference with other PowerInvisibility items
|
||||
// the effect has to be refreshed each tic.
|
||||
InitEffect();
|
||||
fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT;
|
||||
Owner->alpha = clamp<fixed_t>((/*OwnersNormalAlpha*/OPAQUE - ts), 0, OPAQUE);
|
||||
switch (Mode)
|
||||
{
|
||||
case (NAME_Fuzzy):
|
||||
Owner->RenderStyle = STYLE_OptFuzzy;
|
||||
break;
|
||||
case (NAME_Opaque):
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
break;
|
||||
case (NAME_Additive):
|
||||
Owner->RenderStyle = STYLE_Add;
|
||||
break;
|
||||
case (NAME_Stencil):
|
||||
Owner->RenderStyle = STYLE_Stencil;
|
||||
break;
|
||||
case (NAME_None):
|
||||
case (NAME_Translucent):
|
||||
Owner->RenderStyle = STYLE_Translucent;
|
||||
break;
|
||||
default: // Something's wrong
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
Owner->alpha = OPAQUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -634,11 +665,12 @@ void APowerInvisibility::EndEffect ()
|
|||
{
|
||||
if (Owner != NULL)
|
||||
{
|
||||
if (flags5 & MF5_CANTSEEK) Owner->flags5 &= ~MF5_CANTSEEK;
|
||||
if (flags3 & MF3_GHOST) Owner->flags3 &= ~MF3_GHOST;
|
||||
Owner->flags &= ~MF_SHADOW;
|
||||
Owner->RenderStyle = STYLE_Normal;
|
||||
Owner->alpha = OPAQUE;
|
||||
Owner->flags &= ~(flags & INVISIBILITY_FLAGS1);
|
||||
Owner->flags3 &= ~(flags3 & INVISIBILITY_FLAGS3);
|
||||
Owner->flags5 &= ~(flags5 & INVISIBILITY_FLAGS5);
|
||||
|
||||
Owner->RenderStyle = STYLE_Normal;//OwnersNormalStyle;
|
||||
Owner->alpha = OPAQUE;//OwnersNormalAlpha;
|
||||
|
||||
// Check whether there are other invisibility items and refresh their effect.
|
||||
// If this isn't done there will be one incorrectly drawn frame when this
|
||||
|
@ -648,7 +680,7 @@ void APowerInvisibility::EndEffect ()
|
|||
{
|
||||
if (item->IsKindOf(RUNTIME_CLASS(APowerInvisibility)) && item != this)
|
||||
{
|
||||
static_cast<APowerInvisibility*>(item)->InitEffect();
|
||||
static_cast<APowerInvisibility*>(item)->DoEffect();
|
||||
}
|
||||
item = item->Inventory;
|
||||
}
|
||||
|
@ -667,16 +699,36 @@ int APowerInvisibility::AlterWeaponSprite (vissprite_t *vis)
|
|||
// Blink if the powerup is wearing off
|
||||
if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8))
|
||||
{
|
||||
vis->RenderStyle = STYLE_Normal;
|
||||
vis->alpha = OPAQUE;
|
||||
vis->RenderStyle = STYLE_Normal;//OwnersNormalStyle;
|
||||
vis->alpha = OPAQUE;//OwnersNormalAlpha;
|
||||
return 1;
|
||||
}
|
||||
else if (changed == 1)
|
||||
{
|
||||
// something else set the weapon sprite back to opaque but this item is still active.
|
||||
fixed_t ts = MIN(Strength * (special1 + 1), FRACUNIT);
|
||||
vis->alpha = clamp<fixed_t>((OPAQUE - ts), 0, OPAQUE);
|
||||
vis->RenderStyle = (Mode == NAME_Fuzzy ? STYLE_OptFuzzy : STYLE_Translucent);
|
||||
fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT;
|
||||
vis->alpha = clamp<fixed_t>((/*OwnersNormalAlpha*/OPAQUE - ts), 0, OPAQUE);
|
||||
switch (Mode)
|
||||
{
|
||||
case (NAME_Fuzzy):
|
||||
vis->RenderStyle = STYLE_OptFuzzy;
|
||||
break;
|
||||
case (NAME_Opaque):
|
||||
vis->RenderStyle = STYLE_Normal;
|
||||
break;
|
||||
case (NAME_Additive):
|
||||
vis->RenderStyle = STYLE_Add;
|
||||
break;
|
||||
case (NAME_Stencil):
|
||||
vis->RenderStyle = STYLE_Stencil;
|
||||
break;
|
||||
case (NAME_None):
|
||||
case (NAME_Cumulative):
|
||||
case (NAME_Translucent):
|
||||
default:
|
||||
vis->RenderStyle = STYLE_Translucent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible
|
||||
if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0))
|
||||
|
|
|
@ -81,11 +81,12 @@ class APowerInvisibility : public APowerup
|
|||
DECLARE_CLASS (APowerInvisibility, APowerup)
|
||||
protected:
|
||||
bool HandlePickup (AInventory *item);
|
||||
void CommonInit ();
|
||||
void InitEffect ();
|
||||
void DoEffect ();
|
||||
void EndEffect ();
|
||||
int AlterWeaponSprite (vissprite_t *vis);
|
||||
// FRenderStyle OwnersNormalStyle;
|
||||
// fixed_t OwnersNormalAlpha;
|
||||
};
|
||||
|
||||
// Needed only for m_cheat.cpp now
|
||||
|
|
|
@ -1728,3 +1728,30 @@ bool AMapRevealer::TryPickup (AActor *&toucher)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AScoreItem
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
IMPLEMENT_CLASS(AScoreItem)
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AScoreItem :: TryPickup
|
||||
//
|
||||
// This function does nothing much. Theoretically, the player could have a
|
||||
// score property which would be incremented by the score items' own score
|
||||
// property (probably using the Amount property for that), but that is not
|
||||
// needed for the moment.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool AScoreItem::TryPickup (AActor *&toucher)
|
||||
{
|
||||
toucher->Score += Amount;
|
||||
GoAwayAndDie();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -475,4 +475,16 @@ public:
|
|||
bool bDepleted;
|
||||
};
|
||||
|
||||
|
||||
// A score item is picked up without being added to the inventory.
|
||||
// Contrarily to FakeInventory, it does nothing.
|
||||
class AScoreItem : public AInventory
|
||||
{
|
||||
DECLARE_CLASS (AScoreItem, AInventory)
|
||||
|
||||
public:
|
||||
bool TryPickup(AActor *&toucher);
|
||||
};
|
||||
|
||||
|
||||
#endif //__A_PICKUPS_H__
|
||||
|
|
16
src/info.cpp
16
src/info.cpp
|
@ -211,7 +211,9 @@ FActorInfo *FActorInfo::GetReplacement (bool lookskill)
|
|||
|
||||
FActorInfo *FActorInfo::GetReplacee (bool lookskill)
|
||||
{
|
||||
FName skillrepname = AllSkills[gameskill].GetReplacedBy(this->Class->TypeName); if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL) {
|
||||
FName skillrepname = AllSkills[gameskill].GetReplacedBy(this->Class->TypeName);
|
||||
if (skillrepname != NAME_None && PClass::FindClass(skillrepname) == NULL)
|
||||
{
|
||||
Printf("Warning: incorrect actor name in definition of skill %s: \
|
||||
inexistent class %s is replaced by class %s\n\
|
||||
Skill replacement will be ignored for this actor.\n",
|
||||
|
@ -229,7 +231,12 @@ FActorInfo *FActorInfo::GetReplacee (bool lookskill)
|
|||
// potential infinite recursion.
|
||||
FActorInfo *savedrep = Replacee;
|
||||
Replacee = NULL;
|
||||
FActorInfo *rep = savedrep; if (lookskill && (skillrepname != NAME_None) && (PClass::FindClass(skillrepname) != NULL)) { rep = PClass::FindClass(skillrepname)->ActorInfo; } rep = rep->GetReplacee (false); Replacee = savedrep;
|
||||
FActorInfo *rep = savedrep;
|
||||
if (lookskill && (skillrepname != NAME_None) && (PClass::FindClass(skillrepname) != NULL))
|
||||
{
|
||||
rep = PClass::FindClass(skillrepname)->ActorInfo;
|
||||
}
|
||||
rep = rep->GetReplacee (false); Replacee = savedrep;
|
||||
return rep;
|
||||
}
|
||||
|
||||
|
@ -445,6 +452,11 @@ CCMD (summonfriend)
|
|||
SummonActor (DEM_SUMMONFRIEND, DEM_SUMMONFRIEND2, argv);
|
||||
}
|
||||
|
||||
CCMD (summonmbf)
|
||||
{
|
||||
SummonActor (DEM_SUMMONMBF, DEM_SUMMONFRIEND2, argv);
|
||||
}
|
||||
|
||||
CCMD (summonfoe)
|
||||
{
|
||||
SummonActor (DEM_SUMMONFOE, DEM_SUMMONFOE2, argv);
|
||||
|
|
|
@ -25,8 +25,11 @@ xx(Ghost)
|
|||
xx(Reflective)
|
||||
|
||||
// Invisibility types
|
||||
xx(Additive)
|
||||
xx(Cumulative)
|
||||
xx(Fuzzy)
|
||||
xx(Opaque)
|
||||
xx(Stencil)
|
||||
|
||||
// Healingradius types
|
||||
xx(Mana)
|
||||
|
|
|
@ -2426,6 +2426,8 @@ enum
|
|||
APROP_Dropped = 18,
|
||||
APROP_Notarget = 19,
|
||||
APROP_Species = 20,
|
||||
// APROP_Nametag
|
||||
APROP_Score = 22,
|
||||
};
|
||||
|
||||
// These are needed for ACS's APROP_RenderStyle
|
||||
|
@ -2578,6 +2580,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
|
|||
case APROP_Species:
|
||||
actor->Species = FBehavior::StaticLookupString(value);
|
||||
break;
|
||||
|
||||
case APROP_Score:
|
||||
actor->Score = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2642,6 +2648,7 @@ int DLevelScript::GetActorProperty (int tid, int property)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
case APROP_Score: return actor->Score;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -376,15 +376,19 @@ bool P_Move (AActor *actor)
|
|||
|
||||
fixed_t tryx, tryy, deltax, deltay, origx, origy;
|
||||
bool try_ok;
|
||||
int speed;
|
||||
int speed = actor->Speed;
|
||||
int movefactor = ORIG_FRICTION_FACTOR;
|
||||
int friction = ORIG_FRICTION;
|
||||
|
||||
if (actor->flags2 & MF2_BLASTED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (actor->movedir == DI_NODIR)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// [RH] Instead of yanking non-floating monsters to the ground,
|
||||
// let gravity drop them down, unless they're moving down a step.
|
||||
|
@ -490,6 +494,7 @@ bool P_Move (AActor *actor)
|
|||
else
|
||||
actor->z -= actor->FloatSpeed;
|
||||
|
||||
|
||||
// [RH] Check to make sure there's nothing in the way of the float
|
||||
if (P_TestMobjZ (actor))
|
||||
{
|
||||
|
@ -500,7 +505,9 @@ bool P_Move (AActor *actor)
|
|||
}
|
||||
|
||||
if (!spechit.Size ())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// open any specials
|
||||
actor->movedir = DI_NODIR;
|
||||
|
|
|
@ -1017,13 +1017,12 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
|
|||
|
||||
damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
|
||||
}
|
||||
|
||||
if (damage == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Push the target unless the source's weapon's kickback is 0.
|
||||
// (i.e. Guantlets/Chainsaw)
|
||||
// (i.e. Gauntlets/Chainsaw)
|
||||
if (inflictor && inflictor != target // [RH] Not if hurting own self
|
||||
&& !(target->flags & MF_NOCLIP)
|
||||
&& !(inflictor->flags2 & MF2_NODMGTHRUST)
|
||||
|
|
|
@ -3250,3 +3250,13 @@ int P_FindLineSpecial (const char *string, int *min_args, int *max_args)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *GetSpecialName(int num)
|
||||
{
|
||||
for(int i = 0; i < countof(LineSpecialNames); i++)
|
||||
{
|
||||
if (LineSpecialNames[i].number == num)
|
||||
return LineSpecialNames[i].name;
|
||||
}
|
||||
return "(unknown)";
|
||||
}
|
|
@ -196,5 +196,6 @@ typedef int (*lnSpecFunc)(struct line_t *line,
|
|||
extern lnSpecFunc LineSpecials[256];
|
||||
|
||||
int P_FindLineSpecial (const char *string, int *min_args=NULL, int *max_args=NULL);
|
||||
const char *GetSpecialName(int num);
|
||||
|
||||
#endif //__P_LNSPEC_H__
|
||||
|
|
|
@ -392,7 +392,7 @@ void P_FindFloorCeiling (AActor *actor, bool onlymidtex = false);
|
|||
|
||||
bool P_ChangeSector (sector_t* sector, int crunch, int amt, int floorOrCeil, bool isreset);
|
||||
|
||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, bool forcenosmart=false, bool check3d = false);
|
||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget = NULL, fixed_t vrange=0, bool forcenosmart=false, bool check3d = false, bool checknonshootable = false);
|
||||
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, bool ismelee = false);
|
||||
AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, FName pufftype, bool ismelee = false);
|
||||
void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);
|
||||
|
|
|
@ -1314,7 +1314,8 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm)
|
|||
|
||||
while ((ld = it.Next()))
|
||||
{
|
||||
if (!PIT_CheckLine(ld, box, tm)) return false;
|
||||
if (!PIT_CheckLine(ld, box, tm))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tm.ceilingz - tm.floorz < thing->height)
|
||||
|
@ -2667,7 +2668,7 @@ struct aim_t
|
|||
bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in);
|
||||
#endif
|
||||
|
||||
void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy);
|
||||
void AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable = false);
|
||||
|
||||
};
|
||||
|
||||
|
@ -2784,7 +2785,7 @@ bool aim_t::AimTraverse3DFloors(const divline_t &trace, intercept_t * in)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy)
|
||||
void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t endy, bool checknonshootable)
|
||||
{
|
||||
FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS);
|
||||
intercept_t *in;
|
||||
|
@ -2839,6 +2840,8 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
|||
if (th == shootthing)
|
||||
continue; // can't shoot self
|
||||
|
||||
if (!checknonshootable) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags
|
||||
{
|
||||
if (!(th->flags&MF_SHOOTABLE))
|
||||
continue; // corpse or something
|
||||
|
||||
|
@ -2850,7 +2853,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
dist = FixedMul (attackrange, in->frac);
|
||||
|
||||
#ifdef _3DFLOORS
|
||||
|
@ -2974,6 +2977,11 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
|||
aimpitch=thingpitch;
|
||||
return;
|
||||
}
|
||||
if (checknonshootable)
|
||||
{
|
||||
linetarget=th;
|
||||
aimpitch=thingpitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2982,7 +2990,7 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
|
|||
// P_AimLineAttack
|
||||
//
|
||||
//============================================================================
|
||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, bool forcenosmart, bool check3d)
|
||||
fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **pLineTarget, fixed_t vrange, bool forcenosmart, bool check3d, bool checknonshootable)
|
||||
{
|
||||
fixed_t x2;
|
||||
fixed_t y2;
|
||||
|
@ -3051,7 +3059,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
|
|||
}
|
||||
#endif
|
||||
|
||||
aim.AimTraverse (t1->x, t1->y, x2, y2);
|
||||
aim.AimTraverse (t1->x, t1->y, x2, y2, checknonshootable);
|
||||
|
||||
if (!aim.linetarget)
|
||||
{
|
||||
|
@ -4124,7 +4132,6 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SECTOR HEIGHT CHANGING
|
||||
// After modifying a sector's floor or ceiling height,
|
||||
|
|
|
@ -325,6 +325,9 @@ void AActor::Serialize (FArchive &arc)
|
|||
<< pushfactor
|
||||
<< Species;
|
||||
|
||||
if (SaveVersion >= 1819)
|
||||
arc << Score;
|
||||
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
int convnum = 0;
|
||||
|
@ -2054,6 +2057,7 @@ void P_MonsterFallingDamage (AActor *mo)
|
|||
//
|
||||
// P_ZMovement
|
||||
//
|
||||
|
||||
void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
||||
{
|
||||
fixed_t dist;
|
||||
|
@ -2084,8 +2088,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
|
|||
if (!mo->waterlevel || mo->flags & MF_CORPSE || (mo->player &&
|
||||
!(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove)))
|
||||
{
|
||||
fixed_t grav = (fixed_t)(level.gravity * mo->Sector->gravity *
|
||||
FIXED2FLOAT(mo->gravity) * 81.92);
|
||||
fixed_t grav = mo->GetGravity();
|
||||
|
||||
// [RH] Double gravity only if running off a ledge. Coming down from
|
||||
// an upward thrust (e.g. a jump) should not double it.
|
||||
|
@ -5347,6 +5350,7 @@ int AActor::SpawnHealth()
|
|||
return (adj <= 0) ? 1 : adj;
|
||||
}
|
||||
}
|
||||
|
||||
FDropItem *AActor::GetDropItems()
|
||||
{
|
||||
unsigned int index = GetClass()->Meta.GetMetaInt (ACMETA_DropItems) - 1;
|
||||
|
@ -5358,6 +5362,21 @@ FDropItem *AActor::GetDropItems()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
fixed_t AActor::GetGravity() const
|
||||
{
|
||||
if (flags & MF_NOGRAVITY) return 0;
|
||||
return fixed_t(level.gravity * Sector->gravity * FIXED2FLOAT(gravity) * 81.92);
|
||||
}
|
||||
|
||||
// killough 11/98:
|
||||
// Whether an object is "sentient" or not. Used for environmental influences.
|
||||
// (left precisely the same as MBF even though it doesn't make much sense.)
|
||||
bool AActor::IsSentient() const
|
||||
{
|
||||
return health > 0 || SeeState != NULL;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// DropItem handling
|
||||
|
@ -5388,3 +5407,68 @@ int StoreDropItemChain(FDropItem *chain)
|
|||
return DropItemList.Push (chain) + 1;
|
||||
}
|
||||
|
||||
void PrintMiscActorInfo(AActor * query)
|
||||
{
|
||||
if (query)
|
||||
{
|
||||
int flagi;
|
||||
int querystyle = STYLE_Count;
|
||||
for (int style = STYLE_None; style < STYLE_Count; ++style)
|
||||
{ // Check for a legacy render style that matches.
|
||||
if (LegacyRenderStyles[style] == query->RenderStyle)
|
||||
{
|
||||
querystyle = style;
|
||||
break;
|
||||
}
|
||||
}
|
||||
static const char * renderstyles[]= {"None", "Normal", "Fuzzy", "SoulTrans",
|
||||
"OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil"};
|
||||
|
||||
/*
|
||||
Printf("%s %x has the following flags:\n\tflags1: %x",
|
||||
query->GetNameTag().GetChars(), query, query->flags);
|
||||
*/
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->flags & 1<<flagi) Printf(" %s", FLAG_NAME(1<<flagi, flags));
|
||||
Printf("\n\tflags2: %x", query->flags2);
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->flags2 & 1<<flagi) Printf(" %s", FLAG_NAME(1<<flagi, flags2));
|
||||
Printf("\n\tflags3: %x", query->flags3);
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->flags3 & 1<<flagi) Printf(" %s", FLAG_NAME(1<<flagi, flags3));
|
||||
Printf("\n\tflags4: %x", query->flags4);
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->flags4 & 1<<flagi) Printf(" %s", FLAG_NAME(1<<flagi, flags4));
|
||||
Printf("\n\tflags5: %x", query->flags5);
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->flags5 & 1<<flagi) Printf(" %s", FLAG_NAME(1<<flagi, flags5));
|
||||
Printf("\n\tflags6: %x", query->flags6);
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->flags6 & 1<<flagi) Printf(" %s", FLAG_NAME(1<<flagi, flags6));
|
||||
|
||||
/*
|
||||
Printf("\nIts bounce style and factors are %s and f:%f, w:%f; its bounce flags are:\n\tflagsb: %x",
|
||||
bouncestyles[bt], FIXED2FLOAT(query->bouncefactor),
|
||||
FIXED2FLOAT(query->wallbouncefactor), query->BounceFlags);
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->BounceFlags & 1<<flagi) Printf(" %s", flagnamesb[flagi]);
|
||||
*/
|
||||
Printf("\nIts render style is %i:%s with alpha %f and the following render flags:\n\tflagsr: %x",
|
||||
querystyle, (querystyle < STYLE_Count ? renderstyles[querystyle] : "Unknown"),
|
||||
FIXED2FLOAT(query->alpha), query->renderflags);
|
||||
/*
|
||||
for (flagi = 0; flagi < 31; flagi++)
|
||||
if (query->renderflags & 1<<flagi) Printf(" %s", flagnamesr[flagi]);
|
||||
*/
|
||||
Printf("\nIts thing special and arguments are %s(%i, %i, %i, %i, %i), and its specials are %i and %i.",
|
||||
GetSpecialName(query->special), query->args[0], query->args[1],
|
||||
query->args[2], query->args[3], query->args[4],
|
||||
query->special1, query->special2);
|
||||
Printf("\nIts coordinates are x: %f, y: %f, z:%f, floor:%f, ceiling:%f.",
|
||||
FIXED2FLOAT(query->x), FIXED2FLOAT(query->y), FIXED2FLOAT(query->z),
|
||||
FIXED2FLOAT(query->floorz), FIXED2FLOAT(query->ceilingz));
|
||||
Printf("\nIts speed is %f and velocity is x:%f, y:%f, z:%f, combined:%f.\n",
|
||||
FIXED2FLOAT(query->Speed), FIXED2FLOAT(query->velx), FIXED2FLOAT(query->vely), FIXED2FLOAT(query->velz),
|
||||
sqrt(pow(FIXED2FLOAT(query->velx), 2) + pow(FIXED2FLOAT(query->vely), 2) + pow(FIXED2FLOAT(query->velz), 2)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -704,8 +704,7 @@ bool FScanner::GetFloat ()
|
|||
Float = (float)strtod (String, &stopper);
|
||||
if (*stopper != 0)
|
||||
{
|
||||
I_Error ("SC_GetFloat: Bad numeric constant \"%s\".\n"
|
||||
"Script %s, Line %d\n", String, ScriptName.GetChars(), Line);
|
||||
ScriptError ("SC_GetFloat: Bad numeric constant \"%s\".", String);
|
||||
}
|
||||
Number = (int)Float;
|
||||
return true;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "info.h"
|
||||
#include "s_sound.h"
|
||||
#include "sc_man.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
|
||||
class FScanner;
|
||||
|
@ -25,6 +26,9 @@ struct FFlagDef
|
|||
|
||||
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2);
|
||||
void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int index);
|
||||
const char *GetFlagName(int flagnum, int flagoffset);
|
||||
|
||||
#define FLAG_NAME(flagnum, flagvar) GetFlagName(flagnum, myoffsetof(AActor, flagvar))
|
||||
|
||||
|
||||
//==========================================================================
|
||||
|
@ -120,7 +124,7 @@ public:
|
|||
~FStateExpressions();
|
||||
int Add(FxExpression *x, const PClass *o, bool c);
|
||||
int Reserve(int num, const PClass *cls);
|
||||
void Set(int num, FxExpression *x);
|
||||
void Set(int num, FxExpression *x, bool cloned = false);
|
||||
void Copy(int dest, int src, int cnt);
|
||||
int ResolveAll();
|
||||
FxExpression *Get(int no);
|
||||
|
|
|
@ -560,12 +560,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfArmorType)
|
|||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
||||
{
|
||||
ACTION_PARAM_START(5);
|
||||
ACTION_PARAM_START(7);
|
||||
ACTION_PARAM_INT(damage, 0);
|
||||
ACTION_PARAM_INT(distance, 1);
|
||||
ACTION_PARAM_BOOL(hurtSource, 2);
|
||||
ACTION_PARAM_BOOL(alert, 3);
|
||||
ACTION_PARAM_INT(fulldmgdistance, 4);
|
||||
ACTION_PARAM_INT(nails, 5);
|
||||
ACTION_PARAM_INT(naildamage, 6);
|
||||
|
||||
if (damage < 0) // get parameters from metadata
|
||||
{
|
||||
|
@ -578,6 +580,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
|
|||
{
|
||||
if (distance <= 0) distance = damage;
|
||||
}
|
||||
// NailBomb effect, from SMMU but not from its source code: instead it was implemented and
|
||||
// generalized from the documentation at http://www.doomworld.com/eternity/engine/codeptrs.html
|
||||
|
||||
if (nails)
|
||||
{
|
||||
angle_t ang;
|
||||
for (int i = 0; i < nails; i++)
|
||||
{
|
||||
ang = i*(ANGLE_MAX/nails);
|
||||
// Comparing the results of a test wad with Eternity, it seems A_NailBomb does not aim
|
||||
P_LineAttack (self, ang, MISSILERANGE, 0,
|
||||
//P_AimLineAttack (self, ang, MISSILERANGE),
|
||||
naildamage, NAME_None, NAME_BulletPuff);
|
||||
}
|
||||
}
|
||||
|
||||
P_RadiusAttack (self, self->target, damage, distance, self->DamageType, hurtSource, true, fulldmgdistance);
|
||||
if (self->z <= self->floorz + (distance<<FRACBITS))
|
||||
|
@ -1675,6 +1692,47 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Print)
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_PrintBold
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PrintBold)
|
||||
{
|
||||
ACTION_PARAM_START(3);
|
||||
ACTION_PARAM_STRING(text, 0);
|
||||
ACTION_PARAM_FLOAT(time, 1);
|
||||
ACTION_PARAM_NAME(fontname, 2);
|
||||
|
||||
float saved = con_midtime;
|
||||
FFont *font = NULL;
|
||||
|
||||
if (fontname != NAME_None)
|
||||
{
|
||||
font = V_GetFont(fontname);
|
||||
}
|
||||
if (time > 0)
|
||||
{
|
||||
con_midtime = time;
|
||||
}
|
||||
|
||||
C_MidPrintBold(font != NULL ? font : SmallFont, text);
|
||||
con_midtime = saved;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_Log
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Log)
|
||||
{
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_STRING(text, 0);
|
||||
Printf("%s\n", text);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -2769,3 +2827,28 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetArg)
|
|||
self->args[pos] = value;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetSpecial
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetSpecial)
|
||||
{
|
||||
ACTION_PARAM_START(6);
|
||||
ACTION_PARAM_INT(spec, 0);
|
||||
ACTION_PARAM_INT(arg0, 1);
|
||||
ACTION_PARAM_INT(arg1, 2);
|
||||
ACTION_PARAM_INT(arg2, 3);
|
||||
ACTION_PARAM_INT(arg3, 4);
|
||||
ACTION_PARAM_INT(arg4, 5);
|
||||
|
||||
self->special = spec;
|
||||
self->args[0] = arg0;
|
||||
self->args[1] = arg1;
|
||||
self->args[2] = arg2;
|
||||
self->args[3] = arg3;
|
||||
self->args[4] = arg4;
|
||||
}
|
||||
|
||||
|
|
|
@ -391,6 +391,24 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Gets the name of an actor flag
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
const char *GetFlagName(int flagnum, int flagoffset)
|
||||
{
|
||||
for(int i=0; i<countof(ActorFlags); i++)
|
||||
{
|
||||
if (ActorFlags[i].flagbit == flagnum && ActorFlags[i].structoffset == flagoffset)
|
||||
{
|
||||
return ActorFlags[i].name;
|
||||
}
|
||||
}
|
||||
return "(unknown)"; // return something printable
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Find a property by name using a binary search
|
||||
|
@ -534,7 +552,6 @@ static int STACK_ARGS varcmp(const void * a, const void * b)
|
|||
return stricmp(A->name, B->name);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initialization
|
||||
|
|
|
@ -75,6 +75,7 @@ DEFINE_MEMBER_VARIABLE_ALIAS(momx, velx, AActor)
|
|||
DEFINE_MEMBER_VARIABLE_ALIAS(momy, vely, AActor)
|
||||
DEFINE_MEMBER_VARIABLE_ALIAS(momz, velz, AActor)
|
||||
DEFINE_MEMBER_VARIABLE(Damage, AActor)
|
||||
DEFINE_MEMBER_VARIABLE(Score, AActor)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -2812,13 +2813,13 @@ int FStateExpressions::Reserve(int num, const PClass *cls)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FStateExpressions::Set(int num, FxExpression *x)
|
||||
void FStateExpressions::Set(int num, FxExpression *x, bool cloned)
|
||||
{
|
||||
if (num >= 0 && num < int(Size()))
|
||||
{
|
||||
assert(expressions[num].expr == NULL || expressions[num].cloned);
|
||||
expressions[num].expr = x;
|
||||
expressions[num].cloned = false;
|
||||
expressions[num].cloned = cloned;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -849,10 +849,11 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor)
|
|||
//==========================================================================
|
||||
DEFINE_PROPERTY(bouncetype, S, Actor)
|
||||
{
|
||||
static const char *names[] = { "None", "Doom", "Heretic", "Hexen", "DoomCompat", "HereticCompat", "HexenCompat", NULL };
|
||||
static const BYTE flags[] = { BOUNCE_None,
|
||||
static const char *names[] = { "None", "Doom", "Heretic", "Hexen", "DoomCompat", "HereticCompat", "HexenCompat", "Grenade", "Classic", NULL };
|
||||
static const int flags[] = { BOUNCE_None,
|
||||
BOUNCE_Doom, BOUNCE_Heretic, BOUNCE_Hexen,
|
||||
BOUNCE_DoomCompat, BOUNCE_HereticCompat, BOUNCE_HexenCompat };
|
||||
BOUNCE_DoomCompat, BOUNCE_HereticCompat, BOUNCE_HexenCompat,
|
||||
BOUNCE_Grenade, BOUNCE_Classic, };
|
||||
PROP_STRING_PARM(id, 0);
|
||||
int match = MatchString(id, names);
|
||||
if (match < 0)
|
||||
|
@ -1294,7 +1295,6 @@ DEFINE_CLASS_PROPERTY(pickupsound, S, Inventory)
|
|||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(pickupannouncerentry, S, Inventory)
|
||||
{
|
||||
PROP_STRING_PARM(str, 0);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -67,7 +67,7 @@ struct TVector2
|
|||
}
|
||||
|
||||
TVector2 (double a, double b)
|
||||
: X(a), Y(b)
|
||||
: X(vec_t(a)), Y(vec_t(b))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
// Protocol version used in demos.
|
||||
// Bump it if you change existing DEM_ commands or add new ones.
|
||||
// Otherwise, it should be safe to leave it alone.
|
||||
#define DEMOGAMEVERSION 0x211
|
||||
#define DEMOGAMEVERSION 0x212
|
||||
|
||||
// Minimum demo version we can play.
|
||||
// Bump it whenever you change or remove existing DEM_ commands.
|
||||
|
|
|
@ -44,6 +44,7 @@ ACTOR Actor native //: Thinker
|
|||
native fixed_t momx; // alias for velx
|
||||
native fixed_t momy; // alias for vely
|
||||
native fixed_t momz; // alias for velz
|
||||
native int score;
|
||||
|
||||
action native A_MonsterRail();
|
||||
action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15);
|
||||
|
@ -186,6 +187,8 @@ ACTOR Actor native //: Thinker
|
|||
action native A_SpawnItem(class<Actor> itemtype, float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
|
||||
action native A_SpawnItemEx(class<Actor> itemtype, float xofs = 0, float yofs = 0, float zofs = 0, float xvel = 0, float yvel = 0, float zvel = 0, float angle = 0, int flags = 0, int failchance = 0);
|
||||
action native A_Print(string whattoprint, float time = 0, string fontname = "");
|
||||
action native A_PrintBold(string whattoprint, float time = 0, string fontname = "");
|
||||
action native A_Log(string whattoprint);
|
||||
action native A_SetTranslucent(float alpha, int style = 0);
|
||||
action native A_FadeIn(float reduce = 0.1);
|
||||
action native A_FadeOut(float reduce = 0.1, bool remove = true);
|
||||
|
@ -220,7 +223,7 @@ ACTOR Actor native //: Thinker
|
|||
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_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);
|
||||
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_Respawn(bool fog = true);
|
||||
action native A_BarrelDestroy();
|
||||
|
@ -246,11 +249,12 @@ ACTOR Actor native //: Thinker
|
|||
action native A_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
|
||||
action native A_PigPain ();
|
||||
action native A_MonsterRefire(int chance, state label);
|
||||
action native A_SetAngle(float angle);
|
||||
action native A_SetAngle(float angle = 0);
|
||||
action native A_SetPitch(float pitch);
|
||||
action native A_ScaleVelocity(float scale);
|
||||
action native A_ChangeVelocity(float x = 0, float y = 0, float z = 0, int flags = 0);
|
||||
action native A_SetArg(int pos, int value);
|
||||
action native A_SetSpecial(int spec, int arg0, int arg1, int arg2, int arg3, int arg4);
|
||||
|
||||
States
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ ACTOR Inventory native
|
|||
action native A_RailWait();
|
||||
action native A_BFGsound();
|
||||
action native A_FireBFG();
|
||||
action native A_FireOldBFG();
|
||||
action native A_ReFire();
|
||||
action native A_ClearReFire();
|
||||
action native A_CheckReload();
|
||||
|
@ -70,6 +71,14 @@ ACTOR Inventory native
|
|||
}
|
||||
}
|
||||
|
||||
Actor ScoreItem : Inventory native
|
||||
{
|
||||
Height 10
|
||||
+COUNTITEM
|
||||
Inventory.Amount 1
|
||||
+Inventory.ALWAYSPICKUP
|
||||
}
|
||||
|
||||
Actor Ammo : Inventory native
|
||||
{
|
||||
+INVENTORY.KEEPDEPLETED
|
||||
|
@ -161,6 +170,7 @@ ACTOR PowerStrength : Powerup native
|
|||
|
||||
ACTOR PowerInvisibility : Powerup native
|
||||
{
|
||||
+SHADOW
|
||||
Powerup.Duration -60
|
||||
Powerup.Strength 80
|
||||
Powerup.Mode "Fuzzy"
|
||||
|
|
|
@ -137,6 +137,7 @@ ACTOR RandomSpawner native
|
|||
+NOBLOCKMAP
|
||||
+NOSECTOR
|
||||
+NOGRAVITY
|
||||
+THRUACTORS
|
||||
}
|
||||
|
||||
// Fast projectiles -----------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue