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 cast_skill_res _cast_skill(long now, Dictionary<string, string> rpc, skill_type skill_type, IBaseUnit caster, IBaseUnit target, bool precast = false, Point2D to_pos = null) { if (caster.isghost()) return new cast_skill_res() { res = game_err_code.YOU_ARE_GHOST }; IMapUnit pl = caster.get_pack_data(); if (pl.atking != null) return new cast_skill_res() { 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 = Convert.ToInt32(rpc["sid"]); if (pl.holding != null && pl.holding.sid != skill_id) return new cast_skill_res(game_err_code.SKIL_ALREADY_HOLDING_SKILL); skill_conf skillConf = Utility.GetSkillConf(skill_id); if (skillConf == null) return new cast_skill_res(game_err_code.SKIL_NOT_EXIST); if (!skillConf.igccstate) { if (caster.has_state(pl_state_type.PST_CANT_CAST_SKILL)) return new cast_skill_res(game_err_code.SKIL_CANT_CAST); } if (skillConf.tar_tp != (int)skill_type) return new cast_skill_res(game_err_code.SKIL_CAST_TARGET_TYPE_ERR); int skill_level = caster.get_skil_data(skill_id); if (skill_level <= 0) { skill_level = this.get_map_skill(skill_id); if (skill_level <= 0) return new cast_skill_res(game_err_code.SKIL_NOT_LEARN); } if (target != null) { IMapUnit tar_pl = target.get_pack_data(); if (tar_pl.invisible > pl.invisible) return new cast_skill_res(game_err_code.SKIL_TARGET_NOT_AVALIBLE); if (skillConf.tar_tp == (int)skill_type.ST_TARGET) { if (caster.iid != target.iid) { if (!skillConf.Is_Target_Enermy()) { if (caster.can_atk(target)) return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET); bool isaly = caster.isaily(target); if (isaly) { if (!skillConf.Is_Target_ALAI()) return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET); } else { if (!skillConf.Is_Target_MID()) return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET); } } else if (caster.Is_Player()) { if (target.Is_Player()) { if (this.pk_seting == map_pk_setting_type.MPST_PEACE) return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_MAP); if (pl.in_pczone || tar_pl.in_pczone) return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_ZONE); if (this.pk_seting == map_pk_setting_type.MPST_NORMAL) { if (!target.can_atk_direct()) if (!caster.can_atk(target)) return new cast_skill_res(game_err_code.NULL); } else { if (!caster.can_atk(target)) return new cast_skill_res(game_err_code.NULL); } } else if (target.Is_Monster()) { if (target.owner_ply != null) { IBaseUnit owner_sprite = target.owner_ply; IMapUnit owner_pl = owner_sprite.get_pack_data(); if (owner_sprite.iid == caster.iid) return new cast_skill_res(game_err_code.CANT_ATTACK_SELF_PET); if (this.pk_seting == map_pk_setting_type.MPST_PEACE) return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_MAP); if (pl.in_pczone || owner_pl.in_pczone) return new cast_skill_res(game_err_code.CANT_PK_IN_PEACE_ZONE); if (this.pk_seting == map_pk_setting_type.MPST_NORMAL) { if (!owner_sprite.can_atk_direct()) if (!caster.can_atk(owner_sprite)) return new cast_skill_res(game_err_code.NULL); } else { if (!caster.can_atk(owner_sprite)) return new cast_skill_res(game_err_code.NULL); } } else { if (!caster.can_atk(target)) return new cast_skill_res(game_err_code.NULL); } } else { if (!skillConf.Is_Target_SELF()) return new cast_skill_res(game_err_code.SKIL_INVALIDE_TAREGET); } } } } } skill_lv_conf skill_level_conf = skillConf.GetSkillLevelConf(skill_level); if (null == skill_level_conf) return new cast_skill_res(game_err_code.SKIL_LVL_ERR); if (caster.Is_Skill_In_CD(skill_id, now)) return new cast_skill_res(game_err_code.SKIL_CD_NOT_REACH); if (pl.moving != null) update_pl_move(caster, now); int cast_rang = pl.size + pl.atkrange; if (skillConf.cast_rang > 0) cast_rang += skillConf.cast_rang; if (to_pos != null) { if (target != null) { cast_rang += target.get_pack_data().size; if (target.get_pack_data().moving != null) update_pl_move(target, now); } if (skill_level_conf.jump == null && skill_level_conf.teleport == null) { double d_x = to_pos.x - caster.x; double d_y = to_pos.y - caster.y; long rang = cast_rang + 45; if (d_x * d_x + d_y * d_y > rang * rang) return new cast_skill_res(game_err_code.SKIL_CAST_RANG_ERR); } } if (precast && skillConf.cast_tm > 0) { pl.moving = null; pl.casting = new casting() { end_tm = now + skillConf.cast_tm * 100, tar_tp = (int)skill_type, rpc = rpc }; return new cast_skill_res(game_err_code.RES_OK); } if (skillConf.hold_tm < 0) { if (pl.holding != null) pl.holding = null; else { pl.moving = null; pl.holding = new holding() { tar_tp = (int)skill_type, rpc = rpc, start_tm = now, end_tm = now + skillConf.hold_tm * 100 }; return new cast_skill_res(game_err_code.RES_OK); } } if (pl.invisible > 0) { oldSkill.rmv_state_from_pl_by_att("invisible", caster); } caster.Set_Skill_CD(skill_id, now, now + skillConf.cd_tm * 100); cast_skill_res res = new cast_skill_res(game_err_code.RES_OK); res.rpc_data = new Dictionary<string, string>(); if (to_pos != null) { if (skill_level_conf.teleport != null) { pl.moving = null; pl.last_mvpts = null; Point2D t_point = Utility.valpoint_on_line(caster, to_pos, skill_level_conf.teleport.rang); if (skill_level_conf.teleport.tm <= 0) { caster.x = (int)t_point.x; caster.y = (int)t_point.y; } else { pl.teleping = new teleping() { dest_x = (int)t_point.x, dest_y = (int)t_point.y, end_tm = now + skill_level_conf.teleport.tm * 100, percent = 100, rpc = rpc, start_tm = now, telep = skill_level_conf.teleport }; } } else if (skill_level_conf.jump != null) { pl.moving = null; pl.last_mvpts = null; int sub_len = 0; if (target != null) sub_len = 45; Point2D dest_pos = Utility.valpoint_on_line(caster, to_pos, skill_level_conf.jump.rang, sub_len); double dist_x = dest_pos.x - caster.x; double dist_y = dest_pos.y - caster.y; double rang = Math.Sqrt(dist_x * dist_x + dist_y * dist_y); int jump_tm = (int)(rang * 1000 / skill_level_conf.jump.speed); if (jump_tm <= 0) jump_tm = 1; pl.jumping = new jumping() { dest_x = (int)dest_pos.x, dest_y = (int)dest_pos.y, during_tm = jump_tm, end_tm = now + jump_tm, start_tm = now, jump = skill_level_conf.jump, percent = 100, rpc = rpc, tar_iid = (target == null) ? 0 : target.iid, }; } } return res; }