UE3 - UT3 Property changes working only on a host or only on a client

  • 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.

DazJW

Member
Mar 25, 2008
91
0
6
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:
Code:
/** 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:
Code:
/** 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:
Code:
/** 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?
 
Last edited:

DazJW

Member
Mar 25, 2008
91
0
6
Replication blocks handle variables and functions are handled by putting server or client reliable or unreliable in front of them (ie reliable client function).
I can't change the functions because you can't redefine replication for an existing function, and whenever I try to use a replication block for Spread it says bad variable on compile.

Epic's Enforcer code has a "simulated function rotator AddSpread(rotator BaseAim)" function without any else specified and I presume that works on a network.

Edit:
I added
Code:
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
Code:
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.
 
Last edited:

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Which covers the thing that was working on the Client and not the Host and appears to have fixed it.

It sounds like you are running tests on a listen server where the server cannot exist without a player. It's best to test mods like this on a dedicated server as a listen server can produce strange results (the host player is represented by two Actors).

Also, you should state what functions are reliable and unreliable in the replication block. Unreliable simply means something non-essential that can be dropped if a client has low netspeed or packetloss (like sound or visual effects). Anything that isn't properly defined risks not being replicated to the client. The simulated keyword is added to state that a function can be used on a client which doesn't mean it will be automatically used as such.

According to the context, some variables and functions might already be handled by Epic code. So it's up to you to find out what those are and skip them. Anything replicated should be added as a serverpackage so it can be downloaded to a client. I don't know why the compiler is saying that spread is a bad variable.

Edit: http://wiki.beyondunreal.com/Legacy:Compiler_Errors

As for the concept, you can think of the classes that use replication as existing on both the server and client. This approach minimizes network traffic with respect to some approaches that were used previous to Unreal/UT1. The replication block just states what parts of the class are relevant to the server and client.

P.S: There's a few important comments on that link about vectors and rotations.
 
Last edited:

DazJW

Member
Mar 25, 2008
91
0
6
I've just tried with a dedicated server and it was the same.
You can't state anything about functions in a replication block in UE3, you put "reliable client function AddSpread" or something like that. But you can't change the replication settings for a function that already exists in UTWeapon or Weapon (such as AddSpread, StartZoom, EndZoom - all the ones I want to use). You can specify reliable in the replication block either as it won't compile.

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:
Code:
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.
 
Last edited:

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
It would help if you mentionned what classes you're extending :p .
 

DazJW

Member
Mar 25, 2008
91
0
6
Full code :p

Code:
class UTWeap_W1866 extends UTWeapon;

var class<UTDamageType> HeadShotDamageType;
var float HeadShotDamageMult;

/** headshot scale factor when moving slowly or stopped */
var float SlowHeadshotScale;

/** headshot scale factor when running or falling */
var float RunningHeadshotScale;

/** Zoom minimum time*/
var bool bAbortZoom;

/** sound while the zoom is in progress */
var audiocomponent ZoomLoop;
var soundcue ZoomLoopCue;

/** Whether the standard crosshair should be displayed */
var bool bDisplayCrosshair;

/** tracks number of zoom started calls before zoom is ended */
var int ZoomCount;

/** New spread values for Scoped or Not */
var float SpreadScoped;
var float SpreadNoScoped;

/** New values to stop weapon lagging behind look and being off-centre */
var float MaxPitchLagZoom;
var float MaxYawLagZoom;

/** Weapon animations for use while zoomed */
var(Animations)	array<name>	WeaponFireAnimZoom;
var(Animations) array<name> WeaponIdleAnimsZoom;

/** 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;

replication
{
  if ( Role == ROLE_Authority )
	ZoomGroundSpeed,
	ZoomAirSpeed,
	ZoomWaterSpeed,
	ZoomJumpZ,
	BaseGroundSpeed,
	BaseAirSpeed,
	BaseWaterSpeed,
	BaseJumpZ,
	SpreadScoped,
	SpreadNoScoped;
}

server reliable 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;
	}
}

simulated function Activate()
{
	SetTimer(0.0000001,false,'CheckMyZoom');
	super.Activate();
}

function Tick(float DeltaTime)
{
	SetTimer(0.0000001,false,'CheckMyZoom');
}

simulated function ProcessInstantHit( byte FiringMode, ImpactInfo Impact )
{
	local float Scaling;
	local int HeadDamage;

	if( (Role == Role_Authority) && !bUsingAimingHelp )
	{
		if (Instigator == None || VSize(Instigator.Velocity) < Instigator.GroundSpeed * Instigator.CrouchedPct)
		{
			Scaling = SlowHeadshotScale;
		}
		else
		{
			Scaling = RunningHeadshotScale;
		}

		HeadDamage = InstantHitDamage[FiringMode]* HeadShotDamageMult;
		if ( (UTPawn(Impact.HitActor) != None && UTPawn(Impact.HitActor).TakeHeadShot(Impact, HeadShotDamageType, HeadDamage, Scaling, Instigator.Controller)) ||
			(UTVehicleBase(Impact.HitActor) != None && UTVehicleBase(Impact.HitActor).TakeHeadShot(Impact, HeadShotDamageType, HeadDamage, Scaling, Instigator.Controller)) )
		{
			SetFlashLocation(Impact.HitLocation);
			return;
		}
	}

	super.ProcessInstantHit( FiringMode, Impact );
}

simulated function DrawWeaponCrosshair( Hud HUD )
{
	local UTPlayerController PC;

	if( bDisplayCrosshair )
	{
		PC = UTPlayerController(Instigator.Controller);
		if ( (PC == None) || PC.bNoCrosshair )
		{
			return;
		}
		super.DrawWeaponCrosshair(HUD);
	}
}

/** Called when zooming starts
 * @param PC - cast of Instigator.Controller for convenience
 */
simulated function StartZoom(UTPlayerController PC)
{
	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');
	SetTimer(0.0000001,false,'CheckMyZoom');
	}
	Super.StartZoom(PC);
}

simulated function EndFire(Byte FireModeNum)
{
	local UTPlayerController PC;

	// Don't bother performing if this is a dedicated server

	if (WorldInfo.NetMode != NM_DedicatedServer)
	{
		PC = UTPlayerController(Instigator.Controller);
		if (PC != None && LocalPlayer(PC.Player) != none && FireModeNum < bZoomedFireMode.Length && bZoomedFireMode[FireModeNum] != 0 )
		{
			if(GetZoomedState() == ZST_NotZoomed && ZoomCount != 0)
			{
				if(bAbortZoom)
				{
					ClearTimer('Gotozoom');
					LeaveZoom();
				}
				else
				{
					bAbortZoom=true;
				}
			}
			if(ZoomLoop != none)
			{
				ZoomLoop.Stop();
				ZoomLoop = none;
			}
		}
	}
	super.EndFire(FireModeNum);
}

/** Called when zooming ends
 * @param PC - cast of Instigator.Controller for convenience
 */
simulated function EndZoom(UTPlayerController PC)
{
	PlaySound(ZoomOutSound, true);
	bAbortZoom = false;
	if (IsTimerActive('Gotozoom'))
	{
		ClearTimer('Gotozoom');
	}
	SetTimer(0.001,false,'LeaveZoom');
	SetTimer(0.0000001,false,'CheckMyZoom');
	Super.EndZoom(PC);
}
simulated function LeaveZoom()
{
	local UTPlayerController PC;

	bAbortZoom = false;
	PC = UTPlayerController(Instigator.Controller);
	if (PC != none)
	{
		PC.EndZoom();
	}
	ZoomCount = 0;

	PlayWeaponAnimation('WeaponZoomOut',0.3);
	PlayArmAnimation('WeaponZoomOut',0.3);
	SetTimer(0.3,false,'RestartCrosshair');

}
simulated function RestartCrosshair()
{
	bDisplayCrosshair = true;
}

simulated function PutDownWeapon()
{
	ClearTimer('GotoZoom');
	ClearTimer('StopZoom');
	LeaveZoom();
	super.PutDownWeapon();
}
simulated function bool DenyClientWeaponSet()
{
	// don't autoswitch while zoomed
	return (GetZoomedState() != ZST_NotZoomed);
}

simulated function HolderEnteredVehicle()
{
	local UTPawn UTP;

	// clear timers and reset anims
	ClearTimer('GotoZoom');
	ClearTimer('StopZoom');
	PlayWeaponAnimation('WeaponZoomOut', 0.3);

	// partially copied from PlayArmAnimation() - we don't want to abort if third person here because they definitely will
	// since they just got in a vehicle
	if (WorldInfo.NetMode != NM_DedicatedServer)
	{
		UTP = UTPawn(Instigator);
		if (UTP != None)
		{
			// Check we have access to mesh and animations
			if (UTP.ArmsMesh[0] != None && ArmsAnimSet != None && GetArmAnimNodeSeq() != None)
			{
				UTP.ArmsMesh[0].PlayAnim('WeaponZoomOut', 0.3, false);
			}
		}
	}
}

simulated function Gotozoom()
{
	local UTPlayerController PC;

	PC = UTPlayerController(Instigator.Controller);
	if (GetZoomedState() == ZST_NotZoomed)
	{
		PC.FOVAngle = 40;
		Super.StartZoom(PC);
		if (bAbortZoom) // stop the zoom after 1 tick
		{
			SetTimer(0.0001, false, 'StopZoom');
		}
		else
		{
			if(ZoomLoop == none)
			{
				ZoomLoop = CreateAudioComponent(ZoomLoopCue, false, true);
			}
			if(ZoomLoop != none)
			{
				ZoomLoop.Play();
			}
		}
	}

}
simulated function PlayWeaponPutDown()
{
	ClearTimer('GotoZoom');
	ClearTimer('StopZoom');
	if(UTPlayerController(Instigator.Controller) != none)
	{
		UTPlayerController(Instigator.Controller).EndZoom();
	}
	super.PlayWeaponPutDown();
}

simulated function StopZoom()
{
	local UTPlayerController PC;

	if (WorldInfo.NetMode != NM_DedicatedServer)
	{
		PC = UTPlayerController(Instigator.Controller);
		if (PC != None && LocalPlayer(PC.Player) != none)
		{
			PC.StopZoom();
		}
	}
}

simulated function vector GetEffectLocation()
{
	// tracer comes from center if zoomed in
	return (GetZoomedState() != ZST_NotZoomed) ? Instigator.Location : Super.GetEffectLocation();
}

simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
{
	if(GetZoomedState() == ZST_NotZoomed)
	{
	if ( FireModeNum < WeaponFireAnim.Length && WeaponFireAnim[FireModeNum] != '' )
		PlayWeaponAnimation( WeaponFireAnim[FireModeNum], GetFireInterval(FireModeNum) );
	if ( FireModeNum < ArmFireAnim.Length && ArmFireAnim[FireModeNum] != '' && ArmsAnimSet != none)
		PlayArmAnimation( ArmFireAnim[FireModeNum], GetFireInterval(FireModeNum) );
	}
	else
	{
	if ( FireModeNum < WeaponFireAnim.Length && WeaponFireAnim[FireModeNum] != '' )
		PlayWeaponAnimation( WeaponFireAnimZoom[FireModeNum], GetFireInterval(FireModeNum) );
	if ( FireModeNum < ArmFireAnim.Length && ArmFireAnim[FireModeNum] != '' && ArmsAnimSet != none)
		PlayArmAnimation( ArmFireAnim[FireModeNum], GetFireInterval(FireModeNum) );
	}

	// Start muzzle flash effect
	CauseMuzzleFlash();

	ShakeView();
}

simulated state Active
{
	simulated event OnAnimEnd(optional AnimNodeSequence SeqNode, optional float PlayedTime, optional float ExcessTime)
	{
		local int IdleIndex;

		if ( WorldInfo.NetMode != NM_DedicatedServer && WeaponIdleAnims.Length > 0 )
		{

	if(GetZoomedState() == ZST_NotZoomed)
	{
			IdleIndex = Rand(WeaponIdleAnims.Length);
			PlayWeaponAnimation(WeaponIdleAnims[IdleIndex], 0.0, true);
			if(ArmIdleAnims.Length > IdleIndex && ArmsAnimSet != none)
			{
				PlayArmAnimation(ArmIdleAnims[IdleIndex], 0.0,, true);
			}
	}
	else
	{
			IdleIndex = Rand(WeaponIdleAnimsZoom.Length);
			PlayWeaponAnimation(WeaponIdleAnimsZoom[IdleIndex], 0.0, true);
			if(ArmIdleAnims.Length > IdleIndex && ArmsAnimSet != none)
			{
				PlayArmAnimation(ArmIdleAnims[IdleIndex], 0.0,, true);
			}
	}
		}
	}
}

