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

天行健 君子當自強而不息

Controlling Players and Characters(39)

Once characters take enough damage, they die, and when that happens, the following
function is called:

void cCharController::death(sCharacter* attacker, sCharacter* victim)
{
    
// if a PC or NPC dies, then do not remove from list.
    if(victim->type == CHAR_PC || victim->type == CHAR_NPC)
    {        
        victim->update_enable = 
false;

        
if(victim->type == CHAR_PC)
            pc_death(victim);
        
else
            npc_death(victim);
    }
    
else    // victim->type = CHAR_MONSTER
    {
        
// give attacker the victim's experience
        if(attacker && gain_exp(attacker, victim->char_def.exp))
        {
            
char text[128];
            sprintf(text, "+%lu exp.", victim->char_def.exp);
            set_char_msg(attacker, text, 500, COLOR_WHITE);
        }
    }

    
if(m_mil && victim->char_def.money)
        drop_money(victim->pos_x, victim->pos_y, victim->pos_z, victim->char_def.money);

    
if(rand()%100 < victim->char_def.drop_chance)
        drop_item(victim->pos_x, victim->pos_y, victim->pos_z, victim->char_def.drop_item);

    sMeshAnim& mesh_anim = m_mesh_anim[victim->char_def.mesh_index];

    
if(--mesh_anim.count == 0)
    {
        mesh_anim.mesh.free();
        mesh_anim.anim.free();
    }

    
// remove the dead character from list

    
if(victim->prev)
        victim->prev->next = victim->next;
    
else
        m_root_char = victim->next;

    
if(victim->next)
        victim->next->prev = victim->prev;

    victim->prev = victim->next = NULL;
    delete victim;
}

virtual void pc_death(sCharacter* character)
{        

 }

virtual void npc_death(sCharacter* character)
{        
}


Taking the pointer to the victim, the controller is able to handle its death appropriately.
If the victim is a monster, you use the attacking character pointer to apply the
experience points. Also, if a monster dies, the death function determines how much
gold the monster drops and what item (if any) is dropped and calls the appropriate
controller function to handle such dropped items.

Leading into the next function, whenever a PC kills a monster, that PC gains the
experience stored in the monster’s MCL definition. To apply the experience, use
the following function:

    virtual bool gain_exp(sCharacter* character, long amount)
    {
        character->char_def.exp += amount;

        
return true;
    }

Notice that the gain_exp function can be overridden. This can occur when you’re
using a separate battle sequence engine; you don’t want experience added to the
PC until the battle is over. Consequently, you use your own function to keep track
of how much experience to apply when the battle is over.

The overridden function can also occur when the character needs to go up in
experience levels once he gains a certain number of experience points. The
gan_exp function is the place to determine just when a character goes up an
experience level and to take the appropriate actions to increase their abilities.

One note about the gain_exp function: The character controller normally displays
the number of experience points that a PC gains when killing a monster. To stop
the controller from displaying this number (as in the case of the separate battle
sequences), return a value of false from the Experience function.

The next couple of functions are the ones responsible for processing attacks and
spells. Both functions take pointers to the attacking characters (if any) as well as
their intended victims. For spells, a sSpellTracker structure is required to tell the
controller which spell to process, as well as the sSpell structure that contains the
information about the spell effects to use:

bool cCharController::attack(sCharacter* attacker, sCharacter* victim)
{
    
if(attacker == NULL || victim == NULL)
        
return false;

    
// do not attack dead or hurt character
    if(victim->action == CHAR_DIE || victim->action == CHAR_HURT)
        
return false;

    victim->attacker = attacker;
    attacker->victim = victim;
    
    
// return if hit missed
    if(rand()%1000 > get_to_hit(attacker))
    {
        set_char_msg(victim, "Missed!", 500, COLOR_WHITE);
        
return false;
    }

    
// return if hit dodged
    if(rand()%1000 <= get_agility(victim))
    {
        set_char_msg(victim, "Dodged!", 500, COLOR_WHITE);
        
return false;
    }

    
// if character is asleep, randomly wake them up (50% chance).
    if((victim->ailments & AILMENT_SLEEP) && rand()%100 < 50)    
        victim->ailments &= ~AILMENT_SLEEP;    

    
// attack landed, apply damage.
    damage(victim, true, get_attack(attacker), -1, -1);

    
return true;
}

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

