- 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:
Christoph Oelckers 2009-09-14 19:44:14 +00:00
parent 914d993aa1
commit 238d4c3fac
34 changed files with 564 additions and 110 deletions

View file

@ -1,5 +1,14 @@
September 14, 2009 (Changes by Graf Zahl) September 14, 2009 (Changes by Graf Zahl)
- Added a few things from Gez's experimental build: - 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) * Beta Lost Soul (added DoomEdNum 9037 to it)
* A_Mushroom extensions * A_Mushroom extensions
* Vavoom compatible MAPINFO keynames. * Vavoom compatible MAPINFO keynames.

View file

@ -7,13 +7,13 @@ DEFINE_SPECIAL(Polyobj_ExplicitLine, 5, -1, -1, 5)
DEFINE_SPECIAL(Polyobj_MoveTimes8, 6, 4, 4, 4) DEFINE_SPECIAL(Polyobj_MoveTimes8, 6, 4, 4, 4)
DEFINE_SPECIAL(Polyobj_DoorSwing, 7, 4, 4, 4) DEFINE_SPECIAL(Polyobj_DoorSwing, 7, 4, 4, 4)
DEFINE_SPECIAL(Polyobj_DoorSlide, 8, 5, 5, 5) DEFINE_SPECIAL(Polyobj_DoorSlide, 8, 5, 5, 5)
DEFINE_SPECIAL(Line_Horizon, 9, -1, 0, 0) // [RH] draw one-sided wall at horizon DEFINE_SPECIAL(Line_Horizon, 9, -1, 0, 0) // [RH] draw one-sided wall at horizon
DEFINE_SPECIAL(Door_Close, 10, 2, 3, 3) DEFINE_SPECIAL(Door_Close, 10, 2, 3, 3)
DEFINE_SPECIAL(Door_Open, 11, 2, 3, 3) DEFINE_SPECIAL(Door_Open, 11, 2, 3, 3)
DEFINE_SPECIAL(Door_Raise, 12, 3, 4, 4) DEFINE_SPECIAL(Door_Raise, 12, 3, 4, 4)
DEFINE_SPECIAL(Door_LockedRaise, 13, 4, 5, 5) DEFINE_SPECIAL(Door_LockedRaise, 13, 4, 5, 5)
DEFINE_SPECIAL(Door_Animated, 14, 3, 3, 3) DEFINE_SPECIAL(Door_Animated, 14, 3, 3, 3)
DEFINE_SPECIAL(Autosave, 15, 0, 0, 0) // [RH] Save the game *now* DEFINE_SPECIAL(Autosave, 15, 0, 0, 0) // [RH] Save the game *now*
DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2) DEFINE_SPECIAL(Transfer_WallLight, 16, -1, -1, 2)
DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1) DEFINE_SPECIAL(Thing_Raise, 17, 1, 1, 1)
DEFINE_SPECIAL(StartConversation, 18, 1, 2, 2) DEFINE_SPECIAL(StartConversation, 18, 1, 2, 2)
@ -31,13 +31,13 @@ DEFINE_SPECIAL(Pillar_Build, 29, 3, 3, 3)
DEFINE_SPECIAL(Pillar_Open, 30, 4, 4, 4) DEFINE_SPECIAL(Pillar_Open, 30, 4, 4, 4)
DEFINE_SPECIAL(Stairs_BuildDownSync, 31, 4, 4, 4) DEFINE_SPECIAL(Stairs_BuildDownSync, 31, 4, 4, 4)
DEFINE_SPECIAL(Stairs_BuildUpSync, 32, 4, 4, 4) DEFINE_SPECIAL(Stairs_BuildUpSync, 32, 4, 4, 4)
DEFINE_SPECIAL(ForceField, 33, 0, 0, 0) // [RH] Strife's forcefield special (148) DEFINE_SPECIAL(ForceField, 33, 0, 0, 0) // [RH] Strife's forcefield special (148)
DEFINE_SPECIAL(ClearForceField, 34, 1, 1, 1) // [RH] Remove Strife's forcefield from tagged sectors DEFINE_SPECIAL(ClearForceField, 34, 1, 1, 1) // [RH] Remove Strife's forcefield from tagged sectors
DEFINE_SPECIAL(Floor_RaiseByValueTimes8, 35, 3, 3, 3) DEFINE_SPECIAL(Floor_RaiseByValueTimes8, 35, 3, 3, 3)
DEFINE_SPECIAL(Floor_LowerByValueTimes8, 36, 3, 3, 3) DEFINE_SPECIAL(Floor_LowerByValueTimes8, 36, 3, 3, 3)
DEFINE_SPECIAL(Floor_MoveToValue, 37, 3, 4, 4) DEFINE_SPECIAL(Floor_MoveToValue, 37, 3, 4, 4)
DEFINE_SPECIAL(Ceiling_Waggle, 38, 5, 5, 4) // [RH] Complement of Floor_Waggle DEFINE_SPECIAL(Ceiling_Waggle, 38, 5, 5, 4) // [RH] Complement of Floor_Waggle
DEFINE_SPECIAL(Teleport_ZombieChanger, 39, 2, 2, 2) // [RH] Needed for Strife DEFINE_SPECIAL(Teleport_ZombieChanger, 39, 2, 2, 2) // [RH] Needed for Strife
DEFINE_SPECIAL(Ceiling_LowerByValue, 40, 3, 3, 3) DEFINE_SPECIAL(Ceiling_LowerByValue, 40, 3, 3, 3)
DEFINE_SPECIAL(Ceiling_RaiseByValue, 41, 3, 3, 3) DEFINE_SPECIAL(Ceiling_RaiseByValue, 41, 3, 3, 3)
DEFINE_SPECIAL(Ceiling_CrushAndRaise, 42, 3, 4, 4) DEFINE_SPECIAL(Ceiling_CrushAndRaise, 42, 3, 4, 4)
@ -105,9 +105,8 @@ DEFINE_SPECIAL(Light_Strobe, 116, 5, 5, 5)
DEFINE_SPECIAL(Light_Stop, 117, 1, 1, 1) DEFINE_SPECIAL(Light_Stop, 117, 1, 1, 1)
DEFINE_SPECIAL(Thing_Damage, 119, 2, 3, 3) DEFINE_SPECIAL(Thing_Damage, 119, 2, 3, 3)
DEFINE_SPECIAL(Radius_Quake, 120, 5, 5, 5) // Earthquake DEFINE_SPECIAL(Radius_Quake, 120, 5, 5, 5) // Earthquake
DEFINE_SPECIAL(Line_SetIdentification, 121, -1, -1, 5) DEFINE_SPECIAL(Line_SetIdentification, 121, -1, -1, 5)
#if 0 // Skull Tag specials that might be added later #if 0 // Skull Tag specials that might be added later
Thing_SetGravity, 122, -1, -1) Thing_SetGravity, 122, -1, -1)
Thing_ReverseGravity, 123, -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(FS_Execute, 158, 1, 4, 4)
DEFINE_SPECIAL(Sector_SetPlaneReflection, 159, 3, 3, 3) DEFINE_SPECIAL(Sector_SetPlaneReflection, 159, 3, 3, 3)
DEFINE_SPECIAL(Sector_Set3DFloor, 160, -1, -1, 5) 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 // [RH] Begin new specials for ZDoom
DEFINE_SPECIAL(Generic_Crusher2, 169, 5, 5, 5) DEFINE_SPECIAL(Generic_Crusher2, 169, 5, 5, 5)

