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.
This commit is contained in:
Christoph Oelckers 2024-10-03 12:24:16 +02:00
commit 8354c4a5c3
19 changed files with 138 additions and 69 deletions

View file

@ -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
{

View file

@ -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

View file

@ -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.

View file

@ -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<PClass>(NAME_PickupFlash) = FindClassTentative("PickupFlash", RUNTIME_CLASS(AActor));
actor->PointerVar<PClass>(NAME_PickupFlash) = FindClassTentative("PickupFlash", RUNTIME_CLASS(AActor));
}
else
{
defaults->PointerVar<PClass>(NAME_PickupFlash) = nullptr;
actor->PointerVar<PClass>(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<PClass>(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

View file

@ -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)

View file

@ -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
{