PDA

View Full Version : setStance() possible?



filthy_freak_
3rd June 2015, 02:46
I'v spent the past 5 hours trying to figure out if it's possible to change a player stance using libcod without any luck.

Is it even possible to do? Or is it a client-side only?

kung foo man
3rd June 2015, 07:27
Did you try to "reverse" the function? Never tested that, but could work.

Otherwise you could do exexclientcommand("gocrouch") for example.

http://killtube.org/showthread.php?1261-player-execClientCommand%28-quot-say-boobs-quot-%29

filthy_freak_
3rd June 2015, 08:52
Did you try to "reverse" the function? Never tested that, but could work.
Not sure what you mean here.


Otherwise you could do exexclientcommand("gocrouch") for example.
Won't work for bots.

kung foo man
3rd June 2015, 11:26
Reading from the address (https://github.com/kungfooman/libcod/blob/master/gsc_player.cpp#L331)



void gsc_player_stance_get(int id) {
int entity = gentities + id * gentities_size;
unsigned char *stance_address = (unsigned char *)(entity + 8);
int code = *stance_address & 0x0F; // just the last 4 bits tell the state

char *stance = "";
switch (code) {
case 0: stance = "stand"; break; // also in spec
case 2: stance = "stand"; break;
case 4: stance = "duck"; break;
case 6: stance = "duck"; break;
case 8: stance = "lie"; break;
case 10: stance = "lie"; break;
default: printf("unknown stance for player id=%d, code=%d\n", id, code);
}

stackPushString(stance);
}


Writing to the address (untested):



void gsc_player_stance_set(int id) {
char *stance;
if ( ! stackGetParams("s", &stance)) {
printf("scriptengine> ERROR: gsc_player_stance_set(): param \"stance\" has to be a string!\n");
stackPushUndefined();
return;
}
int entity = gentities + id * gentities_size;
unsigned char *stance_address = (unsigned char *)(entity + 8);
if ( ! strcmp(stance, "stand"))
*stance_address |= 0x00; // maybe 0x02
if ( ! strcmp(stance, "duck"))
*stance_address |= 0x04; // maybe 0x06
if ( ! strcmp(stance, "lie"))
*stance_address |= 0x08; // maybe 0x0a
stackPushUndefined();
}

filthy_freak_
3rd June 2015, 11:47
Reading from the address (https://github.com/kungfooman/libcod/blob/master/gsc_player.cpp#L331)



void gsc_player_stance_get(int id) {
int entity = gentities + id * gentities_size;
unsigned char *stance_address = (unsigned char *)(entity + 8);
int code = *stance_address & 0x0F; // just the last 4 bits tell the state

char *stance = "";
switch (code) {
case 0: stance = "stand"; break; // also in spec
case 2: stance = "stand"; break;
case 4: stance = "duck"; break;
case 6: stance = "duck"; break;
case 8: stance = "lie"; break;
case 10: stance = "lie"; break;
default: printf("unknown stance for player id=%d, code=%d\n", id, code);
}

stackPushString(stance);
}


Writing to the address (untested):



void gsc_player_stance_set(int id) {
char *stance;
if ( ! stackGetParams("s", &stance)) {
printf("scriptengine> ERROR: gsc_player_stance_set(): param \"stance\" has to be a string!\n");
stackPushUndefined();
return;
}
int entity = gentities + id * gentities_size;
unsigned char *stance_address = (unsigned char *)(entity + 8);
if ( ! strcmp(stance, "stand"))
*stance_address |= 0x00; // maybe 0x02
if ( ! strcmp(stance, "duck"))
*stance_address |= 0x04; // maybe 0x06
if ( ! strcmp(stance, "lie"))
*stance_address |= 0x08; // maybe 0x0a
stackPushUndefined();
}


Oh yeah tried that but it didn't do anything.

Also decompiled allowstand/allowcrouch/allowprone (With some help) and came up with this;


int* test = (int*)((*(int*)(gentities + id * gentities_size + 344)) + 12);
*test = *test | 0x800001; //80001 = prone I believe.


Which does have some effect on the stance but seems to get overridden (Player starts prone animation for a split second before it will cancel).

Mitch
3rd June 2015, 11:56
Maybe you need to add the code below after you set it.

*(int *)(state + 216) = 11;
Like the melee first bash bug.
https://github.com/M-itch/libcod/commit/c3889453ffce5df9b10f3eb043a4f6d86ac2ce74

filthy_freak_
3rd June 2015, 12:31
Still same problems.

Here is the output i get before & after setting stance_address;


stance_address = 0 //currently standing
stance_address = 4 //set to crouch
stance_address = 0 //reverted back to standing
stance_address = 4 //rinse and repeat


Also for the "test" variable, it seems to do the weird split second animation no matter what I set it to which makes me think its not going to be helpful despite being related to player stance.

kung foo man
3rd June 2015, 15:41
Did you actually try my version and tested the other "maybe-values"? Only 4 bits define the state, maybe the other 4 bits cause the problem, hence the xor-assignment.

You can also try to breakpoint on the "write" of that address: http://stackoverflow.com/questions/58851/can-i-set-a-breakpoint-on-memory-access-in-gdb

So you can trace back which function resets the value.

filthy_freak_
30th June 2015, 10:37
Hmm, just had a thought of another way to do it.

Currently meatbot makes the bot play the stand/crouch/prone animation when it shoots their gun. This can only be done via mp/playeranim.script

So maybe it could be possible to make a libcod function that sets the players current animation using gsc? Could be useful for many things other than bot stances.

Example;


if(player.isSprinting)
player setAnimation("pb_sprint");
else
player setAnimation("none"); //reset back to default/reset back to mp/playeranim.script


Having a quick look, setting g_dumpAnims will report current animations being played so that is a start.

filthy_freak_
30th June 2015, 14:35
After doing a bit more research, I have discovered that if you hook bg_playeranimation (sub_80D82A4 on 1.0) and make it return 0, it does have some sort of effect on animations. However only if sv_cheats/devmap is enabled.

kung foo man
30th June 2015, 17:16
I digged some time through the animation functions and I could set a new animation, but it was instantly resetted. Maybe this helps you to look further without redoing whats already done.

libcod, for version 1.3 iirc:


int BG_AnimationIndexForString(char *string) { ... }

https://github.com/kungfooman/libcod/blob/master/libcod.cpp#L1920

BG_PlayAnim e.g. I just hooked to look what arguments it receives. Just play a bit around with it or add a hook to dump the arguments and still execute the original function.

The actual function calls for testing this animation stuff is here: https://github.com/kungfooman/libcod/blob/master/gsc.cpp#L1935 (https://github.com/kungfooman/libcod/blob/master/gsc.cpp#L1935)

I was calling the closer functions by abusing a cvar, with this: https://github.com/kungfooman/cod2_std/blob/master/debugging.gsc#L10


/rcon set closer "1100,first,second,third arg"



// ps animIndex bodyPart is_0/time setTimer, isContinue, force
case 1100: return stackPushInt(BG_PlayAnim(0x08705480, 0x00000118, 0x00000002, 0x00/*000567*/, 1, 0, 1)); // reload
case 1101: return stackPushInt(BG_PlayAnim(0x08705480, 0x00000082, 0x00000003, 0x00/*000037*/, 1, /*0*/1, 1)); // strafejump
case 1102: return stackPushInt(BG_PlayAnim(0x08705480, 0x00000083, 0x00000003, 0x00/*000037*/, 1, 0, 1)); // oO 1
case 1103: return stackPushInt(BG_PlayAnim(0x08705480, 0x00000080, 0x00000003, 0x00/*000037*/, 1, 0, 1)); // oO 2
case 1104: return stackPushInt(BG_PlayAnim(0x08705480, 0x00000000, 0x00000002, 0x00/*001000*/, 1, 1, 1)); // nothing
case 1105: return stackPushInt(BG_PlayAnim(0x08705480, 0x00000085, 0x00000003, 0x00/*000600*/, 1, 1, 1)); // highjump
case 1106: return stackPushInt(BG_PlayAnim(0x08705480, 0x00000081, 0x00000003, 0x00/*000037*/, 1, 1, 1)); // highjump
case 1107: return stackPushInt(BG_PlayAnim(0x08705480, 6, 0x00000003, 0x00/*000037*/, 1, 1, 1));


Today I would probably use call_function_raw though: http://killtube.org/showthread.php?2108-call_function_raw%28%29-BinaryBuffer-functions-dlopen-dlsym-dlclose

That makes it a lot faster, no need to recompile libcod and restart the server everytime etc.

In php's CoDExtended, get_animation_index(name):



void GScr_xtnded_anim(int a1) { ... }
{"get_animation_index", GScr_xtnded_anim, 0},

https://github.com/riicchhaarrd/CoDExtended/blob/master/old/xtnded/patch%201.1/linux/game/script.cpp#L16

filthy_freak_
30th June 2015, 23:38
Success!

http://killtube.org/downloads/filthy_freak/setanim.gif