For direct access use https://forums.oldunreal.com
It's been quite a while since oldunreal had an overhaul, but we are moving to another server which require some updates and changes. The biggest change is the migration of our old reliable YaBB forum to phpBB. This system expects you to login with your username and old password known from YaBB.
If you experience any problems there is also the usual "password forgotten" function. Don't forget to clear your browser cache!
If you have any further concerns feel free to contact me: Smirftsch@oldunreal.com

changing the speed of projectiles through mutator

The section related to UnrealScript and modding. This board is for coders to discuss and exchange experiences or ask questions.
Post Reply
User avatar
Shivaxi
OldUnreal Member
Posts: 2232
Joined: Wed Mar 08, 2006 4:43 pm

changing the speed of projectiles through mutator

Post by Shivaxi »

So I've tried a few methods already, in mutator, in spawnnotify, bleeder was helping me a little but we couldn't get replication working right online:

Code: Select all

//=============================================================================
// mprojtest.
//=============================================================================
class mprojtest expands SpawnNotify;

var vector ROffset;
var BruteProjectile bp;

Replication
{
    Reliable if(Role==ROLE_Authority) ROffset, bp;
}

Simulated Function PostBeginPlay()
{
local actor A;

ActorClass=Class'Actor';

Super.PostBeginPlay();

    if( Level.NetMode != NM_DedicatedServer )
        Enable('Tick');

//      SetTimer(0.1,false);

foreach allactors(Class'Actor',A)
      {
      if(Mercenary(A)!=None)
            {
            Mercenary(A).ProjectileSpeed=Mercenary(A).ProjectileSpeed*1.5;
            }

      if(Brute(A)!=None)
            {
            Brute(A).ProjectileSpeed=Brute(A).ProjectileSpeed*1.5;
            }

      if(Krall(A)!=None)
            {
            Krall(A).ProjectileSpeed=Krall(A).ProjectileSpeed*2;
            }

      if(Titan(A)!=None)
            {
            Titan(A).ProjectileSpeed=Titan(A).ProjectileSpeed*2;
            }
      }
}


simulated event Actor SpawnNotification(Actor A)
{

      if(Rocket(A)!=None)
            {
            Rocket(A).Velocity=Rocket(A).Velocity*2;
            }

      if(Chunk(A)!=None)
            {
            Chunk(A).SetPhysics(PHYS_Falling);
            }

      if(StingerProjectile(A)!=None)
            {
            StingerProjectile(A).Velocity=StingerProjectile(A).Velocity*3;
            StingerProjectile(A).SetPhysics(PHYS_Falling);
            }

      if(TentacleProjectile(A)!=None)
            {
            //TentacleProjectile(A).Speed=100;
            //TentacleProjectile(A).MaxSpeed=100;
            TentacleProjectile(A).Velocity=TentacleProjectile(A).Velocity*4;
            TentacleProjectile(A).Velocity.Z=TentacleProjectile(A).Velocity.Z+=350;
            TentacleProjectile(A).SetPhysics(PHYS_Falling);
            }

      if(Mercenary(A)!=None)
            {
            Mercenary(A).ProjectileSpeed=Mercenary(A).ProjectileSpeed*1.5;
            }

      if(Brute(A)!=None)
            {
            Brute(A).ProjectileSpeed=Brute(A).ProjectileSpeed*1.5;
            }

      if(BruteProjectile(A)!=None)
            {
            BruteProjectile(A).MaxSpeed=BruteProjectile(A).MaxSpeed*1.5;
            }

      if(SlithProjectile(A)!=None)
            {
            //TentacleProjectile(A).Speed=100;
            //TentacleProjectile(A).MaxSpeed=100;
            SlithProjectile(A).Velocity=SlithProjectile(A).Velocity*2;
            SlithProjectile(A).Velocity.Z=SlithProjectile(A).Velocity.Z+=150;
            SlithProjectile(A).SetPhysics(PHYS_Falling);
            }

      if(Krall(A)!=None)
            {
            Krall(A).ProjectileSpeed=Krall(A).ProjectileSpeed*2;
            }

      if(KraalBolt(A)!=None)
            {
            KraalBolt(A).MaxSpeed=KraalBolt(A).MaxSpeed*2;
            }

      if(Titan(A)!=None)
            {
            Titan(A).ProjectileSpeed=Titan(A).ProjectileSpeed*2;
            }

      if(BigRock(A)!=None)
            {
            BigRock(A).Velocity=BigRock(A).Velocity*1.5;
            BigRock(A).Velocity.Z=BigRock(A).Velocity.Z+=200;
            SetTimer(0.1,False,'RockFall');
            }

      return A;
}

