New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document Actor Flags #1122
base: main
Are you sure you want to change the base?
Document Actor Flags #1122
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a lot of grammar in the new comments in z64actor.h for now. It seems to me that it should be Player
over player
everywhere, too, since it's referring to the actual actor (and not the person at the controls).
include/z64actor.h
Outdated
#define ACTOR_FLAG_NO_UPDATE_CULLING (1 << 4) // actor will keep updating even if outside of the uncull zone | ||
#define ACTOR_FLAG_NO_DRAW_CULLING (1 << 5) // actor will keep drawing even if outside of the uncull zone | ||
#define ACTOR_FLAG_NOT_CULLED (1 << 6) // actor is in the uncull zone. flag still updates regardless of the update/draw cull exclusion flags |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be fine with changing "uncull zone" to "active zone" in general, it may help with all the negative words going on here that make this system confusing. uncull zone is a name i was never happy with since the beginning.
in that case I would also change ACTOR_FLAG_NOT_CULLED
-> ACTOR_FLAG_IN_ACTIVE_ZONE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, long conversation regarding these flags in general for anyone else who wants to talk about these https://discord.com/channels/688807550715560050/688851317593997489/935729171529887754
imo i would rather keep the first two as is, and rename the last one according to my suggestion above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A summary of how these three flags work:
An actor is "culled" when it is outside the "uncull zone" defined by the three uncullZone*
members in the Actor
struct.
An actor being culled or not is indicated by ACTOR_FLAG_6
/ACTOR_FLAG_IN_UNCULL_ZONE
being set (actor is not culled) or cleared (actor is culled).
The set/clear state of this flag is updated every frame between actor update and actor draw (right before draw):
https://github.com/fig02/oot/blob/7774a67ea79076099820a6386a6a5b21c2ee5949/src/code/z_actor.c#L2421-L2425 :
if (func_800314B0(globalCtx, actor)) {
actor->flags |= ACTOR_FLAG_IN_UNCULL_ZONE;
} else {
actor->flags &= ~ACTOR_FLAG_IN_UNCULL_ZONE;
}
When an actor is culled, by default its update and draw functions don't run.
This behavior can be overriden by setting the ACTOR_FLAG_4
/ACTOR_FLAG_NO_UPDATE_CULLING
and/or ACTOR_FLAG_5
/ACTOR_FLAG_NO_DRAW_CULLING
to make update and draw run regardless of the actor being culled.
Comments:
ACTOR_FLAG_NO_UPDATE_CULLING
/draw one can't be "always update"/draw because frozen (freezeTimer
) actors still don't update. This set of flag is "culling"-specific
"no X culling" means "do not apply culling for x" if that's clearer. Wording is hard, suggestions appreciated
Suggestions also appreciated on the "cull", "uncull" words if they can be replaced
@@ -2932,11 +2938,13 @@ void func_800328D4(GlobalContext* globalCtx, ActorContext* actorCtx, Player* pla | |||
sp84 = player->unk_664; | |||
|
|||
while (actor != NULL) { | |||
if ((actor->update != NULL) && ((Player*)actor != player) && CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_0)) { | |||
if ((actor->update != NULL) && ((Player*)actor != player) && | |||
CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_TARGETABLE)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not a fan of naming this one with the whole target context and relevant player code being undocumented. But at least this one is somewhat straightforward, so it may be fine
same for ACTOR_FLAG_CANT_TARGET
(also it's unclear if the flags need to be combined, if they do cant_target shouldn't be a straight negation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
targetable encompasses the whole mechanism of navi flying over something and the player being able to target it.
the CANT_TARGET flag makes it so you cant target it, but navi can still fly over it. I agree that its confusing but didnt have any other way to phrase it
a better way to phrase it might be CANT_LOCK_ON or something, but people would generally call that targeting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe "target_focus_only"? something that makes it sound like it's taking a specific thing away compared to the targeting flag alone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would argue focus sounds like the targeting/locking on part, which is what is being disabled here
|
||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_13)) { | ||
if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOK_ATTACHED)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment about this also being boomerang would be useful
something like "this flag is also set by boomerang for EnSi specifically"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imo en_si doesnt really care about that, the hack is the boomerang using it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like someone reading ensi code would appreciate knowing this also handles boomerang. I think it's worth documenting since the code works with more than hookshot (kind of unintendedly so?)
#define ACTOR_FLAG_SFX_CENTERED (1 << 21) // play sound from sfx field at the center of the screen | ||
#define ACTOR_FLAG_IGNORE_POINT_LIGHTS (1 << 22) // ignores point lights but not directional lights (such as environment lights) | ||
#define ACTOR_FLAG_ALWAYS_THROW (1 << 23) // Player throws held actor even if standing still | ||
#define ACTOR_FLAG_PLAY_BODYHIT_SFX (1 << 24) // when actor hits Player's body, a thump sfx plays |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the "body" part of this important? I'd rather have it be "playerhit"
I would kind of prefer _PLAYERHIT_SFX
or _PLAYERHIT_PLAY_SFX
, not sure
_HITPLAYER_PLAY_SFX
... idk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the name comes from the original sfx name which is bodyhit
I think it does help, there are many sounds you could take to mean a hit sfx. but bodyhit is the thump noise against his body
#define ACTOR_FLAG_HOOK_ATTACHED (1 << 13) // hookshot has attached to the actor (either a collider or surface) | ||
#define ACTOR_FLAG_ARROW_CAN_CARRY (1 << 14) // when an arrow hits the actor it will attach to the actor and carry it | ||
#define ACTOR_FLAG_ARROW_IS_CARRYING (1 << 15) // an arrow is currently carrying this actor | ||
#define ACTOR_FLAG_IMMEDIATE_TALK (1 << 16) // forces Player to talk when in range. needs to be unset manually to avoid infinite talking |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For symmetry with ACTOR_FLAG_TALK_REQUESTED
this could be ACTOR_FLAG_TALK_IMMEDIATE
also
#define ACTOR_FLAG_IMMEDIATE_TALK (1 << 16) // forces Player to talk when in range. needs to be unset manually to avoid infinite talking | |
#define ACTOR_FLAG_IMMEDIATE_TALK (1 << 16) // forces Player to talk when in range. Needs to be unset manually to avoid infinite talking |
In general for these comments it may be nicer to capitalize the sentences and add punctuation
also
Just for curiosity what kind of range are we talking about? 10, 100, 1000 units? I can't find the relevant piece of code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actors broadcast their ability to talk with func_8002F2CC
and other related functions. they specify their own range, its not fixed
@@ -1232,7 +1233,7 @@ void EnBb_Update(Actor* thisx, GlobalContext* globalCtx2) { | |||
if (this->actor.colChkInfo.damageEffect != 0xD) { | |||
this->actionFunc(this, globalCtx); | |||
if ((this->actor.params <= ENBB_BLUE) && (this->actor.speedXZ >= -6.0f) && | |||
((this->actor.flags & ACTOR_FLAG_15) == 0)) { | |||
((this->actor.flags & ACTOR_FLAG_ARROW_IS_CARRYING) == 0)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
((this->actor.flags & ACTOR_FLAG_ARROW_IS_CARRYING) == 0)) { | |
!(this->actor.flags & ACTOR_FLAG_ARROW_IS_CARRYING)) { |
@@ -134,7 +135,8 @@ void ElfMsg2_WaitUntilActivated(ElfMsg2* this, GlobalContext* globalCtx) { | |||
if ((this->actor.world.rot.y >= 0x41) && (this->actor.world.rot.y <= 0x80) && | |||
(Flags_GetSwitch(globalCtx, (this->actor.world.rot.y - 0x41)))) { | |||
ElfMsg2_SetupAction(this, ElfMsg2_WaitForTextRead); | |||
this->actor.flags |= ACTOR_FLAG_0 | ACTOR_FLAG_18; // Make actor targetable and Navi-checkable | |||
this->actor.flags |= | |||
ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_CHECK_WITH_NAVI; // Make actor targetable and Navi-checkable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_CHECK_WITH_NAVI; // Make actor targetable and Navi-checkable | |
ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_CHECK_WITH_NAVI; |
#define ACTOR_FLAG_ARROW_IS_CARRYING (1 << 15) // an arrow is currently carrying this actor | ||
#define ACTOR_FLAG_IMMEDIATE_TALK (1 << 16) // forces Player to talk when in range. needs to be unset manually to avoid infinite talking | ||
#define ACTOR_FLAG_HEAVYBLOCK (1 << 17) // changes actor carrying behavior specifically for the golden gauntlets block actor | ||
#define ACTOR_FLAG_CHECK_WITH_NAVI (1 << 18) // Navi can be used to trigger dialogue when targeting the actor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "targeting" here refers to Navi hovering at the actor's focus pos or locking onto the actor?
@@ -234,7 +234,7 @@ void EnBomChu_WaitForRelease(EnBomChu* this, GlobalContext* globalCtx) { | |||
//! @bug there is no NULL check on the floor poly. If the player is out of bounds the floor poly will be NULL | |||
//! and will cause a crash inside this function. | |||
EnBomChu_UpdateFloorPoly(this, this->actor.floorPoly, globalCtx); | |||
this->actor.flags |= ACTOR_FLAG_0; // make chu targetable | |||
this->actor.flags |= ACTOR_FLAG_TARGETABLE; // make chu targetable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this->actor.flags |= ACTOR_FLAG_TARGETABLE; // make chu targetable | |
this->actor.flags |= ACTOR_FLAG_TARGETABLE; |
This gives a name to every actor flag.
Some minor things were changed along with the flags, for example skyboxOffset -> quakeOffset which was discovered while figuring out how the flag worked