View file

@ -262,6 +262,8 @@ enum
MF4_FRIGHTENED = 0x40000000, // Monster runs away from player MF4_FRIGHTENED = 0x40000000, // Monster runs away from player
/* = 0x80000000, */ /* = 0x80000000, */
// --- mobj.flags5 ---
MF5_FASTER = 0x00000001, // moves faster when DF_FAST_MONSTERS or nightmare is on. 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_FASTMELEE = 0x00000002, // has a faster melee attack when DF_FAST_MONSTERS or nightmare is on.
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
@ -296,6 +298,8 @@ enum
MF5_PAINLESS = 0x40000000, // Actor always inflicts painless damage. MF5_PAINLESS = 0x40000000, // Actor always inflicts painless damage.
MF5_MOVEWITHSECTOR = 0x80000000, // P_ChangeSector() will still process this actor if it has MF_NOBLOCKMAP 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_NOBOSSRIP = 0x00000001, // For rippermissiles: Don't rip through bosses.
MF6_THRUSPECIES = 0x00000002, // Actors passes through other of the same species. MF6_THRUSPECIES = 0x00000002, // Actors passes through other of the same species.
MF6_MTHRUSPECIES = 0x00000004, // Missile passes through actors of its shooter's species. MF6_MTHRUSPECIES = 0x00000004, // Missile passes through actors of its shooter's species.
@ -369,7 +373,7 @@ enum replace_t
ALLOW_REPLACE = 1 ALLOW_REPLACE = 1
}; };
enum EBounceType enum EBounceFlags
{ {
BOUNCE_Walls = 1<<0, // bounces off of walls BOUNCE_Walls = 1<<0, // bounces off of walls
BOUNCE_Floors = 1<<1, // bounces off of floors BOUNCE_Floors = 1<<1, // bounces off of floors
@ -377,7 +381,7 @@ enum EBounceType
BOUNCE_Actors = 1<<3, // bounces off of some actors 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_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_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 BOUNCE_UseSeeSound = 1<<7, // compatibility fallback. This will only be set by
// the compatibility handlers for the old bounce flags. // 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_Quiet = 1<<9, // Strife's grenades don't make a bouncing sound
BOUNCE_ExplodeOnWater = 1<<10, // explodes when hitting a water surface BOUNCE_ExplodeOnWater = 1<<10, // explodes when hitting a water surface
BOUNCE_CanBounceWater = 1<<11, // can bounce on water 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, 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_Heretic = BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_HereticType,
BOUNCE_Doom = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff, BOUNCE_Doom = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff,
BOUNCE_Hexen = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors, 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 // combined types
BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound, BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound,
@ -411,6 +421,20 @@ enum EBounceType
// being "Doom" or "Hexen" and BOUNCE_AllActors was the separate // being "Doom" or "Hexen" and BOUNCE_AllActors was the separate
// MF5_BOUNCEONACTORS, you must set BOUNCE_Actors for BOUNCE_AllActors to have // MF5_BOUNCEONACTORS, you must set BOUNCE_Actors for BOUNCE_AllActors to have
// an effect. // 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 // [RH] Like msecnode_t, but for the blockmap
@ -680,6 +704,10 @@ public:
bool CanSeek(AActor *target) const; bool CanSeek(AActor *target) const;
fixed_t GetGravity() const;
bool IsSentient() const;
// info for drawing // info for drawing
// NOTE: The first member variable *must* be x. // NOTE: The first member variable *must* be x.
fixed_t x,y,z; fixed_t x,y,z;
@ -726,7 +754,7 @@ public:
SWORD movecount; // when 0, select a new dir SWORD movecount; // when 0, select a new dir
TObjPtr<AActor> target; // thing being chased/attacked (or NULL) TObjPtr<AActor> target; // thing being chased/attacked (or NULL)
// also the originator for missiles // 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 TObjPtr<AActor> LastHeard; // [RH] Last actor this one heard
SDWORD reactiontime; // if non 0, don't attack yet; used by SDWORD reactiontime; // if non 0, don't attack yet; used by
// player to freeze a bit after teleporting // player to freeze a bit after teleporting
@ -738,7 +766,7 @@ public:
WORD SpawnAngle; WORD SpawnAngle;
int skillrespawncount; int skillrespawncount;
int TIDtoHate; // TID of things to hate (0 if none) 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> tracer; // Thing being chased/attacked for tracers
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks) TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
fixed_t floorclip; // value to use for floor clipping fixed_t floorclip; // value to use for floor clipping
@ -766,6 +794,8 @@ public:
int FastChaseStrafeCount; int FastChaseStrafeCount;
fixed_t pushfactor; fixed_t pushfactor;
int lastpush; 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 AActor *BlockingMobj; // Actor that blocked the last move
line_t *BlockingLine; // Line 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)); return static_cast<T *>(AActor::StaticSpawn (RUNTIME_CLASS(T), x, y, z, allowreplacement));
} }
void PrintMiscActorInfo(AActor * query);
#define S_FREETARGMOBJ 1 #define S_FREETARGMOBJ 1
#endif // __P_MOBJ_H__ #endif // __P_MOBJ_H__

View file

@ -778,10 +778,31 @@ CCMD(linetarget)
linetarget->GetClass()->TypeName.GetChars(), linetarget->GetClass()->TypeName.GetChars(),
linetarget->health, linetarget->health,
linetarget->SpawnHealth()); linetarget->SpawnHealth());
PrintMiscActorInfo(linetarget);
} }
else Printf("No target found\n"); 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");
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
// //

View file

@ -2094,6 +2094,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
case DEM_SUMMON: case DEM_SUMMON:
case DEM_SUMMONFRIEND: case DEM_SUMMONFRIEND:
case DEM_SUMMONFOE: case DEM_SUMMONFOE:
case DEM_SUMMONMBF:
case DEM_SUMMON2: case DEM_SUMMON2:
case DEM_SUMMONFRIEND2: case DEM_SUMMONFRIEND2:
case DEM_SUMMONFOE2: case DEM_SUMMONFOE2:
@ -2132,7 +2133,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
source->z + 8 * FRACUNIT, ALLOW_REPLACE); source->z + 8 * FRACUNIT, ALLOW_REPLACE);
if (spawned != NULL) if (spawned != NULL)
{ {
if (type == DEM_SUMMONFRIEND || type == DEM_SUMMONFRIEND2) if (type == DEM_SUMMONFRIEND || type == DEM_SUMMONFRIEND2 || type == DEM_SUMMONMBF)
{ {
if (spawned->CountsAsKill()) if (spawned->CountsAsKill())
{ {
@ -2142,6 +2143,8 @@ void Net_DoCommand (int type, BYTE **stream, int player)
spawned->flags |= MF_FRIENDLY; spawned->flags |= MF_FRIENDLY;
spawned->LastHeard = players[player].mo; spawned->LastHeard = players[player].mo;
spawned->health = spawned->SpawnHealth(); spawned->health = spawned->SpawnHealth();
if (type == DEM_SUMMONMBF)
spawned->flags3 |= MF3_NOBLOCKMONST;
} }
else if (type == DEM_SUMMONFOE || type == DEM_SUMMONFOE2) else if (type == DEM_SUMMONFOE || type == DEM_SUMMONFOE2)
{ {
@ -2440,6 +2443,7 @@ void Net_SkipCommand (int type, BYTE **stream)
case DEM_SUMMON: case DEM_SUMMON:
case DEM_SUMMONFRIEND: case DEM_SUMMONFRIEND:
case DEM_SUMMONFOE: case DEM_SUMMONFOE:
case DEM_SUMMONMBF:
case DEM_SPRAY: case DEM_SPRAY:
case DEM_MORPHEX: case DEM_MORPHEX:
case DEM_KILLCLASSCHEAT: case DEM_KILLCLASSCHEAT:

View file

@ -839,5 +839,6 @@ CCMD (playerinfo)
Printf ("PlayerClass: %s (%d)\n", Printf ("PlayerClass: %s (%d)\n",
ui->PlayerClass == -1 ? "Random" : PlayerClasses[ui->PlayerClass].Type->Meta.GetMetaString (APMETA_DisplayName), ui->PlayerClass == -1 ? "Random" : PlayerClasses[ui->PlayerClass].Type->Meta.GetMetaString (APMETA_DisplayName),
ui->PlayerClass); ui->PlayerClass);
PrintMiscActorInfo(players[i].mo);
} }
} }

View file

@ -154,6 +154,7 @@ enum EDemoCommand
DEM_ADDSLOTDEFAULT, // 55 DEM_ADDSLOTDEFAULT, // 55
DEM_ADDSLOT, // 56 DEM_ADDSLOT, // 56
DEM_SETSLOT, // 57 DEM_SETSLOT, // 57
DEM_SUMMONMBF,
}; };
// The following are implemented by cht_DoCheat in m_cheat.cpp // The following are implemented by cht_DoCheat in m_cheat.cpp

