Engine
Class Inventory

source: e:\games\UnrealTournament\Engine\Classes\Inventory.uc
Core.Object
   |
   +--Engine.Actor
      |
      +--Engine.Inventory
Direct Known Subclasses:LadderInventory, TrapSpringer, Pickup, Weapon

class Inventory
extends Engine.Actor

//============================================================================= // The inventory class, the parent class of all objects which can be // picked up and carried by actors. //=============================================================================
Variables
 int AbsorptionPriority
           Which items absorb damage first (higher=first).
 int ArmorAbsorption
           Percent of damage item absorbs 0-100.
 byte AutoSwitchPriority
           Autoswitch value, 0=never autoswitch.
 float BobDamping
           how much to damp view bob
 int Charge
           Amount of armor or charge if not an armor (charge in time*10).
 Texture Icon
           Maximum desireability this item will ever have.
 byte InventoryGroup
           The weapon/inventory set, 1-9 (0=none).
 string ItemArticle
           Human readable article (e.g. "a", "an")
 class ItemMessageClass
           Maximum desireability this item will ever have.
 string ItemName
           Human readable name of item
 String M_Activated
           Maximum desireability this item will ever have.
 String M_Deactivated
           Maximum desireability this item will ever have.
 String M_Selected
           Maximum desireability this item will ever have.
 float MaxDesireability
           Maximum desireability this item will ever have.
 Inventory NextArmor
           Temporary list created by Armors to prioritize damage absorption.
 FlashCount, OldFlashCount
           Maximum desireability this item will ever have.
 string PickupMessage
           Human readable description when picked up.
 class PickupMessageClass
           Maximum desireability this item will ever have.
 mesh PickupViewMesh
           Mesh to render.
 float PickupViewScale
           Mesh scale.
 name PlayerLastTouched
           Player who last touched this item.
 mesh PlayerViewMesh
           Mesh to render.
 vector PlayerViewOffset
           Offset from view center.
 float PlayerViewScale
           Mesh scale.
 name ProtectionType1
           Protects against DamageType (None if non-armor).
 name ProtectionType2
           Secondary protection type (None if non-armor).
 DeActivateSound, RespawnSound
           Maximum desireability this item will ever have.
 float RespawnTime
           Respawn after this time, 0 for instant.
 Texture StatusIcon
           Icon used with ammo/charge/power count.
 mesh ThirdPersonMesh
           Mesh to render.
 float ThirdPersonScale
           Mesh scale.
 bool bActivatable
           Whether item can be activated.
 bool bDisplayableInv
           Item displayed in HUD.
 bool bFirstFrame
           Maximum desireability this item will ever have.
 bool bInstantRespawn
           Can be tagged so this item respawns instantly.
 bool bIsAnArmor
           Item will protect player.
 bool bRotatingPickup
           Rotates when in pickup state.
 bool bSteadyFlash3rd
           Maximum desireability this item will ever have.
 bool bSteadyToggle
           Maximum desireability this item will ever have.

States
Idle2, Sleeping, Activated, Pickup

Function Summary
 void Activate()
     
//
// Toggle Activation of selected Item.
// 
 void AltFire(float Value)
 int ArmorAbsorbDamage(int Damage, name DamageType, vector HitLocation)
     
//
// Absorb damage.
//
 void ArmorImpactEffect(vector HitLocation)
     
//
// This function is called by ArmorAbsorbDamage and displays a visual effect 
// for an impact on an armor.
//
 int ArmorPriority(name DamageType)
     
//
// Return armor value.
//
 void BecomeItem()
     
//
// Become an inventory item.
//
 void BecomePickup()
     
//
// Become a pickup.
//
 vector CalcDrawOffset()
     
//
// Compute offset for drawing.
//
 void ChangedWeapon()
     
//
// Used to inform inventory when owner weapon changes.
//
 void Destroyed()
     
//
// Called by engine when destroyed.
//
 
simulated
DrawStatusIconAt(Canvas Canvas, int X, int Y, optional float)
     
// overridable function to ask the inventory object to draw its StatusIcon
 void DropFrom(vector StartLocation)
     
//
// Toss this item out.
//
 void DropInventory()
 void Fire(float Value)
     
// Fire functions which must be implemented in child classes.
 String GetHumanName()
 void GiveTo(Pawn Other)
     
//
// Give this inventory item to a pawn.
//
 bool HandlePickupQuery(Inventory Item)
     
