- fixed: A_CountdownArg used 0 based indices although all uses of it assumed

it is 1-based.
- added MF5_DONTRIP flag.
- added CheckActorFloorTexture, CheckActorCeilingTexture and
  GetActorLightLevel ACS functions.
- added IF_ADDITIVETIME flag to create powerups that add their duration
  to the one of the currently active item of the same type.
- fixed: bouncecount wasn't decreased when bouncing on walls.
- Added MF5_ALWAYSRESPAWN and MF5_NEVERRESPAWN flags that selectively
  enable or disable monster respawning regardless of skill setting.
- Prettified deprecated flag handling.


SVN r780 (trunk)
This commit is contained in:
Christoph Oelckers 2008-03-01 16:59:17 +00:00
parent 03617dc6f0
commit 5589f6b7a1
10 changed files with 107 additions and 25 deletions

View file

@ -1,4 +1,15 @@
March 1, 2008 (Changes by Graf Zahl) March 1, 2008 (Changes by Graf Zahl)
- fixed: A_CountdownArg used 0 based indices although all uses of it assumed
1-based.
- added MF5_DONTRIP flag.
- added CheckActorFloorTexture, CheckActorCeilingTexture and
GetActorLightLevel ACS functions.
- added IF_ADDITIVETIME flag to create powerups that add their duration
to the one of the currently active item of the same type.
- fixed: bouncecount wasn't decreased when bouncing on walls.
- Added MF5_ALWAYSRESPAWN and MF5_NEVERRESPAWN flags that selectively
enable or disable monster respawning regardless of skill setting.
- Prettified deprecated flag handling.
- Fixed: When starting a level while the music has been paused S_Start has - Fixed: When starting a level while the music has been paused S_Start has
to stop the old music so the new one always starts at the beginning. to stop the old music so the new one always starts at the beginning.
- Fixed:: AActor::master was not serialized. - Fixed:: AActor::master was not serialized.

View file

@ -294,6 +294,10 @@ enum
MF5_NOPAIN = 0x00004000, // If set the pain state won't be entered MF5_NOPAIN = 0x00004000, // If set the pain state won't be entered
MF5_ALWAYSFAST = 0x00008000, // always uses 'fast' attacking logic MF5_ALWAYSFAST = 0x00008000, // always uses 'fast' attacking logic
MF5_NEVERFAST = 0x00010000, // never uses 'fast' attacking logic MF5_NEVERFAST = 0x00010000, // never uses 'fast' attacking logic
MF5_ALWAYSRESPAWN = 0x00020000, // always respawns, regardless of skill setting
MF5_NEVERRESPAWN = 0x00040000, // never respawns, regardless of skill setting
MF5_DONTRIP = 0x00080000, // Ripping projectiles explode when hittin this actor
// --- mobj.renderflags --- // --- mobj.renderflags ---

View file

