public FightBusiness(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players, string npcID, bool isEctype = false) : base(teamA, teamB, players) { m_npcID = npcID; m_isEctype = isEctype; foreach (var v in teamA) { if (v.FType == FighterType.Player) { m_playerCount++; m_totalPlayerLev += v.Level; } else { m_petCount++; m_totalPetLev += v.Level; } } foreach (var v in teamB) { m_totalApcLev += v.Level; } m_averagePetLev = m_totalPetLev / Math.Max(1, m_petCount); m_averagePlayerLev = m_totalPlayerLev / m_playerCount; m_averageApcLev = m_totalApcLev / teamB.Length; }
/// <summary> /// 技能攻击 /// </summary> /// <param name="fighter"></param> /// <param name="par"></param> /// <returns></returns> private bool AttackJiNeng(FightObject fighter, int level, GameConfig gc) { //伤害类型 物理0 魔法1 int injuryType = gc.Value.GetIntOrDefault("InjuryType"); List<ActionResult> results = SkillAttack(fighter, level, gc, injuryType); if (results.Count > 0) { FightAction action = fighter.Action; action.Result = results; int fightCount = action.FightCount; action.FightCount = FightAction.HasAction; m_actions.Add(action); //蓄力,第二次攻击.. SkillBuffer buff = fighter.FindBuffer(BufferType.XuLi); if (buff != null) { action = action.CopyNew(); action.FightCount = fightCount; fighter.Action = action; List<ActionResult> results2 = SkillAttack(fighter, level, gc, injuryType); if (results2.Count > 0) { action.Result = results2; action.FightCount = FightAction.HasAction; m_actions.Add(action); } } return true; } return false; }
public FightBusinessRobApc(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players, string npcID, bool isEctype, SceneApc apc, int subID, RobBusiness rob) : base(teamA, teamB, players, npcID, isEctype, apc, subID) { m_rob = rob; //m_rob = PartProxy.TryGetPart(Part.Rob) as RobBusiness; }
public FightSceneApc(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players, string npcID, bool isEctype, SceneApc apc, int subID) : base(teamA, teamB, players, npcID, isEctype) { m_apc = apc; m_subID = subID; }
/// <summary> /// 处理结果(PK) /// </summary> /// <param name="winTeam">获胜的一方</param> /// <param name="lostTeam">失败的一方</param> protected virtual void FightEnd(FightObject[] winTeam, FightObject[] lostTeam) { SendToTeam(winTeam, FightCommand.FightEndR, (int)FightResult.Win, null, null); SendToTeam(lostTeam, FightCommand.FightEndR, (int)FightResult.Lose, null, null); if (m_changeLife) { List<string> names = new List<string>(winTeam.Length); foreach (FightPlayer f in winTeam) { if (f.FType == FighterType.Player) { names.Add(f.Player.Name); if (f.Online) { //记录PK胜利次数 f.Player.FinishNote(FinishCommand.PKWin, new object[] { 1 }); } } } //记录死亡日志 foreach (FightPlayer f in lostTeam) { if (f.Online && f.FType == FighterType.Player) { LogVariant log = new LogVariant(ServerLogger.zoneid, Actiontype.PKLoss); log.Value["Killer"] = names; //对方(名字列表) log.Value["Scene"] = m_scene.ID; //场景ID log.Value["SceneName"] = m_scene.Name; //场景名字 f.Player.WriteLog(log); } } } }
public FightBusinessRob(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players) : base(teamA, teamB, players) { m_lost = 0; m_protectTime = 0; m_rob = PartProxy.TryGetPart(Part.Rob) as RobBusiness; }
/// <summary> /// 活动开始 /// </summary> /// <param name="teamA"></param> /// <param name="teamB"></param> /// <param name="players"></param> public FightBusinessPro(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players) : base(teamA, teamB, players) { m_lost = 0; m_protectTime = 0; m_pro = PartProxy.TryGetPart(Part.Pro) as ProBusiness; }
protected int m_protectTime = 300; //PK后的保护时间 #endregion Fields #region Constructors public FightBusinessPK(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players) : base(teamA, teamB, players) { m_changeLife = true; m_maxRound = 50; m_lost = 0.1; }
/// <summary> /// 处理成对的(技能+Buffer)对倍率的影响 /// a的感染+b的流血 /// a的蔓延+b的中毒 /// a的趁热+b的灼烧 /// a的劈石(碎石击/断岩击)+b的石化 /// a的崩裂(石锥/钟乳)+b的冰冻 /// a的淡定(冰刃箭/玄冰箭)+b的混乱 /// </summary> /// <param name="target">接受攻击者</param> /// <returns></returns> protected virtual double BufferAddAttack(FightObject target) { if (m_a.FixBuffer == null || m_a.FixBuffer.Count == 0) { return 0; } double p = 0; foreach (var buffer in m_a.FixBuffer) { GameConfig gc = buffer.Value.Item2; if (gc.SubType != SkillSub.AddAttack) continue; int level = buffer.Value.Item1; //受影响的BufferID(灼烧/石化/中毒/混乱/流血/冰冻) string id = gc.Value.GetStringOrDefault("BufferID"); if (target.ExistsBuffer(id)) { var d = gc.Value.GetVariantOrDefault(level.ToString()); if (d != null) { object bei; //AllAttack:double.所有攻击都可提升的伤害倍数 if (d.TryGetValue("AllAttack", out bei)) { p += Convert.ToDouble(bei); } else if ((m_a.Action.Parameter != null) && d.TryGetValue(m_a.Action.Parameter, out bei)) { p += Convert.ToDouble(bei); } } } } return p; }
private static void StartBuffer(FightObject fighter) { fighter.BufferResult.Clear(); for (int i = 0; i < fighter.Buffers.Count; i++) { SkillBuffer buff = fighter.Buffers[i]; buff.RemainingNumber--; if (buff.RemainingNumber <= 0) { fighter.Buffers.RemoveAt(i); i--; } string name = buff.ID; // 流血/中毒/灼烧 if (name == BufferType.LiuXue || name == BufferType.ZhongDu || name == BufferType.ZuoShao) { fighter.BufferResult.AddHP(name, -(int)(buff.V), 1); } // 母育/神谕/再生 else if (name == BufferType.MuYu || name == BufferType.ShengYu || name == BufferType.ZaiSheng) { int hp = fighter.TryHP(buff.V); fighter.BufferResult.AddHP(name, hp); } // 冥想 else if (name == BufferType.MingXiang) { int mp = fighter.TryMP(buff.V); fighter.BufferResult.AddMP(name, mp); } } fighter.BufferResult.HP = fighter.HP; fighter.BufferResult.MP = fighter.MP; }
/// <summary> /// 计算魔法攻击值 /// </summary> /// <returns></returns> protected override int GetGongJi(FightObject target) { double beiShu = 1; SkillBuffer buff = m_a.FindBuffer(BufferType.ShenTuo); if (buff != null) { beiShu += buff.V; } buff = m_a.FindBuffer(BufferType.XiSheng); if (buff != null) { //如提升自己75%的魔法攻击,但会多受到30%的物理伤害 //则保存为 75030(即前面的为提升..后面三位为多受的伤害) int d = Convert.ToInt32(buff.V); beiShu += (d / 1000) * 0.01; //beiShu += buff.V; } //目标有神龙. buff = target.FindBuffer(BufferType.ShengLong); if (buff != null) { beiShu -= buff.V; } return m_Par.GetGonJi(m_a.Life.MoFaGongJi * beiShu) + m_a.MG - target.MF; }
private List<ActionResult> SkillAttack(FightObject fighter, int level, GameConfig gc, int injuryType) { List<ActionResult> results = new List<ActionResult>(); AttackDamage attack; AttackParameter par = new AttackParameter(gc, level); if (injuryType == 0) { attack = new AttackPhysical(fighter, par); } else { attack = new AttackMagic(fighter, par); } TargetType targetType = (TargetType)gc.Value.GetIntOrDefault("TargetType"); if (targetType == TargetType.Single) { var targets = FilterTargets(fighter); if (targets.Count > 0) { ActionResult result = Attack(attack, targets[0]); results.Add(result); } } else { var targets = EnemyTargets(fighter, targetType, par); foreach (var v in targets) { ActionResult result2 = Attack(attack, v, targets); results.Add(result2); } } return results; }
public FightBusinessEctype(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players, TeamInstanceBusiness tb, EctypeApc apc) : base(teamA, teamB, players, apc.Apc.ID, true) { tb.Astate = ActionState.Fight; m_tb = tb; m_apc = apc; }
/// <summary> /// 攻击 /// </summary> /// <param name="target">接受攻击者</param> /// <returns></returns> public override ActionResult Attack(FightObject target) { ActionResult result = new ActionResult(target.ID); bool meingZhong = CheckMingZhong(target); if (meingZhong) { if (m_Par != null) { if (m_Par.Config.SubType == SkillSub.Attack) { m_Par.UseC = target.ExistsBuffer(m_Par.BufferID); } else { m_Par.UseC = false; } } //计算倍率.. double beiShu = CalculatedRate(target, result); // int gongJi = GetGongJi(target); double xiShou = GetXiShou(target); // 战斗公式 int w = (int)(gongJi * (1 - xiShou) * beiShu); w -= target.Life.KangShangHai; // B是否进行了防御 bool fangyu = CheckFangYu(target); if (fangyu) { result.ActionFlag |= ActionFlag.FangYu; //w = w * 6 / 10; w = w >> 1; //50% } WriteShangHai(result, target, w); bool fanji = CheckFanJi(target); if (fanji) { result.ActionFlag |= ActionFlag.FanJi; result.Value["FanJi"] = FanAttack(target); } ChangeShengMing(result, m_a, target); // 添加附带的Buffer. TryAddBuffer(result, target); return result; } else { //闪避 result.ActionFlag |= ActionFlag.ShanBi; } return result; }
/// <summary> /// 计算魔法吸收 /// </summary> /// <returns></returns> protected override double GetXiShou(FightObject target) { double xishou = target.Life.MoFaXiShou; SkillBuffer o = target.FindBuffer(BufferType.ShengLong); if (o != null) { xishou += o.V; } return Math.Min(0.8, xishou); }
/// <summary> /// 普通物理攻击 /// </summary> /// <param name="fighter"></param> /// <param name="index"></param> /// <returns></returns> private bool AttackWuLi(FightObject fighter) { //获取被攻击的对象.. var targets = FilterTargets(fighter); if (targets.Count > 0) { AttackPhysical attack = new AttackPhysical(fighter, null); ActionResult result = Attack(attack, targets[0]); fighter.Action.Result = new List<ActionResult>() { result }; fighter.Action.FightCount = FightAction.HasAction; m_actions.Add(fighter.Action); return true; } return false; }
protected override void FightEnd(FightObject[] winTeam, FightObject[] lostTeam) { base.FightEnd(winTeam, lostTeam); if (m_lost > 0) { foreach (FightPlayer f in lostTeam) { if (f.Online && f.FType == FighterType.Player) { f.Player.LostExperience(m_lost, FinanceType.PKLost); if (m_protectTime > 0 && winTeam == m_teamA) { f.Player.LastPK = DateTime.UtcNow.AddSeconds(m_protectTime); } //你被击败,损失了10%的角色经验 f.Player.Call(ClientCommand.SendActivtyR, "T05", TipManager.GetMessage(ClientReturn.FightBusinessPK1)); } } } //强制PK方取得胜利,添加红/黄名BUFF if (m_lost > 0 && winTeam == m_teamA) { int count = 0; foreach (FightPlayer f in lostTeam) { if (f.FType == FighterType.Player && (!f.Player.RedName)) { count++; } } if (count > 0) { foreach (FightPlayer f in winTeam) { if (f.Online && f.FType == FighterType.Player) { f.Player.SetPKKill(count); } } } } }
/// <summary> /// 逃跑 /// </summary> /// <param name="fighter"></param> /// <returns></returns> protected virtual void TaoPao(FightObject fighter) { FightPlayer f2 = fighter as FightPlayer; if (f2 != null) { if (f2.Player.Team != null && f2.Player.TeamJob == TeamJob.Member) { return; } } double m = fighter.Life.TaoPaoLv; if (fighter.Level <= 10 || NumberRandom.NextDouble() < m) { m_taoPao = true; m_fugitive = fighter; } fighter.Action.Value = new Variant(2); fighter.Action.Value["TaoPao"] = m_taoPao; fighter.Action.FightCount = FightAction.HasAction; m_actions.Add(fighter.Action); }
/// <summary> /// 攻击时计算单个目标 /// </summary> /// <param name="attack"></param> /// <param name="target"></param> /// <param name="targets">所有被攻击的对象</param> /// <returns></returns> private ActionResult Attack(AttackDamage attack, FightObject target, List<FightObject> targets = null) { //查找保护者.保护者成为群攻目标时不能进行保护 FightObject protecter; if (targets == null || targets.Count <= 1) { protecter = m_protecter.Find(x => x.IsLive && x.CanActive && x.Action.Target == target.ID); } else { protecter = m_protecter.Find(x => x.IsLive && x.CanActive && x.Action.Target == target.ID && (!targets.Contains(x))); } target.Protect = (protecter != null); ActionResult result = attack.Attack(target); if (protecter != null) { protecter.ProtectOther = true; ActionResult result2 = attack.Attack(protecter); result.Value["Protecter"] = result2; } return result; }
/// <summary> /// 过滤出所有可攻击的目标 /// </summary> /// <param name="fighter"></param> /// <param name="opponent">是对方还是自方.true:对方,false:友方</param> /// <returns>所有可攻击的目标(主目标保存在列表最前)</returns> protected List<FightObject> FilterTargets(FightObject fighter, bool opponent = true) { //真真/假假为teamA,真假/假真为teamB List<FightObject> live = (fighter.Team == m_teamA ^ opponent) ? m_teamA.Where(x => x.IsLive).ToList() : m_teamB.Where(x => x.IsLive).ToList(); if (live.Count == 0) { return live; } string targetID = fighter.Action.Target; int index = 0; if (live.Count > 1) { if (string.IsNullOrEmpty(targetID)) { index = NumberRandom.Next(live.Count); } else { index = live.FindIndex(x => x.ID == targetID); if (index < 0) { index = NumberRandom.Next(live.Count); } } } //主目标移动到最前 if (index > 0) { FightObject target = live[0]; live[0] = live[index]; live[index] = target; } fighter.Action.Target = live[0].ID; return live; }
/// <summary> /// 生成所有敌方对象.. /// </summary> /// <param name="fighter"></param> /// <param name="targetType"></param> /// <param name="addTargets"></param> /// <returns></returns> protected List<FightObject> EnemyTargets(FightObject fighter, TargetType targetType, AttackParameter par) { List<FightObject> targets = FilterTargets(fighter); if (targets.Count <= 1 || targetType == TargetType.All) { return targets; } //横向目标(先移除与主目标不在同一排的) if (targetType == TargetType.HorizontalAll || targetType == TargetType.HorizontalRandom) { //targets[0]处为主攻目标,位置编号从0开始,小于等于4的为第1列.大于4的为第2列. if (targets[0].P > 4) { targets.RemoveAll(x => x.P <= 4); } else { targets.RemoveAll(x => x.P > 4); } } //随机目标(随机移除多余目标) if (targetType == TargetType.Random || targetType == TargetType.HorizontalRandom) { //附加目标数量:-1时,表示所有活的; int addTargets = par.LevelConfig.GetIntOrDefault("AddTargets"); if (addTargets++ > 0) { while (targets.Count > addTargets) { int index = NumberRandom.Next(1, targets.Count); targets.RemoveAt(index); } } } return targets; }
/// <summary> /// 免死的技能(修身) /// </summary> /// <param name="fighter"></param> /// <param name="level"></param> /// <param name="gc"></param> private bool SkillNoDeath(FightObject fighter, int level, GameConfig gc) { TargetType targetType = (TargetType)gc.Value.GetIntOrDefault("TargetType"); AttackParameter par = new AttackParameter(gc, level); var targets = FriendTargets(fighter, targetType, par); if (targets.Count == 0) return false; var config = par.LevelConfig; if (config == null) return false; double a = config.GetDoubleOrDefault("A"); int r = config.GetIntOrDefault("Round"); if (r <= 0) return false; List<ActionResult> results = new List<ActionResult>(); foreach (var target in targets) { ActionResult result = new ActionResult(target.ID); SkillBuffer buf = new SkillBuffer(gc.Name, fighter.ID, level, r, gc.Value, a); target.AddBuffer(buf); result.ActionFlag |= ActionFlag.AddBuff; result.Value["AddBuffer"] = buf; results.Add(result); } fighter.Action.Result = results; fighter.Action.FightCount = FightAction.HasAction; m_actions.Add(fighter.Action); return true; }
/// <summary> /// 创建招式(AI部分) /// </summary> /// <param name="myTeam"></param> /// <param name="?"></param> /// <param name="?"></param> /// <param name="fightCount"></param> /// <returns></returns> public override void CreateAction(FightObject[] targetTeam, int fightCount) { if (m_ai != null && m_ai.Count > 0) { try { foreach (Variant ai in m_ai) { //出招概率 double p = ai.GetDoubleOrDefault("P"); if (Sinan.Extensions.NumberRandom.RandomHit(p)) { //Target 1 自己 2 队友n 3 敌人n int checkTarget = ai.GetIntOrDefault("CheckTarget"); int n = ai.GetIntOrDefault("AddTargets"); Variant condition = ai.GetVariantOrDefault("Condition"); if (checkTarget <= 1) //检查自己 { if (checkCondition(this, condition, fightCount)) { //生成招式. CreateAction(targetTeam, ai, fightCount); return; } } else if (checkTarget == 2) { int count = 0; foreach (var f in Team) { if (checkCondition(f, condition, fightCount)) { count++; } } if (count >= n) { //生成招式. CreateAction(targetTeam, ai, fightCount); return; } } else if (checkTarget == 3) { int count = 0; foreach (var f in targetTeam) { if (checkCondition(f, condition, fightCount)) { count++; } } if (count >= n) { //生成招式. CreateAction(targetTeam, ai, fightCount); return; } } } } } catch (System.Exception ex) { LogWrapper.Warn("AI error:" + m_apc.ID, ex); } } base.CreateAction(targetTeam, fightCount); }
private void CreateAction(FightObject[] targetTeam, Variant v, int fightCount) { int actionType = v.GetIntOrDefault("ActionType"); FightAction action = new FightAction((ActionType)actionType, this.ID, 0); action.Parameter = v.GetStringOrDefault("Parameter"); action.SkillLev = v.GetIntOrDefault("Level", 1); //Target 1 自己 //Target 2 队友n //Target 3 敌人n //Target 4 随机友方(n) //Target 5 随机敌人(n) //Target 6 血量最少的敌人(n) int actionTarget = v.GetIntOrDefault("ActionTarget"); if (actionTarget <= 1) { action.Target = this.ID; } else if (actionTarget == 4 || actionTarget == 2) { int index = Sinan.Extensions.NumberRandom.Next(Team.Length); action.Target = Team[index].ID; } else if (actionTarget == 5 || actionTarget == 3) { int index = Sinan.Extensions.NumberRandom.Next(targetTeam.Length); action.Target = targetTeam[index].ID; } else if (actionTarget == 6) { int min = Int32.MaxValue; foreach (var target in targetTeam) { if (target.HP > 0 && target.HP < min) { action.Target = target.ID; } } } else { action.Target = string.Empty; } action.Say = NewTalk(v.GetVariantOrDefault("Talk")); action.FightCount = fightCount; this.m_action = action; }
/// <summary> /// 检查对象是否满足条件 /// </summary> /// <param name="f"></param> /// <param name="condition"></param> /// <returns></returns> static bool checkCondition(FightObject f, Variant condition, int round) { Variant caseHp = condition.GetVariantOrDefault("CaseHP"); Variant caseMp = condition.GetVariantOrDefault("CaseMP"); IList caseBuff = condition.GetValueOrDefault<IList>("CaseBuff"); IList caseRound = condition.GetValueOrDefault<IList>("CaseRound"); if (caseHp != null) { double a = caseHp.GetDoubleOrDefault("A"); double b = caseHp.GetDoubleOrDefault("B"); if (a > 0 && a < 1) //百分比 { double test = (f.HP * 1.0) / f.Life.ShengMing; if (test <= a || test > b) { return false; } } else { if (f.HP <= a || f.HP > b) { return false; } } } if (caseMp != null) { double a = caseMp.GetDoubleOrDefault("A"); double b = caseMp.GetDoubleOrDefault("B"); if (a > 0 && a < 1) //百分比 { double test = (f.MP * 1.0) / f.Life.MoFa; if (test <= a || test > b) { return false; } } else { if (f.MP <= a || f.MP > b) { return false; } } } if (caseBuff != null) { bool find = false; foreach (var b in f.Buffers) { if (caseBuff.Contains(b.ID)) { find = true; break; } } if (!find) return false; } if (caseRound != null && caseRound.Count > 0) { return caseRound.Contains(round); } return true; }
public virtual void CreateAction(FightObject[] targetTeam, int fightCount) { if (m_action == null || m_action.FightCount != fightCount) { FightAction action = new FightAction(ActionType.WuLi, ID, fightCount); action.Target = targetTeam[Sinan.Extensions.NumberRandom.Next(targetTeam.Length)].ID; this.m_action = action; } }
public FightBusinessProApc(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players, string npcID, bool isEctype, SceneApc apc, int subID, PartBusiness pro) : base(teamA, teamB, players, npcID, isEctype, apc, subID) { m_rb = pro; }
/// <summary> /// 复活的技能(回生) /// </summary> /// <param name="fighter"></param> /// <param name="level"></param> /// <param name="gc"></param> private bool SkillRevive(FightObject fighter, int level, GameConfig gc) { TargetType targetType = (TargetType)gc.Value.GetIntOrDefault("TargetType"); List<FightObject> targets = null; if (targetType == TargetType.TeamAll) { targets = fighter.Team.Where(x => x.HP == 0).ToList(); } else { FightObject t; if (fighter.FType == FighterType.Pet || fighter.FType == FighterType.Player) { string targetID = fighter.Action.Target; t = fighter.Team.FirstOrDefault(x => x.ID == targetID); } else { t = fighter.Team.FirstOrDefault(x => x.HP == 0); } if (t != null && t.HP == 0) { targets = new List<FightObject>(1); targets.Add(t); } } if (targets == null || targets.Count == 0) { return false; } var results = new List<ActionResult>(targets.Count); foreach (FightObject target in targets) { var config = gc.Value.GetVariantOrDefault(level.ToString()); if (config == null) return false; double a = config.GetDoubleOrDefault("A"); double b = config.GetDoubleOrDefault("B"); ActionResult result = new ActionResult(target.ID); result.ActionFlag |= ActionFlag.Supply; int hp = target.TryHP(a); int mp = target.TryMP(b); target.AddHPAndMP(hp, mp); result.Value["HP"] = hp; result.Value["MP"] = mp; result.Value["ShengMing"] = new MVPair(target.Life.ShengMing, target.HP); result.Value["MoFa"] = new MVPair(target.Life.MoFa, target.MP); results.Add(result); } fighter.Action.Result = results; fighter.Action.FightCount = FightAction.HasAction; m_actions.Add(fighter.Action); return true; }
public FightBusinessCC(FightObject[] teamA, FightObject[] teamB, List<PlayerBusiness> players) : base(teamA, teamB, players) { m_changeLife = false; m_maxRound = 200; }
/// <summary> /// 增加攻击次数(蓄力) /// </summary> /// <param name="fighter"></param> /// <param name="level"></param> /// <param name="gc"></param> private bool SkillXuli(FightObject fighter, int level, GameConfig gc) { var config = gc.Value.GetVariantOrDefault(level.ToString()); if (config == null) return false; int r = config.GetIntOrDefault("Round"); SkillBuffer buf = new SkillBuffer(gc.Name, fighter.ID, level, r + 1, gc.Value); fighter.AddBuffer(buf); fighter.Action.Value = new Variant(); ActionResult result = new ActionResult(fighter.ID); result.ActionFlag |= ActionFlag.AddBuff; result.Value["AddBuffer"] = buf; fighter.Action.Result = new List<ActionResult>() { result }; fighter.Action.FightCount = FightAction.HasAction; m_actions.Add(fighter.Action); return true; }