Controlling Players and Characters(38)

Controlling Players and Characters(38)

Coming up is a huge collection of functions you use to retrieve and set the specific
information about a character (related to the artificial intelligence functionality or
actions):

    cCharIcs* get_char_ics( long  id)
    {
        sCharacter* character;

        
if ((character = get_char(id)) == NULL)
            
return  NULL;

        
return  character->char_ics;
    }

    
void  set_char_lock( long  id,  bool  is_lock)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
            character->is_lock = is_lock;
    }

    
void  set_char_lock_timer( long  id,  long  action_timer)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)            
            character->action_timer = action_timer;
    }

    
void  set_char_type( long  id,  long  type)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
            character->type = type;
    }

    
long  get_char_type( long  id)
    {
        sCharacter* character;

        
if ((character = get_char(id)) == NULL)
            
return  0;

        
return  character->type;
    }

    
void  set_char_ai( long  id,  long  ai)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
            character->ai = ai;
    }

    
long  get_char_ai( long  id)
    {
        sCharacter* character;

        
if ((character = get_char(id)) == NULL)
            
return  0;

        
return  character->ai;
    }

    
void  set_char_distance( long  id,  float  dist)
    {
        
// set evade/follow distance

        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
            character->distance = dist;
    }

    
float  get_char_distance( long  id)
    {
        
// get evade/follow distance

        sCharacter* character;

        
if ((character = get_char(id)) == NULL)
            
return  0.0f;

        
return  character->distance;
    }

    
void  set_char_route( long  id,  long  num_points,  const  sRoutePoint* route)
    {
        sCharacter* character;
        
if ((character = get_char(id)) == NULL)
            
return ;

        
// free old route
        delete[] character->route;
        character->route = NULL;

        
// set new route
         if ((character->num_points = num_points) != 0)
        {
            character->route = 
new  sRoutePoint[num_points];
            memcpy(character->route, route, num_points * 
sizeof (sRoutePoint));

            character->cur_point = 0;
        }
    }

    
void  set_char_script( long  id,  const   char * script_filename)
    {
        sCharacter* character;
        
        
if ((character = get_char(id)) != NULL)
            strcpy(character->script_filename, script_filename);
    }

    
char * get_char_script( long  id)
    {
        sCharacter* character;
        
if ((character = get_char(id)) == NULL)
            
return  NULL;

        
return  character->script_filename;
    }

    
void  set_update_enable( long  id,  bool  update_enable)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
            character->update_enable = update_enable;
    }

    
bool  get_update_enable( long  id)
    {
        sCharacter* character;

        
if ((character = get_char(id)) == NULL)
            
return   false ;

        
return  character->update_enable;
    }

    
void  move_char( long  id,  float  pos_x,  float  pos_y,  float  pos_z)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
        {
            character->pos_x = pos_x;
            character->pos_y = pos_y;
            character->pos_z = pos_z;
        }
    }

    
void  get_char_position( long  id,  float * pos_x,  float * pos_y,  float * pos_z)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
        {
            
if (pos_x)   *pos_x = character->pos_x;
            
if (pos_y)   *pos_y = character->pos_y;
            
if (pos_z)   *pos_z = character->pos_z;
        }
    }

    
void  set_char_bound( long  id,
                        
float  min_x,  float  min_y,  float  min_z,
                        
float  max_x,  float  max_y,  float  max_z)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
        {
            character->min_x = min(min_x, max_x);
            character->min_y = min(min_y, max_y);
            character->min_z = min(min_z, max_z);
            character->max_x = max(min_x, max_x);
            character->max_y = max(min_y, max_y);
            character->max_z = max(min_z, max_z);
        }
    }

    
void  get_char_bound( long  id,
                        
float * min_x,  float * min_y,  float * min_z,
                        
float * max_x,  float * max_y,  float * max_z)
    {
        sCharacter* character;

        
if ((character = get_char(id)) != NULL)
        {
            
if (min_x)   *min_x = character->min_x;
            
if (min_y)   *min_y = character->min_y;
            
if (min_z)   *min_z = character->min_z;
            
if (max_x)   *max_x = character->max_x;
            
if (max_y)   *max_y = character->max_y;
            
if (max_z)   *max_z = character->max_z;
        }
    }

    