function tick(float delta)
{
    local actor a;
    
    if(Level.NetMode!=NM_Client) ROffset=1000*VRand();
      if(!bool(ROffset)) return;
    ROffset.X=int(ROffset.X);
    ROffset.Y=int(ROffset.Y);
    ROffset.Z=int(ROffset.Z);
    
    foreach allactors(Class'Actor',A)
        {
        if(bp!=None) bp.Acceleration=ROffset;
        if(Rocket(A)!=None) Rocket(A).Acceleration=ROffset;
        }

    ROffset=vect(0,0,0);
}

/*simulated function tick(float delta)
{
      local actor a;

      foreach allactors(Class'Actor',A)
            {
            if(BruteProjectile(A)!=None)
                  {
                  BruteProjectile(A).Acceleration.X=Randrange(1000,-1000);
                  BruteProjectile(A).Acceleration.Y=Randrange(1000,-1000);
                  BruteProjectile(A).Acceleration.Z=Randrange(1000,-1000);
                  }

            if(Rocket(A)!=None)
                  {
                  Rocket(A).Acceleration.X=Randrange(1000,-1000);
                  Rocket(A).Acceleration.Y=Randrange(1000,-1000);
                  Rocket(A).Acceleration.Z=Randrange(1000,-1000);
                  }
            }
}*/

simulated function RockFall()
{
      local actor a;

      foreach allactors(Class'Actor',A)
            {
            if(BigRock(A)!=None)
                  {
                  BigRock(A).SetPhysics(PHYS_Falling);
                  }
            }
}
This is what I have so far.  Ignore tick for now, was testing something with rockets having a variation to their flight to give randomness to flight pattern, though doesn't work online at all lol.  and function rockfall is my attempt to get rocks thrown by Titan's to Physics Falling, which doesn't work either for some reason, Titan's have a habbit of throwing both BigRock and Boulder1, one of them will fall and the other will not.

Now anything that gets set as PHYS_Falling works just fine, I can then adjust velocity, and no problem there.  The trouble is other projectiles that are still PHYS_Projectile don't replicate online.  It works perfectly in single player, but online the projectiles still look slow on your client, but end up hitting you well before they visually reach you, since server side the projectile changes are working.

If there's a better way to go about this or to get replication for this working online, would appreciate the help. My goal is to try and do this without having to make custom projectile classes for everything I want to change.
Last edited by Shivaxi on Wed Aug 14, 2019 7:31 pm, edited 1 time in total.
Image  Image
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: changing the speed of projectiles through mutator

Post by Masterkent »

Code: Select all

class ProjBooster expands Mutator;

event BeginPlay()
{
      Spawn(class'ProjBoosterSpawnNotify');
      AddToPackagesMap(string(Class.Outer.Name));
}

function bool IsRelevant(Actor A, out byte bSuperRelevant)
{
      if (ScriptedPawn(A) != none)
            ScriptedPawn(A).ProjectileSpeed *= 3;
      return true;
}

Code: Select all

class ProjBoosterSpawnNotify expands SpawnNotify;

simulated event Actor SpawnNotification(Actor A)
{
      Projectile(A).MaxSpeed *= 3;
      return A;
}

defaultproperties
{
      ActorClass=class'Projectile'
      bHidden=True
      RemoteRole=ROLE_SimulatedProxy
}
User avatar
Shivaxi
OldUnreal Member
Posts: 2232
Joined: Wed Mar 08, 2006 4:43 pm

Re: changing the speed of projectiles through mutator

Post by Shivaxi »

Worked wonders, thanks!

Out of curiosity, it doesn't seem to work for Players though?  Just monsters.  I tried adding:

Projectile(A).Speed *= 3;

