There is no spoon
Legacy:Configurable Weapon Lockers
Configurable Weapon Lockers are placeable actors designed for UT3.
Configurable Weapon Lockers are meant to address two main issues:
1. Because Epic decided that Weapons Throw was an "exploit" in UT3, Configurable Weapon Lockers are meant to replace any weapon factories in a map. Configurable Weapon Lockers can allow a player to restock ammunition as weapon pickups (with weaponstay on) did in previous UT games.
2. UT3's stock weapon lockers automatically fill any weapons they give to the player up to a defined "Locker" ammo amount, which cannot be adjusted. Configurable Weapon Lockers instead fill a weapon up only to the normal pickup amount, and a mapper can specify if they would like the locker to also grant additional ammunition over that amount.
I would like to add some more features to Configurable Weapon Lockers to make them even better. In particular, I would like to add team-specific cWeapon Lockers, and (regarding function #1) a check to see if the player has the designated weapon currently drawn before adding additional ammunition. Possibly more features as requested.
/*************************************************************** * UTWeaponLockerConfigurable * By Wail of Suicide * Contact: WailofSuicide@gmail.com ***************************************************************/ class UTWeaponLockerConfigurable extends UTWeaponLocker_Content; /** NEW */ /** Configurable setting to allow locker-specific ammo amounts to be specified */ var() array<int> LockerConfiguredAmmoValue; var() int DelayPickupTime; /** After a player touches the Locker, he must wait this length of time before being able to touch it again */ var() bool bAlwaysOn; /** There is no delay between the player touching the Locker and being able to restore ammo at this locker*/ var() bool bRequireAmmoToRefill; /** In order to gain more ammunition for a weapon, that weapon must have greater than zero ammunition */ var() bool bRequireDrawnWeapon; /** In order to gain more ammunition for a weapon, the player must have that weapon currently equipped/drawn */ function bool AddCustomer(Pawn P) { local int i; local PawnToucher PT; if ( UTInventoryManager(P.InvManager) == None ) return false; if ( Customers.Length > 0 ) for ( i=0; i<Customers.Length; i++ ) { if ( Customers[i].NextTouchTime < WorldInfo.TimeSeconds ) { if ( Customers[i].P == P ) { /** If AlwaysOn then NextTouchTime has no delay */ if (bAlwaysOn) Customers[i].NextTouchTime = WorldInfo.TimeSeconds; else Customers[i].NextTouchTime = WorldInfo.TimeSeconds + DelayPickupTime; return true; } Customers.Remove(i,1); i--; } else if ( Customers[i].P == P ) return false; } PT.P = P; /** If AlwaysOn then NextTouchTime has no delay */ if (bAlwaysOn) PT.NextTouchTime = WorldInfo.TimeSeconds; else PT.NextTouchTime = WorldInfo.TimeSeconds + DelayPickupTime; Customers[Customers.Length] = PT; return true; } auto state LockerPickup { simulated function ShowActive() { bIsActive = true; AmbientEffect.SetTemplate(ActiveEffectTemplate); NextProximityCheckTime = 0; } simulated function NotifyLocalPlayerDead(PlayerController PC) { ShowActive(); } // When touched by an actor. simulated event Touch( actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal ) { local int i; local UTWeapon Copy; local Pawn Recipient; // If touched by a player pawn, let him pick this up. if( ValidTouch(Other) ) { Recipient = Pawn(Other); if ( (Recipient.Controller != None && Recipient.Controller.IsLocalPlayerController()) || (Recipient.DrivenVehicle != None && Recipient.DrivenVehicle.Controller != None && Recipient.DrivenVehicle.Controller.IsLocalPlayerController()) ) { if ( bIsActive ) { if ( !bAlwaysOn ) { /** If not AlwaysOn then the locker is disabled for the configured delay time */ ShowHidden(); SetTimer(DelayPickupTime,false,'ShowActive'); } } } if ( Role < ROLE_Authority ) return; if ( !AddCustomer(Recipient) ) return; // We need to adjust this part of the function to look for the Configurable Locker Ammo rather than in the Weapon's LockerAmmoCount // If no corresponding ammo value is defined in the locker for the weapon, default to the minimum pickup ammo (rather than minimum locker pickup ammo) for ( i=0; i<Weapons.Length; i++ ) { InventoryType = Weapons[i].WeaponClass< SEMI > Copy = UTWeapon(UTInventoryManager(Recipient.InvManager).HasInventoryOfClass(InventoryType)); if ( Copy != None ) { //If we've configured an ammo value in the locker, check if it is greater than the player's current ammo for that weapon, if so, fill the difference to the weapon's ammo if ( LockerConfiguredAmmoValue[i] != 0 && LockerConfiguredAmmoValue[i] - Copy.AmmoCount > 0 ) { if ( bRequireAmmoToRefill && Copy.AmmoCount <= 0 ) return; Copy.AddAmmo(LockerConfiguredAmmoValue[i] - Copy.AmmoCount); } //If the player's current ammo is less than the default minimum for that weapon, then fill the difference else if (Copy.default.AmmoCount - Copy.AmmoCount > 0) Copy.AddAmmo(Copy.default.AmmoCount - Copy.AmmoCount); Copy.AnnouncePickup(Recipient); } else if (WorldInfo.Game.PickupQuery(Recipient, InventoryType, self)) { Copy = UTWeapon(spawn(InventoryType)); if ( Copy != None ) { Copy.GiveTo(Recipient); Copy.AnnouncePickup(Recipient); //When giving the weapon to the player, check if the locker ammo value has been configured, if so, fill the difference between the locker value and the weapon's initial ammo if ( LockerConfiguredAmmoValue[i] != 0 && LockerConfiguredAmmoValue[i]- Copy.Default.AmmoCount > 0 ) Copy.AddAmmo(LockerConfiguredAmmoValue[i] - Copy.Default.AmmoCount); } else LogInternal(self$" failed to spawn "$inventorytype); } } } } simulated event BeginState(name PreviousStateName) { Super.BeginState(PreviousStateName); ShowActive(); } } State Disabled { simulated function BeginState(name PreviousStateName) { Super.BeginState(PreviousStateName); ShowHidden(); } } defaultproperties { DelayPickupTime=30 bRequireAmmoToRefill=True bAlwaysOn=True Begin Object Class=UTParticleSystemComponent Name=ParticleSystem0 ObjName=ParticleSystem0 Archetype=UTParticleSystemComponent'UTGameContent.Default__UTWeaponLocker_Content:ParticleSystem0' ObjectArchetype=UTParticleSystemComponent'UTGameContent.Default__UTWeaponLocker_Content:ParticleSystem0' End Object AmbientEffect=ParticleSystem0 Begin Object Class=UTParticleSystemComponent Name=ParticleSystem1 ObjName=ParticleSystem1 Archetype=UTParticleSystemComponent'UTGameContent.Default__UTWeaponLocker_Content:ParticleSystem1' ObjectArchetype=UTParticleSystemComponent'UTGameContent.Default__UTWeaponLocker_Content:ParticleSystem1' End Object ProximityEffect=ParticleSystem1 Begin Object Class=DynamicLightEnvironmentComponent Name=PickupLightEnvironment ObjName=PickupLightEnvironment Archetype=DynamicLightEnvironmentComponent'UTGameContent.Default__UTWeaponLocker_Content:PickupLightEnvironment' ObjectArchetype=DynamicLightEnvironmentComponent'UTGameContent.Default__UTWeaponLocker_Content:PickupLightEnvironment' End Object LightEnvironment=PickupLightEnvironment Begin Object Class=CylinderComponent Name=CollisionCylinder ObjName=CollisionCylinder Archetype=CylinderComponent'UTGameContent.Default__UTWeaponLocker_Content:CollisionCylinder' ObjectArchetype=CylinderComponent'UTGameContent.Default__UTWeaponLocker_Content:CollisionCylinder' End Object CylinderComponent=CollisionCylinder Components(0)=CollisionCylinder Begin Object Class=PathRenderingComponent Name=PathRenderer ObjName=PathRenderer Archetype=PathRenderingComponent'UTGameContent.Default__UTWeaponLocker_Content:PathRenderer' ObjectArchetype=PathRenderingComponent'UTGameContent.Default__UTWeaponLocker_Content:PathRenderer' End Object Components(1)=PathRenderer Components(2)=PickupLightEnvironment Begin Object Class=StaticMeshComponent Name=BaseMeshComp ObjName=BaseMeshComp Archetype=StaticMeshComponent'UTGameContent.Default__UTWeaponLocker_Content:BaseMeshComp' ObjectArchetype=StaticMeshComponent'UTGameContent.Default__UTWeaponLocker_Content:BaseMeshComp' End Object Components(3)=BaseMeshComp Components(4)=ParticleSystem0 Components(5)=ParticleSystem1 CollisionComponent=CollisionCylinder Name="Default__UTWeaponLockerConfigurable" ObjectArchetype=UTWeaponLocker_Content'UTGameContent.Default__UTWeaponLocker_Content' }