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

天行健 君子當自強而不息

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>
            欧美在线免费视屏| 欧美一区二区三区精品| 欧美激情一区二区三区在线| 亚洲少妇在线| 欧美黑人在线观看| 在线看国产日韩| 久久成年人视频| 亚洲激情视频| 久久手机免费观看| 在线欧美一区| 欧美电影免费观看大全| 久久久久久亚洲精品不卡4k岛国| 国产亚洲一区二区精品| 久久久久99精品国产片| 欧美在线三级| 国产在线观看精品一区二区三区| 午夜精品视频在线观看一区二区| 在线视频亚洲| 国产精品久久9| 午夜精品一区二区三区四区| 亚洲一区二区三区在线播放| 国产欧美韩日| 日韩五码在线| 99www免费人成精品| 欧美午夜精品一区| 先锋影音久久久| 欧美一级一区| 亚洲国产精品一区二区www| 欧美福利视频在线| 欧美久久久久久蜜桃| 亚洲四色影视在线观看| 99pao成人国产永久免费视频| 欧美日韩国产综合视频在线观看中文| 亚洲视频碰碰| 午夜精品久久久久久久| 狠狠综合久久av一区二区老牛| 嫩草影视亚洲| 欧美精品精品一区| 性色一区二区| 久热re这里精品视频在线6| 99视频精品全国免费| 亚洲一二三级电影| 1769国产精品| 一区二区不卡在线视频 午夜欧美不卡在| 国产精品mm| 久久久亚洲成人| 欧美精品久久99| 久久成人综合网| 欧美插天视频在线播放| 亚洲欧美日韩精品久久亚洲区 | 久久米奇亚洲| 欧美激情精品久久久久久大尺度| 亚洲欧美精品中文字幕在线| 亚洲免费电影在线| 久久综合激情| 欧美日本簧片| 另类人畜视频在线| 国产精品一区二区黑丝| 亚洲人成欧美中文字幕| 国外成人在线视频网站| 中日韩美女免费视频网站在线观看| 永久91嫩草亚洲精品人人| 亚洲一区二区三区中文字幕| 亚洲日本黄色| 久久综合久色欧美综合狠狠| 欧美一二区视频| 欧美日韩国产欧美日美国产精品| 快射av在线播放一区| 国产精品久99| 亚洲美女电影在线| 亚洲高清网站| 欧美在线综合视频| 午夜一区二区三区不卡视频| 99视频在线精品国自产拍免费观看| 在线观看91精品国产入口| 午夜激情久久久| 国产综合在线视频| 亚洲一区二区影院| 亚洲深夜福利在线| 欧美另类综合| 亚洲精品国产精品久久清纯直播| 在线观看亚洲a| 久久精品国产久精国产思思 | 亚洲午夜精品一区二区| 一区二区激情小说| 欧美激情中文不卡| 亚洲人成人一区二区三区| 亚洲黄色av| 女人天堂亚洲aⅴ在线观看| 另类成人小视频在线| 激情综合色丁香一区二区| 久久av一区二区三区漫画| 久久精品国产99国产精品| 国产欧美一二三区| 久久精品中文字幕免费mv| 久久资源av| 18成人免费观看视频| 久久综合久久综合九色| 欧美粗暴jizz性欧美20| 亚洲日本中文字幕区| 欧美精品激情blacked18| 日韩亚洲综合在线| 翔田千里一区二区| 国内外成人免费视频| 久久久久五月天| 亚洲大片一区二区三区| 一本一本久久| 国产精品久久久久久久久久直播 | 免费在线观看精品| 亚洲精品久久在线| 国产精品成人观看视频免费| 亚洲欧美激情诱惑| 麻豆91精品| 一区二区三区精品| 国产日韩一区二区三区在线播放| 欧美黑人国产人伦爽爽爽| 亚洲肉体裸体xxxx137| 一区二区三区色| 国产精品嫩草影院av蜜臀| 欧美一区二区三区视频免费| 欧美jizzhd精品欧美巨大免费| 亚洲三级电影全部在线观看高清| 欧美精品三级在线观看| 亚洲小说春色综合另类电影| 久久久www免费人成黑人精品 | 亚洲日本va午夜在线电影| 欧美日韩精品国产| 午夜一区二区三视频在线观看| 欧美 日韩 国产一区二区在线视频| 99av国产精品欲麻豆| 国产精品色在线| 蜜臀av在线播放一区二区三区| 妖精成人www高清在线观看| 久久蜜臀精品av| 亚洲香蕉网站| 欲色影视综合吧| 国产精品久久久久久久一区探花 | 欧美黄色免费| 欧美一区二区三区久久精品| 亚洲人体偷拍| 久久综合久久美利坚合众国| 亚洲色图自拍| 亚洲精品免费在线观看| 国产字幕视频一区二区| 国产精品国产三级国产普通话99 | 亚洲香蕉伊综合在人在线视看| 免费观看在线综合色| 欧美在线观看一区二区| 中文精品视频| 日韩视频二区| 亚洲国产精品ⅴa在线观看| 国产精品综合久久久| 欧美日韩人人澡狠狠躁视频| 蜜桃av一区二区三区| 久久久久一区二区三区四区| 亚洲欧美视频在线观看| 一区二区三区成人| 亚洲精品一区二区三区不| 欧美激情国产日韩| 免费一级欧美片在线播放| 久久精品五月| 欧美中文字幕视频在线观看| 亚洲欧美日韩天堂一区二区| 99在线热播精品免费| 亚洲欧洲偷拍精品| 在线欧美福利| 亚洲黄一区二区| 亚洲人体一区| 99精品国产一区二区青青牛奶| 91久久中文| 日韩午夜视频在线观看| 日韩一二在线观看| 一本一本a久久| 中文av字幕一区| 中文网丁香综合网| 亚洲在线中文字幕| 先锋影音网一区二区| 欧美在线视频全部完| 亚洲一区二区三区精品动漫| 亚洲欧美日韩国产精品| 一区二区不卡在线视频 午夜欧美不卡在 | 国产精品久久久久久久免费软件 | 国产日韩精品视频一区二区三区| 国产精品入口尤物| 国产日产高清欧美一区二区三区| 国产精品一区视频网站| 国产在线拍揄自揄视频不卡99| 国产一区清纯| 91久久精品国产91性色| 日韩亚洲欧美中文三级| 亚洲一区二区久久| 欧美在线一二三四区| 久久综合一区二区三区| 欧美激情影音先锋| 99视频国产精品免费观看| 亚洲永久免费精品| 久久久久久电影| 欧美激情va永久在线播放| 欧美性生交xxxxx久久久| 国产亚洲精品久久久|