Jump to content


Photo

Property changes working only on a host or only on a client


  • Please log in to reply
6 replies to this topic

#1 Daz

Daz

    title available

  • Hosted
  • 2,654 posts
  •  Revora Co-Founder

Posted 28 February 2009 - 08:57 PM

I've been picking brains on the Epic Games forums about this and I thought I'd try here too.

First I've got a weapon that has an iron-sights function like the Call of Duty games. When I zoom (go into iron sights mode) the weapon's Spread is set to a smaller value called SpreadScoped for better accuracy and then reverts to a larger value called SpreadNoScoped when I zoom out (leave iron sights mode).
When you play an Instant Action game or host a multiplayer game this functions absolutely correctly, but if you join a game it gets ignored (the game uses whatever Spread is set to in default properties).
I also modify the GroundSpeed of the player when you zoom in or out with the same results (fine on host, ignored on join).

At the moment the code relevant to spread changing looks like this:
/** New spread values for Scoped or Not */
var float SpreadScoped;
var float SpreadNoScoped;

simulated function rotator AddSpread(rotator BaseAim)
{
	if(GetZoomedState() == ZST_NotZoomed)
		{
			Spread[0] = FMin(Spread[0]+0.045,0.045);
			Spread[1] = FMin(Spread[1]+0.045,0.045);
		}
		else
		{
			Spread[0] = FMin(Spread[0]+0.0025,0.0025);
			Spread[1] = FMin(Spread[1]+0.0025,0.0025);
		}
	return Super.AddSpread(BaseAim);
}

defaultproperties
{
	Spread(0)=0.045
	SpreadScoped=0.0025
	SpreadNoScoped=0.045
}
This has been tried in various guises including putting "Spread(0) = SpreadScoped" in the zoom in function and "Spread(0) = SpreadNoScoped" in the zoom out function but it still only works on the host.

The speed changing code looks like this:
/** Original values to revert to after zooming out */
var float BaseGroundSpeed;
var float BaseAirSpeed;
var float BaseWaterSpeed;
var float BaseJumpZ;

/** New values to switch to after zooming in */
var float ZoomGroundSpeed;
var float ZoomAirSpeed;
var float ZoomWaterSpeed;
var float ZoomJumpZ;

simulated function StartZoom(UTPlayerController PC)
{
		Local Pawn P;

		P = Pawn(owner);
		P.GroundSpeed = Default.ZoomGroundSpeed;
		P.AirSpeed = Default.ZoomAirSpeed;
		P.WaterSpeed = Default.ZoomWaterSpeed;
		P.JumpZ = Default.ZoomJumpZ;
	ZoomCount++;
	if (ZoomCount == 1 && !IsTimerActive('Gotozoom') && IsActiveWeapon() && HasAmmo(0) && Instigator.IsFirstPerson())
	{
		bDisplayCrosshair = false;
		PlayWeaponAnimation('WeaponZoomIn',0.2);
		PlayArmAnimation('WeaponZoomIn',0.2);
		bAbortZoom = false;
		SetTimer(0.2, false, 'Gotozoom');
	   	SetTimer(0.2,false,'PlayMyZoomIdle');
		Spread[CurrentFireMode] = Default.SpreadScoped;
		MaxYawLag = Default.MaxYawLagZoom;
		MaxPitchLag = Default.MaxPitchLagZoom;
	}
	Super.StartZoom(PC);
}

defaultproperties
{
	BaseGroundSpeed=440.0
	BaseAirSpeed=440.0
	BaseWaterSpeed=220.0
	BaseJumpZ=322.0

	ZoomGroundSpeed=240.0
	ZoomAirSpeed=340.0
	ZoomWaterSpeed=110.0
	ZoomJumpZ=256.0
}

I also have a set of weapons which change the groundspeed of the player when you equip them, this does the exact opposite and works when you join a game but not when you host one.
The code for that looks like this:
/** Absolute Ground Speed for this weapon */
var float NewGroundSpeed;

simulated function Activate()
{
		Local Pawn P;

		P = Pawn(owner);
		P.GroundSpeed = Default.NewGroundSpeed;
	super.Activate();
}

defaultproperties
{
	NewGroundSpeed=280.000000
}

Is it possible this is just down to my network (I'm running two PCs on a wired LAN via a router, one has ZoneAlarm on and one is just running Windows Firewall. They connect and you can play games fine but I'm not sure the firewall settings would let everything through)?

