コード例 #1
0
        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
            }
        }
コード例 #2
0
        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
        }
コード例 #3
0
        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);
        }