Controlling Players and Characters(40)

Controlling Players and Characters(40)

Things are winding down with the controller at this point. You use the following
functions to equip, use, and drop an item:

bool  cCharController::equip(sCharacter* character,  long  item_index,  long  equip_type,  bool  equip_now)
{
    
if (m_mil == NULL || character == NULL)
        
return   false ;

    
// make sure allow equiping of item
     if (! check_bit(m_mil[item_index].usage, character->char_def.class_index))
        
return   false ;

    
// remove current item first and equip new one
     switch (equip_type)
    {
    
case  WEAPON:
        character->char_def.weapon = -1;
        character->weapon_mesh.free();

        
if (equip_now && m_mil[item_index].category == WEAPON)
        {
            character->char_def.weapon = item_index;

            
if (m_mil[item_index].mesh_filename)
            {
                
char  path[MAX_PATH];
                sprintf(path, "%s%s", m_weapon_mesh_path, m_mil[item_index].mesh_filename);

                character->weapon_mesh.load(path, m_texture_path);
                character->weapon_object.create(&character->weapon_mesh);
                character->weapon_object.attach_to_object(&character->
object , "WeaponHand");
            }
        }

        
break ;

    
case  ARMOR:
        character->char_def.armor = -1;

        
if (equip_now && m_mil[item_index].category == ARMOR)
            character->char_def.armor = item_index;

        
break ;

    
case  SHIELD:
        character->char_def.shield = -1;

        
if (equip_now && m_mil[item_index].category == SHIELD)
            character->char_def.shield = item_index;

        
break ;

    
case  ACCESSORY:
        character->char_def.accessory = -1;

        
if (equip_now && m_mil[item_index].category == ACCESSORY)
            character->char_def.accessory = item_index;

        
break ;

    
default :
        
return   false ;
    }

    
return   true ;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void  cCharController::use_item(sCharacter* owner, sCharacter* target, 
                               
long  item_index, sCharItem* char_item)
{
    
if (owner == NULL || target == NULL || m_mil == NULL)
        
return ;

    sItem* item = &m_mil[item_index];

    
// make sure allow to use of item
     if (! check_bit(item->usage, target->char_def.class_index))
        
return ;

    
// use specified item
     switch (item->category)
    {
    
case  EDIBLE:
    
case  HEALING:    // alter health
        target->health_points += item->value;
        
break ;
    }

    
// decrease quantity and remove object if needed
     if (check_bit(item->flags, USEONCE) && char_item)
    {
        char_item->quantity--;

        
if (char_item->quantity <= 0 && owner->char_ics)
            owner->char_ics->remove(char_item);
    }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

bool  cCharController::drop(sCharacter* character, sCharItem* char_item,  long  quantity)
{
    
if (char_item == NULL || m_mil == NULL || character == NULL)
        
return   false ;

    
// make sure item can be dropped
     if (! check_bit(m_mil[char_item->item_index].flags, CANDROP))
        
return   false ;

    char_item->quantity -= quantity;

    
// remove item from ics if no more left
     if (char_item->quantity <= 0 && character->char_ics)
        character->char_ics->remove(char_item);

    
return   true ;
}

With equip, you must specify the character to modify and the item number (from
the MIL) of the item being equipped. You use the equip_type argument to specify which
item type to equip (WEAPON, ARMOR, SHIELD, or ACCESSORY) and the equip_now flag to tell the
controller to equip the specified item (set equip_now to true) or just to unequip the currently
used item (by setting equip_now to false).

As for the use item function (use_item), two characters are required: the owner of the
item and the character on which the item is being used. In that way, one character
can use a healing potion on another character. Specify the MIL item number being
used, as well as a pointer to the owner’s ICS char_item structure so that the quantity
of the item can be decreased.

The next function is required to process the teleport spell effect on PCs. Whenever a
teleport spell is used on a PC, the character controller calls the following function to
handle the effects. Both the pointer to the target character and spell structure are
passed:

virtual bool pc_teleport(sCharacter* character, const sSpell* spell)
{
  return true;
}

Finishing up the character controller class functions is the one that is responsible
for preparing a character to perform an action. You use this function mostly when
controlling your PC via the pc_update function:

    void  set_char_action(sCharacter* character,  long  action,  long  action_timer)
    {
        
if (character == NULL)
            
return ;

        
// make sure attack, spell, and item supporting charge.
         if (action == CHAR_ATTACK || action == CHAR_SPELL || action == CHAR_ITEM)
        {
            
if (character->charge < 100.0f)
                
return ;
        }

        character->action = action;
        play_action_sound(character);

        
long  mesh_index = character->char_def.mesh_index;

        
// set action timer
         if (action_timer == -1)
            character->action_timer = 1;
        
else
        {
            
ulong  anim_length = m_mesh_anim[mesh_index].anim.get_time_length(m_char_anim[action].name);
            character->action_timer = action_timer + anim_length * 30;
        }
    }

When a PC (or any character for that matter) does something, a matching action is
performed. Walking is an action, attacking is an action, and so on. Previously, actions
were defined as CHAR_IDLE, CHAR_MOVE, CHAR_ATTACK, and so on, for example. You need to
set the action argument to one of those values in order to initiate a character action.

For each action that a character can perform, there is a matching animation in the
sCharAnimInfo structure array used to initialize the controller. When a character
performs an action, the appropriate animation is set, as well as the action timer
used to count down the time until the animation is complete. Remember that no
further actions can be performed until the current action is complete.

The last argument in the list, add_timer, is used to add additional milliseconds to the
action timer. Specifying a value of -1 for add_timer, forces set_char_action to not use the
action timer, which means that the action clears on the next update.

你可能感兴趣的:(Controlling Players and Characters(40))