PDA

View Full Version : isTouching()



filthy_freak_
15th June 2015, 14:33
I have made a method for detecting if a player is touching a weapon/turret/bombsite. Basically in any situation where the "Press (F) to use" dialog shows up.

Use example:


if ( player isUseTouching() ) ...


Install

Open gsc.cpp, CTRL + F and search for "resetNextReliableTime". Then add the following on a new line;


{"isusetouching" , gsc_player_isusetouching , 0},


Open gsc_player.hpp, CTRL + F and search for "void gsc_player_resetNextReliableTime(int id);". Then add the following on a new line;


void gsc_player_isusetouching(int id);


Open gsc_player.cpp, CTRL + F and search for "// entity functions". Then add the following on a new line;


void gsc_player_isusetouching(int id) {
#if COD_VERSION == COD2_1_0
int info_use_offset = 0x0811F004;
#elif COD_VERSION == COD2_1_2
int info_use_offset = 0x08121338;
#elif COD_VERSION == COD2_1_3
int info_use_offset = 0x08121494;
#endif

int entity = gentities + id * gentities_size;
int base[2050];
int res = 0;

int (*isUseHover)(int a1, void *d);
*(int *)&isUseHover = info_use_offset;

res = isUseHover(entity, base);
stackPushInt(res);
}


Compile your version and you are done.

Tally
15th June 2015, 15:12
It should not be called isTouching() because there is already a built-in function with that name to determine if you are within a trigger range. Call it something else please.

filthy_freak_
15th June 2015, 15:15
It should not be called isTouching() because there is already a built-in function with that name to determine if you are within a trigger range. Call it something else please.

Yup was just about to edit before seeing this.

Mitch
15th June 2015, 18:11
So if i'm understanding this right and from looking at the used function.

You are checking if the player is touching any triggers that is range.
The difference between 'isTouching' and this new function is that the default 'isTouching' requires you to specify the entity that you want to check.

self isTouching(entity)
self isUseTouching()

The function that you are using is called 'G_TouchTriggers'.
If i'm right it should return which entity you are triggering at the moment.

So maybe call the function: 'player getActiveTouchTrigger() or player getCurrentTouchTrigger()' (in case it does return an entity).

Edit: it doesn't return a entity. But it does notify the entities that someone triggers them.

filthy_freak_
15th June 2015, 19:19
Honestly I didn't even know there was a isTouching() function until after I posted this thread. Made the above method so that my sprint does not clash with stock weapon pickups. You can also block bots from picking up weapons/using turrets with a little tweaking.

Mitch
15th June 2015, 21:11
Honestly I didn't even know there was a isTouching() function until after I posted this thread. Made the above method so that my sprint does not clash with stock weapon pickups. You can also block bots from picking up weapons/using turrets with a little tweaking.

Wouldn't it be more effective and useful to hook the call/function that is responsible for picking up weapons?
Then with a libcod function you can set if the player is allowed to pickup weapons or not.

Like this

player enableWeaponPickup();
player disableWeaponPickup();

Ni3ls
16th June 2015, 11:01
Maybe dumb question, but how to compile it?

Mitch
16th June 2015, 11:21
Maybe dumb question, but how to compile it?

https://github.com/kungfooman/libcod/blob/master/README.md

See: Working with the source / Compiling:

filthy_freak_
16th June 2015, 15:30
Wouldn't it be more effective and useful to hook the call/function that is responsible for picking up weapons?
Then with a libcod function you can set if the player is allowed to pickup weapons or not.

Like this

player enableWeaponPickup();
player disableWeaponPickup();

I don't have the knowledge to do this yet. I'm still earning about C++ and libcod.

Mitch
17th June 2015, 13:59
I don't have the knowledge to do this yet. I'm still earning about C++ and libcod.

This is the information that i found so far.


Touch_Item_Auto = 8105C80 (1.3), 81037F0 (1.0)
It calls:

