예제 #1
0
        public void OnHitVehicle(
            PlayerEntity srcPlayer,
            VehicleEntity targetVehicle,
            IBulletEntity bulletEntity,
            RaycastHit hit)
        {
            Collider         collider = hit.collider;
            VehiclePartIndex partIndex;
            var hitBoxFactor = VehicleEntityUtility.GetHitFactor(targetVehicle, collider, out partIndex);

            var totalDamage = GetBulletDamage(bulletEntity, hitBoxFactor);
            var gameData    = targetVehicle.GetGameData();

            gameData.DecreaseHp(partIndex, totalDamage, srcPlayer.entityKey.Value);
            srcPlayer.statisticsData.Statistics.TotalDamage += totalDamage;

            bulletEntity.IsValid = false;

            srcPlayer.statisticsData.Statistics.ShootingSuccCount++;
            _logger.DebugFormat(
                "bullet from {0} hit vehicle {1}, part {2}",
                bulletEntity.OwnerEntityKey,
                targetVehicle.entityKey.Value,
                collider.name);


            ClientEffectFactory.AddHitVehicleEffectEvent(
                srcPlayer,
                targetVehicle.entityKey.Value,
                hit.point,
                hit.point - targetVehicle.position.Value,
                hit.normal);
        }
예제 #2
0
        private float GetBulletDamage(IBulletEntity bulletEntity, float hitboxFactor, float distance)
        {
            float baseHarm      = bulletEntity.BaseDamage;
            float distanceDecay = bulletEntity.DistanceDecayFactor;
            // 武器基础伤害 * (距离系数 ^ (实际命中距离 / 1270)) * hitbox系数 * 防弹装备系数 * 穿透系数
            float totalDamage = baseHarm * Mathf.Pow(distanceDecay, distance / 12.7f) * hitboxFactor;

            _logger.InfoFormat("bullet damage baseHarm {0}, distance decay {1}, distance {2}, hitbox factor {3}, result damage {4}",
                               baseHarm, distanceDecay, distance, hitboxFactor, totalDamage);

            return(totalDamage);
        }
예제 #3
0
        public void OnHitPlayer(PlayerEntity srcPlayer, PlayerEntity targetPlayer, IBulletEntity bulletEntity,
                                RaycastHit hit, UnityEngine.Vector3 targetPlayerPostion)
        {
            Collider collider = hit.collider;

            EBodyPart part = BulletPlayerUtility.GetBodyPartByHitBoxName(collider);


            _logger.DebugFormat("OnHitPlayer in {0}", part);

            float hitboxFactor = bulletEntity.GetDamageFactor(part);
            float totalDamage  = GetBulletDamage(bulletEntity, hitboxFactor);

            bulletEntity.IsValid = false;

            ClientEffectFactory.AddHitPlayerEffectEvent(srcPlayer, targetPlayer.entityKey.Value, hit.point, hit.point - targetPlayer.position.Value);

            if (targetPlayer.hasStateInterface && targetPlayer.stateInterface.State.CanBeenHit())
            {
                targetPlayer.stateInterface.State.BeenHit();
            }

            _logger.DebugFormat(
                "bullet from {0} hit player {1}, part {2}, hitbox factor {3}, result damage {4}",
                bulletEntity.OwnerEntityKey,
                targetPlayer.entityKey.Value,
                collider,
                hitboxFactor,
                totalDamage);


            if (!targetPlayer.gamePlay.IsLastLifeState(EPlayerLifeState.Dead))
            {
                //有效命中
                if (targetPlayer.gamePlay.IsLastLifeState(EPlayerLifeState.Alive))
                {
                    srcPlayer.statisticsData.Statistics.ShootingPlayerCount++;
                }
                srcPlayer.statisticsData.Statistics.ShootingSuccCount++;
            }

            BulletPlayerUtility.ProcessPlayerHealthDamage(
                _damager,
                srcPlayer,
                targetPlayer,
                new PlayerDamageInfo(totalDamage, (int)EUIDeadType.Weapon, (int)part, bulletEntity.WeaponId, bulletEntity.IsOverWall),
                _damageInfoCollector);
        }
