Files
UT99-Mod-NIUT/Classes/NIUTMutator.uc
2026-01-27 00:46:55 +00:00

1718 lines
55 KiB
Ucode

//=============================================================================
// NIUTMutator.
//=============================================================================
class NIUTMutator extends Mutator config(NIUT);
/*=============================================================================
Mutator for NIUT (No Item Unreal Tournament).
===============================================================================
Author: Mike Fox (a.k.a. ArtfulDodger)
Contact: mfox@legendent.com
URL: www.planetunreal.com/niu
===============================================================================
tbd:
Check zone before healing (shouldn't heal if drowning, in lava etc.).
===============================================================================
Version: 1.26 - chacha
Created: 27/01/26
+Integrate with 469e
+Code cleaning
===============================================================================
Version: 1.25 - chacha
Created: 26/08/25
+Fix random no weapon when join (ugly workaound... I'd like to rewrite this mod)
+Code cleaning
===============================================================================
Version: 1.24
Created: 02/05/00
+Made NIUT work better with other mutators.
+Derive from Mutator instead of Arena so it can be used with other Arena
mutators (e.g. grapple hook mod). This messes up Last Man Standing a bit
because it only keeps ammo in the level if there is an Arena mutator
being used. The work-around is to either have ammo auto-increment or use
any arena mutator (e.g. the grappling hook mod) to force the ammo to
stay (I don't think there is another way -- the LastManStanding Game
type should really be a bit more mutator friendly). I've also created a
dummy arena mutator (DummyArenaMutator) for this purpose.
+The good news is that LastManStanding now works with exactly the
specified weapons, so you can have a Redeemer + super shock rifle
Last Man Standing match. About the only thing that doesn't work is
the fact that the weapons are always given their full complement of
ammo initially instead of the InitialSettings that NIUT specifies. There
doesn't seem to be an easy workaround to this and I don't think its a
big deal, so I probably won't look into it.
+NIUT no longer strips anything but "known" weapons from pawns so it doesn't
interfere with stuff that other mutators want to give them. Each time a
pawn (player / bot) joins the game or respawns, any "known" weapons in the
pawn's inventory at that point are removed. This is also done when cycling
weapons and when the current weapon changes. The list of "known" weapons includes
all the UT and Unreal I weapons currently. If someone adds a new weapon
(e.g. the BattleAxe) and gives this to players, it will *not* be filtered
out by default. To have the new weapon behave just like other weapons add
it to the ExtraWeaponClassStrings list. This means that a grapple (for
example) which has a class derived from weapon should not be affected by
having the NIUT mutator loaded.
+CheckReplacement also only strips out known weapons (unless bForceWeaponSpawn
is set internally.
+Fix for conflict between Low Gravity and NIUT mutators (Low Gravity was
forcing jumpboots to be stripped out even if NIUT was set up to use these).
Solution: have AlwaysKeep() return true for jumpboots.
+Fix for accessed None warnings in RateSelf (give ammo before putting into
Pawn's inventory etc.).
===============================================================================
Version: 1.23
Created: 01/28/00
+Added UI support for specifying NIUT settings through Mod menu.
+bAllWeapons -> !bCycleWeapons
+WeaponClassStrings -> ExtraWeaponClassStrings (support for new weapons not
already in UT).
+Can specify max ammo that any weapon can carry (e.g. limit Redeemer to only
carrying 1 warhead at a time).
+Added MaxHealth option for auto-incremented health (5000 with Redeemer is fun).
+Added StartHealth option to control health that pawns start with.
===============================================================================
Version: 1.21
Created: 01/04/00
+Made it possible to specify how much ammo should be given per second (ammo is
still incremented on each TimeBetweenAmmoIncrements).
+Added InitialAmmoXXX settings to specify how much ammo weapons should have
when given to players (bots). Setting this to 0 means that the weapon will
have no ammo (and won't be available until ammo is found/given to the player).
+Can actually give more ammo to a weapon that it normally allows (e.g. can
start out with redeemers with 99 warheads) and this becomes the new maximum
for the weapon.
+Tweaked default ammo rates for all weapons.
===============================================================================
Version: 1.20
Created: 12/21/99
+If bCycleWeapons is false players get all weapons specified in niut.ini and
ammo auto-increments -- pickups are health vials.
+If TimeBetweenAmmoIncrements is > 0.0, ammo auto-increments by 1 unit every N
seconds where N is determined by settings in niut.ini. Pickups are health
vials.
+Several optimizations (replace ForEach AllActors with, e.g. iterating PawnList
where possible.
===============================================================================
Version: 1.11
Created: 12/09/99
+Fix for translocator getting stripped out in games where it should be kept.
===============================================================================
Version: 1.10
Created: 12/08/99
+Fix for Redeemer ammo not working. TBD: how will UT release handle this --
currently ammo class has no mesh and gives 0 ammo. Change was to make ammo
a sprite and to give it 1 charge (update -- will stick with this approach
for NIUT 1.10).
+Change to support UnrealI and UnrealShare weapons and WeaponPowerUp (UT
normally replaces these with UT equivalents or filters them out).
+When dispersion pistol is in use, all pickups in the level are turned into
powerups so you can upgrade the pistol.
+Don't allow jumpboots, invisibility, damage amplifier to run out before their
time is up (probably no one will even notice this change).
+Added logging in PreBeginPlay (number of weapons) and log info if no weapons
found.
+Added logging each time the weapon is changed, including the number of (real)
players in the game.
+Default to just 1 weapon in slot 0 of the WeaponClassStrings -- rocket launcher
so that you don't have to override a pile of unused slots if you have < N
weapons.
+Default time between weapon switches is now 75 secs. Might help to avoid server
crashes which can occur when many objects created and destroyed before a level
ends.
+Don't zap searchlights (darkmatch support).
+Only play sounds through playerpawns (not bots).
+Weapon switch sound shouldn't get overridden as much now.
===============================================================================
Version: 1.00
Created: 11/05/99
+Weapon changes every MinTimeBetweenWeaponSwitches..MaxTimeBetweenWeaponSwitches
secs instead of every TimeBetweenWeaponSwitches secs.
+Server automatically increments health of all players by HealthIncrementRate
units per second.
+Option to randomly give everyone jump boots, invisibility, power amplifier.
===============================================================================
Version: 0.99
Created: 11/01/99
+Everyone plays with the same weapon at all times.
+Current weapon is chosen from a configurable list of weapons and
should support any Weapon-derived classes, even non-UT weapons.
+Current weapon changes every TimeBetweenWeaponSwitches.
+Weapons are selected randomly/sequentially (bRandomWeapons=true/false).
+If weapons are selected randomly can force all weapons to be used at least
once before restarting the selection process (bUseAllWeapons=true).
+Replaces all pickup items in the level with ammo for the current weapon. If
the current weapon doesn't require ammo, uses health vials. Flags, runes
etc. and the translocator aren't affected.
+Plays a warning sound just before weapon is changed (WarningSound).
+To have some weapons used more frequently that others, just put them
in WeaponClassStrings more than once.
===============================================================================
Notes:
+Doesn't work with double enforcers special case -- single only
+Unreal I weapons don't fire for clients so can only be used against bots in a
standalone (non-server) game.
=============================================================================*/
var() config bool bRandomWeapons; // (true): true ==> weapons selected randomly, false ==> weapons cycled sequentially
var() config bool bUseAllWeapons; // (true): true ==> if bWeaponsRandom is true, all weapons used once per cycle
var() config bool bCycleWeapons; // (true): false ==> players get all weapons in weapons list with auto-incrementing ammo
// weapons
var() config bool bUseChainSaw; // (false)
var() config bool bUseEnforcer; // (false)
var() config bool bUseImpactHammer; // (false)
var() config bool bUseMiniGun; // (false)
var() config bool bUsePulseGun; // (false)
var() config bool bUseRipper; // (false)
var() config bool bUseShockRifle; // (false)
var() config bool bUseSniperRifle; // (false)
var() config bool bUseSuperShockRifle; // (false)
var() config bool bUseBioRifle; // (false)
var() config bool bUseRocketLauncher; // (false)
var() config bool bUseFlakCannon; // (false)
var() config bool bUseRedeemer; // (false)
var() config bool bUseUnrealIFlakCannon; // (false)
var() config bool bUseUnrealIGESBioRifle; // (false)
var() config bool bUseUnrealIMinigun; // (false)
var() config bool bUseUnrealIRazorjack; // (false)
var() config bool bUseUnrealIRifle; // (false)
var() config bool bUseUnrealIASMD; // (false)
var() config bool bUseUnrealIAutoMag; // (false)
var() config bool bUseUnrealIDispersionPistol; // (false)
var() config bool bUseUnrealIEightball; // (false)
var() config bool bUseUnrealIStinger; // (false)
var() config string ExtraWeaponClassStrings[32]; // list of weapons to use (for adding weapons not in UT / Unreal I)
var() config float TimeRecheck; // (2): weapon check ugly workaround to force player to have a weapon
var() config float TimeBetweenWeaponSwitchesMin; // (45): min secs between weapon switches
var() config float TimeBetweenWeaponSwitchesMax; // (45): max secs between weapon switches
var() config float TimeBetweenAmmoIncrements; // (0.0): >0.0 ==> auto-increment ammo at this rate
var() config Sound WarningSound; // (UTSuperHeal): sound to use for "about to switch" warning
var() config int WarningSoundRepeats; // (3): # times to repeat WarningSound
var() config Sound HealthIncrementSound; // (None): sound to play when incrementing player's health
var() config int HealthIncrementAmount; // (0): rate at which health of players is incremented
var() config int StartHealth; // (100): health that pawns start out with
var() config int MaxHealth; // (100): max that health can be auto-incremented to
var() config float TimeBetweenHealthIncrements; // (5): secs between health updates if HealthIncrementRate >= 1
var() config float InvisibilityDelayMin; // (0.0): min time to wait before giving everyone invisibility
var() config float InvisibilityDelayMax; // (0.0): max time to wait before giving everyone invisibility
var() config float InvisibilityDurationMin; // (0.0): min time to wait before giving everyone invisibility
var() config float InvisibilityDurationMax; // (0.0): max time to wait before giving everyone invisibility
var() config float DamageAmplifierDelayMin; // (0.0): min time to wait before giving everyone damage amplifier
var() config float DamageAmplifierDelayMax; // (0.0): max time to wait before giving everyone damage amplifier
var() config float DamageAmplifierDurationMin; // (0.0): min time to wait before giving everyone damage amplifier
var() config float DamageAmplifierDurationMax; // (0.0): max time to wait before giving everyone damage amplifier
var() config float JumpBootsDelayMin; // (0.0): min time to wait before giving everyone jump boots
var() config float JumpBootsDelayMax; // (0.0): max time to wait before giving everyone jump boots
var() config float JumpBootsDurationMin; // (0.0): min time to wait before giving everyone jump boots
var() config float JumpBootsDurationMax; // (0.0): max time to wait before giving everyone jump boots
// ammo incrementing (number of TimeBetweenAmmoIncrements before ammo is incremented by 1)
var() config int InitialRedeemerAmmo;
var() config int InitialRocketAmmo;
var() config int InitialFlakAmmo;
var() config int InitialShockAmmo;
var() config int InitialRifleAmmo;
var() config int InitialPulseAmmo;
var() config int InitialRipperAmmo;
var() config int InitialBioAmmo;
var() config int InitialGunAmmo;
var() config int InitialStingerAmmo;
var() config int InitialOtherAmmo;
// ammo incrementing (number of TimeBetweenAmmoIncrements before ammo is incremented by 1)
var() config float RateRedeemerAmmoPerSec;
var() config float RateRocketAmmoPerSec;
var() config float RateFlakAmmoPerSec;
var() config float RateShockAmmoPerSec;
var() config float RateRifleAmmoPerSec;
var() config float RatePulseAmmoPerSec;
var() config float RateRipperAmmoPerSec;
var() config float RateBioAmmoPerSec;
var() config float RateGunAmmoPerSec;
var() config float RateStingerAmmoPerSec;
var() config float RateOtherAmmoPerSec;
// ammo incrementing (number of TimeBetweenAmmoIncrements before ammo is incremented by 1)
var() config int MaxRedeemerAmmo;
var() config int MaxRocketAmmo;
var() config int MaxFlakAmmo;
var() config int MaxShockAmmo;
var() config int MaxRifleAmmo;
var() config int MaxPulseAmmo;
var() config int MaxRipperAmmo;
var() config int MaxBioAmmo;
var() config int MaxGunAmmo;
var() config int MaxStingerAmmo;
var() config int MaxOtherAmmo;
var int NumWeapons; // number of weapons in ExtraWeaponClassStrings list
var string FilteredWeaponClassStrings[64]; // filtered list of weapons to use
var Class<Weapon> CurrentWeaponClass; // current weapon class
var int CurrentWeaponIndex; // index into FilteredWeaponClassStrings for current weapon
var int NumUsedWeapons; // number of weapons used so far (used with bUseAllWeapons)
var byte UsedWeapons[64]; // list of weapons used so far (used with bUseAllWeapons)
var int NumWarnings; // did "about to switch" warning
var float NextChooseWeaponTime; // when to switch again
var float ChooseWeaponWarningTime; // secs before weapon switch to warn clients
var float NextIncrementHealthTime; // when to do another pass through player health values
var float NextInvisibilityTime; // when to give everyone invisibility
var float NextKillInvisibilityTime; // when to remove invisibility from everyone (also indicates everyone is invisible)
var float NextDamageAmplifierTime; // when to give everyone damage amplifier
var float NextKillDamageAmplifierTime; // when to remove damage amplifier from everyone (also indicates everyone has damage amplifier)
var float NextJumpBootsTime; // when to give everyone jump boots
var float NextKillJumpBootsTime; // when to remove jump boots (also indicates everyone has jump boots)
var float NextAmmoIncrementTime; // when to increment ammo
var float NextTimeRecheck; // when to recheck player's weapon
var float CountRedeemerAmmo;
var float CountRocketAmmo;
var float CountFlakAmmo;
var float CountShockAmmo;
var float CountRifleAmmo;
var float CountPulseAmmo;
var float CountRipperAmmo;
var float CountBioAmmo;
var float CountGunAmmo;
var float CountStingerAmmo;
var float CountOtherAmmo;
// utility variables
var bool bDidTick; // set after first tick occurs
var bool bForceWeaponSpawn; // set to force CheckReplacement to return true for weapons
const LOTSATIME = 99999.0;
//-----------------------------------------------------------------------------
function MaybeAddWeapon( bool bUse, string WeaponClassString, out int NumWeapons )
{
if( bUse )
{
if( DynamicLoadObject( WeaponClassString, class'Class' ) != None )
{
FilteredWeaponClassStrings[ NumWeapons ] = WeaponClassString;
NumWeapons++;
}
else
{
warn( Self $ ": WeaponClassString is invalid in MaybeAddWeapon: " $ WeaponClassString );
}
}
}
//-----------------------------------------------------------------------------
// Prepare list of weapon classes to use, initialize stuff. The first tick that
// this mutator receives will select the first weapon to use and give it to
// all players.
function PreBeginPlay()
{
local int i;
//Super.PreBeginPlay();
// determine how many valid weapons we have
NumWeapons=0;
// standard weapons
MaybeAddWeapon( bUseChainSaw, "Botpack.ChainSaw", NumWeapons );
MaybeAddWeapon( bUseEnforcer, "Botpack.Enforcer", NumWeapons );
MaybeAddWeapon( bUseImpactHammer, "Botpack.ImpactHammer", NumWeapons );
MaybeAddWeapon( bUseMiniGun, "Botpack.MiniGun2", NumWeapons );
MaybeAddWeapon( bUsePulseGun, "Botpack.PulseGun", NumWeapons );
MaybeAddWeapon( bUseRipper, "Botpack.Ripper", NumWeapons );
MaybeAddWeapon( bUseShockRifle, "Botpack.ShockRifle", NumWeapons );
MaybeAddWeapon( bUseSniperRifle, "Botpack.SniperRifle", NumWeapons );
MaybeAddWeapon( bUseSuperShockRifle, "Botpack.SuperShockRifle", NumWeapons );
MaybeAddWeapon( bUseBioRifle, "Botpack.UT_BioRifle", NumWeapons );
MaybeAddWeapon( bUseRocketLauncher, "Botpack.UT_Eightball", NumWeapons );
MaybeAddWeapon( bUseFlakCannon, "Botpack.UT_FlakCannon", NumWeapons );
MaybeAddWeapon( bUseRedeemer, "Botpack.WarheadLauncher", NumWeapons );
MaybeAddWeapon( bUseUnrealIFlakCannon, "UnrealI.FlakCannon", NumWeapons );
MaybeAddWeapon( bUseUnrealIGESBioRifle, "UnrealI.GESBioRifle", NumWeapons );
MaybeAddWeapon( bUseUnrealIMinigun, "UnrealI.Minigun", NumWeapons );
MaybeAddWeapon( bUseUnrealIRazorjack, "UnrealI.Razorjack", NumWeapons );
MaybeAddWeapon( bUseUnrealIRifle, "UnrealI.Rifle", NumWeapons );
MaybeAddWeapon( bUseUnrealIASMD, "UnrealShare.ASMD", NumWeapons );
MaybeAddWeapon( bUseUnrealIAutoMag, "UnrealShare.AutoMag", NumWeapons );
MaybeAddWeapon( bUseUnrealIDispersionPistol,"UnrealShare.DispersionPistol", NumWeapons );
MaybeAddWeapon( bUseUnrealIEightball, "UnrealShare.Eightball", NumWeapons );
MaybeAddWeapon( bUseUnrealIStinger, "UnrealShare.Stinger", NumWeapons );
// weapons specified through ExtraWeaponClassStrings
for( i=0; i<ArrayCount(ExtraWeaponClassStrings); i++ )
{
if( ExtraWeaponClassStrings[i] != "" )
{
if( DynamicLoadObject( ExtraWeaponClassStrings[i], class'Class' ) != None )
{
FilteredWeaponClassStrings[ NumWeapons ] = ExtraWeaponClassStrings[i];
NumWeapons++;
}
else
{
warn( Self $ ": ExtraWeaponClassStrings["$i$"] is invalid: " $ ExtraWeaponClassStrings[i] );
}
}
}
// DefaultWeapon = None;
// AmmoName = '';
// WeaponName = '';
log( "Server is running NIUT 1.25. See www.planetunreal.com/niu for more info" );
log( "NIUT: " $ NumWeapons $ " weapons" );
if( NumWeapons == 0 )
{
log( "NIUT warning: No weapons specified in NIUT.ini (in the UT system folder)" );
FilteredWeaponClassStrings[ 0 ] = "Botpack.UT_Eightball";
NumWeapons = 1;
}
else
{
for( i=0; i<NumWeapons; i++ )
{
log( i $ " : " $ FilteredWeaponClassStrings[i] );
}
}
if( !bCycleWeapons )
{
// weapons never switch
WarningSoundRepeats = 0;
// ammo will be auto-incremented (pickups are health vials)
if( TimeBetweenAmmoIncrements == 0.0 )
{
TimeBetweenAmmoIncrements = 1.0;
}
// call this here since ChooseWeapon will never be called
TransformPickups();
}
if( TimeBetweenAmmoIncrements > 0.0 )
{
CountRedeemerAmmo = 0.0;
CountRocketAmmo = 0.0;
CountFlakAmmo = 0.0;
CountShockAmmo = 0.0;
CountRifleAmmo = 0.0;
CountRipperAmmo = 0.0;
CountBioAmmo = 0.0;
CountGunAmmo = 0.0;
CountStingerAmmo = 0.0;
CountPulseAmmo = 0.0;
CountOtherAmmo = 0.0;
}
NextChooseWeaponTime = 0.0;
NextIncrementHealthTime = 0.0;
NextInvisibilityTime = 0.0;
NextKillInvisibilityTime = 0.0;
NextDamageAmplifierTime = 0.0;
NextKillDamageAmplifierTime = 0.0;
NextJumpBootsTime = 0.0;
NextKillJumpBootsTime = 0.0;
NumWarnings = WarningSoundRepeats;
ChooseWeaponWarningTime = 0.0;
if( WarningSound != None )
{
ChooseWeaponWarningTime = GetSoundDuration( WarningSound );
}
CurrentWeaponIndex = -1;
ResetUsedWeapons();
if( MaxHealth <= 0)
{
MaxHealth = class'Pawn'.default.Health;
}
if( StartHealth <= 0)
{
StartHealth = class'Pawn'.default.Health;
}
}
//-----------------------------------------------------------------------------
// Perform weapon switching etc. when the time is right.
function Tick( float DeltaTime )
{
local Pawn P;
local Inventory Inv;
local bool bWeaponFound;
//Super.Tick( DeltaTime );
// setup
if( !bDidTick )
{
if( InvisibilityDelayMin > 0.0 )
{
NextInvisibilityTime = Level.TimeSeconds + RandRange(InvisibilityDelayMin, InvisibilityDelayMax);
}
if( DamageAmplifierDelayMin > 0.0 )
{
NextDamageAmplifierTime = Level.TimeSeconds + RandRange(DamageAmplifierDelayMin, DamageAmplifierDelayMax);
}
if( JumpBootsDelayMin > 0.0 )
{
NextJumpBootsTime = Level.TimeSeconds + RandRange(JumpBootsDelayMin, JumpBootsDelayMax);
}
if( TimeBetweenAmmoIncrements > 0.0 )
{
NextAmmoIncrementTime = Level.TimeSeconds + TimeBetweenAmmoIncrements;
}
bDidTick = true;
NextTimeRecheck = Level.TimeSeconds + TimeRecheck;
}
else if (!DeathMatchPlus(Level.Game).bRequireReady)
{
if( (NumWarnings < WarningSoundRepeats) && (Level.TimeSeconds >= (NextChooseWeaponTime - (WarningSoundRepeats-NumWarnings)*ChooseWeaponWarningTime )) )
{
// warn that we are about to switch the weapon
if( WarningSound != None )
{
for( P=Level.PawnList; P != None; P=P.NextPawn )
{
if( P.IsA( 'PlayerPawn' ) )
{
PlayerPawn(P).PlaySound( WarningSound,, 8 );
}
}
}
NumWarnings++;
}
// weapon switch
if( bCycleWeapons && Level.TimeSeconds >= NextChooseWeaponTime )
{
// time to change everybody's weapon
ChooseWeapon();
for( P=Level.PawnList; P != None; P=P.NextPawn )
{
if(P.IsInState('Dying') || P.Health <= 0)
continue;
SetInventory( P );
}
NumWarnings = 0;
NextChooseWeaponTime = Level.TimeSeconds + RandRange(TimeBetweenWeaponSwitchesMin, TimeBetweenWeaponSwitchesMax);
NextTimeRecheck = Level.TimeSeconds + TimeRecheck;
}
// ugly safety workaround
else if(bCycleWeapons && Level.TimeSeconds >= NextTimeRecheck)
{
for( P=Level.PawnList; P != None; P=P.NextPawn )
{
if(P.IsInState('Dying') || P.Health <= 0)
continue;
bWeaponFound = false;
for( Inv=P.Inventory; Inv!=None; Inv=Inv.Inventory )
{
if( Inv.IsA( 'Weapon' ) && FilterWeapon( Weapon(Inv) ) )
{
bWeaponFound = true;
break;
}
}
if(!bWeaponFound && (CurrentWeaponClass != None))
{
log("NIUT: ! BUG DETECTED ! Player without weapon, fixing that ... (" $ P $")");
//GiveWeaponTo( P, CurrentWeaponClass );
SetInventory( P );
}
}
NextTimeRecheck = Level.TimeSeconds + TimeRecheck;
}
// increment health
if( (HealthIncrementAmount >= 1) && (Level.TimeSeconds >= NextIncrementHealthTime) )
{
for( P=Level.PawnList; P != None; P=P.NextPawn )
{
if(P.IsInState('Dying') || P.Health <= 0)
continue;
if( (P.Health > 0) && (P.Health < MaxHealth) )
{
P.Health += Min( HealthIncrementAmount, MaxHealth - P.Health );
// play sound only if we won't spam the weapons switch warning (not playing if NumWarnings is 0
if( HealthIncrementSound != None && (NumWarnings == 0) && (PlayerPawn(P) != None) )
{
P.PlaySound( HealthIncrementSound );
}
}
}
NextIncrementHealthTime = Level.TimeSeconds + TimeBetweenHealthIncrements;
}
// invisibility
if( (InvisibilityDelayMin > 0.0) && (Level.TimeSeconds >= NextInvisibilityTime) )
{
for( P=Level.PawnList; P != None; P=P.NextPawn )
{
if(P.IsInState('Dying') || P.Health <= 0)
continue;
GiveInvisibilityTo( P );
// play sound only if we won't spam the weapons switch warning (not playing if NumWarnings is 0
// sound always plays in singleplayer?
if( Level.NetMode != NM_Standalone && (NumWarnings == 0) && (PlayerPawn(P) != None) )
{
P.PlaySound( class'UT_invisibility'.default.ActivateSound,, 8 );
}
}
NextInvisibilityTime = Level.TimeSeconds + LOTSATIME;
NextKillInvisibilityTime = Level.TimeSeconds + RandRange(InvisibilityDurationMin, InvisibilityDurationMax);
}
if( (NextKillInvisibilityTime > 0.0) && (Level.TimeSeconds >= NextKillInvisibilityTime) )
{
RemoveAllInvisibility();
NextKillInvisibilityTime = 0.0;
NextInvisibilityTime = Level.TimeSeconds + RandRange(InvisibilityDelayMin, InvisibilityDelayMax);
}
// damage amplifier
if( (DamageAmplifierDelayMin > 0.0) && (Level.TimeSeconds >= NextDamageAmplifierTime) )
{
for( P=Level.PawnList; P != None; P=P.NextPawn )
{
if(P.IsInState('Dying') || P.Health <= 0)
continue;
GiveDamageAmplifierTo( P );
// play sound only if we won't spam the weapons switch warning (not playing if NumWarnings is 0
// sound always plays in singleplayer?
if( Level.NetMode != NM_Standalone && (NumWarnings == 0) && (PlayerPawn(P) != None) )
{
P.PlaySound( class'UDamage'.default.ActivateSound,, 8 );
}
}
NextDamageAmplifierTime = Level.TimeSeconds + LOTSATIME;
NextKillDamageAmplifierTime = Level.TimeSeconds + RandRange(DamageAmplifierDurationMin, DamageAmplifierDurationMax);
}
if( (NextKillDamageAmplifierTime > 0.0) && (Level.TimeSeconds >= NextKillDamageAmplifierTime) )
{
RemoveAllDamageAmplifiers();
NextKillDamageAmplifierTime = 0.0;
NextDamageAmplifierTime = Level.TimeSeconds + RandRange(DamageAmplifierDelayMin, DamageAmplifierDelayMax);
}
// jump boots
if( (JumpBootsDelayMin > 0.0) && (Level.TimeSeconds >= NextJumpBootsTime) )
{
for( P=Level.PawnList; P != None; P=P.NextPawn )
{
if(P.IsInState('Dying') || P.Health <= 0)
continue;
GiveJumpBootsTo( P );
// play sound only if we won't spam the weapons switch warning (not playing if NumWarnings is 0
// sound always plays in singleplayer?
if( Level.NetMode != NM_Standalone && (NumWarnings == 0) && (PlayerPawn(P) != None) )
{
P.PlaySound( class'ut_jumpboots'.default.ActivateSound,, 8 );
}
}
NextJumpBootsTime = Level.TimeSeconds + LOTSATIME;
NextKillJumpBootsTime = Level.TimeSeconds + RandRange(JumpBootsDurationMin, JumpBootsDurationMax);
}
if( (NextKillJumpBootsTime > 0.0) && (Level.TimeSeconds >= NextKillJumpBootsTime) )
{
RemoveAllJumpBoots();
NextKillJumpBootsTime = 0.0;
NextJumpBootsTime = Level.TimeSeconds + RandRange(JumpBootsDelayMin, JumpBootsDelayMax);
}
// ammo
if( (TimeBetweenAmmoIncrements > 0.0) && (Level.TimeSeconds >= NextAmmoIncrementTime) )
{
IncrementAllAmmo();
NextAmmoIncrementTime = Level.TimeSeconds + TimeBetweenAmmoIncrements;
}
}
else
{
NextTimeRecheck = Level.TimeSeconds + TimeRecheck;
}
}
//-----------------------------------------------------------------------------
// Clear used weapon list used to make sure all weapons are used at least once
// when bUseAllWeapons is set.
function ResetUsedWeapons()
{
local int i;
for( i=0; i<NumWeapons; i++ )
{
UsedWeapons[i] = 0;
}
NumUsedWeapons = 0;
}
//-----------------------------------------------------------------------------
function TransformPickups()
{
local Inventory Inv;
foreach AllActors( class'Inventory', Inv )
{
if( Inv.Owner == None )
{
if( TimeBetweenAmmoIncrements > 0.0 )
{
// replace pickups with health vials -- weapon ammo will be incremented
if( !Inv.IsA( 'HealthVial' ) )
{
ReplaceWith( Inv, "Botpack.HealthVial" );
Inv.Destroy();
}
}
else if( CurrentWeaponClass == Class'DispersionPistol' )
{
// put powerups in level for dispersion pistol
if( !Inv.IsA( 'WeaponPowerUp' ) )
{
ReplaceWith( Inv, "UnrealShare.WeaponPowerUp" );
Inv.Destroy();
}
}
else if( (CurrentWeaponClass.default.AmmoName == None) || (CurrentWeaponClass.default.AmmoName.Name == '') || (CurrentWeaponClass == Class'SuperShockRifle') )
{
// replace with vials of health -- keeps bot destination code happy
if( !Inv.IsA( 'HealthVial' ) )
{
ReplaceWith( Inv, "Botpack.HealthVial" );
Inv.Destroy();
}
}
else
{
if( Inv.Class.Name != CurrentWeaponClass.default.AmmoName.Name )
{
ReplaceWith( Inv, string(CurrentWeaponClass.default.AmmoName) );
Inv.Destroy();
}
}
}
}
if( CurrentWeaponClass == Class'WarheadLauncher' )
{
// UT400 WarheadAmmo currently has no mesh/texture and 0 ammo
foreach AllActors( class'Inventory', Inv )
{
if( Inv.Owner == None && Inv.IsA( 'WarheadAmmo') )
{
Inv.DrawType = DT_Sprite;
Ammo(Inv).AmmoAmount = 1;
}
}
}
}
//-----------------------------------------------------------------------------
// Select the next weapon to use and replace all pickup items in the level with
// ammo for this weapon, or health vials if the weapon doesn't require ammo.
function ChooseWeapon()
{
if( CurrentWeaponIndex == -1 )
{
CurrentWeaponIndex = 0;
}
if( NumWeapons >= 1)
{
if( NumUsedWeapons == NumWeapons )
{
ResetUsedWeapons();
}
if( bRandomWeapons )
{
CurrentWeaponIndex = Rand( NumWeapons );
if( bUseAllWeapons )
{
while( UsedWeapons[CurrentWeaponIndex] != 0 )
{
CurrentWeaponIndex++;
if( CurrentWeaponIndex >= NumWeapons )
{
CurrentWeaponIndex=0;
}
}
}
NumUsedWeapons++;
UsedWeapons[CurrentWeaponIndex] = 1;
}
CurrentWeaponClass = class<Weapon>( DynamicLoadObject( FilteredWeaponClassStrings[CurrentWeaponIndex], class'Class' ) );
if( CurrentWeaponClass == None )
{
warn( Self $ ": CurrentDefaultWeapon is None!" );
}
if( !bRandomWeapons )
{
CurrentWeaponIndex++;
if( CurrentWeaponIndex >= NumWeapons )
{
CurrentWeaponIndex=0;
}
}
}
else
{
warn( Self $ ": ExtraWeaponsClassStrings contain no valid weapon(s)!" );
}
log( "NIUT: " $ Level.TimeSeconds $ " (" $ Level.Game.NumPlayers $ ") -- selected: " $ CurrentWeaponClass $"("$CurrentWeaponIndex$")");
TransformPickups();
NextChooseWeaponTime = Level.TimeSeconds + RandRange( TimeBetweenWeaponSwitchesMin, TimeBetweenWeaponSwitchesMax );
}
//-----------------------------------------------------------------------------
// Give W Amount units of ammo, increasing ammo's MaxAmmo if necessary and make
// sure the weapon doesn't end up with *more* than Amount units of ammo.
function GiveAmmo( Weapon W, Pawn Other, int Amount, int Max )
{
if ( W.AmmoName != None )
{
W.AmmoType = Ammo(Other.FindInventoryType(W.AmmoName));
if ( W.AmmoType != None )
{
if( W.AmmoType.MaxAmmo < Amount )
{
W.AmmoType.MaxAmmo = Amount;
}
W.AmmoType.AddAmmo(Amount);
}
else
{
W.AmmoType = Spawn(W.AmmoName); // Create ammo type required
Other.AddInventory(W.AmmoType); // and add to player's inventory
W.AmmoType.BecomeItem();
if( W.AmmoType.MaxAmmo < Amount )
{
W.AmmoType.MaxAmmo = Amount;
}
W.AmmoType.AmmoAmount = Amount;
W.AmmoType.GotoState('Idle2');
}
if( Max > 0 )
{
// might override temporary MaxAmmo set above to give initial amount
W.AmmoType.MaxAmmo = Max;
}
}
// make sure weapon doesn't have *more* than the specified amount.
if( W.AmmoType!=None && W.AmmoType.AmmoAmount > Amount )
{
W.AmmoType.AmmoAmount = Amount;
}
}
//-----------------------------------------------------------------------------
function GiveWeaponTo( Pawn P, Class<Weapon> WeaponClass )
{
local Weapon newWeapon;
bForceWeaponSpawn = true;
newWeapon = Spawn(WeaponClass);
if( newWeapon != None )
{
newWeapon.Instigator = P;
newWeapon.BecomeItem();
if( newWeapon.IsA( 'ut_eightball' ) || newWeapon.IsA( 'Eightball' ))
{
GiveAmmo( newWeapon, P, InitialRocketAmmo, MaxRocketAmmo );
}
else if( newWeapon.IsA( 'WarheadLauncher' ) )
{
GiveAmmo( newWeapon, P, InitialRedeemerAmmo, MaxRedeemerAmmo );
}
else if( newWeapon.IsA( 'ut_flakcannon' ) || newWeapon.IsA( 'FlakCannon' ))
{
GiveAmmo( newWeapon, P, InitialFlakAmmo, MaxFlakAmmo );
}
else if( newWeapon.IsA( 'shockrifle' ) || newWeapon.IsA( 'ASMD') )
{
GiveAmmo( newWeapon, P, InitialShockAmmo, MaxShockAmmo );
}
else if( newWeapon.IsA( 'sniperrifle' ) || newWeapon.IsA( 'Rifle' ))
{
GiveAmmo( newWeapon, P, InitialRifleAmmo, MaxRifleAmmo );
}
else if( newWeapon.IsA( 'PulseGun' ) )
{
GiveAmmo( newWeapon, P, InitialPulseAmmo, MaxPulseAmmo );
}
else if( newWeapon.IsA( 'ripper' ) || newWeapon.IsA( 'razorjack' ) )
{
GiveAmmo( newWeapon, P, InitialRipperAmmo, MaxRipperAmmo );
}
else if( newWeapon.IsA( 'minigun2' ) || newWeapon.IsA( 'enforcer' ) || newWeapon.IsA( 'AutoMag' ) || newWeapon.IsA( 'Minigun' ) )
{
GiveAmmo( newWeapon, P, InitialGunAmmo, MaxGunAmmo );
}
else if( newWeapon.IsA( 'ut_biorifle' ) || newWeapon.IsA( 'gesbiorifle' ) )
{
GiveAmmo( newWeapon, P, InitialBioAmmo, MaxBioAmmo );
}
else if( newWeapon.IsA( 'stinger' ) )
{
GiveAmmo( newWeapon, P, InitialStingerAmmo, MaxStingerAmmo );
}
else
{
// not one of the standard UT or Unreal I weapons -- handle all of these
// using "other" initial, max ammo etc. which might not be right...
GiveAmmo( newWeapon, P, InitialOtherAmmo, MaxOtherAmmo );
}
// make sure weapon can't be tossed
newWeapon.bCanThrow = false;
P.AddInventory(newWeapon);
newWeapon.SetSwitchPriority(P);
newWeapon.WeaponSet(P);
// mdf-tbd: might be bad to do this...
// newWeapon.BringUp();
}
bForceWeaponSpawn = false;
}
//-----------------------------------------------------------------------------
// Only filter weapons that we know about (including weapons added to the
// ExtraWeaponClassStrings so we don't remove anything that shouldn't be such
// as the CGrapple mutator classes.
function bool FilterWeapon( Weapon W )
{
local int i;
local Class C;
// standard UT and Unreal I weapons
if( W.IsA( 'UT_Eightball' ) ||
W.IsA( 'UT_FlakCannon' ) ||
W.IsA( 'Enforcer' ) ||
W.IsA( 'MiniGun2' ) ||
W.IsA( 'PulseGun' ) ||
W.IsA( 'Ripper' ) ||
W.IsA( 'ShockRifle' ) ||
W.IsA( 'SniperRifle' ) ||
W.IsA( 'SuperShockRifle' ) ||
W.IsA( 'UT_BioRifle' ) ||
W.IsA( 'WarheadLauncher' ) ||
W.IsA( 'ImpactHammer' ) ||
W.IsA( 'ChainSaw' ) ||
W.IsA( 'FlakCannon' ) ||
W.IsA( 'GESBioRifle' ) ||
W.IsA( 'Minigun' ) ||
W.IsA( 'Razorjack' ) ||
W.IsA( 'Rifle' ) ||
W.IsA( 'ASMD' ) ||
W.IsA( 'AutoMag' ) ||
W.IsA( 'DispersionPistol' ) ||
W.IsA( 'Eightball' ) ||
W.IsA( 'Stinger' ) )
{
return true;
}
// check any weapons specified through ExtraWeaponClassStrings
for( i=0; i<ArrayCount(ExtraWeaponClassStrings); i++ )
{
if( ExtraWeaponClassStrings[i] != "" )
{
C = Class( DynamicLoadObject( ExtraWeaponClassStrings[i], class'Class' ) );
if( C != None && W.IsA( C.Name ) )
{
return true;
}
}
}
// don't filter
return false;
}
/*
//-----------------------------------------------------------------------------
function bool FilterItem( Actor Item )
{
if( Item.IsA( 'Translocator' ) ||
Item.IsA( 'SearchLight') ||
Item.IsA( 'UT_invisibility' ) ||
Item.IsA( 'UDamage' ) ||
Item.IsA( 'ut_jumpboots') )
{
return false;
}
if( Item.IsA( 'Weapon' ) )
{
return FilterWeapon( Weapon(Item) );
}
return false;
}
*/
//-----------------------------------------------------------------------------
// Set the given Pawn's weapon to the current one. Get rid of all inventory
// before doing this.
function SetInventory( Pawn P )
{
local Inventory Inv;
local int WeaponIndex;
// filter any weapons before we give the NIUT weapon(s) below (gets rid of default weapon?)
// zap any current inventory
for( Inv=P.Inventory; Inv!=None; Inv=Inv.Inventory )
{
if( Inv.IsA( 'Weapon' ) && FilterWeapon( Weapon(Inv) ) )
{
P.DeleteInventory( Inv );
Inv.Destroy();
}
}
if( !bCycleWeapons )
{
for( WeaponIndex=0; WeaponIndex<NumWeapons; WeaponIndex++ )
{
CurrentWeaponClass = class<Weapon>( DynamicLoadObject( FilteredWeaponClassStrings[WeaponIndex], class'Class' ) );
GiveWeaponTo( P, CurrentWeaponClass );
}
}
else if( CurrentWeaponClass!=None )
{
GiveWeaponTo( P, CurrentWeaponClass );
}
}
//-----------------------------------------------------------------------------
function bool MoreOrLessInt( float Val )
{
return( abs(Val - int(Val+0.5)) < 0.010 );
}
//-----------------------------------------------------------------------------
function AdjustAmmo( Ammo AInv, float AmmoCount )
{
if( MoreOrLessInt(AmmoCount) )
{
AInv.AmmoAmount += int(AmmoCount+0.5);
if( AInv.AmmoAmount > AInv.MaxAmmo )
{
AInv.AmmoAmount = AInv.MaxAmmo;
}
}
}
//-----------------------------------------------------------------------------
function IncrementAllAmmo()
{
local Inventory Inv;
local Pawn P;
CountRedeemerAmmo += (RateRedeemerAmmoPerSec * TimeBetweenAmmoIncrements);
CountRocketAmmo += (RateRocketAmmoPerSec * TimeBetweenAmmoIncrements);
CountFlakAmmo += (RateFlakAmmoPerSec * TimeBetweenAmmoIncrements);
CountRifleAmmo += (RateRifleAmmoPerSec * TimeBetweenAmmoIncrements);
CountGunAmmo += (RateGunAmmoPerSec * TimeBetweenAmmoIncrements);
CountPulseAmmo += (RatePulseAmmoPerSec * TimeBetweenAmmoIncrements);
CountShockAmmo += (RateShockAmmoPerSec * TimeBetweenAmmoIncrements);
CountRipperAmmo += (RateRipperAmmoPerSec * TimeBetweenAmmoIncrements);
CountBioAmmo += (RateBioAmmoPerSec * TimeBetweenAmmoIncrements);
CountStingerAmmo += (RateStingerAmmoPerSec * TimeBetweenAmmoIncrements);
CountOtherAmmo += (RateOtherAmmoPerSec * TimeBetweenAmmoIncrements);
for( P=Level.PawnList; P != None; P=P.NextPawn )
for( Inv=P.Inventory; Inv!=None; Inv=Inv.Inventory )
{
if( Inv.IsA( 'Ammo' ) )
{
if( Inv.IsA( 'RocketPack' ) || Inv.IsA( 'RocketCan' ) )
{
AdjustAmmo( Ammo(Inv), CountRocketAmmo );
}
else if( Inv.IsA( 'FlakAmmo' ) || Inv.IsA( 'FlakBox' ) )
{
AdjustAmmo( Ammo(Inv), CountFlakAmmo );
}
else if( Inv.IsA( 'WarHeadAmmo' ) )
{
AdjustAmmo( Ammo(Inv), CountRedeemerAmmo );
}
else if( Inv.IsA( 'RifleRound' ) || Inv.IsA( 'BulletBox' ) )
{
AdjustAmmo( Ammo(Inv), CountRifleAmmo );
}
else if( Inv.IsA( 'ShellBox' ) || Inv.IsA( 'Miniammo' ) )
{
AdjustAmmo( Ammo(Inv), CountGunAmmo );
}
else if( Inv.IsA( 'PAmmo' ) )
{
AdjustAmmo( Ammo(Inv), CountPulseAmmo );
}
else if( Inv.IsA( 'ASMDAmmo' ) || Inv.IsA( 'ShockCore' ) )
{
AdjustAmmo( Ammo(Inv), CountShockAmmo );
}
else if( Inv.IsA( 'RazorAmmo' ) || Inv.IsA( 'BladeHopper' ) )
{
AdjustAmmo( Ammo(Inv), CountRipperAmmo );
}
else if( Inv.IsA( 'BioAmmo' ) || Inv.IsA( 'Sludge' ) )
{
AdjustAmmo( Ammo(Inv), CountBioAmmo );
}
else if( Inv.IsA( 'StingerAmmo' ) )
{
AdjustAmmo( Ammo(Inv), CountStingerAmmo );
}
else
{
// unknown ammo type
AdjustAmmo( Ammo(Inv), CountOtherAmmo );
}
}
}
if( MoreOrLessInt(CountRedeemerAmmo) )
CountRedeemerAmmo = 0.0;
if( MoreOrLessInt(CountRocketAmmo) )
CountRocketAmmo = 0.0;
if( MoreOrLessInt(CountFlakAmmo) )
CountFlakAmmo = 0.0;
if( MoreOrLessInt(CountRifleAmmo) )
CountRifleAmmo = 0.0;
if( MoreOrLessInt(CountGunAmmo) )
CountGunAmmo = 0.0;
if( MoreOrLessInt(CountPulseAmmo) )
CountPulseAmmo = 0.0;
if( MoreOrLessInt(CountShockAmmo) )
CountShockAmmo = 0.0;
if( MoreOrLessInt(CountRipperAmmo) )
CountRipperAmmo = 0.0;
if( MoreOrLessInt(CountBioAmmo) )
CountBioAmmo = 0.0;
if( MoreOrLessInt(CountStingerAmmo) )
CountStingerAmmo = 0.0;
if( MoreOrLessInt(CountOtherAmmo) )
CountOtherAmmo = 0.0;
}
//-----------------------------------------------------------------------------
function GiveInvisibilityTo( Pawn P )
{
local UT_Invisibility Invisibility;
Invisibility = Spawn( class'UT_Invisibility' );
if( Invisibility != None )
{
Invisibility.Charge = 99999;
Invisibility.Touch( P );
Invisibility.Destroy();
}
}
//-----------------------------------------------------------------------------
function RemoveAllInvisibility()
{
local UT_Invisibility Invisibility;
foreach AllActors( class'UT_invisibility', Invisibility )
{
if( Invisibility.Owner != None && (NumWarnings == 0) && (PlayerPawn(Invisibility.Owner) != None) )
{
Invisibility.Owner.PlaySound( Sound'Botpack.ASMD.Vapour',, 8 );
}
Invisibility.UsedUp();
}
}
//-----------------------------------------------------------------------------
function GiveDamageAmplifierTo( Pawn P )
{
local UDamage DamageAmplifier;
DamageAmplifier = Spawn( class'UDamage' );
if( DamageAmplifier != None )
{
DamageAmplifier.Charge = 99999;
DamageAmplifier.Touch( P );
DamageAmplifier.Destroy();
}
}
//-----------------------------------------------------------------------------
function RemoveAllDamageAmplifiers()
{
local UDamage DamageAmplifier;
foreach AllActors( class'UDamage', DamageAmplifier )
{
if( DamageAmplifier.Owner != None && (NumWarnings == 0) && (PlayerPawn(DamageAmplifier.Owner) != None) )
{
DamageAmplifier.Owner.PlaySound( class'UDamage'.default.DeActivateSound,, 8 );
}
DamageAmplifier.UsedUp();
}
// UT gold might add ExpireMessage?
if( class'UDamage'.default.ExpireMessage == "" )
{
BroadcastMessage( class'UDamage'.default.ItemName $ " has expired." ); // not localized...
}
}
//-----------------------------------------------------------------------------
function GiveJumpBootsTo( Pawn P )
{
local ut_jumpboots JumpBoots;
JumpBoots = Spawn( class'ut_jumpboots' );
if( JumpBoots != None )
{
JumpBoots.Charge = 99999;
JumpBoots.Touch( P );
JumpBoots.Destroy();
}
}
//-----------------------------------------------------------------------------
function RemoveAllJumpBoots()
{
local ut_jumpboots JumpBoots;
foreach AllActors( class'ut_jumpboots', JumpBoots )
{
if( JumpBoots.Owner != None && (NumWarnings == 0) && (PlayerPawn(JumpBoots.Owner) != None) )
{
JumpBoots.Owner.PlaySound( Sound'Botpack.ASMD.Vapour',, 8 );
}
JumpBoots.ResetOwner();
JumpBoots.UsedUp();
}
}
//-----------------------------------------------------------------------------
// Make sure everyone is using the correct weapon, ammo no matter when they
// join the game or respawn.
function ModifyPlayer( Pawn Other )
{
if ( NextMutator != None )
{
NextMutator.ModifyPlayer(Other);
}
SetInventory( Other );
if( NextKillInvisibilityTime > 0.0 )
{
GiveInvisibilityTo( Other );
}
if( NextKillDamageAmplifierTime > 0.0 )
{
GiveDamageAmplifierTo( Other );
}
if( NextKillJumpBootsTime > 0.0 )
{
GiveJumpBootsTo( Other );
}
if( StartHealth != 0 )
{
Other.Health = StartHealth;
}
}
//-----------------------------------------------------------------------------
// Return true for any non-UT weapons and ammo (otherwise DMMutator will swap
// these with UT equivalents).
function bool AlwaysKeep( Actor Other )
{
local bool bRetVal;
bRetVal = false;
if( Other.IsA('Weapon') && !Other.IsA('TournamentWeapon') )
{
if( Other.IsA('Stinger') ||
Other.IsA('Rifle') ||
Other.IsA('Razorjack') ||
Other.IsA('Minigun') ||
Other.IsA('AutoMag') ||
Other.IsA('Eightball') ||
Other.IsA('FlakCannon') ||
Other.IsA('ASMD') ||
Other.IsA('GesBioRifle') ||
Other.IsA('DispersionPistol') )
{
bRetVal = true;
}
}
else if ( Other.IsA('Ammo') && !Other.IsA('TournamentAmmo') )
{
if( Other.IsA('ASMDAmmo') ||
Other.IsA('RocketCan') ||
Other.IsA('StingerAmmo') ||
Other.IsA('RazorAmmo') ||
Other.IsA('RifleRound') ||
Other.IsA('RifleAmmo') ||
Other.IsA('FlakBox') ||
Other.IsA('Clip') ||
Other.IsA('ShellBox') ||
Other.IsA('Sludge') )
{
bRetVal = true;
}
}
else if ( Other.IsA('WeaponPowerUp') )
{
bRetVal = true;
}
else if ( Other.IsA('UT_Jumpboots') )
{
bRetVal = true;
}
else if ( NextMutator != None )
{
bRetVal = NextMutator.AlwaysKeep(Other);
}
return bRetVal;
}
//-----------------------------------------------------------------------------
// Only really here to support LastManStanding which Almost anything gets through at this point, although in some cases these will
// be replaced with other actors with the first tick.
function bool CheckReplacement( Actor Other, out byte bSuperRelevant )
{
local bool bRetVal;
bRetVal = true;
if( bForceWeaponSpawn )
{
bSuperRelevant = 1;
}
else if( Other.Owner != None && Other.IsA('Weapon') && FilterWeapon(Weapon(Other)) )
{
// Filter weapons by replacing them with the current weapon (if set) or by
// removing them since some games (e.g. Last Man Standing) try to give
// players weapons sometime after players join the game.
if( CurrentWeaponClass!= None && !ClassIsChildOf(Other.Class,CurrentWeaponClass) )
{
ReplaceWith(Other, string(CurrentWeaponClass));
}
bRetVal = false;
}
return bRetVal;
}
//-----------------------------------------------------------------------------
// No weapon by default -- this mutator hands out all weapons.
function Class<Weapon> MyDefaultWeapon()
{
return None;
}
//-----------------------------------------------------------------------------
defaultproperties
{
bRandomWeapons=False
bUseAllWeapons=True
bCycleWeapons=True
bUseChainSaw=True
bUseEnforcer=True
bUseImpactHammer=True
bUseMiniGun=True
bUsePulseGun=False
bUseRipper=True
bUseShockRifle=True
bUseSniperRifle=True
bUseSuperShockRifle=True
bUseBioRifle=True
bUseRocketLauncher=True
bUseFlakCannon=True
bUseRedeemer=False
bUseUnrealIFlakCannon=False
bUseUnrealIGESBioRifle=False
bUseUnrealIMinigun=False
bUseUnrealIRazorjack=False
bUseUnrealIRifle=False
bUseUnrealIASMD=False
bUseUnrealIAutoMag=False
bUseUnrealIDispersionPistol=False
bUseUnrealIEightball=False
bUseUnrealIStinger=False
ExtraWeaponClassStrings(0)=""
ExtraWeaponClassStrings(1)=""
ExtraWeaponClassStrings(2)=""
ExtraWeaponClassStrings(3)=""
ExtraWeaponClassStrings(4)=""
ExtraWeaponClassStrings(5)=""
ExtraWeaponClassStrings(6)=""
ExtraWeaponClassStrings(7)=""
ExtraWeaponClassStrings(8)=""
ExtraWeaponClassStrings(9)=""
ExtraWeaponClassStrings(10)=""
ExtraWeaponClassStrings(11)=""
ExtraWeaponClassStrings(12)=""
ExtraWeaponClassStrings(13)=""
ExtraWeaponClassStrings(14)=""
ExtraWeaponClassStrings(15)=""
ExtraWeaponClassStrings(16)=""
ExtraWeaponClassStrings(17)=""
ExtraWeaponClassStrings(18)=""
ExtraWeaponClassStrings(19)=""
ExtraWeaponClassStrings(20)=""
ExtraWeaponClassStrings(21)=""
ExtraWeaponClassStrings(22)=""
ExtraWeaponClassStrings(23)=""
ExtraWeaponClassStrings(24)=""
ExtraWeaponClassStrings(25)=""
ExtraWeaponClassStrings(26)=""
ExtraWeaponClassStrings(27)=""
ExtraWeaponClassStrings(28)=""
ExtraWeaponClassStrings(29)=""
ExtraWeaponClassStrings(30)=""
ExtraWeaponClassStrings(31)=""
TimeRecheck=2.000000
TimeBetweenWeaponSwitchesMin=50.000000
TimeBetweenWeaponSwitchesMax=70.000000
TimeBetweenAmmoIncrements=0.000000
WarningSound=Sound'Botpack.Pickups.UTSuperHeal'
WarningSoundRepeats=3
HealthIncrementSound=None
HealthIncrementAmount=5
StartHealth=100
MaxHealth=200
TimeBetweenHealthIncrements=1.000000
InvisibilityDelayMin=0.000000
InvisibilityDelayMax=0.000000
InvisibilityDurationMin=10.000000
InvisibilityDurationMax=10.000000
DamageAmplifierDelayMin=45.000000
DamageAmplifierDelayMax=45.000000
DamageAmplifierDurationMin=45.000000
DamageAmplifierDurationMax=45.000000
JumpBootsDelayMin=0.000000
JumpBootsDelayMax=0.000000
JumpBootsDurationMin=15.000000
JumpBootsDurationMax=15.000000
InitialRedeemerAmmo=0
InitialRocketAmmo=12
InitialFlakAmmo=12
InitialShockAmmo=12
InitialRifleAmmo=12
InitialPulseAmmo=50
InitialRipperAmmo=25
InitialBioAmmo=50
InitialGunAmmo=100
InitialStingerAmmo=50
InitialOtherAmmo=50
RateRedeemerAmmoPerSec=0.050000
RateRocketAmmoPerSec=0.000000
RateFlakAmmoPerSec=0.200000
RateShockAmmoPerSec=0.670000
RateRifleAmmoPerSec=0.500000
RatePulseAmmoPerSec=2.000000
RateRipperAmmoPerSec=1.500000
RateBioAmmoPerSec=0.250000
RateGunAmmoPerSec=0.000000
RateStingerAmmoPerSec=5.000000
RateOtherAmmoPerSec=5.000000
MaxRedeemerAmmo=1
MaxRocketAmmo=48
MaxFlakAmmo=50
MaxShockAmmo=50
MaxRifleAmmo=50
MaxPulseAmmo=199
MaxRipperAmmo=75
MaxBioAmmo=100
MaxGunAmmo=199
MaxStingerAmmo=200
MaxOtherAmmo=200
NumWeapons=0
FilteredWeaponClassStrings(0)=""
FilteredWeaponClassStrings(1)=""
FilteredWeaponClassStrings(2)=""
FilteredWeaponClassStrings(3)=""
FilteredWeaponClassStrings(4)=""
FilteredWeaponClassStrings(5)=""
FilteredWeaponClassStrings(6)=""
FilteredWeaponClassStrings(7)=""
FilteredWeaponClassStrings(8)=""
FilteredWeaponClassStrings(9)=""
FilteredWeaponClassStrings(10)=""
FilteredWeaponClassStrings(11)=""
FilteredWeaponClassStrings(12)=""
FilteredWeaponClassStrings(13)=""
FilteredWeaponClassStrings(14)=""
FilteredWeaponClassStrings(15)=""
FilteredWeaponClassStrings(16)=""
FilteredWeaponClassStrings(17)=""
FilteredWeaponClassStrings(18)=""
FilteredWeaponClassStrings(19)=""
FilteredWeaponClassStrings(20)=""
FilteredWeaponClassStrings(21)=""
FilteredWeaponClassStrings(22)=""
FilteredWeaponClassStrings(23)=""
FilteredWeaponClassStrings(24)=""
FilteredWeaponClassStrings(25)=""
FilteredWeaponClassStrings(26)=""
FilteredWeaponClassStrings(27)=""
FilteredWeaponClassStrings(28)=""
FilteredWeaponClassStrings(29)=""
FilteredWeaponClassStrings(30)=""
FilteredWeaponClassStrings(31)=""
FilteredWeaponClassStrings(32)=""
FilteredWeaponClassStrings(33)=""
FilteredWeaponClassStrings(34)=""
FilteredWeaponClassStrings(35)=""
FilteredWeaponClassStrings(36)=""
FilteredWeaponClassStrings(37)=""
FilteredWeaponClassStrings(38)=""
FilteredWeaponClassStrings(39)=""
FilteredWeaponClassStrings(40)=""
FilteredWeaponClassStrings(41)=""
FilteredWeaponClassStrings(42)=""
FilteredWeaponClassStrings(43)=""
FilteredWeaponClassStrings(44)=""
FilteredWeaponClassStrings(45)=""
FilteredWeaponClassStrings(46)=""
FilteredWeaponClassStrings(47)=""
FilteredWeaponClassStrings(48)=""
FilteredWeaponClassStrings(49)=""
FilteredWeaponClassStrings(50)=""
FilteredWeaponClassStrings(51)=""
FilteredWeaponClassStrings(52)=""
FilteredWeaponClassStrings(53)=""
FilteredWeaponClassStrings(54)=""
FilteredWeaponClassStrings(55)=""
FilteredWeaponClassStrings(56)=""
FilteredWeaponClassStrings(57)=""
FilteredWeaponClassStrings(58)=""
FilteredWeaponClassStrings(59)=""
FilteredWeaponClassStrings(60)=""
FilteredWeaponClassStrings(61)=""
FilteredWeaponClassStrings(62)=""
FilteredWeaponClassStrings(63)=""
CurrentWeaponClass=None
CurrentWeaponIndex=0
NumUsedWeapons=0
UsedWeapons(0)=0
UsedWeapons(1)=0
UsedWeapons(2)=0
UsedWeapons(3)=0
UsedWeapons(4)=0
UsedWeapons(5)=0
UsedWeapons(6)=0
UsedWeapons(7)=0
UsedWeapons(8)=0
UsedWeapons(9)=0
UsedWeapons(10)=0
UsedWeapons(11)=0
UsedWeapons(12)=0
UsedWeapons(13)=0
UsedWeapons(14)=0
UsedWeapons(15)=0
UsedWeapons(16)=0
UsedWeapons(17)=0
UsedWeapons(18)=0
UsedWeapons(19)=0
UsedWeapons(20)=0
UsedWeapons(21)=0
UsedWeapons(22)=0
UsedWeapons(23)=0
UsedWeapons(24)=0
UsedWeapons(25)=0
UsedWeapons(26)=0
UsedWeapons(27)=0
UsedWeapons(28)=0
UsedWeapons(29)=0
UsedWeapons(30)=0
UsedWeapons(31)=0
UsedWeapons(32)=0
UsedWeapons(33)=0
UsedWeapons(34)=0
UsedWeapons(35)=0
UsedWeapons(36)=0
UsedWeapons(37)=0
UsedWeapons(38)=0
UsedWeapons(39)=0
UsedWeapons(40)=0
UsedWeapons(41)=0
UsedWeapons(42)=0
UsedWeapons(43)=0
UsedWeapons(44)=0
UsedWeapons(45)=0
UsedWeapons(46)=0
UsedWeapons(47)=0
UsedWeapons(48)=0
UsedWeapons(49)=0
UsedWeapons(50)=0
UsedWeapons(51)=0
UsedWeapons(52)=0
UsedWeapons(53)=0
UsedWeapons(54)=0
UsedWeapons(55)=0
UsedWeapons(56)=0
UsedWeapons(57)=0
UsedWeapons(58)=0
UsedWeapons(59)=0
UsedWeapons(60)=0
UsedWeapons(61)=0
UsedWeapons(62)=0
UsedWeapons(63)=0
NumWarnings=0
NextChooseWeaponTime=0.000000
ChooseWeaponWarningTime=0.000000
NextIncrementHealthTime=0.000000
NextInvisibilityTime=0.000000
NextKillInvisibilityTime=0.000000
NextDamageAmplifierTime=0.000000
NextKillDamageAmplifierTime=0.000000
NextJumpBootsTime=0.000000
NextKillJumpBootsTime=0.000000
NextAmmoIncrementTime=0.000000
NextTimeRecheck=2.000000
CountRedeemerAmmo=0.000000
CountRocketAmmo=0.000000
CountFlakAmmo=0.000000
CountShockAmmo=0.000000
CountRifleAmmo=0.000000
CountPulseAmmo=0.000000
CountRipperAmmo=0.000000
CountBioAmmo=0.000000
CountGunAmmo=0.000000
CountStingerAmmo=0.000000
CountOtherAmmo=0.000000
bDidTick=False
bForceWeaponSpawn=False
}