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

天行健 君子當(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 閱讀(308) 評(píng)論(0)  編輯 收藏 引用


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


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(178)

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

搜索

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美成人综合一区| 蜜臀99久久精品久久久久久软件| 欧美裸体一区二区三区| 亚洲精品乱码久久久久久久久 | 国产精品久久久久秋霞鲁丝 | 黄网站免费久久| 久久婷婷综合激情| 久久九九热免费视频| 影音先锋欧美精品| 亚洲国产成人av| 欧美成人性网| 亚洲免费中文| 欧美一区激情| 亚洲国产美国国产综合一区二区| 亚洲国产精品一区在线观看不卡 | 久久久久91| 亚洲三级影院| 亚洲主播在线播放| 黄色工厂这里只有精品| 亚洲春色另类小说| 欧美先锋影音| 久久综合色综合88| 欧美日韩dvd在线观看| 欧美一区影院| 美女久久一区| 欧美一区二区三区播放老司机 | 一本一本a久久| 国产情侣一区| 亚洲国产精品va在看黑人| 欧美午夜无遮挡| 美女精品在线观看| 国产精品美女在线| 亚洲国产成人精品久久| 国产麻豆视频精品| 亚洲三级影片| ●精品国产综合乱码久久久久| 亚洲精品久久久久久久久久久| 国产欧美日韩在线播放| 亚洲欧洲在线一区| 狠狠色丁香婷婷综合久久片| 一区二区三区 在线观看视频| 黄色日韩精品| 亚洲欧美春色| aa亚洲婷婷| 久久久亚洲国产天美传媒修理工| 亚洲免费综合| 欧美激情欧美激情在线五月| 久久精品视频亚洲| 国产精品免费小视频| 亚洲欧洲另类| 亚洲人成网站777色婷婷| 久久精品中文字幕一区二区三区| 亚洲午夜在线观看| 麻豆免费精品视频| 久久亚洲综合色| 国产午夜亚洲精品理论片色戒| 亚洲美女在线视频| 亚洲日韩欧美一区二区在线| 久久米奇亚洲| 裸体一区二区| 一区二区在线不卡| 久久亚洲国产成人| 久久中文精品| 狠狠入ady亚洲精品| 欧美一区二区精品在线| 欧美伊人久久| 国产人成一区二区三区影院| 亚洲欧美日本日韩| 久久精品在线播放| 国产一级一区二区| 久久国产高清| 欧美成ee人免费视频| 精品不卡在线| 久久在精品线影院精品国产| 欧美xx视频| 亚洲啪啪91| 欧美日本国产一区| 999在线观看精品免费不卡网站| 一本色道久久88综合日韩精品| 欧美日韩成人在线播放| 在线亚洲欧美视频| 欧美一区二区视频在线| 很黄很黄激情成人| 免费亚洲电影在线| 亚洲精品你懂的| 99re热这里只有精品免费视频| 欧美精品一区二区三区高清aⅴ| 亚洲六月丁香色婷婷综合久久| 亚洲主播在线| 狠狠色丁香婷婷综合影院| 你懂的国产精品永久在线| 91久久中文字幕| 亚洲欧美电影在线观看| 国产色综合网| 牛夜精品久久久久久久99黑人 | 久久国产婷婷国产香蕉| 在线观看日韩| 欧美性猛片xxxx免费看久爱| 午夜久久资源| 亚洲国产免费| 欧美在线首页| 91久久久久久| 国产片一区二区| 欧美韩国日本一区| 亚洲免费视频网站| 欧美福利在线| 午夜精品久久久久| 亚洲国产成人高清精品| 欧美性生交xxxxx久久久| 销魂美女一区二区三区视频在线| 欧美成人小视频| 先锋资源久久| 亚洲免费精品| 狠狠综合久久| 国产精品一级二级三级| 欧美激情片在线观看| 久久精品水蜜桃av综合天堂| 99视频在线精品国自产拍免费观看| 久久精品国产久精国产爱| 99国产精品久久久久老师| 国内精品久久久久久久影视麻豆 | 欧美一区二区成人| 99热这里只有成人精品国产| 久久久亚洲欧洲日产国码αv | 一区二区欧美视频| 在线日韩中文| 精品99一区二区| 国产免费成人| 国产精品高精视频免费| 欧美大片免费看| 久久久噜噜噜久久久| 香蕉av福利精品导航| 一区二区三区国产在线| 亚洲国产成人av在线| 麻豆乱码国产一区二区三区| 久久精品人人做人人爽| 香蕉精品999视频一区二区| 国产精品99久久久久久久久久久久 | 西瓜成人精品人成网站| 夜夜狂射影院欧美极品| 亚洲国产精品小视频| 欧美大片一区| 欧美激情精品久久久六区热门 | 欧美成人中文| 欧美成va人片在线观看| 免费在线播放第一区高清av| 久久久天天操| 久久久www| 久久久久久久久久久久久久一区| 欧美一区二区精品在线| 欧美一级片在线播放| 欧美有码在线观看视频| 午夜在线不卡| 欧美在线首页| 猫咪成人在线观看| 欧美激情成人在线视频| 亚洲高清在线| 亚洲国产欧美日韩| 亚洲国产清纯| 一区二区三区高清| 亚洲欧美在线观看| 久久av资源网| 老司机免费视频一区二区三区 | 午夜免费日韩视频| 久久aⅴ乱码一区二区三区| 久久久久久久性| 欧美大片免费观看| 国产精品另类一区| 国产主播在线一区| 亚洲欧洲日本一区二区三区| 夜夜狂射影院欧美极品| 欧美一区在线视频| 免费观看一区| 夜夜狂射影院欧美极品| 午夜视频在线观看一区| 久久久女女女女999久久| 欧美激情aaaa| 国产精品久线观看视频| 国内精品嫩模av私拍在线观看 | 亚洲国产精品久久精品怡红院| 99在线精品视频| 欧美诱惑福利视频| 欧美国产综合视频| 亚洲午夜电影在线观看| 久久精品中文| 欧美日韩一区二区三区免费看| 国产免费成人av| 亚洲美洲欧洲综合国产一区| 欧美一级在线播放| 亚洲缚视频在线观看| 亚洲欧美在线观看| 欧美久久久久中文字幕| 国内精品免费在线观看| 亚洲午夜性刺激影院| 女人天堂亚洲aⅴ在线观看| 一区二区三区欧美在线观看| 免费久久精品视频| 国产欧美日韩| 一区二区三区视频在线播放| 美女脱光内衣内裤视频久久网站|