예제 #4
0
        public void OnHitPlayer(Contexts contexts, PlayerEntity srcPlayer, PlayerEntity targetPlayer,
                                IBulletEntity bulletEntity, RaycastHit hit, Vector3 targetPlayerPostion, int cmdSeq)
        {
            if (srcPlayer.gamePlay.IsDead())
            {
                return;
            }

            Collider  collider = hit.collider;
            EBodyPart part     = BulletPlayerUtility.GetBodyPartByHitBoxName(collider);

            _logger.InfoFormat("OnHitPlayer in {0}", part);

            float hitboxFactor = bulletEntity.GetDamageFactor(part);
            float totalDamage  = GetBulletDamage(bulletEntity, hitboxFactor, Vector3.Distance(hit.point, bulletEntity.GunEmitPosition));

            bulletEntity.IsValid = false;

            //由于动画放在客户端做了,服务器调用的命令会被忽视,需要发送事件到客户端
//            if (targetPlayer.hasStateInterface && targetPlayer.stateInterface.State.CanBeenHit())
//            {
//                targetPlayer.stateInterface.State.BeenHit();
//            }

            ClientEffectFactory.AddBeenHitEvent(srcPlayer, targetPlayer, GeneraterUniqueHitId(srcPlayer, cmdSeq), contexts.session.currentTimeObject.CurrentTime);
            ClientEffectFactory.AddHitPlayerEffectEvent(srcPlayer, targetPlayer.entityKey.Value, hit.point, hit.point - targetPlayer.position.Value);

            _logger.InfoFormat("bullet from {0} hit player {1}, part {2}, hitbox factor {3}, result damage {4}",
                               bulletEntity.OwnerEntityKey, targetPlayer.entityKey.Value, collider, hitboxFactor, totalDamage);

            if (!targetPlayer.gamePlay.IsLastLifeState(EPlayerLifeState.Dead))
            {
                //有效命中
                if (targetPlayer.gamePlay.IsLastLifeState(EPlayerLifeState.Alive))
                {
                    srcPlayer.statisticsData.Statistics.ShootingPlayerCount++;
                }
                srcPlayer.statisticsData.Statistics.ShootingSuccCount++;
            }

            BulletPlayerUtility.ProcessPlayerHealthDamage(contexts, _damager, srcPlayer, targetPlayer,
                                                          new PlayerDamageInfo(totalDamage, (int)EUIDeadType.Weapon, (int)part, bulletEntity.WeaponId, bulletEntity.IsOverWall),
                                                          _damageInfoCollector);
        }
