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

天行健 君子當自強而不息

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 閱讀(280) 評論(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>
            欧美精品一区二区三区一线天视频 | 亚洲欧美成人网| 亚洲精品日产精品乱码不卡| 欧美黄色免费| 亚洲视频在线一区观看| 亚洲丝袜av一区| 国产午夜精品麻豆| 免费h精品视频在线播放| 卡通动漫国产精品| 日韩亚洲精品视频| 亚洲一区二区毛片| 国内成人在线| 亚洲区国产区| 国产精品日日摸夜夜添夜夜av| 欧美资源在线| 免费观看不卡av| 亚洲一区在线视频| 欧美影片第一页| 亚洲毛片在线免费观看| 亚洲视频导航| 亚洲国产精品尤物yw在线观看| 欧美激情精品久久久久| 国产精品福利影院| 蜜桃久久精品乱码一区二区| 免费精品99久久国产综合精品| 一区二区三区欧美在线| 久久精品首页| 亚洲天堂av电影| 久久免费少妇高潮久久精品99| 在线一区亚洲| 久久综合中文字幕| 香蕉久久一区二区不卡无毒影院| 久久综合五月| 久久精品国产2020观看福利| 欧美劲爆第一页| 麻豆成人综合网| 国产精品国色综合久久| 欧美大片免费观看在线观看网站推荐| 欧美日韩一区二区三区在线视频| 久久婷婷色综合| 国产精品日韩欧美一区二区三区| 亚洲盗摄视频| 国内视频一区| 亚洲愉拍自拍另类高清精品| 亚洲精品资源美女情侣酒店| 久久se精品一区二区| 亚洲欧美日韩在线| 欧美日韩亚洲一区二区三区在线观看 | 亚洲欧美另类国产| 欧美国产日产韩国视频| 免费高清在线视频一区·| 国产精品美女在线| av72成人在线| 一区二区三区视频在线| 欧美二区在线| 亚洲电影激情视频网站| 又紧又大又爽精品一区二区| 午夜精品福利一区二区三区av| 一区二区三区国产精品| 欧美精品日韩www.p站| 欧美激情1区2区3区| 在线免费观看日韩欧美| 欧美自拍偷拍午夜视频| 久久se精品一区二区| 国产亚洲观看| 久久精品卡一| 欧美国产精品日韩| 亚洲国产欧美日韩精品| 欧美成人免费播放| 亚洲片在线观看| 亚洲制服少妇| 国产日韩欧美一区二区三区四区| 亚洲性视频网站| 欧美在线观看视频一区二区三区| 国产精品国产馆在线真实露脸| 夜色激情一区二区| 欧美一区综合| 伊人久久成人| 免费永久网站黄欧美| 亚洲精品1区2区| 亚洲一区国产| 国产亚洲精品久久久久久| 欧美中文在线观看国产| 亚洲成人自拍视频| 一区二区三区欧美亚洲| 国产精品美女久久久浪潮软件 | 亚洲丰满在线| 亚洲一区视频在线观看视频| 国产嫩草影院久久久久| 久久人人爽人人| 日韩亚洲一区在线播放| 欧美一区二区免费观在线| 国产一区二区观看| 女女同性精品视频| 亚洲午夜精品久久久久久浪潮| 欧美在线观看视频一区二区三区| 一区二区在线不卡| 欧美日韩三级一区二区| 午夜在线一区| 亚洲国产精品黑人久久久| 亚洲制服丝袜在线| 在线观看视频一区二区| 欧美日韩亚洲视频一区| 久久久久欧美| 亚洲午夜国产成人av电影男同| 久久午夜精品一区二区| 99热免费精品在线观看| 国产一区二区三区高清| 欧美日韩国产区| 久久精品色图| 亚洲系列中文字幕| 亚洲国产精品激情在线观看| 久久成人精品视频| 一区二区三区www| 亚洲国产精品女人久久久| 国产精品久久久亚洲一区| 美女脱光内衣内裤视频久久影院 | 蜜桃久久av| 久久精品国产一区二区三| 一本到高清视频免费精品| 红桃视频成人| 国产人久久人人人人爽| 欧美日韩国产一区| 美日韩在线观看| 欧美在线视频在线播放完整版免费观看| 91久久综合亚洲鲁鲁五月天| 美女网站久久| 久久裸体艺术| 久久精品中文字幕一区| 午夜亚洲一区| 午夜精品视频| 亚洲一区二区三区免费在线观看| 亚洲精品女av网站| 在线日韩电影| 一区在线电影| 在线成人激情黄色| 激情欧美丁香| 在线观看日韩欧美| 激情综合在线| 在线免费观看欧美| 亚洲国产精品成人| 伊人精品久久久久7777| 影音先锋亚洲视频| 亚洲国产精品久久久久婷婷884 | 亚洲精品资源| 99视频精品在线| 在线综合视频| 亚洲免费在线精品一区| 亚洲综合色自拍一区| 亚洲欧美在线另类| 欧美在线免费视频| 久久久久久**毛片大全| 久久色中文字幕| 欧美国产一区在线| 亚洲日本中文字幕区| 一区二区欧美激情| 亚洲欧美日韩国产一区二区三区 | 亚洲在线不卡| 久久国产精品99国产精| 久久久久久九九九九| 欧美mv日韩mv国产网站| 欧美日韩一区二区在线播放| 国产精品毛片高清在线完整版| 国产欧美一区二区精品性| 狠狠色丁香婷婷综合影院| 亚洲区中文字幕| 亚洲一区影院| 免费观看成人www动漫视频| 亚洲风情在线资源站| 中文在线资源观看网站视频免费不卡 | 久久久久www| 亚洲成色www8888| 在线视频一区观看| 久久久久久一区二区三区| 欧美日韩1234| 国产亚洲欧美另类一区二区三区| 亚洲国产一区二区三区青草影视| 亚洲免费av网站| 久久久精品2019中文字幕神马| 欧美成人嫩草网站| 亚洲午夜电影网| 欧美mv日韩mv国产网站| 国产精品美女视频网站| 亚洲欧洲日韩女同| 欧美一区日韩一区| 亚洲国产91| 欧美一区二区三区在线视频| 欧美韩日高清| 一区免费观看视频| 亚洲欧美日韩另类精品一区二区三区| 美女诱惑一区| 亚洲欧美精品suv| 欧美日韩亚洲一区二| 亚洲国产成人不卡| 久久精品人人做人人爽电影蜜月| 91久久精品国产91性色tv| 久久久久久久久久久久久9999 | 久色婷婷小香蕉久久| 国产精品入口夜色视频大尺度| 亚洲免费不卡|