예제 #1
0
        /// <inheritdoc/>
        public void HandlePacket(Player player, Span <byte> packet)
        {
            if (packet.Length < 7)
            {
                return;
            }

            using var loggerScope = player.Logger.BeginScope(this.GetType());
            HitRequest message    = packet;
            var        currentMap = player.CurrentMap;

            if (currentMap == null)
            {
                player.Logger.LogWarning($"Current player map not set. Possible hacker action. Character name: {player.Name}");
                return;
            }

            var target = currentMap.GetObject(message.TargetId) as IAttackable;

            if (target == null)
            {
                player.Logger.LogWarning($"Object {message.TargetId} of current player map not found alive. Possible hacker action. Character name: {player.Name}");
            }
            else
            {
                this.hitAction.Hit(player, target, message.AttackAnimation, message.LookingDirection.ParseAsDirection());
            }
        }
예제 #2
0
        /// <summary>
        ///     檢查資料合法性
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private bool _CheckDataLegality(HitRequest request)
        {
            if (request.FishDatas.Any(x => x.FishOdds <= 0))
            {
                _OnHitExceptionEvent.Invoke("FishData.Odds 不可為0");
                Singleton <Log> .Instance.WriteInfo("FishData.Odds 不可為0");

                return(false);
            }

            if (request.FishDatas.Any(x => x.FishStatus < FISH_STATUS.NORMAL || x.FishStatus > FISH_STATUS.FREEZE))
            {
                _OnHitExceptionEvent.Invoke("FishData.FishStatus 無此狀態");
                Singleton <Log> .Instance.WriteInfo("FishData.FishStatus 無此狀態");

                return(false);
            }

            if (request.WeaponData.TotalHits <= 0)
            {
                _OnHitExceptionEvent.Invoke("WeaponData.TotalHitOdds 不可為0");
                Singleton <Log> .Instance.WriteInfo("WeaponData.TotalHitOdds 不可為0");

                return(false);
            }

            if (request.WeaponData.WeaponType < WEAPON_TYPE.NORMAL || request.WeaponData.WeaponType > WEAPON_TYPE.FREEZE_BOMB)
            {
                _OnHitExceptionEvent.Invoke("WeaponData.WeaponType,無此編號");
                Singleton <Log> .Instance.WriteInfo("WeaponData.WeaponType,無此編號");

                return(false);
            }

            if (request.WeaponData.WeaponBet <= 0 || request.WeaponData.WeaponBet > 1000)
            {
                _OnHitExceptionEvent.Invoke("WeaponData.WeaponBet,押注分數錯誤");
                Singleton <Log> .Instance.WriteInfo("WeaponData.WeaponBet,押注分數錯誤");

                return(false);
            }

            if (request.WeaponData.WeaponOdds != 1)
            {
                _OnHitExceptionEvent.Invoke("WeaponData.OddsResult,目前只能為1");
                Singleton <Log> .Instance.WriteInfo("WeaponData.OddsResult,目前只能為1");

                return(false);
            }

            if (request.WeaponData.TotalHits != request.FishDatas.Length)
            {
                _OnHitExceptionEvent.Invoke("WeaponData.TotalHits,擊中數量不符");
                Singleton <Log> .Instance.WriteInfo("WeaponData.TotalHits,擊中數量不符");

                return(false);
            }

            return(true);
        }
예제 #3
0
        public static FarmBuffer.BUFFER_BLOCK GetBlock(HitRequest request, int max_bet)
        {
            var bet = request.WeaponData.GetTotalBet();

            if (bet >= ((750 * max_bet) / 1000))
            {
                return(FarmBuffer.BUFFER_BLOCK.BLOCK_5);
            }

            if (bet >= ((500 * max_bet) / 1000))
            {
                return(FarmBuffer.BUFFER_BLOCK.BLOCK_4);
            }

            if (bet >= ((250 * max_bet) / 1000))
            {
                return(FarmBuffer.BUFFER_BLOCK.BLOCK_3);
            }

            if (bet >= ((100 * max_bet) / 1000))
            {
                return(FarmBuffer.BUFFER_BLOCK.BLOCK_2);
            }

            return(FarmBuffer.BUFFER_BLOCK.BLOCK_1);
        }
