diff --git a/src/gamedata/a_weapons.h b/src/gamedata/a_weapons.h index 82cfd2999d..786990223f 100644 --- a/src/gamedata/a_weapons.h +++ b/src/gamedata/a_weapons.h @@ -154,9 +154,9 @@ enum WIF_STAFF2_KICKBACK = 0x00002000, // the powered-up Heretic staff has special kickback WIF_NOAUTOAIM = 0x00004000, // this weapon never uses autoaim (useful for ballistic projectiles) WIF_MELEEWEAPON = 0x00008000, // melee weapon. Used by bots and monster AI. - //WIF_DEHAMMO = 0x00010000, - WIF_NODEATHDESELECT = 0x00020000, // Don't jump to the Deselect state when the player dies - WIF_NODEATHINPUT = 0x00040000, // The weapon cannot be fired/reloaded/whatever when the player is dead - WIF_CHEATNOTWEAPON = 0x08000000, // Give cheat considers this not a weapon (used by Sigil) + WIF_NODEATHDESELECT = 0x00010000, // Don't jump to the Deselect state when the player dies + WIF_NODEATHINPUT = 0x00020000, // The weapon cannot be fired/reloaded/whatever when the player is dead + WIF_CHEATNOTWEAPON = 0x00040000, // Give cheat considers this not a weapon (used by Sigil) + WIF_NOAUTOSWITCHTO = 0x00080000, // cannot be switched to when autoswitching weapons. }; diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 6ab56ebd65..28ac9b801f 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1718,6 +1718,21 @@ static int PatchAmmo (int ammoNum) return result; } +struct DehWeaponBits +{ + const char* name; + int value; +}; + +DehWeaponBits wbits[] = { + { "NOTHRUST", -1 }, // i.e. set kickback to 0 + { "SILENT", WIF_NOALERT }, + { "NOAUTOFIRE", WIF_NOAUTOFIRE }, + { "FLEEMELEE", WIF_MELEEWEAPON }, + { "AUTOSWITCHFROM", WIF_WIMPY_WEAPON }, // ugh, I wish I could change this stupid name... + { "NOAUTOSWITCHTO", WIF_NOAUTOSWITCHTO } +}; + static int PatchWeapon (int weapNum) { int result; @@ -1819,6 +1834,57 @@ static int PatchWeapon (int weapNum) { if (info) info->IntVar(NAME_MinSelAmmo1) = val; } + else if (stricmp(Line1, "MBF21 Bits") == 0) + { + uint32_t value = 0; + bool vchanged = false; + + char* strval; + + for (strval = Line2; (strval = strtok(strval, ",+| \t\f\r")); strval = NULL) + { + if (IsNum(strval)) + { + value |= (unsigned long)strtoll(strval, NULL, 10); + vchanged = true; + } + else + { + unsigned i; + for (i = 0; i < countof(wbits); i++) + { + if (!stricmp(strval, wbits[i].name)) + { + vchanged = true; + value |= 1 << i; + break; + } + } + if (i == countof(wbits)) + { + DPrintf(DMSG_ERROR, "Unknown bit mnemonic %s\n", strval); + } + } + } + if (vchanged) + { + int kickback = 100; + int flags = 0; + for (size_t i = 0; i < countof(wbits); i++) + { + if (value & (1 << i)) + { + int val = wbits[i].value; + if (val == -1) kickback = 0; + else flags |= wbits[i].value; + } + } + info->IntVar(NAME_Kickback) = kickback; + info->IntVar(NAME_WeaponFlags) = flags; + } + DPrintf(DMSG_SPAMMY, "MBF21 Bits: %d (0x%08x)\n", info->flags.GetValue(), info->flags.GetValue()); + } + else { Printf (unknown_str, Line1, "Weapon", weapNum); diff --git a/wadsrc/static/zscript/actors/doom/weaponchainsaw.zs b/wadsrc/static/zscript/actors/doom/weaponchainsaw.zs index e4f3cc6c16..d3b6932d1d 100644 --- a/wadsrc/static/zscript/actors/doom/weaponchainsaw.zs +++ b/wadsrc/static/zscript/actors/doom/weaponchainsaw.zs @@ -16,6 +16,7 @@ class Chainsaw : Weapon Obituary "$OB_MPCHAINSAW"; Tag "$TAG_CHAINSAW"; +WEAPON.MELEEWEAPON + +WEAPON.NOAUTOSWITCHTO } States { diff --git a/wadsrc/static/zscript/actors/doom/weaponfist.zs b/wadsrc/static/zscript/actors/doom/weaponfist.zs index c27188773c..d02099bccf 100644 --- a/wadsrc/static/zscript/actors/doom/weaponfist.zs +++ b/wadsrc/static/zscript/actors/doom/weaponfist.zs @@ -14,6 +14,7 @@ class Fist : Weapon Tag "$TAG_FIST"; +WEAPON.WIMPY_WEAPON +WEAPON.MELEEWEAPON + +WEAPON.NOAUTOSWITCHTO } States { diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index fbf2c24ca5..cbe6a5c3dd 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -333,7 +333,7 @@ class PlayerPawn : Actor (player.ReadyWeapon == NULL || player.ReadyWeapon.bWimpy_Weapon)) { let best = BestWeapon (ammotype); - if (best != NULL && (player.ReadyWeapon == NULL || + if (best != NULL && && !best.bNoAutoSwitchTo && (player.ReadyWeapon == NULL || best.SelectionOrder < player.ReadyWeapon.SelectionOrder)) { player.PendingWeapon = best;