Projectile speed replication

Discussions about Coding and Scripting
Post Reply
User avatar
Barbie
Godlike
Posts: 2792
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Projectile speed replication

Post by Barbie »

Short description: a given value in server's INI file should be transferred to clients.

Long description: For some reasons I want to change the speed of a projectile by an INI file located at the server. For example for the RocketLauncher: I subclassed the default projectile ("SBRocketMk2"), added a new variable "ProjectileSpeed" that should be replicated and assign the value of "ProjectileSpeed" to the variable "Speed" in PostBeginPlay():

Code: Select all

class SBRocketMk2 expands RocketMk2 config(SBRocketMk2);

var config float ProjectileSpeed;

replication {
	reliable if (Role == ROLE_Authority)
		ProjectileSpeed;
}

simulated function logger(string msg) {
	Log(msg);
	broadcastmessage(msg);
}


simulated function PostNetBeginPlay() {
	Logger(self $ ".PostNetBeginPlay: Speed=" $ Speed);
	super.PostNetBeginPlay();
}


simulated function PostBeginPlay() {
	Logger(self $ ".PostBeginPlay starting with SmokeRate=" $ SmokeRate $ ", ProjectileSpeed=" $ ProjectileSpeed  $ ", Speed=" $ Speed);
	Speed = ProjectileSpeed;
	Super.PostBeginPlay();
	logger(self $ ".PostBeginPlay finished with SmokeRate=" $ SmokeRate $ ", ProjectileSpeed=" $ ProjectileSpeed  $ ", Speed=" $ Speed);
}


defaultproperties {
	ProjectileSpeed=20
}
Because the new projectile has to be used, I subclassed the weapon also ("SBEightball") and set the ProjectileClass there. (Unfortunately the default ProjectileClass ("Class'RocketMk2'") is also used in the code, so I have to substitute it there.)
SBEightball

Code: Select all

class SBEightball expands UT_Eightball;


state FireRockets {

	function BeginState() // complete copy of parent except line 87 where class'rocketmk2' is spawned
	{
		local vector FireLocation, StartLoc, X,Y,Z;
		local rotator FireRot, RandRot;
		local rocketmk2 r;
		local UT_SeekingRocket s;
		local ut_grenade g;
		local float Angle, RocketRad;
		local pawn BestTarget, PawnOwner;
		local PlayerPawn PlayerOwner;
		local int DupRockets;
		local bool bMultiRockets;

		PawnOwner = Pawn(Owner);
		if ( PawnOwner == None )
			return;
		PawnOwner.PlayRecoil(FiringSpeed);
		PlayerOwner = PlayerPawn(Owner);
		Angle = 0;
		DupRockets = RocketsLoaded - 1;
		if (DupRockets < 0) DupRockets = 0;
		if ( PlayerOwner == None )
			bTightWad = ( FRand() * 4 < PawnOwner.skill );

		GetAxes(PawnOwner.ViewRotation,X,Y,Z);
		StartLoc = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;

		if ( bFireLoad )
			AdjustedAim = PawnOwner.AdjustAim(ProjectileSpeed, StartLoc, AimError, True, bWarnTarget);
		else
			AdjustedAim = PawnOwner.AdjustToss(AltProjectileSpeed, StartLoc, AimError, True, bAltWarnTarget);

		if ( PlayerOwner != None )
			AdjustedAim = PawnOwner.ViewRotation;

		PlayRFiring(RocketsLoaded-1);
		Owner.MakeNoise(PawnOwner.SoundDampening);
		if ( !bFireLoad )
		{
			LockedTarget = None;
			bLockedOn = false;
		}
		else if ( LockedTarget != None )
		{
			BestTarget = Pawn(CheckTarget());
			if ( (LockedTarget!=None) && (LockedTarget != BestTarget) )
			{
				LockedTarget = None;
				bLockedOn=False;
			}
		}
		else
			BestTarget = None;
		bPendingLock = false;
		bPointing = true;
		FireRot = AdjustedAim;
		RocketRad = 4;
		if (bTightWad || !bFireLoad) RocketRad=7;
		bMultiRockets = ( RocketsLoaded > 1 );
		While ( RocketsLoaded > 0 )
		{
			if ( bMultiRockets )
				Firelocation = StartLoc - (Sin(Angle)*RocketRad - 7.5)*Y + (Cos(Angle)*RocketRad - 7)*Z - X * 4 * FRand();
			else
				FireLocation = StartLoc;
			if (bFireLoad)
			{
				if ( Angle > 0 )
				{
					if ( Angle < 3 && !bTightWad)
						FireRot.Yaw = AdjustedAim.Yaw - Angle * 600;
					else if ( Angle > 3.5 && !bTightWad)
						FireRot.Yaw = AdjustedAim.Yaw + (Angle - 3)  * 600;
					else
						FireRot.Yaw = AdjustedAim.Yaw;
				}
				if ( LockedTarget != None )
				{
					s = Spawn( class 'ut_SeekingRocket',, '', FireLocation,FireRot);
					s.Seeking = LockedTarget;
					s.NumExtraRockets = DupRockets;
					if ( Angle > 0 )
						s.Velocity *= (0.9 + 0.2 * FRand());
				}
				else
				{
					//r = Spawn( class'rocketmk2',, '', FireLocation,FireRot);
					r = RocketMK2(Spawn(ProjectileClass,, '', FireLocation,FireRot));

					r.NumExtraRockets = DupRockets;
					if (RocketsLoaded>4 && bTightWad) r.bRing=True;
					if ( Angle > 0 )
						r.Velocity *= (0.9 + 0.2 * FRand());
				}
			}
			else
			{
				g = Spawn( class 'ut_Grenade',, '', FireLocation,AdjustedAim);
				g.NumExtraGrenades = DupRockets;
				if ( DupRockets > 0 )
				{
					RandRot.Pitch = FRand() * 1500 - 750;
					RandRot.Yaw = FRand() * 1500 - 750;
					RandRot.Roll = FRand() * 1500 - 750;
					g.Velocity = g.Velocity >> RandRot;
				}
			}

			Angle += 1.0484; //2*3.1415/6;
			RocketsLoaded--;
		}
		bTightWad=False;
		bRotated = false;
	}

	function AnimEnd()
	{
		if ( !bRotated && (AmmoType.AmmoAmount > 0) )
		{
			PlayLoading(1.5,0);
			RocketsLoaded = 1;
			bRotated = true;
			return;
		}
		LockedTarget = None;
		Finish();
	}


}


