private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List <Body> ignoredBodies) { Body targetBody = Submarine.PickBody(rayStart, rayEnd, ignoredBodies, Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair, false); if (ExtinquishAmount > 0.0f && item.CurrentHull != null) { List <FireSource> fireSourcesInRange = new List <FireSource>(); //step along the ray in 10% intervals, collecting all fire sources in the range for (float x = 0.0f; x <= Submarine.LastPickedFraction; x += 0.1f) { Vector2 displayPos = ConvertUnits.ToDisplayUnits(rayStart + (rayEnd - rayStart) * x); displayPos += item.CurrentHull.Submarine.Position; Hull hull = Hull.FindHull(displayPos, item.CurrentHull); if (hull == null) { continue; } foreach (FireSource fs in hull.FireSources) { if (fs.IsInDamageRange(displayPos, 125.0f) && !fireSourcesInRange.Contains(fs)) { fireSourcesInRange.Add(fs); } } } foreach (FireSource fs in fireSourcesInRange) { fs.Extinguish(deltaTime, ExtinquishAmount); } } if (targetBody == null || targetBody.UserData == null) { return; } pickedPosition = Submarine.LastPickedPosition; Structure targetStructure; Character targetCharacter; Limb targetLimb; Item targetItem; string effectidentifier = ""; if ((targetStructure = (targetBody.UserData as Structure)) != null) { if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Name)) { return; } if (targetStructure.IsPlatform) { return; } int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition)); if (sectionIndex < 0) { return; } #if CLIENT Vector2 progressBarPos = targetStructure.SectionPosition(sectionIndex); if (targetStructure.Submarine != null) { progressBarPos += targetStructure.Submarine.DrawPosition; } var progressBar = user.UpdateHUDProgressBar( targetStructure, progressBarPos, 1.0f - targetStructure.SectionDamage(sectionIndex) / targetStructure.Health, Color.Red, Color.Green); if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); } Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition); if (targetStructure.Submarine != null) { particlePos += targetStructure.Submarine.DrawPosition; } foreach (var emitter in ParticleEmitterHitStructure) { float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi); emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi); } #endif /* * if (GameMain.Server != null) * { * //Check if this tool is meant to destroy walls first and is a submarine body * if (StructureFixAmount < 0f && user != null && targetStructure.Submarine != null) * { * //50% Remaining Integrity (Now has a gap!) * if ((1f - (targetStructure.SectionDamage(sectionIndex) / targetStructure.Health)) >= 0.5f && (1f - ((targetStructure.SectionDamage(sectionIndex) + (-StructureFixAmount * degreeOfSuccess)) / targetStructure.Health)) < 0.5f) * { * //Respawn Shuttle * if (targetStructure.Submarine == GameMain.Server?.respawnManager?.respawnShuttle) * { * GameMain.Server.ServerLog.WriteLine(user.LogName + " Cut a Hull piece on Respawn Shuttle: 50% Integrity.", Networking.ServerLog.MessageType.Attack); * } * //Coalition submarine * else if (targetStructure.Submarine == Submarine.MainSubs[0]) * { * GameMain.Server.ServerLog.WriteLine(user.LogName + " Cut a Hull piece on Coalition Submarine: 50% Integrity.", Networking.ServerLog.MessageType.Attack); * } * //Renegade Submarine * else if (targetStructure.Submarine == Submarine.MainSubs[1]) * { * GameMain.Server.ServerLog.WriteLine(user.LogName + " Cut a Hull piece on Renegade Submarine: 50% Integrity.", Networking.ServerLog.MessageType.Attack); * } * else * { * GameMain.Server.ServerLog.WriteLine(user.LogName + @" Cut a Hull piece on Shuttle """ + targetStructure.Submarine.Name + @"""" + ": 50% Integrity.", Networking.ServerLog.MessageType.Attack); * } * } * //0% Remaining Integrity * if ((1f - (targetStructure.SectionDamage(sectionIndex) / targetStructure.Health)) > 0.00f && (1f - ((targetStructure.SectionDamage(sectionIndex) + (-StructureFixAmount * degreeOfSuccess)) / targetStructure.Health)) < 0.00f) * { * //Respawn Shuttle * if (targetStructure.Submarine == GameMain.Server?.respawnManager?.respawnShuttle) * { * GameMain.Server.ServerLog.WriteLine(user.LogName + " Cut a Hull piece on Respawn Shuttle: 0% Integrity.", Networking.ServerLog.MessageType.Attack); * } * //Coalition submarine * else if (targetStructure.Submarine == Submarine.MainSubs[0]) * { * GameMain.Server.ServerLog.WriteLine(user.LogName + " Cut a Hull piece on Coalition Submarine: 0% Integrity.", Networking.ServerLog.MessageType.Attack); * } * //Renegade Submarine * else if (targetStructure.Submarine == Submarine.MainSubs[1]) * { * GameMain.Server.ServerLog.WriteLine(user.LogName + " Cut a Hull piece on Renegade Submarine: 0% Integrity.", Networking.ServerLog.MessageType.Attack); * } * else * { * GameMain.Server.ServerLog.WriteLine(user.LogName + @" Cut a Hull piece on Shuttle """ + targetStructure.Submarine.Name + @"""" + ": 0% Integrity.", Networking.ServerLog.MessageType.Attack); * } * } * } * } */ targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess, user); //if the next section is small enough, apply the effect to it as well //(to make it easier to fix a small "left-over" section) for (int i = -1; i < 2; i += 2) { int nextSectionLength = targetStructure.SectionLength(sectionIndex + i); if ((sectionIndex == 1 && i == -1) || (sectionIndex == targetStructure.SectionCount - 2 && i == 1) || (nextSectionLength > 0 && nextSectionLength < Structure.WallSectionSize * 0.3f)) { //targetStructure.HighLightSection(sectionIndex + i); targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess); } } } else if ((targetLimb = (targetBody.UserData as Limb)) != null) { if (item.ContainedItems != null && item.ContainedItems.Length > 0) { effectidentifier = item.Name + " (" + string.Join(", ", Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name)) + ")"; } else { effectidentifier = item.Name; } float previoushealth = targetLimb.character.Health; targetLimb.character.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user, effectidentifier); if (GameMain.NilMod.EnableGriefWatcher && NilMod.NilModGriefWatcher.PlayerIncapaciteDamage && previoushealth > 0f && targetLimb.character.Health <= 0f) { Barotrauma.Networking.Client attackingclient = GameMain.Server.ConnectedClients.Find(c => c.Character != null && c.Character == user); Barotrauma.Networking.Client targetclient = GameMain.Server.ConnectedClients.Find(c => c.Character != null && !c.Character.IsDead && c.Character == targetLimb.character); if (attackingclient != null && targetclient != null) { NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName + " Incapacitated player " + targetclient.Character.LogName + " with " + effectidentifier, attackingclient); } } #if CLIENT Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition); if (targetLimb.character.Submarine != null) { particlePos += targetLimb.character.Submarine.DrawPosition; } foreach (var emitter in ParticleEmitterHitCharacter) { float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi); emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi); } #endif } else if ((targetCharacter = (targetBody.UserData as Character)) != null) { if (item.ContainedItems != null && item.ContainedItems.Length > 0) { effectidentifier = item.Name + " (" + string.Join(", ", Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name)) + ")"; } else { effectidentifier = item.Name; } float previoushealth = targetCharacter.Health; targetCharacter.AddDamage(CauseOfDeath.Damage, -LimbFixAmount * degreeOfSuccess, user, effectidentifier); if (GameMain.NilMod.EnableGriefWatcher && NilMod.NilModGriefWatcher.PlayerIncapaciteDamage && previoushealth > 0f && targetCharacter.Health <= 0f) { Barotrauma.Networking.Client attackingclient = GameMain.Server.ConnectedClients.Find(c => c.Character != null && c.Character == user); Barotrauma.Networking.Client targetclient = GameMain.Server.ConnectedClients.Find(c => c.Character != null && !c.Character.IsDead && c.Character == targetCharacter); if (attackingclient != null && targetclient != null) { NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName + " Incapacitated player " + targetclient.Character.LogName + " with " + effectidentifier, attackingclient); } } #if CLIENT Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition); if (targetCharacter.Submarine != null) { particlePos += targetCharacter.Submarine.DrawPosition; } foreach (var emitter in ParticleEmitterHitCharacter) { float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi); emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi); } #endif } else if ((targetItem = (targetBody.UserData as Item)) != null) { targetItem.IsHighlighted = true; float prevCondition = targetItem.Condition; if (item.ContainedItems != null && item.ContainedItems.Length > 0) { effectidentifier = item.Name + " (" + string.Join(", ", Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name)) + ")"; } else { effectidentifier = item.Name; } ApplyStatusEffectsOnTarget(deltaTime, ActionType.OnUse, targetItem.AllPropertyObjects, user, effectidentifier); #if CLIENT if (item.Condition != prevCondition) { Vector2 progressBarPos = targetItem.DrawPosition; var progressBar = user.UpdateHUDProgressBar( targetItem, progressBarPos, targetItem.Condition / 100.0f, Color.Red, Color.Green); if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); } Vector2 particlePos = ConvertUnits.ToDisplayUnits(pickedPosition); if (targetItem.Submarine != null) { particlePos += targetItem.Submarine.DrawPosition; } foreach (var emitter in ParticleEmitterHitItem) { float particleAngle = item.body.Rotation + ((item.body.Dir > 0.0f) ? 0.0f : MathHelper.Pi); emitter.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi); } } #endif } }
protected void Apply(float deltaTime, Entity entity, List <ISerializableEntity> targets, List <int> cancelledEffects = null, Character causecharacter = null, string identifier = "") { #if CLIENT if (sound != null) { if (loopSound) { if (!Sounds.SoundManager.IsPlaying(sound)) { sound.Play(entity.WorldPosition); } else { sound.UpdatePosition(entity.WorldPosition); } } else { sound.Play(entity.WorldPosition); } } #endif if (identifier == "") { identifier = "statuseffect"; } for (int i = 0; i < useItemCount; i++) { foreach (Item item in targets.FindAll(t => t is Item).Cast <Item>()) { if (item.Removed) { continue; } item.Use(deltaTime, targets.FirstOrDefault(t => t is Character) as Character, causecharacter, identifier); } } if (removeItem) { foreach (Item item in targets.FindAll(t => t is Item).Cast <Item>()) { Entity.Spawner?.AddToRemoveQueue(item); } } if (duration > 0.0f) { DurationListElement element = new DurationListElement(); element.Parent = this; element.Timer = duration; element.Entity = entity; element.Targets = targets; if (cancelledEffects != null) { element.CancelledEffects = cancelledEffects; } element.causecharacter = causecharacter; element.identifier = identifier; /* if (!target.SerializableProperties.TryGetValue(propertyNames[i], out property)) continue; * * if (duration > 0.0f) * { * if (GameMain.Server != null) * { * if (target is Character) * { * Character effectedcharacter = (Character)target; * * if (GameMain.NilMod.LogStatusEffectStun && property.Name.ToLowerInvariant() == "health" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " health per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack); * } * else if (GameMain.NilMod.LogStatusEffectHealth && property.Name.ToLowerInvariant() == "health" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " health per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack); * } * else if (GameMain.NilMod.LogStatusEffectBleed && property.Name.ToLowerInvariant() == "bleeding" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " bleed per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack); * } * else if (GameMain.NilMod.LogStatusEffectOxygen && property.Name.ToLowerInvariant() == "oxygen" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " oxygen per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack); * } * } * }*/ DurationList.Add(element); } else { /* if (GameMain.Server != null) * { * if (target is Character) * { * Character effectedcharacter = (Character)target; * * //Only show values that are not continous to a character over time, that'd get rediculous fast. * if (deltaTime == 1f) * { * if (GameMain.NilMod.LogStatusEffectStun && property.Name.ToLowerInvariant() == "stun" && propertyEffects[i] is float && (float)propertyEffects[i] > 5f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Stunned for " + (Math.Round((float)propertyEffects[i] * (1f - effectedcharacter.Stunresistance), 2)) + " (" + Math.Round(effectedcharacter.Stunresistance * 100f, 2) + "% Resisted).", Networking.ServerLog.MessageType.Attack); * } * else if (GameMain.NilMod.LogStatusEffectHealth && property.Name.ToLowerInvariant() == "health" && propertyEffects[i] is float && (float)propertyEffects[i] < 5f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " health.", Networking.ServerLog.MessageType.Attack); * } * else if (GameMain.NilMod.LogStatusEffectBleed && property.Name.ToLowerInvariant() == "bleeding" && propertyEffects[i] is float && (float)propertyEffects[i] < 5f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " bleed.", Networking.ServerLog.MessageType.Attack); * } * else if (GameMain.NilMod.LogStatusEffectOxygen && property.Name.ToLowerInvariant() == "oxygen" && propertyEffects[i] is float && (float)propertyEffects[i] < 5f) * { * Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " oxygen.", Networking.ServerLog.MessageType.Attack); * } * } * } * }*/ foreach (ISerializableEntity target in targets) { if (target is Entity targetEntity) { if (targetEntity.Removed) { continue; } } if (target is Character) { for (int i = 0; i < propertyNames.Length; i++) { SerializableProperty property; if (cancelledEffects != null && cancelledEffects.Contains(i)) { continue; } if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property)) { continue; } float prevstat = 0f; Character targetcharacter = target as Character; Boolean prevdead = targetcharacter.IsDead; if (propertyEffects[i].GetType() == typeof(float)) { float propertyfloat = Convert.ToSingle(propertyEffects[i]); switch (property.Name.ToLowerInvariant()) { case "health": prevstat = targetcharacter.Health; if (propertyfloat < 0f) { targetcharacter.charRecord.DamageStat("health", -(propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier); } break; case "bleeding": if (propertyfloat > 0f) { targetcharacter.charRecord.DamageStat("bleeding", (propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier); } break; case "oxygen": prevstat = targetcharacter.Oxygen; if (propertyfloat < 0f) { targetcharacter.charRecord.DamageStat("oxygen", -(propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier); } break; case "stun": if (propertyfloat > 0f) { targetcharacter.charRecord.DamageStat("stun", (propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier); } break; case "huskinfectionstate": if (propertyfloat > 0f) { targetcharacter.charRecord.DamageStat("huskinfectionstate", (propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier); } break; default: break; } } ApplyToProperty(property, propertyEffects[i], deltaTime); if (GameMain.NilMod.EnableGriefWatcher && GameMain.Server != null && causecharacter != null) { Barotrauma.Networking.Client targetclient = GameMain.Server.ConnectedClients.Find(c => c.Character == targetcharacter); Barotrauma.Networking.Client attackingclient = GameMain.Server.ConnectedClients.Find(c => c.Character == causecharacter); if (attackingclient != null && targetclient != null) { switch (property.Name.ToLowerInvariant()) { case "health": if (NilMod.NilModGriefWatcher.PlayerIncapaciteDamage) { if (!prevdead) { if (targetcharacter.IsDead) { NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName + " Killed player " + targetclient.Character.LogName + " via " + identifier, attackingclient); } else if (prevstat > 0f && targetcharacter.Health < 0f) { NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName + " Incapacitated player " + targetclient.Character.LogName + " via " + identifier, attackingclient); } } } break; case "oxygen": if (NilMod.NilModGriefWatcher.PlayerIncapaciteOxygen) { if (!prevdead) { if (targetcharacter.IsDead) { NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName + " Killed player " + targetclient.Character.LogName + " via " + identifier, attackingclient); } else if (prevstat > 0f && targetcharacter.Oxygen < 0f) { NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName + " Incapacitated player " + targetclient.Character.LogName + " via " + identifier, attackingclient); } } } break; default: break; } } } } } else if (target is Items.Components.ItemComponent && GameMain.Server != null && causecharacter != null) { for (int i = 0; i < propertyNames.Length; i++) { SerializableProperty property; if (cancelledEffects != null && cancelledEffects.Contains(i)) { continue; } if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property)) { continue; } Items.Components.ItemComponent targetitemcomponent = target as Items.Components.ItemComponent; Networking.Client attackingclient = GameMain.Server.ConnectedClients.Find(c => c.Character == causecharacter); Items.Components.Door door = targetitemcomponent as Items.Components.Door; Boolean previsStuck = false; //Door stuck griefing here if (door != null) { if (propertyNames[i].ToLowerInvariant() == "stuck") { previsStuck = door.IsStuck; } } ApplyToProperty(property, propertyEffects[i], deltaTime); //Door stuck griefing here if (door != null) { if (propertyNames[i].ToLowerInvariant() == "stuck") { if (previsStuck != door.IsStuck) { if (door.IsStuck) { Networking.GameServer.Log(causecharacter.LogName + (door.LinkedGap != null && door.LinkedGap.IsRoomToRoom ? " sealed interior " : " sealed exterior ") + door.Item.Name, Networking.ServerLog.MessageType.ItemInteraction); if (GameMain.NilMod.EnableGriefWatcher && NilMod.NilModGriefWatcher.DoorStuck && attackingclient != null) { NilMod.NilModGriefWatcher.SendWarning( attackingclient.Character.LogName + (door.LinkedGap != null && door.LinkedGap.IsRoomToRoom ? " sealed interior " : " sealed exterior ") + door.Item.Name + " via " + identifier, attackingclient); } } else { Networking.GameServer.Log(causecharacter.LogName + (door.LinkedGap != null && door.LinkedGap.IsRoomToRoom ? " unsealed interior " : " unsealed exterior ") + door.Item.Name, Networking.ServerLog.MessageType.ItemInteraction); } } } } } } else { for (int i = 0; i < propertyNames.Length; i++) { SerializableProperty property; if (cancelledEffects != null && cancelledEffects.Contains(i)) { continue; } if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property)) { continue; } ApplyToProperty(property, propertyEffects[i], deltaTime); } } } } if (explosion != null) { if (identifier == "statuseffect") { explosion.Explode(entity.WorldPosition, causecharacter, ""); } else { explosion.Explode(entity.WorldPosition, causecharacter, identifier); } } Hull hull = null; if (entity is Character) { hull = ((Character)entity).AnimController.CurrentHull; } else if (entity is Item) { hull = ((Item)entity).CurrentHull; } if (FireSize > 0.0f) { var fire = new FireSource(entity.WorldPosition, hull); fire.Size = new Vector2(FireSize, fire.Size.Y); } #if CLIENT foreach (ParticleEmitter emitter in particleEmitters) { emitter.Emit(deltaTime, entity.WorldPosition, hull); } #endif }
private bool OnCollision(Fixture f1, Fixture f2, Contact contact) { if (user == null || user.Removed) { RestoreCollision(); hitting = false; user = null; } Character targetCharacter = null; Limb targetLimb = null; Structure targetStructure = null; if (f2.Body.UserData is Limb) { targetLimb = (Limb)f2.Body.UserData; if (targetLimb.IsSevered || targetLimb.character == null) { return(false); } targetCharacter = targetLimb.character; } else if (f2.Body.UserData is Character) { targetCharacter = (Character)f2.Body.UserData; targetLimb = targetCharacter.AnimController.GetLimb(LimbType.Torso); //Otherwise armor can be bypassed in strange ways } else if (f2.Body.UserData is Structure) { targetStructure = (Structure)f2.Body.UserData; } else { return(false); } if (targetCharacter == picker) { return(false); } string effectidentifier = ""; if (item.ContainedItems != null && item.ContainedItems.Length > 0) { effectidentifier = item.Name + " (" + string.Join(", ", Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name)) + ")"; } else { effectidentifier = item.Name; } if (attack != null) { if (targetLimb != null) { attack.DoDamageToLimb(user, targetLimb, item.WorldPosition, 1.0f); } else if (targetCharacter != null) { attack.DoDamage(user, targetCharacter, item.WorldPosition, 1.0f, true, effectidentifier); } else if (targetStructure != null) { Boolean ModifyRangeValue = false; Boolean ModifyDamageRangeValue = false; if (attack.Range == 0) { ModifyRangeValue = true; } if (attack.DamageRange == 0) { ModifyDamageRangeValue = true; } if (ModifyRangeValue) { attack.Range = 75f; } if (ModifyDamageRangeValue) { attack.DamageRange = 75f; } attack.DoDamage(user, targetStructure, item.WorldPosition, 1.0f); if (ModifyRangeValue) { attack.Range = 0f; } if (ModifyDamageRangeValue) { attack.DamageRange = 0f; } } else { return(false); } } RestoreCollision(); hitting = false; if (GameMain.Client != null) { return(true); } if (GameMain.Server != null && targetCharacter != null) //TODO: Log structure hits { GameMain.Server.CreateEntityEvent(item, new object[] { Networking.NetEntityEvent.Type.ApplyStatusEffect, ActionType.OnUse, targetCharacter.ID }); string logStr = picker?.LogName + " used " + item.Name; if (item.ContainedItems != null && item.ContainedItems.Length > 0) { logStr += "(" + string.Join(", ", item.ContainedItems.Select(i => i?.Name)) + ")"; } logStr += " on " + targetCharacter.LogName + "."; Networking.GameServer.Log(logStr, Networking.ServerLog.MessageType.Attack); if (GameMain.NilMod.EnableGriefWatcher && user != null && user.TeamID == targetCharacter.TeamID && !targetCharacter.IsDead) { Barotrauma.Networking.Client warnedclient = GameMain.Server.ConnectedClients.Find(c => c.Character == user); if (warnedclient != null) { //Melee Other check if (item.ContainedItems != null && item.ContainedItems.Length > 0) { for (int y = 0; y < NilMod.NilModGriefWatcher.GWListMeleeOther.Count; y++) { if (NilMod.NilModGriefWatcher.GWListMeleeOther[y] == item.Name) { NilMod.NilModGriefWatcher.SendWarning(warnedclient.Character.LogName + " attacked " + targetCharacter.LogName + " using " + item.Name + " (" + string.Join(", ", Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name)) + ")", warnedclient); } } } else { for (int y = 0; y < NilMod.NilModGriefWatcher.GWListMeleeOther.Count; y++) { if (NilMod.NilModGriefWatcher.GWListMeleeOther[y] == item.Name) { NilMod.NilModGriefWatcher.SendWarning(warnedclient.Character.LogName + " attacked " + targetCharacter.LogName + " using " + item.Name, warnedclient); } } } //Item Usage Other check if (item.ContainedItems == null || item.ContainedItems.All(i => i == null)) { //Usage Check (And Contained) for (int y = 0; y < NilMod.NilModGriefWatcher.GWListUse.Count; y++) { if (NilMod.NilModGriefWatcher.GWListUse[y] == item.Name) { NilMod.NilModGriefWatcher.SendWarning(warnedclient.Character.LogName + " used Item " + item.Name + " on " + targetCharacter.LogName, warnedclient); } } } else { //Usage Check (And Contained) for (int y = 0; y < NilMod.NilModGriefWatcher.GWListUse.Count; y++) { if (NilMod.NilModGriefWatcher.GWListUse[y] == item.Name || Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name).Contains(NilMod.NilModGriefWatcher.GWListUse[y])) { NilMod.NilModGriefWatcher.SendWarning(warnedclient.Character.LogName + " used item " + item.Name + " (" + string.Join(", ", Array.FindAll(item.ContainedItems, i => i != null).Select(i => i.Name)) + ")" + " on " + targetCharacter.LogName, warnedclient); } } } } } } if (targetCharacter != null) //TODO: Allow OnUse to happen on structures too maybe?? { ApplyStatusEffects(ActionType.OnUse, 1.0f, targetCharacter != null ? targetCharacter : null, user, effectidentifier); } if (DeleteOnUse) { Entity.Spawner.AddToRemoveQueue(item); } return(true); }