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

天行健 君子當自強而不息

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>
            亚洲片区在线| 午夜精品成人在线视频| 999亚洲国产精| 在线视频成人| 在线精品视频免费观看| 性久久久久久| 亚洲女ⅴideoshd黑人| 亚洲视频视频在线| 亚洲一线二线三线久久久| 亚洲自拍另类| 欧美一级午夜免费电影| 午夜精品亚洲| 性娇小13――14欧美| 欧美专区第一页| 久久久激情视频| 久久精品国产成人| 久久久久久综合| 久久另类ts人妖一区二区| 狂野欧美激情性xxxx| 欧美精品一区三区在线观看| 欧美日韩在线第一页| 国产精品日韩欧美综合 | 一区二区三区四区蜜桃| 99re视频这里只有精品| 一区二区三区国产盗摄| 欧美一区二区三区视频免费| 久久国产一区| 亚洲高清不卡在线| 欧美激情第10页| 亚洲高清三级视频| 一本大道久久a久久精二百| 欧美专区福利在线| 你懂的国产精品永久在线| 欧美激情一区二区三区在线| 国产精品久久久久久久久久久久久久 | 亚洲一区二区精品视频| 久久久www| 国产精品成人一区二区三区夜夜夜 | 香蕉久久夜色精品| 久久久精品2019中文字幕神马| 欧美精品久久久久久久免费观看 | 亚洲人体偷拍| 欧美影院成人| 日韩午夜电影av| 久久精品91久久香蕉加勒比| 欧美日韩精品免费观看视频| 激情五月婷婷综合| 亚洲欧美经典视频| 91久久夜色精品国产九色| 欧美一区二区视频在线| 欧美性开放视频| 亚洲另类在线视频| 欧美黄在线观看| 欧美中文字幕在线| 国产女人水真多18毛片18精品视频| 亚洲毛片av| 嫩模写真一区二区三区三州| 欧美中文字幕视频| 国产一区二区三区日韩| 午夜精品久久久久久久99黑人| 亚洲日本aⅴ片在线观看香蕉| 久久人人爽国产| 在线成人激情视频| 蜜桃视频一区| 久久中文久久字幕| 亚洲国产第一| 亚洲国产福利在线| 欧美国产日韩精品免费观看| 91久久久久| 亚洲人成久久| 欧美日韩视频不卡| 中文无字幕一区二区三区| 亚洲精品少妇30p| 欧美日韩亚洲一区二区三区在线观看| 亚洲人线精品午夜| 日韩一级不卡| 国产精品va在线播放我和闺蜜| 一区二区不卡在线视频 午夜欧美不卡在 | 久久伊人免费视频| 亚洲精品久久嫩草网站秘色 | 午夜精品久久| 国产毛片一区二区| 欧美专区亚洲专区| 亚洲欧美一级二级三级| 国内成人自拍视频| 欧美gay视频| 欧美精品 国产精品| 国产精品黄视频| 亚洲欧美日韩人成在线播放| 亚洲欧美国产一区二区三区| 国语自产精品视频在线看8查询8| 麻豆成人综合网| 欧美国产精品一区| 99精品视频免费| 亚洲自拍偷拍福利| 在线视频国产日韩| 一级成人国产| 国内精品久久久久影院优| 欧美黄色免费网站| 国产精品夜色7777狼人| 欧美jizz19hd性欧美| 欧美激情视频在线播放 | 欧美成人视屏| 亚洲欧美日韩天堂| 久久亚洲国产精品一区二区| aⅴ色国产欧美| 欧美一区二区三区四区夜夜大片| 亚洲国产高清在线观看视频| 夜夜嗨av一区二区三区四区 | 欧美激情综合色综合啪啪| 亚洲欧美日韩一区在线| 久久男人av资源网站| 亚洲视频在线二区| 久久中文久久字幕| 欧美专区在线播放| 欧美日韩在线第一页| 欧美国产日韩免费| 国产欧美日韩精品在线| 亚洲精品一区二区三区99| 国产一区二区无遮挡| avtt综合网| 亚洲三级影院| 久久这里有精品15一区二区三区| 欧美在线1区| 欧美日韩一区二区三区在线视频 | 亚洲影院色在线观看免费| 巨胸喷奶水www久久久免费动漫| 午夜国产精品视频| 欧美日韩中文字幕综合视频 | 玖玖玖国产精品| 国产精品视频自拍| 亚洲国产精品电影| 国产精品三区www17con| 日韩午夜电影av| 日韩午夜av在线| 久久久久久婷| 免费成人av资源网| 国产日本欧美一区二区三区在线 | 亚洲国产裸拍裸体视频在线观看乱了| 日韩一级在线观看| 国产在线观看一区| 久久大香伊蕉在人线观看热2| 亚洲视频精品在线| 欧美日韩精品免费观看| 日韩系列在线| 99精品国产一区二区青青牛奶| 久久亚洲一区二区三区四区| 久久久精品网| 娇妻被交换粗又大又硬视频欧美| 久久精品视频免费播放| 麻豆av一区二区三区| 国产一区二区三区网站| 久久久视频精品| 欧美国产日韩a欧美在线观看| 亚洲人成啪啪网站| 欧美日韩国产三区| 亚洲一区二区三区四区五区午夜| 欧美在线观看你懂的| 韩日视频一区| 欧美freesex交免费视频| 亚洲九九精品| 欧美一区二区三区久久精品| 国产亚洲aⅴaaaaaa毛片| 久久久久国产一区二区三区四区| 欧美成人免费在线观看| 一本色道久久综合一区| 国产精品久久久久天堂| 欧美专区一区二区三区| 亚洲大胆人体视频| 亚洲国产三级| 亚洲视频观看| 国产香蕉久久精品综合网| 久久综合精品一区| 亚洲另类在线一区| 久久成人精品视频| 91久久国产自产拍夜夜嗨| 欧美日韩国产成人高清视频| 亚洲欧美日韩高清| 欧美成人自拍| 亚洲一区二区在线视频| 伊人夜夜躁av伊人久久| 欧美日韩一区二区免费在线观看| 欧美在线视频日韩| 日韩一级大片在线| 欧美国产丝袜视频| 午夜影视日本亚洲欧洲精品| 亚洲国产精品女人久久久| 欧美性猛交一区二区三区精品| 久久精品麻豆| 亚洲视频一二| 亚洲国产成人久久综合| 久久精品麻豆| 亚洲视频在线观看三级| 亚洲国产导航| 国内在线观看一区二区三区 | 一区二区av在线| 欧美高清在线一区| 久久精品国产一区二区三区免费看| 日韩视频专区| 亚洲高清网站|