defaultproperties {
	ItemName="Enhanced Rocket Launcher"
	PickupMessage="You got the Enhanced Rocket Launcher."
	ProjectileClass=class'SBRocketMk2'
}
For testing I set the ProjectileSpeed quite high:
SBRocketMk2.ini wrote:[SBEightballV1.SBRocketMk2]
ProjectileSpeed=5000.000000
Running the testmap locally all things work, but playing with client/server and INI file on server only, the client logs
UnrealTournament.ini wrote:ScriptLog: TestProjectileSpeed.SBRocketMk0.PostBeginPlay starting with SmokeRate=0.000000, ProjectileSpeed=20.000000, Speed=900.000000
ScriptLog: TestProjectileSpeed.SBRocketMk0.PostBeginPlay finished with SmokeRate=10.000000, ProjectileSpeed=20.000000, Speed=20.000000
ScriptLog: TestProjectileSpeed.SBRocketMk0.PostNetBeginPlay: Speed=20.000000
Warning: New actor channel received non-open packet: 0/1/1
So "ProjectileSpeed" is not replicated?
Attachments
SBEightball.7z
Project files of "SBEightball"
(6.7 KiB) Downloaded 37 times
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
sektor2111
Godlike
Posts: 6403
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: Projectile speed replication

Post by sektor2111 »

You lost me here. If this projectile has a "defaultproperty" with your desired value, client should know a "defaultproperty" of a certain class if package is being sent to client as it knows other stock things. If that property is changed/changeable via INI... umm... nwm, I'm not going to roam client again - ACE won't love what I do...
User avatar
Feralidragon
Godlike
Posts: 5489
Joined: Wed Feb 27, 2008 6:24 pm
Personal rank: Work In Progress
Location: Liandri

Re: Projectile speed replication

Post by Feralidragon »

It's been a looooong while since I looked at anything concerning projectiles, but I am pretty sure that by the time you call PostBeginPlay, you still don't have any initial values replicated/processed from the server, and that's why you have PostNetBeginPlay, which is only called after the first batch of replicated properties, and that's where you should set the speed in order for it to work online.

In later engine iterations, namely UE3, Epic realized how stupid it was to have 2 different events like this, so they just moved PostBeginPlay to be called later, at PostNetBeginPlay time, and removed the latter.
User avatar
TheDane
Masterful
Posts: 660
Joined: Tue Feb 12, 2008 2:47 pm
Personal rank: Happy fool :-)

Re: Projectile speed replication

Post by TheDane »

You can set it dynamicly through the game with a mutator doing a:

Code: Select all

var config float ConfigurableVariable;

function bool AlwaysKeep(Actor Other)
{
	if (Other.IsA('SBRocketMk2'))
        {
		SBRocketMk2(Other).ProjectileSpeed = ConfigurableVariable;
		return true;
		}
	
	if ( NextMutator != None )
		return ( NextMutator.AlwaysKeep(Other) );
	return false;
}
You can build the above script into any mutator you have running, or ofcause make it as stand-alone. If you use it as stand-alone be sure not to break the chain in the functions (call super and such).
Retired.
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: Projectile speed replication

Post by Higor »

PostBeginPlay your replicated vars haven't been set.

PostNetBeginPlay projectile physics has already been initialized by PostBeginPlay.

Solution?
Reinitialize projectile physics in PostNetBeginPlay.
User avatar
Que
Inhuman
Posts: 781
Joined: Mon Dec 09, 2019 5:49 am
Personal rank: ...
Contact:

Re: Projectile speed replication

Post by Que »

bumping this thread as iam interested where you got with increasing the rocketlauncher projectile speed @barbie.. could you release a mod just for rocketlauncher with adjustable projectile speeds through .ini?
*Join our Discord Here.*
Our mods - MVX , SSB , SmartWFL , UTCmds , BotCommands , Smart Stats , join/leave announcer , NoSmoke , UTLogin , BrightSkins , Server Tran…
*Our Servers
User avatar
Barbie
Godlike
Posts: 2792
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: Projectile speed replication

Post by Barbie »

Whow, it took me half an hour to re-understand this project... :lol2:
Yes, such a mutator should be doable. I will also make "lifespan" configurable, because the range of the projectile results of

Code: Select all

range = lifespan * speed
As soon as I have results, I'll post it here.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
Post Reply