@ -58,7 +58,7 @@ bool APowerupGiver::Use (bool pickup)
power->mode = mode; power->mode = mode;
} }
power->ItemFlags |= ItemFlags & IF_ALWAYSPICKUP; power->ItemFlags |= ItemFlags & (IF_ALWAYSPICKUP|IF_ADDITIVETIME);
if (power->TryPickup (Owner)) if (power->TryPickup (Owner))
{ {
return true; return true;
@ -259,7 +259,12 @@ bool APowerup::HandlePickup (AInventory *item)
} }
// Only increase the EffectTics, not decrease it. // Only increase the EffectTics, not decrease it.
// Color also gets transferred only when the new item has an effect. // Color also gets transferred only when the new item has an effect.
if (power->EffectTics > EffectTics) if (power->ItemFlags & IF_ADDITIVETIME)
{
EffectTics += power->EffectTics;
BlendColor = power->BlendColor;
}
else if (power->EffectTics > EffectTics)
{ {
EffectTics = power->EffectTics; EffectTics = power->EffectTics;
BlendColor = power->BlendColor; BlendColor = power->BlendColor;

View file

@ -90,7 +90,7 @@ enum
IF_INVBAR = 1<<6, // Item appears in the inventory bar IF_INVBAR = 1<<6, // Item appears in the inventory bar
IF_HUBPOWER = 1<<7, // Powerup is kept when moving in a hub IF_HUBPOWER = 1<<7, // Powerup is kept when moving in a hub
IF_INTERHUBSTRIP = 1<<8, // Item is removed when travelling between hubs IF_INTERHUBSTRIP = 1<<8, // Item is removed when travelling between hubs
//IF_PICKUPFLASH = 1<<9, // superseded by 'PickupFlash' property. IF_ADDITIVETIME = 1<<9, // when picked up while another item is active, time is added instead of replaced.
IF_ALWAYSPICKUP = 1<<10, // For IF_AUTOACTIVATE, MaxAmount=0 items: Always "pick up", even if it doesn't do anything IF_ALWAYSPICKUP = 1<<10, // For IF_AUTOACTIVATE, MaxAmount=0 items: Always "pick up", even if it doesn't do anything
IF_FANCYPICKUPSOUND = 1<<11, // Play pickup sound in "surround" mode IF_FANCYPICKUPSOUND = 1<<11, // Play pickup sound in "surround" mode
IF_BIGPOWERUP = 1<<12, // Affected by RESPAWN_SUPER dmflag IF_BIGPOWERUP = 1<<12, // Affected by RESPAWN_SUPER dmflag

View file

@ -5256,6 +5256,41 @@ int DLevelScript::RunScript ()
STACK(3) = P_Thing_Damage (STACK(3), activator, STACK(2), FName(FBehavior::StaticLookupString(STACK(1)))); STACK(3) = P_Thing_Damage (STACK(3), activator, STACK(2), FName(FBehavior::StaticLookupString(STACK(1))));
sp -= 2; sp -= 2;
break; break;
case PCD_CHECKACTORCEILINGTEXTURE:
{
AActor *actor = SingleActorFromTID(STACK(2), activator);
if (actor != NULL)
{
FTexture *tex = TexMan.FindTexture(FBehavior::StaticLookupString(STACK(1)));
STACK(2) = (tex == TexMan[actor->Sector->ceilingpic]);
}
else STACK(2)=0;
sp--;
break;
}
case PCD_CHECKACTORFLOORTEXTURE:
{
AActor *actor = SingleActorFromTID(STACK(2), activator);
if (actor != NULL)
{
FTexture *tex = TexMan.FindTexture(FBehavior::StaticLookupString(STACK(1)));
STACK(2) = (tex == TexMan[actor->Sector->floorpic]);
}
else STACK(2)=0;
sp--;
break;
}
case PCD_GETACTORLIGHTLEVEL:
AActor *actor = SingleActorFromTID(STACK(1), activator);
if (actor != NULL)
{
STACK(1) = actor->Sector->lightlevel;
}
else STACK(1)=0;
break;
} }
} }

View file

@ -544,6 +544,9 @@ public:
PCD_THINGDAMAGE2, PCD_THINGDAMAGE2,
PCD_USEINVENTORY, PCD_USEINVENTORY,
PCD_USEACTORINVENTORY, PCD_USEACTORINVENTORY,
PCD_CHECKACTORCEILINGTEXTURE,
PCD_CHECKACTORFLOORTEXTURE,
/*340*/ PCD_GETACTORLIGHTLEVEL,
PCODE_COMMAND_COUNT PCODE_COMMAND_COUNT
}; };

View file