Touch_Item(item_weapon, player, message = 0 / 1)
Item_weapon and player are probably gentities.
So the function gentityaddress_to_num in gsc_player.cpp will probably give you a number between 0 and 63.

The function is called from:

8187F64 (1.3), 8167AE4 (1.0)
8187F8C (1.3), 8167B0C (1.0)
8187FB4 (1.3), 8167B34 (1.0)
These addresses are pointers to a function like closer or download.
Now you can try and replace these pointers with your own function and return to the original function.
Before return to the function you can add a message to see which of the addresses you need.

These commits might help:
Replacing a function: https://github.com/M-itch/libcod/commit/46f9a0cf71f48be20051f94eaf9ef0a8cb70d2c1
Client number: https://github.com/M-itch/libcod/commit/8a5305d804b5e26e2cf2afa95d1e2387aadc42ff

filthy_freak_
17th June 2015, 21:09
Here is disablePickup()

Usage example:


self disablePickup(true);


Also make sure to set disablePickup(bool) on player connect so it will reset properly.

Installation
Open gsc.cpp, CTRL + F and search for "resetNextReliableTime". Then add the following on a new line;


{"disablepickup" , gsc_player_disable_pickup , 0},


Open gsc_player.hpp, CTRL + F and search for "void gsc_player_resetNextReliableTime(int id);". Then add the following on a new line;


void gsc_player_disable_pickup(int id);


Open gsc_player.cpp, CTRL + F and search for "// entity functions". Then add the following on a new line;


void gsc_player_disable_pickup(int id)
{
int disable;

if ( ! stackGetParams("i", &disable)) {
printf("scriptengine> ERROR: gsc_player_allow_pickup(): param \"disable\"[1] has to be an integer!\n");
stackPushUndefined();
return;
}

extern int disable_player_pickup[64];

if(disable)
disable_player_pickup[id] = (1);
else
disable_player_pickup[id] = (0);
}


Open libcod.cpp, CTRL + F and search for "int hook_RemoteCommandTime(void)". Then add the following function before "int hook_RemoteCommandTime(void)";


int disable_player_pickup[64] = {0};
int clientaddress_to_num(int client);

cHook *hook_disable_pickup;
int disable_pickup(int a1, int a2, int a3)
{
int addrtype, ret = 0;
int clientnum = clientaddress_to_num(a2);
extern int playerinfo_base, playerinfo_size;
if(*(int*)(*(int*)playerinfo_base + clientnum * playerinfo_size) == 4 && !disable_player_pickup[clientnum])
{
hook_disable_pickup->unhook();
signed int (*sig)(int a1, int a2, int a3);
*(int *)&sig = hook_disable_pickup->from;
ret = sig(a1, a2, a3);
hook_disable_pickup->hook();
}
return ret;
}


Also while in libcod.cpp, add search and add the following new lines depending on your version;

1.0;
Search for "cracking_hook_call(0x080707C3, (int)Scr_GetCustomMethod);"

Add the following on a new line;


hook_disable_pickup = new cHook(0x080DCC7A, (int)disable_pickup);
hook_disable_pickup->hook();


1.2;
Search for "cracking_hook_call(0x08070D3F, (int)Scr_GetCustomMethod);"

Add the following on a new line;


hook_disable_pickup = new cHook(0x080DF25A, (int)disable_pickup);
hook_disable_pickup->hook();


1.3;
Search for "cracking_hook_call(0x08070E0B, (int)Scr_GetCustomMethod);"

Add the following on a new line;


hook_disable_pickup = new cHook(0x080DF39E, (int)disable_pickup);
hook_disable_pickup->hook();


Compile your version and you are done.

filthy_freak_
17th June 2015, 21:11
The above function only disables weapon pickup and doesn't disable turrets, bomb planting etc.

filthy_freak_
18th June 2015, 02:13
As requested, I have added disablePickup(bool) to libcod for download.

filthy_freak_
24th June 2015, 09:37
I just noticed an unused variable in int disablePickup(int a1, int a2, int a3).

Replace


int addrtype, ret = 0;

With


int ret = 0;