bool cCharController::spell(sCharacter* caster, const sSpellTracker* spell_tracker, const sSpell* spells)
{
    
if(caster == NULL || spell_tracker == NULL || spells == NULL)
        
return false;

    
const sSpell* spell_ptr = &spells[spell_tracker->spell_index];

    
// reduce magic
    caster->mana_points -= spell_ptr->cost;
    
if(caster->mana_points < 0)
        caster->mana_points = 0;

    
// can not cast if silenced
    if(caster->ailments & AILMENT_SILENCED)
    {
        set_char_msg(caster, "Silenced!", 500, COLOR_WHITE);
        
return false;
    }

    
// handle self-targeting spells instantly
    if(spell_ptr->target == TARGET_SELF)
    {
        spell_effect(caster, caster, spell_ptr);
        
return true;
    }

    
float spell_dist = spell_ptr->range * spell_ptr->range;

    sCharacter* closest_char = NULL;
    
float closest = 0.0f;

    
// scan through all characters and look for hits
    for(sCharacter* char_ptr = m_root_char; char_ptr != NULL; char_ptr = char_ptr->next)
    {
        
// only bother with characters of allowed types.
        // also, allow a RAISE_DEAD PC spell to affect any character.

        
bool allow = false;

        
if(char_ptr != caster && spell_tracker->affect_type == char_ptr->type)
            allow = 
true;

        
if(char_ptr->type == CHAR_PC && spell_ptr->effect == RAISE_DEAD)
            allow = 
true;

        
if(!allow)
            
continue;

        
// get distance from target to character
        float x_diff = fabs(char_ptr->pos_x - spell_tracker->target_x);
        
float y_diff = fabs(char_ptr->pos_y - spell_tracker->target_y);
        
float z_diff = fabs(char_ptr->pos_z - spell_tracker->target_z);

        
// get x/z and y distances
        float xz_dist = (x_diff * x_diff + z_diff * z_diff) - spell_dist;
        
float y_dist  = (y_diff * y_diff) - spell_dist;

        
// get target x/z and y radius
        float min_x, min_y, min_z, max_x, max_y, max_z;
        char_ptr->
object.get_bounds(&min_x, &min_y, &min_z, &max_x, &max_y, &max_z, NULL);

        
float xz_radius = max(max_x - min_x, max_z - min_z) * 0.5f;
        
float y_radius  = (max_y - min_y) * 0.5f;

        
// check if character in range
        if(xz_dist > (xz_radius * xz_radius) || y_dist > (y_radius * y_radius))
            
continue;

        
// determine what to do if in range
        if(spell_ptr->target == TARGET_SINGLE)
        {
            
// record closest character in range
            float dist = x_diff * x_diff + y_diff * y_diff + z_diff * z_diff;

            
if(closest_char == NULL || dist < closest)
            {
                closest_char = char_ptr;
                closest = dist;
            }           
        }
        
else    // spell hit area targets
            spell_effect(caster, char_ptr, spell_ptr);
    }

    
// process spell on closest character if needed
    if(spell_ptr->target == TARGET_SINGLE && closest_char)
        spell_effect(caster, closest_char, spell_ptr);

    
return true;
}

