View Full Version : Requesting help: Weapon mod only works on host computer
Norseman
08-30-2006, 06:24 PM
I created a flak cannon with an Alt fire zoom and an automatic choke that tightens the flak pattern proportional to the change in FOV. It works great in single player and on the host computer in a multi-player game, but doesn't work when I log onto the dedicated server. All computers have the package installed and the package is listed under server pacakges in the UT2004 file in the system folder. The pattern remains as the default and doesn't adjust with the zoom. I have had the same problem with other parameters as well with my other mods. The information doesn't seem to pass between the server and computers logged in.
I'm sure it has something to do with replication, but unfortunately, I am quite clueless when it comes to this subject. Any help would be appreciated. The modified code is below with the variables and defaults, and is a subclass of FlakFire. I changed the variables from locals to globals, but that doesn't seem to help. The DoFireEffect function is taken from XWeapons.ProjectileFire.
Thanks
////////////////////////////
var int flak;
var Vector StartProj, StartTrace, X,Y,Z;
var Rotator R, Aim;
var Vector HitLocation, HitNormal;
var Actor Other;
var int p, SpawnCount;
function DoFireEffect()
{
Instigator.MakeNoise(1.0);
Weapon.GetViewAxes(X,Y,Z);
Spread = 18.00000 * PlayerController(Instigator.Controller).DesiredFOV ;
StartTrace = Instigator.Location + Instigator.EyePosition();// + X*Instigator.CollisionRadius;
StartProj = StartTrace + X*ProjSpawnOffset.X;
if ( !Weapon.WeaponCentered() )
StartProj = StartProj + Weapon.Hand * Y*ProjSpawnOffset.Y + Z*ProjSpawnOffset.Z;
// check if projectile would spawn through a wall and adjust start location accordingly
Other = Weapon.Trace(HitLocation, HitNormal, StartProj, StartTrace, false);
if (Other != None)
{
StartProj = HitLocation;
}
Aim = AdjustAim(StartProj, AimError);
SpawnCount = flak;
X = Vector(Aim);
for (p = 0; p < SpawnCount; p++)
{
R.Yaw = Spread * (FRand()-0.5);
R.Pitch = Spread * (FRand()-0.5);
R.Roll = Spread * (FRand()-0.5);
SpawnProjectile(StartProj, Rotator(X >> R));
}//for p
}
defaultproperties
{
Spread=1600.000000
flak=16
}
Norseman
08-30-2006, 08:52 PM
I read through the Wiki tutorials on replication so I think I have a better understanding of the concepts now. The details are still beyond me though. It seems that I have to declare my variables in a replication statement, but I'm not really sure which Role Authority to assign each one, and which ones should be reliable. I'm also not sure if I need to replicate certain functions as well. If I have to change the role of an existing function, do I need to rename the function? Any hints would be appreciated.
Thanks.
Jrubzjeknf
08-31-2006, 05:03 AM
Please use [code][./code] (minus the .) tags.
-Chris-
08-31-2006, 07:07 AM
How are you going about putting this onto the server, e.g is it a mutator or what? Because depending on what it is you may have a problem with your "extends". E.g. a mutator extends the mutator class, you may have the wrong class.
e.g
class newflak extends mutator
if that helps at all?
Jrubzjeknf
08-31-2006, 10:37 AM
His class is good, he just needs to load his weapon ingame. For that, he can use a custom map.
Norseman
08-31-2006, 06:27 PM
The weapon itself is a subclass of the Flak Cannon, and uses the XWeapons.SniperZoom for Alt fire. I have been using a replacement mutator to replace the Flak Cannon with the new weapon in the game. Could the mutator be part of the problem?
ProjectUT
08-31-2006, 07:36 PM
Try adding
bAlwaysRelevant=true
RemoteRole=ROLE_SimulatedProxy
bNetTemporary=true
bAddToServerPackages=true
To your mutator default properties. I had to add this to mine to get my custom weapon to work online.
porkmanii
08-31-2006, 11:25 PM
I created a flak cannon with an Alt fire zoom and an automatic choke that tightens the flak pattern proportional to the change in FOV. It works great in single player and on the host computer in a multi-player game, but doesn't work when I log onto the dedicated server.
The problem is...
Spread = 18.00000 * PlayerController(Instigator.Controller).DesiredFOV ;
DesiredFOV is not replicated. This means when the value changes on the client (i.e. you zoom in), it does not change on the server. The server has no way of determining your FOV angle.
What you need to do is replicate the player's DesiredFOV to the server. You can't change the replication for PlayerController.DesiredFOV, so you'll have to "copy" it to another variable and replicate it using another class (your Weapon class, for example.) WeaponFire classes have no concept of replication, as they are not sub-classes of Actor.
I read through the Wiki tutorials on replication so I think I have a better understanding of the concepts now. The details are still beyond me though. It seems that I have to declare my variables in a replication statement, but I'm not really sure which Role Authority to assign each one, and which ones should be reliable. I'm also not sure if I need to replicate certain functions as well. If I have to change the role of an existing function, do I need to rename the function? Any hints would be appreciated.
Think of a replication statement as a statement of when a variable or function call should be replicated. Role is a variable declared in Actor, not something assigned to each variable/function (in code, at least; you could say each variable/function has a Role, conceptually). For example:
var float PlayerFOV;
replication
{
reliable if (Role < ROLE_Authority)
PlayerFOV;
}
For a Weapon spawned by the server, this is saying to replicate PlayerFOV from the client to the server. Role equals ROLE_Authority on the server, and for Weapons, RemoteRole equals ROLE_DumbProxy on the server. (Meaning Role equals ROLE_DumbProxy on the client.) So Role < Role_Authority equals true on the client, and false on the server.
This page has a good explanation of what a Role is:
http://wiki.beyondunreal.com/wiki/Role
I could try to explain it myself, but that page is where I learnt from, so you'd best hear it from the source. :)
This page has some information about the difference between reliable and unreliable:
http://wiki.beyondunreal.com/wiki/Replication_Block
Norseman
09-02-2006, 03:55 PM
Thanks to all for helping out on this one. After a lot of trial and error, I finally got the auto choke to work in multiplayer. I'm including the code I used for anyone who may have similar replication issues.
I ended up using WeaponTick to call on one of the functions, and I am wondering if there is another function I can use, or condition I can set so that FlakChoke is not continuously being called. I tried a couple different ones, but then the choke didn't work at all.
Thanks.
Weapon:
class ZoomFlak extends FlakCannon
config(user);
var float sprd, pfov;
replication
{
reliable if( Role<ROLE_Authority )
sprd, pfov, SpreadOut;
unreliable if(Role == ROLE_Authority)
FlakChoke;
}
simulated function SpreadOut(float S)
{
sprd = 18.000*S;
}//SpreadOut
simulated function FlakChoke()
{
pfov=PlayerController(Instigator.Controller).Desir edFOV;
SpreadOut(pfov);
}//FlakChoke
//Starts Zoom in Alt Fire
simulated function ClientStartFire(int mode)
{
if (mode == 1)
{
FireMode[mode].bIsFiring = true;
if( Instigator.Controller.IsA( 'PlayerController' ) )
PlayerController(Instigator.Controller).ToggleZoom ();
}
else
{
Super.ClientStartFire(mode);
}
}
//Stops Zoom
simulated function ClientStopFire(int mode)
{
if (mode == 1)
{
FireMode[mode].bIsFiring = false;
if( PlayerController(Instigator.Controller) != None )
PlayerController(Instigator.Controller).StopZoom() ;
}
else
{
Super.ClientStopFire(mode);
}
}
function WeaponTick(float dt)
{
if(Instigator.IsHumanControlled())
FlakChoke();
}//WeaponTick
defaultproperties
{
FireModeClass(0)=Class'ZF.ZFlakFire'
FireModeClass(1)=Class'XWeapons.SniperZoom'
Description="This modified Flak Cannon has a 10X zoom and an automatic choke that tightens the flak pattern when zooming, making this an effective weapon in close quarters combat and at longer ranges."
PickupClass=Class'ZF.ZoomFlakPickup'
ItemName="Zoom Flak Cannon"
sprd=1600
}
Weapon Fire:
class ZFlakFire extends FlakFire;
function DoFireEffect()
{
local Vector StartProj, StartTrace, X,Y,Z;
local Rotator R, Aim;
local Vector HitLocation, HitNormal;
local Actor Other;
local int p;
local int SpawnCount;
Instigator.MakeNoise(1.0);
Weapon.GetViewAxes(X,Y,Z);
StartTrace = Instigator.Location + Instigator.EyePosition();// + X*Instigator.CollisionRadius;
StartProj = StartTrace + X*ProjSpawnOffset.X;
if ( !Weapon.WeaponCentered() )
StartProj = StartProj + Weapon.Hand * Y*ProjSpawnOffset.Y + Z*ProjSpawnOffset.Z;
// check if projectile would spawn through a wall and adjust start location accordingly
Other = Weapon.Trace(HitLocation, HitNormal, StartProj, StartTrace, false);
if (Other != None)
{
StartProj = HitLocation;
}
Spread=ZoomFlak(Instigator.Weapon).sprd;
Aim = AdjustAim(StartProj, AimError);
SpawnCount = Max(1, ProjPerFire * int(Load));
X = Vector(Aim);
for (p = 0; p < SpawnCount; p++)
{
R.Yaw = Spread * (FRand()-0.5);
R.Pitch = Spread * (FRand()-0.5);
R.Roll = Spread * (FRand()-0.5);
SpawnProjectile(StartProj, Rotator(X >> R));
}
}
defaultproperties
{
ProjPerFire=16
}
Also, the other thing I added, but didn't include here was a faster flak projectile since standard flak takes a long time to get downrange with long range shots.
porkmanii
09-04-2006, 02:35 AM
As FlakChoke() is called each tick, I suggest it be called by the client, rather than replicated. WeaponTick() should execute on the client if it is marked as simulated. You may also need to check that the PlayerController is locally controlled (if not locally controlled, DesiredFOV won't be relevant). For example:
simulated function WeaponTick(float dt)
{
if (Instigator.IsHumanControlled() && Instigator.IsLocallyControlled())
FlakChoke();
}//WeaponTick
This removes the need for FlakChoke to be replicated.
I see pfov is passed as a parameter of SpreadOut()... SpreadOut is replicated, so I'd say pfov does not need to be. Also, SpreadOut is executed on the server, so why does sprd also need to be replicated?
What I think may be more efficient is this:
- if human- and locally controlled, the client calls FlakChoke
- FlakChoke calculates sprd
- sprd is then replicated
simulated function FlakChoke()
{
sprd = 18.0 * PlayerController(Instigator.Controller).DesiredFOV ;
}//FlakChoke
sprd should already be replicating to the server. This removes the need for pfov and SpreadOut.
My 2 cents.
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.