private void OnFightStopReply(byte[] bytes) { FightStopReply input = FightStopReply.Parser.ParseFrom(bytes); if (input.ActorId != ActorId) { return; // 不是自己,略过 } if (!input.Ret) { GameRoomManager.Instance.Log($"ActorBehaviour OnFightStopReply Error - {input.ErrMsg}"); return; } // 每次攻击都要消耗行动点和弹药基数, 所以需要每一轮攻击都判断行动点和弹药基数是否足够 // 如果在战斗中才进行下次进攻的判定, 否则战斗结束 if (input.FightAgain && AmmoBase > 0 && CmdAttack.IsActionPointGranted()) { // 弹药基数足够, 可以再打一轮, 要用 [延迟攻击] 的状态, 时间也要把 [攻击持续时间] & [攻击间隔] 算在一起 StateMachine.TriggerTransition(StateEnum.DELAYFIGHT, 0, input.TargetId, AttackDuration + AttackInterval, AttackDuration + AttackInterval); long roomId = input.RoomId; long ownerId = input.OwnerId; long actorId = input.ActorId; int commandId = (int)CommandManager.CommandID.Attack; int actionPointCost = CommandManager.Instance.Commands[CommandManager.CommandID.Attack].ActionPointCost; CmdAttack.TryCommand(roomId, ownerId, actorId, commandId, actionPointCost); } else if (!input.IsEnemyDead && !IsCounterAttack) { // 我方战斗结束, 如果这时候敌人没死, (我不是处于反击状态), 敌人反击一次 var abTarget = GameRoomManager.Instance.RoomLogic.ActorManager.GetActor(input.TargetId); if (abTarget != null) { abTarget.IsCounterAttack = true; // 这是反击, 不是主动攻击, 记录在自己身上, Stop的时候用 // 反击的时候, 不需要行动点的允许, 直接就可以打 abTarget.IsCounterAttack = true; // 这是反击, 不是主动攻击, 记录在自己身上, Stop的时候用 abTarget.StateMachine.TriggerTransition(StateEnum.FIGHT, 0, input.ActorId, abTarget.AttackDuration); GameRoomManager.Instance.Log("ActorBehaviour OnFightStopReply - 敌人反击"); } } GameRoomManager.Instance.Log($"ActorBehaviour OnFightStopReply - Ammo:{AmmoBase}/{AmmoBaseMax}"); }
private void OnFightStopReply(byte[] bytes) { FightStopReply input = FightStopReply.Parser.ParseFrom(bytes); if (input.ActorId != ActorId) { return; // 不是自己,略过 } if (!input.Ret) { GameRoomManager.Instance.Log($"ActorVisualizer OnFightStopReply Error - {input.ErrMsg}"); return; } if (input.FightAgain) { // 显示自己的血条 ShowSliderBlood(); // 显示对方的血条 var avTarget = GameRoomManager.Instance.GetActorVisualizer(input.TargetId); if (!avTarget) { return; } avTarget.ShowSliderBlood(); } // 如果弹药没了, 提示"弹药已经用完", 提示玩家下次无法攻击了 if (AmmoBase <= 0) { string msg = "弹药已经用完!"; PanelSprayMessage spray = GameRoomManager.Instance.FightManager.SprayMessage.Spawn(_inner, Vector3.zero); if (spray == null) { return; } spray.Play(this, msg, PanelSystemTips.MessageType.Error); } GameRoomManager.Instance.Log("ActorVisualizer OnFightStopReply OK ..."); }
/// <summary> /// 注意,因为这条消息里有删除Actor的操作,所以不能放在ActorBehaviour里去响应,除非找到更好的方法.Nov.15.2019. Liu Gang. /// </summary> /// <param name="args"></param> /// <param name="bytes"></param> private void OnFightStop(SocketAsyncEventArgs args, byte[] bytes) { FightStop input = FightStop.Parser.ParseFrom(bytes); if (input.RoomId != RoomId) { return; // 不是自己房间的消息,略过 } ///////////////// // 1-攻击者 var attacker = ActorManager.GetActor(input.ActorId); if (attacker == null) { FightStopReply output = new FightStopReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, ActorId = input.ActorId, Ret = false, ErrMsg = "Attacker not found!", }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.FightStopReply, output.ToByteArray()); return; } // 2-防御者 var defender = ActorManager.GetActor(input.TargetId); if (defender == null) { FightStopReply output = new FightStopReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, ActorId = input.ActorId, Ret = false, ErrMsg = "Defender not found!", }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.FightStopReply, output.ToByteArray()); return; } // 3-计算弹药基数 bool isFightAgain = false; if (attacker.AmmoBase <= 0) { // 3.1-弹药基数不足, 无法攻击 attacker.AmmoBase = 0; FightStopReply output = new FightStopReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, ActorId = input.ActorId, Ret = false, ErrMsg = "弹药基数不足!", }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.FightStopReply, output.ToByteArray()); return; } else { attacker.AmmoBase--; // 弹药充足, 并且这不是反击的情况下, 允许攻击下一轮 if (attacker.AmmoBase > 0 && !input.IsCounterAttack) { isFightAgain = true; } } // 4-战斗计算 - 减法公式 int damage = (int)Mathf.FloorToInt(attacker.AttackPower - defender.DefencePower); if (input.IsCounterAttack) // 如果是反击,则仅计算60%的伤害 { damage = Mathf.FloorToInt(damage * 0.6f); } if (damage == 0) { damage = 1; } defender.Hp = defender.Hp - damage; // 5-如果已经死亡 bool isEnemyDead = false; if (defender.Hp <= 0) { defender.Hp = 0; isEnemyDead = true; isFightAgain = false; ServerRoomManager.Instance.Log($"RoomLogic OnFightStop 1 - {attacker.ActorId} killed {defender.ActorId}"); } ///////////////// {// 10-挨打者的血量, 群发, UpdateActorInfoReply output = new UpdateActorInfoReply() { RoomId = defender.RoomId, OwnerId = defender.OwnerId, ActorId = defender.ActorId, Hp = defender.Hp, AmmoBase = defender.AmmoBase, Ret = true, }; BroadcastMsg(ROOM_REPLY.UpdateActorInfoReply, output.ToByteArray()); } {// 11-攻击者的弹药基数, 群发, UpdateActorInfoReply output = new UpdateActorInfoReply() { RoomId = attacker.RoomId, OwnerId = attacker.OwnerId, ActorId = attacker.ActorId, Hp = attacker.Hp, AmmoBase = attacker.AmmoBase, Ret = true, }; BroadcastMsg(ROOM_REPLY.UpdateActorInfoReply, output.ToByteArray()); } {// 12-飙血, 群发 SprayBloodReply output = new SprayBloodReply() { RoomId = defender.RoomId, OwnerId = defender.OwnerId, ActorId = defender.ActorId, Damage = damage, Ret = true, }; BroadcastMsg(ROOM_REPLY.SprayBloodReply, output.ToByteArray()); ServerRoomManager.Instance.Log($"飙血 - {defender.ActorId}"); } ///////////////// {// 20-本次攻击结束 FightStopReply output = new FightStopReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, ActorId = input.ActorId, TargetId = input.TargetId, IsEnemyDead = isEnemyDead, FightAgain = isFightAgain, Ret = true, }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.FightStopReply, output.ToByteArray()); } if (isEnemyDead) {// 21-挨打者死了, 发送删除单位的消息 ActorRemoveReply output = new ActorRemoveReply() { RoomId = defender.RoomId, OwnerId = defender.OwnerId, ActorId = defender.ActorId, DieType = 1, Ret = true, }; ActorManager.RemoveActor(defender.ActorId); BroadcastMsg(ROOM_REPLY.ActorRemoveReply, output.ToByteArray()); ServerRoomManager.Instance.Log($"RoomLogic OnFightStop 2 - {attacker.ActorId} killed {defender.ActorId}"); } }