Skip to content

Dynamic Actor IDs#1729

Merged
leggettc18 merged 10 commits intoHarbourMasters:developfrom
Rozelette:actor-test
Jun 2, 2023
Merged

Dynamic Actor IDs#1729
leggettc18 merged 10 commits intoHarbourMasters:developfrom
Rozelette:actor-test

Conversation

@Rozelette
Copy link
Contributor

@Rozelette Rozelette commented Oct 10, 2022

This PR adds an important functionality for eventual custom actor mods: dynamic actor IDs. This allows us to dynamically add actors while the game is running, such as while loading mod OTRs. This is a drop-in replacement for vanilla actors, who will continue to have the same ID as the base game.

This replaces the actor DLF tables, so they have been removed, and some other cleanup was done for actor overlays.

There is no need for this to get merged anytime soon, but I wanted to get this up so that people can see it.

Build Artifacts


const ActorInit Boss_Dodongo_InitVars = {
ACTOR_EN_DODONGO,
ACTOR_BOSS_DODONGO,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this enum was renamed from ACTOR_EN_DODONGO to ACTOR_BOSS_DODONGO, but Gohma's was renamed the opposite way? I'm sure this is probably authentic jank, but if you wouldn't mind elaborating I'd appreciate it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think I'm seeing it, King Dodongo had the regular Dodongo as it's actor ID and Gohma larvae had Queen Gohma's actor id. What effect would this have in game, if any? That seems like it would've caused some pretty big problems I would think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A look through the code tells me that these particular actors don't have their instance's IDs checked very often, so I guess this is harmless and a good idea to take care of here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it's a benign vanilla bug. I made sure to check that their IDs weren't used and to play through the areas where these actors were present to make sure bugs weren't introduced. I fixed the init vars so I could make the assumption that they were accurate while initializing the DB and that actor->id reflected the ActorDB entry for them. Without these changes, I'd have to do more record keeping.

Copy link
Contributor

@dcvz dcvz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving pending the final naming on Lookup vs Retrieve

Copy link
Collaborator

@Kenix3 Kenix3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious why you didn't just load the original actor init struct and added support for two types of init structs. Shouldn't we be creating actor entries into the DB consistently?

@Rozelette
Copy link
Contributor Author

Rozelette commented Nov 11, 2022

The reason I added a new init struct was that it allows us to make changes to how we initialize the table as we add new features (custom actors) that require actors to supply additional information. Already we add descriptions to them for the actor viewer. If we used 1 common struct, that would mean we'd have to update every ActorInit whenever we change the format. With the ActorDBInit, we can populate it as we load the info from the mod files. If we change the struct, that's fine because we can still support loading older mods that, say, don't provide a value for a new field, we can just default that. When loading the ActorInits for built-in actors, we can also just default it for them.

In other words, doing it this way will save us a significant amount of pain in the future.

I will add too that that's the reason why the Add with ActorInit is private. We shouldn't use that for new actors being added.

@briaguya0 briaguya0 added the merge conflicts PR has conflicts that need to be resolved before it can be merged label Dec 5, 2022
@briaguya0 briaguya0 force-pushed the develop branch 2 times, most recently from 05bd4a3 to ba13e6b Compare January 17, 2023 05:34
Copy link
Contributor

@dcvz dcvz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this very much! There are some suggestions about naming. They revolve around using GetEntry, AddEntry and so on.. but I would say if we aim for this to become the way to interact with Actors, we should just name them GetActor, AddActor, etc.

entry.desc = desc.c_str();
}

extern "C" ActorDBEntry* ActorDB_Retrieve(const int id) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is ActorDB the only way now to interact with Actors? If so, I would say let's name it:

Suggested change
extern "C" ActorDBEntry* ActorDB_Retrieve(const int id) {
extern "C" ActorDBEntry* GetActorEntry(const int id) {

if not then I'd say let's go for

Suggested change
extern "C" ActorDBEntry* ActorDB_Retrieve(const int id) {
extern "C" ActorDBEntry* ActorDB_GetEntry(const int id) {

Copy link
Contributor Author

@Rozelette Rozelette May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is the only place to interact with certain information about actors, mainly for spawning them. But, I don't think GetActorEntry is appropriate. This is extern "C", so it is in the global namespace, and so I would like it to be namespaced as best we can. The Namespace_Name pattern is common, see OTRGlobals.h for a whole list of examples.

}

// Get the ActorDB::Enty for the given actor id.
ActorDB::Entry& ActorDB::Retrieve(const int id) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ActorDB::Entry& ActorDB::Retrieve(const int id) {
ActorDB::Entry& ActorDB::GetEntry(const int id) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There were previous discussions on naming this Retrieve to match the custom messages DB. I think naming this RetrieveEntry is good, but I don't want to break consistency with Get.

}

// Get the id for a given actor by name.
int ActorDB::RetrieveId(const std::string& name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int ActorDB::RetrieveId(const std::string& name) {
int ActorDB::GetActorEntryId(const std::string& name) {

return &ActorDB::Instance->Retrieve(id).entry;
}

extern "C" int ActorDB_RetrieveId(const char* name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same suggestion as above and as commented on the C++ counterpart

@Rozelette
Copy link
Contributor Author

Note: there were some build failures on Linux due to different definitions of functions in cmath.h, so I removed them from functions.h. We were already using cmath.h's versions anyways, but when included in a C++ context, the functions were also noexcept, which caused the errors.

Copy link
Collaborator

@Kenix3 Kenix3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a fantastic update to me!

@leggettc18
Copy link
Contributor

leggettc18 commented May 18, 2023

Hmm, I just tested this and Link always seems to immediately fall through the floor. Maybe this doesn't work well with some of the more recent LUS changes?

EDIT: Not sure what changed but now I seem to be getting random crashes all over the place.

@leggettc18
Copy link
Contributor

I think I figured it out, Windows did still need those other math functions. It compiled fine without them but had all kinds of weird issues at runtime. I'll PR to Roze's branch.

@leggettc18
Copy link
Contributor

Also, after being able to build and run correctly on Windows, I found that this also seems to fix issue #2861

Fix missing math functions on Windows.
Co-authored-by: Adam Bird <Archez@users.noreply.github.com>
@leggettc18 leggettc18 merged commit fdf9086 into HarbourMasters:develop Jun 2, 2023
@garrettjoecox garrettjoecox added this to the Sulu (7.1.x) milestone Jun 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge conflicts PR has conflicts that need to be resolved before it can be merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants