Minigun/Script
This is a reference to the Minigun code in case you can't understand the code. All the remarks you see in the code will be done by me. It's a good reference for various guns that fire rapidly and have charge-up times.
//============================================================================= // Minigun // This is the name of the weapon. //============================================================================= class Minigun extends Weapon //The class is the type of weapon, while the extends is used to refer the code to a specific type of actor config(user); // This says that there are variables here that get their values from the user.ini file. // The InterfaceContent.utx file contains all the icons for all the weapons. The following line loads the file so we can get to the icon for our minigun. #EXEC OBJ LOAD FILE=InterfaceContent.utx var float CurrentRoll; var float RollSpeed; //var float FireTime; var() xEmitter ShellCaseEmitter; var() vector AttachLoc; var() rotator AttachRot; var int CurrentMode; var() float GearRatio; var() float GearOffset; var() float Blend; //These are the variables used in the code simulated function PostBeginPlay() //Says to start code after play begins { Super.PostBeginPlay(); if ( Level.NetMode == NM_DedicatedServer ) return; ShellCaseEmitter = spawn(class'ShellSpewer'); if ( ShellCaseEmitter != None ) { ShellCaseEmitter.Trigger(Self, Instigator); AttachToBone(ShellCaseEmitter, 'shell'); } //This says if the ShellCaseEmitter variable is not zero then the minigun will create an emitter to expel the shells when you fire } function DropFrom(vector StartLocation) { local Ammunition AssaultAmmo; // This creates a local instance of Assault Rifle ammunition. local Weapon AssaultRifle; // This creates a local instance of an Assault Rifle. // Both of these will be used in the following lines, but will be "destroyed" when the function ends. Super.DropFrom(StartLocation); if ( (Instigator != None) && (Instigator.Health > 0) ) { AssaultAmmo = Ammunition(Instigator.FindInventoryType(class'MinigunAmmo')); if ( AssaultAmmo == None ) { AssaultAmmo = spawn(class'MinigunAmmo',Instigator); AssaultAmmo.GiveTo( Instigator, None ); } //This is the code to cause the ammo to be shared with the Assualt Rifle AssaultAmmo.AmmoAmount = 0; AssaultRifle = Weapon(Instigator.FindInventoryType(class'AssaultRifle')); if ( AssaultRifle != None ) AssaultRifle.Ammo[0] = AssaultAmmo; } } simulated function OutOfAmmo() { if ( !Instigator.IsLocallyControlled() || HasAmmo() ) return; Instigator.AmbientSound = None; DoAutoSwitch(); } //This says if a minigun runs out of ammo the weapon will autoswitch simulated function Destroyed() { if (ShellCaseEmitter != None) { ShellCaseEmitter.Destroy(); ShellCaseEmitter = None; } Super.Destroyed(); } BotFire() //Initiates this section of code when a bot fires. function bool BotFire(bool bFinished, optional name FiringMode) { local int newmode; local Controller C; C = Instigator.Controller; newMode = BestMode(); if ( newMode == 0 ) { C.bFire = 1; C.bAltFire = 0; } else { C.bFire = 0; C.bAltFire = 1; } if ( bFinished ) return true; if ( FireMode[BotMode].bIsFiring && (NewMode != BotMode) ) StopFire(BotMode); if ( !ReadyToFire(newMode) || ClientState != WS_ReadyToFire ) return false; BotMode = NewMode; StartFire(NewMode); return true; } //Allows the bots to change firing mode when using the minigun //This is the AI Interface function float GetAIRating() { return AIRating * FMin(Pawn(Owner).DamageScaling, 1.5); } BestMode() function byte BestMode() { local float EnemyDist; local bot B; B = Bot(Instigator.Controller); if ( (B == None) || (B.Enemy == None) ) return 0; if ( FireMode[0].bIsFiring ) return 0; else if ( FireMode[1].bIsFiring ) return 1; EnemyDist = VSize(B.Enemy.Location - Instigator.Location); if ( EnemyDist < 2000 ) return 0; return 1; } //This section is used to choose the best firing mode for the bots simulated function SpawnShells(float amountPerSec) { if(ShellCaseEmitter == None || !FirstPersonView()) return; if ( Bot(Instigator.Controller) != None ) { ShellCaseEmitter.Destroy(); return; } ShellCaseEmitter.mRegenRange[0] = amountPerSec; ShellCaseEmitter.mRegenRange[1] = amountPerSec; ShellCaseEmitter.Trigger(self, Instigator); } //This is the code for the amount of shells spawned per sec simulated function bool FirstPersonView() { return (Instigator.IsLocallyControlled() && (PlayerController(Instigator.Controller) != None) && !PlayerController(Instigator.Controller).bBehindView); } //This next section prevents the wrong animations from playing simulated function AnimEnd(int channel) { } // This is client side only: It updates the first person barrel rotation simulated function UpdateRoll(float dt, float speed, int mode) { local rotator r; if (Level.NetMode == NM_DedicatedServer) return; if (mode == CurrentMode) // to limit to one mode { // log(self$" updateroll (mode="$mode$") speed="$speed); RollSpeed = speed; CurrentRoll += dt*RollSpeed; CurrentRoll = CurrentRoll % 65536.f; r.Roll = int(CurrentRoll); SetBoneRotation('Bone Barrels', r, 0, Blend); r.Roll = GearOffset + r.Roll*GearRatio; SetBoneRotation('Bone gear', r, 0, Blend); } } simulated function bool StartFire(int mode) { local bool bStart; if ( !MinigunFire(FireMode[0]).IsIdle() || !MinigunFire(FireMode[1]).IsIdle() ) return false; bStart = Super.StartFire(mode); if (bStart) FireMode[mode].StartFiring(); return bStart; } // If this function returns True, the weapon will start firing, if it returns False, it won't. // This section allows fire modes to return to idle on weapon switch (simulated function DetachFromPawn(Pawn P) { ReturnToIdle(); Super.DetachFromPawn(P); } simulated function bool PutDown() { ReturnToIdle(); return Super.PutDown(); } simulated function ReturnToIdle() { local int mode; for (mode=0; mode<NUM_FIRE_MODES; mode++) { if (FireMode[mode] != None) { FireMode[mode].GotoState('Idle'); } } } defaultproperties // These are the default properties of each variable. Some were created at the top of this file, others are inherited from the weapon's parent class. { AttachLoc=(X=-77.000000,Y=6.000000,Z=4.000000) // Where the model attachs AttachRot=(Pitch=22000,Yaw=-16384) // The rotation it is at GearRatio=-2.370000 Blend=1.000000 FireModeClass(0)=Class'XWeapons.MinigunFire' // Firing mode 1 (Primary) FireModeClass(1)=Class'XWeapons.MinigunAltFire' // Firing mode 2 (Alt/Secondary) PutDownAnim="PutDown" SelectSound=Sound'WeaponSounds.Minigun.SwitchToMiniGun' // The Sound that is played when you switch to this weapon. SelectForce="SwitchToMiniGun" AIRating=0.710000 CurrentRating=0.710000 EffectOffset=(X=100.000000,Y=18.000000,Z=-16.000000) DisplayFOV=60.000000 Priority=7 DefaultPriority=7 HudColor=(B=255) SmallViewOffset=(X=8.000000,Y=1.000000,Z=-2.000000) CenteredOffsetY=-6.000000 CenteredRoll=0 CenteredYaw=-500 InventoryGroup=6 // The inventory group used (i.e. the number you press to reach the gun) PickupClass=Class'XWeapons.MinigunPickup' // The MinigunPickup class defines the weapon the way it sits on the ground. PlayerViewOffset=(X=2.000000,Y=-1.000000) PlayerViewPivot=(Yaw=500) BobDamping=2.250000 AttachmentClass=Class'XWeapons.MinigunAttachment' IconMaterial=Texture'InterfaceContent.HUD.SkinA' IconCoords=(X1=200,Y1=372,X2=321,Y2=462) ItemName="Minigun" // The name! LightType=LT_Pulse // Any of the excellent lighting tutorials LightEffect=LE_NonIncidence // at the Wiki and around the web can LightBrightness=150.000000 // detail what these light properties LightRadius=4.000000 // are. They are the same properties that LightHue=30 // you would set on a light on your map. LightSaturation=150 // If you look closely on a dark map you'll LightPeriod=3 // notice that all the weapons actually give off a pulse light. Mesh=SkeletalMesh'Weapons.Minigun_1st' // The skeletal mesh of the model DrawScale=0.400000 UV2Texture=Shader'XGameShaders.WeaponShaders.WeaponEnvShader' SoundRadius=400.000000 // The radius of the minigun sounds }