combatd.old
来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· OLD 代码 · 共 792 行 · 第 1/3 页
OLD
792 行
else if ( sizeof(prepare) == 0) attack_skill = "unarmed";
else if ( sizeof(prepare) == 1) attack_skill = (keys(prepare))[0];
else if ( sizeof(prepare) == 2) attack_skill = (keys(prepare))[me->query_temp("action_flag")];
// (1) Find out what action the offenser will take.
me->reset_action();
action = me->query("actions");
if( !mapp(action) ) {
me->reset_action();
action = me->query("action");
if( !mapp(action) ) {
CHANNEL_D->do_channel( this_object(), "sys",
sprintf("%s(%s): bad action = %O",
me->name(1), me->query("id"), me->query("actions", 1)));
return 0;
}
}
if (me->query_temp("action_flag") == 0)
result = "\n" + action["action"] + "!\n";
else
result = "\n" + "招式未老"+action["action"] + "!\n";
if(stringp(attack_msg)) result = "\n" + attack_msg + "\n";
//
// (2) Prepare AP, DP for checking if hit.
//
if( objectp(weapon) ) attack_skill = weapon->query("skill_type");
else attack_skill = "unarmed";
limbs = victim->query("limbs");
limb = limbs[random(sizeof(limbs))];
ap = skill_power(me, attack_skill, SKILL_USAGE_ATTACK);
if( ap < 1) ap = 1;
if (userp(me) && intp(action["dodge"]))
me->set_temp("fight/dodge", action["dodge"]);
dp = skill_power(victim, "dodge", SKILL_USAGE_DEFENSE);
if( dp < 1 ) dp = 1;
if( victim->is_busy() ) dp /= 3;
/* // (2.5) Let's see what/who can protect our victim, $N, $n,...all applies
if(sizeof(victim->query_temp("protectors")) && do_protect(me,weapon,ap,victim))
{
result += victim->query_temp("protectors_msg");
damage = RESULT_PROTECT;
}
else
{*/
// (3) Fight!
// Give us a chance of AP/(AP+DP) to "hit" our opponent. Since both
// AP and DP are greater than zero, so we always have chance to hit
// or be hit.
if( random(ap + dp) < dp ) { // Does the victim dodge this hit?
dodge_skill = victim->query_skill_mapped("dodge");
if( !dodge_skill ) dodge_skill = "dodge";
result += SKILL_D(dodge_skill)->query_dodge_msg(limb);
if( dp < ap && (!userp(victim) || !userp(me))
&& random(your["jing"]*100/your["max_jing"] + your["int"]) > 50 ) {
your["combat_exp"] += 1;
victim->improve_skill("dodge", 1);
}
// This is for NPC only. NPC have chance to get exp when fail to hit.
if( (ap < dp) && !userp(me) ) {
if( random(my["int"]) > 15 ) my["combat_exp"] += 1;
me->improve_skill(attack_skill, random(my["int"]));
}
damage = RESULT_DODGE;
} else {
//
// (4) Check if the victim can parry this attack.
//
if( victim->query_temp("weapon") ) {
pp = skill_power(victim, "parry", SKILL_USAGE_DEFENSE);
if( !weapon ) pp *= 2;
} else {
if( weapon ) pp = 0;
else pp = skill_power(victim, "unarmed", SKILL_USAGE_DEFENSE);
}
if( victim->is_busy() ) pp /= 3;
if( pp < 1 ) pp = 1;
if( random(ap + pp)< pp ) {
parry_skill = victim->query_skill_mapped("parry");
if( !parry_skill ) parry_skill = "parry";
// change to SKILL_D(parry_skill) after added parry msg to those
// martial arts that can parry.
result += SKILL_D("parry")->query_parry_msg(weapon);
if( dp < ap && (!userp(victim) || !userp(me))
&& random(your["jing"]*100/your["max_jing"] + your["int"]) > 50 ) {
your["combat_exp"] += 1;
victim->improve_skill("parry", 1);
}
damage = RESULT_PARRY;
} else {
//
// (5) We hit the victim and the victim failed to parry
//
damage = (me->query_temp("apply/damage"))+ 2;
damage = (damage + random(damage)) / 2;
if( action["damage"] )
damage += action["damage"] * damage / 2000;
damage_bonus = me->query_str();
damage_bonus = damage_bonus * damage_bonus / 10;
// if use weapon, effectiveness only 2/3
if(weapon) damage_bonus -= damage_bonus/3;
// Let force skill take effect.
if( my["jiali"] && (my["neili"] > my["jiali"]) ) {
if( force_skill = me->query_skill_mapped("force") ) {
foo = SKILL_D(force_skill)->hit_ob(me, victim, damage_bonus, my["jiali"]);
if( stringp(foo) ) result += foo;
else if( intp(foo) ) damage_bonus += foo;
}
}
if( action["force"] )
damage_bonus += action["force"] * damage_bonus / 100;
if( martial_skill = me->query_skill_mapped(attack_skill) ) {
foo = SKILL_D(martial_skill)->hit_ob(me,victim, damage_bonus);
if( stringp(foo) ) result += foo;
else if(intp(foo) ) damage_bonus += foo;
}
// Let weapon or monster have their special damage.
if( weapon ) {
foo = weapon->hit_ob(me, victim, damage_bonus);
if( stringp(foo) ) result += foo;
else if(intp(foo) ) damage_bonus += foo;
} else {
foo = me->hit_ob(me, victim, damage_bonus);
if( stringp(foo) ) result += foo;
else if(intp(foo) ) damage_bonus += foo;
}
if( damage_bonus > 0 )
damage += (damage_bonus + random(damage_bonus))/2;
if( damage < 0 ) damage = 0;
// Let combat exp take effect
bounce = your["combat_exp"];
while( random(bounce) > my["combat_exp"] ) {
damage -= damage / 3;
defense_factor /= 2;
}
bounce = 0;
// (5.4) see how much damage our flexibility can absorb
damage -= ((int)victim->query_fle());
damage -= (int)victim->query_temp("apply/extra_fle");
if( damage < 0 ) damage = 0;
// (5.5) Check if victim can absorb the damage
absorb_vic = victim->query_skill("iron-cloth") + victim->query_temp("apply/iron-cloth") * 2 ;
if( victim->query_skill("iron-cloth"))
{
absorb_skill = victim->query_skill_mapped("iron-cloth");
if( !absorb_skill ) absorb_skill = "iron-cloth";
result += SKILL_D(absorb_skill)->query_absorb_msg();
}
damage_bonus = me->query_skill("iron-cloth");
if( (damage - absorb_vic) < 0 )
{
absorb_skill = victim->query_skill_mapped("iron-cloth");
if( absorb_skill)
bounce = 0 - ((SKILL_D(absorb_skill)->bounce_ratio()) * (damage - absorb_vic) / 10);
else
bounce = 0;
absorb_skill = me ->query_skill_mapped("iron-cloth");
if( absorb_skill)
bounce -= (SKILL_D(absorb_skill)->bounce_ratio()) * damage_bonus / 10;
else
bounce -= 0;
if ( bounce < 0 ) bounce = 0;
me->receive_damage("qi", bounce, victim );
result += damage_msg(bounce, "反弹伤");
}
else
{
// (6) Inflict the damage.
//
damage = victim->receive_damage("qi", damage, me );
if( (me->is_killing(victim) || weapon)
&& random(damage) > (int)victim->query_temp("apply/armor") ) {
// We are sure that damage is greater than victim's armor here.
victim->receive_wound("qi",damage -(int)victim->query_temp("apply/armor"), me);
wounded = 1;
}
if(stringp(damtype))
result += damage_msg(damage, damtype);
else
result += damage_msg(damage, action["damage_type"]);
}
//
// (7) Give experience
if( !userp(me) || !userp(victim) ) {
if( (ap < dp)
&& (random(my["jing"]*100/my["max_jing"] + my["int"]) > 30) ) {
my["combat_exp"] += 1;
if( my["potential"] - my["learned_points"] < 10000 )
my["potential"] += 1;
me->improve_skill(attack_skill, 1);
}
if( random(your["max_qi"] + your["qi"]) < damage ) {
your["combat_exp"] += 1;
if( your["potential"] - your["learned_points"] < 10000 )
your["potential"] += 1;
}
}
}
} //protector
result = replace_string( result, "$l", limb );
if( victim->query_temp("weapon"))
result = replace_string( result, "$v", (victim->query_temp("weapon"))->name());
if( victim->query_skill_mapped("iron-cloth"))
result = replace_string( result, "$z", to_chinese(victim->query_skill_mapped("iron-cloth")));
if( objectp(weapon) )
result = replace_string( result, "$w", weapon->name() );
else if( stringp(action["weapon"]) )
result = replace_string( result, "$w", action["weapon"] );
message_combatd(result, me, victim );
if( wizardp(me) && (string)me->query("env/combat")=="verbose" )
{
if( damage > 0 )
tell_object(me, sprintf( GRN "AP:%d,DP:%d,PP:%d,伤害力:%d\n" NOR,
ap/100, dp/100, pp/100, damage));
else
tell_object(me, sprintf( GRN "AP:%d,DP:%d,PP:%d\n" NOR,
ap/100, dp/100, pp/100));
}
if( damage > 0 )
{
report_status(victim, wounded);
if( victim->is_busy() ) victim->interrupt_me(me);
if( (!me->is_killing(your["id"])) &&
(!victim->is_killing(my["id"])) &&
victim->query("qi")*2 <= victim->query("max_qi")) {
me->remove_enemy(victim);
victim->remove_enemy(me);
fight_reward(me, victim);
fight_penalty(me, victim);
message_vision( winner_msg[random(sizeof(winner_msg))], me, victim);
}
}
if( functionp(action["post_action"]) )
evaluate( action["post_action"], me, victim, weapon, damage);
}
//This is called in the attack() defined in F_ATTACK, which handles fighting
// in the heart_beat() of all livings. Be sure to optimize it carefully.
void fight(object me, object victim)
{
object ob;
string result;
if( !living(me) ) return;
// If victim is busy or unconcious, always take the chance to makeanattack.
if( victim->is_busy() || !living(victim) ) {
me->set_temp("guarding", 0);
if( !victim->is_fighting(me) ) victim->fight_ob(me);
do_attack(me, victim, me->query_temp("weapon"), TYPE_QUICK);
if( me->is_fighting(victim) && victim->is_fighting(me))
if( (!objectp(me->query_temp("weapon"))
&& sizeof(me->query_skill_prepare()) > 1)
|| ( objectp(me->query_temp("weapon"))
&&(me->query_temp("weapon"))->query("skill_type") == "sword"
&& me->query_skill("pixie-jian", 1) >= 60
&& me->query_skill_mapped("sword") == "pixie-jian") )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?