Jump to content

» «

worldGetAllPeds - applying single action to each Ped

1 reply to this topic
  • GTBunny

    Player Hater

  • Members
  • Joined: 28 Apr 2015
  • United-Kingdom


Posted 28 August 2016 - 09:52 PM Edited by GTBunny, 28 August 2016 - 09:56 PM.

Hi all,


I'm using worldGetAllPeds() to iterate through all current pedestrians ("duh"), but struggling to find a way to track individual peds within that pool.


My situation is that I want to be able to apply a force to each ped once, then leave them alone; however, if I apply an action to each Ped in the worldGetAllPeds() array, it happens every frame because I can't note that I've already done something to a Ped, so I need to be able to track each individual Ped and whether or not I've already 'touched' them. (For example, I want to apply a vertical force to each Ped just once, but it applies every frame, so they go f***ing nuts.)


Each Ped's ID within worldGetAllPeds() -- their position in the resulting array -- can be changed at any time, so can be different from one frame to another; in practice, they keep the same ID for seconds at a time, then it randomly changes, as shown in this video (ID changes from 8 to 7), using the code below:



(C) Alexander Blade 2015

#include "script.h"
#include "keyboard.h"

#include <iostream>
#include <string>
#include <ctime>
#include <vector>

using namespace std;

#pragma warning(disable : 4244 4305) // double <-> float conversions

struct UniquePed
	int pool_id;
	Ped ped;

// Adapted from message() by Luucky @ http://gtaforums.com/topic/803745-text-drawing/

// Thanks!

// Important: x, y = 0.0 to 1.0

void DrawLabel(string label, float x, float y, float scale, bool centered = false)
	char* text = (char *)label.c_str();

	if (centered)

	UI::SET_TEXT_SCALE(scale, scale);
	UI::SET_TEXT_COLOUR(255, 255, 255, 255);
	UI::SET_TEXT_WRAP(0.0, 1.0);
	UI::SET_TEXT_DROPSHADOW(2, 2, 0, 0, 0);
	UI::SET_TEXT_EDGE(1, 0, 0, 0, 205);
	UI::_DRAW_TEXT(x, y);

void main()

	const int ARR_SIZE = 1024;

	string msg = "";

	Ped ped[ARR_SIZE];

	Vector3 pedcoords;

	int ped_count = 0;

	int loop = 0;

	float px = 0.0;
	float py = 0.0;

	int peds = 0;

	while (true)
		ped_count = worldGetAllPeds(ped, ARR_SIZE);

		for (loop = 0; loop < ped_count; loop++)
			if (ped[loop] != PLAYER::GET_PLAYER_PED(PLAYER::PLAYER_ID()))

				pedcoords = ENTITY::GET_ENTITY_COORDS(ped[loop], false);

				if (ENTITY::IS_ENTITY_ON_SCREEN(ped[loop]))
					if (GRAPHICS::_WORLD3D_TO_SCREEN2D(pedcoords.x, pedcoords.y, pedcoords.z, &px, &py))
						msg = "Ped: " + to_string(loop);

						DrawLabel(msg, px, py, 0.25, true);


void ScriptMain()

I've tried adding each Ped to a 'Vector' and comparing, but that doesn't seem to work so far. I'm definitely not a C++ master, so may be going about it the wrong way...


Has anyone actually done this and can provide advice on the basic method that would be necessary to apply an action to each Ped in the current pool just once, which would of course mean being able to track them individually?


Hope this makes sense...

  • GTBunny

    Player Hater

  • Members
  • Joined: 28 Apr 2015
  • United-Kingdom


Posted A week ago

Just looking back at this, I did find an ungodly hack of a workaround -- I set 'flag' to an apparently unused ped config flag value, 409. Setting/checking this flag once applied to a ped, I was able to tell if I'd processed it. The value 409 could of course be used by GTA in future, or even in places I'd simply not run into it being used, but it seemed to work:

                        if (!PED::GET_PED_CONFIG_FLAG(ped[loop], flag, true))
                            PED::SET_PED_CONFIG_FLAG(ped[loop], flag, true);
                            //PED::APPLY_DAMAGE_TO_PED(ped[loop], 100, true);

                            ENTITY::APPLY_FORCE_TO_ENTITY_CENTER_OF_MASS(ped[loop], 1, randfrom(-3.0, 3.0), randfrom(-3.0, 3.0), 20.0, true, true, true, true);

Just posting in case anyone else runs into the need for this...

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users