View file

@ -21,6 +21,7 @@ static FRandom pr_fireshotgun2 ("FireSG2");
static FRandom pr_fireplasma ("FirePlasma"); static FRandom pr_fireplasma ("FirePlasma");
static FRandom pr_firerail ("FireRail"); static FRandom pr_firerail ("FireRail");
static FRandom pr_bfgspray ("BFGSpray"); static FRandom pr_bfgspray ("BFGSpray");
static FRandom pr_oldbfg ("OldBFG");
// //
// A_Punch // A_Punch
@ -553,3 +554,48 @@ DEFINE_ACTION_FUNCTION(AActor, A_BFGsound)
S_Sound (self, CHAN_WEAPON, "weapons/bfgf", 1, ATTN_NORM); 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
}

View file

@ -553,7 +553,7 @@ void APowerStrength::Tick ()
PalEntry APowerStrength::GetBlend () PalEntry APowerStrength::GetBlend ()
{ {
// slowly fade the berzerk out // slowly fade the berserk out
int cnt = 12 - (EffectTics >> 6); int cnt = 12 - (EffectTics >> 6);
if (cnt > 0) if (cnt > 0)
@ -570,35 +570,10 @@ PalEntry APowerStrength::GetBlend ()
IMPLEMENT_CLASS (APowerInvisibility) IMPLEMENT_CLASS (APowerInvisibility)
IMPLEMENT_CLASS (APowerShadow) IMPLEMENT_CLASS (APowerShadow)
//=========================================================================== // Invisibility flag combos
// #define INVISIBILITY_FLAGS1 (MF_SHADOW | MF_STEALTH)
// APowerInvisibility :: CommonInit #define INVISIBILITY_FLAGS3 (MF3_GHOST)
// #define INVISIBILITY_FLAGS5 (MF5_CANTSEEK)
// 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;
}
}
}
//=========================================================================== //===========================================================================
// //
@ -608,7 +583,39 @@ void APowerInvisibility::CommonInit()
void APowerInvisibility::InitEffect () 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(); Super::DoEffect();
// Due to potential interference with other PowerInvisibility items // Due to potential interference with other PowerInvisibility items
// the effect has to be refreshed each tic. // 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 (Owner != NULL)
{ {
if (flags5 & MF5_CANTSEEK) Owner->flags5 &= ~MF5_CANTSEEK; Owner->flags &= ~(flags & INVISIBILITY_FLAGS1);
if (flags3 & MF3_GHOST) Owner->flags3 &= ~MF3_GHOST; Owner->flags3 &= ~(flags3 & INVISIBILITY_FLAGS3);
Owner->flags &= ~MF_SHADOW; Owner->flags5 &= ~(flags5 & INVISIBILITY_FLAGS5);
Owner->RenderStyle = STYLE_Normal;
Owner->alpha = OPAQUE; Owner->RenderStyle = STYLE_Normal;//OwnersNormalStyle;
Owner->alpha = OPAQUE;//OwnersNormalAlpha;
// Check whether there are other invisibility items and refresh their effect. // 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 // 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) if (item->IsKindOf(RUNTIME_CLASS(APowerInvisibility)) && item != this)
{ {
static_cast<APowerInvisibility*>(item)->InitEffect(); static_cast<APowerInvisibility*>(item)->DoEffect();
} }
item = item->Inventory; item = item->Inventory;
} }
@ -667,16 +699,36 @@ int APowerInvisibility::AlterWeaponSprite (vissprite_t *vis)
// Blink if the powerup is wearing off // Blink if the powerup is wearing off
if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8)) if (changed == 0 && EffectTics < 4*32 && !(EffectTics & 8))
{ {
vis->RenderStyle = STYLE_Normal; vis->RenderStyle = STYLE_Normal;//OwnersNormalStyle;
vis->alpha = OPAQUE; vis->alpha = OPAQUE;//OwnersNormalAlpha;
return 1; return 1;
} }
else if (changed == 1) else if (changed == 1)
{ {
// something else set the weapon sprite back to opaque but this item is still active. // something else set the weapon sprite back to opaque but this item is still active.
fixed_t ts = MIN(Strength * (special1 + 1), FRACUNIT); fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT;
vis->alpha = clamp<fixed_t>((OPAQUE - ts), 0, OPAQUE); vis->alpha = clamp<fixed_t>((/*OwnersNormalAlpha*/OPAQUE - ts), 0, OPAQUE);
vis->RenderStyle = (Mode == NAME_Fuzzy ? STYLE_OptFuzzy : STYLE_Translucent); 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 // Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible
if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0))

View file

@ -81,11 +81,12 @@ class APowerInvisibility : public APowerup
DECLARE_CLASS (APowerInvisibility, APowerup) DECLARE_CLASS (APowerInvisibility, APowerup)
protected: protected:
bool HandlePickup (AInventory *item); bool HandlePickup (AInventory *item);
void CommonInit ();
void InitEffect (); void InitEffect ();
void DoEffect (); void DoEffect ();
void EndEffect (); void EndEffect ();
int AlterWeaponSprite (vissprite_t *vis); int AlterWeaponSprite (vissprite_t *vis);
// FRenderStyle OwnersNormalStyle;
// fixed_t OwnersNormalAlpha;
}; };
// Needed only for m_cheat.cpp now // Needed only for m_cheat.cpp now