예제 #4
0
        private string _MakeRequestLog(HitRequest request)
        {
            var weapon = request.WeaponData;

            string weaponDataLog =
                string.Format("WeaponData\r\n{0,-7}{1,-32}{2,-7}{3,-7}{4,-7}\r\n{5,-7}{6,-7}{7,-7}{8,-7}{9,-7}\r\n"
                              , "Bullet", "WeaponType", "Bet", "Odds", "Hits"
                              , weapon.BulletId, weapon.WeaponType, weapon.WeaponBet, weapon.WeaponOdds, weapon.TotalHits);

            var fishTitle = string.Format(
                "FishData\r\n{0,-7}{1,-32}{2,-32}{3,-7}\r\n",
                "Id",
                "FishType",
                "FishStatus",
                "Odds");

            var fishs = request.FishDatas;

            return(weaponDataLog + fishTitle
                   + string.Join(
                       "\r\n",
                       fishs.Select(
                           fish_data =>
                           string.Format(
                               "{0,-7}{1,-32}{2,-32}{3,-7}",
                               fish_data.FishId,
                               fish_data.FishType,
                               fish_data.FishStatus,
                               fish_data.FishOdds)).ToArray()));
        }
        protected override Task Handle(FillHitRequestEvent e, CancellationToken cancellation)
        {
            HitRequest hitRequest = e.HitRequest;

            hitRequest.Damages = _algorithm.GenerateDamage(hitRequest);
            return(Task.CompletedTask);
        }
예제 #6
0
        void IFishStage.Hit(HitRequest request)
        {
            var responses = _Formula.TotalRequest(request);

            _OnTotalHitResponseEvent.Invoke(responses);

            _MakeLog(request, responses);
        }
예제 #7
0
        private void _MakeLog(HitRequest request, IEnumerable <HitResponse> responses)
        {
            const string formats = "PlayerVisitor:{0}\tStage:{1}\r\n<Request>\r\n{2}\r\n<Response>\r\n{3}";

            var log = string.Format(
                formats,
                _AccountId,
                _FishFarmData.FarmId,
                _MakeRequestLog(request),
                _MakeResponesLog(responses));

            Singleton <Log> .Instance.WriteInfo(log);
        }
예제 #8
0
        private void _MakeLog(HitRequest request, HitResponse[] responses)
        {
            var format = "PlayerVisitor:{0}\tStage:{1}\nRequest:{2}\nResponse:{3}";

            var log = string.Format(
                format,
                _AccountId,
                _FishStage,
                request.ShowMembers(" "),
                responses.ShowMembers(" "));

            Singleton <Log> .Instance.WriteInfo(log);
        }
예제 #9
0
        /// <summary>
        ///     魚王倍數 = 所有同種類魚的 total odds
        /// </summary>
        /// <param name="request"></param>
        private void _SetFishKingOdds(HitRequest request)
        {
            var fishKings = request.FishDatas.Where(x => x.FishStatus == FISH_STATUS.KING).ToArray();

            if (!fishKings.Any())
            {
                return;
            }

            foreach (var king in fishKings)
            {
                var smallFishs = request.FishDatas.Where(x => x.FishStatus != FISH_STATUS.KING && x.FishType == king.FishType);

                king.FishOdds += smallFishs.Sum(x => x.FishOdds);
            }
        }
예제 #10
0
 void IFishStage.Hit(HitRequest request)
 {
     _OnTotalHitResponseEvent(
         request.FishDatas.Select(
             requset_fish_data => new HitResponse
     {
         DieResult =
             Random.Instance.NextInt(1, 4) == 1 ? FISH_DETERMINATION.DEATH : FISH_DETERMINATION.SURVIVAL,
         FishId          = requset_fish_data.FishId,
         WepId           = request.WeaponData.BulletId,
         FeedbackWeapons = new[]
         {
             WEAPON_TYPE.INVALID
         }
     }).ToArray());
 }
