## Engine
Class Pickup

source: C:\XIII\Engine\Classes\Pickup.uc

    Core.Object
       |
       +--Engine.Actor
          |
          +--Engine.Pickup

Direct Known Subclasses:Ammo, ArmorPickup, WeaponPickup, MultiplayerMedPickup, XIIIDecoPickup, XIIIPickup, MarioPickUp, MarioSuperBonusPickUp

class Pickup
extends Engine.Actor

    //=============================================================================
    // Pickup items.
    //
    // Pickup is the base class of actors that when touched by an appropriate pawn,
    // will create and place an Inventory actor in that pawn's inventory chain.  Each
    // pickup class has an associated inventory class (its InventoryType).  Pickups are
    // placed by level designers.  Pickups can only interact with pawns when in their
    // default Pickup state.  Pickups verify that they can give inventory to a pawn by
    // calling the GameInfo's PickupQuery() function.  After a pickup spawns an inventory
    // item for a pawn, it then queries the GameInfo by calling the GameInfo's
    // ShouldRespawn() function about whether it should remain active, enter its Sleep
    // state and later become active again, or destroy itself.
    //
    // When navigation paths are built, each pickup has an InventorySpot (a subclass
    // of NavigationPoint) placed on it and associated with it
    // (the Pickup's MyMarker== the InventorySpot,
    // and the InventorySpot's markedItem == the pickup).
    //
    //=============================================================================

Variables
`class` | `InventoryType` Inventory class to spawn when picking up.
`float` | `MaxDesireability` Maximum desireability this item will ever have.
`InventorySpot` | `MyMarker` assigned when rebulding paths w/ bLonePlayer=false
`string` | `PickupMessage` Human readable description when picked up.
`sound` | `PickupSound` Human readable description when picked up.
`float` | `RespawnTime` Respawn after this time, 0 for instant.
`bool` | `bInstantRespawn` Can be tagged so this item respawns instantly.
`bool` | `bOnlyReplicateHidden` only replicate changes in bHidden (optimization for level pickups)
`sound` | `hRespawnSound` Human readable description when picked up.

States
Sleeping, Pickup

Function Summary
`void` | `AnnouncePickup(Pawn Receiver)`
    //_____________________________________________________________________________
`float` | `BotDesireability(Pawn Bot)`
    /* Pickups have an AI interface to allow AIControllers, such as bots, to assess the
     desireability of acquiring that pickup.  The BotDesireability() method returns a
     float typically between 0 and 1 describing how valuable the pickup is to the
     AIController.  This method is called when an AIController uses the
     FindPathToBestInventory() navigation intrinsic.
    */
`string` | `GetLocalString(optional int, optional PlayerReplicationInfo, optional PlayerReplicationInfo)`
    //_____________________________________________________________________________
    // HUD Messages
`void` | `InitDroppedPickupFor(Inventory Inv)`
    //_____________________________________________________________________________
`void` | `MatchStarting()`
    //_____________________________________________________________________________
`simulated` | `PostBeginPlay()`
    //_____________________________________________________________________________
`bool` | `ReadyToPickup(float MaxWait)`
    //_____________________________________________________________________________
`void` | `Reset()`
    //_____________________________________________________________________________
    // reset actor to initial state - used when restarting level without reloading.
`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` | `StartSleeping()`
    //_____________________________________________________________________________

State Sleeping Function Summary
`void` | `StartSleeping()`
`bool` | `ReadyToPickup(float MaxWait)`

State Pickup Function Summary
`void` | `Timer()`
`void` | `CheckTouching()`
    // Make sure no pawn already touching (while touch was disabled in sleep).
`bool` | `ValidTouch(Actor Other)`
        /* ValidTouch()
        Validate touch (if valid return true to let other pick me up and trigger event).
        */
`bool` | `ReadyToPickup(float MaxWait)`