View file

@ -1728,3 +1728,30 @@ bool AMapRevealer::TryPickup (AActor *&toucher)
return true; 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;
}

View file

@ -475,4 +475,16 @@ public:
bool bDepleted; 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__ #endif //__A_PICKUPS_H__

View file

@ -211,7 +211,9 @@ FActorInfo *FActorInfo::GetReplacement (bool lookskill)
FActorInfo *FActorInfo::GetReplacee (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: \ Printf("Warning: incorrect actor name in definition of skill %s: \
inexistent class %s is replaced by class %s\n\ inexistent class %s is replaced by class %s\n\
Skill replacement will be ignored for this actor.\n", Skill replacement will be ignored for this actor.\n",
@ -229,7 +231,12 @@ FActorInfo *FActorInfo::GetReplacee (bool lookskill)
// potential infinite recursion. // potential infinite recursion.
FActorInfo *savedrep = Replacee; FActorInfo *savedrep = Replacee;
Replacee = NULL; 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; return rep;
} }
@ -445,6 +452,11 @@ CCMD (summonfriend)
SummonActor (DEM_SUMMONFRIEND, DEM_SUMMONFRIEND2, argv); SummonActor (DEM_SUMMONFRIEND, DEM_SUMMONFRIEND2, argv);
} }
CCMD (summonmbf)
{
SummonActor (DEM_SUMMONMBF, DEM_SUMMONFRIEND2, argv);
}
CCMD (summonfoe) CCMD (summonfoe)
{ {
SummonActor (DEM_SUMMONFOE, DEM_SUMMONFOE2, argv); SummonActor (DEM_SUMMONFOE, DEM_SUMMONFOE2, argv);

View file

@ -25,8 +25,11 @@ xx(Ghost)
xx(Reflective) xx(Reflective)
// Invisibility types // Invisibility types
xx(Additive)
xx(Cumulative) xx(Cumulative)
xx(Fuzzy) xx(Fuzzy)
xx(Opaque)
xx(Stencil)
// Healingradius types // Healingradius types
xx(Mana) xx(Mana)

View file

@ -2426,6 +2426,8 @@ enum
APROP_Dropped = 18, APROP_Dropped = 18,
APROP_Notarget = 19, APROP_Notarget = 19,
APROP_Species = 20, APROP_Species = 20,
// APROP_Nametag
APROP_Score = 22,
}; };
// These are needed for ACS's APROP_RenderStyle // These are needed for ACS's APROP_RenderStyle
@ -2578,6 +2580,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
case APROP_Species: case APROP_Species:
actor->Species = FBehavior::StaticLookupString(value); actor->Species = FBehavior::StaticLookupString(value);
break; break;
case APROP_Score:
actor->Score = value;
break;
} }
} }
@ -2642,6 +2648,7 @@ int DLevelScript::GetActorProperty (int tid, int property)
{ {
return 0; return 0;
} }
case APROP_Score: return actor->Score;
default: return 0; default: return 0;
} }
} }

View file

@ -376,15 +376,19 @@ bool P_Move (AActor *actor)
fixed_t tryx, tryy, deltax, deltay, origx, origy; fixed_t tryx, tryy, deltax, deltay, origx, origy;
bool try_ok; bool try_ok;
int speed; int speed = actor->Speed;
int movefactor = ORIG_FRICTION_FACTOR; int movefactor = ORIG_FRICTION_FACTOR;
int friction = ORIG_FRICTION; int friction = ORIG_FRICTION;
if (actor->flags2 & MF2_BLASTED) if (actor->flags2 & MF2_BLASTED)
{
return true; return true;
}
if (actor->movedir == DI_NODIR) if (actor->movedir == DI_NODIR)
{
return false; return false;
}
// [RH] Instead of yanking non-floating monsters to the ground, // [RH] Instead of yanking non-floating monsters to the ground,
// let gravity drop them down, unless they're moving down a step. // let gravity drop them down, unless they're moving down a step.
@ -490,6 +494,7 @@ bool P_Move (AActor *actor)
else else
actor->z -= actor->FloatSpeed; actor->z -= actor->FloatSpeed;
// [RH] Check to make sure there's nothing in the way of the float // [RH] Check to make sure there's nothing in the way of the float
if (P_TestMobjZ (actor)) if (P_TestMobjZ (actor))
{ {
@ -500,7 +505,9 @@ bool P_Move (AActor *actor)
} }
if (!spechit.Size ()) if (!spechit.Size ())
{
return false; return false;
}
// open any specials // open any specials
actor->movedir = DI_NODIR; actor->movedir = DI_NODIR;
@ -684,7 +691,7 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay)
return; return;
} }
actor->movedir = DI_NODIR; // can not move actor->movedir = DI_NODIR; // cannot move
} }
@ -2315,7 +2322,7 @@ void A_Chase(AActor *self)
// A_FaceTarget // A_FaceTarget
// //
//============================================================================= //=============================================================================
void A_FaceTarget(AActor *self) void A_FaceTarget (AActor *self)
{ {
if (!self->target) if (!self->target)
return; return;

View file

@ -1017,13 +1017,12 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
damage = target->TakeSpecialDamage (inflictor, source, damage, mod); damage = target->TakeSpecialDamage (inflictor, source, damage, mod);
} }
if (damage == -1) if (damage == -1)
{ {
return; return;
} }
// Push the target unless the source's weapon's kickback is 0. // 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 if (inflictor && inflictor != target // [RH] Not if hurting own self
&& !(target->flags & MF_NOCLIP) && !(target->flags & MF_NOCLIP)
&& !(inflictor->flags2 & MF2_NODMGTHRUST) && !(inflictor->flags2 & MF2_NODMGTHRUST)
@ -1047,13 +1046,13 @@ void P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage
// Calculate this as float to avoid overflows so that the // Calculate this as float to avoid overflows so that the
// clamping that had to be done here can be removed. // clamping that had to be done here can be removed.
double fltthrust; double fltthrust;
fltthrust = mod == NAME_MDK ? 10 : 32; fltthrust = mod == NAME_MDK ? 10 : 32;
if (target->Mass > 0) if (target->Mass > 0)
{ {
fltthrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., fltthrust); fltthrust = clamp((damage * 0.125 * kickback) / target->Mass, 0., fltthrust);
} }
thrust = FLOAT2FIXED(fltthrust); thrust = FLOAT2FIXED(fltthrust);

