Jump to content

GTA IV C++ ScriptHook - How to retrieve all entities?


Recommended Posts

Hello everybody, I just made up this account because I need help about GTA IV Coding with Aru scripthook.

I can see that GTA IV has many natives, but still, I can't find one to achieve my goal: retrieving all pedestrians within a certain range, or all pedestrians actually existing.

I am coding in C++ with Aru's ScriptHook, but I noticed that Scripthookdotnet implements methods likeĀ 

World.GetAllPeds()

Which returns all pedestrians in the world...I have no clue on how to obtain that in pure C++, since there are no natives that expose directly this function.

I thought about using nativeĀ 

GET RANDOM CHAR IN AREA OFFSET NO SAVE

To fill up an array of Pedestrians, then at each call check if the pedestrian is inside the array and if it is not, add it to the array.

It would populate it, but it seems like a hack(ish) way to obtain what I am after.

Will anybody help me please? Thank you.

Edited by NAST0R
Link to comment
https://gtaforums.com/topic/975096-gta-iv-c-scripthook-how-to-retrieve-all-entities/
Share on other sites

You can look at the ScriptHokkDotNet source code to find out :

World::GetAllPeds() -> World::GetValidPedHandles() -> MemoryAccess::GetPedHandleList() -> MemoryAccess::GetListOfHandlesInPool()
	array<int>^ MemoryAccess::GetListOfHandlesInPool(int PoolAddress) {
		List<int>^ list = gcnew List<int>();
		int listadr =		*(int*)(PoolAddress);
		int booladr =		*(int*)(PoolAddress + 4);
		int maxcount =		*(int*)(PoolAddress + 8);
		int itemsize =		*(int*)(PoolAddress + 12);
		int val;
		for (int i = 0; i < maxcount; i++) {
			val =  (int) *(u8*)(booladr + i); // parity value
			if ((val&0x80) == 0) { // wrong was: (val > 0)
				val = (i << 8) | val;
				list->Add(val);
			}
		}
		return list->ToArray();
	}

And here is your solution.

That's said, I'm not sure it's the best way to do what you wants to do, but this is where I would have started. Hope it helps.

Thank you for this answer Teki. I actually solved it in a much simpler way, I see in ScriptHookDotNet source code the author does some weird memory magic to obtain all handles, I can't understand that in depth.
But now I have another problem: if I try to create a blip, it succesfully shows on the map, and I can set various options about it succesfully, BUT some weird stuff happens:
If I create a blip viaĀ 

AddBlipForContact(MyFloatX, MyFloatY, MyFloatZ, &MyPtrToStoreBlip);

And set its display value to the one which should display radar, map and 3D marker, the 3D marker is HUGE and I cannot change its dimensions by changing blip scale, since it only affects the sprite on the map and radar.

If I instead try to create it via

AddBlipForCoord(MyFloatX, MyFloatY, MyFloatZ, &MyPtrToStoreBlip);

Whatever display mode I choose, the yellow arrow 3D marker simply doesn't show up.

I've been searching for two days for the solution of this problem, and on the internet it seems like the entire GTA 4 modding comunity simply never got this problem, which is weird, since I am sure I am calling the native for creating and setting the blip correctly, otherwise it wouldn't even show on radar and map.

Am I missing something? I simply need a way to place a visible marker like the yellow mission arrows, I tried many things, like using DRAW_COLOURED_CYLINDER native by directly invoking it and passing parameters...it causes a crash. I don't know what to do.

Edited by NAST0R
typo

Bump for: I actually tried implementing the following piece of code from DotNet src code:

array<int>^ MemoryAccess::GetListOfHandlesInPool(int PoolAddress) {
		List<int>^ list = gcnew List<int>();
		int listadr =		*(int*)(PoolAddress);
		int booladr =		*(int*)(PoolAddress + 4);
		int maxcount =		*(int*)(PoolAddress + 8);
		int itemsize =		*(int*)(PoolAddress + 12);
		int val;
		for (int i = 0; i < maxcount; i++) {
			val =  (int) *(u8*)(booladr + i); // parity value
			if ((val&0x80) == 0) { // wrong was: (val > 0)
				val = (i << 8) | val;
				list->Add(val);
			}
		}
		return list->ToArray();
	}

But it doesn't work. I call it passing the pedestrians pool address specified in the source code for the latest version supported (1.1.2.0), but the returned array is always of Length 0, meaning that "val&0x80", for whatever val, is never equal to 0.
Perhaps the pool addresses changed in time? I am currently experimenting on latest version, 1.2.0.43.
If anybody who knows enough of C++ could help, it would do me a great favor.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 0 User Currently Viewing
    0 members, 0 Anonymous, 0 Guests

×
×
  • Create New...

Important Information

By using GTAForums.com, you agree to our Terms of Use and Privacy Policy.