@ -1019,7 +1019,7 @@ bool PIT_CheckThing (AActor *thing)
{ {
return true; return true;
} }
if (DoRipping) if (DoRipping && !(thing->flags5 & MF5_DONTRIP))
{ {
if (LastRipped != thing) if (LastRipped != thing)
{ {
@ -2475,6 +2475,13 @@ bool P_BounceWall (AActor *mo)
return true; return true;
} }
// The amount of bounces is limited
if (mo->bouncecount>0 && --mo->bouncecount==0)
{
P_ExplodeMissile(mo, NULL, NULL);
return true;
}
side = P_PointOnLineSide (mo->x, mo->y, line); side = P_PointOnLineSide (mo->x, mo->y, line);
lineangle = R_PointToAngle2 (0, 0, line->dx, line->dy); lineangle = R_PointToAngle2 (0, 0, line->dx, line->dy);
if (side == 1) if (side == 1)

View file

@ -2963,8 +2963,15 @@ void AActor::Tick ()
{ {
int respawn_monsters = G_SkillProperty(SKILLP_Respawn); int respawn_monsters = G_SkillProperty(SKILLP_Respawn);
// check for nightmare respawn // check for nightmare respawn
if (!respawn_monsters || !(flags3 & MF3_ISMONSTER) || (flags2 & MF2_DORMANT)) if (!(flags5 & MF5_ALWAYSRESPAWN))
return; {
if (!respawn_monsters || !(flags3 & MF3_ISMONSTER) || (flags2 & MF2_DORMANT) || (flags5 & MF5_NEVERRESPAWN))
return;
int limit = G_SkillProperty (SKILLP_RespawnLimit);
if (limit > 0 && skillrespawncount >= limit)
return;
}
movecount++; movecount++;
@ -2977,9 +2984,6 @@ void AActor::Tick ()
if (pr_nightmarerespawn() > 4) if (pr_nightmarerespawn() > 4)
return; return;
if (G_SkillProperty (SKILLP_RespawnLimit) && (this)->skillrespawncount >= G_SkillProperty (SKILLP_RespawnLimit))
return;
P_NightmareRespawn (this); P_NightmareRespawn (this);
} }
} }
@ -4405,7 +4409,7 @@ bool P_CheckMissileSpawn (AActor* th)
if (!P_TryMove (th, th->x, th->y, false)) if (!P_TryMove (th, th->x, th->y, false))
{ {
// [RH] Don't explode ripping missiles that spawn inside something // [RH] Don't explode ripping missiles that spawn inside something
if (BlockingMobj == NULL || !(th->flags2 & MF2_RIP)) if (BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (BlockingMobj->flags5 & MF5_DONTRIP))
{ {
// If this is a monster spawned by A_CustomMissile subtract it from the counter. // If this is a monster spawned by A_CustomMissile subtract it from the counter.
if (th->CountsAsKill()) if (th->CountsAsKill())

View file

@ -1915,9 +1915,9 @@ void A_CountdownArg(AActor * self)
{ {
int index=CheckIndex(1); int index=CheckIndex(1);
if (index<0) return; if (index<0) return;
index = EvalExpressionI (StateParameters[index], self); index = EvalExpressionI (StateParameters[index], self) - 1;
if (index<=0 || index>5) return; if (index<0 || index>=5) return;
if (!self->args[index]--) if (!self->args[index]--)
{ {
if (self->flags&MF_MISSILE) if (self->flags&MF_MISSILE)

View file

@ -79,7 +79,7 @@
// [RH] Keep GCC quiet by not using offsetof on Actor types. // [RH] Keep GCC quiet by not using offsetof on Actor types.
#define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1 } #define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1 }
#define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1 } #define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1 }
#define DEFINE_DEPRECATED_FLAG(name, type, index) { index, #name, -1 } #define DEFINE_DEPRECATED_FLAG(name, type) { DEPF_##name, #name, -1 }
struct flagdef struct flagdef
{ {
@ -88,6 +88,15 @@ struct flagdef
int structoffset; int structoffset;
}; };
enum
{
DEPF_FIREDAMAGE,
DEPF_ICEDAMAGE,
DEPF_LOWGRAVITY,
DEPF_LONGMELEERANGE,
DEPF_SHORTMISSILERANGE,
DEPF_PICKUPFLASH
};
static flagdef ActorFlags[]= static flagdef ActorFlags[]=
{ {
@ -221,6 +230,9 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(MF5, NOPAIN, AActor, flags5), DEFINE_FLAG(MF5, NOPAIN, AActor, flags5),
DEFINE_FLAG(MF5, ALWAYSFAST, AActor, flags5), DEFINE_FLAG(MF5, ALWAYSFAST, AActor, flags5),
DEFINE_FLAG(MF5, NEVERFAST, AActor, flags5), DEFINE_FLAG(MF5, NEVERFAST, AActor, flags5),
DEFINE_FLAG(MF5, ALWAYSRESPAWN, AActor, flags5),
DEFINE_FLAG(MF5, NEVERRESPAWN, AActor, flags5),
DEFINE_FLAG(MF5, DONTRIP, AActor, flags5),
// Effect flags // Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
@ -231,11 +243,11 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags), DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags),
// Deprecated flags. Handling must be performed in HandleDeprecatedFlags // Deprecated flags. Handling must be performed in HandleDeprecatedFlags
DEFINE_DEPRECATED_FLAG(FIREDAMAGE, AActor, 0), DEFINE_DEPRECATED_FLAG(FIREDAMAGE, AActor),
DEFINE_DEPRECATED_FLAG(ICEDAMAGE, AActor, 1), DEFINE_DEPRECATED_FLAG(ICEDAMAGE, AActor),
DEFINE_DEPRECATED_FLAG(LOWGRAVITY, AActor, 2), DEFINE_DEPRECATED_FLAG(LOWGRAVITY, AActor),
DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE, AActor, 3), DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE, AActor),
DEFINE_DEPRECATED_FLAG(LONGMELEERANGE, AActor, 4), DEFINE_DEPRECATED_FLAG(LONGMELEERANGE, AActor),
}; };
static flagdef InventoryFlags[] = static flagdef InventoryFlags[] =
@ -252,8 +264,9 @@ static flagdef InventoryFlags[] =
DEFINE_FLAG(IF, BIGPOWERUP, AInventory, ItemFlags), DEFINE_FLAG(IF, BIGPOWERUP, AInventory, ItemFlags),
DEFINE_FLAG(IF, KEEPDEPLETED, AInventory, ItemFlags), DEFINE_FLAG(IF, KEEPDEPLETED, AInventory, ItemFlags),
DEFINE_FLAG(IF, IGNORESKILL, AInventory, ItemFlags), DEFINE_FLAG(IF, IGNORESKILL, AInventory, ItemFlags),
DEFINE_FLAG(IF, ADDITIVETIME, AInventory, ItemFlags),
DEFINE_DEPRECATED_FLAG(PICKUPFLASH, AInventory, 5), DEFINE_DEPRECATED_FLAG(PICKUPFLASH, AInventory),
}; };
@ -385,22 +398,22 @@ static void HandleDeprecatedFlags(AActor *defaults, bool set, int index)
{ {
switch (index) switch (index)
{ {
case 0: // FIREDAMAGE case DEPF_FIREDAMAGE:
defaults->DamageType = set? NAME_Fire : NAME_None; defaults->DamageType = set? NAME_Fire : NAME_None;
break; break;
case 1: // ICEDAMAGE case DEPF_ICEDAMAGE:
defaults->DamageType = set? NAME_Ice : NAME_None; defaults->DamageType = set? NAME_Ice : NAME_None;
break; break;
case 2: // LOWGRAVITY case DEPF_LOWGRAVITY:
defaults->gravity = set? FRACUNIT/8 : FRACUNIT; defaults->gravity = set? FRACUNIT/8 : FRACUNIT;
break; break;
case 3: // SHORTMISSILERANGE case DEPF_SHORTMISSILERANGE:
defaults->maxtargetrange = set? 896*FRACUNIT : 0; defaults->maxtargetrange = set? 896*FRACUNIT : 0;
break; break;
case 4: // LONGMELEERANGE case DEPF_LONGMELEERANGE:
defaults->meleethreshold = set? 196*FRACUNIT : 0; defaults->meleethreshold = set? 196*FRACUNIT : 0;
break; break;
case 5: // INVENTORY.PICKUPFLASH case DEPF_PICKUPFLASH:
if (set) if (set)
{ {
static_cast<AInventory*>(defaults)->PickupFlash = fuglyname("PickupFlash"); static_cast<AInventory*>(defaults)->PickupFlash = fuglyname("PickupFlash");