View file

@ -3250,3 +3250,13 @@ int P_FindLineSpecial (const char *string, int *min_args, int *max_args)
} }
return 0; 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)";
}

View file

@ -196,5 +196,6 @@ typedef int (*lnSpecFunc)(struct line_t *line,
extern lnSpecFunc LineSpecials[256]; extern lnSpecFunc LineSpecials[256];
int P_FindLineSpecial (const char *string, int *min_args=NULL, int *max_args=NULL); int P_FindLineSpecial (const char *string, int *min_args=NULL, int *max_args=NULL);
const char *GetSpecialName(int num);
#endif //__P_LNSPEC_H__ #endif //__P_LNSPEC_H__

View file

@ -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); 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, 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); 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); void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target, angle_t angle, int pitch);

View file

@ -1314,7 +1314,8 @@ bool P_CheckPosition (AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm)
while ((ld = it.Next())) 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) if (tm.ceilingz - tm.floorz < thing->height)
@ -2667,7 +2668,7 @@ struct aim_t
bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in); bool AimTraverse3DFloors(const divline_t &trace, intercept_t * in);
#endif #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); FPathTraverse it(startx, starty, endx, endy, PT_ADDLINES|PT_ADDTHINGS);
intercept_t *in; intercept_t *in;
@ -2839,18 +2840,20 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
if (th == shootthing) if (th == shootthing)
continue; // can't shoot self continue; // can't shoot self
if (!(th->flags&MF_SHOOTABLE)) if (!checknonshootable) // For info CCMD, ignore stuff about GHOST and SHOOTABLE flags
continue; // corpse or something
// check for physical attacks on a ghost
if ((th->flags3 & MF3_GHOST) &&
shootthing->player && // [RH] Be sure shootthing is a player
shootthing->player->ReadyWeapon &&
(shootthing->player->ReadyWeapon->flags2 & MF2_THRUGHOST))
{ {
continue; if (!(th->flags&MF_SHOOTABLE))
continue; // corpse or something
// check for physical attacks on a ghost
if ((th->flags3 & MF3_GHOST) &&
shootthing->player && // [RH] Be sure shootthing is a player
shootthing->player->ReadyWeapon &&
(shootthing->player->ReadyWeapon->flags2 & MF2_THRUGHOST))
{
continue;
}
} }
dist = FixedMul (attackrange, in->frac); dist = FixedMul (attackrange, in->frac);
#ifdef _3DFLOORS #ifdef _3DFLOORS
@ -2974,6 +2977,11 @@ void aim_t::AimTraverse (fixed_t startx, fixed_t starty, fixed_t endx, fixed_t e
aimpitch=thingpitch; aimpitch=thingpitch;
return; 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 // 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 x2;
fixed_t y2; fixed_t y2;
@ -3051,7 +3059,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
} }
#endif #endif
aim.AimTraverse (t1->x, t1->y, x2, y2); aim.AimTraverse (t1->x, t1->y, x2, y2, checknonshootable);
if (!aim.linetarget) if (!aim.linetarget)
{ {
@ -4124,7 +4132,6 @@ void P_RadiusAttack (AActor *bombspot, AActor *bombsource, int bombdamage, int b
} }
} }
// //
// SECTOR HEIGHT CHANGING // SECTOR HEIGHT CHANGING
// After modifying a sector's floor or ceiling height, // After modifying a sector's floor or ceiling height,

View file