Each of the preceding functions takes into account the attacking and defending
characters’ abilities and adjust their values accordingly. When an attack connects,
damage is dealt. When a spell is found to have affected the target (remember,
there’s a chance it might fail), the next function is called to process the effects:
bool cCharController::spell_effect(sCharacter* caster, sCharacter* target, const sSpell* spell)
{
    
if(target == NULL || spell == NULL)
        
return false;

    
long chance;

    
// calculate chance of hitting
    if(caster)
    {
        
// a spell always lands if target == caster
        if(caster == target)
            chance = 100;
        
else
            chance = (get_mental(caster)/100.0f + 1.0f) * spell->chance;        
    }
    
else
        chance = spell->chance;

    
// alter chance by target's registance
    if(caster != target)
        chance *= (1.0f - get_resistance(target)/100.0f);

    
// see if spell failed
    if(rand()%100 > chance)
    {
        set_char_msg(target, "Failed!", 500, COLOR_WHITE);
        
return false;
    }
    
    
bool can_hit = true;    // flag character to allow effect

    
if(target->action == CHAR_HURT || target->action == CHAR_DIE)
        can_hit = 
false;

    
// store attacker and victim

    target->attacker = caster;
  
    
if(caster)
        caster->victim = target;

    
char text[64];

    
// process spell effect
    switch(spell->effect)
    {
    
case ALTER_HEALTH:
        
if(can_hit)
        {
            
if(spell->value[0] < 0.0f)      // apply damage
                damage(target, false, -spell->value[0], spell->damage_class, spell->cure_class);
            
else if(spell->value[0] > 0.0f) // cure damage
            {
                target->health_points += spell->value[0];

                
if(target->health_points > target->char_def.health_points)
                    target->health_points = target->char_def.health_points;

                
// display amount healed
                sprintf(text, "+%lu HP", spell->value[0]);
                set_char_msg(target, text, 500, D3DCOLOR_RGBA(0, 64, 255, 255));
            }            
        }

        
break;

    
case ALTER_MANA:
        
if(can_hit)
        {
            target->mana_points += spell->value[0];

            
if(target->mana_points < 0)
                target->mana_points = 0;
            
else if(target->mana_points > target->char_def.mana_points)
                target->mana_points = target->char_def.mana_points;

            
if(spell->value[0] < 0.0f)
                sprintf(text, "%ld MP", spell->value[0]);
            
else if(spell->value[0] > 0.0f)
                sprintf(text, "+%ld MP", spell->value[0]);

            set_char_msg(target, text, 500, D3DCOLOR_RGBA(0, 128, 64, 255));            
        }

        
break;

    
case CURE_AILMENT:
        
if(can_hit)
        {
            
// cure ailment and display message
            target->ailments &= ~(long)spell->value[0];
            set_char_msg(target, "Cure", 500, COLOR_WHITE);            
        }

        
break;

    
case CAUSE_AILMENT:
        
if(can_hit)
        {
            
// cause ailment and display message
            target->ailments |= (long)spell->value[0];
            set_char_msg(target, "Ailment", 500, COLOR_WHITE);            
        }

        
break;

    
case RAISE_DEAD:
        
if(target->action == CHAR_DIE)
        {
            target->health_points = 1;
            target->mana_points   = 0;
            target->action        = CHAR_DIE;
            target->is_lock       = 
false;
            target->action_timer  = 0;
            target->ailments      = 0;
            target->update_enable = 
true;
        }
            
        
break;

    
case INSTANT_KILL:
        
if(can_hit)
            set_char_action(target, CHAR_DIE, 0);

        
break;

    
case DISPEL_MAGIC:
        
if(can_hit)
            target->ailments = 0;

        
break;

    
case TELEPORT:      // teleport PC/NPC/MONSTER
        if(can_hit)
        {
            
if(target->type == CHAR_PC)
                pc_teleport(caster, spell);
            
else
            {
                target->pos_x = spell->value[0];
                target->pos_y = spell->value[1];
                target->pos_z = spell->value[2];
            }
        }

        
break;
    }

    
return true;
}
 

posted on 2007-12-04 19:45 lovedday 閱讀(277) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統計

常用鏈接

