public static void DamageHandler( object target, ref MyDamageInformation info ) { if ( !PluginSettings.Instance.ProtectedEnabled ) return; IMySlimBlock block = target as IMySlimBlock; if ( block == null ) return; IMyCubeGrid grid = block.CubeGrid; ulong steamId = PlayerMap.Instance.GetSteamId( info.AttackerId ); foreach ( ProtectedItem item in PluginSettings.Instance.ProtectedItems ) { if ( item.Enabled && item.EntityId == grid.EntityId ) { //TODO: figure out how to get owner of a grinder /* if ( info.Type == MyDamageType.Grind || info.Type == MyDamageType.Weld ) { IMyEntity weapon; if ( !MyAPIGateway.Entities.TryGetEntityById( info.AttackerId, out weapon ) ) return; Wrapper.GameAction( ( ) => { if(weapon.GetObjectBuilder() == MyObjectBuilder_AngleGrinderDefinition ) { var grinder = (MyObjectBuilder_AngleGrinderDefinition)weapon; grinder.own } ); if ( PlayerManager.Instance.IsUserAdmin( steamId ) || grid.BigOwners.Contains( info.AttackerId ) ) return; } //grid owners and admins can grind or weld protected grids */ //else //{ info.Amount = 0; if ( DateTime.Now - _lastLog > TimeSpan.FromSeconds( 1 ) ) { _lastLog = DateTime.Now; Essentials.Log.Info( "Protected entity {0}.", grid.DisplayName ); //Essentials.Log.Info( "Protected entity \"{0}\" from player \"{1}\".", grid.DisplayName, PlayerMap.Instance.GetFastPlayerNameFromSteamId( steamId ) ); } //} } } }
public static void DamageHandler(Object obj, ref MyDamageInformation info) { try { IMySlimBlock targetBlock = obj as IMySlimBlock; IMyCubeGrid targetGrid = targetBlock.CubeGrid; if (Storage.Data.Grids.Grids.Find(g => g.Id == targetGrid.EntityId) != null) { info.Amount = 0f; } return; } catch { } }
protected override bool Activate(HashSet<MySlimBlock> targets) { m_otherGrid = null; if (targets.Count > 0) { m_otherGrid = targets.FirstElement().CubeGrid; } if (Sync.IsServer) { float coefficient = (MyShipGrinderConstants.GRINDER_COOLDOWN_IN_MILISECONDS * 0.001f) / targets.Count; foreach (var block in targets) { if ((MySession.Static.IsScenario || MySession.Static.Settings.ScenarioEditMode) && !block.CubeGrid.BlocksDestructionEnabled) continue; m_otherGrid = block.CubeGrid; float damage = MySession.Static.GrinderSpeedMultiplier * MyShipGrinderConstants.GRINDER_AMOUNT_PER_SECOND * coefficient; MyDamageInformation damageInfo = new MyDamageInformation(false, damage, MyDamageType.Grind, EntityId); if (block.UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo); block.DecreaseMountLevel(damageInfo.Amount, Inventory); block.MoveItemsFromConstructionStockpile(Inventory); if (block.UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo); if (block.IsFullyDismounted) { if (block.FatBlock is IMyInventoryOwner) EmptyBlockInventories(block.FatBlock as IMyInventoryOwner); if(block.UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(block, damageInfo); block.SpawnConstructionStockpile(); block.CubeGrid.RazeBlock(block.Min); } } } m_wantsToShake = targets.Count != 0; return targets.Count != 0; }
public void DamageHandler(object entity, ref MyDamageInformation info) { try { long attacker = info.AttackerId; MyAPIGateway.Utilities.ShowMessage("", info.AttackerId.ToString()); MDInfo sourceDriver = Data.Drivers.Find(d => d.Id == attacker); if (sourceDriver != null) { info.Amount = info.Amount * sourceDriver.DamageMultiplier; } } catch { } }
private static void DamageHandler(object target, ref MyDamageInformation info) { if (!Config.ProtectionEnabled) return; IMySlimBlock block = target as IMySlimBlock; if (block != null) { if (CanDamageBlock(info.AttackerId, block, info.Type)) return; info.Amount = 0; return; } IMyCharacter character = target as IMyCharacter; if (character != null) { var players = new List<IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players, p => p != null && p.Controller.ControlledEntity != null && p.Controller.ControlledEntity.Entity != null); var player = players.FirstOrDefault(p => p.GetCharacter() == character); if (player == null) return; if (!IsProtected(player.Controller.ControlledEntity.Entity)) return; if (info.Type == MyDamageType.LowPressure || info.Type == MyDamageType.Asphyxia || info.Type == MyDamageType.Environment || info.Type == MyDamageType.Fall || info.Type == MyDamageType.Fire || info.Type == MyDamageType.Radioactivity || info.Type == MyDamageType.Suicide || info.Type == MyDamageType.Unknown) return; info.Amount = 0; } }
public static void KillCharacter(MyCharacter character, MyDamageInformation damageInfo) { Debug.Assert(Sync.IsServer, "KillCharacter called from client"); KillCharacterMsg msg = new KillCharacterMsg() { entityId = character.EntityId, DamageInfo = damageInfo }; character.Kill(false, damageInfo); Sync.Layer.SendMessageToAll<KillCharacterMsg>(ref msg); }
/// <summary> /// Raised before damage is applied. Can be modified. /// </summary> /// <param name="target">The target object</param> /// <param name="info">Information about the damage. Can be modified</param> public void RaiseBeforeDamageApplied(object target, ref MyDamageInformation info) { foreach (var item in m_beforeDamageHandlers) item.Item2(target, ref info); }
/// <summary> /// Raised after damage is applied /// </summary> /// <param name="target">The target object</param> /// <param name="info">Information about the damage</param> public void RaiseAfterDamageApplied(object target, MyDamageInformation info) { foreach (var item in m_afterDamageHandlers) item.Item2(target, info); }
public bool DoDamage(float damage, MyStringHash damageType, bool updateSync, long attackerId = 0) { if ((!CharacterCanDie && !(damageType == MyDamageType.Suicide && MyPerGameSettings.CharacterSuicideEnabled)) || StatComp == null) return false; MyEntity attacker; if (damageType != MyDamageType.Suicide && MyEntities.TryGetEntityById(attackerId, out attacker)) { // Checking friendly fire using faction's friendly fire settings var localPlayer = MyPlayer.GetPlayerFromCharacter(this); MyPlayer otherPlayer = null; if (attacker == this) { return false; } else if (attacker is MyCharacter) { otherPlayer = MyPlayer.GetPlayerFromCharacter(attacker as MyCharacter); } else if (attacker is IMyGunBaseUser) { otherPlayer = MyPlayer.GetPlayerFromWeapon(attacker as IMyGunBaseUser); } else if (attacker is MyHandDrill) { otherPlayer = MyPlayer.GetPlayerFromCharacter((attacker as MyHandDrill).Owner); } if (localPlayer != null && otherPlayer != null) { var localPlayerFaction = MySession.Static.Factions.TryGetPlayerFaction(localPlayer.Identity.IdentityId) as MyFaction; if (localPlayerFaction != null && !localPlayerFaction.EnableFriendlyFire && localPlayerFaction.IsMember(otherPlayer.Identity.IdentityId)) { return false; // No Friendly Fire Enabled! } } } MyDamageInformation damageInfo = new MyDamageInformation(false, damage, damageType, attackerId); if (UseDamageSystem && !(m_dieAfterSimulation || IsDead)) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageInfo); if (damageInfo.Amount <= 0f) return false; StatComp.DoDamage(damage, updateSync, damageInfo); // Cache the last damage information for the analytics module. MyAnalyticsHelper.SetLastDamageInformation(damageInfo); if (UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageInfo); return true; }
/// <summary> /// Raised when an object is destroyed. /// </summary> /// <param name="target">The target object</param> /// <param name="info">Information about the damage</param> public void RaiseDestroyed(object target, MyDamageInformation info) { foreach (var item in m_destroyHandlers) item.Item2(target, info); }
public void Kill(bool sync, MyDamageInformation damageInfo) { if (m_dieAfterSimulation || IsDead || (MyFakes.DEVELOPMENT_PRESET && damageInfo.Type != MyDamageType.Suicide)) return; if (sync) { KillCharacter(damageInfo); return; } if (UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, damageInfo); MyAnalyticsHelper.SetLastDamageInformation(damageInfo); m_dieAfterSimulation = true; }
public void DoDamage(float damage, Common.ObjectBuilders.Definitions.MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (Sync.IsServer) { MyDamageInformation info = new MyDamageInformation(false, damage, damageType, attackerId); if (UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref info); m_hitPoints -= info.Amount; if (UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, info); if (m_hitPoints <= 0) { MyFracturedPiecesManager.Static.RemoveFracturePiece(this, 2); if (UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, info); } } }
private void Grind() { var block = GetTargetBlock(); if (block != null) { float hackMultiplier = 1.0f; if (block.FatBlock != null && Owner != null && Owner.ControllerInfo.Controller != null && Owner.ControllerInfo.Controller.Player != null) { var relation = block.FatBlock.GetUserRelationToOwner(Owner.ControllerInfo.Controller.Player.Identity.IdentityId); if (relation == MyRelationsBetweenPlayerAndBlock.Enemies || relation == MyRelationsBetweenPlayerAndBlock.Neutral) hackMultiplier = MySession.Static.HackSpeedMultiplier; } float damage = GrinderAmount; MyDamageInformation damageInfo = new MyDamageInformation(false, damage * hackMultiplier, MyDamageType.Grind, EntityId); if (block.UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo); block.DecreaseMountLevel(damageInfo.Amount, CharacterInventory); block.MoveItemsFromConstructionStockpile(CharacterInventory); if (block.UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo); if (block.IsFullyDismounted) { if (block.UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(block, damageInfo); block.SpawnConstructionStockpile(); block.CubeGrid.RazeBlock(block.Min); } } var targetDestroyable = GetTargetDestroyable(); if (targetDestroyable != null && Sync.IsServer) targetDestroyable.DoDamage(20, MyDamageType.Grind, true, attackerId: Owner != null ? Owner.EntityId : 0); }
public void DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (sync) { if (Sync.IsServer) MySyncDamage.DoDamageSynced(Entity, damage, damageType, attackerId); } else { MyDamageInformation info = new MyDamageInformation(false, damage, damageType, attackerId); if (Entity.UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(Entity, ref info); m_integrity -= info.Amount; if (Entity.UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(Entity, info); if (m_integrity <= 0 && Sync.IsServer) { m_closeAfterSimulation = Sync.IsServer; if (Entity.UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(Entity, info); return; } } return; }
private void Grind() { var block = GetTargetBlock(); MyStringHash target = m_metal; if (block != null && (!(MySession.Static.IsScenario || MySession.Static.Settings.ScenarioEditMode) || block.CubeGrid.BlocksDestructionEnabled)) { float hackMultiplier = 1.0f; if (block.FatBlock != null && Owner != null && Owner.ControllerInfo.Controller != null && Owner.ControllerInfo.Controller.Player != null) { var relation = block.FatBlock.GetUserRelationToOwner(Owner.ControllerInfo.Controller.Player.Identity.IdentityId); if (relation == VRage.Game.MyRelationsBetweenPlayerAndBlock.Enemies || relation == VRage.Game.MyRelationsBetweenPlayerAndBlock.Neutral) hackMultiplier = MySession.Static.HackSpeedMultiplier; } float damage = GrinderAmount; MyDamageInformation damageInfo = new MyDamageInformation(false, damage * hackMultiplier, MyDamageType.Grind, EntityId); if (block.UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo); block.DecreaseMountLevel(damageInfo.Amount, CharacterInventory); block.MoveItemsFromConstructionStockpile(CharacterInventory); if (block.UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo); if (block.IsFullyDismounted) { if (block.UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(block, damageInfo); block.SpawnConstructionStockpile(); block.CubeGrid.RazeBlock(block.Min); } if (block.BlockDefinition.PhysicalMaterial.Id.SubtypeName.Length > 0) target = block.BlockDefinition.PhysicalMaterial.Id.SubtypeId; } var targetDestroyable = GetTargetDestroyable(); if (targetDestroyable != null) { //HACK to not grind yourself if(targetDestroyable is MyCharacter && (targetDestroyable as MyCharacter) == Owner) { return; } //damage tracking if (targetDestroyable is MyCharacter && MySession.Static.ControlledEntity == this.Owner && (targetDestroyable as MyCharacter).IsDead == false) MySession.Static.TotalDamageDealt += 20; targetDestroyable.DoDamage(20, MyDamageType.Grind, true, attackerId: Owner != null ? Owner.EntityId : 0); if (targetDestroyable is MyCharacter) target = MyStringHash.GetOrCompute((targetDestroyable as MyCharacter).Definition.PhysicalMaterial); } if (block != null || targetDestroyable != null) { m_actualSound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_source, target); } }
private static void GodModeDamageHandler_Server(object target, ref MyDamageInformation info) { if (target is IMyCharacter && Players.Any(p => target == p.Controller.ControlledEntity)) info.Amount = 0; }
public static void SetLastDamageInformation(MyDamageInformation lastDamageInformation) { try { IMyAnalytics analytics = MyPerGameSettings.AnalyticsTracker; if (analytics == null) return; // Empty message is sent from the server, we don't want it to rewrite the true damage cause. if (lastDamageInformation.Type == default(MyStringHash)) return; m_lastDamageInformation = lastDamageInformation; } catch (Exception ex) { MyLog.Default.WriteLine(ex); } }
void OnKillCharacter(MyDamageInformation damageInfo) { Kill(false, damageInfo); }
private void KillCharacter(MyDamageInformation damageInfo) { Debug.Assert(Sync.IsServer, "KillCharacter called from client"); Kill(false, damageInfo); MyMultiplayer.RaiseEvent(this, x => x.OnKillCharacter, damageInfo); }
//public List<object> m_debugBones = new List<object>(); /// <summary> /// Applies deformation, returns true when block was destroyed (explosion should be generated) /// </summary> /// <param name="deformationOffset">Amount of deformation in the localPos</param> /// <param name="offsetThreshold">When deformation offset for bone is lower then threshold, it won't move the bone at all or do damage</param> public int ApplyDeformation(float deformationOffset, float softAreaPlanar, float softAreaVertical, Vector3 localPos, Vector3 localNormal, MyStringHash damageType, float offsetThreshold = 0, float lowerRatioLimit = 0, long attackerId = 0) { int blocksDeformed = 0; offsetThreshold /= m_grid.GridSizeEnum == MyCubeSize.Large ? 1 : 5; float roundSize = m_grid.GridSize / m_grid.Skeleton.BoneDensity; Vector3I roundedPos = Vector3I.Round((localPos + new Vector3(m_grid.GridSize / 2)) / roundSize); Vector3I gridPos = Vector3I.Round((localPos + new Vector3(m_grid.GridSize / 2)) / m_grid.GridSize); Vector3I gridOffset = roundedPos - gridPos * m_grid.Skeleton.BoneDensity; float breakOffset = m_grid.GridSize * 0.7f; float breakOffsetDestruction = breakOffset; Vector3I min = Vector3I.MaxValue; Vector3I max = Vector3I.MinValue; bool isDirty = false; bool destructionDone = false; Vector3 absNormal = Vector3.Abs(localNormal); float maxNorm = Math.Max(Math.Max(absNormal.X, absNormal.Y), absNormal.Z); float maxDef = maxNorm * deformationOffset; float destructionPotencial = (1 - breakOffsetDestruction / maxDef); float minDeformationRatio = 1; var softAreaPlanarR = 1.0f / softAreaPlanar; var softAreaVerticalR = 1.0f / softAreaVertical; var gridSizeR = 1.0f / m_grid.GridSize; Vector3D forward = localNormal; var up = MyUtils.GetRandomPerpendicularVector(ref forward); float minLength = Math.Min(m_grid.GridSize / 256.0f, deformationOffset * 0.06f); // When we're sure that there will be destroyed blocks, it's not necessary to do deformations, just do destruction MyDamageInformation damageInfo = new MyDamageInformation(true, 1f, MyDamageType.Deformation, attackerId); if (destructionPotencial > 0) { float critVertical = destructionPotencial * softAreaVertical; float critPlanar = destructionPotencial * softAreaPlanar; var he = new Vector3(critPlanar, critPlanar, critVertical); MyOrientedBoundingBox obb = new MyOrientedBoundingBox(gridPos,he, Quaternion.CreateFromForwardUp(forward, up)); var aabb = obb.GetAABB(); //float maxCritDist = Math.Max(critPlanar, critVertical); //Vector3I distCubes = new Vector3I((int)Math.Ceiling(maxCritDist / m_grid.GridSize)); //Vector3I minOffset = gridPos - distCubes; //Vector3I maxOffset = gridPos + distCubes; var minOffset = Vector3I.Floor(aabb.Min); var maxOffset = Vector3I.Ceiling(aabb.Max); minOffset = Vector3I.Max(minOffset, m_grid.Min); maxOffset = Vector3I.Min(maxOffset, m_grid.Max); ProfilerShort.Begin("Update destruction"); Vector3I offset; for (offset.X = minOffset.X; offset.X <= maxOffset.X; offset.X++) { for (offset.Y = minOffset.Y; offset.Y <= maxOffset.Y; offset.Y++) { for (offset.Z = minOffset.Z; offset.Z <= maxOffset.Z; offset.Z++) { Vector3 closestCorner = m_grid.GetClosestCorner(offset, localPos); float soften = 1.0f; if (offset != gridPos) { soften = CalculateSoften(softAreaPlanarR, softAreaVerticalR, ref localNormal, closestCorner - localPos); } float deformation = maxDef * soften; if (deformation > breakOffsetDestruction) { var block = m_grid.GetCubeBlock(offset); if (block != null) { if (block.UseDamageSystem) { damageInfo.Amount = 1; MyDamageSystem.Static.RaiseBeforeDamageApplied(block, ref damageInfo); if (damageInfo.Amount == 0f) continue; } minDeformationRatio = Math.Min(minDeformationRatio, block.DeformationRatio); if (Math.Max(lowerRatioLimit, block.DeformationRatio) * deformation > breakOffsetDestruction) { ProfilerShort.Begin("Remove destroyed blocks"); min = Vector3I.Min(min, block.Min - Vector3I.One); max = Vector3I.Max(max, block.Max + Vector3I.One); isDirty = true; m_grid.RemoveDestroyedBlock(block); ProfilerShort.End(); destructionDone = true; } blocksDeformed++; } } } } } ProfilerShort.End(); // When there was no destruction, reduce area and do deformation minDeformationRatio = Math.Max(minDeformationRatio, 0.2f); softAreaPlanar *= minDeformationRatio; softAreaVertical *= minDeformationRatio; } if (!destructionDone) { //m_debugBones.Clear(); var boneDensity = m_grid.Skeleton.BoneDensity; ProfilerShort.Begin("Update deformation"); MyOrientedBoundingBox obb = new MyOrientedBoundingBox( gridPos * boneDensity + gridOffset, new Vector3(softAreaPlanar * gridSizeR * boneDensity, softAreaPlanar * gridSizeR * boneDensity , softAreaVertical * gridSizeR * boneDensity), Quaternion.CreateFromForwardUp(forward, up)); var aabb = obb.GetAABB(); //float softArea = Math.Max(softAreaPlanar, softAreaVertical); //var distBones = new Vector3I((int)Math.Ceiling(softArea / m_grid.GridSize * m_grid.Skeleton.BoneDensity)); //Vector3I minOffset = gridPos * m_grid.Skeleton.BoneDensity + gridOffset - distBones; //Vector3I maxOffset = gridPos * m_grid.Skeleton.BoneDensity + gridOffset + distBones; var minOffset = Vector3I.Floor(aabb.Min); var maxOffset = Vector3I.Ceiling(aabb.Max); minOffset = Vector3I.Max(minOffset, m_grid.Min * m_grid.Skeleton.BoneDensity); maxOffset = Vector3I.Min(maxOffset, m_grid.Max * m_grid.Skeleton.BoneDensity); Vector3I minDirtyBone = Vector3I.MaxValue; Vector3I maxDirtyBone = Vector3I.MinValue; ProfilerShort.Begin("Get bones"); m_tmpBoneList.Clear(); m_grid.GetExistingBones( minOffset, maxOffset, m_tmpBoneList, damageInfo); ProfilerShort.End(); ProfilerShort.Begin("Deform bones"); Vector3 bone; Vector3I baseOffset = gridPos * m_grid.Skeleton.BoneDensity; float boneDensityR = 1.0f / m_grid.Skeleton.BoneDensity; var halfGridSize = new Vector3(m_grid.GridSize * 0.5f); ProfilerShort.CustomValue("Bone Count", m_tmpBoneList.Count,0); foreach (var b in m_tmpBoneList) { var boneIndex = b.Key; var baseBonePos = boneIndex * m_grid.GridSize * boneDensityR - halfGridSize; m_grid.Skeleton.GetBone(ref boneIndex, out bone); var bonePos = bone + baseBonePos; float soften = CalculateSoften(softAreaPlanarR, softAreaVerticalR, ref localNormal, bonePos - localPos); if (soften == 0) continue; min = Vector3I.Min(min, Vector3I.Floor(bonePos * gridSizeR - Vector3.One * boneDensityR)); max = Vector3I.Max(max, Vector3I.Ceiling(bonePos *gridSizeR + Vector3.One * boneDensityR)); isDirty = true; float deformationRatio = 1.0f; bool doDeformation = true; var block2 = b.Value; { Debug.Assert(block2 != null, "Block cannot be null"); deformationRatio = Math.Max(lowerRatioLimit, block2.DeformationRatio); // + some deformation coeficient based on integrity float maxAxisDeformation = maxNorm * deformationOffset * soften; doDeformation = block2.UsesDeformation; if (block2.IsDestroyed) // || block2.DoDamage(maxAxisDeformation / m_grid.GridSize, damageType, addDirtyParts: false)) { destructionDone = true; } } if (deformationOffset * deformationRatio < offsetThreshold) continue; float deformationLength = deformationOffset * soften * deformationRatio; var deformation = localNormal * deformationLength; bool canDeform = damageType != MyDamageType.Bullet || (Math.Abs(bone.X + deformation.X) < breakOffset && Math.Abs(bone.Y + deformation.Y) < breakOffset && Math.Abs(bone.Z + deformation.Z) < breakOffset); if (canDeform && deformationLength > minLength) { bone += deformation; //m_debugBones.Add(new Tuple<Vector3, float>(bonePos, deformationRatio)); var offset = boneIndex - baseOffset; if (Math.Abs(bone.X) > breakOffset || Math.Abs(bone.Y) > breakOffset || Math.Abs(bone.Z) > breakOffset) { m_tmpCubeList.Clear(); Vector3I wrappedBoneOffset = offset; Vector3I wrappedGridPos = gridPos; m_grid.Skeleton.Wrap(ref wrappedGridPos, ref wrappedBoneOffset); m_grid.Skeleton.GetAffectedCubes(wrappedGridPos, wrappedBoneOffset, m_tmpCubeList, m_grid); foreach (var c in m_tmpCubeList) { var block = m_grid.GetCubeBlock(c); if (block != null) { ProfilerShort.Begin("Remove destroyed blocks"); m_grid.RemoveDestroyedBlock(block); AddDirtyBlock(block); ProfilerShort.End(); destructionDone = true; blocksDeformed++; } } } else if (doDeformation && Sync.IsServer) { minDirtyBone = Vector3I.Min(minDirtyBone, boneIndex); maxDirtyBone = Vector3I.Max(maxDirtyBone, boneIndex); m_grid.Skeleton.SetBone(ref boneIndex, ref bone); m_grid.AddDirtyBone(gridPos, offset); m_grid.BonesToSend.AddInput(boneIndex); } } } ProfilerShort.End(); ProfilerShort.End(); } if (isDirty) { m_dirtyCubesInfo.DirtyParts.Add(new BoundingBoxI() { Min = min, Max = max }); } return blocksDeformed; }
public bool DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (Sync.IsServer) { MyDamageInformation info = new MyDamageInformation(false, damage, damageType, attackerId); if (UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref info); m_hitPoints -= info.Amount; if (UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, info); if (m_hitPoints <= 0) { MyFracturedPiecesManager.Static.RemoveFracturePiece(this, 2); if (UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, info); } } return true; }
public void DoDamage(float damage, MyDamageType damageType, bool sync, long attackerId) { if (MarkedForClose) return; if (sync) { if (!Sync.IsServer) return; else { MySyncHelper.DoDamageSynced(this, damage, damageType, attackerId); return; } } MyDamageInformation damageinfo = new MyDamageInformation(false, damage, damageType, attackerId); if(UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageinfo); var typeId = Item.Content.TypeId; if (typeId == typeof(MyObjectBuilder_Ore) || typeId == typeof(MyObjectBuilder_Ingot)) { if (Item.Amount < 1) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; MyFloatingObjects.RemoveFloatingObject(this); } } else { if (Sync.IsServer) MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)damageinfo.Amount); } } else { m_health -= (10 + 90 * DamageMultiplier) * damageinfo.Amount; if(UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageinfo); if (m_health < 0) { //TODO: SYNC particle MyParticleEffect effect; if (MyParticlesManager.TryCreateParticleEffect((int)MyParticleEffectsIDEnum.Smoke_Construction, out effect)) { effect.WorldMatrix = WorldMatrix; effect.UserScale = 0.4f; } if (Sync.IsServer) MyFloatingObjects.RemoveFloatingObject(this); //TODO: dont compare to string? if (Item.Content.SubtypeId == m_explosives && Sync.IsServer) { var expSphere = new BoundingSphere(WorldMatrix.Translation, (float)Item.Amount * 0.01f + 0.5f);// MathHelper.Clamp((float)Item.Amount, 0, 300) * 0.5f); MyExplosionInfo info = new MyExplosionInfo() { PlayerDamage = 0, Damage = 800, ExplosionType = MyExplosionTypeEnum.WARHEAD_EXPLOSION_15, ExplosionSphere = expSphere, LifespanMiliseconds = MyExplosionsConstants.EXPLOSION_LIFESPAN, CascadeLevel = 0, HitEntity = this, ParticleScale = 1, OwnerEntity = this, Direction = WorldMatrix.Forward, VoxelExplosionCenter = expSphere.Center, ExplosionFlags = MyExplosionFlags.AFFECT_VOXELS | MyExplosionFlags.APPLY_FORCE_AND_DAMAGE | MyExplosionFlags.CREATE_DEBRIS | MyExplosionFlags.CREATE_DECALS | MyExplosionFlags.CREATE_PARTICLE_EFFECT | MyExplosionFlags.CREATE_SHRAPNELS | MyExplosionFlags.APPLY_DEFORMATION, VoxelCutoutScale = 0.5f, PlaySound = true, ApplyForceAndDamage = true, ObjectsRemoveDelayInMiliseconds = 40 }; MyExplosions.AddExplosion(ref info); } if (MyFakes.ENABLE_SCRAP && Sync.IsServer) { if (Item.Content.SubtypeId == ScrapBuilder.SubtypeId) return; var contentDefinitionId = Item.Content.GetId(); if (contentDefinitionId.TypeId == typeof(MyObjectBuilder_Component)) { var definition = MyDefinitionManager.Static.GetComponentDefinition((Item.Content as MyObjectBuilder_Component).GetId()); if (MyRandom.Instance.NextFloat() < definition.DropProbability) MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(Item.Amount * 0.8f, ScrapBuilder), PositionComp.GetPosition(), WorldMatrix.Forward, WorldMatrix.Up); } } if(UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, damageinfo); } } return; }
void Sandbox.ModAPI.IMyCharacter.Kill(object statChangeData) { MyDamageInformation damageInfo = new MyDamageInformation(); if (statChangeData != null) damageInfo = (MyDamageInformation)statChangeData; Kill(true, damageInfo); }
private void GodModeDamageHandler_Client(object target, ref MyDamageInformation info) { if (GodModeEnabled && target is IMyCharacter && target == MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity) info.Amount = 0; }
private void ApplyVolumetriDamageToGrid(MyDamageInfo damageInfo, long attackerId) { var damagedBlocks = damageInfo.ExplosionDamage.DamagedBlocks; var explodedBlocks = damageInfo.AffectedCubeBlocks; var explodedGrids = damageInfo.AffectedCubeGrids; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("foreach (var damagedBlock in damagedBlocks)"); if (MyDebugDrawSettings.DEBUG_DRAW_VOLUMETRIC_EXPLOSION_COLORING) { foreach (var explodedBlock in explodedBlocks) { explodedBlock.CubeGrid.ChangeColor(explodedBlock, new Vector3(0.66f, 1f, 1f)); } foreach (var damagedBlock in damagedBlocks) { float hue = 1f - damagedBlock.Value / damageInfo.ExplosionDamage.Damage; damagedBlock.Key.CubeGrid.ChangeColor(damagedBlock.Key, new Vector3(hue / 3f, 1.0f, 0.5f)); } } else { foreach (var damagedBlock in damagedBlocks) { var cubeBlock = damagedBlock.Key; if (cubeBlock.FatBlock != null && cubeBlock.FatBlock.MarkedForClose) continue; if (!cubeBlock.CubeGrid.BlocksDestructionEnabled) continue; // Allow mods to modify damage. This will cause a double call. Once here and once in the DoDamage, but only real way to do a check here MyDamageInformation checkInfo = new MyDamageInformation(false, damagedBlock.Value, MyDamageType.Explosion, attackerId); if (cubeBlock.UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(cubeBlock, ref checkInfo); if (cubeBlock.FatBlock == null && cubeBlock.Integrity / cubeBlock.DeformationRatio < checkInfo.Amount) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("RemoveBlock"); cubeBlock.CubeGrid.RemoveDestroyedBlock(cubeBlock); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } else { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("ApplyDestructionDeformation"); float damage = damagedBlock.Value; if (cubeBlock.FatBlock != null) { damage *= 7f; } (cubeBlock as IMyDestroyableObject).DoDamage(damage, MyDamageType.Explosion, true); if (!cubeBlock.IsDestroyed) { cubeBlock.CubeGrid.ApplyDestructionDeformation(cubeBlock); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } foreach (var neighbour in cubeBlock.Neighbours) { neighbour.CubeGrid.Physics.AddDirtyBlock(neighbour); } cubeBlock.CubeGrid.Physics.AddDirtyBlock(cubeBlock); } } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); var sphere = damageInfo.Sphere; if (!MyDebugDrawSettings.DEBUG_DRAW_VOLUMETRIC_EXPLOSION_COLORING) { foreach (var grid in explodedGrids) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("UpdateDirty"); grid.UpdateDirty(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("CreateExplosionDebris"); if (m_explosionInfo.HitEntity == grid) { BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(new BoundingSphereD(sphere.Center, sphere.Radius * 1.5f)); MyDebris.Static.CreateExplosionDebris(ref sphere, grid, ref aabb, 0.5f, false); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } } }
private void IndestructibleDamageHandler(object target, ref MyDamageInformation info) { if (Config.NoGrindIndestructible && target is IMySlimBlock) { var block = target as IMySlimBlock; var grid = block.CubeGrid; if (grid != null && !((MyObjectBuilder_CubeGrid)grid.GetObjectBuilder()).DestructibleBlocks) info.Amount = 0; } }
public void DoDamage(float damage, MyDamageType damageType, bool addDirtyParts = true, MyHitInfo? hitInfo = null, bool createDecal = true, long attackerId = 0) { if (!CubeGrid.BlocksDestructionEnabled) return; if(FatBlock is MyCompoundCubeBlock) //jn: TODO think of something better { (FatBlock as MyCompoundCubeBlock).DoDamage(damage, damageType, hitInfo, attackerId); return; } damage *= DamageRatio; // Low-integrity blocks get more damage if (MyPerGameSettings.Destruction) { damage *= DeformationRatio; } ProfilerShort.Begin("FatBlock.DoDamage"); try { if (FatBlock != null && CubeGrid.Physics != null && CubeGrid.Physics.Enabled) //Fatblock dont have physics { var destroyable = FatBlock as IMyDestroyableObject; if (destroyable != null) destroyable.DoDamage(damage, damageType, false, attackerId: attackerId); } } finally { ProfilerShort.End(); } MyDamageInformation damageInfo = new MyDamageInformation(false, damage, damageType, attackerId); if (UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageInfo); MySession.Static.NegativeIntegrityTotal += damageInfo.Amount; AccumulatedDamage += damageInfo.Amount; if (m_componentStack.Integrity - AccumulatedDamage <= MyComponentStack.MOUNT_THRESHOLD) { if (MyPerGameSettings.Destruction && hitInfo.HasValue) { AccumulatedDamage = 0; var gridPhysics = CubeGrid.Physics; float maxDestructionRadius = CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.5f : 3; if(Sync.IsServer) Sandbox.Engine.Physics.MyDestructionHelper.TriggerDestruction(damageInfo.Amount - m_componentStack.Integrity, gridPhysics, hitInfo.Value.Position, hitInfo.Value.Normal, maxDestructionRadius); } else { ApplyAccumulatedDamage(addDirtyParts); } CubeGrid.RemoveFromDamageApplication(this); } else { if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RationEnoughForDamageEffect((Integrity - damage) / MaxIntegrity)) FatBlock.SetDamageEffect(true); if (hitInfo.HasValue && createDecal) CubeGrid.RenderData.AddDecal(Position, Vector3D.Transform(hitInfo.Value.Position, CubeGrid.PositionComp.WorldMatrixInvScaled), Vector3D.TransformNormal(hitInfo.Value.Normal, CubeGrid.PositionComp.WorldMatrixInvScaled), BlockDefinition.PhysicalMaterial.DamageDecal); } if (UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageInfo); m_lastDamage = damage; m_lastAttackerId = attackerId; m_lastDamageType = damageType; return; }
void IMyDestroyableObject.DoDamage(float damage, MyDamageType damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (MarkedToExplode || (!MySession.Static.DestructibleBlocks)) return; //if (!IsFunctional) // return false; if (sync) { if (Sync.IsServer) MySyncHelper.DoDamageSynced(this, damage, damageType, attackerId); } else { MyDamageInformation damageInfo = new MyDamageInformation(false, damage, damageType, attackerId); if (UseDamageSystem) MyDamageSystem.Static.RaiseBeforeDamageApplied(this, ref damageInfo); m_damageType = damageType; if (damageInfo.Amount > 0) { if (UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageInfo); OnDestroy(); if (UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, damageInfo); } } return; }
public static void SetLastDamageInformation(MyDamageInformation lastDamageInformation) { try { // Empty message is sent from the server, we don't want it to rewrite the true damage cause. if (lastDamageInformation.Type == default(MyStringHash)) return; m_lastDamageInformation = lastDamageInformation; } catch (Exception ex) { MyLog.Default.WriteLine(ex); } }