@ -325,6 +325,9 @@ void AActor::Serialize (FArchive &arc)
<< pushfactor << pushfactor
<< Species; << Species;
if (SaveVersion >= 1819)
arc << Score;
if (arc.IsStoring ()) if (arc.IsStoring ())
{ {
int convnum = 0; int convnum = 0;
@ -1845,7 +1848,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
BlockingMobj->y, BlockingMobj->y,
mo->x, mo->y); mo->x, mo->y);
// Change angle for deflection/reflection // Change angle for deflection/reflection
if (mo->AdjustReflectionAngle (BlockingMobj, angle)) if (mo->AdjustReflectionAngle (BlockingMobj, angle))
{ {
goto explode; goto explode;
@ -2054,12 +2057,13 @@ void P_MonsterFallingDamage (AActor *mo)
// //
// P_ZMovement // P_ZMovement
// //
void P_ZMovement (AActor *mo, fixed_t oldfloorz) void P_ZMovement (AActor *mo, fixed_t oldfloorz)
{ {
fixed_t dist; fixed_t dist;
fixed_t delta; fixed_t delta;
fixed_t oldz = mo->z; fixed_t oldz = mo->z;
// //
// check for smooth step up // check for smooth step up
// //
@ -2084,8 +2088,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz)
if (!mo->waterlevel || mo->flags & MF_CORPSE || (mo->player && if (!mo->waterlevel || mo->flags & MF_CORPSE || (mo->player &&
!(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove))) !(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove)))
{ {
fixed_t grav = (fixed_t)(level.gravity * mo->Sector->gravity * fixed_t grav = mo->GetGravity();
FIXED2FLOAT(mo->gravity) * 81.92);
// [RH] Double gravity only if running off a ledge. Coming down from // [RH] Double gravity only if running off a ledge. Coming down from
// an upward thrust (e.g. a jump) should not double it. // an upward thrust (e.g. a jump) should not double it.
@ -3404,7 +3407,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
AActor *actor; AActor *actor;
actor = static_cast<AActor *>(const_cast<PClass *>(type)->CreateNew ()); actor = static_cast<AActor *>(const_cast<PClass *>(type)->CreateNew ());
actor->x = actor->PrevX = ix; actor->x = actor->PrevX = ix;
@ -5347,6 +5350,7 @@ int AActor::SpawnHealth()
return (adj <= 0) ? 1 : adj; return (adj <= 0) ? 1 : adj;
} }
} }
FDropItem *AActor::GetDropItems() FDropItem *AActor::GetDropItems()
{ {
unsigned int index = GetClass()->Meta.GetMetaInt (ACMETA_DropItems) - 1; unsigned int index = GetClass()->Meta.GetMetaInt (ACMETA_DropItems) - 1;
@ -5358,6 +5362,21 @@ FDropItem *AActor::GetDropItems()
return NULL; 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 // DropItem handling
@ -5388,3 +5407,68 @@ int StoreDropItemChain(FDropItem *chain)
return DropItemList.Push (chain) + 1; 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)));
}
}

View file

@ -2535,7 +2535,7 @@ void player_t::Serialize (FArchive &arc)
<< ConversationPC << ConversationPC
<< ConversationNPCAngle << ConversationNPCAngle
<< ConversationFaceTalker; << ConversationFaceTalker;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
arc << frags[i]; arc << frags[i];
for (i = 0; i < NUMPSPRITES; i++) for (i = 0; i < NUMPSPRITES; i++)

View file

@ -704,8 +704,7 @@ bool FScanner::GetFloat ()
Float = (float)strtod (String, &stopper); Float = (float)strtod (String, &stopper);
if (*stopper != 0) if (*stopper != 0)
{ {
I_Error ("SC_GetFloat: Bad numeric constant \"%s\".\n" ScriptError ("SC_GetFloat: Bad numeric constant \"%s\".", String);
"Script %s, Line %d\n", String, ScriptName.GetChars(), Line);
} }
Number = (int)Float; Number = (int)Float;
return true; return true;

View file

@ -5,6 +5,7 @@
#include "info.h" #include "info.h"
#include "s_sound.h" #include "s_sound.h"
#include "sc_man.h" #include "sc_man.h"
#include "cmdlib.h"
class FScanner; class FScanner;
@ -25,6 +26,9 @@ struct FFlagDef
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2); FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2);
void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int index); 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(); ~FStateExpressions();
int Add(FxExpression *x, const PClass *o, bool c); int Add(FxExpression *x, const PClass *o, bool c);
int Reserve(int num, const PClass *cls); 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); void Copy(int dest, int src, int cnt);
int ResolveAll(); int ResolveAll();
FxExpression *Get(int no); FxExpression *Get(int no);

View file

@ -560,12 +560,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfArmorType)
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
{ {
ACTION_PARAM_START(5); ACTION_PARAM_START(7);
ACTION_PARAM_INT(damage, 0); ACTION_PARAM_INT(damage, 0);
ACTION_PARAM_INT(distance, 1); ACTION_PARAM_INT(distance, 1);
ACTION_PARAM_BOOL(hurtSource, 2); ACTION_PARAM_BOOL(hurtSource, 2);
ACTION_PARAM_BOOL(alert, 3); ACTION_PARAM_BOOL(alert, 3);
ACTION_PARAM_INT(fulldmgdistance, 4); ACTION_PARAM_INT(fulldmgdistance, 4);
ACTION_PARAM_INT(nails, 5);
ACTION_PARAM_INT(naildamage, 6);
if (damage < 0) // get parameters from metadata if (damage < 0) // get parameters from metadata
{ {
@ -578,6 +580,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
{ {
if (distance <= 0) distance = damage; 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); P_RadiusAttack (self, self->target, damage, distance, self->DamageType, hurtSource, true, fulldmgdistance);
if (self->z <= self->floorz + (distance<<FRACBITS)) 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; 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;
}

View file

@ -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 // 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); return stricmp(A->name, B->name);
} }
//========================================================================== //==========================================================================
// //
// Initialization // Initialization

View file

@ -75,6 +75,7 @@ DEFINE_MEMBER_VARIABLE_ALIAS(momx, velx, AActor)
DEFINE_MEMBER_VARIABLE_ALIAS(momy, vely, AActor) DEFINE_MEMBER_VARIABLE_ALIAS(momy, vely, AActor)
DEFINE_MEMBER_VARIABLE_ALIAS(momz, velz, AActor) DEFINE_MEMBER_VARIABLE_ALIAS(momz, velz, AActor)
DEFINE_MEMBER_VARIABLE(Damage, 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())) if (num >= 0 && num < int(Size()))
{ {
assert(expressions[num].expr == NULL || expressions[num].cloned); assert(expressions[num].expr == NULL || expressions[num].cloned);
expressions[num].expr = x; expressions[num].expr = x;
expressions[num].cloned = false; expressions[num].cloned = cloned;
} }
} }