If not can anyone contribute a possible solution?

Edit:
I added
replication
{
  if ( Role == ROLE_Authority )
	ZoomGroundSpeed,
	ZoomAirSpeed,
	ZoomWaterSpeed,
	ZoomJumpZ,
	BaseGroundSpeed,
	BaseAirSpeed,
	BaseWaterSpeed,
	BaseJumpZ,
	SpreadScoped,
	SpreadNoScoped;
}
Which covers the things that were only working on the Host and not the Client and had no effect.

I added
replication
{
  if ( Role == ROLE_Authority )
	NewGroundSpeed;
}
Which covers the thing that was working on the Client and not the Host and appears to have fixed it.

Edited by Daz, 01 March 2009 - 10:51 AM.


#2 ambershee

ambershee

    Nimbusfish Rawks

  • Hosted
  • 3,114 posts
  • Location:Derby, UK
  • Projects:Mutator Week & Unreal 3 Projects
  •  Mad Mod Boffin

Posted 01 March 2009 - 01:44 PM

The issue, is that your code isn't taking into account replication - so any clients will never see those changes- they're written server side only. You might be able to find a tutorial out there, but essentially, you're going to need a replication block.

Edit: Never mind, you've already solved that, lol.

Edited by ambershee, 01 March 2009 - 01:45 PM.


#3 Daz

Daz

    title available

  • Hosted
  • 2,654 posts
  •  Revora Co-Founder

Posted 01 March 2009 - 05:50 PM

I did a little test by setting my Spread(0) to a daft value that would be very visually obvious.
I moved all of the stuff I want to happen when you zoom in or out out of the zoom functions and into this new function:
simulated function CheckMyZoom()
{
		Local Pawn P;

		P = Pawn(owner);
	if(GetZoomedState() == ZST_NotZoomed)
	{
			P.GroundSpeed = Default.BaseGroundSpeed;
			P.AirSpeed = Default.BaseAirSpeed;
			P.WaterSpeed = Default.BaseWaterSpeed;
			P.JumpZ = Default.BaseJumpZ;
		Spread[CurrentFireMode] = Default.SpreadNoScoped;
		MaxYawLag = Default.MaxYawLag;
		MaxPitchLag = Default.MaxPitchLag;
	}
	else
	{
			P.GroundSpeed = Default.ZoomGroundSpeed;
			P.AirSpeed = Default.ZoomAirSpeed;
			P.WaterSpeed = Default.ZoomWaterSpeed;
			P.JumpZ = Default.ZoomJumpZ;
		Spread[CurrentFireMode] = Default.SpreadScoped;
		MaxYawLag = Default.MaxYawLagZoom;
		MaxPitchLag = Default.MaxPitchLagZoom;
	}
}

And coded so that this function would run on "simulated function Activate()", "simulated function StartZoom(UTPlayerController PC)" and "simulated function EndZoom(UTPlayerController PC)".

The idea of this was that I can see if my function is running at all because if it didn't I would get the silly huge Spread(0) value, whereas if it did I would get the SpreadNoScoped value (without any zooming in or out).