//
// Function which lets existing items in a pawn's inventory
// prevent the pawn from picking something up. Return true to abort pickup
// or if item handles pickup, otherwise keep going through inventory list.
//
 float InventoryCapsFloat(name Property, Pawn Other, Actor Test)
     
// For future use.
 string InventoryCapsString(name Property, Pawn Other, Actor Test)
 void OwnerJumped()
     
//
// Used to inform inventory when owner jumps.
//
 void PostBeginPlay()
 Inventory PrioritizeArmor(int Damage, name DamageType, vector HitLocation)
     
//
// Return the best armor to use.
//
 Weapon RecommendWeapon(out float, out int)
 int ReduceDamage(int Damage, name DamageType, vector HitLocation)
     
//
// Scan the player's inventory looking for items that reduce damage
// to the player.  If Armor's protection type matches DamageType, then no damage is taken.
// Returns the reduced damage.
//
 Inventory SelectNext()
     
//
// Select first activatable item.
//
 void SetOwnerDisplay()
     
// used to ask inventory if it needs to affect its owners display properties
 void SetRespawn()
     
//
// Set up respawn waiting if desired.
//
 Inventory SpawnCopy(Pawn Other)
     
// Either give this inventory to player Other, or spawn a copy
// and give it to the player Other, setting up original to be respawned.
//
 void Use(Pawn User)
 Weapon WeaponChange(byte F)
     
//
// Find a weapon in inventory that has an Inventory Group matching F.
//


State Idle2 Function Summary


State Sleeping Function Summary
 void ActivateTranslator(bool bHint)
 void EndState()
 void BeginState()


State Activated Function Summary
 void Activate()
 void EndState()
 void BeginState()


State Pickup Function Summary
 void EndState()
 void BeginState()
 void Timer()
 void CheckTouching()
     
// Make sure no pawn already touching (while touch was disabled in sleep).
 void Landed(Vector HitNormal)
     
// Landed on ground.
 void Touch(Actor Other)
     
// When touched by an actor.
 bool ValidTouch(Actor Other)
     
// Validate touch, and if valid trigger event.
 void ZoneChange(ZoneInfo NewZone)



Source Code