To the spawn notify as well but player projectiles were still slow/normal.  I can even do in game "admin set projectile speed 99999" and that'll work online haha.

EDIT: huh, doing Projectile(A).Velocity *= 3; actually works
Last edited by Shivaxi on Thu Aug 15, 2019 8:40 pm, edited 1 time in total.
Image  Image
User avatar
Shivaxi
OldUnreal Member
Posts: 2232
Joined: Wed Mar 08, 2006 4:43 pm

Re: changing the speed of projectiles through mutator

Post by Shivaxi »

onto the randomized rocket flight idea:

Code: Select all

simulated function woowee()
{
local actor a;

      foreach allactors(Class'Actor',A)
            {
            if(Rocket(A)!=None)
                  {
                  Rocket(A).Acceleration.X=Randrange(1000,-1000);
                  Rocket(A).Acceleration.Y=Randrange(1000,-1000);
                  Rocket(A).Acceleration.Z=Randrange(1000,-1000);
                  }
            }
      SetTimer(0.1,True,'woowee');
}
This obviously doesn't replicate in the least online lol, but I wouldn't know where to begin. Bleeder had a stab at it but we could never getting working right, would only tick once online and send the rocket in one direction only.
Image  Image
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: changing the speed of projectiles through mutator

Post by Masterkent »

Out of curiosity, it doesn't seem to work for Players though?  Just monsters.
That code sample works only for ScriptedPawns.
I tried adding:

Projectile(A).Speed *= 3;

To the spawn notify as well but player projectiles were still slow/normal.
Projectile's Speed is used to calculate the initial Velocity. Most projectiles perform such a calculation in BeginState() of their initial state. Since the initial state is entered prior to calling the SpawnNotify handler (see https://wiki.beyondunreal.com/What_happ ... is_spawned), it's too late to modify projectile's Speed in SpawnNotification. If you want to alter Velocity after it was evaluated from Speed, you have to modify Velocity directly.
onto the randomized rocket flight idea:

Code: Select all

simulated function woowee()
{
local actor a;

      foreach allactors(Class'Actor',A)
            {
            if(Rocket(A)!=None)
                  {
                  Rocket(A).Acceleration.X=Randrange(1000,-1000);
                  Rocket(A).Acceleration.Y=Randrange(1000,-1000);
                  Rocket(A).Acceleration.Z=Randrange(1000,-1000);
                  }
            }
      SetTimer(0.1,True,'woowee');
}
This obviously doesn't replicate in the least online lol
Acceleration is replicated only for newly spawned actors. And if you call your simulated function woowee on both machines (on the server and the client), then of course you'll get wrong client-side values of Acceleration, because they will be evaluated independently and differently than on the server. Such a tricky movement requires a rather non-trivial algorithm of synchronization if you want to achieve a proper client-side prediction.
User avatar
Shivaxi
OldUnreal Member
Posts: 2232
Joined: Wed Mar 08, 2006 4:43 pm

Re: changing the speed of projectiles through mutator

Post by Shivaxi »

hmm, I remember the drunk missile launcher from U4E does this actually, and it replicates online as well, just tested:

Code: Select all

class DrunkMissile expands WarlordRocket;

var actor seeking;

simulated function PostBeginPlay()
{
      Super.PostBeginPlay();
      seeking=None;
      Velocity = Speed * vector(Rotation);
      SetTimer(0.2,true);
}

simulated function timer()
{
      local spritesmokepuff b;
      local vector x,y,z;
      local float bestDist, bestAim;
      local vector SeekingDir;
      local float MagnitudeVel;

      If (Seeking==None)
      {      
            bestAim = 0.8;//0.93
            seeking = instigator.PickTarget(bestAim, bestDist, Normal(Velocity), Location);
      }
      If (Seeking != None  && Seeking != Instigator) 
      {
            SeekingDir = Normal(Seeking.Location - Location);
      //      if ( (SeekingDir Dot InitialDir) > 0 )
      //      {
                  MagnitudeVel = VSize(Velocity);
                  Velocity =  0.99*MagnitudeVel * Normal(SeekingDir * 0.5 * MagnitudeVel + Velocity);            
                  SetRotation(rotator(Velocity));
      //      }
      }

      GetAxes(rotation,x,y,z);
      x.x+=0.8*(0.5-frand());
      x.y+=0.8*(0.5-frand());
      x.z+=0.8*(0.5-frand());
      SetRotation(rotator(x));
      Velocity = Speed * vector(Rotation);
      b = Spawn(class'spritesmokepuff');
      b.RemoteRole = ROLE_None;            
}
difference being though that this is right in the projectile of the missile, also dumbproxy