예제 #5
0
        private void OnHitEnvironment(PlayerEntity srcPlayer, IBulletEntity bulletEntity, RaycastHit hit)
        {
            if (srcPlayer.gamePlay.IsDead())
            {
                _logger.InfoFormat("[hit] environment dead");
                return;
            }

            ThicknessInfo   thicknessInfo;
            EnvironmentInfo info = BulletEnvironmentUtility.GetEnvironmentInfoByHitBoxName(hit, bulletEntity.Velocity, out thicknessInfo);
            float           damageDecayFactor = _environmentTypeConfigManager.GetDamageDecayFactorByEnvironmentType(info.Type);
            float           energyDecayFactor = _environmentTypeConfigManager.GetEnergyDecayFactorByEnvironmentType(info.Type);
            float           oldThickNess      = bulletEntity.PenetrableThickness;
            float           oldDamage         = bulletEntity.BaseDamage;

            bulletEntity.BaseDamage           *= damageDecayFactor;
            bulletEntity.PenetrableThickness   = bulletEntity.PenetrableThickness * energyDecayFactor - info.Thickness;
            bulletEntity.PenetrableLayerCount -= info.LayerCount;

            if (bulletEntity.PenetrableLayerCount <= 0 || bulletEntity.PenetrableThickness <= 0)
            {
                bulletEntity.IsValid = false;
            }
            else
            {
                bulletEntity.AddPenetrateInfo(info.Type);
            }

            EBulletCaliber caliber = bulletEntity.Caliber; //根据口径

            var collider          = hit.collider;
            var fracturedHittable = collider.GetComponent <FracturedHittable>();

            if (fracturedHittable != null)
            {
                EntityKey?hittedObjectKey = null;

                var script = fracturedHittable.gameObject.GetComponent <FracturedHittable>();
                if (script == null)
                {
                    return;
                }

                var objtype = MapObjectUtility.GetGameObjType(script.Owner);
                if (objtype < 0)
                {
                    return;
                }

                var rawObjKey = MapObjectUtility.GetGameObjId(script.Owner);

                if (rawObjKey != Int32.MinValue && !SharedConfig.IsServer &&
                    MapObjectUtility.GetMapObjectByGameObject(script.Owner) == null)
                {
                    MapObjectUtility.SendCreateMapObjMsg(objtype, rawObjKey);
                    _logger.InfoFormat("CreateMapObjEvent: type:{0}, obj:{1}, num:{2}", (ETriggerObjectType)objtype,
                                       fracturedHittable.gameObject,
                                       srcPlayer.uploadEvents.Events.Events[EEventType.CreateMapObj].Count);
                }

                FracturedAbstractChunk fracturedChunk = null;

                fracturedChunk = fracturedHittable.Hit(hit.point, hit.normal);
                if (fracturedHittable.HasBulletHole && fracturedChunk != null)
                {
                    ClientEffectFactory.CreateHitFracturedChunkEffect(_contexts.clientEffect, _entityIdGenerator, hit.point,
                                                                      srcPlayer.entityKey.Value, hittedObjectKey.Value, fracturedChunk.ChunkId,
                                                                      hit.point - fracturedChunk.transform.position, hit.normal);
                }

                srcPlayer.statisticsData.Statistics.ShootingSuccCount++;

                if (fracturedHittable.HasBulletHole && fracturedChunk != null && bulletEntity.IsValid && thicknessInfo.Thickness > 0)
                {
                    ClientEffectFactory.CreateHitFracturedChunkEffect(_contexts.clientEffect, _entityIdGenerator, thicknessInfo.OutPoint, srcPlayer.entityKey.Value,
                                                                      hittedObjectKey.Value, fracturedChunk.ChunkId, thicknessInfo.OutPoint - fracturedChunk.transform.position, thicknessInfo.Normal);
                }
            }
            else
            {
                ClientEffectFactory.AdHitEnvironmentEffectEvent(srcPlayer, hit.point, hit.normal, info.Type);

                if (bulletEntity.IsValid && thicknessInfo.Thickness > 0)
                {
                    ClientEffectFactory.AdHitEnvironmentEffectEvent(srcPlayer, thicknessInfo.OutPoint, thicknessInfo.Normal, info.Type);
                }
            }

            _logger.InfoFormat("[hit]bullet from {0} hit environment {1}, collier {2}, base damage {3}->{4}, penetrable thick {5}->{6}, env ({7}), remain layer {8}",
                               bulletEntity.OwnerEntityKey, hit.point, hit.collider.name, oldDamage, bulletEntity.BaseDamage, oldThickNess, bulletEntity.PenetrableThickness,
                               info, bulletEntity.PenetrableLayerCount);
        }
예제 #6
0
        public virtual void OnHit(int cmdSeq, IBulletEntity bulletEntity, RaycastHit hit, ICompensationWorld compensationWorld)
        {
            bulletEntity.HitPoint = hit.point;
            Collider collider = hit.collider;

            if (collider == null)
            {
                _logger.ErrorFormat("bullet hit unknown collier {0}", bulletEntity.OwnerEntityKey);
                return;
            }

            PlayerEntity srcPlayer = _contexts.player.GetEntityWithEntityKey(bulletEntity.OwnerEntityKey);

            if (srcPlayer == null)
            {
                _logger.WarnFormat("bullet from unkown {0} hit environment {1}, collier {2}",
                                   bulletEntity.OwnerEntityKey, hit.point, collider.name);
                return;
            }

            PlayerEntity  targetPlayer  = null;
            VehicleEntity targetVehicle = null;

            var comp = hit.collider.transform.gameObject.GetComponent <HitBoxOwnerComponent>();

            if (comp != null)
            {
                targetPlayer  = _contexts.player.GetEntityWithEntityKey(comp.OwnerEntityKey);
                targetVehicle = _contexts.vehicle.GetEntityWithEntityKey(comp.OwnerEntityKey);
            }

            if (targetPlayer != null)
            {
                try
                {
                    _OnHitPlayer.BeginProfileOnlyEnableProfile();
                    Vector3 pos;
                    if (compensationWorld.TryGetEntityPosition(targetPlayer.entityKey.Value, out pos))
                    {
                        OnHitPlayer(_contexts, srcPlayer, targetPlayer, bulletEntity, hit, pos, cmdSeq);
                    }
                    else
                    {
                        _logger.ErrorFormat("cant get player compensation position with key {0}", targetPlayer.entityKey.Value);
                        OnHitPlayer(_contexts, srcPlayer, targetPlayer, bulletEntity, hit, targetPlayer.position.Value, cmdSeq);
                    }
                    bulletEntity.HitType = EHitType.Player;
                }
                finally
                {
                    _OnHitPlayer.EndProfileOnlyEnableProfile();
                }
                return;
            }

            if (targetVehicle != null)
            {
                try
                {
                    _OnHitVehicle.BeginProfileOnlyEnableProfile();
                    OnHitVehicle(srcPlayer, targetVehicle, bulletEntity, hit);
                    bulletEntity.HitType = EHitType.Vehicle;
                }
                finally
                {
                    _OnHitVehicle.EndProfileOnlyEnableProfile();
                }
                return;
            }

            try
            {
                _OnHitEnvironment.BeginProfileOnlyEnableProfile();
                OnHitEnvironment(srcPlayer, bulletEntity, hit);
                bulletEntity.HitType = EHitType.Environment;
            }
            finally
            {
                _OnHitEnvironment.EndProfileOnlyEnableProfile();
            }
        }
