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); // } } }