UE1 - UT Weird timing with PreventDeath()

  • Two Factor Authentication is now available on BeyondUnreal Forums. To configure it, visit your Profile and look for the "Two Step Verification" option on the left side. We can send codes via email (may be slower) or you can set up any TOTP Authenticator app on your phone (Authy, Google Authenticator, etc) to deliver codes. It is highly recommended that you configure this to keep your account safe.

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
I'm sending one player to another's location and I'm trying to stop telefragging using PreventDeath. However, upon testing I noticed this weird behaviour :

Code:
ScriptLog: killedId 1
ScriptLog: killerId 2
ScriptLog: sendPawn.PlayerReplicationInfo.PlayerID 2
ScriptLog: destPawn.PlayerReplicationInfo.PlayerID 1
ScriptLog: sentPlayers[ sendPawn.PlayerReplicationInfo.PlayerID ] 1
ScriptLog: destPlayers[ destPawn.PlayerReplicationInfo.PlayerID ] 1

Line 1 and line 2 are from PreventDeath(). All the rest of the lines come from variables set in Mutate(). The last two are from tables of bytes that I'm using as booleans. This reflects a condition that tests if the sent player is the one that frags the player at the destination.

Now, in the sequence of events, I trigger instructions in Mutate() and then a player is displaced. However, from this log it looks like PreventDeath() is being triggered before I do anything. Obviously, this completely messes up my test. What is going on :D ?
 
Last edited:

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
I don't understand your mix of PreventDeath (called right before a player dies) and Mutate. (called when a player uses a "mutate something" console command)
Technically Mutate is on no way related to telefragging at all.
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
I guess my explanation is clear as mud.

What I'm doing is simply setting the location of player A to that of player B. Normally, this will cause a telefrag (similar to what happens when two players attempt to spawn at the same playerstart).

What I'm trying to avoid is this telefrag by making two players coexist in the same space. I don't know if this is advised and can cause undesireable effects (player being sent is automatically "bounced" off the other player ?). In the meantime, I'm experimenting with collision settings.

Here's the mutate function :

Code:
function Mutate( string mutateString, PlayerPawn pp )
{
[...]					if( destPawn != none )
					{
						//p.SetCollision( false, false, false );
						p.SetDisplayProperties( STY_Translucent, p.Texture, p.bUnLit, p.bMeshEnviromap );

						sendPawn.ClientSetLocation( destPawn.Location, destPawn.ViewRotation );
						pp.ClientMessage( "Player has been sent." );
						// logs were here

So what's (or should be) happening in the sequence of things is that an admin logs in and chooses a player location as destination. Then he chooses another player to be sent to that location.

The variables I'm outputting are all set before anything happens to the player.

However, as soon as PreventDeath is called when the first player coincides with the second player, it's as if none of those variables have been set. This totally baffles me.

Either I've done something terribly wrong or it's as if PreventDeath is being called before any of the variables get set in Mutate.
 
Last edited:

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
I'm using Mutate() to intercept mutate commands from an admin. It allows them to choose a first player using their PlayerID and then a second player in the same manner. Mutate() then automatically changes the location of the first player to match the location of the second player.

That's when the telefrag takes place and that's what I'm trying to avoid with PreventDeath().

In order to do that, I need to test if Killer is the player who's location is being changed and if Killed is the player who's location was chosen as a destination.

That's where a problem has popped up. The class variables appear empty even though I set them in Mutate() beforehand. Perhaps there's something wrong in the way I'm using PreventDeath :

Code:
function bool PreventDeath(Pawn Killed, Pawn Killer, name damageType, vector HitLocation)
{
	Super.PreventDeath(Killed,Killer,DamageType,HitLocation);

	if( Killer.Style == STY_Translucent ) // Blah code here to check player
	{
		//
		p.SetDisplayProperties( STY_Normal, Killer.Texture, Killer.bUnLit, Killer.bMeshEnviromap );

		return true;
	}

	return false;
}

I could write some code to change the location to somewhere nearby but I want to get this working first so some adjustments can be made afterwards.

P.S: This mod is for BunnyTrack in case you're wondering what this is all about.
 
Last edited:

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
And to clarify the tests in the first post, this is what I was expecting to happen :

Mutate()
1) PlayerID of player who's location is being changed: 2
2) PlayerID of player who's location is being used for the location change: 1
3) sentPlayers[ 2 ] (table of bytes) is given the value of 1
4) destPlayers[ 1 ] (table of bytes) is given the value of 1
5) Player 2 location is set to Player 1 location.

PreventDeath()
1) Killer PlayerID = 2
2) Killed PlayerID = 1
3) sentPlayers[ 2 ] = 1
4) destPlayers[ 1 ] = 1

Here's what actually happens :

Mutate()
1) PlayerID of player who's location is being changed: 2
2) PlayerID of player who's location is being used for the location change: 1
3) sentPlayers[ 2 ] (table of bytes) is given the value of 1
4) destPlayers[ 1 ] (table of bytes) is given the value of 1
5) Player 2 location is set to Player 1 location.

PreventDeath()
1) Killer PlayerID = 2
2) Killed PlayerID = 1
3) sentPlayers[ 2 ] = 0
4) destPlayers[ 1 ] = 0

And it's at about this point I was saying wtf to myself and decided to post here :p .
 
Last edited:

Wormbo

Administrator
Staff member
Jun 4, 2001
5,913
36
48
Germany
www.koehler-homepage.de
How about something like this instead:
Code:
local bool bTemCollideActors, bTempBlockActors, bTempBlockPlayers;
local vector TempLocation;

bTemCollideActors = Player2.bCollideActors;
bTempBlockActors = Player2.bBlockActors;
bTempBlockPlayers = Player2.bBlockPlayers;
TempLocation = Player2.Location;
Player2.SetCollision(False, False, False);
Player2.SetLocation(Player1.Location);
Player1.SetLocation(TempLocation);
Player2.SetCollision(bTemCollideActors, bTempBlockActors, bTempBlockPlayers);
Player2.SetLocation(Player2.Location); // to force touching stuff (try without this line first and see if weird stuff happens)
This should work around the entire telefragging problem.
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Thanks for the suggestion. I'll probably get this working today so I'll post back if I've figured out what's happening.

P.S: That quote in your signature is so true it's taunting me :p .