1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. 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.

Replication Problems ......

Discussion in 'Programming' started by Wang, Feb 24, 2002.

  1. Wang

    Wang Wibble

    Joined:
    Feb 7, 2002
    Messages:
    22
    Likes Received:
    0
    Having written a mutator for my own amusement to mimic some of the functionality in AQ2, I now have it working fine in a bot match. However parts of it don't work when running a LAN game. I know it has something to do with replication but despite playing around with the code I still can't get the effects I want. The bits that are currently not working are: leg damage with limping and bandaging. Here is the relvant code so far:

    Code:
    class WangTPlayer expands TournamentPlayer abstract;
    
    var bool bLimp;
    var bool bBleed;
    var bool bandaging;
    var int iDamageVal; // This basically governs how fast they bleed
    var float limpTime; // This is used to control the accel/decel of limping player
    var float bleedTime; // This is used to control the frequency of bleeding
    var float bandageTime;
    
    
    function DoJump( optional float F )
    {
       local vector HitLocation, HitNormal, StartTrace, EndTrace, X, Y, Z;
       if (bLimp) {
          // No jumping when limping
          Log("Refused jump");
          return;
       }
       //Log("Do the jump");
       GetAxes(ViewRotation, X, Y, Z);
       StartTrace = Location; // + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z;
       EndTrace = StartTrace + 60 * X;
       HitActor = Trace(HitLocation, HitNormal, EndTrace, StartTrace, true);
       if ((HitActor != None) && HitActor.IsA('Pawn')) {
          kickEm(HitActor, HitLocation, HitNormal, X, Y, Z);
       }
       Super.DoJump(F);
    }
    
    function kickEm(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z)
    {
       Other.TakeDamage(25.0, Self, HitLocation, 65000.0 * X, 'kick');
    }
    
    function TakeFallingDamage() {
       // This function allows complete control on how falling damage is incurred
       if (Velocity.Z < -1 * JumpZ) {
          MakeNoise(-0.5 * Velocity.Z/(FMax(JumpZ, 150.0)));
          if (Velocity.Z <= -500 - JumpZ) {
             if ( (Velocity.Z < -750 - JumpZ) && (ReducedDamageType != 'All') ) {
                if ( (Velocity.Z < -1100 - JumpZ) && (ReducedDamageType != 'All') ) {
                   Log("Going to Die with giblets");
                   TakeDamage(1000, None, Location, vect(0,0,0), 'Fell');
                } else {
                   Log("Going to Die without gibs");
                   Velocity.Z = 0;
                   Health = 1;
                   TakeDamage(1, None, Location, vect(0,0,0), 'Fell');
                }
    
             } else if ( Role == ROLE_Authority ) {
                Log("Doing Normal damage");
    
                bLimp = true;
    
                TakeDamage(-0.03 * (Velocity.Z + JumpZ), None, Location, vect(0,0,0), 'Fell');
             }
             ShakeView(0.175 - 0.00007 * Velocity.Z, -0.85 * Velocity.Z, -0.002 * Velocity.Z);
          }
       } else if ( Velocity.Z > 0.5 * Default.JumpZ )
           MakeNoise(0.35);
    }
    
    exec function bandage()
    {
       local Weapon W;
    
       W = Weapon;
       PendingWeapon = None;
       if ( Weapon != None )
          Weapon.PutDown();
       PendingWeapon = W;
       bandaging = true;
       GotoState('PlayerWalking');
    }
    
    function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation,
                                  Vector momentum, name damageType)
    {
       local int HitHeight, HitAngle;
       if (damageType != 'bleed') {
          bBleed = true;
    
          HitHeight = hitLocation.Z - Location.Z;
    
          HitAngle = (Rotation.Yaw - rotator(hitLocation - Location).Yaw) & 65535;
    
          if (HitHeight > 0.62 * CollisionHeight) {
             Log("Head hit");
             iDamageVal += 30;
          } else if (HitHeight < 0.35 * CollisionHeight) {
            Log("Leg hit");
             iDamageVal += 2;
             bLimp = True;
             if (damageType == 'fell') {
                bBleed = false;
             }
          } else {
             Log("Body hit");
             iDamageVal += 5;
          }
    
          if ( (HitAngle < 12000 && HitAngle > 0) || (HitAngle > 53535 && HitAngle < 65535) ) {
             Log("Frontal hit");
          } else if ( (HitAngle < 44768 && HitAngle > 20768) ) {
             Log("Rear hit");
          } else {
             Log("Side hit");
          }
       }
    
    
       Super.TakeDamage(Damage, instigatedBy, hitlocation,
                                  momentum, damageType);
    
    
    }
    
    function Died(pawn Killer, name damageType, vector HitLocation)
    {
         bLimp = false;
         bBleed = false;
         iDamageVal = 0;
         limpTime = 0;
         bleedTime = 0;
         bandaging = false;
         bandageTime = 0;
    
         Super.Died(Killer, damageType, HitLocation);
    }
    
    state PlayerWalking
    {
    ignores SeePlayer, HearNoise, Bump;
    
       event PlayerTick( float DeltaTime )
       {
       local rotator splatRot;
       local vector splatLoc;
    // ***************** NEW CODE
          if (bLimp && (Physics != PHYS_Falling)) {
             limpTime += DeltaTime;
             if (limpTime > 0.3) {
                Log("limping");
    //            Log(limpTime);
                Velocity.X = Velocity.X / 10;
                Velocity.Y = Velocity.Y / 10;
                limpTime = 0;
             }
          }
          if (bBleed && (Physics != PHYS_Falling)) {
             bleedTime += DeltaTime;
             if (bleedTime > 0.75) {
                Log("Bleeding");
                // Set the splat pitch
                splatRot.Pitch = 16384;
                splatLoc = Location;
    
             // Create a bloodsplat under the player
                if ( splatLoc != OldLocation) {
    //               Log("bBleed Now Splatting");
                   Spawn( class'BloodSplat', , , splatLoc, splatRot );
                }
                Log("Doing bleed damage");
    //            Log(iDamageVal);
                TakeDamage(iDamageVal, Self, vect(0,0,0), vect(0,0,0), 'bleed');
                bleedTime = 0;
             }
          }
          if (bandaging) {
             Weapon = None;  // in case client confused because of weapon switch just before bandaging
             bandageTime += DeltaTime;
             if ((bandageTime > 3) && (iDamageVal > 0))
                iDamageVal -= 10;
             if (iDamageVal <= 0) {
                bandageTime = 0;
                bBleed = false;
                bLimp = false;
                iDamageVal = 0;
                bandaging = false;
                bleedTime = 0;
                limpTime = 0;
                Weapon = PendingWeapon;
                PendingWeapon.SetDefaultDisplayProperties();
                ChangedWeapon();
             }
          }
    // ***************** NEW CODE
          if ( bUpdatePosition )
             ClientUpdatePosition();
    
          PlayerMove(DeltaTime);
       }
    
       function Dodge(eDodgeDir DodgeMove)
       {
          local vector X,Y,Z;
    
          if ( bIsCrouching || (Physics != PHYS_Walking) || bLimp )
             return;
    
          GetAxes(Rotation,X,Y,Z);
          if (DodgeMove == DODGE_Forward)
             Velocity = 1.5*GroundSpeed*X + (Velocity Dot Y)*Y;
          else if (DodgeMove == DODGE_Back)
             Velocity = -1.5*GroundSpeed*X + (Velocity Dot Y)*Y;
          else if (DodgeMove == DODGE_Left)
             Velocity = 1.5*GroundSpeed*Y + (Velocity Dot X)*X;
          else if (DodgeMove == DODGE_Right)
             Velocity = -1.5*GroundSpeed*Y + (Velocity Dot X)*X;
    
          Velocity.Z = 160;
          PlayOwnedSound(JumpSound, SLOT_Talk, 1.0, true, 800, 1.0 );
          PlayDodge(DodgeMove);
          DodgeDir = DODGE_Active;
          SetPhysics(PHYS_Falling);
       }
       
       exec function Fire( optional float F )
       {
          if (bandaging)
             return;
          Super.Fire(F);
       }
       exec function AltFire( optional float F )
       {
          if (bandaging)
             return;
          Super.AltFire(F);
       }
    }
    
    DefaultProperties
    {
    
    }
    So when a player gets shot or falls (TakeFallingDamage, TakeDamage) bLimp is set to true. Then DoJump should prevent the player jumping. It does but in a LAN game there are some glitches as the player starts to jump then decides not to causing the screen to jump for a split second.
    The other main problem is that none of the code in the PlayerTick of state PlayerWalking seems to be running (bleeding, limping, bandaging)

    What needs replicating and how????????????????
    (sorry for the long post :) )
     
  2. Wormbo

    Wormbo Administrator Staff Member

    Joined:
    Jun 4, 2001
    Messages:
    5,913
    Likes Received:
    36
    Let's see...

    Bandage() is activated through a key press (client), right? But it should be called on the server.

    bLimp is set on the server, but the client tries to guess how the server behaves so he needs to know about the bLimp variable.
    Code:
    replication
    {
    	reliable if ( Role < ROLE_Authority )
    		Bandage;
    
    	unreliable if ( Role == ROLE_Authority )
    		bLimp;
    }
    I'm not sure about the other variables, but maybe "bandaging" should also replicated to clients. (Role == ROLE_Authority)
     
  3. Wang

    Wang Wibble

    Joined:
    Feb 7, 2002
    Messages:
    22
    Likes Received:
    0
    Thanks for taking the time to reply. After going through the replication docs and re-reading my own post again I think it was a bit of an uninformed question :)
    I now have a handle on the replication stuff and with this knowledge shuffled the code around a bit and added a replication statement.
    Through the use of loads of Log statements it appears that the PlayerTick does not run on the server (?) (no scriptlogs in the server.log but loads in the UT.log)
    Assuming this is the case I took the bleed/limp functionality out of the player tick and put them into functions which get called from the tick. These funcs I then added to the replication statement (client to server), and the vars involved going the other way. So I now have:

    Code:
    replication
    {
         reliable if (Role < ROLE_Authority)
              bandage, Bleed, Heal, Limp;
       reliable if (Role == ROLE_Authority)
          bLimp, bBleed, bandaging, iDamageVal ;
    }
    and

    Code:
    state PlayerWalking
    {
    ignores SeePlayer, HearNoise, Bump;
    
       event PlayerTick( float DeltaTime )
       {
    // ***************** NEW CODE
          if (bLimp && (Physics != PHYS_Falling)) {
             Limp(DeltaTime);
          }
          if (bBleed && (Physics != PHYS_Falling)) {
             Bleed(DeltaTime);
          }
          if (bandaging) {
             Heal(DeltaTime);
          }
    // ***************** NEW CODE
          if ( bUpdatePosition )
    This now works (or seems to, I havent had much time). I guess my question now is does PlayerTick only run on the client and is what I have done the "right/correct" way to do things?
     
  4. butto

    butto Red Orchestra Coder

    Joined:
    Dec 2, 2001
    Messages:
    693
    Likes Received:
    0
    PlayerTick() only runs on the client in a network game. It really pisses me off too because I had to make a separate class to manage some things that I wanted the server to have authority over.
     
  5. 2COOL4-U

    2COOL4-U New Member

    Joined:
    Mar 17, 2001
    Messages:
    505
    Likes Received:
    0
    we had to do it too for Defence Alliance's syrigne
     

Share This Page