예제 #11
0
        void IFishStage.Hit(HitRequest request)
        {
            if (!_CheckDataLegality(request))
            {
                return;
            }

            _SetFishKingOdds(request);

            var totalRequest = new ZsHitChecker(_FishFarmData, _FormulaPlayerRecord, _CreateRandoms()).TotalRequest(request);

            _FormulaFarmRecorder.Save(_FishFarmData);
            _FormulaPlayerRecorder.Save(_FormulaPlayerRecord);

            _OnTotalHitResponseEvent.Invoke(totalRequest);

            _MakeLog(request, totalRequest);
        }
예제 #12
0
 public static SuPacket GenerateSuPacket(this IBattleEntity entity, HitRequest hit, ushort damages) =>
 new SuPacket
 {
     VisualType        = entity.Type,
     VisualId          = entity.Id,
     HitMode           = hit.HitMode,
     Damage            = damages,
     HpPercentage      = entity.HpPercentage, // factorise this code with extension
     PositionX         = entity.Position.X,
     PositionY         = entity.Position.X,
     TargetIsAlive     = hit.Target.IsAlive,
     AttackAnimation   = hit.UsedSkill.AttackAnimation,
     SkillCooldown     = hit.UsedSkill.Cooldown,
     SkillEffect       = hit.UsedSkill.Effect,
     SkillVnum         = hit.UsedSkill.Id,
     SkillTypeMinusOne = hit.UsedSkill.SkillType - 1,
     TargetVisualType  = hit.Target.Type,
     TargetId          = hit.Target.Id
 };
