Announcement

Collapse
No announcement yet.

Getting my mutator to work in multiplayer?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Getting my mutator to work in multiplayer?

    My mutator only appears to work in single player, when I try to play a multiplayer game, only the host appears to be able to doublejump, and do the special moves. For instance when you press ctrl when at the peak of the jump, you should be able to do a "superjump" (jump much higher).
    Provided the entire source code. Is there anything special I must do to make something work for everyone in the game?


    JJJumpboots.uc
    Code:
    class JJJumpBoots extends UTJumpBoots;
    
    
    /** adds or removes our bonus from the given pawn */
    simulated function AdjustPawn(UTPawn P, bool bRemoveBonus)
    {
    	if (P != None)
    	{
    		if (bRemoveBonus)
    		{
    			P.MultiJumpBoost -= MultiJumpBoost;
    			P.MaxFallSpeed -= MultiJumpBoost;
    			P.JumpBootCharge = 0;
    			// increase cost of high jump nodes so bots don't waste the boots for small shortcuts
    			if (P.Controller != None)
    			{
    				P.Controller.HighJumpNodeCostModifier -= 0;
    			}
    		}
    		else
    		{
    			P.MultiJumpBoost += MultiJumpBoost;
    			P.MaxFallSpeed += MultiJumpBoost;
    			P.JumpBootCharge = Charges;
    			// increase cost of high jump nodes so bots don't waste the boots for small shortcuts
    			if (P.Controller != None)
    			{
    				P.Controller.HighJumpNodeCostModifier += 0;
    			}
    		}
    	}
    }
    
    simulated function OwnerEvent(name EventName)
    {
    	if (Role == ROLE_Authority)
    	{
    		if (EventName == 'MultiJump')
    		{
    			Charges++;
    			UTPawn(Owner).JumpBootCharge = Charges;
    			Spawn(class'UTJumpBootEffect', Owner,, Owner.Location, Owner.Rotation);
    			Owner.PlaySound(ActivateSound, false, true, false);
    		}
    		else if (EventName == 'Landed' && Charges < 0)
    		{
    			Destroy();
    		}
    	}
    	else if (EventName == 'MultiJump')
    	{
    		Owner.PlaySound(ActivateSound, false, true, false);
    	}
    }
    
    DefaultProperties
    {
    	Charges=1
    	MultiJumpBoost=110
    	bDropOnDeath = false
    	//ActivateSound=SoundCue'MoveXmp_Sfx.RangerJumpJetThrustCue'
    	ActivateSound=SoundCue'JumpJettingSounds.JJ2Cue'
    	//ActivateSound=SoundCue'A_Pickups_Powerups.PowerUps.A_Powerup_JumpBoots_JumpCue'
    }
    JumpJettingMutator
    Code:
    class JumpJettingMutator extends UTMutator
    config (JumpJetting); 
    
    
    struct ReplacementInfo
    {
    	/** class name of the powerup we want to get rid of */
    	var name OldClassName;
    	/** fully qualified path of the class to replace it with */
    	var string NewClassPath;
    };
    
    
    var config string Validate;
    var config float DefaultCameraScale, MinimumCameraScale, MaximumCameraScale;
    var config bool bStartIn3rdPerson;
    var config array<ReplacementInfo> PowerupsToReplace;
    
    function bool CheckReplacement(Actor Other)
    {
    	local UTPowerupPickupFactory PowerupPickup;
    	local int Index;
    
    	PowerupPickup = UTPowerupPickupFactory(Other);
    	if (PowerupPickup != None)
    	{
    		if (PowerupPickup.InventoryType != None)
    		{
    			Index = PowerupsToReplace.Find('OldClassName', PowerupPickup.InventoryType.Name);
    			if (Index != Index_None)
    			{
    				if (PowerupsToReplace[Index].NewClassPath == "")
    				{
    					return false;
    				}
    				PowerupPickup.InventoryType = class<UTInventory>(DynamicLoadObject(PowerupsToReplace[Index].NewClassPath, class'Class'));
    				PowerupPickup.InitializePickup();
    			}
    		}
    	}
    	return true;
    }
    
    simulated function InitMutator(string options, out string ErrorMessage)
    {
        //DEBUG
        //LogInternal("MKLOG -> JumpJetting.InitMutator: CALLED");
        //DEBUG
    
        //INFO (neoaez)  20071124: Validate the INI and recreate if missing
        if ( Validate != "VALID" )
        {
            LogInternal( "MKLOG -> JumpJetting.InitMutator: Config file was not valid.  Recreating." );
            Validate = "VALID";
            DefaultCameraScale = 9.0;
            MinimumCameraScale = 4.0;
            MaximumCameraScale = 10.0;
        }
        /** INFO (neoaez) 20071124: check for valid values
    	 * */
        
        /** INFO (neoaez) 20071128: Let's avoid some quirkiness by making sure the minimum value is not greater than our maximum value.  
    	 * If it is let's just make them equal.
    	 * */
        if( MinimumCameraScale > MaximumCameraScale ) { MaximumCameraScale = MinimumCameraScale; }
        
        /** INFO (neoaez) 20071128: Let's make sure the values are valid.  I pulled these values from EPIC's code.
    	 * */
        if ( MaximumCameraScale > 40.0 ) { MaximumCameraScale = 40.0; }
        if ( MinimumCameraScale < 1.0 ) { MinimumCameraScale = 1.0; }
    
        if ( DefaultCameraScale > 40.0 ) { DefaultCameraScale = 40.0; }
        if ( DefaultCameraScale < 1.0 ) { DefaultCameraScale = 1.0; }
    
        /** INFO (neoaez) 20071128: Write out the config with the current values.
    	 * */
        SaveConfig();
    
        /** INFO (neoaez) 20071124: continue the mutator chain
    	 * */
        Super.InitMutator( options, ErrorMessage );
    }
    
    simulated function ModifyPlayer( Pawn Other )
    {
        local UTPawn P;
        local NewPawn NP;
    
        P = UTPawn( Other );
        if( P != None )
        {
    	
            NP = NewPawn( P );
            if ( NP != None )
            {
    		//Jumpjet Settings
    		NP.CreateInventory(class'JumpJetting.JJJumpboots');
    		NP.DoubleJumpThreshold = Max(NP.JJ_DoubleJumpThresHold, P.DoubleJumpThreshold); //1000
    		NP.MaxMultiJump = Max(3, P.MaxMultiJump); //3
    		NP.DodgeSpeed = NP.JJ_DodgeSpeed;	//730
    		NP.DodgeSpeedZ = NP.JJ_DodgeSpeedZ;	//230
    		NP.MultiJumpRemaining = 4;
    		NP.JumpZ = NP.JJ_JumpZ; //380
    		NP.WaterSpeed = NP.JJ_WaterSpeed; //355
    		NP.Groundspeed = NP.JJ_GroundSpeed;	//462
    		NP.Aircontrol = NP.JJ_Aircontrol; //20
    		NP.DefaultAirControl = NP.JJ_DefaultAirControl; //20
    		NP.SuperHealthMax = NP.JJ_SuperHealthMax;
    		NP.MaxFallSpeed = NP.JJ_MaxFallSpeed;
    		
    		//ThirdPerson Settings
    		NP.ClientSetValidCameraScaleValues( MinimumCameraScale, MaximumCameraScale );
                	NP.ClientSetCameraScale( DefaultCameraScale );
              	NP.ClientSetStartingCameraView();
                	NP.ClientInitInteraction();
            }
        }
        Super.ModifyPlayer( Other );
    }
    
    simulated function PostBeginPlay()
    {
        local UTGame Game;
    
        Super.PostBeginPlay();
        Game = UTGame( WorldInfo.Game );
        if ( Game != None )
        	Game.DefaultPawnClass = class'JumpJetting.NewPawn';
    		
    }
    
    
    defaultproperties
    {
        	Name="JumpJetting"
    }
    NewInteraction.uc
    Code:
    class NewInteraction extends Interaction
    config(jumpjetting);
    
    var PlayerController PC;
    var name bigjump;
    var config name JumpJetKey1, JumpJetKey2, JumpJetKey3;
    var config float AntiGravityBoost;
    var config name ToggleCameraKey, IncreaseCameraScaleKey, DecreaseCameraScaleKey;
    
    //reliable client function InitInteraction( PlayerController Player )
    //{
    //    InitInteraction( Player );
    //}
    
    function InitInteraction( PlayerController Player )
    {	
    	PC = Player;
    }
    
    function bool InputKey( int ControllerId, name Key, EInputEvent EventType, optional float AmountDepressed = 1.f, optional bool bGamepad )
    {
        local NewPawn NP;
        
        NP = NewPawn( PC.Pawn );
        if ( NP != None )
        {
             if ( Key == bigjump && EventType == IE_Pressed )
            {
    	NP.SuperJump();
            }
            if (( Key == bigjump && EventType == IE_Released ) || NP.Physics == PHYS_Walking)
            {
    	NP.ResetSuperJump();
            }
    
    
            if ( Key == JumpJetKey3 && EventType == IE_Pressed )
            {
    	    if ((NP.MultiJumpRemaining < 3) && (NP.Physics == PHYS_Falling))
    	    	NP.CustomGravityScaling = AntiGravityBoost;
            }
    	if ( Key == JumpJetKey1 && EventType == IE_Pressed )
            {
    	    if ((NP.MultiJumpRemaining < 3) && (NP.Physics == PHYS_Falling))
    	    	NP.CustomGravityScaling = AntiGravityBoost;
            }
    	if ( (Key == JumpJetKey1 && EventType == IE_Released || Key == JumpJetKey3 && EventType == IE_Released) || NP.Physics == PHYS_Walking )
    	{ 
    	    NP.CustomGravityScaling = 1.0;
    	    NP.DoubleJumpBoost = -45;   
    	}  
    	//ThirdPerson Keys
    	if ( Key == ToggleCameraKey && EventType == IE_Pressed )
            {
                NP.ToggleCamera();               
            }
            
            if( Key == IncreaseCameraScaleKey && EventType == IE_Pressed )
            {
                NP.IncreaseCameraScale();
            }
        
            if( Key == DecreaseCameraScaleKey && EventType == IE_Pressed )
            {
                NP.DecreaseCameraScale();
            }
        }
        return false;
    }
    
    
    defaultproperties
    {
       __OnReceivedNativeInputKey__Delegate=Default__NewInteraction.InputKey
       Name="Default__NewInteraction"
       ObjectArchetype=Interaction'Engine.Default__Interaction'
       bigjump = LeftControl
    
    }
    NewPawn
    Code:
    class NewPawn extends UTPawn
    config (JumpJetting);
    
    /** INFO (neoaez) 20071128: config file variables
     * */
    var config float CameraScaleAdjustSensitivity, MyCameraScale;
    var config bool bStartIn3rdPerson;
    
    var float CameraScalePriorToFeignDeath, CurrentCameraScalePriorToFeignDeath, MinimumCameraScale, MaximumCameraScale;
    var bool  bBehindViewPriorToFeignDeath;
    
    /** INFO (hideinlight): config file variables for JumpJetting
     * */
    var config int FirstJumpBoost;
    var config int DoubleJumpBoost;
    var config int DodgeJumpBoost;
    var config int ForthJump;
    var config int FallJumpBoost;
    
    var config int VelFirstJumpBoost;
    var config int VelDoubleJumpBoost;
    var config int VelDodgeJumpBoost;
    var config int VelBoost;
    
    var config bool bCanVelBoost;
    
    var config int SuperDoubleJumpBoost;
    var config int SuperDodgeJumpBoost;
    
    var config int JJ_DoubleJumpThresHold;
    var config int JJ_DodgeSpeed;
    var config int JJ_DodgeSpeedZ;
    var config int JJ_JumpZ; 
    var config int JJ_GroundSpeed;
    var config int JJ_WaterSpeed;
    var config int JJ_HighDoubleJumpThreshold;
    var config float JJ_DefaultAirControl;
    var config float JJ_AirControl;
    
    var config float JJ_SuperHealthMax;
    var config float JJ_MaxFallSpeed;
    
    reliable client function ClientInitInteraction()
    {
        local PlayerController PC;
        local int i;
        local bool bFound;
        
        PC = PlayerController( Controller );
        if ( PC == None ) 
        { 
    	return; 
        }
    
        for (i = 0; i < PC.Interactions.Length; i++)
        {    
            if (NewInteraction( PC.Interactions[i] ) != None) { bFound = true; }               
        }
    
        if (!bFound)
        {
            PC.Interactions.Insert( 0, 1 );
            PC.Interactions[0] = new( PC ) class'NewInteraction';
            NewInteraction( PC.Interactions[0] ).InitInteraction( PC );
        }
    }
    
    function bool DoJump( bool bUpdating )
    {
    	// This extra jump allows a jumping or dodging pawn to jump again mid-air
    	// (via thrusters). The pawn must be within +/- DoubleJumpThreshold velocity units of the
    	// apex of the jump to do this special move.
    	if ( !bUpdating && CanDoubleJump() && (Abs(Velocity.Z) < JJ_DoubleJumpThreshold) && IsLocallyControlled() )
    	{
    		if (MultiJumpRemaining == 3)
    		{		        
    			//`log("Multi at 3");
    		}
    		
    		else if (MultiJumpRemaining == 2)
    		{		        
    			MultiJumpBoost=DoubleJumpBoost;
    			//`log("FirstJump");
    			MultiJumpRemaining = 0;
    			VelBoost = VelBoost * VelDoubleJumpBoost; 
    		}
    
    		else if (MultiJumpRemaining == 1)
    		{
    			MultiJumpBoost=DodgeJumpBoost;
    			VelBoost = VelBoost * VelDodgeJumpBoost; 
    			//`log("SecondJump");
    		}
    		else
    		{
    			MultiJumpBoost=ForthJump;
    			//`log("ForthJump");	
    		}
    	 
    		if ( PlayerController(Controller) != None )
    			PlayerController(Controller).bDoubleJump = true;
    		DoDoubleJump(bUpdating);
    		MultiJumpRemaining -= 1;
    
    		return true;
    	}
    
    	if (bJumpCapable && !bIsCrouched && !bWantsToCrouch && (Physics == PHYS_Walking || Physics == PHYS_Ladder || Physics == 	PHYS_Spider))
    	{
    		if ( Physics == PHYS_Spider )
    			Velocity = JumpZ * Floor;
    		else if ( Physics == PHYS_Ladder )
    			Velocity.Z = 0;
    		else if ( bIsWalking )
    		{
    			Velocity.Z = Default.JumpZ;
    		}
    		else 
    		{
    			Velocity.Z = JumpZ;
    			//hideinlight. To seperate the first jump from the doublejump
    			MultiJumpRemaining -= 1;
    		}
    			
    		if (Base != None && !Base.bWorldGeometry && Base.Velocity.Z > 0.f)
    		{
    			if ((WorldInfo.WorldGravityZ != WorldInfo.DefaultGravityZ) && (GetGravityZ() == WorldInfo.WorldGravityZ)) 
    			{
    				Velocity.Z += Base.Velocity.Z * sqrt(GetGravityZ()/WorldInfo.DefaultGravityZ);
    			}
    			else
    			{
    				Velocity.Z += Base.Velocity.Z;
    			}
    		}
    		SetPhysics(PHYS_Falling);
    		bReadyToDoubleJump = true;
    		bDodging = false;
    		if ( !bUpdating )
    		    PlayJumpingSound();
    		return true;
    	}
    	return false;
    }
    
    function DoDoubleJump( bool bUpdating )
    {
    	if ( !bIsCrouched && !bWantsToCrouch )
    	{
    		if ( !IsLocallyControlled() || AIController(Controller) != None )
    		{
    			MultiJumpRemaining -= 1;
    		}
    		if (Abs(Velocity.Z) > JJ_HighDoubleJumpThreshold)
    			Velocity.Z = JumpZ + FallJumpBoost;
    		else 
    		{
    			Velocity.Z = JumpZ + MultiJumpBoost;
    			if (bCanVelBoost)
    				Velocity = Velocity * VelBoost;
    		}
    		InvManager.OwnerEvent('MultiJump');
    		SetPhysics(PHYS_Falling);
    		BaseEyeHeight = DoubleJumpEyeHeight;
    		if (!bUpdating)
    		{
    			SoundGroupClass.Static.PlayDoubleJumpSound(self);
    		}
    	}
    }
    
    function bool PerformDodge(eDoubleClickDir DoubleClickMove, vector Dir, vector Cross)
    {
    	local float VelocityZ;
    
    	if ( Physics == PHYS_Falling )
    	{
    		TakeFallingDamage();
    	}
    
    	bDodging = true;
    	if (MultiJumpRemaining > 1)
    	{
    		MultiJumpRemaining = 1;
    		//`log("MultiJump has been set to 1");
    	}
    	else
    		//`log("No change in MultiJumps");
    		
    	
    	--MultiDodgeRemaining;
    
    	bReadyToDoubleJump = (JumpBootCharge > 0);
    	VelocityZ = Velocity.Z;
    	Velocity = DodgeSpeed*Dir + (Velocity Dot Cross)*Cross;
    
    	if ( VelocityZ < -200 )
    		Velocity.Z = VelocityZ + DodgeSpeedZ;
    	else
    		Velocity.Z = DodgeSpeedZ;
    
    	CurrentDir = DoubleClickMove;
    	SetPhysics(PHYS_Falling);
    	SoundGroupClass.Static.PlayDodgeSound(self);
    	return true;
    }
    exec function SuperJump()
    {
    	bCanVelBoost = True;
    	DoubleJumpBoost = SuperDoubleJumpBoost;
    	DodgeJumpBoost = SuperDodgeJumpBoost;
    }
    exec function ResetSuperJump()
    {
    	bCanVelBoost = False;
    	DoubleJumpBoost = -45;
    	DodgeJumpBoost = -45;
    }
    exec function JJJumps(int x,int y,int z)
    { 
    	FirstJumpBoost = x;
    	DoubleJumpBoost = y;
    	DodgeJumpBoost = z;
    } 
    exec function JJDodging(int s, int h)
    {
        	DodgeSpeed = s;
        	DodgeSpeedZ = h;
    }
    
    reliable client function ClientSetCameraScale( float scale )
    {
        SetCameraScale( scale );
    }
    
    function SetCameraScale( float scale )
    {
        //DEBUG
        //LogInternal( "MKLOG -> NewPawn.SetCameraScale: MyCameraScale:" @ MyCameraScale );
        //DEBUG
        
        /** INFO (neoaez) 20071128: On death and at the beginning of a new match the camera scale gets reset to its default 9.0
         * We are going to check a local variable for a value.   If it is not 0 then we use it, otherwise let the engine do what 
         * it wants 
         * */
        if( MyCameraScale > 0 )
        {
            CameraScale = MyCameraScale;
            CurrentCameraScale = MyCameraScale;
        }
        else
        {
            CameraScale = scale;
            CurrentCameraScale = scale;
        }    
    }
    
    reliable client function ClientSetStartingCameraView()
    {
        local UTPlayerController PC;
        local name NewMode;
        
        PC = UTPlayerController( Controller );
        if ( PC != None )
        {
            if( !bStartIn3rdPerson )
            {
                NewMode = 'FirstPerson';
            }
           else
           {
               NewMode = 'ThirdPerson';
           }
           PC.ServerCamera( NewMode );
        }
    }
    
    reliable client function ClientSetValidCameraScaleValues( float min, float max )
    {
        MinimumCameraScale = min;
        MaximumCameraScale = max;
    }
    
    exec function IncreaseCameraScale()
    {
        local UTPlayerController PC;
        
        //DEBUG
        //LogInternal( "MKLOG -> NewPawn.IncreaseCameraScale: CameraScaleAdjustSensitivity:" @ CameraScaleAdjustSensitivity );
        //DEBUG
        
        /** INFO (neoaez) 20071128: If we are in first-person then ignore this command
         * */
        PC = UTPlayerController( Controller );
        if ( PC != None )
        {
            if( PC.UsingFirstPersonCamera() ) { return; }
         
            if( CameraScaleAdjustSensitivity <= 0 ) { CameraScaleAdjustSensitivity = 1.0; }
            CameraScale = CameraScale + 1.0 * CameraScaleAdjustSensitivity;
         
            if( CameraScale >= MaximumCameraScale )
            {
                CameraScale = MaximumCameraScale;
            }
            MyCameraScale = CameraScale;
            SaveConfig();
        }
    }
    
    exec function DecreaseCameraScale()
    {
        local UTPlayerController PC;
        
        //DEBUG
        //LogInternal( "MKLOG -> NewPawn.DecreaseCameraScale: CameraScaleAdjustSensitivity:" @ CameraScaleAdjustSensitivity );
        //DEBUG
        
        /** INFO (neoaez) 20071128: If we are in first-person then ignore this command
         * */
        PC = UTPlayerController( Controller );
        if ( PC != None )
        {
            if( PC.UsingFirstPersonCamera() ) { return; }
        
            if( CameraScaleAdjustSensitivity <= 0 ) { CameraScaleAdjustSensitivity = 1.0; }
            CameraScale = CameraScale - 1.0 * CameraScaleAdjustSensitivity;
        
            if( CameraScale <= MinimumCameraScale )
            {
                CameraScale = MinimumCameraScale;
            }
            MyCameraScale = CameraScale;
            SaveConfig();
        }
    }
    
    exec function ToggleCamera()
    {    
        local UTPlayerController PC;
        local bool bCurrentBehindView;
        local name NewMode;
        
        PC = UTPlayerController( Controller );
        if ( PC != None )
        {
            bCurrentBehindView = PC.bBehindView;
            
            if( bCurrentBehindView )
            {
                NewMode = 'FirstPerson';
            }
            else
            {
                NewMode = 'ThirdPerson';
            }
            PC.ServerCamera( NewMode );
        }
    }
    
    simulated function bool CalcThirdPersonCam( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
    {
        local vector CamStart, HitLocation, HitNormal, CamDir;
        local float DesiredCameraZOffset;
    
        ModifyRotForDebugFreeCam(out_CamRot);
    
        CamStart = Location;
    
        if ( bWinnerCam )
        {
            // use "hero" cam
            SetHeroCam(out_CamRot);
        }
        else
        {
            DesiredCameraZOffset = (Health > 0) ? 1.5 * GetCollisionHeight() + Mesh.Translation.Z : 0.f;
            CameraZOffset = (fDeltaTime < 0.2) ? DesiredCameraZOffset * 5 * fDeltaTime + (1 - 5*fDeltaTime) * CameraZOffset : DesiredCameraZOffset;
        }
        CamStart.Z += CameraZOffset;
        CamDir = Vector(out_CamRot) * GetCollisionRadius() * CurrentCameraScale;
    
        if ( (Health <= 0) || bFeigningDeath )
        {
            // adjust camera position to make sure it's not clipping into world
            // @todo fixmesteve.  Note that you can still get clipping if FindSpot fails (happens rarely)
            FindSpot(GetCollisionExtent(),CamStart);
        }
        if ( CurrentCameraScale < CameraScale )
        {
            //DEBUG
            //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was smaller): [PRIOR to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
            //DEBUG
    
            CurrentCameraScale = FMin( CameraScale, CurrentCameraScale + 5 * FMax( CameraScale - CurrentCameraScale, 0.3 )*fDeltaTime );
            //DEBUG
            //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was smaller): [After to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
            //DEBUG
            
        }
        else if ( CurrentCameraScale > CameraScale )
        {
            //DEBUG
            //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was larger): [PRIOR to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
            //DEBUG
            
            /** INFO (neoaez) 20080614: fixes a logic bug with EPIC's original code.  
             * Changed the second FMax state in the line below from:
             * FMax( CameraScale - CurrentCameraScale, 0.3 )*fDeltaTime );
             * to:
             * FMax( CurrentCameraScale - CameraScale, 0.3 )*fDeltaTime );
             * Since the CurrentCameraScale value is more than CameraScale the original code would result in a negative value compared against
             * the 0.3 value.  Of course the 0.3 value would win every time.  This is not desirable.
             * */
            CurrentCameraScale = FMax( CameraScale, CurrentCameraScale - 5 * FMax( CurrentCameraScale - CameraScale, 0.3 )*fDeltaTime );
            
            //DEBUG
            //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was larger): [After to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
            //DEBUG
           
        }
        if (CamDir.Z > GetCollisionHeight())
        {
            CamDir *= square(cos(out_CamRot.Pitch * 0.0000958738)); // 0.0000958738 = 2*PI/65536
        }
        out_CamLoc = CamStart - CamDir;
        if (Trace(HitLocation, HitNormal, out_CamLoc, CamStart, false, vect(12,12,12)) != None)
        {
            out_CamLoc = HitLocation;
            return false;
        }
        return true;
    }
    
    state FeigningDeath
    {
        ignores ServerHoverboard, SwitchWeapon, QuickPick, FaceRotation, ForceRagdoll, AdjustCameraScale, SetMovementPhysics;
    
        exec simulated function FeignDeath()
        {
            if ( bFeigningDeath )
            {
                Global.FeignDeath();
            }
        }
    
        reliable server function ServerFeignDeath()
        {
            if ( Role == ROLE_Authority && !WorldInfo.GRI.bMatchIsOver && !IsTimerActive( 'FeignDeathDelayTimer' ) && bFeigningDeath )
            {
                bFeigningDeath = false;
                PlayFeignDeath();
            }
        }
    
        event bool EncroachingOn( Actor Other )
        {
            // don't abort moves in ragdoll
            return false;
        }
    
        simulated function bool CanThrowWeapon()
        {
            return false;
        }
    
        simulated function Tick( float DeltaTime )
        {
            local rotator NewRotation;
    
            if ( bPlayingFeignDeathRecovery && PlayerController( Controller ) != None )
            {
                // interpolate Controller yaw to our yaw so that we don't get our rotation snapped around when we get out of feign death
                NewRotation = Controller.Rotation;
                NewRotation.Yaw = RInterpTo( NewRotation, Rotation, DeltaTime, 2.0 ).Yaw;
                Controller.SetRotation( NewRotation );
    
                if ( WorldInfo.TimeSeconds - FeignDeathRecoveryStartTime > 0.8 )
                {
                    CameraScale = 1.0;
                }
            }
        }
    
        simulated function bool CalcThirdPersonCam( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
        {
            local vector CamStart, HitLocation, HitNormal, CamDir;
            local RB_BodyInstance RootBodyInst;
            local matrix RootBodyTM;
    
            if ( CurrentCameraScale < CameraScale )
            {
                //DEBUG
                //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was smaller): [PRIOR to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
                //DEBUG
    
                CurrentCameraScale = FMin( CameraScale, CurrentCameraScale + 5 * FMax( CameraScale - CurrentCameraScale, 0.3 )*fDeltaTime );
                //DEBUG
                //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was smaller): [After to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
                //DEBUG
                
            }
            else if ( CurrentCameraScale > CameraScale )
            {
                //DEBUG
                //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was larger): [PRIOR to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
                //DEBUG
                
                CurrentCameraScale = FMax( CameraScale, CurrentCameraScale - 5 * FMax( CurrentCameraScale - CameraScale, 0.3 )*fDeltaTime );
                
                //DEBUG
                //WarnInternal( "MKLOG -> NewPawn.CalcThirdPersonCam (was larger): [After to Adjustment]CurrentCameraScale:" @ CurrentCameraScale );
                //DEBUG
               
            }
    
            //CamStart = Mesh.Bounds.Origin + vect(0,0,1) * BaseEyeHeight; (Replaced with below due to Bounds being updated 2x per frame 
            //which can result in jitter-cam
            CamStart = Mesh.GetPosition();
            if( Mesh.PhysicsAssetInstance != None )
            {
                RootBodyInst = Mesh.PhysicsAssetInstance.Bodies[Mesh.PhysicsAssetInstance.RootBodyIndex];
                if( RootBodyInst.IsValidBodyInstance() )
                {
                    RootBodyTM = RootBodyInst.GetUnrealWorldTM();
                    CamStart.X = RootBodyTM.WPlane.X;
                    CamStart.Y = RootBodyTM.WPlane.Y;
                    CamStart.Z = RootBodyTM.WPlane.Z;
                }
            }
            CamStart += vect( 0,0,1 ) * BaseEyeHeight;
    
            CamDir = vector( out_CamRot ) * GetCollisionRadius() * CurrentCameraScale;
    //      `log("Mesh"@Mesh.Bounds.Origin@" --- Base Eye Height "@BaseEyeHeight);
    
            if ( CamDir.Z > GetCollisionHeight() )
            {
                CamDir *= square( cos( out_CamRot.Pitch * 0.0000958738 ) ); // 0.0000958738 = 2*PI/65536
            }
            out_CamLoc = CamStart - CamDir;
            if ( Trace( HitLocation, HitNormal, out_CamLoc, CamStart, false, vect( 12,12,12 ) ) != None )
            {
                out_CamLoc = HitLocation;
            }
            return true;
        }
    
        simulated event OnAnimEnd( AnimNodeSequence SeqNode, float PlayedTime, float ExcessTime )
        {
            if ( Physics != PHYS_RigidBody && !bPlayingFeignDeathRecovery )
            {
                // blend out of feign death animation
                if ( FeignDeathBlend != None )
                {
                    FeignDeathBlend.SetBlendTarget( 0.0, 0.5 );
                }
                GotoState( 'Auto' );
            }
        }
    
        simulated event BeginState( name PreviousStateName )
        {
            local UTPlayerController PC;
            local UTWeapon UTWeap;
    
            bCanPickupInventory = false;
            StopFiring();
            bNoWeaponFiring = true;
    
            UTWeap = UTWeapon( Weapon );
            if ( UTWeap != None )
            {
                UTWeap.PlayWeaponPutDown();
            }
            if( UTWeap != none && PC != none )
            {
                UTPlayerController( Controller ).EndZoom();
            }
    
            PC = UTPlayerController( Controller );
            if ( PC != None )
            {
                CameraScalePriorToFeignDeath = CameraScale;
                CurrentCameraScalePriorToFeignDeath = CurrentCameraScale;
                bBehindViewPriorToFeignDeath = PC.bBehindView;
                PC.SetBehindView( true );
                CurrentCameraScale = 1.5;
                CameraScale = 2.25;
            }
    
            DropFlag();
        }
    
        simulated function EndState( name NextStateName )
        {
            local UTPlayerController PC;
            local UTPawn P;
    
            if ( NextStateName != 'Dying' )
            {
                bNoWeaponFiring = default.bNoWeaponFiring;
                bCanPickupInventory = default.bCanPickupInventory;
                Global.SetMovementPhysics();
                PC = UTPlayerController( Controller );
                if ( PC != None )
                {
                   PC.SetBehindView( bBehindViewPriorToFeignDeath );
                }
    
                 CurrentCameraScale = CurrentCameraScalePriorToFeignDeath;
                CameraScale = CameraScalePriorToFeignDeath;
                bForcedFeignDeath = false;
                bPlayingFeignDeathRecovery = false;
    
                // jump away from other feigning death pawns to make sure we don't get stuck
                foreach TouchingActors( class'UTPawn', P )
                {
                    if ( P.IsInState( 'FeigningDeath' ) )
                    {
                        JumpOffPawn();
                    }
                }
            }
        }
    }
    
    /** INFO (neoaez) 20080610: Thanks to the ActionCam mutator for this fix. 
     * Correct aim to sync projectile trajectory with camera trace
     * */
    simulated singular function Rotator GetBaseAimRotation()
    {
        local vector    POVLoc;
        local rotator   POVRot;
        local UTPlayerController PC;
    
        local vector TargetLocation;
        local vector HitLocation, HitNormal;
        local int TraceScalar;
    
        // If we have a controller, by default we aim at the player's 'eyes' direction
        // that is by default Controller.Rotation for AI, and camera (crosshair) rotation for human players.
        if( Controller != None && !InFreeCam() )
        {
            Controller.GetPlayerViewPoint(POVLoc, POVRot);        
            PC = UTPlayerController( Controller );
            
            //DEBUG
            //LogInternal( "MKLOG -> NewPawn.GetBaseAimRotation: PC.bBehindView = "@PC.bBehindView );
            //DEBUG
            
            /** INFO (neoaez) 20080615: If we are in first-person then there is no need to correct the original
             * aim code provided by EPIC.  
             * */
            if ( !PC.bBehindView )
            {
                
                //DEBUG
                //LogInternal( "MKLOG -> NewPawn.GetBaseAimRotation: Was first-person so returning POVRot" );
                //DEBUG           
                return POVRot; 
            }
            //DEBUG
            //LogInternal( "MKLOG -> NewPawn.GetBaseAimRotation: Not first-person so adjusting POVRot" );
            //DEBUG           
            
            /** INFO (neoaez) 20080610: changed ActionCam code in the following line from this:        
             * TargetLocation = POVLoc + (vector(POVRot)*100000);
             * to remove arbitray scalar used in trace to that of the weapon equipped.  This follows the
             * example set out by the function GetWeaponAim in UTVehicle  Fixes an accuracy issue when
             * in third-person.
             * */
             if (Weapon.bMeleeWeapon) { TraceScalar = 100000; }
             else { TraceScalar = Weapon.GetTraceRange(); }
             TargetLocation = POVLoc + ( vector( POVRot ) * TraceScalar );
             if( Trace( HitLocation, HitNormal, TargetLocation, POVLoc, false,,,TRACEFLAG_Bullet ) == None )
             {
                 HitLocation = TargetLocation;
             }
             POVRot = rotator( HitLocation - GetWeaponStartTraceLocation() );
    
             return POVRot;
        }
    
        // If we have no controller, we simply use our rotation
        POVRot = Rotation;
    
        // If our Pitch is 0, then use RemoveViewPitch
        if( POVRot.Pitch == 0 )
        {
            POVRot.Pitch = RemoteViewPitch << 8;
        }
    
        return POVRot;
    }
    
    defaultproperties
    {
    
    }

    #2
    At the least, I think your pawn class and/or your interaction class will need a little replication for multiplayer. You can easily debug by logging variables at functions which are called on client/server, and checking the logs of each.

    Comment


      #3
      Originally posted by NickG View Post
      At the least, I think your pawn class and/or your interaction class will need a little replication for multiplayer. You can easily debug by logging variables at functions which are called on client/server, and checking the logs of each.
      Replication looks complicated as hell. Think I'm gonna start over and create a very basic mutator that replaces the pawn and play around with it on the network and see what works and doesn't work in a network environment.
      So far using configs appear to add an extra layer of complications.

      Afterwards I'll try to add back the Interaction class, which I can't seem to use for changing values of the pawn client side.

      Comment

      Working...
      X