EDIT: so apparently

Rocket(A).Acceleration.X=Randrange(1000,-1000);
Rocket(A).Acceleration.Y=Randrange(1000,-1000);
Rocket(A).Acceleration.Z=Randrange(1000,-1000);

will work perfectly and even replicate in a tick function should the rocket be set to dumbproxy and bNetTemporary is False. Unfortunately you can't set bNetTemporary to false on the fly or in a mutator, returns "can't assign const variables", so I may have to make a new projectile afterall.
Last edited by Shivaxi on Sat Aug 17, 2019 7:23 am, edited 1 time in total.
Image  Image
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: changing the speed of projectiles through mutator

Post by Masterkent »

difference being though that this is right in the projectile of the missile, also dumbproxy

EDIT: so apparently

Rocket(A).Acceleration.X=Randrange(1000,-1000);
Rocket(A).Acceleration.Y=Randrange(1000,-1000);
Rocket(A).Acceleration.Z=Randrange(1000,-1000);

will work perfectly and even replicate in a tick function should the rocket be set to dumbproxy and bNetTemporary is False.
ROLE_DumbProxy disables client-side movement simulation entirely, the client will update projectile's location only when receiving its new location from the server. Such a movement doesn't look smooth, you literally can see how the projectile constantly teleports on its way to the target. This effect is usually less noticeable when server's tick rate matches the frame rate on the client (e.g., 60 ticks per second on the server and 60 FPS on the client), but otherwise it may look really ugly. Another trouble with ROLE_DumbProxy is that you can't use client-side projectile's simulated functions to spawn effects such as smoke; spawning lots of effects server-side and replicating them to clients may flood the network bandwidth and cause lags.
Last edited by Masterkent on Sat Aug 17, 2019 8:14 am, edited 1 time in total.
User avatar
Shivaxi
OldUnreal Member
Posts: 2232
Joined: Wed Mar 08, 2006 4:43 pm

Re: changing the speed of projectiles through mutator

Post by Shivaxi »

difference being though that this is right in the projectile of the missile, also dumbproxy

EDIT: so apparently

Rocket(A).Acceleration.X=Randrange(1000,-1000);
Rocket(A).Acceleration.Y=Randrange(1000,-1000);
Rocket(A).Acceleration.Z=Randrange(1000,-1000);

will work perfectly and even replicate in a tick function should the rocket be set to dumbproxy and bNetTemporary is False.
ROLE_DumbProxy disables client-side movement simulation entirely, the client will update projectile's location only when receiving its new location from the server. Such a movement doesn't look smooth, you literally can see how the projectile constantly teleports on its way to the target. This effect is usually less noticeable when server's tick rate matches the frame rate on the client (e.g., 60 ticks per second on the server and 60 FPS on the client), but otherwise it may look really ugly. Another trouble with ROLE_DumbProxy is that you can't use client-side projectile's simulated functions to spawn effects such as smoke; spawning lots of effects server-side and replicating them to clients may flood the network bandwidth and cause lags.
Isn't this how the seeking rocket works though? seeking rocket is dumb proxy, updates its position to the client seemingly smoothly (though i do run my servertickrate at 60) and on it also spawns smoke online just fine.
Image  Image
User avatar
Masterkent
OldUnreal Member
Posts: 1469
Joined: Fri Apr 05, 2013 12:41 pm

Re: changing the speed of projectiles through mutator

Post by Masterkent »

Isn't this how the seeking rocket works though?
Yes, but that doesn't mean that it's a good implementation choice. In particular, ROLE_SimulatedProxy with enabled bSimulatedPawnRep could work much better.
seeking rocket is dumb proxy, updates its position to the client seemingly smoothly
It doesn't look smoothly for me, even when server tick rate matches client-side frame rate.
Post Reply

Return to “UScript Board”