1718 lines
55 KiB
Ucode
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
|
|
}
|