Skip to content
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

How do you work with DotNetGenericList? #40

Closed
hntd187 opened this issue Nov 1, 2019 · 5 comments
Closed

How do you work with DotNetGenericList? #40

hntd187 opened this issue Nov 1, 2019 · 5 comments

Comments

@hntd187
Copy link

hntd187 commented Nov 1, 2019

Hey Praydog,

Been working a lot with the framework and it all looks great. I'm trying to see the HP of the current enemies around me, but I can't seem to figure out the structure of the EnemyManager in app.ropeway.EnemyManager the enemy list is a DotNetGenericList, but I keep crashing RE2 trying to get some information about the elements. I can iterate over the data, and get their respective types, but it seems like it doesn't like trying to actually do anything with the app.ropeway.EnemyManager.RegisterEnemyInfo it just bombs. I can't find any other mods that work with the generic list and I don't know if you're still working on this project, but have you had any success working with this?

@praydog praydog closed this as completed in 50b0a51 Nov 1, 2019
@praydog
Copy link
Owner

praydog commented Nov 1, 2019

Hey. I haven't really worked on this project in a while, but I'd be glad to help.

I had the same problem when I was trying to port this project to DMC5, but never committed the fix. I've committed the change that should fix this. Let me know if there's anything else you need help with.

@hntd187
Copy link
Author

hntd187 commented Nov 1, 2019

Thanks any improvements to the obj explorer is helpful. What I meant was I am developing my own mod https://github.com/hntd187/RE2-Mod-Framework/blob/master/src/Speedrun.cpp and I was trying to find enemy health but actually accessing this seems problematic and crashes a lot.

I get it similar to this

auto enemy_manager = globals.get<RopewayEnemyManager>("app.ropeway.EnemyManager");

but then reading it doesn't work. I was trying to read the enemy_manager->enemyList but reading into the actual list doesn't work. The resharper export marks it as a DotNetGenericList do you have any insight on reading this? Or if you know a better way to get the current enemy info I'm happy to use that instead, thanks a lot for the help

@praydog
Copy link
Owner

praydog commented Nov 1, 2019

Here's a little example of how to get all the enemies' HP.

    auto enemy_manager = g_framework->getGlobals()->get<RopewayEnemyManager>("app.ropeway.EnemyManager");

    if (enemy_manager == nullptr) {
        return;
    }

    // Be sure to check for null pointers.
    // This is the active enemies list
    auto enemy_controllers = enemy_manager->enemyControllers;

    if (enemy_controllers == nullptr || enemy_controllers->data == nullptr) {
        return;
    }

    // numElements is the total allocated, not the actual number of elements, so there could be empty entries
    for (auto i = 0; i < enemy_controllers->data->numElements; ++i) {
        // app.ropeway.EnemyController
        auto enemy_controller = utility::REArray::getElement<RopewayEnemyController>(enemy_controllers->data, i);

        // Not valid.
        if (enemy_controller == nullptr) {
            break;
        }

        // May not be necessary, if the field is guaranteed to not be corrupted.
        if (!utility::REManagedObject::isManagedObject(enemy_controller)) {
            continue;
        }

        REBehavior* hitpoint_controller = nullptr;

        // Traverse the enemy controller's children to find the hitpoint controller
        for (auto component = enemy_controller->childComponent; component != nullptr && component != enemy_controller; component = component->childComponent) {
            if (utility::REManagedObject::isA(component, "app.ropeway.HitPointController")) {
                hitpoint_controller = (REBehavior*)component;
                break;
            }
        }

        if (hitpoint_controller == nullptr) {
            continue;
        }

        // Get the health
        auto health = utility::REManagedObject::getField<int32_t>(hitpoint_controller, "CurrentHitPoint");

        // Do whatever you wanted to do here.
    }

@hntd187
Copy link
Author

hntd187 commented Nov 2, 2019

Interesting, I was doing something very similar to this, lemme try this and get back to you, thanks a lot for the help

@hntd187
Copy link
Author

hntd187 commented Nov 2, 2019

Okay that works perfectly, I wonder what I was doing wrong here, but I think I wasn't traversing to the hit point controller correctly so thanks that helps a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants