读书笔记
// This function calculates the combined skill/combat_exp power of a certain
// skill. This value is used for A/(A+B) probability use.
varargs int skill_power(object ob, string skill, int usage)
{
int status, level, power;
if( !living(ob) ) return 0;
level = ob->query_skill(skill); //取得技能有效等级
switch(usage) {
case SKILL_USAGE_ATTACK: //攻击技能
level = ob->eff_skill_level(level, SKILL_USAGE_ATTACK); //根据char的guild(种族?)属性,给技能加乘,这里好像没用到guild属性
level += ob->query_temp("apply/attack"); //调用do_attack时设定的,如:me->add_temp("apply/attack", me->query_skill("qixiu-jian",1));
//基本技能和特殊技能直接相加,并不像有效等级那样基本技能/2+特殊技能
break;
case SKILL_USAGE_DEFENSE: //防御技能
level = ob->eff_skill_level(level, SKILL_USAGE_DEFENSE);
level += ob->query_temp("apply/defense"); //除了极个别npc外,没有对这个参数设定
break;
}
if( !level ) return (int)ob->query("combat_exp") / 2;
power = (level*level*level) / 3;
if( (status = ob->query("max_sen")) > 0 ) { //技能等级power=power/最大jx*jx 所以精神一定要满,但不一定要很高
if ( power > 100000 )
power = power / status * (int)ob->query("sen");
else
power = power * (int)ob->query("sen") / status;
}
power += ob->query("combat_exp");
return power;
}
// do_attack()
//
// Perform an attack action. This function is called by fight() or as an
// interface for some special utilize in quests.
//
varargs int do_attack(object me, object victim, object weapon, int attack_type)
{
mapping my, your, action, victim_action;
string limb, *limbs, result;
string attack_skill, force_skill, martial_skill, dodge_skill, parry_skill;
mixed foo;
int ap, dp, pp;
int damage, damage_bonus, defense_factor;
int wounded = 0;
//int cost;
int mod_val;
my = me->query_entire_dbase();
your = victim->query_entire_dbase();
//
// (1) Find out what action the offenser will take.
//
action = me->query("actions"); //调用do_attack时设定的,如:me->set("actions", (: call_other, SKILL_D("qixiu-jian"), "query_action" :) );
if( !mapp(action) ) {
me->reset_action();
action = me->query("actions");
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;
}
}
result = "\n" + action["action"] + "!\n";
//
// (2) Prepare AP, DP for checking if hit.
//
if( objectp(weapon) ) { //有武器时,看武器的skill,否则skill=unarmed
if( weapon->query("use_apply_skill") )
attack_skill = weapon->query("apply/skill_type");
else
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); //计算攻击power 攻击者
if( ap < 1) ap = 1;
dp = skill_power(victim, "dodge", SKILL_USAGE_DEFENSE); //计算防御power 被攻击者
// mon 8/3/98
if(living(victim))
dodge_skill = victim->query_skill_mapped("dodge"); //取得被攻击者的enable dodge
else
dodge_skill = 0;
mod_val = 0;
if( dodge_skill ) {
victim_action = SKILL_D(dodge_skill)->query_action(); //传回动作,西游记好像没设定dodge的action,最后mod_val=0
if( victim_action && victim_action["dodge_power"] ) //只有kugu-blade有dodge_power,kugu-blade理所当然的是最好的轻功
mod_val = victim_action["dodge_power"];
}
if( victim->is_busy() ) dp /= 3; //目标在busy状态下,防御/3
if( dp < 0 ) dp = 0;
// mon 8/10/99
if( dodge_skill && action["dodge"] ) //action["dodge"]攻击者使用技能的action的随机一个的dodge
mod_val += action["dodge"];
if( dp > 1000000 ) //按照特殊技能的mod_val加乘目标防御dp
mod_val = dp / 100 * (100 + mod_val);
else
mod_val = (100 + mod_val) * dp / 100;
if( mod_val < 0 ) mod_val = 0;
//
// (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) < mod_val ) { // Does the victim dodge this hit?
if( !dodge_skill ) { //取得dodge动作的msg
dodge_skill = "dodge";
result += SKILL_D(dodge_skill)->query_dodge_msg(limb);
}
else {
if( victim_action && victim_action["dodge_action"] )
result += victim_action["dodge_action"];
else
result += SKILL_D(dodge_skill)->query_dodge_msg(limb);
}
if( dp < ap && (!userp(victim) || !userp(me)) // 被打的一方,随即加轻功
&& random(sizeof(victim->query_enemy())) < 4
&& random(your["sen"]*100/your["max_sen"] + your["int"]*your["cps"]) > 150 ) {
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) ) { //攻击者为npc的时候,攻击〉防御 并且 智商〉15 加基本攻击技能
if( random(my["int"]) > 15 ) my["combat_exp"] += 1;
me->improve_skill(attack_skill, random(my["int"]));
}
damage = RESULT_DODGE; //-1
} else {
//
// (4) Check if the victim can parry this attack.
//
if( victim->query_temp("weapon") ) { //当被攻击者拿着武器
pp = skill_power(victim, "parry", SKILL_USAGE_DEFENSE); //计算parry,
if( !weapon ) pp *= 2; //攻击者没拿武器时,pp(parry防御)*2,对方有武器时不要空手打!!!
parry_skill = victim->query_skill_mapped("parry"); //parry的enable技能
} else {
if( weapon ) pp = 0; //攻击者有武器,被攻击者没有武器时,被攻击parry防御=0
else pp = skill_power(victim, "unarmed", SKILL_USAGE_DEFENSE); //否则计算unarmed的防御
parry_skill = victim->query_skill_mapped("unarmed"); //unarmed的enable技能
}
if( victim->is_busy() ) pp /= 3; //当被攻击者busy时,pp/3
if( pp < 0 ) pp = 0;
mod_val = 0;
if( action["parry"] ) mod_val = action["parry"]; //攻击者招数里的action的parry
if( pp > 1000000 ) //给pp按照mod_val加乘
mod_val = pp / 100 * (100 + mod_val);
else
mod_val = (100 + mod_val) * pp / 100;
if(mod_val < 0) mod_val = 0;
if( random(ap + pp)< mod_val ) {
//parry_skill = victim->query_skill_mapped("parry");
if( !parry_skill ) parry_skill = "parry"; //取得parry msg
// change to SKILL_D(parry_skill) after added parry msg to those
// martial arts that can parry.
// because of number of local variable limit, here use
// dodge_skill
dodge_skill = SKILL_D(parry_skill)->query_parry_msg(weapon);
if( dodge_skill ) result += dodge_skill;
else
result += SKILL_D("parry")->query_parry_msg(weapon);
if( pp < ap && (!userp(victim) || !userp(me)) //随即加paary技能
&& random(sizeof(victim->query_enemy())) < 4
&& random(your["sen"]*100/your["max_sen"] + your["int"]*your["cps"]) > 150 ) {
your["combat_exp"] += 1;
victim->improve_skill("parry", 1);
}
damage = RESULT_PARRY; -2
} else {
//
// (5) We hit the victim and the victim failed to parry
//
damage = me->query_temp("apply/damage"); //攻击者的apply/damage
damage = (damage + random(damage)) / 2; //取damage的随机数
if( action["damage"] )
damage += action["damage"] * damage / 100; //招数的damage加乘
damage_bonus = me->query_str(); //有效体格
// Let force skill take effect.
if( my["force_factor"] && (my["force"] > my["force_factor"]) ) { //有enforce,且内力>enforce时
if( force_skill = me->query_skill_mapped("force") ) { //有特殊内功时
foo = SKILL_D(force_skill)->hit_ob(me, victim, damage_bonus, my["force_factor"]);
if( stringp(foo) ) result += foo;
else if( intp(foo) ) damage_bonus += foo;
}
}
if( action["force"] ) //技能action里有force的时候,加乘damage_bonus(只有拳法有force action)
damage_bonus += action["force"] * damage_bonus / 100;
if( martial_skill = me->query_skill_mapped(attack_skill) ) { //攻击技能的enable技能
foo = SKILL_D(martial_skill)->hit_ob(me, victim, damage_bonus);//击中的效果msg和伤害,只有baihua-zhang有msg
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 * 3 / 4;
}
if( damage_bonus > 0 ) //damage_bonus加乘到damage
damage += (damage_bonus + random(damage_bonus))/2;
if( damage < 0 ) damage = 0;
// Let combat exp take effect
defense_factor = your["combat_exp"];
while( random(defense_factor) > my["combat_exp"] ) { //如果被攻击者的wx随即值〉攻击者的wx,那么damage*2/3 进行下一次随即判断
damage -= damage / 3;
defense_factor /= 2;
}
//
// (6) Inflict the damage.
//
damage = victim->receive_damage("kee", damage, me ); //减qx
if( (me->is_killing(victim) || weapon) //攻击者killing或者有武器
&& random(damage) > (int)victim->query_temp("apply/armor") ) { //随即damage〉被攻击者防御时,减少当前气血最大值(damage-防御)
// We are sure that damage is greater than victim's armor here.
victim->receive_wound("kee",
damage - (int)victim->query_temp("apply/armor"), me);
wounded = 1;
}
result += damage_msg(damage, action["damage_type"]);
//
// (7) Give experience
//
if( !userp(me) || !userp(victim) ) { //随即奖励技能,潜能(潜能<100时)
if( (ap < dp)
&& (random(my["sen"]*100/my["max_sen"] + my["int"]*my["cps"]) > 150) ) {
my["combat_exp"] += 1;
if( my["potential"] - my["learned_points"] < 100 )
my["potential"] += 1;
me->improve_skill(attack_skill, 1);
}
if( random(your["max_kee"] + your["kee"]) < damage ) {
your["combat_exp"] += 1;
if( your["potential"] - your["learned_points"] < 100 )
your["potential"] += 1;
}
}
}
}
result = replace_string( result, "$l", limb ); //编辑msg
if( objectp(weapon) )
result = replace_string( result, "$w", weapon->name() );
else if( stringp(action["weapon"]) )
result = replace_string( result, "$w", action["weapon"] );
if( objectp(victim->query_temp("weapon")) )
result = replace_string( result, "$W",
victim->query_temp("weapon")->name() );
if ((damage != RESULT_DODGE) && (damage != RESULT_PARRY) )
message_vision(result, me, victim );
else
if ( (string)me->query("env/brief_message") != "YES"
&& (string)victim->query("env/brief_message") != "YES" )
message_vision(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,Mod:%d,伤害力:%d\n" NOR,
ap, dp, pp, mod_val, damage));
else
tell_object(me, sprintf( GRN "AP:%d,DP:%d,PP:%d,Mod:%d\n" NOR,
ap, dp, pp, mod_val));
}
if( wizardp(victim) && (string)victim->query("env/combat")=="verbose" ) {
if( damage > 0 )
tell_object(victim, sprintf( GRN "AP:%d,DP:%d,PP:%d,Mod:%d,伤害力:%d\n" NOR,
ap/100, dp/100, pp/100, mod_val/100, damage));
else
tell_object(victim, sprintf( GRN "AP:%d,DP:%d,PP:%d,Mod:%d\n" NOR,
ap/100, dp/100, pp/100, mod_val/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"])) ) {
// fight until one side's kee is < 50%
if( victim->query("kee") < victim->query("max_kee") * 50 / 100) {
me->remove_enemy(victim);
victim->remove_enemy(me);
message_vision( winner_msg[random(sizeof(winner_msg))], me, victim);
}
}
}
if( functionp(action["post_action"]) )
evaluate( action["post_action"], me, victim, weapon, damage);
if( damage > 0 && attack_type != TYPE_QUICK && //攻击成功,且不是追加攻击
me->query_temp("perf_quick") && me->is_fighting(victim) ) { //perf_quick,战斗中 但是perf_quick没被设定
if( me->query_temp("weapon") &&
me->query_temp("perf_quick/"+me->query_temp("weapon")->query("skill_type")) ) {
if( me->query_temp("perf_quick/msg") )
message_vision(CYN + me->query_temp("perf_quick/msg") +NOR, me, victim);
else
message_vision(CYN + "$N得势不饶人,对$n展开连续攻击。"+NOR, me, victim);
do_attack(me, victim, me->query_temp("weapon"), TYPE_QUICK);
return 1;
}
}
// See if the victim can make a riposte.
if( attack_type==TYPE_REGULAR //没击中时被反击
&& damage < 1
&& victim->query_temp("guarding") ) {
victim->set_temp("guarding", 0);
if( random(my["cps"]) < 5 ) {
message_vision("$N一击不中,露出了破绽!\n", me);
do_attack(victim, me, victim->query_temp("weapon"), TYPE_QUICK);
} else {
message_vision("$N见$n攻击失误,趁机发动攻击!\n", victim, me);
do_attack(victim, me, victim->query_temp("weapon"), TYPE_RIPOSTE);
}
}
}