Source Code

    00001	//=============================================================================
    00002	// Pickup items.
    00003	//
    00004	// Pickup is the base class of actors that when touched by an appropriate pawn,
    00005	// will create and place an Inventory actor in that pawn's inventory chain.  Each
    00006	// pickup class has an associated inventory class (its InventoryType).  Pickups are
    00007	// placed by level designers.  Pickups can only interact with pawns when in their
    00008	// default Pickup state.  Pickups verify that they can give inventory to a pawn by
    00009	// calling the GameInfo's PickupQuery() function.  After a pickup spawns an inventory
    00010	// item for a pawn, it then queries the GameInfo by calling the GameInfo's
    00011	// ShouldRespawn() function about whether it should remain active, enter its Sleep
    00012	// state and later become active again, or destroy itself.
    00013	//
    00014	// When navigation paths are built, each pickup has an InventorySpot (a subclass
    00015	// of NavigationPoint) placed on it and associated with it
    00016	// (the Pickup's MyMarker== the InventorySpot,
    00017	// and the InventorySpot's markedItem == the pickup).
    00018	//
    00019	//=============================================================================
    00020	class Pickup extends Actor
    00021	    abstract
    00022	    placeable
    00023	    native
    00024	    nativereplication;
    00025
    00026	//_____________________________________________________________________________
    00027	// AI related info.
    00028	var() bool bInstantRespawn;             // Can be tagged so this item respawns instantly.
    00029	var bool bOnlyReplicateHidden;          // only replicate changes in bHidden (optimization for level pickups)
    00030	var(Display) bool bAmbientGlow;         // Whether to glow or not.
    00031	var() float MaxDesireability;           // Maximum desireability this item will ever have.
    00032	var InventorySpot MyMarker;             // assigned when rebulding paths w/ bLonePlayer=false
    00033	var() class<Inventory> InventoryType;   // Inventory class to spawn when picking up.
    00034	var() float RespawnTime;                // Respawn after this time, 0 for instant.
    00035	var() localized string PickupMessage;   // Human readable description when picked up.
    00036	var() sound PickupSound;
    00037	var() sound hRespawnSound;
    00038
    00039	//_____________________________________________________________________________
    00040	simulated function PostBeginPlay()
    00041	{
    00042	    if ( !Level.bLonePlayer )
    00043	      SetDrawScale(1.5); // MULTI, ALL Pickups SCALED UP
    00044	    Super.PostBeginPlay();
    00045	}
    00046
    00047	//_____________________________________________________________________________
    00048	// Called when picked up on clients/on-line players = called on bHidden replication received
    00049	simulated event ClientPickedUp()
    00050	{
    00051	    if ( Level.NetMode != NM_StandAlone )
    00052	    { // on-line only play pickup sound
    00053	//      Log(Self@"SND ClientPickedUp"@PickupSound);
    00054	      PlaySound(PickupSound);
    00055	    }
    00056	}
    00057
    00058	//_____________________________________________________________________________
    00059	simulated event ClientRespawned()
    00060	{
    00061	//    Log("PICKUP SND CLIENTRESPAWN"@hRespawnSound);
    00062	    PlaySound(hRespawnSound);
    00063	}
    00064
    00065	//_____________________________________________________________________________
    00066	function MatchStarting()
    00067	{
    00068	    if ( ! Level.bLonePlayer )
    00069	    {
    00070	        if (MyMarker == none )
    00071	           Destroy();
    00072	        else
    00073	            Reset();
    00074	    }
    00075	}
    00076
    00077	//_____________________________________________________________________________
    00078	event Destroyed()
    00079	{
    00080	    if (MyMarker != None )
    00081	      MyMarker.markedItem = None;
    00082	    if (Inventory != None )
    00083	      Inventory.Destroy();
    00084	}
    00085
    00086	//_____________________________________________________________________________
    00087	// reset actor to initial state - used when restarting level without reloading.
    00088	function Reset()
    00089	{
    00090	    if ( Inventory != None )
    00091	      destroy();
    00092	    else
    00093	    {
    00094	      GotoState('Pickup');
    00095	      Super.Reset();
    00096	    }
    00097	}
    00098
    00099	//_____________________________________________________________________________
    00100	/* Pickups have an AI interface to allow AIControllers, such as bots, to assess the
    00101	 desireability of acquiring that pickup.  The BotDesireability() method returns a
    00102	 float typically between 0 and 1 describing how valuable the pickup is to the
    00103	 AIController.  This method is called when an AIController uses the
    00104	 FindPathToBestInventory() navigation intrinsic.
    00105	*/
    00106	function float BotDesireability( pawn Bot )
    00107	{
    00108	    local Inventory AlreadyHas;
    00109	    local float desire;
    00110
    00111	    desire = MaxDesireability;
    00112
    00113	    if ( RespawnTime < 10 )
    00114	    {
    00115	      AlreadyHas = Bot.FindInventoryType(InventoryType);
    00116	      if ( AlreadyHas != None )
    00117	      {
    00118	        if ( Inventory != None )
    00119	        {
    00120	          if( Inventory.Charge <= AlreadyHas.Charge )
    00121	            return -1;
    00122	        }
    00123	        else if ( InventoryType.Default.Charge <= AlreadyHas.Charge )
    00124	          return -1;
    00125	      }
    00126	    }
    00127	    return desire;
    00128	}
    00129
    00130	//_____________________________________________________________________________
    00131	// Either give this inventory to player Other, or spawn a copy
    00132	// and give it to the player Other, setting up original to be respawned.
    00133	function inventory SpawnCopy( pawn Other )
    00134	{
    00135	    local inventory Copy;
    00136
    00137	    if ( Inventory != None )
    00138	    {
    00139	      Copy = Inventory;
    00140	      Inventory = None;
    00141	    }
    00142	    else
    00143	      Copy = spawn(InventoryType,Other,,,rot(0,0,0));
    00144
    00145	    Copy.GiveTo( Other );
    00146	    if( Level.Game.ShouldRespawn(self) )
    00147	      StartSleeping();
    00148	    else
    00149	      Destroy();
    00150	    return Copy;
    00151	}
    00152
    00153	//_____________________________________________________________________________
    00154	function StartSleeping()
    00155	{
    00156	    GotoState('Sleeping');
    00157	}
    00158
    00159	//_____________________________________________________________________________
    00160	function AnnouncePickup( Pawn Receiver )
    00161	{
    00162	    Receiver.HandlePickup(self);
    00163	    if ( Level.Game.StatLog != None )
    00164	      Level.Game.StatLog.LogPickup(self, Receiver);
    00165	    SetRespawn();
    00166	}
    00167
    00168	//_____________________________________________________________________________
    00169	// Set up respawn waiting if desired.
    00170	function SetRespawn()
    00171	{
    00172	    if( Level.Game.ShouldRespawn(self) )
    00173	      GotoState('Sleeping');
    00174	    else
    00175	      Destroy();
    00176	}
    00177
    00178	//_____________________________________________________________________________
    00179	// HUD Messages
    00180	static function string GetLocalString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2 )
    00181	{
    00182	     return Default.PickupMessage;
    00183	}
    00184
    00185	//_____________________________________________________________________________
    00186	function InitDroppedPickupFor(Inventory Inv)
    00187	{
    00188	    bOnlyReplicateHidden = false;
    00189	    SetPhysics(PHYS_Falling);
    00190	    GotoState('');
    00191	    Inventory = Inv;
    00192	    bAlwaysRelevant = false;
    00193	    bMovable = true;
    00194	    RefreshDisplaying();
    00195	}
    00196
    00197	//_____________________________________________________________________________
    00198	function bool ReadyToPickup(float MaxWait)
    00199	{
    00200	    return false;
    00201	}
    00202
    00203	//_____________________________________________________________________________
    00204	event Landed(Vector HitNormal)
    00205	{
    00206	    GotoState('Pickup');
    00207	}
    00208
    00209	//_____________________________________________________________________________
    00210	// Pickup state: this inventory item is sitting on the ground.
    00211	auto state Pickup
    00212	{
    00213	    function bool ReadyToPickup(float MaxWait)
    00214	    {
    00215	      return true;
    00216	    }
    00217
    00218	    /* ValidTouch()
    00219	    Validate touch (if valid return true to let other pick me up and trigger event).
    00220	    */
    00221	    function bool ValidTouch( actor Other )
    00222	    {
    00223	      // make sure its a live player
    00224	      if ( (Pawn(Other) == None) || !Pawn(Other).bCanPickupInventory || (Pawn(Other).Health <= 0) )
    00225	        return false;
    00226
    00227	      // make sure not touching through wall
    00228	      // ELR take EyeHeight into account
    00229	      if ( !FastTrace(Other.Location+Pawn(Other).EyeHeight*vect(0,0,1), Location) )
    00230	        return false;
    00231
    00232	      // make sure game will let player pick me up
    00233	      if( Level.Game.PickupQuery(Pawn(Other), self) )
    00234	      {
    00235	        TriggerEvent(Event, self, Pawn(Other));
    00236	        return true;
    00237	      }
    00238	      return false;
    00239
} 00240 00241 // When touched by an actor. 00242 event Touch( actor Other ) 00243 { 00244 local Inventory Copy; 00245 00246 // If touched by a player pawn, let him pick this up. 00247 if( ValidTouch(Other) ) 00248 { 00249 Copy = SpawnCopy(Pawn(Other)); 00250 AnnouncePickup(Pawn(Other)); 00251 Copy.PickupFunction(Pawn(Other)); 00252 } 00253 // don't allow inventory to pile up (frame rate hit) 00254 else if ( (Inventory != None) && Other.IsA('Pickup') 00255 && (Pickup(Other).Inventory != None) ) 00256 { 00257 if ( Level.bLonePlayer ) 00258 { 00259 // ELR No destroy, push instead 00260 //Destroy(); 00261 Velocity = normal(Location - Other.Location) * 100 + vect(0,0,50); 00262 SetPhysics(PHYS_Falling); 00263 } 00264 else 00265 Destroy(); 00266 } 00267 } 00268 00269 // Make sure no pawn already touching (while touch was disabled in sleep). 00270 function CheckTouching() 00271 { 00272 local Pawn P; 00273 00274 ForEach TouchingActors(class'Pawn', P) 00275 Touch(P); 00276 } 00277 00278 function Timer() 00279 { 00280 if ( Inventory != None ) 00281 { 00282 if ( (FRand() < 0.1) || !PlayerCanSeeMe() ) 00283 Destroy(); 00284 else 00285 SetTimer(3.0, true); 00286 } 00287 } 00288 00289 event BeginState() 00290 { 00291 bOnlyReplicateHidden = true; 00292 if ( Inventory != None ) 00293 SetTimer(20, false); 00294 } 00295 Begin: 00296 CheckTouching(); 00297 } 00298 00299 00300 //_____________________________________________________________________________ 00301 // Sleeping state: Sitting hidden waiting to respawn. 00302 State Sleeping 00303 { 00304 ignores Touch; 00305 00306 function bool ReadyToPickup(float MaxWait) 00307 { 00308 return (LatentFloat < MaxWait); 00309 } 00310 00311 function StartSleeping() {} 00312 00313 event BeginState() 00314 { 00315 bHidden = true; 00316 ClientPickedUp(); 00317 RefreshDisplaying(); // on clients this is made native in APickup::PostNetReceive() if bOnlyReplicateHidden. 00318 } 00319 event EndState() 00320 { 00321 bHidden = false; 00322 RefreshDisplaying(); // on clients this is made native in APickup::PostNetReceive() if bOnlyReplicateHidden. 00323 } 00324 Begin: 00325 Sleep( ReSpawnTime ); 00326 Sleep( Level.Game.PlaySpawnEffect(self) ); 00327 // Log("PICKUP SND RESPAWN"@hRespawnSound); 00328 PlaySound(hRespawnSound); 00329 GoToState( 'Pickup' ); 00330 } 00331 00332 defaultproperties 00333 { 00334 bOnlyReplicateHidden=True 00335 MaxDesireability=0.005000 00336 PickupMessage="Snagged an item." 00337 bOrientOnSlope=True 00338 bAlwaysRelevant=True 00339 bIgnoreDynLight=False 00340 bMovable=False 00341 bCollideActors=True 00342 bCollideWorld=True 00343 bUseCylinderCollision=True 00344 bCanSeeThrough=True 00345 bCanShootThroughWithRayCastingWeapon=True 00346 bCanShootThroughWithProjectileWeapon=True 00347 bFixedRotationDir=True 00348 DrawType=DT_Mesh 00349 Texture=Texture'Engine.S_Inventory' 00350 RotationRate=(Yaw=5000) 00351 DesiredRotation=(Yaw=30000) 00352 NetPriority=1.400000 00353 NetUpdateFrequency=8.000000 00354 }

End Source Code