View file

@ -849,10 +849,11 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor)
//========================================================================== //==========================================================================
DEFINE_PROPERTY(bouncetype, S, Actor) DEFINE_PROPERTY(bouncetype, S, Actor)
{ {
static const char *names[] = { "None", "Doom", "Heretic", "Hexen", "DoomCompat", "HereticCompat", "HexenCompat", NULL }; static const char *names[] = { "None", "Doom", "Heretic", "Hexen", "DoomCompat", "HereticCompat", "HexenCompat", "Grenade", "Classic", NULL };
static const BYTE flags[] = { BOUNCE_None, static const int flags[] = { BOUNCE_None,
BOUNCE_Doom, BOUNCE_Heretic, BOUNCE_Hexen, 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); PROP_STRING_PARM(id, 0);
int match = MatchString(id, names); int match = MatchString(id, names);
if (match < 0) if (match < 0)
@ -1294,7 +1295,6 @@ DEFINE_CLASS_PROPERTY(pickupsound, S, Inventory)
//========================================================================== //==========================================================================
DEFINE_CLASS_PROPERTY(pickupannouncerentry, S, Inventory) DEFINE_CLASS_PROPERTY(pickupannouncerentry, S, Inventory)
{ {
PROP_STRING_PARM(str, 0);
} }
//========================================================================== //==========================================================================

View file

@ -67,7 +67,7 @@ struct TVector2
} }
TVector2 (double a, double b) TVector2 (double a, double b)
: X(a), Y(b) : X(vec_t(a)), Y(vec_t(b))
{ {
} }

View file

@ -64,7 +64,7 @@
// Protocol version used in demos. // Protocol version used in demos.
// Bump it if you change existing DEM_ commands or add new ones. // Bump it if you change existing DEM_ commands or add new ones.
// Otherwise, it should be safe to leave it alone. // Otherwise, it should be safe to leave it alone.
#define DEMOGAMEVERSION 0x211 #define DEMOGAMEVERSION 0x212
// Minimum demo version we can play. // Minimum demo version we can play.
// Bump it whenever you change or remove existing DEM_ commands. // Bump it whenever you change or remove existing DEM_ commands.

View file

@ -44,6 +44,7 @@ ACTOR Actor native //: Thinker
native fixed_t momx; // alias for velx native fixed_t momx; // alias for velx
native fixed_t momy; // alias for vely native fixed_t momy; // alias for vely
native fixed_t momz; // alias for velz native fixed_t momz; // alias for velz
native int score;
action native A_MonsterRail(); action native A_MonsterRail();
action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15); 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_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_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_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_SetTranslucent(float alpha, int style = 0);
action native A_FadeIn(float reduce = 0.1); action native A_FadeIn(float reduce = 0.1);
action native A_FadeOut(float reduce = 0.1, bool remove = true); 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_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_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); 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();
action native A_Respawn(bool fog = true); action native A_Respawn(bool fog = true);
action native A_BarrelDestroy(); 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_DropWeaponPieces(class<Actor> p1, class<Actor> p2, class<Actor> p3);
action native A_PigPain (); action native A_PigPain ();
action native A_MonsterRefire(int chance, state label); 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_SetPitch(float pitch);
action native A_ScaleVelocity(float scale); 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_ChangeVelocity(float x = 0, float y = 0, float z = 0, int flags = 0);
action native A_SetArg(int pos, int value); 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 States
{ {

View file

@ -35,6 +35,7 @@ ACTOR Inventory native
action native A_RailWait(); action native A_RailWait();
action native A_BFGsound(); action native A_BFGsound();
action native A_FireBFG(); action native A_FireBFG();
action native A_FireOldBFG();
action native A_ReFire(); action native A_ReFire();
action native A_ClearReFire(); action native A_ClearReFire();
action native A_CheckReload(); 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 Actor Ammo : Inventory native
{ {
+INVENTORY.KEEPDEPLETED +INVENTORY.KEEPDEPLETED
@ -161,6 +170,7 @@ ACTOR PowerStrength : Powerup native
ACTOR PowerInvisibility : Powerup native ACTOR PowerInvisibility : Powerup native
{ {
+SHADOW
Powerup.Duration -60 Powerup.Duration -60
Powerup.Strength 80 Powerup.Strength 80
Powerup.Mode "Fuzzy" Powerup.Mode "Fuzzy"

View file

@ -137,6 +137,7 @@ ACTOR RandomSpawner native
+NOBLOCKMAP +NOBLOCKMAP
+NOSECTOR +NOSECTOR
+NOGRAVITY +NOGRAVITY
+THRUACTORS
} }
// Fast projectiles ----------------------------------------------------------- // Fast projectiles -----------------------------------------------------------