Legacy:WeaponSystemFramework - Unreal Wiki

# Legacy:WeaponSystemFramework

### From Unreal Wiki, The Unreal Engine Documentation Site

## The Vehicle Weapon System Framework

I've written up this class to make implementation of weapons for vehicles both easily and quickly. A configurable zoom option and automated projectile firing/timing is already implemented and toggleable with use of the defaultproperties section.

A note about the zoom, in order to ensure the behavior intended, both the zoom and await variables needs to be set to true. It should still *work* but i don't suggest it.

### Key Concepts

The server will exclusively call the TimerUpdateWithoutDriver and TimerUpdateWithDriver. The First every tick ( Be careful ), and the other every tick while a player is in the vehicle.

All of the Server* functions will be executed exclusively on the server.

All of the Client* functions will be executed exclusively on network-clients.

All of the base functions of this same family ( I.E. ServerPriFireInactive, ClientPriFireInactive, *PriFireInactive* ) are executed on the local machine of the person in the turret.

All client effects/rendering should be done in the base functions (PriFireInactive). This is the first function called, and is called locally on the client before any replication takes place, this will both be the fastest/most frequent to execute code.

Client* functions may not actually have a practical use but if you come up with something that should really be done in there let me know.

To make your primary fire spawn a projectile.

    defaultproperties
    {
    bPriFireSpawnProject=true
    bRepeatedPriFire=true //optional
    PrimaryProjectileClass=MyPackage.MyClass
    FireInterval=1.0
    }

To make your alternate fire zoom.

    defaultproperties
    {
      bDoAltZoom=true
      bShouldAwaitAltRelease=true
      ZoomMinFov=25.000
      ZoomMaxFov=120.0
      ZoomIncrement=0.5
    }

Note that setting zoomIncrement to a negative value makes a zoom out. A positive ZoomIncrement zooms in. (FOV-ZoomIncrement)

