diff --git a/docs/rh-log.txt b/docs/rh-log.txt index c54985e670..3f002df346 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,15 @@ 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 to stop the old music so the new one always starts at the beginning. - Fixed:: AActor::master was not serialized. diff --git a/src/actor.h b/src/actor.h index 99a642a6d2..a08ea5d68a 100644 --- a/src/actor.h +++ b/src/actor.h @@ -294,6 +294,10 @@ enum MF5_NOPAIN = 0x00004000, // If set the pain state won't be entered MF5_ALWAYSFAST = 0x00008000, // always 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 --- diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 2783c74c87..ff64b44f4a 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -58,7 +58,7 @@ bool APowerupGiver::Use (bool pickup) power->mode = mode; } - power->ItemFlags |= ItemFlags & IF_ALWAYSPICKUP; + power->ItemFlags |= ItemFlags & (IF_ALWAYSPICKUP|IF_ADDITIVETIME); if (power->TryPickup (Owner)) { return true; @@ -259,7 +259,12 @@ bool APowerup::HandlePickup (AInventory *item) } // Only increase the EffectTics, not decrease it. // 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; BlendColor = power->BlendColor; diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 0acf901702..3ceaa9a0a9 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -90,7 +90,7 @@ enum IF_INVBAR = 1<<6, // Item appears in the inventory bar IF_HUBPOWER = 1<<7, // Powerup is kept when moving in a hub 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_FANCYPICKUPSOUND = 1<<11, // Play pickup sound in "surround" mode IF_BIGPOWERUP = 1<<12, // Affected by RESPAWN_SUPER dmflag diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 58b2f2a673..503fd7def0 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -5256,6 +5256,41 @@ int DLevelScript::RunScript () STACK(3) = P_Thing_Damage (STACK(3), activator, STACK(2), FName(FBehavior::StaticLookupString(STACK(1)))); sp -= 2; 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; } } diff --git a/src/p_acs.h b/src/p_acs.h index 3d63b90e6d..de0b0ea98b 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -544,6 +544,9 @@ public: PCD_THINGDAMAGE2, PCD_USEINVENTORY, PCD_USEACTORINVENTORY, + PCD_CHECKACTORCEILINGTEXTURE, + PCD_CHECKACTORFLOORTEXTURE, +/*340*/ PCD_GETACTORLIGHTLEVEL, PCODE_COMMAND_COUNT }; diff --git a/src/p_map.cpp b/src/p_map.cpp index 4453c5cd67..704eae9574 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1019,7 +1019,7 @@ bool PIT_CheckThing (AActor *thing) { return true; } - if (DoRipping) + if (DoRipping && !(thing->flags5 & MF5_DONTRIP)) { if (LastRipped != thing) { @@ -2475,6 +2475,13 @@ bool P_BounceWall (AActor *mo) 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); lineangle = R_PointToAngle2 (0, 0, line->dx, line->dy); if (side == 1) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 41a9b5a51b..c3fa26d96b 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2963,8 +2963,15 @@ void AActor::Tick () { int respawn_monsters = G_SkillProperty(SKILLP_Respawn); // check for nightmare respawn - if (!respawn_monsters || !(flags3 & MF3_ISMONSTER) || (flags2 & MF2_DORMANT)) - return; + if (!(flags5 & MF5_ALWAYSRESPAWN)) + { + 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++; @@ -2977,9 +2984,6 @@ void AActor::Tick () if (pr_nightmarerespawn() > 4) return; - if (G_SkillProperty (SKILLP_RespawnLimit) && (this)->skillrespawncount >= G_SkillProperty (SKILLP_RespawnLimit)) - return; - P_NightmareRespawn (this); } } @@ -4405,7 +4409,7 @@ bool P_CheckMissileSpawn (AActor* th) if (!P_TryMove (th, th->x, th->y, false)) { // [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 (th->CountsAsKill()) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 2d63010a2c..e4c49b32e3 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -1915,9 +1915,9 @@ void A_CountdownArg(AActor * self) { int index=CheckIndex(1); 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->flags&MF_MISSILE) diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 8c0be85764..093068a241 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -79,7 +79,7 @@ // [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_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 { @@ -88,6 +88,15 @@ struct flagdef int structoffset; }; +enum +{ + DEPF_FIREDAMAGE, + DEPF_ICEDAMAGE, + DEPF_LOWGRAVITY, + DEPF_LONGMELEERANGE, + DEPF_SHORTMISSILERANGE, + DEPF_PICKUPFLASH +}; static flagdef ActorFlags[]= { @@ -221,6 +230,9 @@ static flagdef ActorFlags[]= DEFINE_FLAG(MF5, NOPAIN, AActor, flags5), DEFINE_FLAG(MF5, ALWAYSFAST, 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 DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), @@ -231,11 +243,11 @@ static flagdef ActorFlags[]= DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags), // Deprecated flags. Handling must be performed in HandleDeprecatedFlags - DEFINE_DEPRECATED_FLAG(FIREDAMAGE, AActor, 0), - DEFINE_DEPRECATED_FLAG(ICEDAMAGE, AActor, 1), - DEFINE_DEPRECATED_FLAG(LOWGRAVITY, AActor, 2), - DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE, AActor, 3), - DEFINE_DEPRECATED_FLAG(LONGMELEERANGE, AActor, 4), + DEFINE_DEPRECATED_FLAG(FIREDAMAGE, AActor), + DEFINE_DEPRECATED_FLAG(ICEDAMAGE, AActor), + DEFINE_DEPRECATED_FLAG(LOWGRAVITY, AActor), + DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE, AActor), + DEFINE_DEPRECATED_FLAG(LONGMELEERANGE, AActor), }; static flagdef InventoryFlags[] = @@ -252,8 +264,9 @@ static flagdef InventoryFlags[] = DEFINE_FLAG(IF, BIGPOWERUP, AInventory, ItemFlags), DEFINE_FLAG(IF, KEEPDEPLETED, 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) { - case 0: // FIREDAMAGE + case DEPF_FIREDAMAGE: defaults->DamageType = set? NAME_Fire : NAME_None; break; - case 1: // ICEDAMAGE + case DEPF_ICEDAMAGE: defaults->DamageType = set? NAME_Ice : NAME_None; break; - case 2: // LOWGRAVITY + case DEPF_LOWGRAVITY: defaults->gravity = set? FRACUNIT/8 : FRACUNIT; break; - case 3: // SHORTMISSILERANGE + case DEPF_SHORTMISSILERANGE: defaults->maxtargetrange = set? 896*FRACUNIT : 0; break; - case 4: // LONGMELEERANGE + case DEPF_LONGMELEERANGE: defaults->meleethreshold = set? 196*FRACUNIT : 0; break; - case 5: // INVENTORY.PICKUPFLASH + case DEPF_PICKUPFLASH: if (set) { static_cast(defaults)->PickupFlash = fuglyname("PickupFlash");