diff --git a/src/actor.h b/src/actor.h index be7a4f006e..98e593a7db 100644 --- a/src/actor.h +++ b/src/actor.h @@ -236,7 +236,7 @@ enum MF4_RANDOMIZE = 0x00000010, // Missile has random initial tic count MF4_NOSKIN = 0x00000020, // Player cannot use skins MF4_FIXMAPTHINGPOS = 0x00000040, // Fix this actor's position when spawned as a map thing - MF4_ACTLIKEBRIDGE = 0x00000080, // Pickups can "stand" on this actor + MF4_ACTLIKEBRIDGE = 0x00000080, // Pickups can "stand" on this actor / cannot be moved by any sector action. MF4_STRIFEDAMAGE = 0x00000100, // Strife projectiles only do up to 4x damage, not 8x MF4_CANUSEWALLS = 0x00000200, // Can activate 'use' specials @@ -266,7 +266,7 @@ enum // --- mobj.flags5 --- MF5_DONTDRAIN = 0x00000001, // cannot be drained health from. - /* = 0x00000002, */ + /* = 0x00000002, reserved for use by scripting branch */ MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret @@ -284,7 +284,7 @@ enum 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 + MF5_DONTRIP = 0x00080000, // Ripping projectiles explode when hitting this actor MF5_NOINFIGHTING = 0x00100000, // This actor doesn't switch target when it's hurt MF5_NOINTERACTION = 0x00200000, // Thing is completely excluded from any gameplay related checks MF5_NOTIMEFREEZE = 0x00400000, // Actor is not affected by time freezer @@ -334,6 +334,11 @@ enum MF6_NOTONAUTOMAP = 0x40000000, // will not be shown on automap with the 'scanner' powerup. MF6_RELATIVETOFLOOR = 0x80000000, // [RC] Make flying actors be affected by lifts. +// --- mobj.flags6 --- + + MF7_NEVERTARGET = 0x00000001, // can not be targetted at all, even if monster friendliness is considered. + MF7_NOTELESTOMP = 0x00000002, // cannot telefrag under any circumstances (even when set by MAPINFO) + // --- mobj.renderflags --- RF_XFLIP = 0x0001, // Flip sprite horizontally @@ -838,6 +843,7 @@ public: DWORD flags4; // [RH] Even more flags! DWORD flags5; // OMG! We need another one. DWORD flags6; // Shit! Where did all the flags go? + DWORD flags7; // // [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it. DWORD VisibleToTeam; diff --git a/src/d_main.cpp b/src/d_main.cpp index 5e67b69ddf..75a616bf4e 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1300,7 +1300,7 @@ void D_DoAdvanceDemo (void) gamestate = GS_DEMOSCREEN; pagename = gameinfo.titlePage; pagetic = (int)(gameinfo.titleTime * TICRATE); - S_StartMusic (gameinfo.titleMusic); + S_ChangeMusic (gameinfo.titleMusic, gameinfo.titleOrder, false); demosequence = 3; pagecount = 0; C_HideConsole (); diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 5c8cd96149..2ef2b03c54 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -589,7 +589,7 @@ void APowerInvisibility::DoEffect () Super::DoEffect(); // Due to potential interference with other PowerInvisibility items // the effect has to be refreshed each tic. - fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; + fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; Owner->alpha = clamp((OPAQUE - ts), 0, OPAQUE); switch (Mode) { @@ -669,7 +669,7 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) else if (changed == 1) { // something else set the weapon sprite back to opaque but this item is still active. - fixed_t ts = Strength * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; + fixed_t ts = (Strength/100) * (special1 + 1); if (ts > FRACUNIT) ts = FRACUNIT; vis->alpha = clamp((OPAQUE - ts), 0, OPAQUE); switch (Mode) { @@ -696,7 +696,7 @@ int APowerInvisibility::AlterWeaponSprite (visstyle_t *vis) // Handling of Strife-like cumulative invisibility powerups, the weapon itself shouldn't become invisible if ((vis->alpha < TRANSLUC25 && special1 > 0) || (vis->alpha == 0)) { - vis->alpha = clamp((OPAQUE - Strength), 0, OPAQUE); + vis->alpha = clamp((OPAQUE - (Strength/100)), 0, OPAQUE); vis->colormap = SpecialColormaps[INVERSECOLORMAP].Colormap; } return -1; // This item is valid so another one shouldn't reset the translucency diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 6c68990d14..22d1e009fb 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -134,6 +134,8 @@ enum IF_RESTRICTABSOLUTELY = 1<<19, // RestrictedTo and ForbiddenTo do not allow pickup in any form by other classes IF_NEVERRESPAWN = 1<<20, // Never, ever respawns IF_NOSCREENFLASH = 1<<21, // No pickup flash on the player's screen + IF_TOSSED = 1<<22, // Was spawned by P_DropItem (i.e. as a monster drop) + }; diff --git a/src/gi.cpp b/src/gi.cpp index 75476c8005..d9d58dc9e6 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -184,6 +184,20 @@ const char* GameInfoBorders[] = gameinfo.key.color = NAME_Null; \ } +#define GAMEINFOKEY_MUSIC(key, order, variable) \ + else if(nextKey.CompareNoCase(variable) == 0) \ + { \ + sc.MustGetToken(TK_StringConst); \ + gameinfo.order = 0; \ + char *colon = strchr (sc.String, ':'); \ + if (colon) \ + { \ + gameinfo.order = atoi(colon+1); \ + *colon = 0; \ + } \ + gameinfo.key = sc.String; \ + } + void FMapInfoParser::ParseGameInfo() { @@ -286,12 +300,12 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true) GAMEINFOKEY_STRINGARRAY(PlayerClasses, "addplayerclasses", 0, false) GAMEINFOKEY_STRINGARRAY(PlayerClasses, "playerclasses", 0, true) - GAMEINFOKEY_STRING(titleMusic, "titleMusic") + GAMEINFOKEY_MUSIC(titleMusic, titleOrder, "titleMusic") GAMEINFOKEY_FLOAT(titleTime, "titleTime") GAMEINFOKEY_FLOAT(advisoryTime, "advisoryTime") GAMEINFOKEY_FLOAT(pageTime, "pageTime") GAMEINFOKEY_STRING(chatSound, "chatSound") - GAMEINFOKEY_STRING(finaleMusic, "finaleMusic") + GAMEINFOKEY_MUSIC(finaleMusic, finaleOrder, "finaleMusic") GAMEINFOKEY_CSTRING(finaleFlat, "finaleFlat", 8) GAMEINFOKEY_STRINGARRAY(finalePages, "finalePage", 8, true) GAMEINFOKEY_STRINGARRAY(infoPages, "addinfoPage", 8, false) @@ -309,7 +323,7 @@ void FMapInfoParser::ParseGameInfo() GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor") GAMEINFOKEY_STRING(backpacktype, "backpacktype") GAMEINFOKEY_STRING(statusbar, "statusbar") - GAMEINFOKEY_STRING(intermissionMusic, "intermissionMusic") + GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic") GAMEINFOKEY_STRING(CursorPic, "CursorPic") GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic") GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis") diff --git a/src/gi.h b/src/gi.h index ff678df074..6b887e1dd0 100644 --- a/src/gi.h +++ b/src/gi.h @@ -91,11 +91,13 @@ struct gameinfo_t TArray PlayerClasses; FString titleMusic; + int titleOrder; float titleTime; float advisoryTime; float pageTime; FString chatSound; FString finaleMusic; + int finaleOrder; char finaleFlat[9]; char borderFlat[9]; char SkyFlatName[9]; @@ -114,6 +116,7 @@ struct gameinfo_t FString backpacktype; FString statusbar; FString intermissionMusic; + int intermissionOrder; FString CursorPic; DWORD dimcolor; float dimamount; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 6ee67006e4..91090e4328 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -80,7 +80,7 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) if (desc->mMusic.IsEmpty()) { // only start the default music if this is the first action in an intermission - if (first) S_ChangeMusic (gameinfo.finaleMusic, 0, desc->mMusicLooping); + if (first) S_ChangeMusic (gameinfo.finaleMusic, gameinfo.finaleOrder, desc->mMusicLooping); } else { diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 07c467bac6..5d9d48bea6 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -311,6 +311,7 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->flags4 = player->mo->GetDefault()->flags4; player->mo->flags5 = player->mo->GetDefault()->flags5; player->mo->flags6 = player->mo->GetDefault()->flags6; + player->mo->flags7 = player->mo->GetDefault()->flags7; player->mo->renderflags &= ~RF_INVISIBLE; player->mo->height = player->mo->GetDefault()->height; player->mo->radius = player->mo->GetDefault()->radius; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 81a58ac158..437940d032 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2644,6 +2644,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) corpsehit->flags4 = info->flags4; corpsehit->flags5 = info->flags5; corpsehit->flags6 = info->flags6; + corpsehit->flags7 = info->flags7; corpsehit->health = info->health; corpsehit->target = NULL; corpsehit->lastenemy = NULL; @@ -3087,6 +3088,7 @@ AInventory *P_DropItem (AActor *source, const PClass *type, int dropamount, int { AInventory * inv = static_cast(mo); ModifyDropAmount(inv, dropamount); + inv->ItemFlags |= IF_TOSSED; if (inv->SpecialDropAction (source)) { // The special action indicates that the item should not spawn diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 0ee955a826..47ed87888c 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1508,6 +1508,9 @@ bool AActor::OkayToSwitchTarget (AActor *other) if (other == this) return false; // [RH] Don't hate self (can happen when shooting barrels) + if (other->flags7 & MF7_NEVERTARGET) + return false; // never EVER target me! + if (!(other->flags & MF_SHOOTABLE)) return false; // Don't attack things that can't be hurt diff --git a/src/p_map.cpp b/src/p_map.cpp index ee7c63263e..442e77876f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -334,8 +334,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr spechit.Clear (); - bool StompAlwaysFrags = (thing->flags2 & MF2_TELESTOMP) || - (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag; + bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP); FBoundingBox box(x, y, thing->radius); FBlockLinesIterator it(box); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 14607a6823..a2addad0ea 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -200,8 +200,12 @@ void AActor::Serialize (FArchive &arc) << flags3 << flags4 << flags5 - << flags6 - << special1 + << flags6; + if (SaveVersion >= 4504) + { + arc << flags7; + } + arc << special1 << special2 << health << movedir @@ -826,7 +830,7 @@ void AActor::CopyFriendliness (AActor *other, bool changeTarget, bool resetHealt flags4 = (flags4 & ~(MF4_NOHATEPLAYERS | MF4_BOSSSPAWNED)) | (other->flags4 & (MF4_NOHATEPLAYERS | MF4_BOSSSPAWNED)); FriendPlayer = other->FriendPlayer; DesignatedTeam = other->DesignatedTeam; - if (changeTarget && other->target != NULL && !(other->target->flags3 & MF3_NOTARGET)) + if (changeTarget && other->target != NULL && !(other->target->flags3 & MF3_NOTARGET) && !(other->target->flags7 & MF7_NEVERTARGET)) { // LastHeard must be set as well so that A_Look can react to the new target if called LastHeard = target = other->target; @@ -6133,6 +6137,9 @@ void PrintMiscActorInfo(AActor *query) Printf("\n\tflags6: %x", query->flags6); for (flagi = 0; flagi <= 31; flagi++) if (query->flags6 & 1<flags7); + for (flagi = 0; flagi <= 31; flagi++) + if (query->flags7 & 1<BounceFlags, FIXED2FLOAT(query->bouncefactor), FIXED2FLOAT(query->wallbouncefactor)); diff --git a/src/p_things.cpp b/src/p_things.cpp index a0f905a7fc..4828e8cbc6 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -452,6 +452,7 @@ bool P_Thing_Raise(AActor *thing) thing->flags4 = info->flags4; thing->flags5 = info->flags5; thing->flags6 = info->flags6; + thing->flags7 = info->flags7; thing->health = info->health; thing->target = NULL; thing->lastenemy = NULL; diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index c01855eecf..57dd363c80 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -237,6 +237,9 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF6, NOTONAUTOMAP, AActor, flags6), DEFINE_FLAG(MF6, RELATIVETOFLOOR, AActor, flags6), + DEFINE_FLAG(MF7, NEVERTARGET, AActor, flags7), + DEFINE_FLAG(MF7, NOTELESTOMP, AActor, flags7), + // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), DEFINE_FLAG2(FX_ROCKET, ROCKETTRAIL, AActor, effects), @@ -305,6 +308,7 @@ static FFlagDef InventoryFlags[] = DEFINE_FLAG(IF, RESTRICTABSOLUTELY, AInventory, ItemFlags), DEFINE_FLAG(IF, NEVERRESPAWN, AInventory, ItemFlags), DEFINE_FLAG(IF, NOSCREENFLASH, AInventory, ItemFlags), + DEFINE_FLAG(IF, TOSSED, AInventory, ItemFlags), DEFINE_DEPRECATED_FLAG(PICKUPFLASH), DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP),}; diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 34234e5838..2c0abee179 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1286,7 +1286,8 @@ DEFINE_PROPERTY(clearflags, 0, Actor) defaults->flags3 = defaults->flags4 = defaults->flags5 = - defaults->flags6 = 0; + defaults->flags6 = + defaults->flags7 = 0; defaults->flags2 &= MF2_ARGSDEFINED; // this flag must not be cleared } @@ -2113,9 +2114,8 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, strength, F, Inventory) I_Error("\"powerup.strength\" requires an actor of type \"Powerup\"\n"); return; } - // Puts a percent value in the 0.0..1.0 range PROP_FIXED_PARM(f, 0); - *pStrength = f / 100; + *pStrength = f; } //========================================================================== diff --git a/src/version.h b/src/version.h index ea24da8ff8..4c116c7d82 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4503 +#define SAVEVER 4504 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 37b418ce99..6ae9148aff 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -1947,7 +1947,7 @@ void WI_Ticker(void) if (level.info->InterMusic.IsNotEmpty()) S_ChangeMusic(level.info->InterMusic, level.info->intermusicorder); else - S_ChangeMusic (gameinfo.intermissionMusic.GetChars()); + S_ChangeMusic (gameinfo.intermissionMusic.GetChars(), gameinfo.intermissionOrder); } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 31051a1a17..3ba47a5c1d 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -300,7 +300,7 @@ ACTOR Actor native //: Thinker action native A_Quake(int intensity, int duration, int damrad, int tremrad, sound sfx = "world/quake"); action native A_SetTics(int tics); action native A_SetDamageType(name damagetype); - action native A_DropItem(class item, int dropamount = -1, int chance = -1); + action native A_DropItem(class item, int dropamount = -1, int chance = 256); action native A_CheckSightOrRange(float distance, state label); action native A_CheckRange(float distance, state label);