예제 #7
0
        public void MoveBullet(IBulletEntity bulletEntity, int renderTime,
                               List <DefaultBulletSegment> allBulletSegments)
        {
            if (renderTime < bulletEntity.NextFrameTime)
            {
                return;
            }

            var origin        = bulletEntity.Origin;
            var velocity      = bulletEntity.Velocity;
            var gravity       = bulletEntity.Gravity;
            var velocityDecay = bulletEntity.VelocityDecay;
            var distance      = bulletEntity.Distance;

            float interval = (renderTime - bulletEntity.ServerTime) / 1000.0f;

            Vector3 oldOrigin = origin;

            // O(1) = O(0) + V(0) * t;
            origin.x = origin.x + velocity.x * interval;
            origin.y = origin.y + velocity.y * interval;
            origin.z = origin.z + velocity.z * interval;

            if (DebugConfig.DrawBulletLine)
            {
                RuntimeDebugDraw.Draw.DrawLine(oldOrigin, origin, Color.blue, 60f);
                Debug.DrawLine(oldOrigin, origin, Color.red, 60f);
            }
            // V(1) = V(0) + a * t
            Vector3 v = velocity;

            v.y      = v.y - gravity * interval;
            v        = v * Mathf.Pow(velocityDecay, interval);
            velocity = v;

            RaySegment raySegment = new RaySegment();

            raySegment.Ray.origin = oldOrigin;
            var direction = origin - oldOrigin;

            raySegment.Ray.direction = direction;
            raySegment.Length        = direction.magnitude;


            distance += raySegment.Length;

            _logger.DebugFormat("move bullet velocity {0}, direction {1}, distance {2}, total distance {3}, interval {4}, move {5} -> {6}, stepinterval {7}",
                                velocity, direction, raySegment.Length, distance, interval, oldOrigin, origin, _stepInterval);

            DefaultBulletSegment segment = DefaultBulletSegment.Allocate(renderTime, raySegment, bulletEntity);

            allBulletSegments.Add(segment);

            if (Mathf.Approximately(v.magnitude, 0))
            {
                bulletEntity.IsValid = false;
                _logger.ErrorFormat("bullet velocity is zero, set to invalid");
            }

            bulletEntity.Origin        = origin;
            bulletEntity.ServerTime    = renderTime;
            bulletEntity.Velocity      = velocity;
            bulletEntity.Distance      = distance;
            bulletEntity.NextFrameTime = renderTime + _stepInterval;
        }
예제 #8
0
 protected override void OnCleanUp()
 {
     ServerTime   = 0;
     BulletEntity = null;
     ObjectAllocatorHolder <DefaultBulletSegment> .Free(this);
 }
예제 #9
0
        public static DefaultBulletSegment Allocate(int serverTime, RaySegment raySegment, IBulletEntity bulletEntity)
        {
            var ret = ObjectAllocatorHolder <DefaultBulletSegment> .Allocate();

            ret.ServerTime   = serverTime;
            ret.RaySegment   = raySegment;
            ret.BulletEntity = bulletEntity;
            return(ret);
        }