void  set_target_char( long  id,  long  target_id)
    {
        sCharacter* character;
        
if ((character = get_char(id)) == NULL)
            
return ;

        
if (target_id == -1)
            character->target_char = NULL;
        
else
        {
            sCharacter* target_char;

            
for (target_char = m_root_char; target_char != NULL; target_char = target_char->next)
            {
                
if (target_char->id == target_id)
                {
                    character->target_char = target_char;
                    
break ;
                }
            }

            
// clear target if not found in list
             if (target_char == NULL)
                character->target_char = NULL;
        }
    }

    
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;
        }
    }

Skipping the details on the preceding functions, you now encounter the function
used to set up the data that displays a message over a character:

    void  set_char_msg(sCharacter* character,  const   char * msg,  long  msg_timer, D3DCOLOR msg_color)
    {
        
// set text messages to float up from character

        strcpy(character->msg, msg);

        character->msg_timer = msg_timer;
        character->msg_color = msg_color;
    }

set_char_msg allows you to temporarily overlay a string of text for Timer milliseconds, drawing
the text in the color specified. You set a character message to inform the player of
an event, such as how many health points were reduced because of an attack.

Coming next is the function that processes the damage taken from an attack,
whether it’s physical or magical (as denoted by the is_physical_attack flag, set to true for
physical attacks or false for magical):

void  cCharController::damage(sCharacter* victim,
                             
bool  is_physical_attack,  long  attack_amount,
                             
long  damage_class,  long  cure_class)
{
    
// can not attack if already dead or being hurt or not update enabled
     if (victim == NULL || !victim->update_enable || victim->action == CHAR_DIE || victim->action == CHAR_HURT)
        
return ;

    
float    range;
    
long     damage_amount;
    
    
if (is_physical_attack)   // adjust for defense if physical attack
    {
        
// random value for less/more damage (-+10%)
        range = (rand()%20 + 90.0f) / 100.0f;
        damage_amount = attack_amount * range;

        
// subtract for defencse to victim (allow -20% difference)
        range = (rand()%20 + 80.0f) / 100.0f;
        damage_amount -= (get_defense(victim) * range);
    }
    
else      // adjust for magical attack            
        damage_amount = attack_amount * (1.0f - get_resistance(victim)/100.0f);    

    
if (damage_amount < 0)    // bounds check
        damage_amount = 0;

    
// check for double damage
     if (victim->char_def.class_index == damage_class)
        damage_amount *= 2;

    
// check for cure damage
     if (victim->char_def.class_index == cure_class)
        damage_amount = -labs(damage_amount) / 2;

    
// if no physical damage is dealt then randomly deal 10-20% of damage from the original amount.
     if (damage_amount == 0 && is_physical_attack)
    {
        range = (rand()%10 + 10) / 100.0f;
        damage_amount = attack_amount * range;
    }
    
    victim->health_points -= damage_amount;

    
char  text[128];

    
if (damage_amount > 0)        // set hurt status and display message
    {
        sprintf(text, "-%lu HP", damage_amount);
        set_char_msg(victim, text, 500, D3DCOLOR_RGBA(255, 64, 0, 255));

        
// only set hurt if idle or moving
         if (victim->action == CHAR_MOVE || victim->action == CHAR_IDLE)
            set_char_action(victim, CHAR_HURT, 0);
    }
    
else   if (damage_amount < 0)   // display cure amount
    {
        sprintf(text, "+%lu HP", -damage_amount);
        set_char_msg(victim, text, 500, D3DCOLOR_RGBA(0, 64, 255, 255));
    }    
}

Damage takes a pointer to the character taking damage, the type of damage (physical
or magical), the amount of damage to apply, and the double damage and cure
classes of the attack. You adjust the damage amount based on the defense and resistance
abilities of the victim.

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