Mitch
30th June 2015, 12:53
The above function only disables weapon pickup and doesn't disable turrets, bomb planting etc.

The code doesn't work correctly, because a2 isn't a client address but a gentity address.
You need to replace 'clientaddress_to_num' with 'gentityaddress_to_num' to get a valid client number.
Edit: the function uses a different a2 variable. So i was wrong. See: http://killtube.org/showthread.php?2210-isTouching()&p=12093&viewfull=1#post12093

filthy_freak_
30th June 2015, 13:43
The code doesn't work correctly, because a2 isn't a client address but a gentity address.
You need to replace 'clientaddress_to_num' with 'gentityaddress_to_num' to get a valid client number.

Are you sure? This is what my log returns;


clientaddress_to_num = 0, gentityaddress_to_num = 1024




int clientnum = clientaddress_to_num(a2);
int clientnum2 = gentityaddress_to_num(a2);
printf("clientaddress_to_num = %i, gentityaddress_to_num = %i\n", clientnum, clientnum2);

Mitch
30th June 2015, 14:05
Are you sure? This is what my log returns;


clientaddress_to_num = 0, gentityaddress_to_num = 1024




int clientnum = clientaddress_to_num(a2);
int clientnum2 = gentityaddress_to_num(a2);
printf("clientaddress_to_num = %i, gentityaddress_to_num = %i\n", clientnum, clientnum2);


Maybe it is a difference between 1.0 and 1.3 (= where i tested it).

Edit: In 1.3 i get this:
clientaddress_to_num = -55, gentityaddress_to_num = 0

filthy_freak_
30th June 2015, 14:15
Remove post

Mitch
30th June 2015, 14:27
EDIT:

Found the problem.

Didn't post the correct addresses for 1.2 and 1.3

Here are the correct addresses:
1.2


hook_delete_weapon = new cHook(0x08105E9E, (int)delete_weapon);
hook_delete_weapon->hook();


1.3


hook_delete_weapon = new cHook(0x08105FFA, (int)delete_weapon);
hook_delete_weapon->hook();


I will update the above post with the fix. Triple edit: Seems like I can't =(

I'm using a function one level higher.

My function (gentity):

sub_8105CAC(signed int s, int a2, int a3)
Your function (client):

result = sub_80DF39E(s, *(_DWORD *)(a2 + 344), a3);

Edit: i committed my version. https://github.com/M-itch/libcod/commit/0dc04f73028a9e2e1aa54a5c096f7f20d91a895f

filthy_freak_
30th June 2015, 14:28
Maybe it is a difference between 1.0 and 1.3 (= where i tested it).

Edit: In 1.3 i get this:
clientaddress_to_num = -55, gentityaddress_to_num = 0

Are you sure you have set


hook_disable_pickup = new cHook(0x080DF39E, (int)disable_pickup);
hook_disable_pickup->hook();

correctly?

EDIT: Going by your previous post, seems like you didn't.

By the way, the use of sub_80DF39E over sub_8105CAC is intentional. Using sub_80DF39E will only disable weapon pickup whereas sub_8105CAC will disable everything with a Use (f) dialogue. Hence why the custom function is called disablePickup and not disableUse.

Mitch
30th June 2015, 16:21
EDIT: Going by your previous post, seems like you didn't.

By the way, the use of sub_80DF39E over sub_8105CAC is intentional. Using sub_80DF39E will only disable weapon pickup whereas sub_8105CAC will disable everything with a Use (f) dialogue. Hence why the custom function is called disablePickup and not disableUse.

My version works exactly the same.

Can you try this:
After you picked up a weapon and disabled the pickup.
You should be hearing the ammo pickup sound and the weapon will disappear and reappear when you go over the weapon again.
(+ not max ammo)

There are 3 pointers to the function Touch_Item_Auto and i only replace the last one (3).
1: This one is responsible for the 'Press [Use] to swap for ...' message.
2: No idea. I don't know how to trigger it. It might have something to do with picking up health.
3: Picks up the item.