From 8354c4a5c360460cbcc53e141da32ec2684601e4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Oct 2024 12:24:16 +0200 Subject: [PATCH] Replaced MISSILE(EVEN)MORE with a real property and added related Dehacked options from Crispy Doom. This also adds proper deprecation messages to the deprecated flags which were missing due to a bad definition macro. --- src/gamedata/d_dehacked.cpp | 30 ++++++- src/playsim/actor.h | 5 +- src/playsim/p_enemy.cpp | 3 +- src/playsim/p_mobj.cpp | 1 + src/scripting/decorate/thingdef_parse.cpp | 2 +- src/scripting/thingdef.h | 8 +- src/scripting/thingdef_data.cpp | 36 +++++---- src/scripting/thingdef_properties.cpp | 81 +++++++++++++------ src/scripting/vmthunks_actors.cpp | 1 + src/scripting/zscript/zcc_compile_doom.cpp | 7 +- wadsrc/static/zscript/actors/actor.zs | 2 + .../static/zscript/actors/doom/cyberdemon.zs | 2 +- wadsrc/static/zscript/actors/doom/lostsoul.zs | 3 +- wadsrc/static/zscript/actors/doom/revenant.zs | 2 +- .../zscript/actors/doom/spidermaster.zs | 2 +- .../zscript/actors/heretic/hereticimp.zs | 4 +- .../static/zscript/actors/strife/acolyte.zs | 14 ++-- .../static/zscript/actors/strife/crusader.zs | 2 +- .../static/zscript/actors/strife/sentinel.zs | 2 +- 19 files changed, 138 insertions(+), 69 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 77e9d1320..e10f78dfb 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1153,7 +1153,7 @@ static const struct DehFlags2 deh_mobjflags_mbf21[] = { {"NORADIUSDMG", [](AActor* defaults) { defaults->flags3 |= MF3_NORADIUSDMG; }}, // doesn't take splash damage {"FORCERADIUSDMG", [](AActor* defaults) { defaults->flags4 |= MF4_FORCERADIUSDMG; }}, // causes splash damage even if target immune {"HIGHERMPROB", [](AActor* defaults) { defaults->MinMissileChance = 160; }}, // higher missile attack probability - {"RANGEHALF", [](AActor* defaults) { defaults->flags4 |= MF4_MISSILEMORE; }}, // use half distance for missile attack probability + {"RANGEHALF", [](AActor* defaults) { defaults->missilechancemult = 0.5; }}, // use half distance for missile attack probability {"NOTHRESHOLD", [](AActor* defaults) { defaults->flags4 |= MF4_QUICKTORETALIATE; }}, // no targeting threshold {"LONGMELEE", [](AActor* defaults) { defaults->meleethreshold = 196; }}, // long melee range {"BOSS", [](AActor* defaults) { defaults->flags2 |= MF2_BOSS; defaults->flags3 |= MF3_NORADIUSDMG; }}, // full volume see / death sound + splash immunity @@ -1174,9 +1174,10 @@ static void ClearBits2Stuff(AActor* defaults) defaults->maxtargetrange = 0; defaults->MinMissileChance = 200; defaults->meleethreshold = 0; + defaults->missilechancemult = 1; defaults->flags2 &= ~(MF2_BOSS | MF2_RIP); defaults->flags3 &= ~(MF3_NOTARGET | MF3_NORADIUSDMG | MF3_FULLVOLDEATH); - defaults->flags4 &= ~(MF4_MISSILEMORE | MF4_QUICKTORETALIATE | MF4_FORCERADIUSDMG); + defaults->flags4 &= ~(MF4_QUICKTORETALIATE | MF4_FORCERADIUSDMG); defaults->flags8 &= ~(MF8_E1M8BOSS | MF8_E2M8BOSS | MF8_E3M8BOSS | MF8_E4M8BOSS | MF8_E4M6BOSS | MF8_MAP07BOSS1 | MF8_MAP07BOSS2 | MF8_FULLVOLSEE); } @@ -1437,6 +1438,27 @@ static int PatchThing (int thingy, int flags) } DPrintf(DMSG_SPAMMY, "MBF21 Bits: %d (0x%08x)\n", info->flags.GetValue(), info->flags.GetValue()); } + // New fields from Crispy Doom + else if (!stricmp(Line1, "Melee threshold")) + { + info->meleethreshold = DEHToDouble(val); + } + else if (!stricmp(Line1, "Max target range")) + { + // [crispy] Maximum distance range to start shooting (zero for unlimited) + info->maxtargetrange = DEHToDouble(val); + } + else if (!stricmp(Line1, "Min missile chance")) + { + // [crispy] Minimum chance for firing a missile + info->MinMissileChance = DEHToDouble(val); + } + else if (!stricmp(Line1, "Missile chance multiplier")) + { + // [crispy] Multiplies the chance of firing a missile (65536 = normal chance) + info->missilechancemult = DEHToDouble(val); + } + else if (linelen > 6) { if (stricmp (Line1 + linelen - 6, " frame") == 0) @@ -3861,7 +3883,7 @@ struct FlagHandler #define F4(flag) { [](AActor* a) { a->flags4 |= flag; }, [](AActor* a) { a->flags4 &= ~flag; }, [](AActor* a)->bool { return a->flags4 & flag; } } #define F6(flag) { [](AActor* a) { a->flags6 |= flag; }, [](AActor* a) { a->flags6 &= ~flag; }, [](AActor* a)->bool { return a->flags6 & flag; } } #define F8(flag) { [](AActor* a) { a->flags8 |= flag; }, [](AActor* a) { a->flags8 &= ~flag; }, [](AActor* a)->bool { return a->flags8 & flag; } } -#define DEPF(flag) { [](AActor* a) { HandleDeprecatedFlags(a, nullptr, true, flag); }, [](AActor* a) { HandleDeprecatedFlags(a, nullptr, false, flag); }, [](AActor* a)->bool { return CheckDeprecatedFlags(a, nullptr, flag); } } +#define DEPF(flag) { [](AActor* a) { HandleDeprecatedFlags(a, true, flag); }, [](AActor* a) { HandleDeprecatedFlags(a, false, flag); }, [](AActor* a)->bool { return !!CheckDeprecatedFlags(a, flag); } } void SetNoSector(AActor* a) { @@ -4112,7 +4134,7 @@ static FlagHandler flag2handlers[32] = { F3(MF3_NORADIUSDMG), F4(MF4_FORCERADIUSDMG), DEPF(DEPF_HIGHERMPROB), - F4(MF4_MISSILEMORE), + DEPF(DEPF_MISSILEMORE), F4(MF4_QUICKTORETALIATE), DEPF(DEPF_LONGMELEERANGE), { SetBoss, ClearBoss, [](AActor* a)->bool { return a->flags2 & MF2_BOSS; } }, diff --git a/src/playsim/actor.h b/src/playsim/actor.h index c83a7f229..daa60f45f 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -262,8 +262,8 @@ enum ActorFlag4 MF4_STRIFEDAMAGE = 0x00000100, // Strife projectiles only do up to 4x damage, not 8x MF4_CANUSEWALLS = 0x00000200, // Can activate 'use' specials - MF4_MISSILEMORE = 0x00000400, // increases the chance of a missile attack - MF4_MISSILEEVENMORE = 0x00000800, // significantly increases the chance of a missile attack + // = 0x00000400, + // = 0x00000800, MF4_FORCERADIUSDMG = 0x00001000, // if put on an object it will override MF3_NORADIUSDMG MF4_DONTFALL = 0x00002000, // Doesn't have NOGRAVITY disabled when dying. MF4_SEESDAGGERS = 0x00004000, // This actor can see you striking with a dagger @@ -1255,6 +1255,7 @@ public: // but instead tries to come closer for a melee attack. // This is not the same as meleerange double maxtargetrange; // any target farther away cannot be attacked + double missilechancemult; // distance multiplier for CheckMeleeRange, formerly done with MISSILE(EVEN)MORE flags. double bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70. double wallbouncefactor; // The bounce factor for walls can be different. double Gravity; // [GRB] Gravity factor diff --git a/src/playsim/p_enemy.cpp b/src/playsim/p_enemy.cpp index 1d49f4b3a..55f501488 100644 --- a/src/playsim/p_enemy.cpp +++ b/src/playsim/p_enemy.cpp @@ -373,8 +373,7 @@ static int P_CheckMissileRange (AActor *actor) if (actor->MeleeState != nullptr && dist < actor->meleethreshold) return false; // From the Revenant: close enough for fist attack - if (actor->flags4 & MF4_MISSILEMORE) dist *= 0.5; - if (actor->flags4 & MF4_MISSILEEVENMORE) dist *= 0.125; + dist *= actor->missilechancemult; int mmc = int(actor->MinMissileChance * G_SkillProperty(SKILLP_Aggressiveness)); return pr_checkmissilerange() >= min(int(dist), mmc); diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index e863445f2..0cbcb813b 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -320,6 +320,7 @@ void AActor::Serialize(FSerializer &arc) A("wallbouncefactor", wallbouncefactor) A("bouncecount", bouncecount) A("maxtargetrange", maxtargetrange) + A("missilechancemult", missilechancemult) A("meleethreshold", meleethreshold) A("meleerange", meleerange) A("damagetype", DamageType) diff --git a/src/scripting/decorate/thingdef_parse.cpp b/src/scripting/decorate/thingdef_parse.cpp index a1cc7702e..19c8f38ab 100644 --- a/src/scripting/decorate/thingdef_parse.cpp +++ b/src/scripting/decorate/thingdef_parse.cpp @@ -475,7 +475,7 @@ void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char * AActor *defaults = (AActor*)bag.Info->Defaults; if (fd->structoffset == -1) // this is a deprecated flag that has been changed into a real property { - HandleDeprecatedFlags(defaults, bag.Info, mod=='+', fd->flagbit); + HandleDeprecatedFlags(defaults, mod=='+', fd->flagbit); } else { diff --git a/src/scripting/thingdef.h b/src/scripting/thingdef.h index 34cd34666..f12cca99d 100644 --- a/src/scripting/thingdef.h +++ b/src/scripting/thingdef.h @@ -66,12 +66,13 @@ struct FFlagDef int structoffset; int fieldsize; int varflags; + VersionInfo deprecationVersion; }; void FinalizeClass(PClass *cls, FStateDefinitions &statedef); FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2, bool strict = false); -void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int index); -bool CheckDeprecatedFlags(AActor *actor, PClassActor *info, int index); +void HandleDeprecatedFlags(AActor *defaults, int set, int index); +int CheckDeprecatedFlags(AActor *actor, int index); const char *GetFlagName(unsigned int flagnum, int flagoffset); void ModActorFlag(AActor *actor, FFlagDef *fd, bool set); bool ModActorFlag(AActor *actor, const FString &flagname, bool set, bool printerror = true); @@ -229,6 +230,9 @@ enum DEPF_DOOMBOUNCE = 11, DEPF_INTERHUBSTRIP = 12, DEPF_HIGHERMPROB = 13, + // all that follow need ZScript emulation! + DEPF_MISSILEMORE = 14, + DEPF_MISSILEEVENMORE = 15 }; // Types of old style decorations diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index cc97b1a2d..8f19bab54 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -75,8 +75,8 @@ extern float BackbuttonAlpha; #define DEFINE_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native } #define DEFINE_PROTECTED_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_ReadOnly|VARF_InternalAccess } #define DEFINE_FLAG2(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native } -#define DEFINE_FLAG2_DEPRECATED(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_Deprecated } -#define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0, true } +#define DEFINE_FLAG2_DEPRECATED(symbol, name, type, variable, version) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_Deprecated } +#define DEFINE_DEPRECATED_FLAG(name, version) { DEPF_##name, #name, -1, 0, VARF_Deprecated, version } #define DEFINE_DUMMY_FLAG(name, deprec) { DEPF_UNUSED, #name, -1, 0, deprec? VARF_Deprecated:0 } // internal flags. These do not get exposed to actor definitions but scripts need to be able to access them as variables. @@ -210,8 +210,6 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG(MF4, ACTLIKEBRIDGE, AActor, flags4), DEFINE_FLAG(MF4, STRIFEDAMAGE, AActor, flags4), DEFINE_FLAG(MF4, CANUSEWALLS, AActor, flags4), - DEFINE_FLAG(MF4, MISSILEMORE, AActor, flags4), - DEFINE_FLAG(MF4, MISSILEEVENMORE, AActor, flags4), DEFINE_FLAG(MF4, FORCERADIUSDMG, AActor, flags4), DEFINE_FLAG(MF4, DONTFALL, AActor, flags4), DEFINE_FLAG(MF4, SEESDAGGERS, AActor, flags4), @@ -410,6 +408,11 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG2(BOUNCE_NotOnSky, DONTBOUNCEONSKY, AActor, BounceFlags), DEFINE_FLAG2(OF_Transient, NOSAVEGAME, AActor, ObjectFlags), + + // Deprecated flags which need a ZScript workaround. + DEFINE_DEPRECATED_FLAG(MISSILEMORE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(MISSILEEVENMORE, MakeVersion(4, 13, 0)), + }; // These won't be accessible through bitfield variables @@ -417,24 +420,25 @@ static FFlagDef MoreFlagDefs[] = { // Deprecated flags. Handling must be performed in HandleDeprecatedFlags - DEFINE_DEPRECATED_FLAG(FIREDAMAGE), - DEFINE_DEPRECATED_FLAG(ICEDAMAGE), - DEFINE_DEPRECATED_FLAG(LOWGRAVITY), - DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE), - DEFINE_DEPRECATED_FLAG(LONGMELEERANGE), - DEFINE_DEPRECATED_FLAG(QUARTERGRAVITY), - DEFINE_DEPRECATED_FLAG(FIRERESIST), - DEFINE_DEPRECATED_FLAG(HERETICBOUNCE), - DEFINE_DEPRECATED_FLAG(HEXENBOUNCE), - DEFINE_DEPRECATED_FLAG(DOOMBOUNCE), - DEFINE_DEPRECATED_FLAG(HIGHERMPROB), + // Note: Although deprecated since DECORATE times, they were never actually flagged as deprecated before 4.13.0 and no message was output... + DEFINE_DEPRECATED_FLAG(FIREDAMAGE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(ICEDAMAGE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(LOWGRAVITY, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(SHORTMISSILERANGE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(LONGMELEERANGE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(QUARTERGRAVITY, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(FIRERESIST, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(HERETICBOUNCE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(HEXENBOUNCE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(DOOMBOUNCE, MakeVersion(4, 13, 0)), + DEFINE_DEPRECATED_FLAG(HIGHERMPROB, MakeVersion(4, 13, 0)), // Deprecated flags with no more existing functionality. DEFINE_DUMMY_FLAG(FASTER, true), // obsolete, replaced by 'Fast' state flag DEFINE_DUMMY_FLAG(FASTMELEE, true), // obsolete, replaced by 'Fast' state flag // Deprecated name as an alias - DEFINE_FLAG2_DEPRECATED(MF4_DONTHARMCLASS, DONTHURTSPECIES, AActor, flags4), + DEFINE_FLAG2_DEPRECATED(MF4_DONTHARMCLASS, DONTHURTSPECIES, AActor, flags4, 0), // Various Skulltag flags that are quite irrelevant to ZDoom // [BC] New DECORATE flag defines here. diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index f6cd07335..4969765a7 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -176,7 +176,7 @@ bool ModActorFlag(AActor *actor, const FString &flagname, bool set, bool printer if (fd->structoffset == -1) { - HandleDeprecatedFlags(actor, cls, set, fd->flagbit); + HandleDeprecatedFlags(actor, set, fd->flagbit); } else { @@ -214,7 +214,7 @@ INTBOOL CheckActorFlag(AActor *owner, FFlagDef *fd) { if (fd->structoffset == -1) { - return CheckDeprecatedFlags(owner, owner->GetClass(), fd->flagbit); + return CheckDeprecatedFlags(owner, fd->flagbit); } else #ifdef __BIG_ENDIAN__ @@ -270,65 +270,92 @@ INTBOOL CheckActorFlag(AActor *owner, const char *flagname, bool printerror) // Handles the deprecated flags and sets the respective properties // to appropriate values. This is solely intended for backwards // compatibility so mixing this with code that is aware of the real -// properties is not recommended +// properties is not recommended and may not do what is expected // //=========================================================================== -void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int index) +void HandleDeprecatedFlags(AActor *actor, int set, int index) { switch (index) { case DEPF_FIREDAMAGE: - defaults->DamageType = set? NAME_Fire : NAME_None; + actor->DamageType = set? NAME_Fire : NAME_None; break; case DEPF_ICEDAMAGE: - defaults->DamageType = set? NAME_Ice : NAME_None; + actor->DamageType = set? NAME_Ice : NAME_None; break; case DEPF_LOWGRAVITY: - defaults->Gravity = set ? 1. / 8 : 1.; + actor->Gravity = set ? 1. / 8 : 1.; break; case DEPF_SHORTMISSILERANGE: - defaults->maxtargetrange = set? 896. : 0.; + actor->maxtargetrange = set? 896. : 0.; break; case DEPF_LONGMELEERANGE: - defaults->meleethreshold = set? 196. : 0.; + actor->meleethreshold = set? 196. : 0.; break; case DEPF_QUARTERGRAVITY: - defaults->Gravity = set ? 1. / 4 : 1.; + actor->Gravity = set ? 1. / 4 : 1.; break; case DEPF_FIRERESIST: - info->SetDamageFactor(NAME_Fire, set ? 0.5 : 1.); + actor->GetClass()->SetDamageFactor(NAME_Fire, set ? 0.5 : 1.); break; // the bounce flags will set the compatibility bounce modes to remain compatible case DEPF_HERETICBOUNCE: - defaults->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); - if (set) defaults->BounceFlags |= BOUNCE_HereticCompat; + actor->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); + if (set) actor->BounceFlags |= BOUNCE_HereticCompat; break; case DEPF_HEXENBOUNCE: - defaults->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); - if (set) defaults->BounceFlags |= BOUNCE_HexenCompat; + actor->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); + if (set) actor->BounceFlags |= BOUNCE_HexenCompat; break; case DEPF_DOOMBOUNCE: - defaults->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); - if (set) defaults->BounceFlags |= BOUNCE_DoomCompat; + actor->BounceFlags &= ~(BOUNCE_TypeMask|BOUNCE_UseSeeSound); + if (set) actor->BounceFlags |= BOUNCE_DoomCompat; break; case DEPF_PICKUPFLASH: if (set) { - defaults->PointerVar(NAME_PickupFlash) = FindClassTentative("PickupFlash", RUNTIME_CLASS(AActor)); + actor->PointerVar(NAME_PickupFlash) = FindClassTentative("PickupFlash", RUNTIME_CLASS(AActor)); } else { - defaults->PointerVar(NAME_PickupFlash) = nullptr; + actor->PointerVar(NAME_PickupFlash) = nullptr; } break; case DEPF_INTERHUBSTRIP: // Old system was 0 or 1, so if the flag is cleared, assume 1. - defaults->IntVar(NAME_InterHubAmount) = set ? 0 : 1; + actor->IntVar(NAME_InterHubAmount) = set ? 0 : 1; break; case DEPF_HIGHERMPROB: - defaults->MinMissileChance = set ? 160 : 200; + actor->MinMissileChance = set ? 160 : 200; break; + case DEPF_MISSILEMORE: + if (set) + { + if (actor->missilechancemult == 0.125) actor->missilechancemult = 0.0625; + else actor->missilechancemult = 0.5; + } + else + { + if (actor->missilechancemult == 0.0625) actor->missilechancemult = 0.125; + else actor->missilechancemult = 1; + } + break; + + case DEPF_MISSILEEVENMORE: + if (set) + { + if (actor->missilechancemult == 0.5) actor->missilechancemult = 0.0625; + else actor->missilechancemult = 0.125; + } + else + { + if (actor->missilechancemult == 0.0625) actor->missilechancemult = 0.5; + else actor->missilechancemult = 1; + } + break; + + default: break; // silence GCC } @@ -344,7 +371,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in // //=========================================================================== -bool CheckDeprecatedFlags(AActor *actor, PClassActor *info, int index) +int CheckDeprecatedFlags(AActor *actor, int index) { // A deprecated flag is false if // a) it hasn't been added here @@ -368,7 +395,7 @@ bool CheckDeprecatedFlags(AActor *actor, PClassActor *info, int index) case DEPF_QUARTERGRAVITY: return actor->Gravity == 1./4; case DEPF_FIRERESIST: - for (auto &df : info->ActorInfo()->DamageFactors) + for (auto &df : actor->GetClass()->ActorInfo()->DamageFactors) { if (df.first == NAME_Fire) return df.second == 0.5; } @@ -387,10 +414,16 @@ bool CheckDeprecatedFlags(AActor *actor, PClassActor *info, int index) return actor->PointerVar(NAME_PickupFlash) == PClass::FindClass(NAME_PickupFlash); case DEPF_INTERHUBSTRIP: - return !(actor->IntVar(NAME_InterHubAmount)); + return actor->IntVar(NAME_InterHubAmount) == 0; case DEPF_HIGHERMPROB: return actor->MinMissileChance <= 160; + + case DEPF_MISSILEMORE: + return actor->missilechancemult == 0.5 || actor->missilechancemult == 0.0625; + + case DEPF_MISSILEEVENMORE: + return actor->missilechancemult == 0.125 || actor->missilechancemult == 0.0625; } return false; // Any entirely unknown flag is not set diff --git a/src/scripting/vmthunks_actors.cpp b/src/scripting/vmthunks_actors.cpp index 527bd9178..18cd8aa32 100644 --- a/src/scripting/vmthunks_actors.cpp +++ b/src/scripting/vmthunks_actors.cpp @@ -2044,6 +2044,7 @@ DEFINE_FIELD(AActor, Species) DEFINE_FIELD(AActor, alternative) DEFINE_FIELD(AActor, goal) DEFINE_FIELD(AActor, MinMissileChance) +DEFINE_FIELD(AActor, missilechancemult) DEFINE_FIELD(AActor, LastLookPlayerNumber) DEFINE_FIELD(AActor, SpawnFlags) DEFINE_FIELD(AActor, meleethreshold) diff --git a/src/scripting/zscript/zcc_compile_doom.cpp b/src/scripting/zscript/zcc_compile_doom.cpp index 4becfc4fe..3563967e5 100644 --- a/src/scripting/zscript/zcc_compile_doom.cpp +++ b/src/scripting/zscript/zcc_compile_doom.cpp @@ -795,13 +795,14 @@ void ZCCDoomCompiler::ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg) auto fd = FindFlag(cls, n1, n2, true); if (fd != nullptr) { - if (fd->varflags & VARF_Deprecated) + if ((fd->varflags & VARF_Deprecated) && fd->deprecationVersion <= this->mVersion) { - Warn(flg, "Deprecated flag '%s%s%s' used", n1, n2 ? "." : "", n2 ? n2 : ""); + Warn(flg, "Deprecated flag '%s%s%s' used, deprecated since %d.%d.%d", n1, n2 ? "." : "", n2 ? n2 : "", + fd->deprecationVersion.major, fd->deprecationVersion.minor, fd->deprecationVersion.revision); } if (fd->structoffset == -1) { - HandleDeprecatedFlags((AActor*)cls->Defaults, cls, flg->set, fd->flagbit); + HandleDeprecatedFlags((AActor*)cls->Defaults, flg->set, fd->flagbit); } else { diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index cae1d161b..a29b912c5 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -187,6 +187,7 @@ class Actor : Thinker native native Actor Alternative; native Actor goal; native uint8 MinMissileChance; + native double MissileChanceMult; native int8 LastLookPlayerNumber; native uint SpawnFlags; native double meleethreshold; @@ -339,6 +340,7 @@ class Actor : Thinker native property WeaveIndexXY: WeaveIndexXY; property WeaveIndexZ: WeaveIndexZ; property MinMissileChance: MinMissileChance; + property MissileChanceMult: MissileChanceMult; property MaxStepHeight: MaxStepHeight; property MaxDropoffHeight: MaxDropoffHeight; property MaxSlopeSteepness: MaxSlopeSteepness; diff --git a/wadsrc/static/zscript/actors/doom/cyberdemon.zs b/wadsrc/static/zscript/actors/doom/cyberdemon.zs index d795fc31a..b18861bf9 100644 --- a/wadsrc/static/zscript/actors/doom/cyberdemon.zs +++ b/wadsrc/static/zscript/actors/doom/cyberdemon.zs @@ -16,8 +16,8 @@ class Cyberdemon : Actor PainChance 20; Monster; MinMissileChance 160; + MissileChanceMult 0.5; +BOSS - +MISSILEMORE +FLOORCLIP +NORADIUSDMG +DONTMORPH diff --git a/wadsrc/static/zscript/actors/doom/lostsoul.zs b/wadsrc/static/zscript/actors/doom/lostsoul.zs index 7feb8553b..0712a6d49 100644 --- a/wadsrc/static/zscript/actors/doom/lostsoul.zs +++ b/wadsrc/static/zscript/actors/doom/lostsoul.zs @@ -14,8 +14,9 @@ class LostSoul : Actor Speed 8; Damage 3; PainChance 256; + MissileChanceMult 0.5; Monster; - +FLOAT +NOGRAVITY +MISSILEMORE +DONTFALL +NOICEDEATH +ZDOOMTRANS +RETARGETAFTERSLAM + +FLOAT +NOGRAVITY +DONTFALL +NOICEDEATH +ZDOOMTRANS +RETARGETAFTERSLAM AttackSound "skull/melee"; PainSound "skull/pain"; DeathSound "skull/death"; diff --git a/wadsrc/static/zscript/actors/doom/revenant.zs b/wadsrc/static/zscript/actors/doom/revenant.zs index 36599e3a9..90492727a 100644 --- a/wadsrc/static/zscript/actors/doom/revenant.zs +++ b/wadsrc/static/zscript/actors/doom/revenant.zs @@ -15,7 +15,7 @@ class Revenant : Actor PainChance 100; Monster; MeleeThreshold 196; - +MISSILEMORE + MissileChanceMult 0.5; +FLOORCLIP SeeSound "skeleton/sight"; PainSound "skeleton/pain"; diff --git a/wadsrc/static/zscript/actors/doom/spidermaster.zs b/wadsrc/static/zscript/actors/doom/spidermaster.zs index 3ad0b8846..62701e395 100644 --- a/wadsrc/static/zscript/actors/doom/spidermaster.zs +++ b/wadsrc/static/zscript/actors/doom/spidermaster.zs @@ -13,9 +13,9 @@ class SpiderMastermind : Actor Mass 1000; Speed 12; PainChance 40; + MissileChanceMult 0.5; Monster; +BOSS - +MISSILEMORE +FLOORCLIP +NORADIUSDMG +DONTMORPH diff --git a/wadsrc/static/zscript/actors/heretic/hereticimp.zs b/wadsrc/static/zscript/actors/heretic/hereticimp.zs index 3a938b4ed..5ea8b063e 100644 --- a/wadsrc/static/zscript/actors/heretic/hereticimp.zs +++ b/wadsrc/static/zscript/actors/heretic/hereticimp.zs @@ -13,12 +13,12 @@ class HereticImp : Actor Mass 50; Speed 10; Painchance 200; + MissileChanceMult 0.5; Monster; +FLOAT +NOGRAVITY +SPAWNFLOAT +DONTOVERLAP - +MISSILEMORE SeeSound "himp/sight"; AttackSound "himp/attack"; PainSound "himp/pain"; @@ -159,7 +159,7 @@ class HereticImpLeader : HereticImp { Species "HereticImpLeader"; Health 80; - -MISSILEMORE + MissileChanceMult 1; AttackSound "himp/leaderattack"; } States diff --git a/wadsrc/static/zscript/actors/strife/acolyte.zs b/wadsrc/static/zscript/actors/strife/acolyte.zs index 5aeb0e63a..c86a6e5d3 100644 --- a/wadsrc/static/zscript/actors/strife/acolyte.zs +++ b/wadsrc/static/zscript/actors/strife/acolyte.zs @@ -155,7 +155,7 @@ class AcolyteTan : Acolyte { Default { - +MISSILEMORE +MISSILEEVENMORE + MissileChanceMult 0.0625; DropItem "ClipOfBullets"; } } @@ -166,7 +166,7 @@ class AcolyteRed : Acolyte { Default { - +MISSILEMORE +MISSILEEVENMORE + MissileChanceMult 0.0625; Translation 0; } } @@ -177,7 +177,7 @@ class AcolyteRust : Acolyte { Default { - +MISSILEMORE +MISSILEEVENMORE + MissileChanceMult 0.0625; Translation 1; } } @@ -188,7 +188,7 @@ class AcolyteGray : Acolyte { Default { - +MISSILEMORE +MISSILEEVENMORE + MissileChanceMult 0.0625; Translation 2; } } @@ -199,7 +199,7 @@ class AcolyteDGreen : Acolyte { Default { - +MISSILEMORE +MISSILEEVENMORE + MissileChanceMult 0.0625; Translation 3; } } @@ -210,7 +210,7 @@ class AcolyteGold : Acolyte { Default { - +MISSILEMORE +MISSILEEVENMORE + MissileChanceMult 0.0625; Translation 4; } } @@ -243,7 +243,7 @@ class AcolyteShadow : Acolyte { Default { - +MISSILEMORE + MissileChanceMult 0.5; DropItem "ClipOfBullets"; } States diff --git a/wadsrc/static/zscript/actors/strife/crusader.zs b/wadsrc/static/zscript/actors/strife/crusader.zs index f08d0f847..daee0d2e9 100644 --- a/wadsrc/static/zscript/actors/strife/crusader.zs +++ b/wadsrc/static/zscript/actors/strife/crusader.zs @@ -11,10 +11,10 @@ class Crusader : Actor Mass 400; Health 400; Painchance 128; + MissileChanceMult 0.5; Monster; +FLOORCLIP +DONTMORPH - +MISSILEMORE +INCOMBAT +NOICEDEATH +NOBLOOD diff --git a/wadsrc/static/zscript/actors/strife/sentinel.zs b/wadsrc/static/zscript/actors/strife/sentinel.zs index 0acc8580f..0987cc018 100644 --- a/wadsrc/static/zscript/actors/strife/sentinel.zs +++ b/wadsrc/static/zscript/actors/strife/sentinel.zs @@ -11,6 +11,7 @@ class Sentinel : Actor Radius 23; Height 53; Mass 300; + MissileChanceMult 0.5; Monster; +SPAWNCEILING +NOGRAVITY @@ -18,7 +19,6 @@ class Sentinel : Actor +NOBLOOD +NOBLOCKMONST +INCOMBAT - +MISSILEMORE +LOOKALLAROUND +NEVERRESPAWN MinMissileChance 150;