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

天行健 君子當自強而不息

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>
            久久成人免费| 久久久精品国产一区二区三区| 亚洲国产aⅴ天堂久久| 久久亚洲影音av资源网| 91久久精品国产91性色| 亚洲精品国精品久久99热| 欧美午夜精品久久久久免费视 | 亚洲天堂av高清| 久久国产精品久久久久久| 国产日韩在线视频| 一本久道久久久| 亚洲国产精品va在线观看黑人 | 亚洲最黄网站| 亚洲国产精品第一区二区三区| 亚洲欧美国产视频| 在线观看国产精品淫| 欧美激情欧美激情在线五月| 欧美日韩一区二区视频在线| 亚洲欧美精品suv| 午夜精品理论片| 亚洲第一天堂无码专区| 最新热久久免费视频| 国产色产综合产在线视频| 欧美激情区在线播放| 国产精品久久久亚洲一区| 久久亚洲一区二区| 国产精品福利在线| 久久男人资源视频| 欧美激情在线免费观看| 亚洲欧美日韩一区二区在线| 亚洲欧美另类综合偷拍| 亚洲精品久久久久中文字幕欢迎你 | 欧美精品三级在线观看| 欧美专区中文字幕| 欧美三级资源在线| 久久综合色播五月| 国产精品萝li| 亚洲国产高清一区二区三区| 国产视频在线观看一区二区| 亚洲精品一区二区三区蜜桃久| 国产视频一区三区| 中日韩美女免费视频网址在线观看| 国内一区二区三区在线视频| 亚洲无线视频| 一本一本久久a久久精品牛牛影视| 久久aⅴ国产紧身牛仔裤| 亚洲一区免费网站| 欧美激情精品久久久久久变态| 久久久久欧美| 国产亚洲欧美中文| 亚洲影视在线播放| 亚洲欧美日韩国产另类专区| 欧美日韩国产探花| 日韩一级黄色大片| 在线综合亚洲欧美在线视频| 欧美成人dvd在线视频| 欧美h视频在线| 在线观看亚洲视频啊啊啊啊| 久久精品国产91精品亚洲| 午夜久久久久久| 国产精品自拍视频| 亚洲欧美日韩中文视频| 久久国产精品网站| 国产日韩三区| 欧美与黑人午夜性猛交久久久| 亚洲欧美日韩精品久久久| 国产精品成人久久久久| 亚洲午夜久久久久久久久电影院| 亚洲综合视频一区| 国产精品一卡二卡| 午夜精品一区二区三区电影天堂 | 欧美承认网站| 亚洲韩国日本中文字幕| 欧美精品福利| 在线亚洲成人| 久久国产精品网站| 狠狠爱综合网| 欧美大尺度在线| 日韩亚洲精品电影| 欧美一区二区三区四区高清| 国产一区清纯| 欧美a级大片| 亚洲天堂av在线免费| 久久精品国产亚洲5555| 在线观看欧美一区| 欧美二区在线| 亚洲一区二区不卡免费| 久久一日本道色综合久久| 亚洲美女在线一区| 国产精品一二三| 久久综合狠狠综合久久激情| 最新日韩精品| 久久九九国产| 亚洲伦伦在线| 国产日韩成人精品| 欧美成人高清| 亚洲欧美国产另类| 亚洲人在线视频| 欧美在线1区| 夜夜嗨一区二区| 国产一区二区看久久| 欧美精品久久久久久久| 欧美在线短视频| 99热这里只有精品8| 久久久蜜臀国产一区二区| 日韩视频在线观看一区二区| 国产私拍一区| 国产精品v日韩精品v欧美精品网站| 欧美专区在线观看| 99精品国产在热久久下载| 女生裸体视频一区二区三区| 亚洲欧美国产毛片在线| 亚洲日韩第九十九页| 国产在线国偷精品产拍免费yy| 欧美日韩在线第一页| 久久一区中文字幕| 香蕉免费一区二区三区在线观看| 亚洲人精品午夜| 免费欧美在线| 久久国产色av| 欧美资源在线观看| 先锋影音一区二区三区| 一本色道久久综合亚洲精品婷婷| 亚洲电影在线观看| 黑人一区二区| 国内精品久久久久久久影视蜜臀| 国产精品国产a级| 欧美另类女人| 欧美精品日韩| 欧美激情久久久久久| 欧美a级片网| 欧美成人一区二免费视频软件| 久久久亚洲国产天美传媒修理工| 久久成人国产| 欧美一级大片在线免费观看| 亚洲一区二区在| 亚洲香蕉成视频在线观看 | 欧美大片一区二区| 免费短视频成人日韩| 美女被久久久| 欧美a级片网站| 欧美韩国一区| 亚洲国产成人不卡| 亚洲欧洲综合另类| 亚洲另类春色国产| 一区二区三区日韩精品视频| 在线亚洲国产精品网站| 亚洲私人影院在线观看| 亚洲免费视频在线观看| 午夜免费日韩视频| 久久久久国产精品一区| 久久综合999| 欧美日韩视频免费播放| 国产精品成av人在线视午夜片| 国产精品草草| 国产一区二区三区在线观看免费| 国产一区二区三区在线播放免费观看 | 国产精品日韩久久久| 国产欧美日韩视频在线观看| 国产在线欧美| 亚洲精品社区| 亚洲免费中文字幕| 久久五月天婷婷| 亚洲高清自拍| 制服丝袜亚洲播放| 欧美一区二区三区在线视频 | 久久噜噜噜精品国产亚洲综合| 免播放器亚洲一区| 欧美午夜在线| 国产日韩av一区二区| 亚洲全部视频| 久久超碰97中文字幕| 亚洲电影免费在线观看| 宅男噜噜噜66一区二区66| 亚洲欧美日本精品| 你懂的视频一区二区| 国产精品久久7| 亚洲国产精品一区在线观看不卡| 一区二区三区四区国产精品| 久久亚洲二区| 中文亚洲字幕| 欧美成人免费va影院高清| 国产精品久久久久久久久| 亚洲国产电影| 久久国产精品久久久久久久久久| 亚洲精品久久久蜜桃| 性欧美激情精品| 欧美日韩蜜桃| 91久久国产精品91久久性色| 欧美一区二区久久久| 亚洲欧洲一区二区天堂久久| 欧美影院精品一区| 国产精品高潮呻吟视频| 亚洲日本一区二区| 久久精品系列| 亚洲一区日本| 欧美午夜激情在线| 99精品免费| 亚洲电影欧美电影有声小说| 久久免费视频网|