青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

Controlling Players and Characters(33)

The next two functions to come along work in conjunction with the update functionality
of the class. At every frame that a character needs updating, a specific
function is called to update the character’s actions. This specific function is dependent
on the type of character being updated; for PCs, that specific function is
pc_update (which is overridden by you in order to control your player).

virtual void pc_update(sCharacter* character, long elaspsed,
                       float* x_move, float* y_move, float* z_move)
{
}

For NPCs and monsters, the update function called is npc_monster_update. pc_update does
nothing at this point because you need to write the code in the main application
to control the player. Monsters and NPCs already have their AIs sets, and the controller
knows how to handle them with npc_monster_update.

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

static bool char_can_spell_health(const sCharacter* character, const sSpell* spell, int spell_index)
{
    
return spell->name[0] && spell->effect == ALTER_HEALTH && spell->value[0] > 0.0f &&
           character->mana_points >= spell->cost &&
           (character->char_def.magic_spell[spell_index / 32] & (1 << (spell_index & 31)));
}

static bool char_can_spell_dispel(const sCharacter* character, const sSpell* spell, int spell_index)
{
    
return spell->name[0] && spell->effect == DISPEL_MAGIC && character->mana_points >= spell->cost &&
           (character->char_def.magic_spell[spell_index / 32] & (1 << (spell_index & 31)));
}

static bool char_can_spell_ailment(const sCharacter* character, const sSpell* spell, int spell_index)
{
    
return spell->name[0] && spell->effect == CAUSE_AILMENT && character->mana_points >= spell->cost &&
           (character->char_def.magic_spell[spell_index / 32] & (1 << (spell_index & 31)));
}

static bool char_can_spell(const sCharacter* character, const sSpell* spell, int spell_index)
{
    
return spell->name[0] && character->mana_points >= spell->cost &&
           (character->char_def.magic_spell[spell_index / 32] & (1 << (spell_index & 31)));
}

static bool is_char_ailment(const sCharacter* character)
{
    
return character->ailments & AILMENT_POISON ||
           character->ailments & AILMENT_SLEEP ||             
           character->ailments & AILMENT_PARALYZE ||          
           character->ailments & AILMENT_ENCHANTED ||         
           character->ailments & AILMENT_DUMBFOUNDED ||       
           character->ailments & AILMENT_SLOW ||              
           character->ailments & AILMENT_BLIND ||             
           character->ailments & AILMENT_SILENCED;
}

