quarta-feira, 1 de fevereiro de 2012

PickupFactory e Inventory em UnrealScript


A classe PickupFactory foi feita para fornecer itens de inventário para os jogadores nos cenários do jogo Unreal Tournament. Ela é representada visualmente por uma base e pelo item que ela fornece conforme a imagem acima.

PickupFactory é uma subclasse de NavigationPoint que é uma subclasse de Actor. A árvore de classes abaixo mostra os tipos de PickupFactory disponíveis no UDK:


Outra forma de representar um item de inventário no cenário é através da classe DroppedPickup. Esta classe é usada quando um Pawn lança um item de inventário no cenário, isso pode ocorrer quando ele morre.

A classe InventoryManager é responsável por gerenciar os objetos da classe Inventory de um Pawn. Como exemplo de itens de inventário no Unreal Tournament temos as botas de pulo, o Berserker que aumenta a taxa de tiro, o UDamage que aumenta o dano, e todas as armas são subclasses de Inventory como pode ser visto na imagem abaixo.


Quando um Pawn toca um PickupFactory ou um DroppedPickup, um item da classe Inventory é fornecido ao jogador através da função "Inventory.GiveTo( Pawn Other )". Esta função chama outra função do InventoryManager chamada AddInventory() que verifica se o novo item de inventário já existe em uma lista ligada de objetos Inventory antes de adicioná-lo. Depois disso é chamado a função "Inventory.GivenTo()" que finalmente chama a função "Inventory.AdjustPawn()" que é responsável por adicionar ou remover o efeito do item no objeto Pawn.

O código abaixo é da função AddInventory() da classe InventoryManager onde podemos ver o uso da lista ligada de objetos da classe Inventory.
//Na classe InventoryManager: 

simulated function bool AddInventory(Inventory NewItem, optional bool bDoNotActivate)
{
    local Inventory Item, LastItem;
    
    if( (NewItem != None) && !NewItem.bDeleteMe )
    {
        // se ainda não houver uma lista, inicia com esse novo item.
        if( InventoryChain == None )
        {
            InventoryChain = newItem;
        }
        else
        {
            // Se o Item já estiver na Lista Ligada, não adiciona.
            for (Item = InventoryChain; Item != None; Item = Item.Inventory)
            {
                if( Item == NewItem )
                {
                    return FALSE;
                }
                LastItem = Item;
            }
            LastItem.Inventory = NewItem;
        }
        
        //Instigator é uma variável que guarda o objeto Pawn que pegou o Item.
        NewItem.SetOwner( Instigator );
        NewItem.Instigator = Instigator;
        NewItem.InvManager = Self;
        NewItem.GivenTo( Instigator, bDoNotActivate);
        
        Instigator.TriggerEventClass(class'SeqEvent_GetInventory', NewItem);
        return TRUE;
    }

    return FALSE;
}