simulated function PlayMyZoomIdle()
{
		PlayWeaponAnimation('WeaponZoomIdle',0.0,true);
		PlayArmAnimation('WeaponIdle',0.0,true);
}

defaultproperties
{
	// Weapon SkeletalMesh
	Begin Object class=AnimNodeSequence Name=MeshSequenceA
	End Object

	// Weapon SkeletalMesh
	Begin Object Name=FirstPersonMesh
		SkeletalMesh=SkeletalMesh'DZ_WP_W1866.Mesh.SK_WP_DZ1866_1st'
		AnimSets(0)=AnimSet'DZ_WP_W1866.Anims.AS_WP_DZ1866_1st'
		Animations=MeshSequenceA
		FOV=65.0
	End Object

	AttachmentClass=class'Mod_W1866.UTAttachment_W1866'

	Begin Object Name=PickupMesh
		SkeletalMesh=SkeletalMesh'DZ_WP_W1866.Mesh.SK_WP_DZ1866_3rd'
	End Object

	WeaponFireTypes(0)=EWFT_InstantHit
	InstantHitDamage(0)=35
	InstantHitMomentum(0)=+10.0
	FireInterval(0)=+0.55
	InstantHitDamageTypes(0)=class'Mod_W1866.UTDmgType_44RimFire'
	Spread(0)=5.0
	SpreadScoped=0.0025
	SpreadNoScoped=0.045

	InstantHitDamageTypes(1)=None
	FiringStatesArray(1)=Active
	FireInterval(1)=+0.55

	WeaponFireSnd[0]=SoundCue'A_Weapon_Sniper.Sniper.A_Weapon_Sniper_Fire_Cue'
	WeaponEquipSnd=SoundCue'A_Weapon_Sniper.Sniper.A_Weapon_Sniper_Raise_Cue'
	WeaponPutDownSnd=SoundCue'A_Weapon_Sniper.Sniper.A_Weapon_Sniper_Lower_Cue'
	ZoomOutSound=None
	ZoomInSound=None
	ZoomLoopCue=None

	WeaponFireAnimZoom(0)=WeaponZoomFire
	WeaponIdleAnimsZoom(0)=WeaponZoomIdle

	PickupSound=SoundCue'A_Pickups.Weapons.Cue.A_Pickup_Weapons_Sniper_Cue'
	PickupMessage="Winchester 1866"
	ItemName="Winchester 1866"

	MaxDesireability=0.65
	AIRating=0.65
	CurrentRating=0.65
	bInstantHit=true
	bSplashJump=false
	bRecommendSplashDamage=false
	bSniping=true
	ShouldFireOnRelease(0)=0
	ShouldFireOnRelease(1)=0

	FireOffset=(X=0,Y=0)
	PlayerViewOffset=(X=0.0,Y=0.0,Z=0.0)

	/** AmmoCount=13 */
	/** LockerAmmoCount=26 */
	/** MaxAmmoCount=52 */

	AmmoCount=26
	LockerAmmoCount=26
	MaxAmmoCount=52

	MuzzleFlashSocket=MuzzleFlashSocket
	MuzzleFlashPSCTemplate=ParticleSystem'DZ_WP_W1866.Effects.P_WP_W1866_MuzzleFlash'
	MuzzleFlashDuration=0.3
	MuzzleFlashLightClass=class'UTGame.UTRocketMuzzleFlashLight'

	LockerRotation=(Pitch=32768,Roll=16384)

	IconCoordinates=(U=728,V=382,UL=162,VL=45)

	QuickPickGroup=2
	QuickPickWeight=0.85

	WeaponColor=(R=160,G=0,B=255,A=255)

	InventoryGroup=2
	GroupWeight=0.4

	IconX=400
	IconY=129
	IconWidth=22
	IconHeight=48

	HeadShotDamageType=class'Mod_W1866.UTDmgType_44RimFireHeadshot'
	HeadShotDamageMult=3.0
	SlowHeadshotScale=1.3
	RunningHeadshotScale=0.9

	// Configure the zoom

	bZoomedFireMode(0)=0
	bZoomedFireMode(1)=1

	ZoomedTargetFOV=50.0
	ZoomedRate=30.0

	bDisplaycrosshair = true;

	CrosshairImage=Texture2D'DZ_WP_W1866.Textures.t_xhair_w1866'
	CrossHairCoordinates=(U=0,V=0,UL=128,VL=128)

	JumpDamping=0.2
	MaxPitchLag=100
	MaxYawLag=150
	MaxPitchLagZoom=40
	MaxYawLagZoom=50

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

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

DazJW

Member
Mar 25, 2008
91
0
6
That's about variables in .ini files.

I've read the networking overview on UDN Three and as far as I can tell the code I have is correct (as evidenced by the fact it uses SpreadNoScoped and ignores Spread).

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.
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
I have to admit that at this point I'm lost since I have nothing handy to refer to (this machine can't handle UT3). If you could post an attached zip with the code of UTWeapon and whatever weapon you're basing this on, that would be useful. I don't have much time but I'll try and help as I can.