예제 #10
0
        private void OnHitEnvironment(PlayerEntity srcPlayer, IBulletEntity bulletEntity, RaycastHit hit)
        {
            ThicknessInfo   thicknessInfo;
            EnvironmentInfo info = BulletEnvironmentUtility.GetEnvironmentInfoByHitBoxName(hit, bulletEntity.Velocity, out thicknessInfo);
            float           damageDecayFactor = _environmentTypeConfigManager.GetDamageDecayFactorByEnvironmentType(info.Type);
            float           energyDecayFactor = _environmentTypeConfigManager.GetEnergyDecayFactorByEnvironmentType(info.Type);
            float           oldThickNess      = bulletEntity.PenetrableThickness;
            float           oldDamage         = bulletEntity.BaseDamage;

            bulletEntity.BaseDamage           *= damageDecayFactor;
            bulletEntity.PenetrableThickness   = bulletEntity.PenetrableThickness * energyDecayFactor - info.Thickness;
            bulletEntity.PenetrableLayerCount -= info.LayerCount;

            if (bulletEntity.PenetrableLayerCount <= 0 || bulletEntity.PenetrableThickness <= 0)
            {
                bulletEntity.IsValid = false;
            }
            else
            {
                bulletEntity.AddPenetrateInfo(info.Type);
            }

            EBulletCaliber caliber = bulletEntity.Caliber; //根据口径

            var collider          = hit.collider;
            var fracturedHittable = collider.GetComponent <FracturedHittable>();

            if (fracturedHittable != null)
            {
                EntityKey?hittedObjectKey = null;

                var sceneObjectEntity = MapObjectUtility.GetMapObjectOfFracturedHittable(fracturedHittable);
                if (sceneObjectEntity != null)
                {
                    hittedObjectKey = sceneObjectEntity.entityKey.Value;
                }
                else
                {
                    var mapObjectEntity = MapObjectUtility.GetMapObjectOfFracturedHittable(fracturedHittable);
                    if (mapObjectEntity != null)
                    {
                        hittedObjectKey = mapObjectEntity.entityKey.Value;
                    }
                }

                FracturedAbstractChunk fracturedChunk = null;

                if (null != hittedObjectKey)
                {
                    fracturedChunk = fracturedHittable.Hit(hit.point, hit.normal);
                    if (fracturedHittable.HasBulletHole && fracturedChunk != null)
                    {
                        ClientEffectFactory.CreateHitFracturedChunkEffect(
                            _contexts.clientEffect,
                            _entityIdGenerator,
                            hit.point,
                            srcPlayer.entityKey.Value,
                            hittedObjectKey.Value,
                            fracturedChunk.ChunkId,
                            hit.point - fracturedChunk.transform.position,
                            hit.normal);
                    }

                    srcPlayer.statisticsData.Statistics.ShootingSuccCount++;
                }
                else
                {
                    _logger.ErrorFormat("no entity reference attached to {0}", fracturedHittable.name);
                }
                if (fracturedHittable.HasBulletHole && fracturedChunk != null &&
                    bulletEntity.IsValid && thicknessInfo.Thickness > 0)
                {
                    ClientEffectFactory.CreateHitFracturedChunkEffect(_contexts.clientEffect,
                                                                      _entityIdGenerator,
                                                                      thicknessInfo.OutPoint,
                                                                      srcPlayer.entityKey.Value,
                                                                      hittedObjectKey.Value,
                                                                      fracturedChunk.ChunkId,
                                                                      thicknessInfo.OutPoint - fracturedChunk.transform.position,
                                                                      thicknessInfo.Normal);
                }
            }
            else
            {
                ClientEffectFactory.AdHitEnvironmentEffectEvent(srcPlayer, hit.point,
                                                                hit.normal, info.Type);

                if (bulletEntity.IsValid && thicknessInfo.Thickness > 0)
                {
                    ClientEffectFactory.AdHitEnvironmentEffectEvent(srcPlayer, thicknessInfo.OutPoint, thicknessInfo.Normal, info.Type);
                }
            }


            _logger.DebugFormat(
                "bullet from {0} hit environment {1}, collier {2}, base damage {3}->{4}, penetrable thick {5}->{6}, env ({7}), remain layer {8}",
                bulletEntity.OwnerEntityKey,
                hit.point, hit.collider.name,
                oldDamage, bulletEntity.BaseDamage,
                oldThickNess, bulletEntity.PenetrableThickness,
                info,
                bulletEntity.PenetrableLayerCount);

            DamageInfoDebuger.OnEnvironmentHit(_contexts.player, _damager, _damageInfoCollector);
        }