mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 06:53:40 +00:00
Add SetActorFlag ACS function
int SetActorFlag(int tid, str flagname, bool value); - Mimics DECORATE's A_ChangeFlag - Returns number of actors affected (number of things with the flag) - Affects activator if TID is 0 # Conflicts: # src/p_acs.cpp
This commit is contained in:
parent
f536523fbd
commit
2e8aa53e6a
4 changed files with 96 additions and 84 deletions
|
@ -4451,6 +4451,7 @@ enum EACSFunctions
|
||||||
|
|
||||||
ACSF_CheckClass = 200,
|
ACSF_CheckClass = 200,
|
||||||
ACSF_DamageActor, // [arookas]
|
ACSF_DamageActor, // [arookas]
|
||||||
|
ACSF_SetActorFlag,
|
||||||
|
|
||||||
// ZDaemon
|
// ZDaemon
|
||||||
ACSF_GetTeamScore = 19620, // (int team)
|
ACSF_GetTeamScore = 19620, // (int team)
|
||||||
|
@ -6046,6 +6047,34 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
return P_DamageMobj(target, inflictor, inflictor, args[4], damagetype);
|
return P_DamageMobj(target, inflictor, inflictor, args[4], damagetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ACSF_SetActorFlag:
|
||||||
|
{
|
||||||
|
int tid = args[0];
|
||||||
|
FString flagname = FBehavior::StaticLookupString(args[1]);
|
||||||
|
bool flagvalue = !!args[2];
|
||||||
|
int count = 0; // Return value; number of actors affected
|
||||||
|
if (tid == 0)
|
||||||
|
{
|
||||||
|
if (ModActorFlag(activator, flagname, flagvalue))
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FActorIterator it(tid);
|
||||||
|
while ((actor = it.Next()) != nullptr)
|
||||||
|
{
|
||||||
|
// Don't log errors when affecting many actors because things might share a TID but not share the flag
|
||||||
|
if (ModActorFlag(actor, flagname, flagvalue, false))
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ void HandleDeprecatedFlags(AActor *defaults, PClassActor *info, bool set, int in
|
||||||
bool CheckDeprecatedFlags(const AActor *actor, PClassActor *info, int index);
|
bool CheckDeprecatedFlags(const AActor *actor, PClassActor *info, int index);
|
||||||
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
||||||
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set);
|
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set);
|
||||||
|
bool ModActorFlag(AActor *actor, FString &flagname, bool set, bool printerror = true);
|
||||||
INTBOOL CheckActorFlag(const AActor *actor, FFlagDef *fd);
|
INTBOOL CheckActorFlag(const AActor *actor, FFlagDef *fd);
|
||||||
INTBOOL CheckActorFlag(const AActor *owner, const char *flagname, bool printerror = true);
|
INTBOOL CheckActorFlag(const AActor *owner, const char *flagname, bool printerror = true);
|
||||||
|
|
||||||
|
|
|
@ -4681,90 +4681,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
|
||||||
PARAM_STRING (flagname);
|
PARAM_STRING (flagname);
|
||||||
PARAM_BOOL (value);
|
PARAM_BOOL (value);
|
||||||
|
|
||||||
const char *dot = strchr(flagname, '.');
|
ModActorFlag(self, flagname, value);
|
||||||
FFlagDef *fd;
|
|
||||||
PClassActor *cls = self->GetClass();
|
|
||||||
|
|
||||||
if (dot != NULL)
|
|
||||||
{
|
|
||||||
FString part1(flagname.GetChars(), dot - flagname);
|
|
||||||
fd = FindFlag(cls, part1, dot + 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fd = FindFlag(cls, flagname, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd != NULL)
|
|
||||||
{
|
|
||||||
bool kill_before, kill_after;
|
|
||||||
INTBOOL item_before, item_after;
|
|
||||||
INTBOOL secret_before, secret_after;
|
|
||||||
|
|
||||||
kill_before = self->CountsAsKill();
|
|
||||||
item_before = self->flags & MF_COUNTITEM;
|
|
||||||
secret_before = self->flags5 & MF5_COUNTSECRET;
|
|
||||||
|
|
||||||
if (fd->structoffset == -1)
|
|
||||||
{
|
|
||||||
HandleDeprecatedFlags(self, cls, value, fd->flagbit);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ActorFlags *flagp = (ActorFlags*) (((char*)self) + fd->structoffset);
|
|
||||||
|
|
||||||
// If these 2 flags get changed we need to update the blockmap and sector links.
|
|
||||||
bool linkchange = flagp == &self->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
|
|
||||||
|
|
||||||
if (linkchange) self->UnlinkFromWorld();
|
|
||||||
ModActorFlag(self, fd, value);
|
|
||||||
if (linkchange) self->LinkToWorld();
|
|
||||||
}
|
|
||||||
kill_after = self->CountsAsKill();
|
|
||||||
item_after = self->flags & MF_COUNTITEM;
|
|
||||||
secret_after = self->flags5 & MF5_COUNTSECRET;
|
|
||||||
// Was this monster previously worth a kill but no longer is?
|
|
||||||
// Or vice versa?
|
|
||||||
if (kill_before != kill_after)
|
|
||||||
{
|
|
||||||
if (kill_after)
|
|
||||||
{ // It counts as a kill now.
|
|
||||||
level.total_monsters++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // It no longer counts as a kill.
|
|
||||||
level.total_monsters--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// same for items
|
|
||||||
if (item_before != item_after)
|
|
||||||
{
|
|
||||||
if (item_after)
|
|
||||||
{ // It counts as an item now.
|
|
||||||
level.total_items++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // It no longer counts as an item
|
|
||||||
level.total_items--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// and secretd
|
|
||||||
if (secret_before != secret_after)
|
|
||||||
{
|
|
||||||
if (secret_after)
|
|
||||||
{ // It counts as an secret now.
|
|
||||||
level.total_secrets++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // It no longer counts as an secret
|
|
||||||
level.total_secrets--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Printf("Unknown flag '%s' in '%s'\n", flagname.GetChars(), cls->TypeName.GetChars());
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,71 @@ void ModActorFlag(AActor *actor, FFlagDef *fd, bool set)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Finds a flag by name and sets or clears it
|
||||||
|
//
|
||||||
|
// Returns true if the flag was found for the actor; else returns false
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool ModActorFlag(AActor *actor, FString &flagname, bool set, bool printerror)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (actor != NULL)
|
||||||
|
{
|
||||||
|
const char *dot = strchr(flagname, '.');
|
||||||
|
FFlagDef *fd;
|
||||||
|
PClassActor *cls = actor->GetClass();
|
||||||
|
|
||||||
|
if (dot != NULL)
|
||||||
|
{
|
||||||
|
FString part1(flagname.GetChars(), dot - flagname);
|
||||||
|
fd = FindFlag(cls, part1, dot + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fd = FindFlag(cls, flagname, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd != NULL)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
if (actor->CountsAsKill() && actor->health > 0) --level.total_monsters;
|
||||||
|
if (actor->flags & MF_COUNTITEM) --level.total_items;
|
||||||
|
if (actor->flags5 & MF5_COUNTSECRET) --level.total_secrets;
|
||||||
|
|
||||||
|
if (fd->structoffset == -1)
|
||||||
|
{
|
||||||
|
HandleDeprecatedFlags(actor, cls, set, fd->flagbit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ActorFlags *flagp = (ActorFlags*)(((char*)actor) + fd->structoffset);
|
||||||
|
|
||||||
|
// If these 2 flags get changed we need to update the blockmap and sector links.
|
||||||
|
bool linkchange = flagp == &actor->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
|
||||||
|
|
||||||
|
if (linkchange) actor->UnlinkFromWorld();
|
||||||
|
ModActorFlag(actor, fd, set);
|
||||||
|
if (linkchange) actor->LinkToWorld();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actor->CountsAsKill() && actor->health > 0) ++level.total_monsters;
|
||||||
|
if (actor->flags & MF_COUNTITEM) ++level.total_items;
|
||||||
|
if (actor->flags5 & MF5_COUNTSECRET) ++level.total_secrets;
|
||||||
|
}
|
||||||
|
else if (printerror)
|
||||||
|
{
|
||||||
|
DPrintf(DMSG_ERROR, "ACS/DECORATE: '%s' is not a flag in '%s'\n", flagname.GetChars(), cls->TypeName.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Returns whether an actor flag is true or not.
|
// Returns whether an actor flag is true or not.
|
||||||
|
|
Loading…
Reference in a new issue