gtav-ent/GTAV-EnhancedNativeTrainer

Any ideas on why setting a Ped that's being aimed at to ragdoll isn't working?

Closed this issue · 20 comments

if (featureWeaponTranqAmmo){
        int duration = 100000;

        Ped* pedsInArea = new Ped[10];
        PED::GET_PED_NEARBY_PEDS(playerPed, pedsInArea, -1);
        Ped currentPed = playerPed;

        if (PED::IS_PED_SHOOTING(playerPed))
        {
            for (int i = 0; i < 10; i++)
            {
                if (PLAYER::IS_PLAYER_TARGETTING_ENTITY(playerPed, pedsInArea[i]))
                {
                    currentPed = pedsInArea[i];
                    break;
                }
            }

            //ENTITY::SET_ENTITY_HEALTH(currentPed, ENTITY::GET_ENTITY_MAX_HEALTH(currentPed));
            PED::SET_PED_TO_RAGDOLL(currentPed, duration, (duration * 1000), 3, 1, 1, 1);
            //ENTITY::SET_ENTITY_HEALTH(currentPed, ENTITY::GET_ENTITY_MAX_HEALTH(currentPed));
        }

I can't seem to get it to ragdoll the ped, it occasional will select the right ped though.

I made a bit of progress.

    if (featureWeaponTranqAmmo){
        int duration = 100000;
        const int numElms = 10;
        //Start at index 2, and the odd elements are padding
        const int arrSize = numElms * 2 + 2;
        int peds[arrSize];
        //0 index is the size of the array
        peds[0] = numElms;

        int count = PED::GET_PED_NEARBY_PEDS(PLAYER::PLAYER_PED_ID(), peds, -1);

        for (int i = 0; i < count; ++i)
        {
            int offsettedID = i * 2 + 2;
            if (ENTITY::DOES_ENTITY_EXIST(peds[offsettedID]))
            {
                if (PLAYER::IS_PLAYER_TARGETTING_ENTITY(player, peds[offsettedID]) || PLAYER::IS_PLAYER_FREE_AIMING_AT_ENTITY(player, peds[offsettedID])){
                    if (PED::IS_PED_SHOOTING(playerPed)){//checking if ped is shooting didn't seem to work, even with the EXLPLODE_PED_HEAD test
                    //PED::EXPLODE_PED_HEAD(peds[offsettedID], 0x5FC3C11); // I was using this as a test to make sure this was even working
                    PED::SET_PED_TO_RAGDOLL(peds[offsettedID], duration, (duration * 1000), 3, true, true, true);
                    //}
                }
            }
        }
    }

As you can see, the issue now is both setting ragdolls, which isn't working, and checking if the playerPed is shooting.
The targeting works, but neither of those do.

More progress but now I'm absolutely stumped.

if (featureWeaponTranqAmmo){
        int duration = 100000;
        const int numElms = 10;
        //Start at index 2, and the odd elements are padding
        const int arrSize = numElms * 2 + 2;
        int peds[arrSize];
        //0 index is the size of the array
        peds[0] = numElms;

        int count = PED::GET_PED_NEARBY_PEDS(PLAYER::PLAYER_PED_ID(), peds, -1);

        for (int i = 0; i < count; ++i)
        {
            int offsettedID = i * 2 + 2;
            if (ENTITY::DOES_ENTITY_EXIST(peds[offsettedID]))
            {
                if (PLAYER::IS_PLAYER_TARGETTING_ENTITY(player, peds[offsettedID]) || PLAYER::IS_PLAYER_FREE_AIMING_AT_ENTITY(player, peds[offsettedID])){
                    if (PED::IS_PED_SHOOTING(playerPed)){//checking if ped is shooting doesn't work because it only causes them to ragdoll when being shot, and they don't ragdoll all the way
                        PED::SET_PED_TO_RAGDOLL(peds[offsettedID], duration, 20, 1, true, true, true);//how do we get this to run for whatever duration is?
                    }
                }
            }
        }
    }

Looking at the code, I'm trying to gather an idea of what you're trying to do.
Is your goal to have your target fall over/flop around when you shoot them?

I guess a description of what I'm trying to get to happen would probably
help.
I'm trying to get them to ragdoll for the duration(in milliseconds) when
they're shot.
On Aug 31, 2015 11:42 AM, "Robert K." notifications@github.com wrote:

Looking at the code, I'm trying to gather an idea of what you're trying to
do.
Is your goal to have your target fall over/flop around when you shoot them?


Reply to this email directly or view it on GitHub
#145 (comment)
.

I'm at work so I can't help too much right now, but I see you're trying to grab a list of all nearby peds and then checking if you're aiming (freeaim or locked-on) at them.

What if you just tried using BOOL _GET_AIMED_ENTITY(Player player, Entity *entity) and BOOL GET_PLAYER_TARGET_ENTITY(Player player, Entity *entity)? These functions return true if you're aiming at an entity, and the functions populate the passed Entity pointer with the information of what you're aiming at. You can then use the pointer to do whatever rag-doll stuff you want.

That way you don't need to collect a list of nearby peds all the time, which in my experience has been a little wonky and has some random-like behavior that I haven't been able to characterize yet.

By the way this features sounds awesome and hilarious.

The trainer already collects and maintains a pool of peds.

I don't think there's anything wrong with the natives. There may be something wrong with how you're passing/using the Entity pointer. Can you post an example for us of how you're using them?

Okay it looks like I did revert it so I'll see if I can get those to work this time now that I don't have as much of a time constraint.

Okay so I did a little searching around as well, and I found that you have to keep calling the ragdoll native every frame in order to get them to ragdoll, any ideas on how you would do it from a shot?

Any updates? Still looks promising.

Aside from me finding that you have to keep calling the ragdoll native, no. I can't figure out a good way to get it to keep going for the duration after they're shot.

You could try doing it for x number of frames. The main part of the script executes once each frame so you can create a counter and keep your rag doll going for some certain number of frames instead of trying to use milliseconds.

Sent from my iPhone

On Sep 4, 2015, at 1:45 PM, FlakTheMighty notifications@github.com wrote:

Aside from me finding that you have to keep calling the ragdoll native, no. I can't figure out a good way to get it to keep going for the duration after they're shot.


Reply to this email directly or view it on GitHub.

@rkwapisz That's actually a brilliant idea, and I'm trying to find a suitable number for the duration in frames now.

Alright, so this is a good time for them staying down, but the code is very, very sloppy.
If anyone knows any ways to clean it up I'd appreciate it.

std::vector<Ped> beingShot;
std::vector<int> runTimes;
void update_weapon_features(BOOL bPlayerExists, Player player)
{
    Ped playerPed = PLAYER::PLAYER_PED_ID();

    if (featureWeaponTranqAmmo){

        int duration = 10000;
        int pushForce = 10000;

        const int numElms = 10;
        //Start at index 2, and the odd elements are padding
        const int arrSize = numElms * 2 + 2;
        int peds[arrSize];
        //0 index is the size of the array
        peds[0] = numElms;

        int count = PED::GET_PED_NEARBY_PEDS(PLAYER::PLAYER_PED_ID(), peds, -1);

        for (int i = 0; i < count; ++i)
        {
            int offsettedID = i * 2 + 2;
            if (ENTITY::DOES_ENTITY_EXIST(peds[offsettedID]))
            {
                if (PLAYER::IS_PLAYER_TARGETTING_ENTITY(player, peds[offsettedID]) || PLAYER::IS_PLAYER_FREE_AIMING_AT_ENTITY(player, peds[offsettedID])){
                    if (PED::IS_PED_SHOOTING(playerPed)){
                        beingShot.push_back(peds[offsettedID]);
                        //PED::EXPLODE_PED_HEAD(peds[offsettedID], 0x5FC3C11); // I was using this as a test to make sure this was even working
                        PED::SET_PED_TO_RAGDOLL(peds[offsettedID], pushForce, 20, 1, true, true, true);
                        ENTITY::SET_ENTITY_HEALTH(peds[offsettedID], ENTITY::GET_ENTITY_MAX_HEALTH(peds[offsettedID]));
                        runTimes.push_back(1);
                    }
                }
                else{
                    for (int i = 0; i < beingShot.size(); i++){
                        if (runTimes[i] != 0 && runTimes[i] < duration){
                            ENTITY::SET_ENTITY_HEALTH(peds[offsettedID], ENTITY::GET_ENTITY_MAX_HEALTH(peds[offsettedID]));
                            PED::SET_PED_TO_RAGDOLL(beingShot[i], pushForce, 20, 1, true, true, true);
                            runTimes[i]++;
                        }
                    }
                }
            }
        }

        for (int i = 0; i < beingShot.size(); i++){
            if (runTimes[i] == duration){
                runTimes.erase(runTimes.begin() + i);
                beingShot.erase(beingShot.begin() + i);
            }
        }
    }

I'm thinking of maybe trying to do something with a bunch of this code. I'd like to have peds ragdoll when I'm aiming at them (not shooting, though), and also possibly create an aura around my player within which all peds ragdoll.

The following kills peds in the area around the player

    if (featureDirtNap)
    {
        const int numElms = 10;
        const int arrSize = numElms * 2 + 2;  //Start at index 2, and the odd elements are padding
        int peds[arrSize];
        //0 index is the size of the array
        peds[0] = numElms;

        int count = PED::GET_PED_NEARBY_PEDS(PLAYER::PLAYER_PED_ID(), peds, -1);

        for (int i = 0; i < count; ++i)
        {
            int offsettedID = i * 2 + 2;
            if (ENTITY::DOES_ENTITY_EXIST(peds[offsettedID]))
            {
                PED::EXPLODE_PED_HEAD(peds[offsettedID], 0x5FC3C11);
            }
        }
    }

and this should ragdoll any ped in the area

    std::vector<Ped> beingRagdolled;
    std::vector<int> ragdollTimes;

//Wherver this is going for you, mine's in update_world_features


    if(ragdollField){
        int duration = 10000;
        int pushForce = 10000;

        const int numElms = 10;
        //Start at index 2, and the odd elements are padding
        const int arrSize = numElms * 2 + 2;
        int peds[arrSize];
        //0 index is the size of the array
        peds[0] = numElms;

        int count = PED::GET_PED_NEARBY_PEDS(PLAYER::PLAYER_PED_ID(), peds, -1);

        for (int i = 0; i < count; ++i)
        {
            int offsettedID = i * 2 + 2;
            if (ENTITY::DOES_ENTITY_EXIST(peds[offsettedID]))
            {
                beingRagdolled.push_back(peds[offsettedID]);
                PED::SET_PED_TO_RAGDOLL(peds[offsettedID], pushForce, 20, 1, true, true, true);
                ragdollTimes.push_back(1);
            }
        }

        for (int i = 0; i < beingRagdolled.size(); i++){
             if (ragdollTimes[i] != 0 && ragdollTimes[i] < duration){
                    ENTITY::SET_ENTITY_HEALTH(peds[offsettedID], ENTITY::GET_ENTITY_MAX_HEALTH(peds[offsettedID]));
                    PED::SET_PED_TO_RAGDOLL(beingRagdolled[i], pushForce, 20, 1, true, true, true);
                    ragdollTimes[i]++;
                }
            }

        for (int i = 0; i < beingRagdolled.size(); i++){
            if (ragdollTimes[i] == duration){
                ragdollTimes.erase(ragdollTimes.begin() + i);
                beingRagdolled.erase(beingRagdolled.begin() + i);
            }
        }
    }

I didn't test it, but it should work going off of the shooting and killing two as examples.