P.S: The fact that you're not able to redefine replication may be due to inheritance. I don't know if it's possible to override the replication block.
 
Last edited:

DazJW

Member
Mar 25, 2008
91
0
6
Here's a zip with my weapon (W1866), the Enforcer code (that uses AddSpread), the Sniper Rifle code (which uses the zoom check I use) and the relevant chain of extends above them.

Yeah me not being able to redefine the replication on the functions is down to inheritance.
 

Attachments

  • WinchesterAndRelevants.zip
    52.8 KB · Views: 3

DazJW

Member
Mar 25, 2008
91
0
6
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:
Code:
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.
 
Last edited:

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Try hardcoding the values instead of using defaults.
 

DazJW

Member
Mar 25, 2008
91
0
6
I've tried that and it didn't work.
I got someone to watch the server output and it's only logging NoScoped when I spawn, so as far as it's concerned CheckMyZoom isn't running at all over than on activate.
 

DazJW

Member
Mar 25, 2008
91
0
6
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:
Code:
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.
 

DannyMeister

UT3 Jailbreak Coder
Dec 11, 2002
1,275
1
38
40
Bolivar, Missouri
If the server logs nothing, then that means it is only getting executed client side. This is probably because for the sniper rifle which you took this code from, zooming changes nothing that matters to anyone but the client. You could try creating a new server side function called ServerStartZoom() and call it if you are the client. See StartFire() and ServerStartFire() in Weapon.uc as an example.

That gets you started in the right direction. You could still have trouble if any of the variables you change in your server-side function are needed client-side but aren't replicated. You can just add them to the replication block if they are your own variables. If they are variables defined in your superclass (as is the case for Spread) then you either need to make things work when the client does not need to know the value, or create a new variable e.g. MySpread and rewrite your client-side functions to use it.
 
Last edited:

DazJW

Member
Mar 25, 2008
91
0
6
Sorted.
Thanks a lot for pointing me to those two functions, I've used them to make a server zoom function and it's working perfectly now.
Cheers.
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
If the server logs nothing, then that means it is only getting executed client side.

I figured something like that was happening but don't have any experience with UE3. Yes, some functions only work clientside as it's only relevant to the player. It's a good idea to make sure these functions can't be messed around too much if they do anything special. This can be done either by interacting with the server every now and then or locking values in some way. As there's some interaction with the server, there shouldn't be too much of a problem if someone finds a way of changing zoom or other things.

P.S: Spread = FOV ?
 

Zur

surrealistic mad cow
Jul 8, 2002
11,708
8
38
48
Oh, it's been made into a variable. I'm definitely going to check that out just to see how it works. In UE1 it's usually just a series of calculations specific to each weapon.