Page MenuHomeFeedback Tracker

Weapon stuck in dead player hands
Closed, DuplicatePublic

Description

(((Sometimes))) when a player is killed, other players cannot loot the weapon from the dead player's hands.
Whenever this happens, it can be fixed by going far enough from the dead player that the other player "cache"s the dead player and then returning to the dead player and "uncaching" the dead player.

This issue occurs because the function that drops the item from player hands is only ran on the server, meaning the weapon ACTUALLY drops to the ground on the server, but the client who is there will not see it on the ground and won't be able to access it in the corpse.

Details

Severity
Minor
Resolution
Open
Reproducibility
Sometimes
Operating System
Windows 10 x64
Category
Multiplayer
Steps To Reproduce

You need the following to test this (fast): 1x server instance, 2x client instance

  1. 2 clients on server
  2. Client A and Client B must be close (not cached)
  3. Client A must have a weapon in hands (I used "AK74")
  4. Client A must die with weapon in hands (I jumped off a high place)
  5. If Client B sees the weapon drop to the ground as expected, repeat steps 2, 3, 4, 5 until the weapon is stuck in Client A's dead hands and cannot be interacted with
  6. Client B can now fix the weapon from being stuck by going (at least 1000m) away from the Client A's glitched corpse - Causing it to be cached and then returning to it - Causing it to be uncached.
Additional Information

I fixed this with the following code in a serverside mod:

modded class PlayerBase {
	override void EEKilled( Object killer ) {

		// run the previous EE killed
		super.EEKilled( killer );

		// drop item from hands if there is one in hands
		ItemBase dayx_t_ItemInHands = GetItemInHands();
		if (dayx_t_ItemInHands) {
			bool dayx_t_IsItemDropped = this.LocalReplaceItemInHandsWithNewElsewhere(new DestroyItemInCorpsesHandsAndCreateNewOnGndLambda(dayx_t_ItemInHands, dayx_t_ItemInHands.GetType(), this, false));
		};
	};
};

Notice the Local in LocalReplaceItemInHandsWithNewElsewhere

Event Timeline

nigel created this task.Sep 26 2019, 1:51 PM

I'm not sure if all the information is correct, but after testing this, this is the conclusion and fix that I came up with.

Geez changed the task status from New to Assigned.Sep 30 2019, 3:40 PM

My buddy and I were able to get a 100% repro of this bug by killing someone as they were firing their weapon. In our case a AK74 on full auto. No other scenarios we tried could reproduce the bug.

We inserted @nigel 's code into our server mod as a test, and we were still able to 100% repro the bug. :(

nigel added a comment.Oct 19 2019, 9:02 PM

I'll try shooting and dying erik. Maybe I can reproduce it as well. I did my tests solo and jumping down from a high place to die and then teleported back there.
The plot thickens

Updated code to fix the issue when player fires a gun.

modded class PlayerBase {
	override void EEKilled( Object killer ) {

		// run the previous EE killed
		super.EEKilled( killer );

		// set timesran as 0
		dayxSrv_dropGunOnDeath_m_TimesRan = 0;
		GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( dayxSrv_dropGunOnDeath_FixGun, 500, false );	// Changed delay from 100 to 500 to make sure it werks harder
	};

	int dayxSrv_dropGunOnDeath_m_TimesRan;

	void dayxSrv_dropGunOnDeath_FixGun() {
		// increment times ran
		dayxSrv_dropGunOnDeath_m_TimesRan++;
		Print("dayxSrv - dropGunOnDeath.TimesRan:" + dayxSrv_dropGunOnDeath_m_TimesRan);

		// drop item from hands if there is one in hands
		ItemBase dayx_t_ItemInHands = GetItemInHands();
		Print("dayxSrv - dropGunOnDeath.dayx_t_ItemInHands:" + dayx_t_ItemInHands);
		if (dayx_t_ItemInHands) {
			vector dayxSrv_dropGunOnDeath_t_Pos = dayx_t_ItemInHands.GetPosition();
			dayxSrv_dropGunOnDeath_t_Pos[1] = dayxSrv_dropGunOnDeath_t_Pos[1] + 1.35;

			// move the item up a little bit ( to prevent it from falling through the floor)
			dayx_t_ItemInHands.SetPosition(dayxSrv_dropGunOnDeath_t_Pos);



			//bool dayx_t_IsItemDropped = DropItem(dayx_t_ItemInHands);
			//Print("dayxSrv - dropGunOnDeath.dayx_t_IsItemDropped:" + dayx_t_IsItemDropped);
			bool dayx_t_IsItemDropped = this.LocalReplaceItemInHandsWithNewElsewhere(new DestroyItemInCorpsesHandsAndCreateNewOnGndLambda(dayx_t_ItemInHands, dayx_t_ItemInHands.GetType(), this, false));

			Print("dayxSrv - dropGunOnDeath.dayx_t_IsItemDropped:" + dayx_t_IsItemDropped);
		};
		// check if item was removed from hands
		Print("dayxSrv - dropGunOnDeath.GetItemInHands:" + GetItemInHands());


		// if item is still in hands, redo the fix gun 2 more times
		if (GetItemInHands() != NULL) {
			if (dayxSrv_dropGunOnDeath_m_TimesRan <= 3) {
				GetGame().GetCallQueue( CALL_CATEGORY_SYSTEM ).CallLater( dayxSrv_dropGunOnDeath_FixGun, 500, false );
			};

		};

	};
};

Demonstration video:
https://streamable.com/1fpps