Legacy:ONSWeapon
Summary
This is the base class of all of the vehicle and turret weapons found in the Onslaught Gametype.
Something to note about all ONSWeapon sub-classes is that they only can fire when in one of the firing states. InstantFireMode or ProjectileFireMode. This takes place through the ONSWeapon property bInstantFire which is checked in ONSWeapon's PostNetBeginPlay() function to goto one of the two states.
Properties
Weapon Bone Rotation System
- var() name YawBone
- var() float YawStartConstraint
- var() float YawEndConstraint
- var float YawConstraintDelta
- var() name PitchBone
- var() int PitchUpLimit
- var() int PitchDownLimit
- var rotator CurrentAim
- var vector WeaponFireLocation
- written by CalcWeaponFire
- var rotator WeaponFireRotation
- written by CalcWeaponFire
- var() name WeaponFireAttachmentBone
- var() name GunnerAttachmentBone
- var() float WeaponFireOffset
- var() float DualFireOffset
- If your weapon has twin muzzles, e.g. Energy Turret and Raptor, this causes shots to alternate from each barrel.
- var() vector WeaponOffset
- var() rotator LastRotation
- var() float RotationsPerSecond
Bools
- var bool bInstant Rotation
- //NOTE: Gradual rotation via RotationsPerSecond still used for non-owning net clients to smooth rotation changes
- var bool bActive
- var() bool bInstantFire
- As Noted Above specifies InstantFireState instead of ProjectileFireState for the generic weapon firing code to use.
- var() bool bDualIndependantTargeting
- // When using a DualFireOffset each shot will be independantly targeted at the crosshair
- var bool bShowChargingBar
- Bender Style?
- var bool bCallInstigatorPostRender
- //if Instigator exists, during this actor's native PostRender(), call Instigator->PostRender() (used when weapon is visible but owner is bHidden)
- var bool bForceCenterAim
- Not Used on The Goliath?
- var() bool bAimable
- Determines whether the weapon can be physically turned by the player (i.e. turret rotation or gun barrel pitch).
- var bool bDoOffsetTrace
- //trace from outside vehicle's collision back towards weapon to determine firing offset
Probably Another Goliathy Type Feature
- var() bool bAmbientFireSound
- var() bool bAmbientAltFireSound
- var() bool bInheritVelocity
- var bool bIsAltFire
- var bool bIsRepeatingFF
- var() bool bReflective
- Can be reflected by shield gun shield?
- var const bool bCorrectAim
- // output variable - set natively - means gun can hit what controller is aiming at
Aiming
- var() float FireIntervalAimLock
- //fraction of FireInterval/AltFireInterval during which you can't move the gun
- var float AimLockReleaseTime
- //when this time is reached gun can move again
- var vector CurrentHitLocation
- var float Spread
- var float AimTraceRange
Impact/Damage
- var vector LastHitLocation
- var byte FlashCount
- var byte OldFlashCount
- var byte HitCount
- var byte OldHitCount
Team Skins
- var byte Team
- var() Material RedSkin
- Var() Material BlueSkin
Timing
- var() float FireInterval, AltFireInterval
- var float FireCountDown
Effects
- var() class<Emitter> FlashEmitterClass
- var Emitter FlashEmitter
- var() class<Emitter> EffectEmitterClass
- var Emitter EffectEmitter
- var() class<ONSWeaponAmbientEmitter> AmbientEffectEmitterClass
- var ONSWeaponAmbientEmitter AmbientEffectEmitter
Sound
- var() sound FireSoundClass
- var() float FireSoundVolume
- var() float FireSoundRadius
- var() float FireSoundPitch
- var() sound AltFireSoundClass
- var() float AltFireSoundVolume
- var() float AltFireSoundRadius
- var() float AltFireSoundPitch
- Why ISN'T this here? :0
- var() float AmbientSoundScaling
Force Feedback
- var() string FireForce
- var() string AltFireForce
Instant Fire Stuff
- var class<DamageType> DamageType
- var int DamageMin, DamageMax
- Instant Hits work by applying damage as RealDamage = DamageMin + Rand(DamageMax-DamageMin)
- var float TraceRange
- var float Momentum
Projectile Fire Stuff
- var() class<Projectile> ProjectileClass
- var() class<Projectile> AltFireProjectileClass
- var array<Projectile> Projectiles
- //ignore these when doing third person aiming trace (only necessary if projectiles fired have bProjTarget==true)
Camera Shakes
- var() vector ShakeRotMag
- // how far to rot view
- var() vector ShakeRotRate
- // how fast to rot view
- var() float ShakeRotTime
- // how much time to rot the instigator's view
- var() vector ShakeOffsetMag
- // max view offset vertically
- var() vector ShakeOffsetRate
- // how fast to offset view vertically
- var() float ShakeOffsetTime
- // how much time to offset view
AI
ONSWeapon defines the struct ONSWeaponAIInfo
- var ONSWeaponAIInfo AIInfo[2]
- varFireProperties SavedFireProperties[2]
DEBUGGING
- var string DebugInfo
Replication
I am still pretty lost when it comes to replication. An explanation of what this says would be nice though.
<uscript> replication {
reliable if (bNetDirty && !bNetOwner && Role == ROLE_Authority) CurrentHitLocation, FlashCount; reliable if (bNetDirty && Role == ROLE_Authority) HitCount, LastHitLocation, bActive, bForceCenterAim, bCallInstigatorPostRender, Team;
} </uscript>
Functions
- native function int LimitPitch(int Pitch, rotator ForwardRotation, optional int WeaponYaw)
- simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos)
- This will draw the state of bActive, bCorrectAim and the DebugInfo String :
- simulated function PostBeginPlay()
-
- Calculate YawConstraintDelta
- Setup Drawing of the Charging Bar
- Apply Berserk Fire Modifier If APplicable?
- simulated function PostNetBeginPlay()
-
- Sets the weapon into a state, either InstantFireMode if bInstantFire == true or ProjectileFireMode
- InitEffect
- Super()
- simulated function InitEffects()
- Attaches FlashEmitterClass and AmbientEffectEmitterClass to their locations based on WeaponFireAttachmentBone if they are != none
- simulated function SetGRI(GameReplicationInfo GRI)
- simulated function SetFireRateModifier(float Modifier)
- function SpawnHitEffects(actor HitActor, vector HitLocation, vector HitNormal )
- EMPTY
- simulated event ClientSpawnHitEffects()
- simulated function ShakeView()
- If the person using our ONSWeapon is a player controller call WeaponShakeView(ShakeRotMag, ShakeRotRate, SHakeRotTime, ShakeOffsetMag, ShakeOffsetRate, ShakeOffsetTime)
- simulated function ClientStartFire(Controller C, bool bAltFire)
- //ClientStartFire() and ClientStopFire() are only called for the client that owns the weapon (and not at all for bots)
- This is where force feedback is activated and OwnerEffects() is called
- simulated function ClientStopFire(Controller C, bool bWasAltFire)
- Stops Force Feedback and our AmbientEffectEmitter if it exists
- simulated function ClientPlayForceFeedback( String EffectName )
- Verify It's a Valid PlayerController And Get TO IT
- simulated function StopForceFeedback( String EffectName )
- Verify It's a Valid PlayerController and Get TO IT
- simulated event OwnerEffects()
- //do effects (muzzle flash, force feedback, etc) immediately for the weapon's owner (don't wait for replication)
- event bool AttemptFire(Controller C, bool bAltFire)
- Fire if we can (This means FireCountdown is <= 0)
- If we can fire, we will call Fire() or AltFire()
- If we can fire we will set FireCountdown to either FireInterval or AltFireInterval
- If we can fire aimlock will be applied
- If we can fire, we will return true
- Aimlock is implemented here as AimLockReleaseTime = Level.TimeSeconds + FireCountDown*FireIntervalAimLock
- function rotator AdjustAim(bool bAltFire)
- This tells a bot how to line up a shot
- function byte BestMode()
- //AI: return the best fire mode for the situation
- function Fire( Controller C )
- This Non-State Version just writes a friendly message to the logs
- function AltFire( Controller C )
- This Non-State Version just writes a friendly message to the logs
- function bool CanAttack(Actor Other)
- // return false if out of range, can't see target, etc.
- simulated function float MaxRange()
- Gives a max distance for bots to use when deciding how to use a weapon.
- function Projectile SpawnProjectile(class<Projectile> ProjClass, bool bAltFire)
-
- First thing this function does is determine the spawn location, this can either be WeaponFireLocation or is computed through a collision trace if bDoOffsetTrace == true
- Next the projectile is spawned, if bInheritVelocity == true then the Projectile.Velocity = Instigator.Velocity
- Firing Noises are played using FireClass/AltFireClass and FireSoundRadius/AltFireSoundRadius
- As i look at the code here, i notice that AltFireSoundVolume is not used here but rather FireSoundVolume/255.0 is used in both the primary and secondary firing modes.
- The projectile that was spawned is returned
- function CeaseFire(Controller C)
- Stops ambient sounds being played and resets Flash/Hit Count
- simulated event FlashMuzzleFlash()
- simulated function Destroyed()
- Cleans up Effects (DestroyEffects()) and calls SUper()
- simulated function DestroyEffects()
- simulated function SetTeam( byte T )
- Sets the current Skin to the proper teams skin
- simulated function SimulateTraceFire( out vector Start, out Rotator Dir, out vector HitLocation, out vector HitNormal )
- Client Side Trace, does NOT apply damage, Does predict hit locations
- function TraceFire( Vector Start, rotator dir )
- Does a trace and applies damage
- function SpawnBeamEffect(Vector Start, Rotator Dir, Vector HitLocation, Vector HitNormal, int ReflectNum)
- EMPTY
- simulated function CalcWeaponFire()
- Calculates the exact spot the weapon is firing From based on rotation/coords/bDualIndependentTargeting, and writes them to WeaponFireLocation and WeaponFireRotation
- simulated function float ChargeBar()
- static function StaticPrecache( LevelInfo L )
States
InstantFireMode
- function Fire(Controller C)
- Apply Some Effects and Call TraceFire to do damage
- function AltFire(Controller C)
- EMPTY
- simulated event ClientSpawnHitEffects()
- Determines the Hit Location and Calls SpawnHitEffects()
- simulated function SpawnHitEffects( actor HitActor, vector HitLocation, vector HitNormal )
- Actually spawns hit effects on a client
ProjectileFireMode
- function Fire(Controller C)
- <uscript>SpawnProjectile(ProjectileClass, false)</uscript>
- function AltFire( Controller C )
- <uscript> if (AltFireProjectileClass == None)
Fire(C); else SpawnProjectile(AltFireProjectileClass, True);</uscript>
Default Properties
<uscript> defaultproperties {
YawEndConstraint=65535.000000 PitchUpLimit=5000 PitchDownLimit=60000 RotationsPerSecond=0.750000 bAimable=True bCorrectAim=True FireInterval=0.500000 FireSoundVolume=160.000000 FireSoundRadius=300.000000 FireSoundPitch=1.000000 AltFireSoundVolume=160.000000 AltFireSoundRadius=300.000000 AmbientSoundScaling=1.000000 DamageType=XWeapons.DamTypeMinigunBullet DamageMin=6 DamageMax=6 TraceRange=10000.000000 Momentum=1.000000 AIInfo(0)=(aimerror=600.000000,RefireRate=0.900000) AIInfo(1)=(aimerror=600.000000,RefireRate=0.900000) DrawType=DT_Mesh bIgnoreEncroachers=True bReplicateInstigator=True RemoteRole=ROLE_SimulatedProxy NetUpdateFrequency=5.000000 SoundVolume=255 SoundRadius=100.000000 bBlockZeroExtentTraces=False bBlockNonZeroExtentTraces=False bNoRepMesh=True
} </uscript>
Discussion
Sweavo: anyone know how to tell when the player has released the fire button? AFAICT CeaseWeaponFire doesn't happen until after the FireInterval expires...?