00001	//=============================================================================
00002	// The inventory class, the parent class of all objects which can be
00003	// picked up and carried by actors.
00004	//=============================================================================
00005	class Inventory extends Actor
00006		abstract
00007		native
00008		nativereplication;
00009	
00010	#exec Texture Import File=Textures\Inventry.pcx Name=S_Inventory Mips=Off Flags=2
00011	
00012	//-----------------------------------------------------------------------------
00013	// Information relevant to Active/Inactive state.
00014	
00015	var() travel byte AutoSwitchPriority; // Autoswitch value, 0=never autoswitch.
00016	var() byte        InventoryGroup;     // The weapon/inventory set, 1-9 (0=none).
00017	var() bool        bActivatable;       // Whether item can be activated.
00018	var() bool	 	  bDisplayableInv;	  // Item displayed in HUD.
00019	var	travel bool   bActive;			  // Whether item is currently activated.
00020	var	  bool		  bSleepTouch;		  // Set when item is touched when leaving sleep state.
00021	var	  bool		  bHeldItem;		  // Set once an item has left pickup state.
00022	var	  bool	  bTossedOut;			  // true if weapon was tossed out (so players can't cheat w/ weaponstay)
00023	
00024	//-----------------------------------------------------------------------------
00025	// Ambient glow related info.
00026	
00027	var(Display) bool bAmbientGlow;		  // Whether to glow or not.
00028	
00029	//-----------------------------------------------------------------------------
00030	// Information relevant to Pickup state.
00031	
00032	var() bool		bInstantRespawn;	  // Can be tagged so this item respawns instantly.
00033	var() bool		bRotatingPickup;	  // Rotates when in pickup state.
00034	var() localized string PickupMessage; // Human readable description when picked up.
00035	var() localized string ItemName;      // Human readable name of item
00036	var() localized string ItemArticle;   // Human readable article (e.g. "a", "an")
00037	var() float     RespawnTime;          // Respawn after this time, 0 for instant.
00038	var name 		PlayerLastTouched;    // Player who last touched this item.
00039	
00040	//-----------------------------------------------------------------------------
00041	// Rendering information.
00042	
00043	// Player view rendering info.
00044	var() vector      PlayerViewOffset;   // Offset from view center.
00045	var() mesh        PlayerViewMesh;     // Mesh to render.
00046	var() float       PlayerViewScale;    // Mesh scale.
00047	var() float		  BobDamping;		  // how much to damp view bob
00048	
00049	// Pickup view rendering info.
00050	var() mesh        PickupViewMesh;     // Mesh to render.
00051	var() float       PickupViewScale;    // Mesh scale.
00052	
00053	// 3rd person mesh.
00054	var() mesh        ThirdPersonMesh;    // Mesh to render.
00055	var() float       ThirdPersonScale;   // Mesh scale.
00056	
00057	//-----------------------------------------------------------------------------
00058	// Status bar info.
00059	
00060	var() texture     StatusIcon;         // Icon used with ammo/charge/power count.
00061	
00062	//-----------------------------------------------------------------------------
00063	// Armor related info.
00064	
00065	var() name		  ProtectionType1;	  // Protects against DamageType (None if non-armor).
00066	var() name		  ProtectionType2;	  // Secondary protection type (None if non-armor).
00067	var() travel int  Charge;			  // Amount of armor or charge if not an armor (charge in time*10).
00068	var() int		  ArmorAbsorption;	  // Percent of damage item absorbs 0-100.
00069	var() bool		  bIsAnArmor;		  // Item will protect player.
00070	var() int		  AbsorptionPriority; // Which items absorb damage first (higher=first).
00071	var() inventory	  NextArmor;		  // Temporary list created by Armors to prioritize damage absorption.
00072	
00073	//-----------------------------------------------------------------------------
00074	// AI related info.
00075	
00076	var() float		  MaxDesireability;	  // Maximum desireability this item will ever have.
00077	var	  InventorySpot MyMarker;
00078	
00079	//-----------------------------------------------------------------------------
00080	// 3rd person muzzleflash
00081	
00082	var bool bSteadyFlash3rd;
00083	var bool bFirstFrame;
00084	var(MuzzleFlash) bool bMuzzleFlashParticles;
00085	var(MuzzleFlash) bool bToggleSteadyFlash;
00086	var bool	bSteadyToggle;
00087	var byte FlashCount, OldFlashCount;
00088	var(MuzzleFlash) ERenderStyle MuzzleFlashStyle;
00089	var(MuzzleFlash) mesh MuzzleFlashMesh;
00090	var(MuzzleFlash) float MuzzleFlashScale;
00091	var(MuzzleFlash) texture MuzzleFlashTexture;
00092	
00093	//-----------------------------------------------------------------------------
00094	// Sound assignments.
00095	
00096	var() sound PickupSound, ActivateSound, DeActivateSound, RespawnSound;
00097	
00098	//-----------------------------------------------------------------------------
00099	// HUD graphics.
00100	
00101	var() texture Icon;
00102	var() localized String M_Activated;
00103	var() localized String M_Selected;
00104	var() localized String M_Deactivated;
00105	
00106	//-----------------------------------------------------------------------------
00107	// Messaging
00108	
00109	var() class<LocalMessage> PickupMessageClass;
00110	var() class<LocalMessage> ItemMessageClass;
00111	
00112	// Network replication.
00113	replication
00114	{
00115		// Things the server should send to the client.
00116		reliable if( Role==ROLE_Authority && bNetOwner )
00117			bIsAnArmor, Charge, bActivatable, bActive, PlayerViewOffset, PlayerViewMesh, PlayerViewScale;
00118		unreliable if( Role==ROLE_Authority )
00119			FlashCount, bSteadyFlash3rd, ThirdPersonMesh, ThirdPersonScale;
00120	}
00121	
00122	function PostBeginPlay()
00123	{
00124		if ( ItemName == "" )
00125			ItemName = GetItemName(string(Class));
00126	
00127		Super.PostBeginPlay();
00128	}
00129	
00130	// Draw first person view of inventory
00131	simulated event RenderOverlays( canvas Canvas )
00132	{
00133		if ( Owner == None )
00134			return;
00135		if ( (Level.NetMode == NM_Client) && (!Owner.IsA('PlayerPawn') || (PlayerPawn(Owner).Player == None)) )
00136			return;
00137		SetLocation( Owner.Location + CalcDrawOffset() );
00138		SetRotation( Pawn(Owner).ViewRotation );
00139		Canvas.DrawActor(self, false);
00140	}
00141	
00142	function String GetHumanName()
00143	{
00144		return ItemArticle@ItemName;
00145	}
00146	
00147	// overridable function to ask the inventory object to draw its StatusIcon
00148	simulated function DrawStatusIconAt( canvas Canvas, int X, int Y, optional float Scale )
00149	{
00150		if( Scale == 0.0 )
00151			Scale = 1.0;
00152		Canvas.SetPos( X, Y );
00153		Canvas.DrawIcon( StatusIcon, Scale );
00154	}
00155	
00156	//=============================================================================
00157	// AI inventory functions.
00158	
00159	event float BotDesireability( pawn Bot )
00160	{
00161		local Inventory AlreadyHas;
00162		local float desire;
00163		local bool bChecked;
00164	
00165		desire = MaxDesireability;
00166	
00167		if ( RespawnTime < 10 )
00168		{
00169			bChecked = true;
00170			AlreadyHas = Bot.FindInventoryType(class); 
00171			if ( (AlreadyHas != None) 
00172				&& (AlreadyHas.Charge >= Charge) )
00173					return -1;
00174		}
00175	
00176		if( bIsAnArmor )
00177		{
00178			if ( !bChecked )
00179				AlreadyHas = Bot.FindInventoryType(class); 
00180			if ( AlreadyHas != None )
00181				desire *= (1 - AlreadyHas.Charge * AlreadyHas.ArmorAbsorption * 0.00003);
00182			
00183			desire *= (Charge * 0.005);
00184			desire *= (ArmorAbsorption * 0.01);
00185			return desire;
00186		}
00187		else return desire;
00188	}
00189	
00190	function Weapon RecommendWeapon( out float rating, out int bUseAltMode )
00191	{
00192		if ( inventory != None )
00193			return inventory.RecommendWeapon(rating, bUseAltMode);
00194		else
00195		{
00196			rating = -1;
00197			return None;
00198		}
00199	}
00200	
00201	//=============================================================================
00202	// Inventory travelling across servers.
00203	
00204	//
00205	// Called after a travelling inventory item has been accepted into a level.
00206	//
00207	event TravelPreAccept()
00208	{
00209		Super.TravelPreAccept();
00210		GiveTo( Pawn(Owner) );
00211		if( bActive )
00212			Activate();
00213	}
00214	
00215	//=============================================================================
00216	// General inventory functions.
00217	
00218	//
00219	// Called by engine when destroyed.
00220	//
00221	function Destroyed()
00222	{
00223		if (MyMarker != None )
00224			MyMarker.markedItem = None;		
00225		// Remove from owner's inventory.
00226		if( Pawn(Owner)!=None )
00227			Pawn(Owner).DeleteInventory( Self );
00228	}
00229	
00230	//
00231	// Compute offset for drawing.
00232	//
00233	simulated final function vector CalcDrawOffset()
00234	{
00235		local vector DrawOffset, WeaponBob;
00236		local Pawn PawnOwner;
00237	
00238		PawnOwner = Pawn(Owner);
00239		DrawOffset = ((0.9/PawnOwner.FOVAngle * PlayerViewOffset) >> PawnOwner.ViewRotation);
00240	
00241		if ( (Level.NetMode == NM_DedicatedServer) 
00242			|| ((Level.NetMode == NM_ListenServer) && (Owner.RemoteRole == ROLE_AutonomousProxy)) )
00243			DrawOffset += (PawnOwner.BaseEyeHeight * vect(0,0,1));
00244		else
00245		{	
00246			DrawOffset += (PawnOwner.EyeHeight * vect(0,0,1));
00247			WeaponBob = BobDamping * PawnOwner.WalkBob;
00248			WeaponBob.Z = (0.45 + 0.55 * BobDamping) * PawnOwner.WalkBob.Z;
00249			DrawOffset += WeaponBob;
00250		}
00251		return DrawOffset;
00252	}
00253	
00254	//
00255	// Become a pickup.
00256	//
00257	function BecomePickup()
00258	{
00259		if ( Physics != PHYS_Falling )
00260			RemoteRole    = ROLE_SimulatedProxy;
00261		Mesh          = PickupViewMesh;
00262		DrawScale     = PickupViewScale;
00263		bOnlyOwnerSee = false;
00264		bHidden       = false;
00265		bCarriedItem  = false;
00266		NetPriority   = 1.4;
00267		SetCollision( true, false, false );
00268	}
00269	
00270	//
00271	// Become an inventory item.
00272	//
00273	function BecomeItem()
00274	{
00275		RemoteRole    = ROLE_SimulatedProxy;
00276		Mesh          = PlayerViewMesh;
00277		DrawScale     = PlayerViewScale;
00278		bOnlyOwnerSee = true;
00279		bHidden       = true;
00280		bCarriedItem  = true;
00281		NetPriority   = 1.4;
00282		SetCollision( false, false, false );
00283		SetPhysics(PHYS_None);
00284		SetTimer(0.0,False);
00285		AmbientGlow = 0;
00286	}
00287	
00288	//
00289	// Give this inventory item to a pawn.
00290	//
00291	function GiveTo( pawn Other )
00292	{
00293		Instigator = Other;
00294		BecomeItem();
00295		Other.AddInventory( Self );
00296		GotoState('Idle2');
00297	}
00298	
00299	// Either give this inventory to player Other, or spawn a copy
00300	// and give it to the player Other, setting up original to be respawned.
00301	//
00302	function inventory SpawnCopy( pawn Other )
00303	{
00304		local inventory Copy;
00305		if( Level.Game.ShouldRespawn(self) )
00306		{
00307			Copy = spawn(Class,Other,,,rot(0,0,0));
00308			Copy.Tag           = Tag;
00309			Copy.Event         = Event;
00310			GotoState('Sleeping');
00311		}
00312		else
00313			Copy = self;
00314	
00315		Copy.RespawnTime = 0.0;
00316		Copy.bHeldItem = true;
00317		Copy.GiveTo( Other );
00318		return Copy;
00319	}
00320	
00321	//
00322	// Set up respawn waiting if desired.
00323	//
00324	function SetRespawn()
00325	{
00326		if( Level.Game.ShouldRespawn(self) )
00327			GotoState('Sleeping');
00328		else
00329			Destroy();
00330	}
00331	
00332	
00333	//
00334	// Toggle Activation of selected Item.
00335	// 
00336	function Activate()
00337	{
00338		if( bActivatable )
00339		{
00340			if (Level.Game.LocalLog != None)
00341				Level.Game.LocalLog.LogItemActivate(Self, Pawn(Owner));
00342			if (Level.Game.WorldLog != None)
00343				Level.Game.WorldLog.LogItemActivate(Self, Pawn(Owner));
00344	
00345			if ( M_Activated != "" )
00346				Pawn(Owner).ClientMessage(ItemName$M_Activated);	
00347			GoToState('Activated');
00348		}
00349	}
00350	
00351	//
00352	// Function which lets existing items in a pawn's inventory
00353	// prevent the pawn from picking something up. Return true to abort pickup
00354	// or if item handles pickup, otherwise keep going through inventory list.
00355	//
00356	function bool HandlePickupQuery( inventory Item )
00357	{
00358		if ( Item.Class == Class )
00359			return true;
00360		if ( Inventory == None )
00361			return false;
00362	
00363		return Inventory.HandlePickupQuery(Item);
00364	}
00365	
00366	//
00367	// Select first activatable item.
00368	//
00369	function Inventory SelectNext()
00370	{
00371		if ( bActivatable ) 
00372		{
00373			if ( M_Selected != "" )
00374				Pawn(Owner).ClientMessage(ItemName$M_Selected);
00375			return self;
00376		}
00377		if ( Inventory != None )
00378			return Inventory.SelectNext();
00379		else
00380			return None;
00381	}
00382	
00383	//
00384	// Toss this item out.
00385	//
00386	function DropFrom(vector StartLocation)
00387	{
00388		if ( !SetLocation(StartLocation) )
00389			return; 
00390		RespawnTime = 0.0; //don't respawn
00391		SetPhysics(PHYS_Falling);
00392		RemoteRole = ROLE_DumbProxy;
00393		BecomePickup();
00394		NetPriority = 2.5;
00395		NetUpdateFrequency = 20;
00396		bCollideWorld = true;
00397		if ( Pawn(Owner) != None )
00398			Pawn(Owner).DeleteInventory(self);
00399		Inventory = None;
00400		GotoState('PickUp', 'Dropped');
00401	}
00402	
00403	function DropInventory()
00404	{
00405	}
00406	
00407	//=============================================================================
00408	// Capabilities: For feeding general info to bots.
00409	
00410	// For future use.
00411	function float InventoryCapsFloat( name Property, pawn Other, actor Test );
00412	function string InventoryCapsString( name Property, pawn Other, actor Test );
00413	
00414	//=============================================================================
00415	// Firing/using.
00416	
00417	// Fire functions which must be implemented in child classes.
00418	function Fire( float Value );
00419	function AltFire( float Value );
00420	function Use( pawn User );
00421	
00422	//=============================================================================
00423	// Weapon functions.
00424	
00425	//
00426	// Find a weapon in inventory that has an Inventory Group matching F.
00427	//
00428	
00429	function Weapon WeaponChange( byte F )
00430	{
00431		if( Inventory == None)
00432			return None;
00433		else
00434			return Inventory.WeaponChange( F );
00435	}
00436	
00437	//=============================================================================
00438	// Armor functions.
00439	
00440	//
00441	// Scan the player's inventory looking for items that reduce damage
00442	// to the player.  If Armor's protection type matches DamageType, then no damage is taken.
00443	// Returns the reduced damage.
00444	//
00445	function int ReduceDamage( int Damage, name DamageType, vector HitLocation )
00446	{
00447		local Inventory FirstArmor;
00448		local int ReducedAmount,ArmorDamage;
00449		
00450		if( Damage<0 )
00451			return 0;
00452		
00453		ReducedAmount = Damage;
00454		FirstArmor = PrioritizeArmor(Damage, DamageType, HitLocation);
00455		while( (FirstArmor != None) && (ReducedAmount > 0) )
00456		{
00457			ReducedAmount = FirstArmor.ArmorAbsorbDamage(ReducedAmount, DamageType, HitLocation);
00458			FirstArmor = FirstArmor.nextArmor;
00459		} 
00460		return ReducedAmount;
00461	}
00462	
00463	//
00464	// Return the best armor to use.
00465	//
00466	function inventory PrioritizeArmor( int Damage, name DamageType, vector HitLocation )
00467	{
00468		local Inventory FirstArmor, InsertAfter;
00469	
00470		if ( Inventory != None )
00471			FirstArmor = Inventory.PrioritizeArmor(Damage, DamageType, HitLocation);
00472		else
00473			FirstArmor = None;
00474	
00475		if ( bIsAnArmor)
00476		{
00477			if ( FirstArmor == None )
00478			{
00479				nextArmor = None;
00480				return self;
00481			}
00482	
00483			// insert this armor into the prioritized armor list
00484			if ( FirstArmor.ArmorPriority(DamageType) < ArmorPriority(DamageType) )
00485			{
00486				nextArmor = FirstArmor;
00487				return self;
00488			}
00489			InsertAfter = FirstArmor;
00490			while ( (InsertAfter.nextArmor != None) 
00491				&& (InsertAfter.nextArmor.ArmorPriority(DamageType) > ArmorPriority(DamageType)) )
00492				InsertAfter = InsertAfter.nextArmor;
00493	
00494			nextArmor = InsertAfter.nextArmor;
00495			InsertAfter.nextArmor = self;
00496		}
00497		return FirstArmor;
00498	}
00499	
00500	//
00501	// Absorb damage.
00502	//
00503	function int ArmorAbsorbDamage(int Damage, name DamageType, vector HitLocation)
00504	{
00505		local int ArmorDamage;
00506	
00507		if ( DamageType != 'Drowned' )
00508			ArmorImpactEffect(HitLocation);
00509		if( (DamageType!='None') && ((ProtectionType1==DamageType) || (ProtectionType2==DamageType)) )
00510			return 0;
00511		
00512		if (DamageType=='Drowned') Return Damage;
00513		
00514		ArmorDamage = (Damage * ArmorAbsorption) / 100;
00515		if( ArmorDamage >= Charge )
00516		{
00517			ArmorDamage = Charge;
00518			Destroy();
00519		}
00520		else 
00521			Charge -= ArmorDamage;
00522		return (Damage - ArmorDamage);
00523	}
00524	
00525	//
00526	// Return armor value.
00527	//
00528	function int ArmorPriority(name DamageType)
00529	{
00530		if ( DamageType == 'Drowned' )
00531			return 0;
00532		if( (DamageType!='None') 
00533			&& ((ProtectionType1==DamageType) || (ProtectionType2==DamageType)) )
00534			return 1000000;
00535	
00536		return AbsorptionPriority;
00537	}
00538	
00539	//
00540	// This function is called by ArmorAbsorbDamage and displays a visual effect 
00541	// for an impact on an armor.
00542	//
00543	function ArmorImpactEffect(vector HitLocation){ }
00544	
00545	//
00546	// Used to inform inventory when owner jumps.
00547	//
00548	function OwnerJumped()
00549	{
00550		if( Inventory != None )
00551			Inventory.OwnerJumped();
00552	}
00553	
00554	//
00555	// Used to inform inventory when owner weapon changes.
00556	//
00557	function ChangedWeapon()
00558	{
00559		if( Inventory != None )
00560			Inventory.ChangedWeapon();
00561	}
00562	
00563	// used to ask inventory if it needs to affect its owners display properties
00564	function SetOwnerDisplay()
00565	{
00566		if( Inventory != None )
00567			Inventory.SetOwnerDisplay();
00568	}
00569	
00570	//=============================================================================
00571	// Pickup state: this inventory item is sitting on the ground.
00572	
00573	auto state Pickup
00574	{
00575		singular function ZoneChange( ZoneInfo NewZone )
00576		{
00577			local float splashsize;
00578			local actor splash;
00579	
00580			if( NewZone.bWaterZone && !Region.Zone.bWaterZone ) 
00581			{
00582				splashSize = 0.000025 * Mass * (250 - 0.5 * Velocity.Z);
00583				if ( NewZone.EntrySound != None )
00584					PlaySound(NewZone.EntrySound, SLOT_Interact, splashSize);
00585				if ( NewZone.EntryActor != None )
00586				{
00587					splash = Spawn(NewZone.EntryActor); 
00588					if ( splash != None )
00589						splash.DrawScale = 2 * splashSize;
00590				}
00591			}
00592		}
00593	
00594		// Validate touch, and if valid trigger event.
00595		function bool ValidTouch( actor Other )
00596		{
00597			local Actor A;
00598	
00599			if( Other.bIsPawn && Pawn(Other).bIsPlayer && (Pawn(Other).Health > 0) && Level.Game.PickupQuery(Pawn(Other), self) )
00600			{
00601				if( Event != '' )
00602					foreach AllActors( class 'Actor', A, Event )
00603						A.Trigger( Other, Other.Instigator );
00604				return true;
00605			}
00606			return false;
00607		}
00608			
00609		// When touched by an actor.
00610		function Touch( actor Other )
00611		{
00612			// If touched by a player pawn, let him pick this up.
00613			if( ValidTouch(Other) )
00614			{
00615				if (Level.Game.LocalLog != None)
00616					Level.Game.LocalLog.LogPickup(Self, Pawn(Other));
00617				if (Level.Game.WorldLog != None)
00618					Level.Game.WorldLog.LogPickup(Self, Pawn(Other));
00619				SpawnCopy(Pawn(Other));
00620				if ( PickupMessageClass == None )
00621					Pawn(Other).ClientMessage(PickupMessage, 'Pickup');
00622				else
00623					Pawn(Other).ReceiveLocalizedMessage( PickupMessageClass, 0, None, None, Self.Class );
00624				PlaySound (PickupSound);		
00625				if ( Level.Game.Difficulty > 1 )
00626					Other.MakeNoise(0.1 * Level.Game.Difficulty);
00627				if ( Pawn(Other).MoveTarget == self )
00628					Pawn(Other).MoveTimer = -1.0;		
00629			}
00630			else if ( bTossedOut && (Other.Class == Class)
00631					&& Inventory(Other).bTossedOut )
00632					Destroy();
00633		}
00634	
00635		// Landed on ground.
00636		function Landed(Vector HitNormal)
00637		{
00638			local rotator newRot;
00639			newRot = Rotation;
00640			newRot.pitch = 0;
00641			netUpdateFrequency = Default.NetUpdateFrequency;
00642			SetRotation(newRot);
00643			SetTimer(2.0, false);
00644		}
00645	
00646		// Make sure no pawn already touching (while touch was disabled in sleep).
00647		function CheckTouching()
00648		{
00649			local int i;
00650	
00651			bSleepTouch = false;
00652			for ( i=0; i<4; i++ )
00653				if ( (Touching[i] != None) && Touching[i].IsA('Pawn') )
00654					Touch(Touching[i]);
00655		}
00656	
00657		function Timer()
00658		{
00659			if ( RemoteRole != ROLE_SimulatedProxy )
00660			{
00661				NetPriority = 1.4;
00662				RemoteRole = ROLE_SimulatedProxy;
00663				if ( bHeldItem )
00664				{
00665					if ( bTossedOut )
00666						SetTimer(15.0, false);
00667					else
00668						SetTimer(40.0, false);
00669				}
00670				return;
00671			}
00672	
00673			if ( bHeldItem )
00674			{
00675				if (  (FRand() < 0.1) || !PlayerCanSeeMe() )
00676					Destroy();
00677				else
00678					SetTimer(3.0, true);
00679			}
00680		}
00681	
00682		function BeginState()
00683		{
00684			BecomePickup();
00685			bCollideWorld = true;
00686			if ( bHeldItem )
00687				SetTimer(30, false);
00688			else if ( Level.bStartup )
00689			{
00690				bAlwaysRelevant = true;
00691				NetUpdateFrequency = 8;
00692			}
00693		}
00694	
00695		function EndState()
00696		{
00697			bCollideWorld = false;
00698			bSleepTouch = false;
00699		}
00700	
00701	Begin:
00702		BecomePickup();
00703		if ( bRotatingPickup && (Physics != PHYS_Falling) )
00704			SetPhysics(PHYS_Rotating);
00705	
00706	Dropped:
00707		if( bAmbientGlow )
00708			AmbientGlow=255;
00709		if( bSleepTouch )
00710			CheckTouching();
00711	}
00712	
00713	//=============================================================================
00714	// Active state: this inventory item is armed and ready to rock!
00715	
00716	state Activated
00717	{
00718		function BeginState()
00719		{
00720			bActive = true;
00721			if ( Pawn(Owner).bIsPlayer && (ProtectionType1 != '') )
00722				Pawn(Owner).ReducedDamageType = ProtectionType1;
00723		}
00724	
00725		function EndState()
00726		{
00727			bActive = false;
00728			if ( (Pawn(Owner) != None)
00729				&& Pawn(Owner).bIsPlayer && (ProtectionType1 != '') )
00730				Pawn(Owner).ReducedDamageType = '';
00731		}
00732	
00733		function Activate()
00734		{
00735			if ( (Pawn(Owner) != None) && (M_Deactivated != "") )
00736				Pawn(Owner).ClientMessage(ItemName$M_Deactivated);	
00737			GoToState('DeActivated');	
00738		}
00739	}
00740	
00741	//=============================================================================
00742	// Sleeping state: Sitting hidden waiting to respawn.
00743	
00744	State Sleeping
00745	{
00746		ignores Touch;
00747	
00748		function BeginState()
00749		{
00750			BecomePickup();
00751			bHidden = true;
00752		}
00753		function EndState()
00754		{
00755			local int i;
00756	
00757			bSleepTouch = false;
00758			for ( i=0; i<4; i++ )
00759				if ( (Touching[i] != None) && Touching[i].IsA('Pawn') )
00760					bSleepTouch = true;
00761		}			
00762	Begin:
00763		Sleep( ReSpawnTime );
00764		PlaySound( RespawnSound );	
00765		Sleep( Level.Game.PlaySpawnEffect(self) );
00766		GoToState( 'Pickup' );
00767	}
00768	
00769	function ActivateTranslator(bool bHint)
00770	{
00771		if( Inventory!=None )
00772			Inventory.ActivateTranslator( bHint );
00773	}
00774	
00775	//
00776	// Null state.
00777	//
00778	State Idle2
00779	{
00780	}
00781	
00782	defaultproperties
00783	{
00784	     bAmbientGlow=True
00785	     bRotatingPickup=True
00786	     PickupMessage="Snagged an item."
00787	     ItemArticle="a"
00788	     PlayerViewScale=1.000000
00789	     BobDamping=0.960000
00790	     PickupViewScale=1.000000
00791	     ThirdPersonScale=1.000000
00792	     MaxDesireability=0.005000
00793	     bFirstFrame=True
00794	     bToggleSteadyFlash=True
00795	     M_Activated=" activated."
00796	     M_Selected=" selected."
00797	     M_Deactivated=" deactivated."
00798	     RemoteRole=ROLE_SimulatedProxy
00799	     DrawType=DT_Mesh
00800	     Texture=Texture'Engine.S_Inventory'
00801	     AmbientGlow=255
00802	     bIsItemGoal=True
00803	     bTravel=True
00804	     CollisionRadius=30.000000
00805	     CollisionHeight=30.000000
00806	     bCollideActors=True
00807	     bFixedRotationDir=True
00808	     RotationRate=(Yaw=5000)
00809	     DesiredRotation=(Yaw=30000)
00810	     NetPriority=1.400000
00811	     NetUpdateFrequency=10.000000
00812	}

End Source Code