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); }
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); }
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); }
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); }
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); }
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(); } }
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; }
protected override void OnCleanUp() { ServerTime = 0; BulletEntity = null; ObjectAllocatorHolder <DefaultBulletSegment> .Free(this); }
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); }
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); }