Here are all of the new default properties, with what i have thought to be fairly intuitive names.

    defaultproperties
    {
         TimerUpdateFrequency=0.01;
         bDoPriZoom=false
         bDoAltZoom=false
         bPriFireSpawnProjectile=false
         bAltFireSpawnProjectile=false
         bShouldAwaitPriRelease=false
         bShouldAwaitAltRelease=false
         bRepeatedPriFire=false
         bRepeatedAltFire=false
         ZoomMinFov=25.000
         ZoomMaxFov=120.0
         ZoomIncrement=0.5
         FireInterval=1.0
         AltFireInterval=0.0
         PrimaryProjectileClass=none
         SecondaryProjectileClass=none
    }

    class MTPBaseStationaryWeapon extends ONSWeapon;

    // Real-Time Key Press Variables
    var bool bIsAltFiring, bWasAltFiring;
    var bool bIsPriFiring, bWasPriFiring;
    var bool bAwaitingAltRelease, bAwaitingPriRelease;

    // Realtime Zoom Variables
    var float ZoomLevel;
    var bool bZooming;

    // Real-Time Weapon Variables
    var float LastPriFireTime, LastAltFireTime;

    // Configuration Weapon Variables
    var float TimerUpdateFrequency;
    var class<Projectile> PrimaryProjectileClass;
    var class<Projectile> SecondaryProjectileClass;
    var bool bPriFireSpawnProjectile, bAltFireSpawnProjectile;
    var bool bRepeatedPriFire, bRepeatedAltFire;

    // Configuration Key Press Variables
    var bool bShouldAwaitAltRelease, bShouldAwaitPriRelease;

    // Config/Default Oriented Zoom Variables
    var float ZoomMinFov, ZoomMaxFov, ZoomIncrement;
    var bool bDoPriZoom, bDoAltZoom;

    replication
    {
        reliable if( Role == Role_Authority )
            LastPriFireTime, LastAltFireTime, bAwaitingAltRelease, bAwaitingPriRelease;
        reliable if( Role < Role_Authority )
            ServerPriFirePressed, ServerPriFireReleased, ServerPriFireInactive, ServerPriFireActive,
            ServerAltFirePressed, ServerAltFireReleased, ServerAltFireInactive, ServerAltFireActive,
            ServerTimerUpdateWithDriver, ServerTimerUpdateWithoutDriver,
            ServerCantPriFire, ServerCantAltFire, ServerAwaitRelease;
        reliable if( Role == Role_Authority )
            ClientPriFirePressed, ClientPriFireReleased, ClientPriFireInactive, ClientPriFireActive,
            ClientAltFirePressed, ClientAltFireReleased, ClientAltFireInactive, ClientAltFireActive,
            ClientTimerUpdateWithDriver, ClientTimerUpdateWithoutDriver,
            ClientCantPriFire, ClientCantAltFire;
    }

    simulated function CalcWeaponFire()
    {
        Super.CalcWeaponFire()

        DualFireOffset*=-1;
    }

    event bool AttemptFire(Controller C, bool bAltFire)
    {
        local bool bCanFire;

            if(Role != ROLE_Authority || bForceCenterAim)
                    return False;

            if( !bAltFire && CanPriFire() )
                bCanFire = True;

            if( bAltFire && CanAltFire() )
                bCanFire = true;

            if( bCanFire )
            {
                    if (bCorrectAim)
                            WeaponFireRotation = AdjustAim(bAltFire);
                    if (Spread > 0)
                            WeaponFireRotation = rotator(vector(WeaponFireRotation) + VRand()*FRand()*Spread);

                    Instigator.MakeNoise(1.0);

                    if (bAltFire)
                    {
                            AltFire(C);
                    }
                    else
                    {
                        Fire(C);
                    }

                    AimLockReleaseTime = Level.TimeSeconds + FireCountdown * FireIntervalAimLock;
            }

            return bCanFire;
    }

    function class<Projectile> GetProjectileClass(bool bAltFire)
    {
        if( bAltFire )
            return GetSecondaryProjectileClass();
        else
            return GetPrimaryProjectileClass();
    }

    function class<Projectile> GetPrimaryProjectileClass()
    {
        return PrimaryProjectileClass;
    }

    function class<Projectile> GetSecondaryProjectileClass()
    {
        return SecondaryProjectileClass;
    }

    function SpawnProjectileNone(bool bAltFire)
    {
        if( bAltFire )
            SpawnProjectileNoneAltFire();
        else
            SpawnProjectileNonePriFire();
    }

    function SpawnProjectileNoneAltFire()
    {
    }

    function SpawnProjectileNonePriFire()
    {
    }

    function Projectile SpawnProjectileInit(Projectile P, bool bAltFire)
    {
        return P;
    }

    // You'll Probably Never Want To Super.Call() this when overriding
    function PlayFiringAnimations()
    {
        if (!Level.bDropDetail && Level.DetailMode != DM_Low)
        {
            if (DualFireOffset < 0)
                    PlayAnim('RightFire');
            else
                    PlayAnim('LeftFire');
        }
    }

    function Projectile SpawnProjectile(class<Projectile> ProjClass, bool bAltFire)
    {
            local Projectile P;
            local class<Projectile> ProClass;

            PlayFiringAnimations();

        ProClass = GetProjectileClass(bAltFire);

        // Get Current Client Weapon Rotation
        CalcWeaponFire();

        if( ProClass != none )
            P = Super.SpawnProjectile(ProClass, bAltFire);

        if( P == none )
        {
            SpawnProjectileNone(bAltFire);
            return none;
        }

        P.SetOwner(self);

        return SpawnProjectileInit(P, bAltFire);
    }

    simulated function WeaponInit()
    {
        LastPriFireTime=Level.TimeSeconds;
        LastAltFireTime=Level.TimeSeconds;
        bAwaitingPriRelease=false;
        bAwaitingAltRelease=false;
    }

    simulated function bool PriFireWaitingRelease()
    {
        return bAwaitingPriRelease && bShouldAwaitPriRelease;
    }

    simulated function bool AltFireWaitingRelease()
    {
        return bAwaitingAltRelease && bShouldAwaitAltRelease;
    }

    /////////////////////////////////////////////////////////
    // Entry Point Timer Functions, Called On Client OR Server
    simulated function PriFirePressed()
    {
        if( ShouldPriZoom() )
            StartZoom(false);

        ServerPriFirePressed();
    }

    simulated function PriFireReleased()
    {
        if( bDoPriZoom )
            EndZoom();

        ServerPriFireReleased();
    }

    simulated function PriFireInactive()
    {
        ServerPriFireInactive();
    }

    simulated function PriFireActive()
    {
        if( ShouldPriZoom() )
            DoZoom();

        ServerPriFireActive();
    }

    simulated function AltFirePressed()
    {
        if( ShouldAltZoom() )
            StartZoom(true);

        ServerAltFirePressed();
    }

    simulated function AltFireReleased()
    {
        if( bDoAltZoom )
            EndZoom();

        ServerAltFireReleased();
    }

    simulated function AltFireInactive()
    {
        ServerAltFireInactive();
    }

    simulated function AltFireActive()
    {
        if( ShouldAltZoom() )
            DoZoom();

        ServerAltFireActive();
    }

    simulated function TimerUpdateWithDriver()
    {
        ServerTimerUpdateWithDriver();
    }

    simulated function TimerUpdateWithoutDriver()
    {
        ServerTimerUpdateWithoutDriver();
    }
    // End Entry Point Timer Functions
    ////////////////////////////////////////

    function ServerAwaitRelease( bool bAltFire )
    {
        if( bAltFire )
            bAwaitingAltRelease=true;
        else
            bAwaitingPriRelease=true;
    }

    /////////////////////////////////////////////////
    // Zooming Functions
    //
    // Only One Zoom Feature Per Weapon
    simulated function StartZoom(bool bAltFire)
    {
        if( ZoomLevel != 0.0 )
        {
            RevertZoom();

            ServerAwaitRelease( bAltFire );
        }
        else
        {
            ZoomInit();
            DoZoom();
        }
    }

    simulated function ZoomInit()
    {
            bZooming=True;
    }

    simulated function RevertZoom()
    {
          EndZoom();
          ZoomLevel = 0.0;

          if( Instigator != none && Instigator.Controller != none && PlayerController(Instigator.Controller) != none )
                   PlayerController(Instigator.Controller).DesiredFOV = PlayerController(Instigator.Controller).DefaultFOV;
    }

    simulated function EndZoom()
    {
          bZooming=False;
    }

    simulated function bool IsZooming()
    {
        return bZooming;
    }

    simulated function DoZoom()
    {
        if( !IsZooming() )
            return;

        PreZoom();

        ZoomLevel += ZoomIncrement;

        if( 90.0 - ZoomLevel < ZoomMinFov )
                    ZoomLevel = 90 - ZoomMinFov;

            if( 90.0 - ZoomLevel > ZoomMaxFov )
                ZoomLevel = 90 - ZoomMaxFov;

        if( Instigator != none && Instigator.Controller != none && PlayerController(Instigator.Controller) != none )
              PlayerController(Instigator.Controller).DesiredFOV = FClamp(90.0 - ZoomLevel, 1, 170);

        PostZoom();
    }

    simulated function PreZoom()
    {
    }

    simulated function PostZoom()
    {
    }

    simulated function bool ShouldAltZoom()
    {
        return bDoAltZoom && !AltFireWaitingRelease();
    }

    simulated function bool ShouldPriZoom()
    {
        return bDoPriZoom && !PriFireWaitingRelease();
    }

    /////////////////////////////////////////
    // Begin Server Side Timer Functions
    // These Must Be Super.Called()
    // Or The Client Functions Won't Be Replicated
    function ServerPriFirePressed()
    {
        ServerTryPriFire();
            ClientPriFirePressed();
    }

    function ServerTryPriFire()
    {
        if( CanPriFire() )
                ServerPriFire();
            else
               ServerCantPriFire();
    }

    // This Is Not The Place For (House Keeping), use Inactive,
    // This is for specific thigns happening when the mouse is released
    // I.E. Fire On Release.
    function ServerPriFireReleased()
    {
            ClientPriFireReleased();
            ServerPriFireInactive();
    }

    function ServerPriFireInactive()
    {
        if( PriFireWaitingRelease() )
        {
            bAwaitingPriRelease=false;
        }

        ClientPriFireInactive();
    }

    function ServerPriFireActive()
    {
        if( bRepeatedPriFire )
            ServerTryPriFire();

            ClientPriFireActive();
    }

    /////////////////////////
    // Server Alt Fire Routines
    function ServerAltFirePressed()
    {
        ServerTryAltFire();
        ClientAltFirePressed();
    }

    function ServerTryAltFire()
    {
        if( CanAltFire() )
            ServerAltFire();
        else
            ServerCantAltFire();
    }

    function ServerAltFireReleased()
    {
        ClientAltFireReleased();
        ServerAltFireInactive();
    }

    function ServerAltFireInactive()
    {
        if( AltFireWaitingRelease() )
        {
            bAwaitingAltRelease=false;
        }

        ClientAltFireInactive();
    }

    function ServerAltFireActive()
    {
        if( bRepeatedAltFire )
            ServerTryAltFire();

        ClientAltFireActive();
    }

    function ServerTimerUpdateWithDriver()
    {
        ClientTimerUpdateWithDriver();
    }

    function ServerTimerUpdateWithoutDriver()
    {
        ClientTimerUpdateWithoutDriver();
    }
    // End Server Side Timer Functions
    //////////////////////////////////////////

    /////////////////////////////////////////////
    // Pri Fire Guts
    simulated function bool CanPriFire()
    {
        return (LastPriFireTime + FireInterval) <= Level.TimeSeconds && !PriFireWaitingRelease();
    }

    // Overriding Should Call Super After All Other Functions
    // Use ServerPostPriFire To Do Modifications After Projectile Exists
    function ServerPriFire()
    {
        LastPriFireTime=Level.TimeSeconds;

        if( bPriFireSpawnProjectile )
            SpawnProjectile(none, false);

        ServerPostPriFire();
    }

    function ServerCantPriFire()
    {
        ClientCantPriFire();
    }

    simulated function ClientCantPriFire()
    {
    }

    function ServerPostPriFire()
    {
    }

    ////////////////////////////////////////
    //Alt Fire Guts
    simulated function bool CanAltFire()
    {
        return (LastAltFireTime + AltFireInterval) <= Level.TimeSeconds && !AltFireWaitingRelease();
    }

    // Overriding Should Call super After All Other Commands
    // Use ServerPostAltFire To Do Modifications After Projectile Exists
    function ServerAltFire()
    {
        LastAltFireTime=Level.TimeSeconds;

        if( bAltFireSpawnProjectile )
            SpawnProjectile(none, true);

        ServerPostAltFire();
    }

    function ServerPostAltFire()
    {
    }

    function ServerCantAltFire()
    {
        ClientCantAltFire();
    }

    simulated function ClientCantAltFire()
    {
    }

    //////////////////////////////////////////
    // Begin Client Side Timer Functions
    simulated function ClientPriFirePressed()
    {
    }

    simulated function ClientPriFireReleased()
    {
    }

    simulated function ClientPriFireInactive()
    {
    }

    simulated function ClientPriFireActive()
    {
    }

    simulated function ClientAltFirePressed()
    {
    }

    simulated function ClientAltFireReleased()
    {
    }

    simulated function ClientAltFireInactive()
    {
    }

    simulated function ClientAltFireActive()
    {
    }

    simulated function ClientTimerUpdateWithDriver()
    {
    }

    simulated function ClientTimerUpdateWithoutDriver()
    {
    }
    // End Client Side Timer Functions
    //////////////////////////////////////

    simulated state ProjectileFireMode
    {
        simulated function BeginState()
        {
            super.BeginState();

            SetTimer(TimerUpdateFrequency,true);

            //Input Var Initializations
            bIsAltFiring = false;
            bIsPriFiring = false;

            // Zoom Init
            RevertZoom();

            WeaponInit();
        }

        simulated function EndState()
        {
            SetTimer(0.0, false);
            super.EndState();
        }

        // For Bot Support
        function Fire(Controller C)
        {
            PriFirePressed();
        }

        function AltFire(Controller C)
        {
                AltFirePressed();
        }

        simulated function Timer()
        {
            if( ROLE == ROLE_Authority )
                TimerUpdateWithoutDriver();

            // Re-Init If  We Are An Un-Powered Turret On The Server
            if( Role == ROLE_Authority && ONSStationaryWeaponPawn(Owner) != none &&
                    !ONSStationaryWeaponPawn(Owner).bPowered )
            {
                WeaponInit();
            }

            if( Instigator == none || Instigator.Controller == none )
                return;

            if( ROLE == ROLE_Authority )
                TimerUpdateWithDriver();

            if( !Instigator.IsLocallyControlled() )
                return;

            ///////////////////////////////////////////
            // Key Input Data Initilization

            bWasAltFiring = bIsAltFiring;
            bIsAltFiring = !(Instigator.Controller.bAltFire == 0);

            bWasPriFiring = bIsPriFiring;
            bIsPriFiring = !(Instigator.Controller.bFire == 0);

            //////////////////////////////////////////

            if( bIsPriFiring && !bWasPriFiring ) // Primary Fire Was Just Pressed
                    {
            //      log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Pri Fire Pressed");
                          PriFirePressed();
                    }
                    else
                    if( !bIsPriFiring && bWasPriFiring ) // Primary Fire Was Just Released
                    {
             //   log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Pri Fire Released");
                PriFireReleased();
                    }
                    else
            if( !bIsPriFiring )  // Code Executed When Primary Fire is Not Pressed
                    {
             //   log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Pri Fire Inactive");

                        PriFireInactive();
                    }
            else // Primary Fire Is Pressed
                {
             //   log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Pri Fire Active");

                PriFireActive();
            }

            if( bIsAltFiring && !bWasAltFiring )  // Alt Fire Was Just Pressed
                    {
                     //   log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Alt Fire Pressed");
                AltFirePressed();
                    }
                    else
                    if( !bIsAltFiring && bWasAltFiring )  // Alt Fire Was Just Released
                    {
                     //    log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Alt Fire Released");
                 AltFireReleased();
                    }
                    else
                    if( !bIsAltFiring ) // Code Executed When Alt Fire is Not Pressed
                    {
            //    log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Alt Fire Inactive");
                     AltFireInactive();
                    }
            else  // Alt Fire Is Pressed
                {
            //    log("["$Level.TimeSeconds@"] MTPBaseStationaryWeapon: Alt Fire Active");

                     AltFireActive();
            }
        }
    }

    defaultproperties
    {
         YawBone="TurretBase"
         PitchBone="Dummy01"
         PitchUpLimit=15000
         PitchDownLimit=52500
         WeaponFireAttachmentBone="TurretCockpit"
         GunnerAttachmentBone="TurretCockpit"
         WeaponFireOffset=25.000000
         DualFireOffset=75.000000
         bInstantRotation=True
         bInstantFire=False
         bDualIndependantTargeting=True
         AIInfo(0)=(bInstantHit=False,aimerror=750.000000)
         Mesh=SkeletalMesh'ONSWeapons-A.NewManualGun'
         CollisionRadius=50.000000
         CollisionHeight=70.000000
         TimerUpdateFrequency=0.01;
         bDoPriZoom=false
         bDoAltZoom=false
         bPriFireSpawnProjectile=false
         bAltFireSpawnProjectile=false
         bShouldAwaitPriRelease=false
         bShouldAwaitAltRelease=false
         bRepeatedPriFire=false
         bRepeatedAltFire=false
         ZoomMinFov=25.000
         ZoomMaxFov=120.0
         ZoomIncrement=0.5
         FireInterval=1.0
         AltFireInterval=0.0
         PrimaryProjectileClass=none
         SecondaryProjectileClass=none
    }

##### Views

- Legacy
- Discussion
- Current revision

##### Search