static bool is_enhanced_ailment(long ailment)
{
    
return ailment & AILMENT_STRONG ||      
           ailment & AILMENT_BARRIER ||     
           ailment & AILMENT_SUREFOOTED ||  
           ailment & AILMENT_FAST ||        
           ailment & AILMENT_HAWKEYE;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
 
void cCharController::npc_monster_update(sCharacter* character, long elapsed,
                                         
float* x_move, float* y_move, float* z_move)
{
    
if(character == NULL)
        
return;

    
float move_x, move_y, move_z;
    move_x = move_y = move_z = 0.0f;

    
float x_diff, y_diff, z_diff, dist, radius;

    
float speed = elapsed/1000.0f * get_speed(character);

    
// move character based on their type
    switch(character->ai)
    {
    
case CHAR_STAND:
        
break;

    
case CHAR_WANDER:
        
// calculate new distance and direction if needed

        character->distance -= elapsed;

        
if(character->distance <= 0.0f)
        {
            character->distance  = rand()%2000 + 2000.0f;
            character->direction = (rand()%360) * 0.01744444f;
        }

        
// process walk or stand still
        if(character->distance > 1000.0f)
        {
            move_x = sin(character->direction) * speed;
            move_z = cos(character->direction) * speed;

            character->action = CHAR_MOVE;
        }
        
else
        {
            
// stand still for one second
            character->action = CHAR_IDLE;
        }

        
break;

    
case CHAR_ROUTE:
      {
        sRoutePoint* route = &character->route[character->cur_point];

        
// determine if character has reached point

        x_diff = fabs(character->pos_x - route->pos_x);
        y_diff = fabs(character->pos_y - route->pos_y);
        z_diff = fabs(character->pos_z - route->pos_z);

        dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;
        radius = get_xz_radius(character) * 0.25f;

        
// goto next point if reached
        if(dist < (radius * radius))
        {
            
if(++character->cur_point >= character->num_points)
                character->cur_point = 0;

            route = &character->route[character->cur_point];

            
// calculate new differences and distance 

            x_diff = fabs(character->pos_x - route->pos_x);
            y_diff = fabs(character->pos_y - route->pos_y);
            z_diff = fabs(character->pos_z - route->pos_z);

            dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;
        }

        
// setup movement towards target
        dist = sqrt(dist);

        
if(speed > dist)
            speed = dist;

        move_x = (route->pos_x - character->pos_x) / dist * speed;
        move_z = (route->pos_z - character->pos_z) / dist * speed;

        character->direction = atan2(move_x, move_z);
        character->action    = CHAR_MOVE;

        
break;
      }

    
case CHAR_FOLLOW:    
        
// check distance between characters

        x_diff = fabs(character->pos_x - character->target_char->pos_x);
        y_diff = fabs(character->pos_y - character->target_char->pos_y);
        z_diff = fabs(character->pos_z - character->target_char->pos_z);

        dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

        
// update if further than target
        if(dist > (character->distance * character->distance))
        {
            
// setup movement towards target
            dist = sqrt(dist);

            
if(speed > dist)
                speed = dist;

            move_x = (character->target_char->pos_x - character->pos_x) / dist * speed;
            move_z = (character->target_char->pos_z - character->pos_z) / dist * speed;
            
            character->direction = atan2(move_x, move_z);
            character->action    = CHAR_MOVE;
        }

        
break;

    
case CHAR_EVADE:
        
// check distance between characters

        x_diff = fabs(character->pos_x - character->target_char->pos_x);
        y_diff = fabs(character->pos_y - character->target_char->pos_y);
        z_diff = fabs(character->pos_z - character->target_char->pos_z);

        dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

        
// update if closer than distance
        if(dist < (character->distance * character->distance))
        {
            
// setup movement away from target
            dist = sqrt(dist);

            
if(speed > dist)
                speed = dist;

            move_x = -(character->target_char->pos_x - character->pos_x) / dist * speed;
            move_z = -(character->target_char->pos_z - character->pos_z) / dist * speed;

            character->direction = atan2(move_x, move_z);
            character->action = CHAR_MOVE;
        }

        
break;
    }

    sCharacter* char_ptr;

    
// process monster actions if at full charge
    if(character->type == CHAR_MONSTER && character->charge >= 100.0f)
    {
        
// determine chance of attacking
        if(rand()%100 <= character->char_def.to_attack)
        {
            
// scan through list and pick a character
            for(char_ptr = m_root_char; char_ptr != NULL; char_ptr = char_ptr->next)
            {
                
// randomly pick update enabled PC, and make sure the target is not hurt or dead.
                if(char_ptr != character && char_ptr->type == CHAR_PC && char_ptr->update_enable &&
                   char_ptr->action != CHAR_DIE && char_ptr->action != CHAR_HURT && rand()%100 < 50)
                {
                    
// get distance to target
                    x_diff = fabs(character->pos_x - char_ptr->pos_x);
                    y_diff = fabs(character->pos_y - char_ptr->pos_y);
                    z_diff = fabs(character->pos_z - char_ptr->pos_z);

                    dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

                    
// make sure in range to attack                    
                    radius = get_xz_radius(character) + character->char_def.attack_range;

                    
// attack only in range
                    if((radius * radius) >= dist)
                    {                        
                        character->victim  = char_ptr;
                        char_ptr->attacker = character;

                        
// clear movement
                        move_x = move_y = move_z = 0.0f;

                        
// point towards target character
                        x_diff = char_ptr->pos_x - character->pos_x;
                        z_diff = char_ptr->pos_z - character->pos_z;
                        character->direction = atan2(x_diff, z_diff);

                        set_char_action(character, CHAR_ATTACK, 0);
                        
break;
                    }
                }
            }
        }   
        
else if(rand()%100 <= character->char_def.to_magic)
        {
            
// determine chance of spell casting

            
bool is_spell_cast = false;
            
long spell_index;

            
// if health is less than half, then there is 50% chance of healing (if monster knows any heal spells).
            if(character->health_points <= character->char_def.health_points / 2)
            {
                
// search for a known heal spell
                for(long i = 0; i < NUM_SPELL_DEF; i++)
                {
                    
// this is the spell, determine chance to heal.
                    if(char_can_spell_health(character, &m_msl[i], i) && rand()%100 < 50)
                    {                        
                        character->victim      = character;
                        character->attacker    = character;
                        character->spell_index = i;
                        character->target_type = CHAR_MONSTER;                     
                        character->target_x    = character->pos_x;
                        character->target_y    = character->pos_y;
                        character->target_z    = character->pos_z;

                        
// clear movement
                        move_x = move_y = move_z = 0.0f;
                       
                        set_char_action(character, CHAR_SPELL, 0);
                        is_spell_cast = 
true;
                        
break;
                    }
                }
            }

            
// if there are bad status ailments, then there is 50% chance of dispeling magic.
            if(is_char_ailment(character) && !is_spell_cast)
            {
                
// search for a known dispell spell
                for(long i = 0; i < NUM_SPELL_DEF; i++)
                {
                    
// this is the spell, determine chance to dispel.
                    if(char_can_spell_dispel(character, &m_msl[i], i) && rand()%100 < 50)
                    {                        
                        character->victim      = character;
                        character->attacker    = character;
                        character->spell_index = i;
                        character->target_type = CHAR_MONSTER;                     
                        character->target_x    = character->pos_x;
                        character->target_y    = character->pos_y;
                        character->target_z    = character->pos_z;

                        
// clear movement
                        move_x = move_y = move_z = 0.0f;
                       
                        set_char_action(character, CHAR_SPELL, 0);
                        is_spell_cast = 
true;
                        
break;
                    }
                }
            }

            
// if no spells already cast, then pick a random spell to attack with.
            if(!is_spell_cast)
            {
                spell_index = rand() % NUM_SPELL_DEF;

                
// scan through list until a spell is found that monster can cast.
                for(long i = 0; i < NUM_SPELL_DEF; i++)
                {
                    
if(char_can_spell(character, &m_msl[spell_index], spell_index) && rand()%100 < 50)
                    {
                        
// scan through list and pick a character
                        for(char_ptr = m_root_char; char_ptr != NULL; char_ptr = char_ptr->next)
                        {
                            
// randomly pick an update enabled PC, and make sure the target is not hurt or dead.
                            // also, do not cast self-targeting spells here.
                            if(char_ptr != character && m_msl[spell_index].target != TARGET_SELF &&
                                char_ptr->type == CHAR_PC && char_ptr->update_enable &&
                                char_ptr->action != CHAR_DIE && char_ptr->action != CHAR_HURT &&
                                rand()%100 < 50)
                            {
                                
float y1, y2;

                                
// get heights of attacker and target for line of sight checking
                                character->object.get_bounds(NULL, NULL, NULL, NULL, &y1, NULL, NULL);
                                y1 = (y1 * 0.5f) + character->pos_y;

                                char_ptr->
object.get_bounds(NULL, NULL, NULL, NULL, &y2, NULL, NULL);
                                y2 = (y2 * 0.5f) + char_ptr->pos_y;

                                
// get distance to target

                                x_diff = fabs(character->pos_x - char_ptr->pos_x);
                                y_diff = fabs(character->pos_y - char_ptr->pos_y);
                                z_diff = fabs(character->pos_z - char_ptr->pos_z);
                
                                dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;
                                dist = sqrt(dist) - get_xz_radius(char_ptr);
                               
                                
bool in_line_sight = line_of_sight(character, char_ptr,
                                                                   character->pos_x, y1, character->pos_z,
                                                                   char_ptr->pos_x, y2, char_ptr->pos_z);

                                
// make sure target is in range and in line sight
                                if(in_line_sight && dist <= m_msl[spell_index].max_dist)
                                {
                                    character->victim      = char_ptr;
                                    char_ptr->attacker     = character;
                                    character->spell_index = spell_index;
                                    character->target_type = CHAR_PC;
                                    character->target_x    = char_ptr->pos_x;
                                    character->target_y    = char_ptr->pos_y;
                                    character->target_z    = char_ptr->pos_z;

                                    
// face toward target (only if not self)
                                    x_diff = char_ptr->pos_x - character->pos_x;
                                    z_diff = char_ptr->pos_z - character->pos_z;

                                    character->direction = atan2(x_diff, z_diff);

                                    move_x = move_y = move_z = 0.0f;    
// clear movement

                                    set_char_action(character, CHAR_SPELL, 0);
                                    is_spell_cast = 
true;
                                    
break;
                                }
                            }
                        }

                        
break;
                    }

                    
// go to next spelll
                    spell_index = (spell_index + 1) % NUM_SPELL_DEF;
                }
            }

            
// if still no spell cast, try casting a known self-enhancing ailment-effecting spell.
            if(!is_spell_cast)
            {
                
for(long i = 0; i < NUM_SPELL_DEF; i++)
                {
                    
// make sure it is self-enhancing
                    if(char_can_spell_ailment(character, &m_msl[i], i) && is_enhanced_ailment(m_msl[i].value[0]) &&
                       rand()%100 < 10)
                    {
                        
// make sure ailment not already set
                        if(!(character->ailments & (long)m_msl[i].value[0]))
                        {
                            character->victim      = character;
                            character->attacker    = character;
                            character->spell_index = i;
                            character->target_type = CHAR_MONSTER;
                            character->target_x    = character->pos_x;
                            character->target_y    = character->pos_y;
                            character->target_z    = character->pos_z;

                            move_x = move_y = move_z = 0.0f;    
// clear movement

                            set_char_action(character, CHAR_SPELL, 0);
                            
break;
                        }
                    }
                }
            }
        }
    }

    
// store movement
    *x_move = move_x;
    *y_move = move_y;
    *z_move = move_z;
}

The steps taken for initiating an update and processing all of a character’s actions
is a long one. First, you iterate each character in the list of active characters. The
appropriate character’s update function is called (pc_update or npc_monster_update).

posted on 2007-12-04 16:29 lovedday 閱讀(305) 評論(0)  編輯 收藏 引用

公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            女人香蕉久久**毛片精品| 久久精品最新地址| 欧美精品久久久久久久久老牛影院 | 久久精彩视频| 香蕉视频成人在线观看| 亚洲一区二区三区在线| 亚洲在线黄色| 久久久国际精品| 欧美3dxxxxhd| 亚洲欧洲在线一区| 亚洲免费电影在线| 一区二区三区**美女毛片| 亚洲欧美成人网| 欧美在线在线| 欧美精品www| 国产偷国产偷亚洲高清97cao | 久久久久久国产精品mv| 久久av二区| 欧美激情视频一区二区三区免费| 男同欧美伦乱| 亚洲欧美韩国| 亚洲精品久久久久久下一站| 亚洲无限av看| 国产欧美大片| 久久婷婷久久| 欧美激情中文不卡| 亚洲综合视频1区| 久久精品国产第一区二区三区| 午夜精品久久久久久99热| 香蕉久久国产| 亚洲欧洲视频在线| 免费欧美网站| 国产精品亚洲美女av网站| 亚洲一区二区在线免费观看视频 | 欧美天天综合网| 亚洲精品久久久久久下一站| 久久免费精品日本久久中文字幕| 亚洲精品色图| 免费亚洲电影在线观看| 亚洲国产精品免费| 亚洲人在线视频| 欧美精品在线播放| 亚洲一区二区在线观看视频| 一本综合精品| 国产精品女人久久久久久| 亚洲欧美日韩国产一区二区三区| 一区二区高清在线| 国产精品午夜在线观看| 欧美伊人久久| 亚洲欧美中文另类| 尤物在线观看一区| 久久综合久色欧美综合狠狠| 久久精品日韩欧美| 亚洲日本成人网| 中文无字幕一区二区三区| 国产欧美日韩免费| 亚洲国产成人av| 欧美日韩一区二区三区四区五区| 亚洲视频大全| 久久蜜桃香蕉精品一区二区三区| 伊人久久噜噜噜躁狠狠躁| 欧美国产一区视频在线观看| 国产精品久久久久久久久免费| 乱中年女人伦av一区二区| 欧美日韩国产综合网| 麻豆精品视频在线| 国产精品www994| 91久久精品国产91性色| 依依成人综合视频| 午夜精品视频在线观看| 在线亚洲精品| 欧美日韩成人一区| 亚洲国产成人在线| 尤物视频一区二区| 久久亚洲综合色一区二区三区| 久久aⅴ国产欧美74aaa| 国产精品欧美日韩| 亚洲午夜一区二区三区| 午夜精品亚洲一区二区三区嫩草| 欧美成人午夜激情| 亚洲国产日韩美| av成人免费| 国产精品jizz在线观看美国| 在线性视频日韩欧美| 亚洲女同性videos| 国产精品久久久久91| 午夜久久久久久久久久一区二区| 美脚丝袜一区二区三区在线观看 | 亚洲一级免费视频| 欧美日韩一区二区在线观看| 一片黄亚洲嫩模| 久久亚洲国产成人| 在线欧美日韩国产| 免费不卡视频| 欧美在线播放一区| 亚洲免费高清视频| 久久综合中文| 亚洲专区免费| 亚洲乱码国产乱码精品精98午夜 | 午夜精品影院| 亚洲黄网站黄| 久久午夜av| 午夜精品国产精品大乳美女| 亚洲国产日韩欧美综合久久 | 欧美激情一区三区| 欧美综合二区| 性伦欧美刺激片在线观看| 日韩一级成人av| 亚洲免费不卡| 亚洲精品国产精品久久清纯直播| 久久精品免费观看| 久久久久国产一区二区三区| 亚洲影院在线观看| 午夜激情综合网| 亚洲欧美日韩天堂一区二区| 一本到12不卡视频在线dvd| 在线看日韩av| 亚洲精品资源| 一本到12不卡视频在线dvd| 亚洲精品久久视频| 久久人人97超碰精品888| 性欧美8khd高清极品| 亚洲欧美日韩成人高清在线一区| 亚洲影院免费观看| 欧美在线视频全部完| 久久久国产亚洲精品| 久久视频精品在线| 另类激情亚洲| 欧美日韩在线视频首页| 国产精品网站一区| 亚洲二区在线视频| 亚洲欧美成人一区二区在线电影 | 国产精品任我爽爆在线播放| 国产午夜精品久久| 一区精品久久| 亚洲在线观看视频网站| 欧美成人第一页| 亚洲欧美国产制服动漫| 欧美激情精品久久久久| 国产午夜精品一区二区三区视频| 激情一区二区| 久久久久久网| 亚洲欧美日韩国产一区二区| 欧美激情一区三区| 亚洲成人在线视频网站| 午夜在线一区二区| 99这里只有精品| 欧美日韩精品在线播放| 在线免费观看一区二区三区| 亚洲永久免费av| 一区二区三欧美| 欧美高清视频一二三区| 亚洲三级色网| 欧美国产三区| 老色鬼久久亚洲一区二区| 国产综合欧美| 亚洲香蕉网站| 亚洲视频在线二区| 国产精品视频1区| 欧美中文字幕在线| 午夜精品免费在线| 亚洲第一精品福利| 激情久久五月| 奶水喷射视频一区| 久久欧美中文字幕| 一区二区三区欧美亚洲| 亚洲国产成人tv| 欧美精品1区2区| 欧美一区免费视频| 久久久999精品| 亚洲日本一区二区| 亚洲在线一区二区| 亚洲欧美在线网| 亚洲日本欧美天堂| 亚洲欧美日产图| 亚洲精品自在在线观看| 亚洲小说欧美另类社区| 激情成人综合网| 99re热这里只有精品视频| 国产日本欧美在线观看| 久久午夜国产精品| 国产精品久久久久久一区二区三区| 久久婷婷av| 欧美性理论片在线观看片免费| 欧美/亚洲一区| 国产欧美 在线欧美| 日韩视频一区二区三区| 激情久久一区| 欧美在线|欧美| 欧美福利视频在线| 久久综合导航| 国产午夜精品全部视频在线播放| 亚洲人成毛片在线播放女女| 国产日韩欧美成人| 亚洲专区在线视频| 亚洲欧美久久久| 国产精品v欧美精品v日本精品动漫| 免费观看日韩av| 亚洲欧洲一区二区在线观看| 欧美高清hd18日本|