On both the host and client the function worked on activate (ie both PCs used the SpreadNoScoped value rather than Spread(0), but only the host switched to the SpreadScoped value after zooming in (as it always has been).

Unless I'm hugely overlooking something the problem is with using either the AddSpread, StartZoom or EndZoom (or InstantFire, I tried that too, Tick aswell) function to call my function and influence these variables and as such I need another way to make my function run.

Edited by Daz, 01 March 2009 - 06:23 PM.


#4 Daz

Daz

    title available

  • Hosted
  • 2,654 posts
  •  Revora Co-Founder

Posted 02 March 2009 - 05:56 PM

I moved the spread changes back into an AddSpread function and that also selects SpreadNoScoped, which suggests that the problem is "if(GetZoomedState() == ZST_NotZoomed)" always returning true when you're not a host. But the Sniper Rifle uses it so that wouldn't make sense.

#5 ambershee

ambershee

    Nimbusfish Rawks

  • Hosted
  • 3,114 posts
  • Location:Derby, UK
  • Projects:Mutator Week & Unreal 3 Projects
  •  Mad Mod Boffin

Posted 03 March 2009 - 07:49 PM

Are you sure your states are being replicated? If they're not, the weapon will never enter the zoomed state. You'll have to manually call 'GoToState' in order for a state change to be replicated.

#6 Daz

Daz

    title available

  • Hosted
  • 2,654 posts
  •  Revora Co-Founder

Posted 03 March 2009 - 07:58 PM

There's not actually a state for being zoomed in, zoomed or not works like this
simulated function EZoomState GetZoomedState()
{
	local PlayerController PC;
	PC = PlayerController(Instigator.Controller);
	if ( PC != none && PC.FOVAngle != PC.DefaultFOV )
	{
		if ( PC.FOVAngle == PC.DesiredFOV )
		{
			return ZST_Zoomed;
		}

		return ( PC.FOVAngle < PC.DesiredFOV ) ? ZST_ZoomingOut : ZST_ZoomingIn;
	}
	return ZST_NotZoomed;
}

I haven't actually played with this function.

Edit:
Well it's certainly running just not returning true when zoomed in.

Edit Again:
I've just had a look at the RealWeapons mutator, he uses a boolean to check if he's zoomed or not so I switched to that method to see if it worked.

So I've got "GoAim = true;" and "GoAim = false;" in the appropriate places (and specified as a variable) and my checkzoom function now looks like this:
simulated function CheckMyZoom()
{
		Local Pawn P;
		P = Pawn(Owner);
	  if (GoAim == true)
	{
			P.GroundSpeed = Default.ZoomGroundSpeed;
			P.AirSpeed = Default.ZoomAirSpeed;
			P.WaterSpeed = Default.ZoomWaterSpeed;
			P.JumpZ = Default.ZoomJumpZ;
		Spread[CurrentFireMode] = Default.SpreadScoped;
		  `log("GoScoped");
	}
	  else if (GoAim == false)
	{
			P.GroundSpeed = Default.BaseGroundSpeed;
			P.AirSpeed = Default.BaseAirSpeed;
			P.WaterSpeed = Default.BaseWaterSpeed;
			P.JumpZ = Default.BaseJumpZ;
		Spread[CurrentFireMode] = Default.SpreadNoScoped;
		  `log("NoScoped");
	}
}

It's logging GoScoped and NoScoped as it should but the values aren't being set.
I've just looked at the host and it's logged NoScoped twice, but the client log has nine alternating GoScoped and NoScoped.

Edited by Daz, 03 March 2009 - 09:26 PM.


#7 Daz

Daz

    title available

  • Hosted
  • 2,654 posts
  •  Revora Co-Founder

Posted 04 March 2009 - 03:44 PM

I switched to hard coding and it still didn't work. I've just tried the RealWeapons2.1 stuff on a network and that was totally and utterly screwed aswell.

I had functions and variables all over the place so I've gone back to this simple version.
The important bits of code now are:
simulated function StartZoom(UTPlayerController PC)
{
	local utpawn p;
	p = utpawn(instigator);
		if (P != none)
		{
			P.GroundSpeed = 240;
			P.AirSpeed = 340;
			P.WaterSpeed = 110;
			P.JumpZ = 256;
			Spread[0] = 0.0025;
		`log("StartZoomValsSet");
	}
	bDisplayCrosshair = false;
	PlayWeaponAnimation('WeaponZoomIn',0.2);
	PlayArmAnimation('WeaponZoomIn',0.2);
	SetTimer(0.2, false, 'Gotozoom');
	SetTimer(0.2,false,'PlayMyZoomIdle');
		`log("StartZoom");
}
simulated function LeaveZoom()
{
	local UTPlayerController PC;
	local utpawn p;
	p = utpawn(instigator);
	PC = UTPlayerController(Instigator.Controller);
	if (PC != none)
	{
		PC.EndZoom();
	}
		if (P != none)
		{
			P.GroundSpeed = 440;
			P.AirSpeed = 440;
			P.WaterSpeed = 220;
			P.JumpZ = 322;
			Spread[0] = 0.045;
		`log("LeaveZoomValsSet");
	}
	PlayWeaponAnimation('WeaponZoomOut',0.3);
	PlayArmAnimation('WeaponZoomOut',0.3);
	SetTimer(0.3,false,'RestartCrosshair');
		`log("LeaveZoom");
}
The server logged absolutely nothing at all from the above.

Edit:
A post from DannyMeister on Beyond Unreal pointed me to StartFire() and ServerStartFire(), using the same method to sync the server and client I've got this working now.

Edited by Daz, 05 March 2009 - 09:20 AM.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users