//public static bool apply_skill_eff_to(long cur_clock_tm, IBaseUnit from, IBaseUnit target, dmg dmg, int aff, int skill_id, int percentage) //{ // tres sk_res = new tres(); // sk_res.rate = 100; // return apply_skill_eff_to(cur_clock_tm, from, target, sk_res, aff, skill_id, percentage); //} public static bool apply_skill_eff_to(long cur_clock_tm, IBaseUnit from, IBaseUnit target, tres_conf sk_res, int aff, int skill_id, int percentage) { var dflag = true; if (target.isdie() || target.isghost()) { // TO DO : 考虑有些技能能作用于尸体 if (dflag) Utility.debug(" !apply_skill_eff_to false 1"); return false; } if (target.ignore_dmg()) { if (dflag) Utility.debug(" !apply_skill_eff_to false 2"); return false; } //if ( "rate" in sk_res ) if (sk_res.rate > 0) { if (Utility.random(0, 100) > sk_res.rate) { if (dflag) Utility.debug(" !apply_skill_eff_to false 3"); return false; } } var to_pl = target.get_pack_data(); var frm_pl = from.get_pack_data(); //var rpc_data = new Variant(); //rpc_data["hited"] = 3; //rpc_data["sid"] = skill_id; //rpc_data["frm_iid"] = frm_pl.iid; //rpc_data["to_iid"] = to_pl.iid; if (target.has_state(pl_state_type.PST_SKILL_AVOID)) { // 目标技能免疫 // send single_skill_res msg to clients //rpc_data["hited"] = 0;//免疫 //target.broad_cast_zone_msg_and_self(22, rpc_data); if (dflag) Utility.debug(" !apply_skill_eff_to false 4"); return false; } //if(from.get_sprite_type() == map_sprite_type.MST_MONSTER && target.get_sprite_type() == map_sprite_type.MST_MONSTER) //{ // return false; // 一家人不打一家人 //} // TO DO : 根据aff判断敌人、盟友关系从而确定是否受此状态影响 game_err_code check_res = Utility.check_target_type(from, target, aff, target.gmap.pk_seting); if (check_res != game_err_code.RES_OK) return false; if (from.get_sprite_type() == map_sprite_type.MstPlayer) { if (target.can_atk(from)) { target.atk_by(from); } } //if(sk_res.hp_dmg != 0) //{ // rpc_data.hp_dmg <- {}; // rpc_data.hp_dmg.hp_dmg <- sk_res.hp_dmg; // to_pl.hp -= sk_res.hp_dmg; // if(to_pl.hp > to_pl.max_hp) // { // to_pl.hp = to_pl.max_hp; // } //} //if(sk_res.mp_dmg != 0) //{ // rpc_data.mp_dmg <- {}; // rpc_data.mp_dmg.mp_dmg <- sk_res.mp_dmg; // to_pl.mp -= sk_res.mp_dmg; // if(to_pl.mp > to_pl.max_mp) // { // to_pl.mp = to_pl.max_mp; // } //} Utility.debug("apply_skill_eff_to try apply_dmg_on_pl!"); //no_dmg 不计算伤害 if (sk_res.no_dmg == 0) { var ret = grid_map.apply_dmg_on_pl(target, from, sk_res.convert2damage(), cur_clock_tm, percentage, true); Utility.debug("!apply_skill_eff_to apply_dmg_on_pl:" + ret); if (ret["hited"]._int32 != 3) { // 未命中 // send single_skill_res msg to clients //rpc_data["hited"] = ret["hited"]; //target.broad_cast_zone_msg_and_self(22, rpc_data); if (dflag) Utility.debug(" !apply_skill_eff_to false 20"); return false; } } //sys.trace(sys.SLT_DETAIL, "sk_res.rmv_stat ["+sk_res.rmv_stat+"]\n"); if (sk_res.rmv_stat > 0) { int rmv_stat = sk_res.rmv_stat; if (to_pl.states != null) { //sys.dumpobj(to_pl.states); // 移除所有状态 rmv_stat_from_pl_by_gb(rmv_stat, target, to_pl); } } if (sk_res.rmv_1stat > 0) { if (to_pl.states != null) { // 移除一个状态 rmv_1stat_from_pl_by_gb(sk_res.rmv_1stat, target, to_pl); } } if (sk_res.tar_state > 0) { int tar_state = sk_res.tar_state; var add_stat = true; if (sk_res.stat_rat > 0) { // 有几率触发技能效果 var judg = Utility.random(0, 100); if (judg > sk_res.stat_rat) { //sys.trace(sys.SLT_DETAIL, "stat_rat["+sk_res.stat_rat+"] < judg["+judg+"]\n"); if (dflag) Utility.debug(" !apply_skill_eff_to false 21"); add_stat = false; } } if (add_stat) { // add state eff to character var state_obj = add_state_to_pl(cur_clock_tm, target, sk_res, from, percentage); if (state_obj != null) { // rpc_data.states < -state_obj; //rpc_data.states <- {}; //rpc_data.states.id <- state_obj.id; //rpc_data.states.par <- state_obj.par; //rpc_data.states.start_tm <-state_obj.start_tm; //rpc_data.states.end_tm <- state_obj.end_tm; } } } if (sk_res.cd_red != null) { // 减少cd //var skcds = []; foreach (var cd_red in sk_res.cd_red) { int sktp = cd_red.sktp; int cd_reduce = (cd_red.red_tm * percentage / 10); if (sktp == 0) { foreach (int sk_key in to_pl.skill_cd.Keys) { //cd -= (sk_res.cd_red.red_tm * 100 * per / 1000); to_pl.skill_cd[sk_key] -= cd_reduce; //skcds.push({ sktp = sktp, cdtm = cd - cur_clock_tm}); } } else if (to_pl.skill_cd.ContainsKey(sktp)) { to_pl.skill_cd[sktp] -= cd_reduce; //skcds.push({ sktp = cd_red.sktp, cdtm = to_pl.skill_cd[cd_red.sktp] - cur_clock_tm}); } } // if (skcds.len() > 0) // { //// send self_attchange msg //::send_rpc(to_pl.sid, 32, { skcds = skcds}); // } } if (!to_pl.cfmv) { if (sk_res.fmv != null) { var judge = Utility.random(0, 100); int fmv_rate = sk_res.fmv.rate; int fmv_dir = sk_res.fmv.dir; int fmv_rang = sk_res.fmv.rang; if (judge < fmv_rate) { var dir = fmv_dir; if (dir == 2) {//随机前后 dir = Utility.random(0, 2); } // 迫使目标移动 if (dir == 0) { // 远离自己的方向 var dist_x = to_pl.x - frm_pl.x; var dist_y = to_pl.y - frm_pl.y; if ((dist_x != 0) || (dist_y != 0)) { var vec = Utility.normalize_vec2(dist_x, dist_y); var from_x = to_pl.x; var from_y = to_pl.y; to_pl.x += (int)(vec.x * fmv_rang); to_pl.y += (int)(vec.y * fmv_rang); var dest_pos = target.gmap.valpoint_on_vector(to_pl.x, to_pl.y, from_x, from_y, vec); var to_grid_pos = target.gmap.get_grid_by_pt(dest_pos.x, dest_pos.y); //if(!to_grid_pos || (dest_pos.x < 0) || (dest_pos.y < 0)) //{ // // 目标坐标非法,出错 // Utility.trace_err("fmv frm_pl.x["+frm_pl.x+"] frm_pl.y["+frm_pl.y+"] from_x["+from_x+"] y["+from_y+"] to_pl.x["+to_pl.x+"] to_pl.y["+to_pl.y+"] dest_pos.x["+dest_pos.x+"] dest_pos.y["+dest_pos.y+"] vec:\n"); // sys.dumpobj(vec); //} to_pl.x = (int)dest_pos.x; to_pl.y = (int)dest_pos.y; //sys.trace(sys.SLT_DETAIL, "fmv to_pl.x["+to_pl.x+"] ["+to_pl.y+"]\n"); if (target.get_sprite_type() == map_sprite_type.MstPlayer && !target.is_in_lvl) { to_pl.lx = to_pl.x; to_pl.ly = to_pl.y; } } } else if (dir == 1) { // 靠近自己的方向 var dist_x = frm_pl.x - to_pl.x; var dist_y = frm_pl.y - to_pl.y; if ((dist_x != 0) || (dist_y != 0)) { var dist2 = dist_x * dist_x + dist_y * dist_y; var vec = Utility.normalize_vec2(dist_x, dist_y); if (fmv_rang == 0 || fmv_rang * fmv_rang >= dist2) { // 拉近到自己身边一格 var from_x = to_pl.x; var from_y = to_pl.y; to_pl.x = (int)(frm_pl.x - vec.x * game_const.map_grid_pixel); to_pl.y = (int)(frm_pl.y - vec.y * game_const.map_grid_pixel); var dest_pos = target.gmap.valpoint_on_vector(to_pl.x, to_pl.y, from_x, from_y, vec); to_pl.x = (int)dest_pos.x; to_pl.y = (int)dest_pos.y; if (target.get_sprite_type() == map_sprite_type.MstPlayer && !target.is_in_lvl) { to_pl.lx = to_pl.x; to_pl.ly = to_pl.y; } } else { var from_x = to_pl.x; var from_y = to_pl.y; to_pl.x += (int)(vec.x * fmv_rang); to_pl.y += (int)(vec.y * fmv_rang); var dest_pos = target.gmap.valpoint_on_vector(to_pl.x, to_pl.y, from_x, from_y, vec); to_pl.x = (int)dest_pos.x; to_pl.y = (int)dest_pos.y; if (target.get_sprite_type() == map_sprite_type.MstPlayer && !target.is_in_lvl) { to_pl.lx = to_pl.x; to_pl.ly = to_pl.y; } } } } } if (to_pl.moving != null) { // 停止移动 //var data = { tm = cur_clock_tm, iid = to_pl.iid, x = to_pl.x, y = to_pl.y, face = to_pl.face }; // send stop move msg to clients //target.gmap.broadcast_map_rpc(10, data); //target.broad_cast_zone_msg_and_self(10, data); //delete to_pl.moving; to_pl.moving = null; } to_pl.last_mvpts = null; //rpc_data.fmv < - { to_x = to_pl.x, to_y = to_pl.y, dir = sk_res.fmv.dir}; if (to_pl.casting != null) { // 停止施法 //var data = { iid = to_pl.iid }; // send cancel_casting_res to clients //target.broad_cast_zone_msg_and_self(29, data); //delete to_pl.casting; to_pl.casting = null; } } } //var gmap = target.gmap; //if(to_pl.hp <= 0) //{ // // die! // to_pl.hp = 0; // target.die(from); // rpc_data.isdie = true; //} // send single_skill_res msg to clients //gmap.broadcast_map_rpc(22, rpc_data); //target.broad_cast_zone_msg_and_self(22, rpc_data); return true; }
public static game_err_code check_target_type(IBaseUnit caster, IBaseUnit tar_sprite, int aff, map_pk_setting_type map_pk_seting) { IMapUnit pl = caster.get_pack_data(); IMapUnit tar_pl = tar_sprite.get_pack_data(); if (pl.iid != tar_pl.iid) { // 作用于其他角色 if ((aff & (int)skill_aff_type.SAT_ENERMY) != (int)skill_aff_type.SAT_ENERMY) { if (caster.can_atk(tar_sprite)) return game_err_code.SKIL_INVALIDE_TAREGET;//敌人 // 根据aff判断盟友关系从而确定是否受此状态影响 var isaily = caster.isaily(tar_sprite); if (isaily) { if ((aff & (int)skill_aff_type.SAT_ALLY) != (int)skill_aff_type.SAT_ALLY) return game_err_code.SKIL_INVALIDE_TAREGET; // 不对盟友产生影响 } else {//中立方 if ((aff & (int)skill_aff_type.SAT_MID) != (int)skill_aff_type.SAT_MID) return game_err_code.SKIL_INVALIDE_TAREGET; } } else if (caster.get_sprite_type() == map_sprite_type.MstPlayer) {// 根据地图、个人pk状态决定是否可以释放技能 if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { if (map_pk_seting == map_pk_setting_type.MPST_PEACE) return game_err_code.CANT_PK_IN_PEACE_MAP; if (pl.in_pczone || tar_pl.in_pczone) return game_err_code.CANT_PK_IN_PEACE_ZONE; if (map_pk_seting == map_pk_setting_type.MPST_NORMAL) { if (!tar_sprite.can_atk_direct()) { //不可攻击的玩家 if (!caster.can_atk(tar_sprite)) return game_err_code.CANT_ATK; } } else { //pk地图 if (!caster.can_atk(tar_sprite)) return game_err_code.CANT_ATK; } } else if (tar_sprite.get_sprite_type() == map_sprite_type.MstMonster) { if (tar_sprite.owner_ply != null) { //战宠 var owner_sprite = tar_sprite.owner_ply; var ower_pl = owner_sprite.get_pack_data(); if (ower_pl.iid == pl.iid) return game_err_code.CANT_ATTACK_SELF_PET; if (map_pk_seting == map_pk_setting_type.MPST_PEACE) return game_err_code.CANT_PK_IN_PEACE_MAP; if (pl.in_pczone || ower_pl.in_pczone) return game_err_code.CANT_PK_IN_PEACE_ZONE; if (map_pk_seting == map_pk_setting_type.MPST_NORMAL) { if (!owner_sprite.can_atk_direct()) { //不可攻击的玩家 if (!caster.can_atk(owner_sprite)) return game_err_code.CANT_ATK; } } else { //pk地图 if (!caster.can_atk(owner_sprite)) return game_err_code.CANT_ATK; } } else { if (!caster.can_atk(tar_sprite)) return game_err_code.CANT_ATK; } } } else { if (!caster.can_atk(tar_sprite)) return game_err_code.CANT_ATK; } } else { // 作用于自己 if ((aff & (int)skill_aff_type.SAT_SELF) != (int)skill_aff_type.SAT_SELF) return game_err_code.SKIL_INVALIDE_TAREGET; // 不对自己产生影响 } return game_err_code.RES_OK; }
public static int _update_pl_pt_move(IBaseUnit sprite, long cur_clock_tm) { var pl = sprite.get_pack_data(); var speed = pl.speed; // moving var tmleft = cur_clock_tm - pl.moving.start_tm; if (tmleft <= 0) { return 0; } var move_distance = (tmleft * speed) / 1000.0; for (; move_distance > 0 && pl.moving.pts.Count > 0;) { var pt = pl.moving.pts.pop(); var to_x = pt.x * game_const.map_grid_pixel + 16; var to_y = pt.y * game_const.map_grid_pixel + 16; //Utility.trace_err("pt.x: [" + pt.x + "] pt.y["+pt.y+"] to_x["+to_x+"] to_y["+to_y+"]\n"); if (to_x == pl.x && to_y == pl.y) { continue; } var x_dis = to_x - pl.x; var y_dis = to_y - pl.y; var distance = Math.Sqrt((x_dis) * (x_dis) + (y_dis) * (y_dis)); if (distance > move_distance) { pl.moving.float_x += (x_dis) / distance * move_distance; pl.moving.float_y += (y_dis) / distance * move_distance; pl.x = (int)(pl.moving.float_x); pl.y = (int)(pl.moving.float_y); //pl.x += ((to_x - pl.x)/distance * move_distance); //pl.y += ((to_y - pl.y)/distance * move_distance); //pl.x += (to_x - pl.x)/distance * move_distance; //pl.y += (to_y - pl.y)/distance * move_distance; move_distance = 0; pl.moving.pts.push(pt); if (sprite.get_sprite_type() == map_sprite_type.MstPlayer && !sprite.is_in_lvl) { pl.lx = pl.x; pl.ly = pl.y; } //Utility.trace_err("moving x: [" + pl.x +"] y:[" + pl.y + "] float_x["+pl.moving.float_x+"] float_y["+pl.moving.float_y+"] \n"); } else { move_distance -= distance; pl.x = (int)to_x; pl.y = (int)to_y; pl.moving.float_x = (to_x); pl.moving.float_y = (to_y); if (sprite.get_sprite_type() == map_sprite_type.MstPlayer) { if (!sprite.is_in_lvl) { pl.lx = pl.x; pl.ly = pl.y; } if (pl.moving.ppts == null) pl.moving.ppts = new List<Point2D>(); pl.moving.ppts.push(pt); // 记录历史经过的节点 } //Utility.trace_err("Rich x: [" + pl.x +"] y:[" + pl.y + "] float_x["+pl.moving.float_x+"] float_y["+pl.moving.float_y+"] \n"); } } sprite.on_pos_change(pl.x, pl.y); if (pl.moving.pts.Count <= 0) { if (pl.moving.ppts != null) pl.last_mvpts = pl.moving.ppts; pl.moving = null; //Utility.trace_err("Stop at x: [" + pl.x +"] y:[" + pl.y + "] \n"); return (int)(move_distance * 1000 / pl.speed); // 停止后剩余时间 } else { pl.moving.start_tm = cur_clock_tm; } return 0; }
// { // level = 1, // atktp = atk_type.ATKTP_ATK, // atk_min = 100, // atk_max = 100, // matk_min = 100, // matk_max = 100, // atk_rate = 1000, // 命中率 // miss_rate = 0, // 闪避 // pkatkrate = 100, // pkmisrate = 100, // criatk = 0, // criatk_debuffs = 0, //暴击抵抗,相对 criatk 的抵抗 ,千分比, 算法:受到暴击击的概率降低xx // cridmg = 0, // exatk = 0, // exatk_debuffs = 0, // 卓越一击率抵抗, 相对 exatk 的抵抗 ,千分比, 算法:受到卓越一击的概率降低xx // exdmg = 0, // dobrate = 0, // igdef_rate = 0, // igdef_rate_debuffs = 0, // 抵抗无视防御几率 // def_red = 0, // dmg_red = 0, // atk_dmg_mul = 0, // igdmg_red = 0, // 无视伤害减免几率,千分比 // igatk_dmg_mul = 0,// 无视伤害增益几率,千分比 // hpsuck = 0, // 每次攻击吸收生命值 // hpsuck_dmgmul = 0, // 每次攻击吸收生命值增加伤害比例 // addResist = [0,0,0,0,0,0,0], // 属性攻击 // clansred = 0, // iid = 0, //}; // damage { noratk: } ?? public static Variant apply_dmg_on_pl_ex(IBaseUnit tar_sprite, IBaseUnit frm_sprite, damage damage, long cur_clock_tm, int per, bool wpnatk = false, bool direct_dmg = false) { // TO DO : 优化: per = 1000时不需要计算增益 //direct_dmg 默认伤害....? 技能伤害, 追击伤害, 有miss几率 //wpnatk 是否默认攻击 //::g_dump( "apply_dmg [ damage ] ===>>>> ", damage ) ; //::g_dump( "apply_dmg [ flags ] ===>>>> ", { wpnatk = wpnatk, direct_dmg = direct_dmg } ) ; if (frm_sprite != null) { frm_sprite.on_hurt(tar_sprite); } tar_sprite.on_be_hurt(frm_sprite); var tar_pl = tar_sprite.get_pack_data(); // 取不到状态添加对象情况下,本函数frm_sprite可能为空,则需要默认的计算参数 var pl = default(IMapUnit);// g_dmg_calc_def_pl; if (frm_sprite != null) { pl = frm_sprite.get_pack_data(); pl.last_atk_tm = cur_clock_tm; // 触发普通攻击cd } var ret = new Variant(); ret["hited"] = 3; ret["criatk"] = 0; ret["dmg"] = 0; ret["dobdmg"] = false; ret["isdie"] = false; ret["frm_iid"] = pl.iid; ret["to_iid"] = tar_pl.iid; // 计算玩家 VS NPC 等级调整伤害 //var dmg_per_add = 0; var is_pvp = true; if (frm_sprite != null) { if (frm_sprite.get_sprite_type() == map_sprite_type.MstMonster) { is_pvp = false; } } if (tar_sprite.get_sprite_type() == map_sprite_type.MstMonster) { is_pvp = false; } // miss check var bAllMiss = false; if (direct_dmg) { if (is_pvp) { // pvp var atk_rate = 100 * (pl.pkatkrate / (pl.pkatkrate + tar_pl.pkmisrate)/* * (pl.level/(pl.level + tar_pl.level))*/); var lvl_dist = tar_pl.level - pl.level; if (lvl_dist >= 300) { atk_rate -= 15; } else if (lvl_dist >= 200) { atk_rate -= 10; } else if (lvl_dist >= 100) { atk_rate -= 5; } var judg = Utility.random(0, 100); if (judg > atk_rate) { // miss ret["hited"] = 1; return ret; } } else { // pve var atk_rate = 100.0 * (pl.atk_rate - tar_pl.miss_rate) / pl.atk_rate; if (atk_rate < 5) { if (atk_rate < 0) { bAllMiss = true; } atk_rate = 5; } var judg = Utility.random(0, 100); if (judg > atk_rate) { // miss ret["hited"] = 1; return ret; } } } double targetDef = tar_pl.def; if (is_pvp) targetDef += tar_pl.pkdef; targetDef = (targetDef - targetDef * (pl.def_red / 1000.0)); var igdef_rate = pl.igdef_rate - tar_pl.igdef_rate_debuffs; if (igdef_rate > 0) { var judg = Utility.random(0, 1000); if (judg < igdef_rate) { targetDef = 0; ret["criatk"] = 1; // 无视防御 } } //Utility.trace_info("apply_dmg_on_pl frm_sprite:["+frm_sprite+"] per["+per+"]\n"); //sys.dumpobj(pl); //var combat_conf = get_general_combat_conf(); double total_dmg = 0; // TO DO : 计算伤害 damage 是否是物理伤害 if (pl.atktp == atk_type.ATKTP_MATK && !wpnatk && (damage.plyatk != 1)) { //pl.atktp == atk_type.ATKTP_MATK 是 魔攻攻击分类角色 // !wpnatk 不是默认攻击 // (!("plyatk" in damage) || damage.plyatk!=1) 不是物理攻击 // 根据魔法攻击计算伤害 int dmg_min = damage.dmg_min + pl.matk_min * damage.noratk; int dmg_max = damage.dmg_max + pl.matk_max * damage.noratk; if (is_pvp && pl.pkmatk != 0) {//pvp魔法攻击增加 dmg_min += pl.pkmatk; dmg_max += pl.pkmatk; } if (damage.attr >= 0) {// 属性攻击 dmg_min += pl.addResist[damage.attr]; dmg_max += pl.addResist[damage.attr]; } // TO DO : 根据装备武器不同来计算伤害 //if(direct_dmg && frm_sprite) //{ // //frm_sprite.get_equip_by_pos(6); // 获取装备的武器 //} double dmg = 0; var dmg_calced = false; if (damage.noratk > 0 && (pl.criatk - pl.criatk_debuffs > 0 || pl.exatk - pl.exatk_debuffs > 0)) { var judg = Utility.random(0, 1000); if (judg < pl.exatk - pl.exatk_debuffs) {//卓越一击几率 dmg = dmg_max - targetDef; dmg += dmg_max * (0.2 + pl.exper_add / 1000.0); dmg += pl.exdmg; ret["criatk"] = 2; // 卓越一击 dmg_calced = true; } else { judg = Utility.random(0, 1000); if (judg < pl.criatk - pl.criatk_debuffs) {// 会心一击几率 dmg = dmg_max - targetDef; dmg += pl.cridmg; ret["criatk"] = 3; // 会心一击 dmg_calced = true; } } } if (!dmg_calced) { dmg = Utility.random(dmg_min, dmg_max + 1); //if(is_pvp) //{ // dmg = dmg - (targetDef*tar_sprite.game_conf.pvp_def_per/100.0); //} //else //{ // dmg = dmg - targetDef; //} } if (frm_sprite != null && frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { //// 技能攻击,技能额外加成 //int dmg_mul = damage["noratk"]; //var baseatt_conf = frm_sprite.carr_gen_conf.baseatt[0]; //if( ("inte2atk" in baseatt_conf) && baseatt_conf.inte2atk != 0 ) //{ // dmg_mul += pl.inte/(pl.inte+baseatt_conf.inte2atk); //} ////sys.trace( sys.SLT_DETAIL, "atk_type.ATKTP_MATK dmg_mul=" + dmg_mul + " baseatt_conf.inte2atk =" + baseatt_conf.inte2atk + "\n") //dmg = dmg * dmg_mul; } if (dmg <= 0) { dmg = 1; } total_dmg += dmg; } else { // 根据攻击力计算伤害 var skil_dmg_min = damage.dmg_min + pl.atk_min; var skil_dmg_max = damage.dmg_max + pl.atk_max; if (is_pvp && pl.pkatk != 0) { skil_dmg_min += pl.pkatk; skil_dmg_max += pl.pkatk; } if (damage.attr >= 0) { skil_dmg_min += pl.addResist[damage.attr]; skil_dmg_max += pl.addResist[damage.attr]; } double dmg = 0; var dmg_calced = false; if (damage.noratk > 0 && (pl.criatk - pl.criatk_debuffs > 0 || pl.exatk - pl.exatk_debuffs > 0)) { var judg = Utility.random(0, 1000); if (judg < pl.exatk - pl.exatk_debuffs) { dmg = skil_dmg_max; dmg += skil_dmg_max * (0.2 + pl.exper_add / 1000.0); dmg += pl.cridmg; dmg += pl.exdmg; ret["criatk"] = 2; // 卓越一击 dmg_calced = true; } else { judg = Utility.random(0, 1000); if (judg < pl.criatk - pl.criatk_debuffs) { dmg = skil_dmg_max; dmg += pl.cridmg; ret["criatk"] = 3; // 会心一击 dmg_calced = true; } } } if (!dmg_calced) { dmg = Utility.random(skil_dmg_min, skil_dmg_max + 1); } //if(is_pvp) //{ // dmg = dmg - (targetDef*tar_sprite.game_conf.pvp_def_per/100.0); //} //else //{ // dmg = dmg - targetDef; //} if (!wpnatk && frm_sprite != null && frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { // 物理技能攻击,技能额外加成 var dmg_mul = damage.noratk; //var baseatt_conf = frm_sprite.carr_gen_conf.baseatt[0]; //if( ("inte2atk" in baseatt_conf) && baseatt_conf.inte2atk != 0 ) //{ // dmg_mul += pl.inte/(pl.inte+baseatt_conf.inte2atk); //} //sys.trace( sys.SLT_DETAIL, "atk_type.ATKTP_ATK dmg_mul=" + dmg_mul + "\n") dmg = dmg * dmg_mul; } if (dmg <= 0) { dmg = 1; } total_dmg += dmg; } if (bAllMiss) {//pve中 攻击者攻击几率 小于 被攻击者 miss几率时,攻击减益到30% total_dmg = (total_dmg * 30) / 100; } if (tar_pl.dmg_red != 1) {//伤害减免 if (pl.igdmg_red <= 0) { //无视伤害减免几率 total_dmg = (total_dmg * tar_pl.dmg_red); } else { var judg = Utility.random(0, 1000); if (judg >= pl.igdmg_red) { total_dmg = (total_dmg * tar_pl.dmg_red); } } } if (is_pvp && tar_pl.pkdmg_red != 1) { //pvp 伤害减免 total_dmg = (total_dmg * tar_pl.pkdmg_red); } var tlevel = pl.level / 10; if (total_dmg >= 0 && total_dmg < tlevel) { if (tlevel < 1) { tlevel = 1; } total_dmg = tlevel; } // TO DO : sprite damage, 小精灵伤害 if (direct_dmg) { // 计算生命损耗伤害加成 if (frm_sprite != null && pl.hpsuck > 0) { // 损耗自己生命 if (pl.hp > pl.hpsuck) { pl.hp -= pl.hpsuck; if (pl.hp < 0) pl.hp = 0; // broadcast hpchange msg //frm_sprite.broad_cast_zone_msg_and_self(26, {iid=pl.iid, hpchange={hpadd=-pl.hpsuck, die=(pl.hp <= 0), frm_iid=pl.iid}}); //if(pl.cid >0) //{ // var tid = team.get_ply_teamid(pl.cid); // if(tid > 0) // { // // 在队伍中,发送队友属性变化消息 // team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp}, pl.sid); // } //} if (pl.hpsuck_dmgmul > 0) { // 增加攻击伤害 total_dmg = total_dmg * ((1000.0 + pl.hpsuck_dmgmul) / 1000.0); } } } var atk_dmg_mul = pl.atk_dmg_mul; if (pl.igatk_dmg_mul > 0) { //无视伤害增益几率 var judg = Utility.random(0, 1000); if (judg < pl.igatk_dmg_mul) { atk_dmg_mul = 0; } } if (is_pvp) { total_dmg += (total_dmg * ((atk_dmg_mul + pl.pkatk_dmg_mul) / 1000.0)); } else { total_dmg += (total_dmg * (atk_dmg_mul / 1000.0)); } //// 计算技能伤害的属性加成值 //if(damage.ContainsKey("attdmg_mul")) //{ // foreach(var attdmg in damage["attdmg_mul"]) // { // var val = 0; // if(attdmg.name in pl) // { // val = pl[attdmg.name]; // } // total_dmg *= ((attdmg.base + val * attdmg.val ) / attdmg.basediv); // } //} //if("attdmg_add" in damage) //{ // foreach(attdmg in damage.attdmg_add) // { // var val = 0; // if(attdmg.name in pl) // { // val = pl[attdmg.name]; // } // total_dmg += ((attdmg.base + val * attdmg.val ) / attdmg.basediv); // } //} //if((tar_sprite.get_sprite_type()==map_sprite_type.MstMonster) && tar_pl.clanatt_eff) //{ // // 需要计算副本中帮派科技伤害减免 // var clanper = 1000 - tar_pl.clanred + pl.clansred; // //Utility.trace_info("calc clanatt total_dmg["+total_dmg+"] clanper["+clanper+"] pl.clansred["+pl.clansred+"] tar_pl.clanred["+tar_pl.clanred+"]\n"); // total_dmg = (total_dmg * ((clanper)/1000.0)); // //Utility.trace_info("calc clanatt total_dmg["+total_dmg+"]\n"); //} // TO DO : 吸蓝 mpsteal } total_dmg += damage.hp_dmg; total_dmg = (total_dmg * (per / 1000.0)); //sys.dumpobj(damage); //Utility.trace_info("total_dmg:["+total_dmg+"]\n"); if (total_dmg.CompareTo(0) > 0) { var real_atk_dmg = total_dmg; if (total_dmg > 0) { if (frm_sprite != null) { tar_sprite.onhate(frm_sprite, total_dmg); tar_sprite.ondmg(frm_sprite, total_dmg); if (frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { if (frm_sprite.gmap.blvlmap) { frm_sprite.gmap.worldsvr.on_dmg(frm_sprite, tar_sprite, total_dmg); } } if (direct_dmg) { frm_sprite.calc_weapon_dura(total_dmg); // 计算装备耐久损耗 frm_sprite.on_make_direct_dmg(); } } if (direct_dmg) { tar_sprite.calc_eqp_dura(total_dmg); // 计算装备耐久损耗 // 计算双倍伤害 if (pl.dobrate > 0) { var judg = Utility.random(0, 1000); if (judg < pl.dobrate) { total_dmg += total_dmg; ret["dobdmg"] = true; } } } // 吸收伤害 total_dmg = pl_absorb_dmg(tar_sprite, tar_pl, total_dmg); // 魔法抵扣生命 total_dmg = pl_hpdmg_2_mpdmg(tar_sprite, tar_pl, total_dmg); // 伤害链接 pl_dmg_link(tar_sprite, tar_pl, total_dmg); } if (is_pvp && total_dmg > 0) { var pkignore_dp = false;//无视dp var pkigdp_rate = pl.pkigdp_rate - tar_pl.pkigdp_rate_debuffs; if (pkigdp_rate > 0) { var judg = Utility.random(0, 1000); pkignore_dp = judg < pkigdp_rate; } if (!pkignore_dp) { if (tar_pl.dp < total_dmg) { var dp_dmg = tar_pl.dp; tar_pl.dp = 0; //剩余值 10倍作用于hp total_dmg = ((total_dmg - dp_dmg));//*tar_sprite.game_conf.ply_hp_dmg_factor); tar_pl.hp -= (int)total_dmg; if (tar_pl.hp < 0) tar_pl.hp = 0; ret["dp_dmg"] = dp_dmg; } else { tar_pl.dp -= (int)total_dmg; if (tar_pl.dp > tar_pl.max_dp) tar_pl.dp = tar_pl.max_dp; ret["dp_dmg"] = total_dmg; total_dmg = 0; } } else { //剩余值 10倍作用于hp total_dmg = (total_dmg * 10);//tar_sprite.game_conf.ply_hp_dmg_factor); tar_pl.hp -= (int)total_dmg; if (tar_pl.hp < 0) tar_pl.hp = 0; } //sys.trace( sys.SLT_DETAIL, "tar_pl.cid =" + tar_pl.cid + " tar_pl.dp = " + tar_pl.dp + " tar_pl.hp = " + tar_pl.hp + "\n"); } else { tar_pl.hp -= (int)total_dmg; if (tar_pl.hp < 0) tar_pl.hp = 0; if (tar_pl.hp > tar_pl.max_hp) tar_pl.hp = tar_pl.max_hp; } // broadcast hpchange msg //tar_sprite.broad_cast_zone_msg_and_self(26, {iid=tar_pl.iid, hpchange={hpadd=-total_dmg, die=(tar_pl.hp <= 0), frm_iid=pl.iid}}); ret["isdie"] = (tar_pl.hp <= 0); ret["dmg"] = total_dmg; //if(tar_pl.cid >0) //{ // var tid = team.get_ply_teamid(tar_pl.cid); // if(tid > 0) // { // // 在队伍中,发送队友属性变化消息 // if( is_pvp ) // { // team_bcast_rpc_except(tid, 138, {cid=tar_pl.cid, hp=tar_pl.hp, dp=tar_pl.dp}, tar_pl.sid); // } // else // { // team_bcast_rpc_except(tid, 138, {cid=tar_pl.cid, hp=tar_pl.hp}, tar_pl.sid); // } // } //} if (tar_pl.hp <= 0) { // die! tar_sprite.die(frm_sprite); } //目标死亡,本次伤害不反弹 if (frm_sprite != null && real_atk_dmg > 0 && tar_pl.iid != pl.iid && tar_pl.hp > 0) { // 反弹伤害 double dmg = 0; if (tar_pl.rev_dmg_mul > 0) { dmg = (real_atk_dmg * ((tar_pl.rev_dmg_mul) / 1000.0)); if (dmg <= 0) dmg = 1; } if (tar_pl.rev_atk > 0) { var judg = Utility.random(0, 1000); if (judg < tar_pl.rev_atk) { dmg += real_atk_dmg; } } //if(is_pvp) //{ // dmg = (dmg * combat_conf.pk_dmg_per/100); //} if (dmg > 0) { // 吸收伤害 dmg = pl_absorb_dmg(frm_sprite, pl, dmg); // 魔法抵扣生命 dmg = pl_hpdmg_2_mpdmg(frm_sprite, pl, dmg); frm_sprite.onhate(tar_sprite, dmg); frm_sprite.ondmg(tar_sprite, dmg); //var frm_hpchange = {frm_iid=tar_pl.iid} if (is_pvp) { //sys.trace( sys.SLT_DETAIL, "pl.dp =" + pl.dp + "pl.hp = "+ pl.hp + "\n"); if (pl.dp < dmg) { var dp_dmg = pl.dp; pl.dp = 0; //剩余值 10倍作用于hp dmg = ((dmg - dp_dmg));//*tar_sprite.game_conf.ply_hp_dmg_factor); pl.hp -= (int)dmg; if (pl.hp < 0) pl.hp = 0; //frm_hpchange.dpadd <- -dp_dmg; //frm_hpchange.hpadd <- -dmg; //frm_hpchange.die <- pl.hp <= 0; } else { pl.dp -= (int)dmg; //frm_hpchange.dpadd <- -dmg; } //sys.dumpobj( frm_hpchange ); } else { pl.hp -= (int)dmg; if (pl.hp < 0) pl.hp = 0; //frm_hpchange.hpadd <- -dmg; //frm_hpchange.die <- pl.hp <= 0; } // broadcast hpchange msg //frm_sprite.broad_cast_zone_msg_and_self(26, {iid=pl.iid, hpchange=frm_hpchange}); //if(pl.cid > 0) ////if("cid" in pl) //{ // var tid = team.get_ply_teamid(pl.cid); // if(tid > 0) // { // // 在队伍中,发送队友属性变化消息 // if ( is_pvp ) // { // team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp, dp=pl.dp}, pl.sid); // } // else // { // team_bcast_rpc_except(tid, 138, {cid=pl.cid, hp=pl.hp}, pl.sid); // } // } //} if (pl.hp <= 0) { // 被弹死了 frm_sprite.die(tar_sprite); } } } } // 魔法值、怒气值调整 var mpchanged = false; //var mpchange_rpc = {}; if (damage.mp_dmg != 0) { var mpdmg = (damage.mp_dmg * per / 1000); tar_pl.mp -= mpdmg; if (tar_pl.mp < 0) tar_pl.mp = 0; if (tar_pl.mp > tar_pl.max_mp) tar_pl.mp = tar_pl.max_mp; //mpchange_rpc.mpadd <- -mpdmg; mpchanged = true; if (frm_sprite != null) { tar_sprite.onhate(frm_sprite, mpdmg); } } if (mpchanged && tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { // send mpchange msg //::send_rpc(tar_pl.sid, 32, mpchange_rpc); } return ret; }
public void die(IBaseUnit killer) { if (this.dying) { return; } this.dying = true; long cur_clock_tm = DateTime.Now.ToBinary(); // 尝试触发死亡ai动作 this._trig_dying_act(cur_clock_tm); // TO DO : player die // 中断打坐 //this.try_stop_recover(); this.respawn_tm = cur_clock_tm + 30000; // 30 秒后安全复活 this.pinfo.isdie = true; pinfo.atking = null; pinfo.moving = null; if (pinfo.states != null) { bool _remark_pl_state = false; if (this.pinfo.states.state_par.Count > 0) { for (var idx = 0; idx < this.pinfo.states.state_par.Count; ++idx) { var val = this.pinfo.states.state_par[idx]; if (val.desc.die_keep == 1) continue; this.pinfo.states.state_par.RemoveAt(idx); --idx; _remark_pl_state = true; } } //pinfo.states.state = 0; //pinfo.states.mov_spd_mul = 1.0; //pinfo.states.atk_spd_mul = 1.0; //pinfo.states.mp2hp = 0; //pinfo.states.dmglnkper = 0; //re_calc_cha_data(); if (_remark_pl_state) Skill._remark_pl_state(this, pinfo); } if (pinfo.jumping != null) { // 跳跃中死亡,落在目标点 pinfo.x = pinfo.jumping.dest_x; pinfo.y = pinfo.jumping.dest_y; if (!this.is_in_lvl) { pinfo.lx = pinfo.x; pinfo.ly = pinfo.y; } pinfo.jumping = null; } if (gmap != null) { if (gmap.blvlmap) { //if (this.gmap.worldsvr.is_lvlmis_lvl()) //{ // this.allow_respawn_tm = sys.clock_time() + 6000; // 侠客行副本中,必须6秒后复活 //} this.gmap.worldsvr.on_ply_die(this); } else { if (gmap.pk_seting != map_pk_setting_type.MPST_PK) {//经验惩罚 } } if (killer != null && killer.get_sprite_type() == map_sprite_type.MstMonster) { if (killer.owner_ply != null) { killer = killer.owner_ply; // 宠物击杀相当于玩家角色击杀 } } if (killer != null && killer.get_sprite_type() == map_sprite_type.MstPlayer) { IMapUnit killer_pl = killer.get_pack_data(); //local pkdp = true; if (!gmap.blvlmap) { // 添加仇敌 //_add_foes(this, killer.pinfo); //计算pk值 //是否为中立地图 if (gmap.pk_seting == map_pk_setting_type.MPST_NORMAL) { if (!this.can_atk_direct()) { //自己为正义玩家 //sys.dumpobj( defend_tm_map ); //sys.trace( sys.SLT_ERR, "killer.pinfo.cid = " + killer.pinfo.cid + "sys.time()" + sys.time() + "\n") int killer_cid = killer_pl.cid; long defend_en_tm = 0; long now_s = DateTime.Now.ToBinary(); defend_tm_map.TryGetValue(killer_cid, out defend_en_tm); if (defend_en_tm > 0) { //自己是正当防卫 则 if (defend_en_tm >= now_s) { //增加对方pk值 int add_val = 1; int pkv = killer_pl.pk_v; if (pkv < 0) {//击杀者 有正义值 则清除 add_val = 1 - pkv; } killer.add_pk_v(add_val); } else { defend_tm_map.Remove(killer_cid); } } } else {//可直接攻击的玩家 if (killer.is_justice()) {//击杀者 为正义玩家 降低PK值 killer.sub_pk_v(1, true); } } } this.check_tsk_attribute(true); } else { // 在副本中 // 增加击杀值 killer_pl.kp++; killer_pl.cur_kp++; this.gmap.worldsvr.on_kp(killer, this); } } // remove atking from atker // TO DO : 增加被锁定列表,死亡后清理被锁定列表中的对象的攻击信息即可 foreach (var val in gmap.map_sprites.Values) { val.on_spr_die(pinfo.iid); } } // 清理助攻列表 if (this.kp_asist_rec) { this.beatk_ply_cids.Clear(); } }
public bool isaily(IBaseUnit spr) { if (spr.get_sprite_type() == map_sprite_type.MstMonster && spr.owner_ply != null) spr = spr.owner_ply; // 用主人代替宠物检查敌我关系 IMapUnit pl = spr.get_pack_data(); if (pl.iid == this.pinfo.iid) return true; if (pl.lvlsideid != 0 && pinfo.lvlsideid == pl.lvlsideid) return true; if (pl.teamid == 0 || pinfo.teamid == 0) return false; if (pl.teamid == pinfo.teamid) return true; if (pl.clanid == 0 || pinfo.clanid == 0) return false; if (pl.clanid == pinfo.clanid) return true; return false; }
public void update_skill_holding(IBaseUnit caster, IMapUnit pl, long cur_clock_tm) { if (pl.holding == null) return; var holding = pl.holding; if (cur_clock_tm > 0 && cur_clock_tm < holding.end_tm) { return; } var senderr = caster.get_sprite_type() == map_sprite_type.MstPlayer; switch (holding.tar_tp) { case (int)skill_type.ST_SELF: this.do_cast_self_skill(caster, holding.rpc, false, senderr); break; case (int)skill_type.ST_TARGET: this.do_cast_target_skill(caster, holding.rpc, false, senderr); break; case (int)skill_type.ST_GROUND: this.do_cast_ground_skill(caster, holding.rpc, false, senderr); break; } }
public bool isaily(IBaseUnit spr) { if (null != this.owner_ply) return this.owner_ply.isaily(spr); if (spr.get_sprite_type() == map_sprite_type.MstMonster && null != spr.owner_ply) { spr = spr.owner_ply; } IMapUnit pl = spr.get_pack_data(); if (pl.lvlsideid > 0) { return pl.lvlsideid == this.mondata.lvlsideid; } if (spr.get_sprite_type() == map_sprite_type.MstMonster) return true; return false; }
public bool do_cast_target_skill(IBaseUnit caster, Variant rpc, bool precast = true, bool senderr = true) { var tar_iid = rpc["to_iid"]._int32; IBaseUnit tar_sprite = this.get_sprite_by_iid(tar_iid); if (tar_sprite == null) return false; if (!this.has_sprite_by_iid(caster.iid)) return false; if (tar_sprite.has_state(pl_state_type.PST_SKILL_AVOID)) { if (senderr) { //::send_rpc(caster.pinfo.sid, 27, { res = game_err_code.SKIL_TARGET_AVOID}); } return false; } if (tar_sprite.isdie() || tar_sprite.isghost()) { if (senderr) { //::send_rpc(caster.pinfo.sid, 27, { res = game_err_code.SKIL_CANT_APPLY_TO_DEADMEN}); } return false; } long cur_clock_tm = DateTime.Now.ToBinary(); var cast_skill_res = _cast_skill(cur_clock_tm, rpc, skill_type.ST_TARGET, caster, tar_sprite.get_pack_data(), tar_sprite, precast); if (cast_skill_res == null) return false; if (cast_skill_res.res != game_err_code.RES_OK) { if (senderr) { //::send_rpc(caster.pinfo.sid, 27, cast_skill_res); } //Utility.trace_err("persist_game cast skill cast_skill_res.res = [" + cast_skill_res.res + "]\n"); return false; } else if (cast_skill_res.rpc_data == null) { return true; } // TO DO : rang check & trace cast_skill_res.rpc_data["to_iid"] = tar_iid; // send cast target skill msg //caster.gmap.broadcast_map_rpc(13, cast_skill_res.rpc_data); //caster.broad_cast_zone_msg_and_self(13, cast_skill_res.rpc_data); skill_lv_conf skill_lvl_data = cast_skill_res.skill_level_conf; if (skill_lvl_data.sres != null) { Skill.apply_skill_eff_to(cur_clock_tm, caster, caster, skill_lvl_data.sres, (int)skill_aff_type.SAT_SELF, rpc["sid"]._int32, cast_skill_res.percent); } _post_cast_skill(cur_clock_tm, caster, rpc, cast_skill_res, tar_sprite, tar_sprite.get_pack_data()); //if("tres" in cast_skill_res.skill_lvl_data) //{ // if("trang" in cast_skill_res.skill_lvl_data) // { // foreach(tres in cast_skill_res.skill_lvl_data.tres) // { // apply_rang_eff(cur_clock_tm, caster, this.map_sprites[tar_iid].get_pack_data(), tres, tres.aff, cast_skill_res.skill_lvl_data.trang, rpc.sid, cast_skill_res.percent); // } // } // else // { // foreach(tres in cast_skill_res.skill_lvl_data.tres) // { // apply_skill_eff_to(cur_clock_tm, caster, this.map_sprites[tar_iid], tres, tres.aff, rpc.sid, cast_skill_res.percent); // } // } //} if (caster.get_sprite_type() == map_sprite_type.MstPlayer) { if (!tar_sprite.isdie() && !tar_sprite.isghost()) { if ((cast_skill_res.skill_data.aff & (int)skill_aff_type.SAT_ENERMY) > 0) { foreach (var petmon in caster.petmon_insts) { var petmondata = petmon.get_pack_data(); if (petmondata.atking == null) { petmondata.atking = new atking() { start_tm = cur_clock_tm, tar_iid = tar_iid, trace_tm_left = 0 }; } else if (petmondata.atking.tar_iid != tar_iid) { petmondata.atking.tar_iid = tar_iid; } } } } } return true; }
public bool do_cast_ground_skill(IBaseUnit caster, Variant rpc, bool precast = true, bool senderr = true) { Point2D center = null; IBaseUnit tar_sprite = null; IMapUnit cast_pl = caster.get_pack_data(); if (this.map_sprites.ContainsKey(cast_pl.iid)) return false; if (rpc.ContainsKey("to_iid")) { var tar_iid = rpc["to_iid"]._int32; tar_sprite = this.get_sprite_by_iid(tar_iid); if (tar_sprite == null) return false; if (tar_sprite.has_state(pl_state_type.PST_SKILL_AVOID)) return false; if (tar_sprite.isdie() || tar_sprite.isghost()) return false; var tar_pl = tar_sprite.get_pack_data(); center = new Point2D(tar_pl.x, tar_pl.y); if (tar_pl.x == cast_pl.x && tar_pl.y == cast_pl.y) { double angle = rpc["angle"]._double; var radian = angle / 180.0 * Math.PI; center.x += 32 * Math.Cos(radian); center.y += 32 * Math.Sin(radian); } } else if (rpc.ContainsKey("x")) { int x = rpc["x"]._int32; int y = rpc["y"]._int32; if (x < 0 || y < 0 || x >= this.width || y >= this.height) return false; center = new Point2D(x * game_const.map_grid_pixel + 16, y * game_const.map_grid_pixel + 16); } else { return false; } var cur_clock_tm = DateTime.Now.ToBinary(); var cast_skill_res = _cast_skill(cur_clock_tm, rpc, skill_type.ST_GROUND, caster, center, tar_sprite, precast); if (cast_skill_res == null) return false; if (cast_skill_res.res != game_err_code.RES_OK) return false; else if (cast_skill_res.rpc_data == null) return true; if (cast_skill_res.skill_level_conf.sres != null) Skill.apply_skill_eff_to(cur_clock_tm, caster, caster, cast_skill_res.skill_level_conf.sres, (int)skill_aff_type.SAT_SELF, rpc["sid"]._int32, cast_skill_res.percent); _post_cast_skill(cur_clock_tm, caster, rpc, cast_skill_res, tar_sprite, center); //if("tres" in cast_skill_res.skill_lvl_data && "trang" in cast_skill_res.skill_lvl_data) //{ // var center = {x=rpc.x*game_const.map_grid_pixel+16, y=rpc.y*game_const.map_grid_pixel+16}; // foreach(tres in cast_skill_res.skill_lvl_data.tres) // { // apply_rang_eff(cur_clock_tm, caster, center, tres, tres.aff, cast_skill_res.skill_lvl_data.trang, rpc.sid, cast_skill_res.percent); // } //} if (tar_sprite != null) { int tar_iid = tar_sprite.get_pack_data().iid; if (caster.get_sprite_type() == map_sprite_type.MstPlayer) { if (!tar_sprite.isdie() && !tar_sprite.isghost()) { foreach (var petmon in caster.petmon_insts) { var petmondata = petmon.get_pack_data(); if (petmondata.atking == null) { petmondata.atking = new atking() { start_tm = cur_clock_tm, tar_iid = tar_iid, trace_tm_left = 0 }; } else if (petmondata.atking.tar_iid != tar_iid) { petmondata.atking.tar_iid = tar_iid; } } } } } return true; }
public cast_skill_res _cast_skill(long cur_clock_tm, Variant rpc, skill_type tar_tp, IBaseUnit caster, IPoint2D to_pos, IBaseUnit tar_sprite, bool precast) { var cur_tm_s = DateTime.Now.ToBinary(); if (caster.isghost()) return new cast_skill_res(game_err_code.YOU_ARE_GHOST); var pl = caster.get_pack_data(); if (pl.casting != null) return new cast_skill_res(game_err_code.SKIL_ALREADY_CASTING_SKILL); if (pl.jumping != null) return new cast_skill_res(game_err_code.SKIL_CANT_CAST_WHEN_JUMP); int skill_id = rpc["sid"]._int32; //有聚气状态 使用任何技能 将触发它 if (pl.holding != null && skill_id != pl.holding.rpc["sid"]._int32) return new cast_skill_res(game_err_code.SKIL_ALREADY_HOLDING_SKILL); var skill_data = Utility.get_skil_skill_desc(skill_id); if (skill_data == null) return new cast_skill_res(game_err_code.SKIL_NOT_EXIST); if (skill_data.tar_tp != (int)tar_tp) { // Err: skill target type wrong return new cast_skill_res(game_err_code.SKIL_CAST_TARGET_TYPE_ERR); } // check caster own the skill and get skill level var caster_skil_data = caster.get_skil_data(skill_id); if (caster_skil_data == null) { caster_skil_data = this.get_map_skill(skill_id); if (caster_skil_data == null) { return new cast_skill_res(game_err_code.SKIL_NOT_LEARN); } } if (tar_sprite != null) { var tar_pl = tar_sprite.get_pack_data(); if (tar_pl.invisible > pl.observer) { // 看不到目标 return new cast_skill_res(game_err_code.SKIL_TARGET_NOT_AVALIBLE); } if (skill_data.tar_tp == (int)skill_type.ST_TARGET) { game_err_code check_res = Utility.check_target_type(caster, tar_sprite, skill_data.aff, this.pk_seting); if (check_res != game_err_code.RES_OK) return null; } } var skill_level_conf = Utility.get_skil_skill_lvl_desc(skill_id, caster_skil_data.sklvl); if (skill_level_conf == null) { // Err: skill data error Utility.trace_err("persist_game cast skill monster iid[" + pl.iid + "] skill [" + skill_id + "] sklvl[" + caster_skil_data.sklvl + "] data error\n"); return new cast_skill_res(game_err_code.SKIL_LVL_ERR); } if (cur_clock_tm < pl.skill_gen_cd) { //Utility.trace_err("persist_game cast skill caster [" + caster.get_iid() +"] skill ["+rpc.sid+"] cd not reach\n"); return new cast_skill_res(game_err_code.SKIL_CD_NOT_REACH); } if (pl.moving != null) update_pl_move(caster, cur_clock_tm); // rang check var cast_rang = pl.size + pl.atkrange; cast_rang += skill_data.cast_rang; if (to_pos != null) { if (tar_sprite != null) { var tar_pl = tar_sprite.get_pack_data(); cast_rang += tar_pl.size; if (tar_pl.moving != null) update_pl_move(tar_sprite, cur_clock_tm); } if (skill_level_conf.jump == null && skill_level_conf.teleport == null) { // 近战技能 var dist_x = to_pos.x - pl.x; var dist_y = to_pos.y - pl.y; var rang = cast_rang + 45; // 允许1格误差 if (dist_x * dist_x + dist_y * dist_y > rang * rang) { //Utility.trace_err("persist_game cast skill caster [" + caster.get_iid() +"] skill ["+rpc.sid+"] ground skill out of rang\n"); return new cast_skill_res(game_err_code.SKIL_CAST_RANG_ERR); } } } // 计算吟唱时间 if (precast && skill_data.cast_tm > 0) { var cast_tm = skill_data.cast_tm; var mul = 0; var add = 0; cast_tm = (cast_tm * 1000 / (1000 + mul) - add); //Utility.trace_info("cast_tm:["+cast_tm+"] \n"); if (cast_tm > 0) { // 需要吟唱 pl.moving = null; pl.casting = new casting() { tar_tp = (int)tar_tp, rpc = rpc, end_tm = (cur_clock_tm + cast_tm * 100) }; return new cast_skill_res(game_err_code.RES_OK); } } var hold_per = 1; if (skill_data.hold_tm > 0) { var hold_tm = skill_data.hold_tm; if (pl.holding != null) { hold_per = (int)(cur_clock_tm - pl.holding.start_tm) / (hold_tm * 100); if (hold_per > 1) hold_per = 1; pl.holding = null; } else { pl.moving = null; pl.holding = new holding() { tar_tp = (int)tar_tp, rpc = rpc, start_tm = cur_clock_tm, end_tm = cur_clock_tm + hold_tm * 100 }; return new cast_skill_res(game_err_code.RES_OK); } } if (pl.invisible > 0) { // 攻击就现身 Skill.rmv_state_from_pl_by_att("invisible", caster, pl); } var cd_tm = skill_level_conf.cd; var cdmul = 0; cd_tm = (cd_tm * 1000 / (1000 + cdmul)); if (cd_tm < 2) cd_tm = 2; //Utility.trace_info("cd_tm:["+cd_tm+"] \n"); pl.skill_gen_cd = cur_clock_tm + cd_tm * 100; pl.skill_gen_cdst = cur_clock_tm; //Utility.trace_err("persist_game cast self skill caster [" + caster.get_iid() +"] skill ["+rpc.sid+"] cd ["+pl.skill_cd[skill_data.cdtp]+"]\n"); var percent = 1000; percent = (percent * hold_per); if (percent <= 0) percent = 1; Variant rpc_data = new Variant(); rpc["res"] = (int)game_err_code.RES_OK; rpc["start_tm"] = rpc["start_tm"]; rpc["frm_iid"] = pl.iid; rpc["sid"] = rpc["sid"]; cast_skill_res cast_skill_res = new cast_skill_res(game_err_code.RES_OK) { skill_data = skill_data, skill_level_conf = skill_level_conf, rpc_data = rpc_data, percent = percent }; if (to_pos != null) { if (skill_level_conf.teleport != null) { // 瞬移 pl.moving = null; pl.last_mvpts = null; var telep_tm = 0; telep_tm = skill_level_conf.teleport.tm * 100; var dest_pos = Utility.valpoint_on_line(pl, to_pos, skill_level_conf.teleport.rang); if (telep_tm == 0) {//立即 pl.x = (int)dest_pos.x; pl.y = (int)dest_pos.y; if (caster.get_sprite_type() == map_sprite_type.MstPlayer && !caster.is_in_lvl) { pl.lx = pl.x; pl.ly = pl.y; } } else { pl.teleping = new teleping() { start_tm = cur_clock_tm, end_tm = (cur_clock_tm + telep_tm), telep = skill_level_conf.teleport, rpc = rpc, percent = percent, dest_x = (int)dest_pos.x, dest_y = (int)dest_pos.y }; } //rpc_data.telep < - { to_x = dest_pos.x, to_y = dest_pos.y, tm = telep_tm}; } else if (skill_level_conf.jump != null) { // 跳跃 pl.moving = null; pl.last_mvpts = null; var sub_len = 0; if (tar_sprite != null) { sub_len = 45; } var dest_pos = Utility.valpoint_on_line(pl, to_pos, skill_level_conf.jump.jump_rang, sub_len); var dist_x = dest_pos.x - pl.x; var dist_y = dest_pos.y - pl.y; var rang = Math.Sqrt(dist_x * dist_x + dist_y * dist_y); long jump_tm = (long)(rang * 1000 / skill_level_conf.jump.speed); if (jump_tm <= 0) jump_tm = 1; //pl.x = dest_pos.x; //pl.y = dest_pos.y; rpc_data["jump"] = new Variant(); rpc_data["jump"]["tm"] = jump_tm; rpc_data["jump"]["to_x"] = dest_pos.x; rpc_data["jump"]["to_y"] = dest_pos.y; var tar_iid = 0; if (tar_sprite != null) tar_iid = tar_sprite.get_pack_data().iid; pl.jumping = new jumping() { start_tm = cur_clock_tm, during_tm = jump_tm, end_tm = (cur_clock_tm + jump_tm), jump = skill_level_conf.jump, rpc = rpc, percent = percent, dest_x = (int)dest_pos.x, dest_y = (int)dest_pos.y, tar_iid = tar_iid }; } // if ("fly" in skill_level_conf && skill_level_conf.fly.speed > 0) //{ // var dest_pos = { x = to_pos.x, y = to_pos.y }; // var dist_x = dest_pos.x - pl.x; // var dist_y = dest_pos.y - pl.y; // var rang = Math.Sqrt(dist_x * dist_x + dist_y * dist_y); // if ("toend" in skill_level_conf.fly ) // { // var max_rang = skill_level_conf.fly.rang + cast_rang; // dest_pos.x = (dist_x * max_rang / rang + pl.x); // dest_pos.y = (dist_y * max_rang / rang + pl.y); // rang = max_rang; // } // var fly_tm = (rang * 1000 / skill_level_conf.fly.speed); // var fly_end_tm = cur_clock_tm + fly_tm; // var tar_iid = 0; // if (tar_sprite) tar_iid = tar_sprite.get_pack_data().iid; // // 记录飞行道具 // this.map_flys.push({ end_tm = fly_end_tm, frm_iid = pl.iid, rpc = rpc, cast_skill_res = cast_skill_res, tar_iid = tar_iid, frm_pos ={ x = pl.x, y = pl.y}, target_pos = dest_pos}); // rpc_data.fly < - { tm = fly_tm, to_x = dest_pos.x, to_y = dest_pos.y}; // } } //::g_dump( "cast_skill_res OK:", cast_skill_res ); return cast_skill_res; }
public void apply_direct_dmg_on_pl(IBaseUnit tar_sprite, IBaseUnit frm_sprite, Variant damage, long cur_clock_tm, int per) { // TO DO : 优化: per = 1000时不需要计算增益 var tar_pl = tar_sprite.get_pack_data(); // 取不到状态添加对象情况下,本函数frm_sprite可能为空,则需要默认的计算参数 var pl = default(IMapUnit); if (frm_sprite != null) { pl = frm_sprite.get_pack_data(); pl.last_atk_tm = cur_clock_tm; // 触发普通攻击cd } //Utility.trace_info("apply_dmg_on_pl frm_sprite:["+frm_sprite+"] per["+per+"]\n"); //sys.dumpobj(pl); //var hpchange = {}; if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer) {// 玩家 防护值调整 double dpdmg = 0; if (damage.ContainsKey("dp_dmg")) { dpdmg = (damage["dp_dmg"]._int32 * per / 1000); } if (damage.ContainsKey("dp_per")) { dpdmg += (damage["dp_per"]._int32 * per / 100000.0 * tar_pl.max_dp); } // if (frm_sprite != null && damage.ContainsKey("dattadj")) // { // foreach (attname, val in damage.dattadj[0] ) //{ // if (attname in pl ) // { // dpdmg += (pl[attname] / val); // //sys.trace( sys.SLT_DETAIL, " pl[" + attname + "]= " + pl[attname] + " mpdmg=" + mpdmg + "\n" ); // } // } // } if (dpdmg != 0) { tar_pl.dp -= (int)dpdmg; if (tar_pl.dp < 0) tar_pl.dp = 0; if (tar_pl.dp > tar_pl.max_dp) tar_pl.dp = tar_pl.max_dp; //sys.trace( sys.SLT_DETAIL, "dpdmg tar_pl.cid =" + tar_pl.cid + " tar_pl.dp = " + tar_pl.dp + "\n"); //hpchange.dpadd < - -dpdmg; } } double total_dmg = 0; // if ("hp_dmg" in damage) //{ // total_dmg = (damage.hp_dmg * per / 1000.0); // //sys.trace( sys.SLT_DETAIL, "per= " + per + " total_dmg=" + total_dmg + "\n" ); // } // if ("hp_per" in damage ) //{ // total_dmg += (damage.hp_per * per / 100000.0 * tar_pl.max_hp); // } // if (frm_sprite && ("hattadj" in damage) ) //{ // foreach (attname, val in damage.hattadj[0] ) // { // if (attname in pl ) // { // total_dmg += (pl[attname] / val); // //sys.trace( sys.SLT_DETAIL, " pl[" + attname + "]= " + pl[attname] + " total_dmg=" + total_dmg + "\n" ); // } // } // } //sys.dumpobj(damage); //Utility.trace_info("total_dmg:["+total_dmg+"]\n"); if (total_dmg != 0) { if (total_dmg > 0) { if (frm_sprite != null) { tar_sprite.onhate(frm_sprite, total_dmg); tar_sprite.ondmg(frm_sprite, total_dmg); if (frm_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { if (frm_sprite.gmap.blvlmap) { frm_sprite.gmap.worldsvr.on_dmg(frm_sprite, tar_sprite, total_dmg); } } } // 吸收伤害 total_dmg = pl_absorb_dmg(tar_sprite, tar_pl, total_dmg); // 魔法抵扣生命 total_dmg = pl_hpdmg_2_mpdmg(tar_sprite, tar_pl, total_dmg); // 伤害链接 pl_dmg_link(tar_sprite, tar_pl, total_dmg); } tar_pl.hp -= (int)total_dmg; if (tar_pl.hp < 0) tar_pl.hp = 0; if (tar_pl.hp > tar_pl.max_hp) tar_pl.hp = tar_pl.max_hp; //hpchange.hpadd < - -total_dmg; //hpchange.die < -tar_pl.hp <= 0; } // if (hpchange.Count > 0) // { // // broadcast hpchange msg // hpchange.frm_iid < -pl.iid; // tar_sprite.broad_cast_zone_msg_and_self(26, { iid = tar_pl.iid, hpchange = hpchange}); // if ("cid" in tar_pl) //{ // var tid = team.get_ply_teamid(tar_pl.cid); // if (tid > 0) // { // // 在队伍中,发送队友属性变化消息 // team_bcast_rpc_except(tid, 138, { cid = tar_pl.cid, hp = tar_pl.hp, dp = tar_pl.dp}, tar_pl.sid); // } // } if (tar_pl.hp <= 0) { // die! tar_sprite.die(frm_sprite); } //} double mpdmg = 0; // if ("mp_dmg" in damage) //{ // mpdmg = (damage.mp_dmg * per / 1000); // } // if ("mp_per" in damage ) //{ // mpdmg += (damage.mp_per * per / 100000.0 * tar_pl.max_mp); // } // if (frm_sprite && ("mattadj" in damage) ) //{ // foreach (attname, val in damage.mattadj[0] ) // { // if (attname in pl ) // { // mpdmg += (pl[attname] / val); // //sys.trace( sys.SLT_DETAIL, " pl[" + attname + "]= " + pl[attname] + " mpdmg=" + mpdmg + "\n" ); // } // } // } //Utility.trace_info("mpdmg:["+mpdmg+"]\n"); //if (mpdmg != 0) //{ // // 魔法值、怒气值调整 // var mpchange_rpc = { }; // tar_pl.mp -= mpdmg; // if (tar_pl.mp < 0) tar_pl.mp = 0; // if (tar_pl.mp > tar_pl.max_mp) tar_pl.mp = tar_pl.max_mp; // mpchange_rpc.mpadd < - -mpdmg; // if (frm_sprite) // { // tar_sprite.onhate(frm_sprite, mpdmg); // } // if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer) // { //// send mpchange msg //::send_rpc(tar_pl.sid, 32, mpchange_rpc); // } //} }
public static int _update_pl_ori_move(IBaseUnit sprite, long cur_clock_tm) { var pl = sprite.get_pack_data(); var dflag = true; var speed = pl.speed; var tmleft = cur_clock_tm - pl.moving.start_tm; if (dflag) Utility.debug("_update_pl_ori_move speed[" + speed + "] tmleft[" + tmleft + "]"); if (tmleft <= 0) { return 0; } // moving var to_end = false; var move_distance = tmleft * speed / 1000.0; if (move_distance >= pl.moving.max_r) { to_end = true; move_distance = pl.moving.max_r; } var to_x = pl.moving.stx + (move_distance * pl.moving.ori_cos); var to_y = pl.moving.sty + (move_distance * pl.moving.ori_sin); if (dflag) { Utility.debug(" move_distance[" + move_distance + "] tmleft[" + tmleft + "] speed[" + speed + "] cur_clock_tm[" + cur_clock_tm + "] pl.moving.start_tm[" + pl.moving.start_tm + "] pl.x[" + pl.x + "] pl.y[" + pl.y + "] to_x[" + to_x + "] to_y[" + to_y + "]"); } if (to_end) { Utility.debug("_update_pl_ori_move to_end !!! "); pl.moving = null; } pl.x = (int)to_x; pl.y = (int)to_y; if (sprite.get_sprite_type() == map_sprite_type.MstPlayer && !sprite.is_in_lvl) { pl.lx = pl.x; pl.ly = pl.y; } sprite.on_pos_change(pl.x, pl.y); return 0; }
public void die(IBaseUnit killer, bool clear_owner = true) { if (dying) return; dying = true; this.mondata.isdie = true; long cur_clock_tm = DateTime.Now.ToBinary(); if (this.mondata.respawn_tm < 3100) this.respawn_tm = 3100 + cur_clock_tm; else this.respawn_tm = this.mondata.respawn_tm + cur_clock_tm; this.die_tm = cur_clock_tm; this.mondata.atking = null; this.mondata.moving = null; if (null != this.mondata.jumping) { this.mondata.x = this.mondata.jumping.dest_x; this.mondata.y = this.mondata.jumping.dest_y; this.mondata.jumping = null; } if (null != this.mondata.patrol) { this.mondata.patrol.idx = 0; this.mondata.patrol.cnt = this.mondata.patrol.init_cnt; } foreach (IBaseUnit bu in this.gmap.map_sprites.Values) { IMapUnit ux = bu.get_pack_data(); if (null != ux.atking) { if (ux.atking.tar_iid == this.iid) ux.atking = null; } bu.on_spr_die(this.iid); } if (null != killer) { if (killer.get_sprite_type() == map_sprite_type.MstMonster) if (null != killer.owner_ply) killer = killer.owner_ply; //ISprite owner = this; //owner.remove_from_hurt_from_iids(this.iid); } this.hatelist.Clear(); this._on_leave_battle(cur_clock_tm); //this.mondata.atking = null; //this.mondata.moving = null; //if (null != this.mondata.jumping) //{ // this.mondata.x = this.mondata.jumping.dest_x; // this.mondata.y = this.mondata.jumping.dest_y; // this.mondata.jumping = null; //} foreach (KeyValuePair<int, IBaseUnit> pair in this.gmap.map_sprites) { IMapUnit unit = pair.Value.get_pack_data(); if (null != unit.atking) { if (unit.atking.tar_iid == this.mondata.iid) unit.atking = null; } } }
public void update_jumping(IBaseUnit caster, IMapUnit pl, long cur_clock_tm) { if (pl.jumping == null) return; var jumping = pl.jumping; if (jumping.end_tm > cur_clock_tm) { long jumping_tm = cur_clock_tm - jumping.start_tm; pl.x += ((jumping.dest_x - pl.x) * jumping_tm / jumping.during_tm); pl.y += ((jumping.dest_y - pl.y) * jumping_tm / jumping.during_tm); //Utility.trace_info("pl.x["+pl.x+"] pl.y["+pl.y+"]\n"); if (caster.get_sprite_type() == map_sprite_type.MstPlayer && !caster.is_in_lvl) { pl.lx = pl.x; pl.ly = pl.y; } return; } pl.x = jumping.dest_x; pl.y = jumping.dest_y; if (caster.get_sprite_type() == map_sprite_type.MstPlayer && !caster.is_in_lvl) { pl.lx = pl.x; pl.ly = pl.y; } int skill_id = jumping.rpc["sid"]._int32; if (jumping.jump.tres == null) return; if (jumping.jump.rang != null) { Skill.apply_rang_eff(cur_clock_tm, caster, caster.get_pack_data(), jumping.jump.tres, jumping.jump.rang, skill_id, jumping.percent); } else { IBaseUnit tar_sprite = caster.gmap.get_sprite_by_iid(pl.jumping.tar_iid); if (tar_sprite != null) { var tar_pl = tar_sprite.get_pack_data(); var dist_x = tar_pl.x - pl.x; var dist_y = tar_pl.y - pl.y; if (dist_x * dist_x + dist_y * dist_y < 100 * 100) { // 在范围内 foreach (var tres in jumping.jump.tres) Skill.apply_skill_eff_to(cur_clock_tm, caster, tar_sprite, tres, tres.aff, skill_id, pl.jumping.percent); } } } }
public bool onhate(IBaseUnit atker, int hate_value, bool callhatp = true) { if (this.collect_tar > 0) return false; if (this.mondata.revange == 0) return false; if (this.running_tm > 0) return false; if (atker.isdie()) return false; if (atker.get_sprite_type() == map_sprite_type.MstMonster) if (atker.collect_tar > 0) return false; if (!can_atk(atker)) return false; int atker_iid = atker.get_pack_data().iid; if (this.iid == atker_iid) return false; if (this.monconf.ai.hate_add > 0) { hate_value = this.monconf.ai.hate_add; } if (this.hatelist.ContainsKey(atker_iid)) this.hatelist[atker_iid] += hate_value; else { this.hatelist[atker_iid] = hate_value; if (this.monconf.ai.hatp > 0) { long dist2 = this.mondata.defrang * this.mondata.defrang; foreach (KeyValuePair<int, IBaseUnit> pair in this.gmap.map_mons) { var m = pair.Value as Monster; if (m.iid == this.iid) continue; if (m.monconf.ai.hatp <= 0) continue; if (!same_hatp(m)) continue; if (m.hatelist.ContainsKey(atker_iid)) continue; if (Utility.distance2(this, m) < dist2) { m.onhate(atker, hate_value, false); } } } } if (this.mondata.atking == null) { if (this.mondata.patrol != null && this.mondata.patrol.tracing == null) { this.mondata.patrol.movto.trinitx = (int)this.mondata.x; this.mondata.patrol.movto.trinity = (int)this.mondata.y; this.mondata.patrol.movto.tracing = true; } long now = DateTime.Now.ToBinary(); //Dictionary<string,long> this.mondata.atking = new atking() { tar_iid = atker.iid, start_tm = now - this.mondata.atkcdtm, trace_tm_left = 0 }; //TODO broadcast this.broad_cast_zone_msg(12, new NetMsgData()); } return true; }
public void update_teleping(IBaseUnit caster, IMapUnit pl, long cur_clock_tm) { if (pl.teleping == null) { return; } if (pl.teleping.end_tm > cur_clock_tm) { return; } pl.x = pl.teleping.dest_x; pl.y = pl.teleping.dest_y; //Utility.trace_info("pl.x["+pl.x+"] pl.y["+pl.y+"]\n"); if (caster.get_sprite_type() == map_sprite_type.MstPlayer && !caster.is_in_lvl) { pl.lx = pl.x; pl.ly = pl.y; } pl.teleping = null; }
public bool can_atk(IBaseUnit spr) { if (null != this.owner_ply) { return this.owner_ply.can_atk(spr); } if (this.get_sprite_type() == map_sprite_type.MstMonster && null != spr.owner_ply) spr = spr.owner_ply; IMapUnit pl = spr.get_pack_data(); if (pl.lvlsideid > 0) return this.mondata.lvlsideid != pl.lvlsideid; if (this.mondata.lvlsideid == 0 && spr.get_sprite_type() == map_sprite_type.MstMonster) return false; return true; }
public void on_km(IBaseUnit killer, int mid) { if (this.kmtriggers.Count <= 0) { return; } // 更新触发器 IMapUnit pl = null; if (killer != null) { pl = killer.get_pack_data(); } List<int> to_rmv_tmtrgids = new List<int>(); List<int> to_rmv_areatrgids = new List<int>(); List<int> to_rmv_kmtrgids = new List<int>(); List<int> to_rmv_uitmtrgids = new List<int>(); List<int> to_rmv_mistrgids = new List<int>(); List<int> to_add_trgconf = new List<int>(); List<int> to_rmv_othertrgids = new List<int>(); var need_sync_km_cnt = false; foreach (var trg in this.kmtriggers.Values) { // 触发 if (trg.conf.km.mid != mid) continue; if (pl != null && (trg.conf.km.sideid != 0 && trg.conf.km.sideid != pl.lvlsideid)) continue; if (killer != null && killer.get_sprite_type() == map_sprite_type.MstPlayer) { //if (!_trigger_attchk(killer, trg.conf)) //{ // continue; //} } ++trg.kmcnt; if (trg.kmcnt < trg.tkmcnt) { continue; } trg.kmcnt = 0; --trg.cnt; if (trg.cnt <= 0) { to_rmv_kmtrgids.push(trg.conf.id); } this._trig_res(trg.conf, killer, to_add_trgconf, to_rmv_tmtrgids, to_rmv_areatrgids, to_rmv_kmtrgids, to_rmv_uitmtrgids, to_rmv_mistrgids, to_rmv_othertrgids); } foreach (var trid in to_rmv_tmtrgids) { //if (trid in this.tmtriggers) delete this.tmtriggers[trid]; } foreach (var trid in to_rmv_areatrgids) { //if (trid in this.areatriggers) delete this.areatriggers[trid]; } foreach (var trid in to_rmv_kmtrgids) { //if (trid in this.kmtriggers) delete this.kmtriggers[trid]; } foreach (var trid in to_rmv_uitmtrgids) { //if (trid in this.useitmtriggers) delete this.useitmtriggers[trid]; } foreach (var trid in to_rmv_mistrgids) { //if (trid in this.mistriggers) delete this.mistriggers[trid]; } foreach (var trid in to_rmv_othertrgids) { //if (trid in this.othertriggers) delete this.othertriggers[trid]; } foreach (var trid in to_add_trgconf) { this._add_triger(this.trigger_conf[trid]); } }
public void ondmg(IBaseUnit atker, int dmg) { int atker_cid = atker.get_pack_data().cid; long now_s = DateTime.Now.ToBinary(); // 被攻击 if (this.kp_asist_rec) { // 需要记录助攻 if (atker.get_sprite_type() == map_sprite_type.MstMonster) { return; } this.beatk_ply_cids[atker_cid] = now_s; // 记录攻击者cid this.lastdmgtm = now_s; // 记录最后一次受伤害时间 } if (gmap.pk_seting == map_pk_setting_type.MPST_NORMAL) { if (atker.get_sprite_type() == map_sprite_type.MstPlayer) { if (atker_cid != pinfo.cid && !this.can_atk_direct()) { if (!atker.defend_tm_map.ContainsKey(pinfo.cid)) { //是否被正当防御 //是否第一次记录 defend_tm_map[atker_cid] = now_s + 10000; } } } } }
public static void update_pl_atk(IBaseUnit sprite, long cur_clock_tm) { var pl = sprite.get_pack_data(); if (pl.atking == null) return; var cd_tm = sprite.get_atk_cd(); if (pl.casting != null) { // 吟唱中,不更新攻击 _hold_pl_atk(pl, cd_tm, cur_clock_tm); return; } if (pl.holding != null) { // 聚气中,不更新攻击 _hold_pl_atk(pl, cd_tm, cur_clock_tm); return; } if (sprite.has_state(pl_state_type.PST_CANT_ATTACK)) { // can't attack _hold_pl_atk(pl, cd_tm, cur_clock_tm); return; } //Utility.trace_err("update [" + pl.iid +"] attack \n"); if (!sprite.gmap.has_sprite_by_iid(pl.atking.tar_iid)) { // 目标不在同一地图 sprite.cancel_atk(); // TO DO : send msg return; } var tar_sprite = sprite.gmap.map_sprites[pl.atking.tar_iid]; var tar_pl = tar_sprite.get_pack_data(); if (sprite.isghost() || tar_sprite.isghost()) { // 对方是灵魂状态,停止攻击 sprite.cancel_atk(); return; } if (tar_sprite.ignore_dmg()) { _hold_pl_atk(pl, cd_tm, cur_clock_tm); return; } if (cur_clock_tm < pl.skill_gen_cd) { // 与技能共cd _hold_pl_atk(pl, cd_tm, cur_clock_tm); return; } //Utility.trace_err("[" + pl.iid +"] attack ["+pl.atking.tar_iid+"] cur tm: ["+cur_clock_tm+"] atkstarttm["+pl.atking.start_tm+"]\n"); // TO DO : update face var tm_interval = cur_clock_tm - pl.atking.start_tm; //Utility.trace_err("[" + pl.iid +"] attack ["+pl.atking.tar_iid+"] tm_interval: ["+tm_interval+"] cd_tm ["+cd_tm+"]\n"); if (tm_interval < cd_tm) { // 没到攻击间隔 return; } if (tar_pl.invisible > pl.observer) { // 看不到目标 if (sprite.get_sprite_type() == map_sprite_type.MstMonster) { //delete pl.atking; // 停止攻击 pl.atking = null; } else { _hold_pl_atk(pl, cd_tm, cur_clock_tm); } return; } //Utility.trace_err("pl.x [" + pl.x +"] pl.y ["+pl.y+"] tar_pl.x: ["+tar_pl.x+"] tar_pl.y: ["+tar_pl.y+"]\n"); //Utility.trace_err("dist_x [" + dist_x +"] dist_y ["+dist_y+"] atkrange: ["+pl.atkrange+"]\n"); var dist_x = tar_pl.x - pl.x; var dist_y = tar_pl.y - pl.y; var range = pl.atkrange + pl.size + tar_pl.size + 32; // 允许1格误差 if (dist_x * dist_x + dist_y * dist_y > range * range) { // 不在攻击范围内 _hold_pl_atk(pl, cd_tm, cur_clock_tm); return; } var atkcnt_trigered = false; var added_state = false; if (pl.states != null) { // 检查按攻击次数结算状态 foreach (var val in pl.states.state_par) { if (val.atkedcnt < 0 || val.desc.atkcnt == null) continue; ++val.atkedcnt; //Utility.trace_info("val.atkedcnt["+val.atkedcnt+"] val.desc.atkcnt.cnt["+val.desc.atkcnt.cnt+"]") if (val.atkedcnt < val.desc.atkcnt.cnt) { continue; } //sys.dumpobj(val); // 触发结算状态 atkcnt_trigered = true; if (val.desc.atkcnt.add_stat > 0) { var state_obj = Skill.add_state_to_pl(cur_clock_tm, tar_sprite, new tres_conf(val.desc.atkcnt.add_stat), sprite, val.per, false); if (state_obj != null) { added_state = true; // broadcast add state msg; //tar_sprite.broad_cast_zone_msg_and_self(24, { iid = tar_pl.iid, states =[state_obj]}); } } if (val.desc.atkcnt.dmg > 0) { apply_dmg_on_pl(tar_sprite, sprite, new damage() { hp_dmg = val.desc.atkcnt.dmg }, cur_clock_tm, val.par); } } } if (pl.invisible > 0) { // 攻击就现身 Skill.rmv_state_from_pl_by_att("invisible", sprite, pl); } //if(sprite.get_sprite_type()==map_sprite_type.MstPlayer) //{ // // 中断打坐 // sprite.try_stop_recover(); //} tar_sprite.atk_by(sprite); if (atkcnt_trigered) { // 触发了攻击次数结算状态,该次攻击失效 if (added_state) { Skill._remark_pl_state(tar_sprite, tar_pl); } if (pl.atking != null) pl.atking.start_tm = cur_clock_tm; return; } // 计算攻击次数 var atk_count = (tm_interval / cd_tm); var atk_tm_left = tm_interval % cd_tm; var total_dmg = 0; pl.atking.start_tm = cur_clock_tm - atk_tm_left; pl.last_atk_tm = pl.atking.start_tm; pl.skill_gen_cd = pl.atking.start_tm + cd_tm; // 触发技能cd pl.skill_gen_cdst = pl.atking.start_tm; // 触发技能cd起始 var real_cd_tm = pl.skill_gen_cd - cur_clock_tm; if (real_cd_tm < 0) real_cd_tm = 0; // 判断对象是否攻击免疫 if (tar_sprite.has_state(pl_state_type.PST_ATK_AVOID)) { // can't be attack // send avoid attack msg //Utility.trace_err("[" + pl.iid +"] attack ["+pl.atking.tar_iid+"] target avoid attack\n"); //sprite.broad_cast_zone_msg_and_self(18, { hited = 0, frm_iid = pl.iid, to_iid = pl.atking.tar_iid}); return; } //::g_dump( " update_pl_atk() ===>>>> ", "") ; var ret = apply_dmg_on_pl_ex(tar_sprite, sprite, new damage() { dmg_min = 0, dmg_max = 0, noratk = 1, hp_dmg = 0, mp_dmg = 0 }, cur_clock_tm, (int)atk_count * 1000, true, true); //ret.atkcount < -atk_count; //ret.cdtm < -real_cd_tm; // send attack msg sprite.broad_cast_zone_msg_and_self(18, ret); if (tar_sprite.get_sprite_type() == map_sprite_type.MstPlayer) { //目标不在视野 需要补发消息 // if (!sprite.is_ply_inzone(tar_pl.sid)) // { //::send_rpc(tar_pl.sid, 18, ret); // } } }
public bool can_atk(IBaseUnit spr) { if (spr.get_sprite_type() == map_sprite_type.MstMonster && spr.owner_ply != null) spr = spr.owner_ply; // 用主人代替宠物检查敌我关系 IMapUnit pl = spr.get_pack_data(); if (pl.iid == this.pinfo.iid) return false; //if (spr.get_sprite_type() == map_sprite_type.MstPlayer && pl.level < game_conf.pk_safe_lvl) //{ // return false; //} if (pl.lvlsideid != 0) { if (pinfo.lvlsideid != pl.lvlsideid) return true; if ((gmap != null && !gmap.ignore_side) || spr.get_sprite_type() == map_sprite_type.MstMonster) return false; } bool cannt_pk = false; switch (pinfo.pk_state) { case pk_state_type.PKST_PEACE: cannt_pk = spr.get_sprite_type() == map_sprite_type.MstPlayer; break; case pk_state_type.PKST_PK_ALL: cannt_pk = false; break; case pk_state_type.PKST_PK_TEAM: if (pl.teamid == 0 || pinfo.teamid == 0) cannt_pk = false; else cannt_pk = pl.teamid == pinfo.teamid; break; case pk_state_type.PKST_PK_CLAN: if (pl.clanid == 0 || pinfo.clanid == 0) cannt_pk = false; else cannt_pk = pl.clanid == pinfo.clanid; break; } return !cannt_pk; }
public void on_km(IBaseUnit killer, IBaseUnit mon) { if (killer == null) return; IMapUnit pl = killer.get_pack_data(); IMapUnit mondata = mon.get_pack_data(); int mid = mondata.mid; if (is_score_km) { if (!score_km.ContainsKey(mid)) score_km._score_km[mid] = new _score_km() { mid = mid, cnt = 0 }; var kminfo = score_km._score_km[mid]; kminfo.cnt++; score_km.kmcnt++; //算个总数 //::g_dump( "on_lvl_km score_km: ", score_km ); } if (pl.lvlsideid > 0) { // 分阵营 //if (this.cltwar) //{ // // 领地争夺战 // if (("kmfin" in this.cltwar) && mid == this.cltwar.kmfin.tar_mid) //{ // --this.cltwar.kmfin.cntleft; // if (this.cltwar.kmfin.cntleft < 0) // { // this.cltwar.kmfin.cntleft = 0; // } // // 通知客户端杀怪 lvl_km msg // if (killer.get_sprite_type() == map_sprite_type.MST_PLAYER) // { // this.broad_cast_msg(249, { sideid = pl.lvlsideid, cid = pl.cid, name = pl.name, mid = mid}); // } // else // { // // 怪物杀死怪物 // this.broad_cast_msg(249, { sideid = pl.lvlsideid, cid = 0, name = killer.monconf.name, mid = mid}); // } // } //} //else if (this.clcqwar) //{ // // 帮派奴役战 // if (mid == this.clcqwar.tar_mid) // { // --this.clcqwar.cntleft; // if (this.clcqwar.cntleft < 0) // { // this.clcqwar.cntleft = 0; // } // // 通知客户端杀怪 lvl_km msg // if (killer.get_sprite_type() == map_sprite_type.MST_PLAYER) // { // this.broad_cast_msg(249, { sideid = pl.lvlsideid, cid = pl.cid, name = pl.name, mid = mid}); // } // else // { // // 怪物杀死怪物 // this.broad_cast_msg(249, { sideid = pl.lvlsideid, cid = 0, name = killer.monconf.name, mid = mid}); // } // } //} // else if (pl.lvlsideid in this.kmfinbyside) //{ // local kmside = this.kmfinbyside[pl.lvlsideid]; // if (mid in kmside) // { // local km = kmside[mid]; // --km.cntleft; // // 通知客户端杀怪 lvl_km msg // if (killer.get_sprite_type() == map_sprite_type.MST_PLAYER) // { // this.broad_cast_msg(249, { sideid = pl.lvlsideid, cid = pl.cid, name = pl.name, mid = mid}); // } // else // { // // 怪物杀死怪物 // this.broad_cast_msg(249, { sideid = pl.lvlsideid, cid = 0, name = killer.monconf.name, mid = mid}); // } // if (km.cntleft < 0) // { // km.cntleft = 0; // } // //_check_finish(); // } // } //else if (pl.lvlsideid in this.ptfinbyside) //{ // if (this.maxptside < 0 && ("kmpt" in mon.monconf)) // { // local sidept = this.ptfinbyside[pl.lvlsideid]; // // 杀怪得积分 // sidept.pt += mon.monconf.kmpt; // // 通知客户端积分值变化 lvl_km msg // this.broad_cast_msg(249, { sideid = pl.lvlsideid, pt = sidept.pt}); // if (sidept.pt >= sidept.maxpt) // { // this.maxptside = pl.lvlsideid; // } // // 胜利检查在update中进行 // } // } } else if (killer.get_sprite_type() == map_sprite_type.MstPlayer) { //IMapUnit pl = killer.get_pack_data(); if (kmfin.ContainsKey(mid)) { if (this.gpmap_maxply > 0) { var gp_map = this.gp_maps[this.cid2gpid[pl.cid] - 1]; var km = gp_map.kmfin[mid]; --km.cntleft; if (km.cntleft < 0) { km.cntleft = 0; } } else { var km = this.kmfin[mid]; --km.cntleft; if (km.cntleft < 0) { km.cntleft = 0; } } // 通知客户端杀怪 lvl_km msg //this.broad_cast_msg(249, { sideid = pl.lvlsideid, cid = pl.cid, name = ply.pinfo.name, mid = mid}); //_check_finish(); } } if (killer.get_sprite_type() == map_sprite_type.MstPlayer) { // if ("bcast_kill" in this.lvl_conf ) //{ // local bcast_kill_conf = this.lvl_conf.bcast_kill[0]; // foreach (monid in bcast_kill_conf.ids) // { // if (monid == mid) // { // // 发送系统公告 // _broad_cast_sys_msg({ cid = pl.cid, name = pl.name, tp = bcast_msg_tp.LVL_MON_KILLED, par = mid, par1 = this.ltpid}); // break; // } // } // } } if (mon.get_pack_data().owner_cid > 0) { // if (this.diff_lvl in map_need_km) //{ // foreach (mapid,kmdata in this.map_need_km[this.diff_lvl]) // { // if (kmdata.mapid == mon.gmap.mapid) // { //击杀地图需求怪,需广播到所有玩家 // if (kmdata.mid == 0 || kmdata.mid == mon.mondata.mid) // { // local moncnt = this.get_map_mon(mon.gmap.mapid); // broad_cast_msg(237, { tp = 4, mapid = kmdata.mapid, cntleft = moncnt}); // } // break; // } // } // } } }