예제 #13
0
        /// <inheritdoc/>
        public void HandlePacket(Player player, Span <byte> packet)
        {
            if (packet.Length < 7)
            {
                return;
            }

            using var loggerScope = player.Logger.BeginScope(this.GetType());
            HitRequest message    = packet;
            var        currentMap = player.CurrentMap;

            if (currentMap is null)
            {
                player.Logger.LogWarning($"Current player map not set. Possible hacker action. Character name: {player.Name}");
                return;
            }

            if (currentMap.GetObject(message.TargetId) is not IAttackable target)
            {
                player.Logger.LogWarning($"Object {message.TargetId} of current player map not found alive. Possible hacker action. Character name: {player.Name}");
            }
예제 #14
0
        public override HitResponse[] TotalRequest(HitRequest request)
        {
            var block = CalculationBufferBlock.GetBlock(request, _DataVisitor.Farm.MaxBet);

            _DataVisitor.FocusBufferBlock = block;

            // 只有第一發才能累積buffer
            if (request.WeaponData.WeaponType == WEAPON_TYPE.NORMAL && request.WeaponData.TotalHits == 1)
            {
                new AccumulationBufferRule(_DataVisitor, request).Run();

                new ApproachBaseOddsRule(_DataVisitor).Run();

                new AdjustmentAverageRule(_DataVisitor, request).Run();
            }

            new AdjustmentGameLevelRule(_DataVisitor).Run();

            new AdjustmentPlayerPhaseRule(_DataVisitor).Run();

            return(new DeathRule(_DataVisitor, request).Run());
        }
예제 #15
0
 /// <summary>
 ///     Use this extension only if your damages are lower than
 ///     <value>65535</value>
 ///     (ushort limit)
 /// </summary>
 /// <param name="entity"></param>
 /// <param name="hit"></param>
 /// <returns></returns>
 public static SuPacket GenerateSuPacket(this IBattleEntity entity, HitRequest hit) => GenerateSuPacket(entity, hit, (ushort)hit.Damages);
 public AdjustmentAverageRule(DataVisitor fish_visitor, HitRequest hit_request)
 {
     _DataVisitor = fish_visitor;
     _HitRequest  = hit_request;
 }
예제 #17
0
        /// <summary>
        /// Handle any kind of Monster interaction
        /// </summary>
        internal void MonsterLife()
        {
            if (Monster == null)
            {
                return;
            }
            // handle hit queue
            HitRequest hitRequest = null;

            while (HitQueue.TryDequeue(out hitRequest))
            {
                if (IsAlive)
                {
                    int hitmode = 0;

                    // calculate damage
                    int damage = hitRequest.Session.Character.GenerateDamage(this, hitRequest.Skill, ref hitmode);

                    switch (hitRequest.TargetHitType)
                    {
                    case Domain.TargetHitType.SingleTargetHit:
                    {
                        // Target Hit
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {(hitRequest.SkillEffect)} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)(((float)CurrentHp / (float)Monster.MaxHP) * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case Domain.TargetHitType.SingleTargetHitCombo:
                    {
                        // Taget Hit Combo
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.SkillCombo.Animation} {hitRequest.SkillCombo.Effect} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)(((float)CurrentHp / (float)Monster.MaxHP) * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case Domain.TargetHitType.SingleAOETargetHit:
                    {
                        // Target Hit Single AOE
                        switch (hitmode)
                        {
                        case 1:
                            hitmode = 4;
                            break;

                        case 3:
                            hitmode = 6;
                            break;

                        default:
                            hitmode = 5;
                            break;
                        }
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {(hitRequest.SkillEffect)} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)(((float)CurrentHp / (float)Monster.MaxHP) * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case Domain.TargetHitType.AOETargetHit:
                    {
                        // Target Hit AOE
                        switch (hitmode)
                        {
                        case 1:
                            hitmode = 4;
                            break;

                        case 3:
                            hitmode = 6;
                            break;

                        default:
                            hitmode = 5;
                            break;
                        }
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {(hitRequest.SkillEffect)} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)(((float)CurrentHp / (float)Monster.MaxHP) * 100)} {damage} {hitmode} {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case Domain.TargetHitType.ZoneHit:
                    {
                        // Zone HIT
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} {hitRequest.MapX} {hitRequest.MapY} {(IsAlive ? 1 : 0)} {(int)(((float)CurrentHp / (float)Monster.MaxHP) * 100)} {damage} 5 {hitRequest.Skill.SkillType - 1}");
                        break;
                    }

                    case Domain.TargetHitType.SpecialZoneHit:
                    {
                        // Special Zone hit
                        Map?.Broadcast($"su 1 {hitRequest.Session.Character.CharacterId} 3 {MapMonsterId} {hitRequest.Skill.SkillVNum} {hitRequest.Skill.Cooldown} {hitRequest.Skill.AttackAnimation} {hitRequest.SkillEffect} {hitRequest.Session.Character.MapX} {hitRequest.Session.Character.MapY} {(IsAlive ? 1 : 0)} {(int)(((float)CurrentHp / (float)Monster.MaxHP) * 100)} {damage} 0 {hitRequest.Skill.SkillType - 1}");
                        break;
                    }
                    }

                    // generate the kill bonus
                    hitRequest.Session.Character.GenerateKillBonus(this);
                }
                else
                {
                    // monster already has been killed, send cancel
                    hitRequest.Session.SendPacket($"cancel 2 {MapMonsterId}");
                }
            }

            // Respawn
            if (!IsAlive && ShouldRespawn.Value)
            {
                double timeDeath = (DateTime.Now - Death).TotalSeconds;
                if (timeDeath >= Monster.RespawnTime / 10)
                {
                    Respawn();
                }
                return;
            }
            // normal movement
            else if (Target == -1)
            {
                Move();
                return;
            }
            // target following
            else
            {
                ClientSession targetSession = Map.GetSessionByCharacterId(Target);

                // remove target in some situations
                if (targetSession == null || targetSession.Character.Invisible || targetSession.Character.Hp <= 0)
                {
                    RemoveTarget();
                    return;
                }

                NpcMonsterSkill npcMonsterSkill = null;
                if (_random.Next(10) > 8 && Skills != null)
                {
                    npcMonsterSkill = Skills.Where(s => (DateTime.Now - s.LastSkillUse).TotalMilliseconds >= 100 * s.Skill.Cooldown).OrderBy(rnd => _random.Next()).FirstOrDefault();
                }

                // check if target is in range
                if (targetSession != null && !targetSession.Character.InvisibleGm && !targetSession.Character.Invisible && targetSession.Character.Hp > 0 &&
                    ((npcMonsterSkill != null && CurrentMp >= npcMonsterSkill.Skill.MpCost &&
                      Map.GetDistance(new MapCell()
                {
                    X = this.MapX, Y = this.MapY
                },
                                      new MapCell()
                {
                    X = targetSession.Character.MapX, Y = targetSession.Character.MapY
                }) < npcMonsterSkill.Skill.Range) ||
                     (Map.GetDistance(new MapCell()
                {
                    X = this.MapX, Y = this.MapY
                },
                                      new MapCell()
                {
                    X = targetSession.Character.MapX, Y = targetSession.Character.MapY
                }) <= Monster.BasicRange)))
                {
                    TargetHit(targetSession, npcMonsterSkill);
                }
                else
                {
                    if (targetSession != null)
                    {
                        FollowTarget(targetSession);
                    }
                }
            }
        }
예제 #18
0
        public override HitResponse[] TotalRequest(HitRequest request)
        {
            var hitResponses = new List <HitResponse>();

            foreach (var fishData in request.FishDatas)
            {
                const int   MAX_WEPBET    = 10000;
                const int   MAX_WEPODDS   = 10000;
                const short MAX_TOTALHITS = 1000;
                const short MAX_FISHODDS  = 1000;
                const long  gateOffset    = 0x0fffffff;

                if (request.WeaponData.WeaponBet > MAX_WEPBET)
                {
                    hitResponses.Add(HitTest._Miss(fishData, request.WeaponData));
                    continue;
                }

                if (request.WeaponData.WeaponOdds > MAX_WEPODDS)
                {
                    hitResponses.Add(HitTest._Miss(fishData, request.WeaponData));
                    continue;
                }

                if (request.WeaponData.TotalHits == 0 || request.WeaponData.TotalHits > MAX_TOTALHITS)
                {
                    hitResponses.Add(HitTest._Miss(fishData, request.WeaponData));
                    continue;
                }

                if (fishData.FishOdds == 0 || fishData.FishOdds > MAX_FISHODDS)
                {
                    hitResponses.Add(HitTest._Miss(fishData, request.WeaponData));
                }
                else
                {
                    long gate = 1000;
                    gate *= gateOffset;
                    gate *= request.WeaponData.WeaponBet;
                    gate /= request.WeaponData.TotalHits;
                    gate /= fishData.FishOdds;
                    gate /= 1000;

                    if (gate > 0x0fffffff)
                    {
                        gate = 0x10000000;
                    }

                    var rValue = _Random.NextLong(0, long.MaxValue);

                    var value = rValue % 0x10000000;

                    if (value < gate)
                    {
                        hitResponses.Add(_Die(fishData, request.WeaponData));
                    }
                    else
                    {
                        hitResponses.Add(HitTest._Miss(fishData, request.WeaponData));
                    }
                }
            }

            return(hitResponses.ToArray());
        }
예제 #19
0
        protected override async Task Handle(UseSkillEvent e, CancellationToken cancellation)
        {
            if (!(e.Sender is IBattleEntity entity))
            {
                return;
            }

            IBattleEntity target = e.Target;
            SkillDto      skill  = e.Skill;

            if (!(entity is IPlayerEntity player))
            {
                player = null;
            }

            if (e.Skill.MpCost > entity.Mp) //TODO: others check
            {
                if (!(player is null))
                {
                    await player.SendPacketAsync(target.GenerateTargetCancelPacket(CancelPacketType.InCombatMode));
                }

                return;
            }

            List <IBattleEntity> targets = new List <IBattleEntity>();

            switch ((SkillTargetType)skill.TargetType)
            {
            case SkillTargetType.SingleHit:
            case SkillTargetType.SingleBuff when skill.HitType == 0:
                // if too much distance, send cancel packet
                if (entity.GetDistance(target) > skill.Range + target.BasicArea + 1)
                {
                    if (!(player is null))
                    {
                        await player.SendPacketAsync(target.GenerateTargetCancelPacket(CancelPacketType.InCombatMode));
                    }

                    return;
                }

                if (entity.Type == VisualType.Character && target.Type == VisualType.Character && !entity.CurrentMap.IsPvpEnabled && skill.HitType != 1)
                {
                    if (!(player is null))
                    {
                        await player.SendPacketAsync(target.GenerateTargetCancelPacket(CancelPacketType.InCombatMode));
                    }

                    return;
                }

                targets.Add(target);
                break;

            case SkillTargetType.AOE when skill.HitType == 1:     // Target Hit
                if (skill.TargetRange == 0)
                {
                    targets.Add(target);
                    goto default;
                }

                targets.Add(target);
                break;

            case SkillTargetType.AOE when skill.HitType != 1:     // Buff
                switch (skill.HitType)
                {
                case 0:
                case 4:         // Apply Buff on himself
                    targets.Add(target);


                    break;

                case 2:         // Apply Buff in range
                    if (skill.TargetRange == 0)
                    {
                        if (!(player is null))
                        {
                            await player.SendPacketAsync(target.GenerateTargetCancelPacket(CancelPacketType.InCombatMode));
                        }

                        return;
                    }

                    // apply buff on each entities of type
                    break;
                }

                break;

            default:
                if (!(player is null))
                {
                    await player.SendPacketAsync(target.GenerateTargetCancelPacket(CancelPacketType.InCombatMode));
                }
                targets.Add(target);

                return;
            }

            await entity.CurrentMap.BroadcastAsync(entity.GenerateCtPacket(e.Target, e.Skill));

            await entity.DecreaseMp(e.Skill.MpCost);

            //TODO: Skill Cooldown

            foreach (IBattleEntity t in targets)
            {
                HitRequest hitRequest = await _hitRequestFactory.CreateHitRequest(entity, t, e.Skill);

                await entity.EmitEventAsync(new FillHitRequestEvent
                {
                    HitRequest = hitRequest,
                });

                await entity.EmitEventAsync(new ProcessHitRequestEvent
                {
                    HitRequest = hitRequest
                });
            }
        }
예제 #20
0
 public DeathRule(DataVisitor visitor, HitRequest request)
 {
     _Visitor      = visitor;
     _Request      = request;
     _HitResponses = new List <HitResponse>();
 }
        protected override async Task Handle(ProcessHitRequestEvent e, CancellationToken cancellation)
        {
            HitRequest    hitRequest   = e.HitRequest;
            IBattleEntity target       = hitRequest.Target;
            uint          givenDamages = 0;
            await Task.Delay(hitRequest.UsedSkill.CastTime * 100, cancellation);

            List <SuPacket> packets = new List <SuPacket>();

            while (givenDamages != hitRequest.Damages && target.IsAlive)
            {
                ushort nextDamages = hitRequest.Damages - givenDamages > ushort.MaxValue ? ushort.MaxValue : (ushort)(hitRequest.Damages - givenDamages);
                givenDamages += nextDamages;
                if (target.Hp - nextDamages <= 0)
                {
                    target.Hp = 0;
                    switch (target) // send death event
                    {
                    case IPlayerEntity player:
                        await player.EmitEventAsync(new PlayerDeathEvent { Killer = hitRequest.Sender });

                        break;

                    case IMonsterEntity monster:
                        await monster.EmitEventAsync(new MonsterDeathEvent { Killer = hitRequest.Sender });

                        break;

                    case INpcEntity npc:
                        await npc.EmitEventAsync(new NpcDeathEvent { Killer = hitRequest.Sender });

                        break;
                    }

                    packets.Add(hitRequest.Sender.GenerateSuPacket(hitRequest, nextDamages));
                    break;
                }

                target.Hp -= nextDamages;
                packets.Add(hitRequest.Sender.GenerateSuPacket(hitRequest, nextDamages));
            }

            if (!packets.Any())
            {
                packets.Add(hitRequest.Sender.GenerateSuPacket(hitRequest, 0));
            }

            await hitRequest.Sender.CurrentMap.BroadcastAsync(hitRequest.Sender.GenerateEffectPacket(hitRequest.UsedSkill.CastEffect));

            await hitRequest.Sender.CurrentMap.BroadcastAsync <SuPacket>(packets);

            Log.Debug($"[{hitRequest.Sender.Type.ToString()}][{hitRequest.Sender.Id}] ATTACK -> [{hitRequest.Target.Type.ToString()}]({hitRequest.Target.Id}) : {givenDamages} damages");

            // sets the new target (for AI)
            if (hitRequest.Target.Type != VisualType.Character && !hitRequest.Target.HasTarget)
            {
                hitRequest.Target.Target = hitRequest.Sender;
            }

            foreach (BCardDto bCardDto in e.HitRequest.Bcards)
            {
                await _bCardHandlerContainer.Handle(e.HitRequest.Sender, e.HitRequest.Target, bCardDto);
            }
        }
예제 #22
0
 public uint GenerateDamage(HitRequest hit)
 {
     return(1);
 }
예제 #23
0
 public override HitResponse[] TotalRequest(HitRequest request)
 {
     throw new NotImplementedException();
 }
 public AccumulationBufferRule(DataVisitor visitor, HitRequest request)
 {
     _Visitor = visitor;
     _Request = request;
 }
예제 #25
0
        Value <int> IPlayer.Hit(int bullet_id, int[] fishids)
        {
            var hasBullet = _PopBullet(bullet_id);

            if (hasBullet == false)
            {
                return(0);
            }

            var logFishs = string.Empty;
            var count    = 0;

            foreach (var fishid in fishids)
            {
                if (_PopFish(fishid) == false)
                {
                    continue;
                }

                if (_Requests.ContainsKey(fishid))
                {
                    continue;
                }

                count++;

                var fishs = new List <RequsetFishData>
                {
                    new RequsetFishData
                    {
                        FishId     = fishid,
                        FishOdds   = 1,
                        FishStatus = FISH_STATUS.NORMAL,
                        FishType   = FISH_TYPE.TROPICAL_FISH
                    }
                };

                var weapon = new RequestWeaponData
                {
                    TotalHits  = fishids.Length,
                    WeaponBet  = _WeaponBet,
                    BulletId   = bullet_id,
                    WeaponOdds = 1,
                    WeaponType = _WeaponType
                };

                var request = new HitRequest(fishs.ToArray(), weapon);
                _Requests.Add(fishid, request);
                _FishStage.Hit(request);

                logFishs += fishid + ",";
            }

            if (count == 0)
            {
                _PushBullet(bullet_id);
            }

            Singleton <Log> .Instance.WriteInfo(
                string.Format(
                    "all WEAPON_TYPE:{0} , targets:{1} , count:{2}",
                    bullet_id,
                    string.Join(",", (from id in fishids select id.ToString()).ToArray()),
                    fishids.Length));

            Singleton <Log> .Instance.WriteInfo(
                string.Format("requested WEAPON_TYPE:{0} , targets:{1} , count:{2}", bullet_id, logFishs, count));

            Singleton <Log> .Instance.WriteInfo(
                string.Format(
                    "request fishs:{0} count:{1} ",
                    string.Join(",", (from id in _Requests.Keys select id.ToString()).ToArray()),
                    _Requests.Count));

            return(count);
        }
예제 #26
0
 public abstract HitResponse[] TotalRequest(HitRequest request);