// Mod actions public static void checkDamage(object block, ref MyDamageInformation info) { if (info.Type != MyDamageType.Bullet && info.Type != MyDamageType.Rocket) { return; } var slimBlock = block as IMySlimBlock; if (slimBlock == null) { return; } var dmgBlock = slimBlock as IMyDestroyableObject; if (dmgBlock == null || dmgBlock.Integrity > info.Amount) { return; } var grid = slimBlock.CubeGrid as IMyCubeGrid; if (grid == null) { return; } var deltaDamage = info.Amount - dmgBlock.Integrity; info.Amount = dmgBlock.Integrity; Vector3D pos = grid.GridIntegerToWorld(slimBlock.Position); BoundingSphereD sphere = new BoundingSphereD(pos, deltaDamage / 500f); MyExplosionInfo bomb = new MyExplosionInfo(deltaDamage * 0.8f, deltaDamage * 0.8f, sphere, MyExplosionTypeEnum.BOMB_EXPLOSION, false, true); bomb.CreateParticleEffect = true; MyExplosions.AddExplosion(ref bomb, 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 DamageHandler(IMySlimBlock block, MyDamageInformation damage) { //if (AiSessionCore.WarDeclared) return; //if (Damaged) return; //Damaged = true; IMyPlayer damager; ReactOnDamage(damage, out damager); if (_fighterSetup.DelayedAiEnable) { LoadKeenAi(); } foreach (IMyTimerBlock timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled && x.CustomName.Contains("Damage"))) { timer.Trigger(); } if (!_fighterSetup.CallHelpOnDamage) { return; } foreach (IMyTimerBlock timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled && x.CustomName.Contains("Security"))) { timer.Trigger(); } }
private void DamageHandler(IMySlimBlock Block, MyDamageInformation Damage) { if (Damaged) { return; } Damaged = true; IMyPlayer Damager; ReactOnDamage(Block, Damage, CalmdownTime, out Damager); if (FighterSetup.DelayedAIEnable) { LoadKeenAI(); } foreach (IMyTimerBlock Timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled && x.CustomName.Contains("Damage"))) { Timer.Trigger(); } if (!FighterSetup.CallHelpOnDamage) { return; } foreach (IMyTimerBlock Timer in Term.GetBlocksOfType <IMyTimerBlock>(collect: x => x.IsFunctional && x.Enabled && x.CustomName.Contains("Security"))) { Timer.Trigger(); } }
private static void AfterDamageHandler(object obj, MyDamageInformation damageInfo) { if (!(obj is IMySlimBlock)) { return; } // grind damage is handled by OnBlockIntegrityChanged, which is faster if (damageInfo.Type == MyDamageType.Grind) { return; } IMySlimBlock block = (IMySlimBlock)obj; long gridId = block.CubeGrid.EntityId; Registrar.ForEach((Projector proj) => { SeenHolo sh; if (!proj.m_holoEntities.TryGetValue(gridId, out sh) || !sh.Holo.Render.Visible || !sh.ColouredByIntegrity) { return; } ColourBlock(block, (IMyCubeGrid)sh.Holo); }); }
public void GenericDamageHandler(object DamagedObject, MyDamageInformation Damage) { try { if (DamagedObject == null) { return; } if (!(DamagedObject is IMySlimBlock)) { return; } IMySlimBlock DamagedBlock = DamagedObject as IMySlimBlock; IMyCubeGrid DamagedGrid = DamagedBlock.CubeGrid; long GridID = DamagedGrid.GetTopMostParent().EntityId; if (DamageHandlers.ContainsKey(GridID)) { try { DamageHandlers[GridID].Invoke(DamagedBlock, Damage); } catch (Exception Scrap) { LogError("DamageHandler.Invoke", Scrap); } } } catch (Exception Scrap) { LogError("GenericDamageHandler", Scrap); } }
internal void BeforeDamageHandler(object o, ref MyDamageInformation info) { var slim = o as IMySlimBlock; if (slim != null) { var cube = slim.FatBlock as MyCubeBlock; var grid = (MyCubeGrid)slim.CubeGrid; if (info.IsDeformation && info.AttackerId > 0 && DeformProtection.Contains(grid)) { Log.Line($"BeforeDamageHandler1"); info.Amount = 0f; return; } CoreComponent comp; if (cube != null && ArmorCubes.TryGetValue(cube, out comp)) { Log.Line($"BeforeDamageHandler2"); info.Amount = 0f; if (info.IsDeformation && info.AttackerId > 0) { DeformProtection.Add(cube.CubeGrid); LastDeform = Tick; } } } }
private void BattleDamage(object target, ref MyDamageInformation info) { if (target is IMyCharacter || Instance._lobbyRunning) { info.Amount = 0; } }
/// <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> /// Determines if damage was done by player. /// </summary> /// <param name="Damager">Provides player who did the damage. Null if damager object is not a player.</param> public static bool IsDoneByPlayer(this MyDamageInformation Damage, out IMyPlayer Damager) { Damager = null; try { IMyEntity AttackerEntity = MyAPIGateway.Entities.GetEntityById(Damage.AttackerId); if (AttackerEntity == null) { AISessionCore.DebugWrite("Damage.IsDoneByPlayer", "Attacker entity was not found.", AntiSpam: false); return(false); } if (AttackerEntity is IMyMeteor) { return(false); } if (AttackerEntity is IMyWarhead) { return(IsDamagedByPlayerWarhead(AttackerEntity as IMyWarhead, out Damager)); } if (AttackerEntity is IMyGunBaseUser) { return(IsDamagedByPlayer(AttackerEntity as IMyGunBaseUser, out Damager)); } if (AttackerEntity is IMyEngineerToolBase) { return(IsDamagedByPlayer(AttackerEntity as IMyEngineerToolBase, out Damager)); } AttackerEntity = AttackerEntity.GetTopMostParent(); if (AttackerEntity == null) { AISessionCore.DebugWrite("Damage.IsDoneByPlayer", "Cannot acquire the attacker's topmost entity", AntiSpam: false); return(false); } if (AttackerEntity is IMyCubeGrid) { IMyCubeGrid Grid = AttackerEntity as IMyCubeGrid; if (Grid.IsPirate()) { return(false); } if (Grid.IsOwnedByNobody()) { return(IsDamagedByPlayerInNeutralGrid(Grid, out Damager)); } return(IsDamagedByPlayerGrid(Grid, out Damager)); } return(false); } catch (Exception Scrap) { AISessionCore.LogError("Damage.IsDoneByPlayer", new Exception("General crash.", Scrap)); return(false); } }
public void GenericDamageHandler(object target, MyDamageInformation info) { if (target == null || !(target is IMySlimBlock)) { return; } IMySlimBlock block = target as IMySlimBlock; IMyCubeGrid grid = block.CubeGrid; long gridId = grid.GetTopMostParent().EntityId; IMyFaction damageeFaction = grid.GetOwningFaction(); IMyPlayer damagerPlayer; IMyFaction damagerFaction; IMyCubeGrid damagerShip; if (damageeFaction != null && info.GetSource(out damagerPlayer, out damagerFaction, out damagerShip)) { if (damagerFaction == null) { return; } EmpireData damagerEmpire = damagerFaction.GetEmpire(); foreach (EmpireManager empire in m_empireManagers) { if (empire.GetData().empireTag == damageeFaction.Tag) { empire.TakeStandingsHit(damagerEmpire); break; } } } }
/// <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); } }
/// <summary> /// Damage Handler: Prevent Damage from BuildAndRepairSystem /// </summary> public void BeforeDamageHandlerNoDamageByBuildAndRepairSystem(object target, ref MyDamageInformation info) { try { if (info.Type == MyDamageType.Weld) { if (target is IMyCharacter) { var logicalComponent = BuildAndRepairSystems.GetValueOrDefault(info.AttackerId); if (logicalComponent != null) { var terminalBlock = logicalComponent.Entity as IMyTerminalBlock; if (Mod.Log.ShouldLog(Logging.Level.Communication)) { Mod.Log.Write(Logging.Level.Communication, "BuildAndRepairSystemMod: Prevent Damage from BuildAndRepairSystem={0} Amount={1}", terminalBlock != null ? terminalBlock.CustomName : logicalComponent.Entity.DisplayName, info.Amount); } info.Amount = 0; } } } } catch (Exception e) { Mod.Log.Error("BuildAndRepairSystemMod: Exception in BeforeDamageHandlerNoDamageByBuildAndRepairSystem: Source={0}, Message={1}", e.Source, e.Message); } }
private static void GodModeDamageHandler_Server(object target, ref MyDamageInformation info) { if (target is IMyCharacter && _players.Any(p => target == p.Character)) { info.Amount = 0; } }
private void GodModeDamageHandler_Client(object target, ref MyDamageInformation info) { if (GodModeEnabled && target is IMyCharacter && target == MyAPIGateway.Session.Player.Character) { info.Amount = 0; } }
private void DamageHandler(object target, ref MyDamageInformation info) { if (!PluginSettings.Instance.ProtectedEnabled) { return; } MySlimBlock block = target as MySlimBlock; if (block == null) { return; } MyCubeGrid grid = block.CubeGrid; foreach (ProtectedItem item in PluginSettings.Instance.ProtectedItems) { if (!item.Enabled || !item.ProtectDamage || item.EntityId != grid.EntityId) { continue; } if (DateTime.Now - _lastLog > TimeSpan.FromSeconds(1)) { _lastLog = DateTime.Now; Essentials.Log.Info($"Protected entity {grid.DisplayName}:{grid.EntityId}."); } if (!item.LogOnly) { info.Amount = 0; } } }
/// <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 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 ) ); } //} } } }
private void GenericDamageHandler(object damagedObject, MyDamageInformation damage) { try { if (!(damagedObject is IMySlimBlock)) { return; } IMySlimBlock damagedBlock = (IMySlimBlock)damagedObject; IMyCubeGrid damagedGrid = damagedBlock.CubeGrid; long gridId = damagedGrid.EntityId; if (!DamageHandlers.ContainsKey(gridId)) { return; } try { DamageHandlers[gridId].Invoke(damagedBlock, damage); } catch (Exception Scrap) { LogErrorInDebugLog("GenericDamageHandler", "Grid damage handler threw: ", Scrap); } } catch (Exception Scrap) { LogErrorInDebugLog("GenericDamageHandler", "Damage handler procedure bugged out: ", Scrap); } }
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); }
private void BeforeDamage(object target, ref MyDamageInformation info) { if (info.Amount == 0) { return; } var slim = target as IMySlimBlock; if (slim == null) { return; } // if any of the protection blocks are on this grid then protect it foreach (var block in ProtectionBlocks) { // checks for same grid-group to extend protection to piston/rotors/wheels but no connectors (change link type to Physical to include those) // same grid only check: block.CubeGrid == slim.CubeGrid if (MyAPIGateway.GridGroups.HasConnection(block.CubeGrid, slim.CubeGrid, GridLinkTypeEnum.Mechanical)) { info.Amount = 0; return; } } }
/// <summary> /// Handles the damage in ProtectionAreas if Protection is enabled. This method is desinged for server side use and will notify the players if they tried to damage the wrong block. /// </summary> /// <param name="target"></param> /// <param name="info"></param> private static void DamageHandler_Server(object target, ref MyDamageInformation info) { if (!Config.ProtectionEnabled) { return; } IMySlimBlock block = target as IMySlimBlock; if (block != null) { IMyPlayer player; if (CanDamageBlock(info.AttackerId, block, info.Type, out player)) { return; } info.Amount = 0; // notify player DateTime time; if (player != null && (!_sentFailedMessage.TryGetValue(player, out time) || DateTime.Now - time >= TimeSpan.FromMilliseconds(GrindFailedMessageInterval))) { MessageClientNotification.SendMessage(player.SteamUserId, "You are not allowed to damage this block.", GrindFailedMessageInterval, MyFontEnum.Red); _sentFailedMessage.Update(player, DateTime.Now); } return; } // disable pvp in PAs 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; } }
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, this.GetInventory()); block.MoveItemsFromConstructionStockpile(this.GetInventory()); if (block.UseDamageSystem) { MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo); } if (block.IsFullyDismounted) { if (block.FatBlock != null && block.FatBlock.HasInventory) { EmptyBlockInventories(block.FatBlock); } if (block.UseDamageSystem) { MyDamageSystem.Static.RaiseDestroyed(block, damageInfo); } block.SpawnConstructionStockpile(); block.CubeGrid.RazeBlock(block.Min); } } if (targets.Count > 0) { SetBuildingMusic(200); } } m_wantsToShake = targets.Count != 0; return(targets.Count != 0); }
private void Grind() { var block = GetTargetBlock(); 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 == 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) { //HACK to not grind yourself if (targetDestroyable is MyCharacter && (targetDestroyable as MyCharacter) == Owner) { return; } targetDestroyable.DoDamage(20, MyDamageType.Grind, true, attackerId: Owner != null ? Owner.EntityId : 0); } }
/// <summary> /// Determines if damage was done by player. /// </summary> /// <param name="damage"></param> /// <param name="damager">Provides player who did the damage. Null if damager object is not a player.</param> public static bool IsDoneByPlayer(this MyDamageInformation damage, out IMyPlayer damager) { damager = null; try { IMyEntity attackerEntity = MyAPIGateway.Entities.GetEntityById(damage.AttackerId); if (damage.IsDeformation || damage.AttackerId == 0 || attackerEntity == null) { return(false); } if (attackerEntity is IMyMeteor) { return(false); } if (attackerEntity is IMyWarhead) { return(IsDamagedByPlayerWarhead(attackerEntity as IMyWarhead, out damager)); } if (attackerEntity is IMyEngineerToolBase) { return(IsDamagedByPlayer(attackerEntity as IMyEngineerToolBase, out damager)); } if (attackerEntity is IMyGunBaseUser) { return(IsDamagedByPlayer(attackerEntity as IMyGunBaseUser, out damager)); } attackerEntity = attackerEntity.GetTopMostParent(); if (attackerEntity == null) { AiSessionCore.DebugLog?.WriteToLog("IsDoneByPlayer", $"attackerEntity was NULL"); AiSessionCore.DebugWrite("Damage.IsDoneByPlayer", "Cannot acquire the attacker's topmost entity", antiSpam: false); return(false); } if (!(attackerEntity is IMyCubeGrid)) { return(false); } IMyCubeGrid grid = attackerEntity as IMyCubeGrid; if (grid.IsPirate()) { return(false); } //grid.GetOwnerFaction() return(grid.IsOwnedByNobody() ? IsDamagedByPlayerInNeutralGrid(grid, out damager) : IsDamagedByPlayerGrid(grid, out damager)); } catch (Exception scrap) { AiSessionCore.LogError("Damage.IsDoneByPlayer", new Exception("General crash.", scrap)); return(false); } }
/** * Determine the source Player and Ship associated with a damage event. * Returns false if the event was environmental, or no player/ship can be determined. */ public static bool GetSource( this MyDamageInformation info, out IMyPlayer damagePlayer, out IMyFaction damageFaction, out IMyCubeGrid damageShip) { damagePlayer = null; damageFaction = null; damageShip = null; IMyEntity entity = MyAPIGateway.Entities.GetEntityById(info.AttackerId); if (entity == null) { return false; } if (entity is IMyMeteor) { return false; } if (entity is IMyThrust) { return false; } if (entity is IMyWarhead) { return GetPlayerByWarhead( entity as IMyWarhead, out damagePlayer, out damageFaction); } entity = entity.GetTopMostParent(); if (entity == null) { return false; } if (entity is IMyCubeGrid) { damageShip = entity as IMyCubeGrid; damagePlayer = damageShip.GetControllingPlayer(); if (damagePlayer == null) { damagePlayer = damageShip.GetOwningPlayer(); } damageFaction = damageShip.GetOwningFaction(); } else { if (entity is IMyEngineerToolBase) { return GetPlayerByTool( entity as IMyEngineerToolBase, out damagePlayer, out damageFaction); } if (entity is IMyGunBaseUser) { return GetPlayerByWeapon( entity as IMyGunBaseUser, out damagePlayer, out damageFaction); } } return damageShip != null || damageFaction != null || damagePlayer != null; }
private void GridDamaged(IMyEntity grid, MyDamageInformation info) { IDamageObserver observer; if (damageObservers.TryGetValue(grid.EntityId, out observer)) { //MyAPIGateway.Utilities.ShowNotification("Attacker ID: " + info.AttackerId); observer.MaliciouslyDamaged(); } }
public void CheckDamage(object block, ref MyDamageInformation info) { if (info.Type == MyDamageType.Deformation) // fix { } if (Shields.Count == 0 || info.Type != MyDamageType.Bullet) { return; } var generator = Shields[0]; var ent = block as IMyEntity; var slimBlock = block as IMySlimBlock; if (slimBlock != null) { ent = slimBlock.CubeGrid; } var dude = block as IMyCharacter; if (dude != null) { ent = dude; } if (ent == null) { return; } var isProtected = false; foreach (var shield in Shields) { if (shield.InHash.Contains(ent)) { isProtected = true; generator = shield; } } if (!isProtected) { return; } IMyEntity attacker; if (!MyAPIGateway.Entities.TryGetEntityById(info.AttackerId, out attacker)) { return; } if (generator.InHash.Contains(attacker)) { return; } info.Amount = 0f; }
void DestroyHandler(object target, MyDamageInformation damage) { if (damage.Type == MyDamageType.Grind) { MyDefinitionId blockId = new MyDefinitionId(); MyRelationsBetweenPlayerAndBlock relation = new MyRelationsBetweenPlayerAndBlock(); string faction = "none"; IMyFaction plFaction; List <long> owners = new List <long>(); long ownerID = -1; IMyEntity ent; MyAPIGateway.Entities.TryGetEntityById(damage.AttackerId, out ent); var hand = ent as IMyHandheldGunObject <MyToolBase>; IMyPlayer pl; if (hand != null && hand.DefinitionId.TypeId == typeof(MyObjectBuilder_AngleGrinder)) { var players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players); pl = players.FirstOrDefault(p => p.IdentityId.Equals(hand.OwnerIdentityId)); plFaction = MyAPIGateway.Session.Factions.TryGetPlayerFaction(pl.IdentityId); } else { //If nothing was returned from Entity return; } if (target is IMySlimBlock) { IMySlimBlock slim = target as IMySlimBlock; blockId = slim.BlockDefinition.Id; relation = slim.FatBlock.GetUserRelationToOwner(pl.IdentityId); faction = slim.FatBlock.GetOwnerFactionTag(); owners = slim.CubeGrid.SmallOwners; ownerID = slim.OwnerId; } else if (target is IMyCubeBlock) //just in cause { var fat = target as IMyCubeBlock; blockId = fat.BlockDefinition; relation = fat.GetUserRelationToOwner(pl.IdentityId); faction = fat.GetOwnerFactionTag(); owners = fat.CubeGrid.SmallOwners; ownerID = fat.OwnerId;//fat.OwnerBlock.BuiltBy; } MyLog.Default.WriteLine($"OwnerID {ownerID} Owner {relation.ToString()} - Player {pl.IdentityId} Faction {faction} - Player Faction {plFaction.Tag} Built By {owners.Count}"); if (owners.Count > 0 && faction != plFaction.Tag && !owners.Contains(pl.IdentityId)) { CalculatePlayers(blockId, ent, pl); } } }
private void CauseKeenHacks(object target, MyDamageInformation info) { // Missles apply damage by blowing up. it is considered a damage by player... if (target.GetType().Name == "MyMissile") { IMyEntity entity = MyAPIGateway.Entities.GetEntityById(info.AttackerId); if (entity != null) { entity.Name = (target as IMyEntity).Name; // more hacks } } }
private void BeforeDamageApplied(object target, ref MyDamageInformation info) { IMySlimBlock slim = target as IMySlimBlock; if (slim == null) return; IMyVoxelBase voxel; if (!miners.TryGetValue(slim.CubeGrid, out voxel)) return; if (voxel.EntityId == info.AttackerId) info.Amount = 0f; }
/// <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 DoDamageInternal(float damage, MyStringHash damageType, bool addDirtyParts = true, MyHitInfo? hitInfo = null, long attackerId = 0) { if (!CubeGrid.BlocksDestructionEnabled && !ForceBlockDestructible) return; damage *= DamageRatio; // Low-integrity blocks get more damage if (MyPerGameSettings.Destruction || MyFakes.ENABLE_VR_BLOCK_DEFORMATION_RATIO) { 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; Debug.Assert(damageInfo.Amount > 0); 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, attackerId: attackerId); } CubeGrid.RemoveFromDamageApplication(this); } else { if (MyFakes.SHOW_DAMAGE_EFFECTS && FatBlock != null && BlockDefinition.RatioEnoughForDamageEffect(BuildIntegrity / MaxIntegrity) == false && BlockDefinition.RatioEnoughForDamageEffect((Integrity - damage) / MaxIntegrity)) FatBlock.SetDamageEffect(true); } if (UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(this, damageInfo); m_lastDamage = damage; m_lastAttackerId = attackerId; m_lastDamageType = damageType; }
private void DamageHandler( object target, ref MyDamageInformation info ) { if ( !PluginSettings.Instance.ProtectedEnabled ) return; MySlimBlock block = target as MySlimBlock; if ( block == null ) return; MyCubeGrid grid = block.CubeGrid; foreach ( ProtectedItem item in PluginSettings.Instance.ProtectedItems ) { if ( !item.Enabled || !item.ProtectDamage || item.EntityId != grid.EntityId ) continue; if ( DateTime.Now - _lastLog > TimeSpan.FromSeconds( 1 ) ) { _lastLog = DateTime.Now; Essentials.Log.Info( $"Protected entity {grid.DisplayName}:{grid.EntityId}." ); } if ( !item.LogOnly ) info.Amount = 0; } }
/// <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); }
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, this.GetInventory()); block.MoveItemsFromConstructionStockpile(this.GetInventory()); if (block.UseDamageSystem) MyDamageSystem.Static.RaiseAfterDamageApplied(block, damageInfo); if (block.IsFullyDismounted) { if (block.FatBlock != null && block.FatBlock.HasInventory) { EmptyBlockInventories(block.FatBlock); } if(block.UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(block, damageInfo); block.SpawnConstructionStockpile(); block.CubeGrid.RazeBlock(block.Min); } } if (targets.Count > 0) SetBuildingMusic(200); } m_wantsToShake = targets.Count != 0; return targets.Count != 0; }
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 bool DoDamage(float damage, MyStringHash damageType, bool updateSync, long attackerId = 0) { if (damageType != MyDamageType.Suicide && ControllerInfo.IsLocallyControlled()) { const float maxShake = 5.0f; MySector.MainCamera.CameraShake.AddShake(maxShake * damage / (damage + maxShake)); } 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! } } if (damage >= 0f && MySession.Static != null && MyMusicController.Static != null) { if (this == MySession.Static.LocalCharacter && attacker is MyVoxelPhysics == false && attacker is MyCubeGrid == false) MyMusicController.Static.Fighting(false, (int)damage * 3);//not fall damage else if (attacker == MySession.Static.LocalCharacter) MyMusicController.Static.Fighting(false, (int)damage * 2);//attack other character else if (attacker is IMyGunBaseUser && (attacker as IMyGunBaseUser).Owner as MyCharacter == MySession.Static.LocalCharacter) MyMusicController.Static.Fighting(false, (int)damage * 2);//attack other character with gun else if (MySession.Static.ControlledEntity == attacker) MyMusicController.Static.Fighting(false, (int)damage);//attack other character with turret } } 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); if (updateSync) TriggerCharacterAnimationEvent("hurt", true); else AnimationController.TriggerAction(MyAnimationVariableStorageHints.StrIdActionHurt); return true; }
//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) { if (!m_grid.BlocksDestructionEnabled) return 0; int blocksDeformed = 0; offsetThreshold /= m_grid.GridSizeEnum == MyCubeSize.Large ? 1 : 5; float roundSize = m_grid.GridSize / MyGridSkeleton.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 * MyGridSkeleton.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 = MyGridSkeleton.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 * MyGridSkeleton.BoneDensity); maxOffset = Vector3I.Min(maxOffset, m_grid.Max * MyGridSkeleton.BoneDensity); Vector3I minDirtyBone = Vector3I.MaxValue; Vector3I maxDirtyBone = Vector3I.MinValue; ProfilerShort.Begin("Get bones"); Debug.Assert(m_tmpBoneList.Count == 0, "Temporary dictionary not cleared properly"); m_grid.GetExistingBones(minOffset, maxOffset, m_tmpBoneList, damageInfo); ProfilerShort.End(); ProfilerShort.Begin("Deform bones"); Vector3 bone; Vector3I baseOffset = gridPos * MyGridSkeleton.BoneDensity; float boneDensityR = 1.0f / MyGridSkeleton.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); } } } m_tmpBoneList.Clear(); 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; }
private static void AfterDamageHandler(object obj, MyDamageInformation damageInfo) { if (!(obj is IMySlimBlock)) return; // grind damage is handled by OnBlockIntegrityChanged, which is faster if (damageInfo.Type == MyDamageType.Grind) return; IMySlimBlock block = (IMySlimBlock)obj; long gridId = block.CubeGrid.EntityId; Registrar.ForEach((Projector proj) => { SeenHolo sh; if (!proj.m_holoEntities.TryGetValue(gridId, out sh) || !sh.Holo.Render.Visible || !sh.ColouredByIntegrity) return; ColourBlock(block, (IMyCubeGrid)sh.Holo); }); }
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 (MySession.Static != null && Owner == MySession.Static.LocalCharacter && MyMusicController.Static != null) MyMusicController.Static.Building(250); 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; if (Owner != null && Owner.ControllerInfo.IsLocallyControlled() && (Owner.IsInFirstPersonView || Owner.ForceFirstPersonCamera)) PerformCameraShake(); } 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 (Owner != null && Owner.ControllerInfo.IsLocallyControlled() && (Owner.IsInFirstPersonView || Owner.ForceFirstPersonCamera)) PerformCameraShake(); } if (block != null || targetDestroyable != null) { m_actualSound = MyMaterialPropertiesHelper.Static.GetCollisionCue(MyMaterialPropertiesHelper.CollisionType.Start, m_source, target); } }
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 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(); } } }
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); } }
/// <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); }
void IMyCharacter.Kill(object statChangeData) { MyDamageInformation damageInfo = new MyDamageInformation(); if (statChangeData != null) damageInfo = (MyDamageInformation)statChangeData; Kill(true, damageInfo); }
bool IMyDestroyableObject.DoDamage(float damage, MyStringHash damageType, bool sync, MyHitInfo? hitInfo, long attackerId) { if (MarkedToExplode || (!MySession.Static.DestructibleBlocks)) return false; //if (!IsFunctional) // return false; if (sync) { if (Sync.IsServer) MySyncDamage.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 true; }
private void KillCharacter(MyDamageInformation damageInfo) { Debug.Assert(Sync.IsServer, "KillCharacter called from client"); Kill(false, damageInfo); MyMultiplayer.RaiseEvent(this, x => x.OnKillCharacter, damageInfo); }
void OnKillCharacter(MyDamageInformation damageInfo) { Kill(false, damageInfo); }
public bool DoDamage(float damage, MyStringHash damageType, bool sync, long attackerId) { if (MarkedForClose) return false; if (sync) { if (Sync.IsServer) { MySyncDamage.DoDamageSynced(this, damage, damageType, attackerId); return true; } else { return false; } } 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; } if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this); } } else { if (Sync.IsServer) { MyFloatingObjects.RemoveFloatingObject(this, (MyFixedPoint)damageinfo.Amount); } } } else { m_health -= 10 * 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 true; 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 (ItemDefinition != null && ItemDefinition.DestroyedPieceId.HasValue && Sync.IsServer) { MyPhysicalItemDefinition pieceDefinition; if (MyDefinitionManager.Static.TryGetPhysicalItemDefinition(ItemDefinition.DestroyedPieceId.Value, out pieceDefinition)) { MyFloatingObjects.Spawn(pieceDefinition, WorldMatrix.Translation, WorldMatrix.Forward, WorldMatrix.Up, ItemDefinition.DestroyedPieces); } else { System.Diagnostics.Debug.Fail("Trying to spawn piece of the item after being destroyed, but definition wasn't found! - " + ItemDefinition.DestroyedPieceId.Value); } } if (UseDamageSystem) MyDamageSystem.Static.RaiseDestroyed(this, damageinfo); } } return true; }
public static void BeforeDamageHandler(object target, ref MyDamageInformation info) { try { Logger.Log.Debug("BeaconSecurity.BeforeDamageHandler {0} - {1}, {2}, {3}", target, info.Amount, info.Type, info.AttackerId); IMySlimBlock targetBlock = target as IMySlimBlock; if (targetBlock == null) return; MyCubeGrid targetGrid = targetBlock.CubeGrid as MyCubeGrid; if (targetGrid == null) return; if (!targetGrid.DestructibleBlocks) { Logger.Log.Debug(" * DestructibleBlocks {0}, so DAMAGE IGNORED...", targetGrid.DestructibleBlocks); info.Amount = 0f; } bool owner = false; IMyFunctionalBlock targetFunctionalBlock = targetBlock.FatBlock as IMyFunctionalBlock; IMyEntity attackerEntity; Logger.Log.Debug(" targetFunctionalBlock '{0}'", targetFunctionalBlock); if (targetFunctionalBlock != null && MyAPIGateway.Entities.TryGetEntityById(info.AttackerId, out attackerEntity)) { if (info.Type == MyDamageType.Grind) { IMyPlayer player = null; if (attackerEntity is IMyShipGrinder) player = MyAPIGateway.Players.GetPlayerControllingEntity(attackerEntity.GetTopMostParent()); if (player == null) { List<IMyPlayer> players = new List<IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players); double nearestDistance = 5.0f; foreach (var pl in players) { IMyEntity character = pl.Controller.ControlledEntity as IMyEntity; if (character != null) { var distance = (character.GetPosition() - attackerEntity.GetPosition()).LengthSquared(); if (distance > nearestDistance) continue; nearestDistance = distance; player = pl; } } } if (player != null) { MyRelationsBetweenPlayerAndBlock relation = targetFunctionalBlock.GetUserRelationToOwner(player.IdentityId); Logger.Log.Debug(" relation '{0}' is {1} == {2}", relation, player.IdentityId, targetFunctionalBlock.OwnerId); owner = (relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.NoOwnership) ? true : false; } } } // check admins grids if (Core.Settings != null && Core.Settings.Indestructible.Contains(targetGrid.EntityId)) { if (owner && Core.Settings.IndestructibleGrindOwner || owner && Core.Settings.IndestructibleOverrideGrindOwner.Contains(targetGrid.EntityId)) { // пилить можно Logger.Log.Debug(" * Target '{0}' has own property, so DAMAGE permit...", targetGrid.DisplayName); } else { // пилить нельзя Logger.Log.Debug(" * Target '{0}' in indestructible list, so DAMAGE IGNORED...", targetGrid.DisplayName); info.Amount = 0f; } } } catch (Exception ex) { Logger.Log.Error("Exception BeforeDamageHandler in {0}", ex.Message); } }