隨筆分類(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>
            亚洲午夜久久久久久尤物| 久久九九全国免费精品观看| 久久成人资源| 翔田千里一区二区| 欧美在线|欧美| 久久亚洲欧洲| 亚洲国产美女| 夜夜精品视频| 欧美一级片久久久久久久 | 日韩亚洲国产精品| 亚洲小视频在线观看| 欧美一区二区三区四区在线 | 欧美/亚洲一区| 欧美日韩一区二区三区视频| 国产亚洲精品久久久| 亚洲电影欧美电影有声小说| 一本色道久久综合| 欧美~级网站不卡| 最新精品在线| 亚洲在线观看| 免费久久99精品国产自| 欧美视频一区| 在线观看中文字幕不卡| 亚洲小说春色综合另类电影| 久久久久国产精品一区| 亚洲每日更新| 久久狠狠亚洲综合| 久久久久天天天天| 国产精品视频免费观看| 亚洲国产天堂久久综合网| 亚洲日本欧美| 美女91精品| 亚洲欧美日韩精品在线| 亚洲欧美日韩天堂| 欧美v亚洲v综合ⅴ国产v| 夜夜嗨av一区二区三区四区| 久久久久久久综合| 欧美日韩欧美一区二区| 亚洲国产美女精品久久久久∴| 99视频一区| 欧美激情第一页xxx| 欧美中文字幕视频在线观看| 国产精品爽爽ⅴa在线观看| 一区二区三区www| 亚洲第一天堂av| 久久综合导航| 亚洲国产裸拍裸体视频在线观看乱了中文| 欧美一级夜夜爽| 中国成人黄色视屏| 欧美日韩综合在线免费观看| 亚洲精选一区| 男人天堂欧美日韩| 久久米奇亚洲| 在线观看一区视频| 久久久水蜜桃av免费网站| 亚洲欧美日韩国产一区| 国产精品一页| 久久9热精品视频| 午夜精品视频网站| 国产一区在线看| 久久一本综合频道| 久久九九精品| 亚洲日本国产| 亚洲日韩欧美视频一区| 欧美日韩精品免费观看视频| 国产精品99久久久久久宅男| 亚洲精选视频免费看| 欧美午夜精品久久久久久人妖| 亚洲少妇诱惑| 午夜精品久久| 亚洲成人影音| 亚洲人成精品久久久久| 欧美午夜精品久久久久久人妖 | 日韩一级不卡| 亚洲精品在线二区| 欧美午夜性色大片在线观看| 亚洲一区二区在线视频| 亚洲欧美日韩精品综合在线观看| 国产日产精品一区二区三区四区的观看方式 | 欧美在线免费观看| 在线观看欧美日韩| 亚洲精品国产精品国自产在线 | 久久国产直播| 亚洲精品系列| 亚洲欧美日韩精品在线| 尤物精品国产第一福利三区| 欧美激情一区二区三区蜜桃视频| 欧美日韩亚洲综合一区| 久久久av毛片精品| 欧美日韩伦理在线免费| 羞羞答答国产精品www一本| 久久久久久久综合色一本| 日韩西西人体444www| 欧美一区二区三区日韩视频| 99pao成人国产永久免费视频| 亚洲一区二区欧美| 亚洲国产精品成人综合| 亚洲一区二区3| 亚洲欧洲美洲综合色网| 亚洲在线免费| 亚洲美女av在线播放| 欧美在线www| 亚洲自啪免费| 欧美激情亚洲自拍| 久久久亚洲国产天美传媒修理工 | 久久伊人免费视频| 欧美二区在线看| 久久久久一区二区三区| 欧美日韩成人一区二区| 久久久欧美一区二区| 欧美四级在线| 久久综合九色综合欧美就去吻| 欧美网站在线观看| 老司机亚洲精品| 国产精品美女主播在线观看纯欲| 欧美激情国产日韩| 国产精品中文在线| 亚洲精选视频在线| 日韩视频免费在线| 久久影院午夜片一区| 久久久久女教师免费一区| 欧美日韩精品系列| 欧美成人免费大片| 国产一级精品aaaaa看| 亚洲伦理久久| 亚洲国产成人久久综合| 欧美片在线播放| 久久综合久久综合久久综合| 欧美a级片网| 欧美在线日韩在线| 欧美日韩在线第一页| 亚洲国产精品黑人久久久 | 亚洲在线一区二区三区| 老司机午夜精品视频| 久久久久久欧美| 国产午夜亚洲精品不卡| 99这里有精品| 99精品视频免费在线观看| 久久夜色精品亚洲噜噜国产mv| 久久精品二区| 国产精品一区二区黑丝| 亚洲精品视频在线播放| 99国内精品久久| 欧美日本三区| 亚洲国产高清在线观看视频| 亚洲精品美女在线观看播放| 亚洲国产精品成人综合| 免费看的黄色欧美网站| 美女尤物久久精品| 欧美日韩日日夜夜| 亚洲精品久久7777| 99精品免费| 国产精品theporn88| 一区二区三区视频免费在线观看| 99re热这里只有精品视频| 欧美日韩国产首页在线观看| 亚洲大黄网站| 夜夜爽99久久国产综合精品女不卡| 久久久久久国产精品mv| 久久久综合激的五月天| 国内成+人亚洲+欧美+综合在线| 久久精品一区二区三区中文字幕| 久久久夜夜夜| 亚洲欧美综合| 久久免费偷拍视频| 亚洲黄色一区| 欧美日韩中文字幕在线| 亚洲欧美另类综合偷拍| 久久综合九色综合网站 | 欧美亚洲在线观看| 国产午夜久久久久| 老司机午夜精品视频| 日韩视频免费观看| 亚洲一区免费在线观看| 狠狠色丁香婷婷综合久久片| 欧美精品在线一区二区三区| 亚洲免费在线观看| 亚洲欧洲一区二区天堂久久| 亚洲一区二区三区色| 国产又爽又黄的激情精品视频 | 欧美日韩岛国| 夜夜爽www精品| 久久亚洲午夜电影| 99re66热这里只有精品3直播| 国产精品网站一区| 欧美成在线观看| 久久精品99国产精品酒店日本| 一本色道久久综合狠狠躁篇的优点| 欧美一区中文字幕| 亚洲精品免费在线| 亚洲一区国产精品| 亚洲狼人精品一区二区三区| 久久久视频精品| 亚洲一区二区三区高清| 亚洲国产日韩欧美在线动漫| 国产精自产拍久久久久久| 欧美日韩精品在线观看| 久久精品视频播放| 亚洲一区国产精品| 亚洲肉体裸体xxxx137|