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

天行健 君子當自強而不息

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>
            亚洲制服欧美中文字幕中文字幕| 欧美一乱一性一交一视频| 久久久夜色精品亚洲| 国产综合视频| 美女国产精品| 欧美高清视频www夜色资源网| 亚洲茄子视频| 一区二区三区四区五区精品视频| 欧美系列亚洲系列| 久久久久国产精品厨房| 久久成人18免费观看| 91久久在线视频| 一本色道久久88亚洲综合88| 国产精品美女一区二区| 久久xxxx精品视频| 麻豆国产精品va在线观看不卡| 亚洲精品午夜精品| 亚洲深夜福利网站| 在线精品观看| 夜夜爽www精品| 国产尤物精品| 亚洲人屁股眼子交8| 欧美亚洲第一区| 免费成人高清视频| 国产精品久久久久aaaa| 久久视频一区二区| 欧美日韩国产不卡| 久久偷窥视频| 国产精品久久久久久户外露出| 另类成人小视频在线| 欧美日韩在线高清| 欧美粗暴jizz性欧美20| 国产精品hd| 欧美国产精品v| 国产视频一区免费看| 亚洲精品久久久久中文字幕欢迎你 | 久久久中精品2020中文| 欧美男人的天堂| 久久成人资源| 国产精品久久久久秋霞鲁丝| 亚洲国产乱码最新视频| 国产日韩欧美综合一区| 99riav国产精品| 在线日本成人| 欧美在线综合视频| 亚洲欧美国产另类| 欧美日韩一区二区在线| 欧美搞黄网站| 欲香欲色天天天综合和网| 亚洲欧美日韩一区二区| 亚洲视频观看| 欧美日韩在线三级| 亚洲精品少妇30p| 亚洲激情一区二区三区| 欧美主播一区二区三区| 欧美一级黄色网| 国产精品亚洲综合| 亚洲视频1区| 亚洲免费在线观看| 欧美日韩无遮挡| 99视频日韩| 亚洲视频综合| 国产精品久久精品日日| 一个色综合av| 午夜精品国产| 国产精品爽爽爽| 香蕉成人伊视频在线观看| 欧美专区在线观看一区| 国产精品美女| 亚洲欧美一区二区视频| 性一交一乱一区二区洋洋av| 国产精品美女久久| 亚洲淫性视频| 久久久久久久久岛国免费| 国产一区二区三区在线观看免费视频| 午夜久久福利| 免费在线观看日韩欧美| 亚洲国产精品国自产拍av秋霞| 看欧美日韩国产| 亚洲精品免费在线播放| 国产精品99久久久久久白浆小说| 欧美午夜免费电影| 亚洲欧美日韩在线不卡| 久久久久**毛片大全| 亚洲国产美女久久久久| 免费日韩成人| 一区二区三区久久久| 久久国产精品久久久| 在线观看三级视频欧美| 欧美日本在线播放| 亚洲一区综合| 亚洲大片在线| 午夜在线视频观看日韩17c| 国产一区久久久| 欧美激情欧美激情在线五月| 一区二区日韩| 另类综合日韩欧美亚洲| 中文欧美字幕免费| 一区二区视频免费在线观看| 欧美国产综合视频| 欧美亚洲三区| 亚洲国产三级在线| 欧美一区午夜视频在线观看| 亚洲电影免费在线| 欧美日韩人人澡狠狠躁视频| 欧美中文字幕不卡| 日韩系列欧美系列| 免费av成人在线| 欧美一级电影久久| 日韩视频免费在线| 国产性做久久久久久| 欧美激情视频网站| 久久精品系列| 中文在线一区| 亚洲日本激情| 男人的天堂亚洲在线| 午夜亚洲性色福利视频| 亚洲免费久久| 亚洲国产精品欧美一二99| 国产精品一二三视频| 欧美女同视频| 欧美高清在线视频| 久久国产欧美日韩精品| 亚洲午夜一二三区视频| 亚洲国产欧美在线| 欧美成人免费网| 久久精品国产99精品国产亚洲性色| 这里只有精品视频| 亚洲精品久久久久| 亚洲国产成人久久综合| 韩国av一区二区三区四区| 国产精品久久久久一区| 欧美日韩一卡| 欧美日韩美女在线| 欧美日韩裸体免费视频| 欧美精品手机在线| 欧美激情久久久久久| 欧美xx69| 欧美日韩国内| 欧美私人啪啪vps| 国产精品ⅴa在线观看h| 国产精品黄色在线观看| 欧美性一区二区| 国产精品一级二级三级| 国产日产欧产精品推荐色 | 美女图片一区二区| 免费欧美在线| 欧美黑人一区二区三区| 欧美丰满高潮xxxx喷水动漫| 欧美激情精品久久久久久免费印度| 毛片一区二区三区| 欧美.com| 欧美亚一区二区| 国产欧美精品| 狠狠色丁香婷综合久久| 在线观看日韩一区| 亚洲精品影视| 午夜精品福利在线观看| 欧美主播一区二区三区| 老色鬼久久亚洲一区二区| 免费欧美在线| 亚洲精品在线三区| 亚洲综合好骚| 蜜臀av国产精品久久久久| 欧美激情一区二区在线| 国产精品高潮粉嫩av| 国产亚洲欧美日韩日本| 亚洲精品1234| 午夜国产精品视频| 久久综合狠狠综合久久激情| 亚洲高清免费在线| 亚洲四色影视在线观看| 久久99在线观看| 欧美激情一区二区久久久| 国产精品www网站| 伊人男人综合视频网| 一本色道88久久加勒比精品| 欧美在线视频不卡| 欧美黄色aaaa| 亚洲综合日韩中文字幕v在线| 久久精品欧美日韩| 欧美日本一道本| 在线成人h网| 先锋影音网一区二区| 欧美电影免费观看| 亚洲欧美在线免费| 欧美精品123区| 国产一区二区三区免费不卡| 亚洲三级影院| 久久在线视频在线| 中文精品一区二区三区 | 欧美在线亚洲一区| 欧美日本国产在线| 亚洲电影中文字幕| 久久av最新网址| 一区二区三区蜜桃网| 嫩草国产精品入口| 国产综合一区二区| 香蕉精品999视频一区二区 | 久久婷婷影院|