Thursday, February 2, 2012

PickupFactory and Inventory in UnrealScript


The PickupFactory class was created to provide inventory items for players in the levels of the Unreal Tournament game. It is represented visually by a base and by the item that it provides as in the image above.

PickupFactory is a subclass of NavigationPoint which is a subclass of Actor. The tree class below shows the types of PickupFactory available in UDK:


Another way to represent an inventory item in the level is using the DroppedPickup class. This class is used when a Pawn throws an inventory item in the level, this can happen when he dies.

The InventoryManager class is responsible for managing the inventory items of a Pawn. As an example of inventory items in Unreal Tournament we have the Jump Boots, the Berserker which increases the rate of fire, the UDamage that increases the damage, and all weapons are subclasses of the Inventory class as can be seen in the image below.


When a Pawn touches a PickupFactory or a DroppedPickup, an object of Inventory class is provided to the player through the function "Inventory.GiveTo(Pawn Other)". This function calls another function of InventoryManager called AddInventory() that checks if the new inventory item exists in a linked list of Inventory objects before adding it. After this, the function "Inventory.GivenTo()" is called which finally calls the function "Inventory.AdjustPawn()" that is responsible for adding or removing the effect of the item in the Pawn object.

The code below is from the AddInventory() function of InventoryManager class. In this function we can see the use of the linked list of objects of the Inventory class.
//In the InventoryManager class: 

simulated function bool AddInventory(Inventory NewItem, optional bool bDoNotActivate)
{
    local Inventory Item, LastItem;
    
    if( (NewItem != None) && !NewItem.bDeleteMe )
    {
        // if we don't have an inventory list, start here
        if( InventoryChain == None )
        {
            InventoryChain = newItem;
        }
        else
        {
            // Skip if already in the inventory.
            for (Item = InventoryChain; Item != None; Item = Item.Inventory)
            {
                if( Item == NewItem )
                {
                    return FALSE;
                }
                LastItem = Item;
            }
            LastItem.Inventory = NewItem;
        }
        
        //Instigator is a variable that keeps a reference to the Pawn that gets the Item.
        NewItem.SetOwner( Instigator );
        NewItem.Instigator = Instigator;
        NewItem.InvManager = Self;
        NewItem.GivenTo( Instigator, bDoNotActivate);
        
        Instigator.TriggerEventClass(class'SeqEvent_GetInventory', NewItem);
        return TRUE;
    }

    return FALSE;
}