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

天行健 君子當(dāng)自強(qiáng)而不息

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)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(178)

3D游戲編程相關(guān)鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美wwwwww| 欧美激情在线播放| 亚洲最新视频在线| 欧美在线免费视屏| 99精品欧美一区| 久久精品在线| 欧美在线亚洲| 欧美视频在线观看视频极品| 欧美高清视频www夜色资源网| 国产精品久久久久久久电影| 欧美1区2区| ●精品国产综合乱码久久久久| 欧美亚洲综合另类| 欧美在线黄色| 国产在线欧美日韩| 欧美伊人精品成人久久综合97| 欧美一区视频在线| 国产欧美二区| 欧美在线免费一级片| 久久综合伊人77777蜜臀| 国产综合色产在线精品| 久久黄色小说| 美女脱光内衣内裤视频久久影院| 国产一区二区毛片| 久久九九国产精品怡红院| 久久综合国产精品台湾中文娱乐网| 国产日韩欧美在线| 欧美在线免费| 欧美激情中文字幕一区二区| 亚洲精品欧洲| 欧美午夜激情小视频| 亚洲网站视频福利| 久久九九热re6这里有精品| 国产尤物精品| 你懂的国产精品| 亚洲精品美女免费| 亚洲一区二区三区色| 国产精品欧美久久| 久久国产精品99国产| 你懂的亚洲视频| 99精品热6080yy久久| 国产精品久久久久9999吃药| 欧美一级免费视频| 亚洲二区三区四区| 在线午夜精品自拍| 国产私拍一区| 欧美国产精品v| 亚洲性图久久| 欧美大片免费久久精品三p | 欧美a级一区二区| 亚洲卡通欧美制服中文| 欧美尤物一区| 亚洲精品久久久久| 国产精品日韩欧美| 久久视频免费观看| 中文av字幕一区| 久久综合网络一区二区| 亚洲视频1区2区| 国模吧视频一区| 欧美日韩精品综合| 久久久久久亚洲精品杨幂换脸| 亚洲国产视频一区| 久久精品免费播放| 夜色激情一区二区| 亚洲一级影院| 欧美成人精品| 久久精品成人一区二区三区蜜臀 | 激情视频一区| 国产精品久久一区主播| 欧美不卡激情三级在线观看| 亚洲一区二三| 日韩午夜av在线| 欧美激情亚洲国产| 久久久视频精品| 午夜精品在线观看| 亚洲特级片在线| 亚洲人成欧美中文字幕| 国产日产精品一区二区三区四区的观看方式 | 欧美综合国产| 亚洲主播在线观看| 亚洲精品久久久久中文字幕欢迎你| 久久久国产成人精品| 亚洲在线播放| 一本色道久久综合精品竹菊 | 亚洲免费不卡| 亚洲电影激情视频网站| 美女任你摸久久| 久久久噜噜噜久久人人看| 香蕉久久夜色| 亚洲永久免费精品| 亚洲小说春色综合另类电影| 亚洲精品美女久久久久| 亚洲第一综合天堂另类专| 国产一区999| 国产一区导航| 韩国三级电影一区二区| 国产精品一区二区视频| 国产精品黄色| 国产精品男人爽免费视频1| 国产精品国色综合久久| 国产精品剧情在线亚洲| 欧美色道久久88综合亚洲精品| 欧美日韩亚洲视频一区| 欧美日韩国产综合视频在线观看| 欧美成人午夜77777| 免费一级欧美在线大片| 欧美风情在线| 欧美日韩aaaaa| 欧美三级电影网| 国产精品嫩草影院av蜜臀| 国产精品婷婷| 狠狠色丁香久久婷婷综合丁香| 狠狠爱综合网| 91久久国产精品91久久性色| 亚洲精品乱码久久久久久蜜桃91| 亚洲精品乱码久久久久久久久| 亚洲看片一区| 午夜精品久久久久久久久久久久| 午夜精品一区二区三区在线视 | 一本不卡影院| 性色av香蕉一区二区| 欧美影院午夜播放| 美日韩在线观看| 欧美日本亚洲视频| 国产精品久久网站| 极品少妇一区二区三区| 亚洲精品久久久久久久久久久久| 中文一区二区| 久久成人精品| 亚洲国产精品尤物yw在线观看| 亚洲精品视频中文字幕| 日韩视频在线免费观看| 亚洲影院污污.| 免费观看欧美在线视频的网站| 亚洲激情精品| 性欧美xxxx视频在线观看| 欧美77777| 国产精品一二一区| 亚洲国产裸拍裸体视频在线观看乱了 | 亚洲一区二区动漫| 久久精品国产免费观看| 亚洲日本激情| 久久国产精品久久国产精品| 欧美日韩岛国| 一区免费观看| 亚洲欧美另类国产| 亚洲国产精品久久人人爱蜜臀 | 欧美精品三级在线观看| 国产欧美一区二区精品忘忧草| 亚洲欧洲精品一区二区三区波多野1战4| 一区二区三区四区国产精品| 久久久精品免费视频| 亚洲精品日韩在线观看| 久久精品综合| 国产精品视频99| 亚洲裸体在线观看| 久久先锋影音av| 亚洲一区二区在线看| 欧美精品一区二| 在线观看亚洲专区| 久久精品一区二区三区不卡牛牛 | 亚洲欧美三级伦理| 欧美日韩免费精品| 亚洲麻豆一区| 欧美成人一区在线| 久久精品视频99| 国产区精品视频| 亚洲欧美日韩精品| 日韩亚洲精品电影| 欧美久久婷婷综合色| 亚洲狠狠丁香婷婷综合久久久| 久久久久久91香蕉国产| 亚洲欧美成人在线| 国产精品免费在线| 亚洲欧美福利一区二区| 99国产一区| 欧美日韩亚洲高清一区二区| 亚洲美女电影在线| 欧美电影电视剧在线观看| 久久久亚洲国产美女国产盗摄| 国产有码一区二区| 久久久久久成人| 欧美一区视频在线| 国产在线拍揄自揄视频不卡99| 亚洲欧美在线免费| 亚洲图片你懂的| 国产精品影院在线观看| 亚洲欧美日韩一区二区| 亚洲欧美国产日韩天堂区| 国产精品你懂的在线欣赏| 亚洲欧美伊人| 欧美一区高清| 影视先锋久久| 亚洲第一黄色| 欧美日韩国产美| 亚洲欧美日韩电影| 欧美一区二区三区免费视| 精品动漫3d一区二区三区免费 | 免费看精品久久片| 女同性一区二区三区人了人一|