コード例 #1
0
        private void DamageCharacters(float deltaTime)
        {
            if (size.X <= 0.0f)
            {
                return;
            }

            for (int i = 0; i < Character.CharacterList.Count; i++)
            {
                Character c = Character.CharacterList[i];
                if (c.AnimController.CurrentHull == null || c.IsDead)
                {
                    continue;
                }

                float range = DamageRange;
                if (c.Position.X < position.X - range || c.Position.X > position.X + size.X + range)
                {
                    continue;
                }
                if (c.Position.Y < position.Y - size.Y || c.Position.Y > hull.Rect.Y)
                {
                    continue;
                }

                float dmg = (float)Math.Sqrt(size.X) * deltaTime / c.AnimController.Limbs.Length;
                foreach (Limb limb in c.AnimController.Limbs)
                {
                    c.AddDamage(limb.SimPosition, DamageType.Burn, dmg, 0, 0, false);
                }
            }
        }
コード例 #2
0
        private void DamageCharacters(float deltaTime)
        {
            if (size.X <= 0.0f)
            {
                return;
            }

            for (int i = 0; i < Character.CharacterList.Count; i++)
            {
                Character c = Character.CharacterList[i];
                if (c.AnimController.CurrentHull == null || c.IsDead)
                {
                    continue;
                }

                if (!IsInDamageRange(c, DamageRange))
                {
                    continue;
                }


                float dmg = (((float)Math.Sqrt(size.X) * deltaTime * GameMain.NilMod.FireCharDamageMultiplier) / c.AnimController.Limbs.Length);
                foreach (Limb limb in c.AnimController.Limbs)
                {
                    if (GameMain.NilMod.FireUseRangedDamage)
                    {
                        float range = DamageRange * GameMain.NilMod.FireCharRangeMultiplier;

                        float closestdistance = Math.Abs(limb.Position.X - position.X) / range;
                        if (closestdistance > Math.Abs(limb.Position.X - (position.X + size.X)) / range)
                        {
                            closestdistance = Math.Abs((limb.Position.X - (position.X + size.X)) / range);
                        }
                        if (limb.Position.X > position.X && limb.Position.X < (position.X + size.X))
                        {
                            closestdistance = 0f;
                        }

                        c.AddDamage(limb.SimPosition, DamageType.Burn, (dmg * Math.Min(Math.Max(((GameMain.NilMod.FireRangedDamageStrength) - (closestdistance * (GameMain.NilMod.FireRangedDamageStrength))), GameMain.NilMod.FireRangedDamageMinMultiplier), GameMain.NilMod.FireRangedDamageMaxMultiplier)), 0, 0, false, 0f, null, "Fire");
                    }
                    else
                    {
                        c.AddDamage(limb.SimPosition, DamageType.Burn, dmg, 0, 0, false, 0f, null, "Fire");
                    }
                }
            }
        }
コード例 #3
0
ファイル: HuskInfection.cs プロジェクト: kachnov/Barotrauma
        private void UpdateActiveState(float deltaTime, Character character)
        {
            if (state != InfectionState.Active)
            {
                ActivateHusk(character);
                state = InfectionState.Active;
            }

            character.AddDamage(CauseOfDeath.Husk, 0.5f * deltaTime, null);
        }
コード例 #4
0
        private void UpdateActiveState(float deltaTime, Character character)
        {
            if (state != InfectionState.Active)
            {
                ActivateHusk(character);
                state = InfectionState.Active;
            }

            character.AddDamage(CauseOfDeath.Husk, GameMain.NilMod.PlayerHuskIncurableDrain * deltaTime, null, "Husk Infection");
            //character.AddDamage(CauseOfDeath.Husk, 0.5f * deltaTime, null);
        }
コード例 #5
0
        private void UpdateTransitionState(float deltaTime, Character character)
        {
            if (state != InfectionState.Transition)
            {
                DeactivateHusk(character);
            }

            IncubationTimer += deltaTime / IncubationDuration;

            character.AddDamage(CauseOfDeath.Husk, GameMain.NilMod.PlayerHuskInfectedDrain * deltaTime, null, "Husk Infection");

            state = InfectionState.Transition;
        }
コード例 #6
0
        private void UpdateActiveState(float deltaTime, Character character)
        {
            if (state != InfectionState.Active)
            {
                if (Character.Controlled == character)
                {
                    new GUIMessageBox("", InfoTextManager.GetInfoText("HuskActivate"));
                }
                ActivateHusk(character);
                state = InfectionState.Active;
            }

            character.AddDamage(CauseOfDeath.Husk, 0.5f * deltaTime, null);
        }
コード例 #7
0
ファイル: LatchOntoAI.cs プロジェクト: juanjp600/Barotrauma
        public void Update(EnemyAIController enemyAI, float deltaTime)
        {
            Character character = enemyAI.Character;

            if (character.Submarine != null)
            {
                DeattachFromBody();
                WallAttachPos = null;
                return;
            }
            if (attachJoints.Count > 0)
            {
                if (Math.Sign(attachLimb.Dir) != Math.Sign(jointDir))
                {
                    attachJoints[0].LocalAnchorA =
                        new Vector2(-attachJoints[0].LocalAnchorA.X, attachJoints[0].LocalAnchorA.Y);
                    attachJoints[0].ReferenceAngle = -attachJoints[0].ReferenceAngle;
                    jointDir = attachLimb.Dir;
                }
                for (int i = 0; i < attachJoints.Count; i++)
                {
                    //something went wrong, limb body is very far from the joint anchor -> deattach
                    if (Vector2.DistanceSquared(attachJoints[i].WorldAnchorB, attachJoints[i].BodyA.Position) > 10.0f * 10.0f)
                    {
                        DebugConsole.ThrowError("Limb body of the character \"" + character.Name + "\" is very far from the attach joint anchor -> deattach");
                        DeattachFromBody();
                        return;
                    }
                }
            }

            attachCooldown -= deltaTime;
            deattachTimer  -= deltaTime;

            Vector2 transformedAttachPos = wallAttachPos;

            if (character.Submarine == null && attachTargetSubmarine != null)
            {
                transformedAttachPos += ConvertUnits.ToSimUnits(attachTargetSubmarine.Position);
            }
            if (transformedAttachPos != Vector2.Zero)
            {
                WallAttachPos = transformedAttachPos;
            }

            switch (enemyAI.State)
            {
            case AIController.AIState.Idle:
                if (attachToWalls && character.Submarine == null && Level.Loaded != null)
                {
                    raycastTimer -= deltaTime;
                    //check if there are any walls nearby the character could attach to
                    if (raycastTimer < 0.0f)
                    {
                        wallAttachPos = Vector2.Zero;

                        var cells = Level.Loaded.GetCells(character.WorldPosition, 1);
                        if (cells.Count > 0)
                        {
                            foreach (Voronoi2.VoronoiCell cell in cells)
                            {
                                foreach (Voronoi2.GraphEdge edge in cell.Edges)
                                {
                                    if (MathUtils.GetLineIntersection(edge.Point1, edge.Point2, character.WorldPosition, cell.Center, out Vector2 intersection))
                                    {
                                        attachSurfaceNormal = edge.GetNormal(cell);
                                        attachTargetBody    = cell.Body;
                                        wallAttachPos       = ConvertUnits.ToSimUnits(intersection);
                                        break;
                                    }
                                }
                                if (WallAttachPos != Vector2.Zero)
                                {
                                    break;
                                }
                            }
                        }
                        raycastTimer = RaycastInterval;
                    }
                }
                else
                {
                    wallAttachPos = Vector2.Zero;
                }

                if (wallAttachPos == Vector2.Zero)
                {
                    DeattachFromBody();
                }
                else
                {
                    float dist = Vector2.Distance(character.SimPosition, wallAttachPos);
                    if (dist < Math.Max(Math.Max(character.AnimController.Collider.radius, character.AnimController.Collider.width), character.AnimController.Collider.height) * 1.2f)
                    {
                        //close enough to a wall -> attach
                        AttachToBody(character.AnimController.Collider, attachLimb, attachTargetBody, wallAttachPos);
                        enemyAI.SteeringManager.Reset();
                    }
                    else
                    {
                        //move closer to the wall
                        DeattachFromBody();
                        enemyAI.SteeringManager.SteeringAvoid(deltaTime, 1.0f, 0.1f);
                        enemyAI.SteeringManager.SteeringSeek(wallAttachPos);
                    }
                }
                break;

            case AIController.AIState.Attack:
                if (enemyAI.AttackingLimb != null)
                {
                    if (attachToSub && wallAttachPos != Vector2.Zero && attachTargetBody != null)
                    {
                        // is not attached or is attached to something else
                        if (!IsAttached || IsAttached && attachJoints[0].BodyB == attachTargetBody)
                        {
                            if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.DamageRange * enemyAI.AttackingLimb.attack.DamageRange)
                            {
                                AttachToBody(character.AnimController.Collider, attachLimb, attachTargetBody, transformedAttachPos);
                            }
                        }
                    }
                }
                break;

            default:
                WallAttachPos = null;
                DeattachFromBody();
                break;
            }

            if (attachTargetBody != null && deattachTimer < 0.0f)
            {
                Entity    entity      = attachTargetBody.UserData as Entity;
                Submarine attachedSub = entity is Submarine ? (Submarine)entity : entity?.Submarine;
                if (attachedSub != null)
                {
                    float velocity       = attachedSub.Velocity == Vector2.Zero ? 0.0f : attachedSub.Velocity.Length();
                    float velocityFactor = (maxDeattachSpeed - minDeattachSpeed <= 0.0f) ?
                                           Math.Sign(Math.Abs(velocity) - minDeattachSpeed) :
                                           (Math.Abs(velocity) - minDeattachSpeed) / (maxDeattachSpeed - minDeattachSpeed);

                    if (Rand.Range(0.0f, 1.0f) < velocityFactor)
                    {
                        DeattachFromBody();
                        character.AddDamage(character.WorldPosition, new List <Affliction>()
                        {
                            AfflictionPrefab.InternalDamage.Instantiate(damageOnDetach)
                        }, detachStun, true);
                        attachCooldown = 5.0f;
                    }
                }

                deattachTimer = 5.0f;
            }
        }
コード例 #8
0
        static DebugConsole()
        {
            commands.Add(new Command("help", "", (string[] args) =>
            {
                if (args.Length == 0)
                {
                    foreach (Command c in commands)
                    {
                        if (string.IsNullOrEmpty(c.help))
                        {
                            continue;
                        }
                        NewMessage(c.help, Color.Cyan);
                    }
                }
                else
                {
                    var matchingCommand = commands.Find(c => c.names.Any(name => name == args[0]));
                    if (matchingCommand == null)
                    {
                        NewMessage("Command " + args[0] + " not found.", Color.Red);
                    }
                    else
                    {
                        NewMessage(matchingCommand.help, Color.Cyan);
                    }
                }
            }));

            commands.Add(new Command("clientlist", "clientlist: List all the clients connected to the server.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }
                NewMessage("***************", Color.Cyan);
                foreach (Client c in GameMain.Server.ConnectedClients)
                {
                    NewMessage("- " + c.ID.ToString() + ": " + c.name + ", " + c.Connection.RemoteEndPoint.Address.ToString(), Color.Cyan);
                }
                NewMessage("***************", Color.Cyan);
            }));


            commands.Add(new Command("createfilelist", "", (string[] args) =>
            {
                UpdaterUtil.SaveFileList("filelist.xml");
            }));

            commands.Add(new Command("spawn|spawncharacter", "spawn [creaturename] [near/inside/outside]: Spawn a creature at a random spawnpoint (use the second parameter to only select spawnpoints near/inside/outside the submarine).", (string[] args) =>
            {
                if (args.Length == 0)
                {
                    return;
                }

                Character spawnedCharacter = null;

                Vector2 spawnPosition = Vector2.Zero;
                WayPoint spawnPoint   = null;

                if (args.Length > 1)
                {
                    switch (args[1].ToLowerInvariant())
                    {
                    case "inside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                        break;

                    case "outside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Enemy);
                        break;

                    case "near":
                    case "close":
                        float closestDist = -1.0f;
                        foreach (WayPoint wp in WayPoint.WayPointList)
                        {
                            if (wp.Submarine != null)
                            {
                                continue;
                            }

                            //don't spawn inside hulls
                            if (Hull.FindHull(wp.WorldPosition, null) != null)
                            {
                                continue;
                            }

                            float dist = Vector2.Distance(wp.WorldPosition, GameMain.GameScreen.Cam.WorldViewCenter);

                            if (closestDist < 0.0f || dist < closestDist)
                            {
                                spawnPoint  = wp;
                                closestDist = dist;
                            }
                        }
                        break;

                    case "cursor":
                        spawnPosition = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                        break;

                    default:
                        spawnPoint = WayPoint.GetRandom(args[0].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                        break;
                    }
                }
                else
                {
                    spawnPoint = WayPoint.GetRandom(args[0].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                }

                if (string.IsNullOrWhiteSpace(args[0]))
                {
                    return;
                }

                if (spawnPoint != null)
                {
                    spawnPosition = spawnPoint.WorldPosition;
                }

                if (args[0].ToLowerInvariant() == "human")
                {
                    spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition);

#if CLIENT
                    if (GameMain.GameSession != null)
                    {
                        SinglePlayerMode mode = GameMain.GameSession.gameMode as SinglePlayerMode;
                        if (mode != null)
                        {
                            Character.Controlled = spawnedCharacter;
                            GameMain.GameSession.CrewManager.AddCharacter(Character.Controlled);
                            GameMain.GameSession.CrewManager.SelectCharacter(null, Character.Controlled);
                        }
                    }
#endif
                }
                else
                {
                    spawnedCharacter = Character.Create(
                        "Content/Characters/"
                        + args[0].First().ToString().ToUpper() + args[0].Substring(1)
                        + "/" + args[0].ToLower() + ".xml", spawnPosition);
                }
            }));

            commands.Add(new Command("spawnitem", "spawnitem [itemname] [cursor/inventory]: Spawn an item at the position of the cursor, in the inventory of the controlled character or at a random spawnpoint if the last parameter is omitted.", (string[] args) =>
            {
                if (args.Length < 1)
                {
                    return;
                }

                Vector2?spawnPos         = null;
                Inventory spawnInventory = null;

                int extraParams = 0;
                switch (args.Last())
                {
                case "cursor":
                    extraParams = 1;
                    spawnPos    = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                    break;

                case "inventory":
                    extraParams    = 1;
                    spawnInventory = Character.Controlled == null ? null : Character.Controlled.Inventory;
                    break;

                default:
                    extraParams = 0;
                    break;
                }

                string itemName = string.Join(" ", args.Take(args.Length - extraParams)).ToLowerInvariant();

                var itemPrefab = MapEntityPrefab.list.Find(ip => ip.Name.ToLowerInvariant() == itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    ThrowError("Item \"" + itemName + "\" not found!");
                    return;
                }

                if (spawnPos == null && spawnInventory == null)
                {
                    var wp   = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                    spawnPos = wp == null ? Vector2.Zero : wp.WorldPosition;
                }

                if (spawnPos != null)
                {
                    Entity.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos);
                }
                else if (spawnInventory != null)
                {
                    Entity.Spawner.AddToSpawnQueue(itemPrefab, spawnInventory);
                }
            }));

            commands.Add(new Command("disablecrewai", "disablecrewai: Disable the AI of the NPCs in the crew.", (string[] args) =>
            {
                HumanAIController.DisableCrewAI = true;
                NewMessage("Crew AI disabled", Color.White);
            }));

            commands.Add(new Command("enablecrewai", "enablecrewai: Enable the AI of the NPCs in the crew.", (string[] args) =>
            {
                HumanAIController.DisableCrewAI = false;
                NewMessage("Crew AI enabled", Color.White);
            }));

            commands.Add(new Command("kick", "kick [name]: Kick a player out of the server.", (string[] args) =>
            {
                if (GameMain.NetworkMember == null || args.Length == 0)
                {
                    return;
                }

                string playerName = string.Join(" ", args);

                ShowQuestionPrompt("Reason for kicking \"" + playerName + "\"?", (reason) =>
                {
                    GameMain.NetworkMember.KickPlayer(playerName, reason);
                });
            }));

            commands.Add(new Command("kickid", "kickid [id]: Kick the player with the specified client ID out of the server.", (string[] args) =>
            {
                if (GameMain.Server == null || args.Length == 0)
                {
                    return;
                }

                int id = 0;
                int.TryParse(args[0], out id);
                var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
                if (client == null)
                {
                    ThrowError("Client id \"" + id + "\" not found.");
                    return;
                }

                ShowQuestionPrompt("Reason for kicking \"" + client.name + "\"?", (reason) =>
                {
                    GameMain.Server.KickPlayer(client.name, reason);
                });
            }));

            commands.Add(new Command("ban", "ban [name]: Kick and ban the player from the server.", (string[] args) =>
            {
                if (GameMain.NetworkMember == null || args.Length == 0)
                {
                    return;
                }

                string clientName = string.Join(" ", args);
                ShowQuestionPrompt("Reason for banning \"" + clientName + "\"?", (reason) =>
                {
                    ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
                    {
                        TimeSpan?banDuration = null;
                        if (!string.IsNullOrWhiteSpace(duration))
                        {
                            TimeSpan parsedBanDuration;
                            if (!TryParseTimeSpan(duration, out parsedBanDuration))
                            {
                                ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
                                return;
                            }
                            banDuration = parsedBanDuration;
                        }

                        GameMain.NetworkMember.BanPlayer(clientName, reason, false, banDuration);
                    });
                });
            }));

            commands.Add(new Command("banid", "banid [id]: Kick and ban the player with the specified client ID from the server.", (string[] args) =>
            {
                if (GameMain.Server == null || args.Length == 0)
                {
                    return;
                }

                int id = 0;
                int.TryParse(args[0], out id);
                var client = GameMain.Server.ConnectedClients.Find(c => c.ID == id);
                if (client == null)
                {
                    ThrowError("Client id \"" + id + "\" not found.");
                    return;
                }

                ShowQuestionPrompt("Reason for banning \"" + client.name + "\"?", (reason) =>
                {
                    ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
                    {
                        TimeSpan?banDuration = null;
                        if (!string.IsNullOrWhiteSpace(duration))
                        {
                            TimeSpan parsedBanDuration;
                            if (!TryParseTimeSpan(duration, out parsedBanDuration))
                            {
                                ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
                                return;
                            }
                            banDuration = parsedBanDuration;
                        }

                        GameMain.Server.BanPlayer(client.name, reason, false, banDuration);
                    });
                });
            }));


            commands.Add(new Command("banip", "banip [ip]: Ban the IP address from the server.", (string[] args) =>
            {
                if (GameMain.Server == null || args.Length == 0)
                {
                    return;
                }

                ShowQuestionPrompt("Reason for banning the ip \"" + commands[1] + "\"?", (reason) =>
                {
                    ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
                    {
                        TimeSpan?banDuration = null;
                        if (!string.IsNullOrWhiteSpace(duration))
                        {
                            TimeSpan parsedBanDuration;
                            if (!TryParseTimeSpan(duration, out parsedBanDuration))
                            {
                                ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
                                return;
                            }
                            banDuration = parsedBanDuration;
                        }

                        var client = GameMain.Server.ConnectedClients.Find(c => c.Connection.RemoteEndPoint.Address.ToString() == args[0]);
                        if (client == null)
                        {
                            GameMain.Server.BanList.BanPlayer("Unnamed", args[0], reason, banDuration);
                        }
                        else
                        {
                            GameMain.Server.KickClient(client, reason);
                        }
                    });
                });
            }));

            commands.Add(new Command("teleportcharacter|teleport", "teleport [character name]: Teleport the specified character to the position of the cursor. If the name parameter is omitted, the controlled character will be teleported.", (string[] args) =>
            {
                Character tpCharacter = null;

                if (args.Length == 0)
                {
                    tpCharacter = Character.Controlled;
                }
                else
                {
                    tpCharacter = FindMatchingCharacter(args, false);
                }

                if (tpCharacter == null)
                {
                    return;
                }

                var cam = GameMain.GameScreen.Cam;
                tpCharacter.AnimController.CurrentHull = null;
                tpCharacter.Submarine = null;
                tpCharacter.AnimController.SetPosition(ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition)));
                tpCharacter.AnimController.FindHull(cam.ScreenToWorld(PlayerInput.MousePosition), true);
            }));

            commands.Add(new Command("godmode", "godmode: Toggle submarine godmode. Makes the main submarine invulnerable to damage.", (string[] args) =>
            {
                if (Submarine.MainSub == null)
                {
                    return;
                }

                Submarine.MainSub.GodMode = !Submarine.MainSub.GodMode;
                NewMessage(Submarine.MainSub.GodMode ? "Godmode on" : "Godmode off", Color.White);
            }));

            commands.Add(new Command("lockx", "lockx: Lock horizontal movement of the main submarine.", (string[] args) =>
            {
                Submarine.LockX = !Submarine.LockX;
            }));

            commands.Add(new Command("locky", "loxky: Lock vertical movement of the main submarine.", (string[] args) =>
            {
                Submarine.LockY = !Submarine.LockY;
            }));

            commands.Add(new Command("dumpids", "", (string[] args) =>
            {
                try
                {
                    int count = args.Length == 0 ? 10 : int.Parse(args[0]);
                    Entity.DumpIds(count);
                }
                catch (Exception e)
                {
                    ThrowError("Failed to dump ids", e);
                }
            }));

            commands.Add(new Command("heal", "heal [character name]: Restore the specified character to full health. If the name parameter is omitted, the controlled character will be healed.", (string[] args) =>
            {
                Character healedCharacter = null;
                if (args.Length == 0)
                {
                    healedCharacter = Character.Controlled;
                }
                else
                {
                    healedCharacter = FindMatchingCharacter(args);
                }

                if (healedCharacter != null)
                {
                    healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
                    healedCharacter.Oxygen   = 100.0f;
                    healedCharacter.Bleeding = 0.0f;
                    healedCharacter.SetStun(0.0f, true);
                }
            }));

            commands.Add(new Command("revive", "revive [character name]: Bring the specified character back from the dead. If the name parameter is omitted, the controlled character will be revived.", (string[] args) =>
            {
                Character revivedCharacter = null;
                if (args.Length == 0)
                {
                    revivedCharacter = Character.Controlled;
                }
                else
                {
                    revivedCharacter = FindMatchingCharacter(args);
                }

                if (revivedCharacter == null)
                {
                    return;
                }

                revivedCharacter.Revive(false);
                if (GameMain.Server != null)
                {
                    foreach (Client c in GameMain.Server.ConnectedClients)
                    {
                        if (c.Character != revivedCharacter)
                        {
                            continue;
                        }
                        //clients stop controlling the character when it dies, force control back
                        GameMain.Server.SetClientCharacter(c, revivedCharacter);
                        break;
                    }
                }
            }));

            commands.Add(new Command("freeze", "", (string[] args) =>
            {
                if (Character.Controlled != null)
                {
                    Character.Controlled.AnimController.Frozen = !Character.Controlled.AnimController.Frozen;
                }
            }));

            commands.Add(new Command("freecamera|freecam", "freecam: Detach the camera from the controlled character.", (string[] args) =>
            {
                Character.Controlled = null;
                GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
            }));

            commands.Add(new Command("water|editwater", "water/editwater: Toggle water editing. Allows adding water into rooms by holding the left mouse button and removing it by holding the right mouse button.", (string[] args) =>
            {
                if (GameMain.Client == null)
                {
                    Hull.EditWater = !Hull.EditWater;
                    NewMessage(Hull.EditWater ? "Water editing on" : "Water editing off", Color.White);
                }
            }));

            commands.Add(new Command("fire|editfire", "fire/editfire: Allows putting up fires by left clicking.", (string[] args) =>
            {
                if (GameMain.Client == null)
                {
                    Hull.EditFire = !Hull.EditFire;
                    NewMessage(Hull.EditFire ? "Fire spawning on" : "Fire spawning off", Color.White);
                }
            }));

            commands.Add(new Command("explosion", "explosion [range] [force] [damage] [structuredamage]: Creates an explosion at the position of the cursor.", (string[] args) =>
            {
                Vector2 explosionPos = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                float range          = 500, force = 10, damage = 50, structureDamage = 10;
                if (args.Length > 0)
                {
                    float.TryParse(args[0], out range);
                }
                if (args.Length > 1)
                {
                    float.TryParse(args[1], out force);
                }
                if (args.Length > 2)
                {
                    float.TryParse(args[2], out damage);
                }
                if (args.Length > 3)
                {
                    float.TryParse(args[3], out structureDamage);
                }
                new Explosion(range, force, damage, structureDamage).Explode(explosionPos);
            }));

            commands.Add(new Command("fixitems", "fixitems: Repairs all items and restores them to full condition.", (string[] args) =>
            {
                foreach (Item it in Item.ItemList)
                {
                    it.Condition = it.Prefab.Health;
                }
            }));

            commands.Add(new Command("fixhulls|fixwalls", "fixwalls/fixhulls: Fixes all walls.", (string[] args) =>
            {
                foreach (Structure w in Structure.WallList)
                {
                    for (int i = 0; i < w.SectionCount; i++)
                    {
                        w.AddDamage(i, -100000.0f);
                    }
                }
            }));

            commands.Add(new Command("power", "power [temperature]: Immediately sets the temperature of the nuclear reactor to the specified value.", (string[] args) =>
            {
                Item reactorItem = Item.ItemList.Find(i => i.GetComponent <Reactor>() != null);
                if (reactorItem == null)
                {
                    return;
                }

                float power = 5000.0f;
                if (args.Length > 0)
                {
                    float.TryParse(args[0], out power);
                }

                var reactor          = reactorItem.GetComponent <Reactor>();
                reactor.ShutDownTemp = power == 0 ? 0 : 7000.0f;
                reactor.AutoTemp     = true;
                reactor.Temperature  = power;

                if (GameMain.Server != null)
                {
                    reactorItem.CreateServerEvent(reactor);
                }
            }));

            commands.Add(new Command("oxygen|air", "oxygen/air: Replenishes the oxygen levels in every room to 100%.", (string[] args) =>
            {
                foreach (Hull hull in Hull.hullList)
                {
                    hull.OxygenPercentage = 100.0f;
                }
            }));

            commands.Add(new Command("killmonsters", "killmonsters: Immediately kills all AI-controlled enemies in the level.", (string[] args) =>
            {
                foreach (Character c in Character.CharacterList)
                {
                    if (!(c.AIController is EnemyAIController))
                    {
                        continue;
                    }
                    c.AddDamage(CauseOfDeath.Damage, 10000.0f, null);
                }
            }));

            commands.Add(new Command("netstats", "netstats: Toggles the visibility of the network statistics UI.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }
                GameMain.Server.ShowNetStats = !GameMain.Server.ShowNetStats;
            }));

            commands.Add(new Command("setclientcharacter", "setclientcharacter [client name] ; [character name]: Gives the client control of the specified character.", (string[] args) =>
            {
                if (GameMain.Server == null)
                {
                    return;
                }

                int separatorIndex = Array.IndexOf(args, ";");

                if (separatorIndex == -1 || args.Length < 3)
                {
                    ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\"");
                    return;
                }

                string[] argsLeft  = args.Take(separatorIndex).ToArray();
                string[] argsRight = args.Skip(separatorIndex).ToArray();

                string clientName = String.Join(" ", argsLeft);

                var client = GameMain.Server.ConnectedClients.Find(c => c.name == clientName);
                if (client == null)
                {
                    ThrowError("Client \"" + clientName + "\" not found.");
                }

                var character = FindMatchingCharacter(argsRight, false);
                GameMain.Server.SetClientCharacter(client, character);
            }));
#if DEBUG
            commands.Add(new Command("spamevents", "A debug command that immediately creates entity events for all items, characters and structures.", (string[] args) =>
            {
                foreach (Item item in Item.ItemList)
                {
                    for (int i = 0; i < item.components.Count; i++)
                    {
                        if (item.components[i] is IServerSerializable)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i });
                        }
                        var itemContainer = item.GetComponent <ItemContainer>();
                        if (itemContainer != null)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState });
                        }

                        GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });

                        item.NeedsPositionUpdate = true;
                    }
                }

                foreach (Character c in Character.CharacterList)
                {
                    GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status });
                }

                foreach (Structure wall in Structure.WallList)
                {
                    GameMain.Server.CreateEntityEvent(wall);
                }
            }));
#endif
            InitProjectSpecific();

            commands.Sort((c1, c2) => c1.names[0].CompareTo(c2.names[0]));
        }
コード例 #9
0
        public void Update(EnemyAIController enemyAI, float deltaTime)
        {
            if (character.Submarine != null)
            {
                DeattachFromBody(reset: true);
                return;
            }
            if (AttachJoints.Count > 0)
            {
                if (Math.Sign(attachLimb.Dir) != Math.Sign(jointDir))
                {
                    AttachJoints[0].LocalAnchorA =
                        new Vector2(-AttachJoints[0].LocalAnchorA.X, AttachJoints[0].LocalAnchorA.Y);
                    AttachJoints[0].ReferenceAngle = -AttachJoints[0].ReferenceAngle;
                    jointDir = attachLimb.Dir;
                }
                for (int i = 0; i < AttachJoints.Count; i++)
                {
                    //something went wrong, limb body is very far from the joint anchor -> deattach
                    if (Vector2.DistanceSquared(AttachJoints[i].WorldAnchorB, AttachJoints[i].BodyA.Position) > 10.0f * 10.0f)
                    {
#if DEBUG
                        DebugConsole.ThrowError("Limb body of the character \"" + character.Name + "\" is very far from the attach joint anchor -> deattach");
#endif
                        DeattachFromBody(reset: true);
                        return;
                    }
                }
            }

            if (attachCooldown > 0)
            {
                attachCooldown -= deltaTime;
            }
            if (deattachTimer > 0)
            {
                deattachTimer -= deltaTime;
            }

            Vector2 transformedAttachPos = wallAttachPos;
            if (character.Submarine == null && targetSubmarine != null)
            {
                transformedAttachPos += ConvertUnits.ToSimUnits(targetSubmarine.Position);
            }
            if (transformedAttachPos != Vector2.Zero)
            {
                WallAttachPos = transformedAttachPos;
            }

            switch (enemyAI.State)
            {
            case AIState.Idle:
                if (AttachToWalls && character.Submarine == null && Level.Loaded != null)
                {
                    if (!IsAttached)
                    {
                        raycastTimer -= deltaTime;
                        //check if there are any walls nearby the character could attach to
                        if (raycastTimer < 0.0f)
                        {
                            wallAttachPos = Vector2.Zero;

                            var cells = Level.Loaded.GetCells(character.WorldPosition, 1);
                            if (cells.Count > 0)
                            {
                                float closestDist = float.PositiveInfinity;
                                foreach (Voronoi2.VoronoiCell cell in cells)
                                {
                                    foreach (Voronoi2.GraphEdge edge in cell.Edges)
                                    {
                                        if (MathUtils.GetLineIntersection(edge.Point1, edge.Point2, character.WorldPosition, cell.Center, out Vector2 intersection))
                                        {
                                            Vector2 potentialAttachPos = ConvertUnits.ToSimUnits(intersection);
                                            float   distSqr            = Vector2.DistanceSquared(character.SimPosition, potentialAttachPos);
                                            if (distSqr < closestDist)
                                            {
                                                attachSurfaceNormal = edge.GetNormal(cell);
                                                targetBody          = cell.Body;
                                                wallAttachPos       = potentialAttachPos;
                                                closestDist         = distSqr;
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                            raycastTimer = RaycastInterval;
                        }
                    }
                }
                else
                {
                    wallAttachPos = Vector2.Zero;
                }

                if (wallAttachPos == Vector2.Zero || targetBody == null)
                {
                    DeattachFromBody(reset: false);
                }
                else
                {
                    float squaredDistance = Vector2.DistanceSquared(character.SimPosition, wallAttachPos);
                    float targetDistance  = Math.Max(Math.Max(character.AnimController.Collider.radius, character.AnimController.Collider.width), character.AnimController.Collider.height) * 1.2f;
                    if (squaredDistance < targetDistance * targetDistance)
                    {
                        //close enough to a wall -> attach
                        AttachToBody(wallAttachPos);
                        enemyAI.SteeringManager.Reset();
                    }
                    else
                    {
                        //move closer to the wall
                        DeattachFromBody(reset: false);
                        enemyAI.SteeringManager.SteeringAvoid(deltaTime, 1.0f, 0.1f);
                        enemyAI.SteeringManager.SteeringSeek(wallAttachPos);
                    }
                }
                break;

            case AIState.Attack:
            case AIState.Aggressive:
                if (enemyAI.AttackingLimb != null)
                {
                    if (AttachToSub && !enemyAI.IsSteeringThroughGap && wallAttachPos != Vector2.Zero && targetBody != null)
                    {
                        // is not attached or is attached to something else
                        if (!IsAttached || IsAttached && AttachJoints[0].BodyB != targetBody)
                        {
                            if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.DamageRange * enemyAI.AttackingLimb.attack.DamageRange)
                            {
                                AttachToBody(transformedAttachPos);
                            }
                        }
                    }
                }
                break;

            default:
                DeattachFromBody(reset: true);
                break;
            }

            if (IsAttached && targetBody != null && targetWall != null && targetSubmarine != null && deattachTimer <= 0.0f)
            {
                bool deattach = false;
                // Deattach if the wall is broken enough where we are attached to
                int targetSection = targetWall.FindSectionIndex(attachLimb.WorldPosition, world: true, clamp: true);
                if (enemyAI.CanPassThroughHole(targetWall, targetSection))
                {
                    deattach       = true;
                    attachCooldown = 2;
                }
                if (!deattach)
                {
                    // Deattach if the velocity is high
                    float velocity = targetSubmarine.Velocity == Vector2.Zero ? 0.0f : targetSubmarine.Velocity.Length();
                    deattach = velocity > maxDeattachSpeed;
                    if (!deattach)
                    {
                        if (velocity > minDeattachSpeed)
                        {
                            float velocityFactor = (maxDeattachSpeed - minDeattachSpeed <= 0.0f) ?
                                                   Math.Sign(Math.Abs(velocity) - minDeattachSpeed) :
                                                   (Math.Abs(velocity) - minDeattachSpeed) / (maxDeattachSpeed - minDeattachSpeed);

                            if (Rand.Range(0.0f, 1.0f) < velocityFactor)
                            {
                                deattach = true;
                                character.AddDamage(character.WorldPosition, new List <Affliction>()
                                {
                                    AfflictionPrefab.InternalDamage.Instantiate(damageOnDetach)
                                }, detachStun, true);
                                attachCooldown = detachStun * 2;
                            }
                        }
                    }
                }
                if (deattach)
                {
                    DeattachFromBody(reset: true);
                }
                deattachTimer = 5.0f;
            }
        }
コード例 #10
0
        public static void ExecuteCommand(string command, GameMain game)
        {
            if (string.IsNullOrWhiteSpace(command))
            {
                return;
            }
            string[] commands = command.Split(' ');

            if (!commands[0].ToLowerInvariant().Equals("admin"))
            {
                NewMessage(textBox.Text, Color.White);
            }

#if !DEBUG
            if (GameMain.Client != null && !IsCommandPermitted(commands[0].ToLowerInvariant(), GameMain.Client))
            {
                ThrowError("You're not permitted to use the command \"" + commands[0].ToLowerInvariant() + "\"!");
                return;
            }
#endif

            switch (commands[0].ToLowerInvariant())
            {
            case "help":
                NewMessage("menu: go to main menu", Color.Cyan);
                NewMessage("game: enter the \"game screen\"", Color.Cyan);
                NewMessage("edit: switch to submarine editor", Color.Cyan);
                NewMessage("edit [submarine name]: load a submarine and switch to submarine editor", Color.Cyan);
                NewMessage("load [submarine name]: load a submarine", Color.Cyan);
                NewMessage("save [submarine name]: save the current submarine using the specified name", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("spawn [creaturename] [near/inside/outside]: spawn a creature at a random spawnpoint (use the second parameter to only select spawnpoints near/inside/outside the submarine)", Color.Cyan);
                NewMessage("spawnitem [itemname] [cursor/inventory]: spawn an item at the position of the cursor, in the inventory of the controlled character or at a random spawnpoint if the last parameter is omitted", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("lights: disable lighting", Color.Cyan);
                NewMessage("los: disable the line of sight effect", Color.Cyan);
                NewMessage("freecam: detach the camera from the controlled character", Color.Cyan);
                NewMessage("control [character name]: start controlling the specified character", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("water: allows adding water into rooms or removing it by holding the left/right mouse buttons", Color.Cyan);
                NewMessage("fire: allows putting up fires by left clicking", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("teleport: teleport the controlled character to the position of the cursor", Color.Cyan);
                NewMessage("teleport [character name]: teleport the specified character to the position of the cursor", Color.Cyan);
                NewMessage("heal: restore the controlled character to full health", Color.Cyan);
                NewMessage("heal [character name]: restore the specified character to full health", Color.Cyan);
                NewMessage("revive: bring the controlled character back from the dead", Color.Cyan);
                NewMessage("revive [character name]: bring the specified character back from the dead", Color.Cyan);
                NewMessage("killmonsters: immediately kills all AI-controlled enemies in the level", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("fixwalls: fixes all the walls", Color.Cyan);
                NewMessage("fixitems: fixes every item/device in the sub", Color.Cyan);
                NewMessage("oxygen: replenishes the oxygen in every room to 100%", Color.Cyan);
                NewMessage("power [amount]: immediately sets the temperature of the reactor to the specified value", Color.Cyan);

                NewMessage(" ", Color.Cyan);

                NewMessage("kick [name]: kick a player out from the server", Color.Cyan);
                NewMessage("ban [name]: kick and ban the player from the server", Color.Cyan);
                NewMessage("banip [IP address]: ban the IP address from the server", Color.Cyan);
                NewMessage("debugdraw: toggles the \"debug draw mode\"", Color.Cyan);
                NewMessage("netstats: toggles the visibility of the network statistics panel", Color.Cyan);

                break;

            case "createfilelist":
                UpdaterUtil.SaveFileList("filelist.xml");
                break;

            case "spawn":
            case "spawncharacter":
                if (commands.Length == 1)
                {
                    return;
                }

                Character spawnedCharacter = null;

                Vector2  spawnPosition = Vector2.Zero;
                WayPoint spawnPoint    = null;

                if (commands.Length > 2)
                {
                    switch (commands[2].ToLowerInvariant())
                    {
                    case "inside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                        break;

                    case "outside":
                        spawnPoint = WayPoint.GetRandom(SpawnType.Enemy);
                        break;

                    case "near":
                    case "close":
                        float closestDist = -1.0f;
                        foreach (WayPoint wp in WayPoint.WayPointList)
                        {
                            if (wp.Submarine != null)
                            {
                                continue;
                            }

                            //don't spawn inside hulls
                            if (Hull.FindHull(wp.WorldPosition, null) != null)
                            {
                                continue;
                            }

                            float dist = Vector2.Distance(wp.WorldPosition, GameMain.GameScreen.Cam.WorldViewCenter);

                            if (closestDist < 0.0f || dist < closestDist)
                            {
                                spawnPoint  = wp;
                                closestDist = dist;
                            }
                        }
                        break;

                    case "cursor":
                        spawnPosition = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                        break;

                    default:
                        spawnPoint = WayPoint.GetRandom(commands[1].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                        break;
                    }
                }
                else
                {
                    spawnPoint = WayPoint.GetRandom(commands[1].ToLowerInvariant() == "human" ? SpawnType.Human : SpawnType.Enemy);
                }

                if (string.IsNullOrWhiteSpace(commands[1]))
                {
                    return;
                }

                if (spawnPoint != null)
                {
                    spawnPosition = spawnPoint.WorldPosition;
                }

                if (commands[1].ToLowerInvariant() == "human")
                {
                    spawnedCharacter = Character.Create(Character.HumanConfigFile, spawnPosition);

                    if (GameMain.GameSession != null)
                    {
                        SinglePlayerMode mode = GameMain.GameSession.gameMode as SinglePlayerMode;
                        if (mode != null)
                        {
                            Character.Controlled = spawnedCharacter;
                            GameMain.GameSession.CrewManager.AddCharacter(Character.Controlled);
                            GameMain.GameSession.CrewManager.SelectCharacter(null, Character.Controlled);
                        }
                    }
                }
                else
                {
                    spawnedCharacter = Character.Create(
                        "Content/Characters/"
                        + commands[1].First().ToString().ToUpper() + commands[1].Substring(1)
                        + "/" + commands[1].ToLower() + ".xml", spawnPosition);
                }

                break;

            case "spawnitem":
                if (commands.Length < 2)
                {
                    return;
                }

                Vector2?  spawnPos       = null;
                Inventory spawnInventory = null;

                int extraParams = 0;
                switch (commands.Last())
                {
                case "cursor":
                    extraParams = 1;
                    spawnPos    = GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition);
                    break;

                case "inventory":
                    extraParams    = 1;
                    spawnInventory = Character.Controlled == null ? null : Character.Controlled.Inventory;
                    break;

                default:
                    extraParams = 0;
                    break;
                }

                string itemName = string.Join(" ", commands.Skip(1).Take(commands.Length - extraParams - 1)).ToLowerInvariant();

                var itemPrefab = MapEntityPrefab.list.Find(ip => ip.Name.ToLowerInvariant() == itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    ThrowError("Item \"" + itemName + "\" not found!");
                    return;
                }

                if (spawnPos == null && spawnInventory == null)
                {
                    var wp = WayPoint.GetRandom(SpawnType.Human, null, Submarine.MainSub);
                    spawnPos = wp == null ? Vector2.Zero : wp.WorldPosition;
                }

                if (spawnPos != null)
                {
                    Item.Spawner.AddToSpawnQueue(itemPrefab, (Vector2)spawnPos);
                }
                else if (spawnInventory != null)
                {
                    Item.Spawner.AddToSpawnQueue(itemPrefab, spawnInventory);
                }

                break;

            case "disablecrewai":
                HumanAIController.DisableCrewAI = !HumanAIController.DisableCrewAI;
                break;

            case "enablecrewai":
                HumanAIController.DisableCrewAI = false;
                break;

            /*case "admin":
             *  if (commands.Length < 2) break;
             *
             *  if (GameMain.Server != null)
             *  {
             *      GameMain.Server.AdminAuthPass = commands[1];
             *
             *  }
             *  else if (GameMain.Client != null)
             *  {
             *      GameMain.Client.RequestAdminAuth(commands[1]);
             *  }
             *  break;*/
            case "kick":
                if (GameMain.NetworkMember == null || commands.Length < 2)
                {
                    break;
                }
                GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), false);

                break;

            case "ban":
                if (GameMain.NetworkMember == null || commands.Length < 2)
                {
                    break;
                }
                GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), true);

                break;

            case "banip":
            {
                if (GameMain.Server == null || commands.Length < 2)
                {
                    break;
                }

                var client = GameMain.Server.ConnectedClients.Find(c => c.Connection.RemoteEndPoint.Address.ToString() == commands[1]);
                if (client == null)
                {
                    GameMain.Server.BanList.BanPlayer("Unnamed", commands[1]);
                }
                else
                {
                    GameMain.Server.KickClient(client, true);
                }
            }
            break;

            case "startclient":
                if (commands.Length == 1)
                {
                    return;
                }
                if (GameMain.Client == null)
                {
                    GameMain.NetworkMember = new GameClient("Name");
                    GameMain.Client.ConnectToServer(commands[1]);
                }
                break;

            case "mainmenuscreen":
            case "mainmenu":
            case "menu":
                GameMain.GameSession = null;

                List <Character> characters = new List <Character>(Character.CharacterList);
                foreach (Character c in characters)
                {
                    c.Remove();
                }

                GameMain.MainMenuScreen.Select();
                break;

            case "gamescreen":
            case "game":
                GameMain.GameScreen.Select();
                break;

            case "editmapscreen":
            case "editmap":
            case "edit":
                if (commands.Length > 1)
                {
                    Submarine.Load(string.Join(" ", commands.Skip(1)), true);
                }
                GameMain.EditMapScreen.Select();
                break;

            case "test":
                Submarine.Load("aegir mark ii", true);
                GameMain.DebugDraw = true;
                GameMain.LightManager.LosEnabled = false;
                GameMain.EditMapScreen.Select();
                break;

            case "editcharacter":
            case "editchar":
                GameMain.EditCharacterScreen.Select();
                break;

            case "controlcharacter":
            case "control":
            {
                if (commands.Length < 2)
                {
                    break;
                }

                var character = FindMatchingCharacter(commands, true);

                if (character != null)
                {
                    Character.Controlled = character;
                }
            }
            break;

            case "setclientcharacter":
            {
                if (GameMain.Server == null)
                {
                    break;
                }

                int separatorIndex = Array.IndexOf(commands, ";");

                if (separatorIndex == -1 || commands.Length < 4)
                {
                    ThrowError("Invalid parameters. The command should be formatted as \"setclientcharacter [client] ; [character]\"");
                    break;
                }

                string[] commandsLeft  = commands.Take(separatorIndex).ToArray();
                string[] commandsRight = commands.Skip(separatorIndex).ToArray();

                string clientName = String.Join(" ", commandsLeft.Skip(1));

                var client = GameMain.Server.ConnectedClients.Find(c => c.name == clientName);
                if (client == null)
                {
                    ThrowError("Client \"" + clientName + "\" not found.");
                }

                var character = FindMatchingCharacter(commandsRight, false);
                GameMain.Server.SetClientCharacter(client, character);
            }
            break;

            case "teleportcharacter":
            case "teleport":
                var tpCharacter = FindMatchingCharacter(commands, false);

                if (commands.Length < 2)
                {
                    tpCharacter = Character.Controlled;
                }

                if (tpCharacter != null)
                {
                    var cam = GameMain.GameScreen.Cam;
                    tpCharacter.AnimController.CurrentHull = null;
                    tpCharacter.Submarine = null;
                    tpCharacter.AnimController.SetPosition(ConvertUnits.ToSimUnits(cam.ScreenToWorld(PlayerInput.MousePosition)));
                    tpCharacter.AnimController.FindHull(cam.ScreenToWorld(PlayerInput.MousePosition), true);
                }
                break;

            case "godmode":
                if (Submarine.MainSub == null)
                {
                    return;
                }

                Submarine.MainSub.GodMode = !Submarine.MainSub.GodMode;
                break;

            case "lockx":
                Submarine.LockX = !Submarine.LockX;
                break;

            case "locky":
                Submarine.LockY = !Submarine.LockY;
                break;

            case "dumpids":
                try
                {
                    int count = commands.Length < 2 ? 10 : int.Parse(commands[1]);
                    Entity.DumpIds(count);
                }
                catch
                {
                    return;
                }
                break;

            case "heal":
                Character healedCharacter = null;
                if (commands.Length == 1)
                {
                    healedCharacter = Character.Controlled;
                }
                else
                {
                    healedCharacter = FindMatchingCharacter(commands);
                }

                if (healedCharacter != null)
                {
                    healedCharacter.AddDamage(CauseOfDeath.Damage, -healedCharacter.MaxHealth, null);
                    healedCharacter.Oxygen   = 100.0f;
                    healedCharacter.Bleeding = 0.0f;
                    healedCharacter.Stun     = 0.0f;
                }

                break;

            case "revive":
                Character revivedCharacter = null;
                if (commands.Length == 1)
                {
                    revivedCharacter = Character.Controlled;
                }
                else
                {
                    revivedCharacter = FindMatchingCharacter(commands);
                }

                if (revivedCharacter != null)
                {
                    revivedCharacter.Revive(false);
                    if (GameMain.Server != null)
                    {
                        foreach (Client c in GameMain.Server.ConnectedClients)
                        {
                            if (c.Character != revivedCharacter)
                            {
                                continue;
                            }
                            //clients stop controlling the character when it dies, force control back
                            GameMain.Server.SetClientCharacter(c, revivedCharacter);
                            break;
                        }
                    }
                }
                break;

            case "freeze":
                if (Character.Controlled != null)
                {
                    Character.Controlled.AnimController.Frozen = !Character.Controlled.AnimController.Frozen;
                }
                break;

            case "freecamera":
            case "freecam":
                Character.Controlled = null;
                GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
                break;

            case "editwater":
            case "water":
                if (GameMain.Client == null)
                {
                    Hull.EditWater = !Hull.EditWater;
                }

                break;

            case "fire":
                if (GameMain.Client == null)
                {
                    Hull.EditFire = !Hull.EditFire;
                }

                break;

            case "fixitems":
                foreach (Item it in Item.ItemList)
                {
                    it.Condition = 100.0f;
                }
                break;

            case "fixhull":
            case "fixwalls":
                foreach (Structure w in Structure.WallList)
                {
                    for (int i = 0; i < w.SectionCount; i++)
                    {
                        w.AddDamage(i, -100000.0f);
                    }
                }
                break;

            case "power":
                Item reactorItem = Item.ItemList.Find(i => i.GetComponent <Reactor>() != null);
                if (reactorItem == null)
                {
                    return;
                }

                float power = 5000.0f;
                if (commands.Length > 1)
                {
                    float.TryParse(commands[1], out power);
                }

                var reactor = reactorItem.GetComponent <Reactor>();
                reactor.ShutDownTemp = power == 0 ? 0 : 7000.0f;
                reactor.AutoTemp     = true;
                reactor.Temperature  = power;

                if (GameMain.Server != null)
                {
                    reactorItem.CreateServerEvent(reactor);
                }
                break;

            case "shake":
                GameMain.GameScreen.Cam.Shake = 10.0f;
                break;

            case "losenabled":
            case "los":
            case "drawlos":
                GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
                break;

            case "lighting":
            case "lightingenabled":
            case "light":
            case "lights":
                GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled;
                break;

            case "oxygen":
            case "air":
                foreach (Hull hull in Hull.hullList)
                {
                    hull.OxygenPercentage = 100.0f;
                }
                break;

            case "tutorial":
                TutorialMode.StartTutorial(Tutorials.TutorialType.TutorialTypes[0]);


                break;

            case "editortutorial":
                GameMain.EditMapScreen.Select();
                GameMain.EditMapScreen.StartTutorial();
                break;

            case "lobbyscreen":
            case "lobby":
                GameMain.LobbyScreen.Select();
                break;

            case "savemap":
            case "savesub":
            case "save":
                if (commands.Length < 2)
                {
                    break;
                }

                if (GameMain.EditMapScreen.CharacterMode)
                {
                    GameMain.EditMapScreen.ToggleCharacterMode();
                }

                string fileName = string.Join(" ", commands.Skip(1));
                if (fileName.Contains("../"))
                {
                    DebugConsole.ThrowError("Illegal symbols in filename (../)");
                    return;
                }

                if (Submarine.SaveCurrent(System.IO.Path.Combine(Submarine.SavePath, fileName + ".sub")))
                {
                    NewMessage("Sub saved", Color.Green);
                    //Submarine.Loaded.First().CheckForErrors();
                }

                break;

            case "loadmap":
            case "loadsub":
            case "load":
                if (commands.Length < 2)
                {
                    break;
                }

                Submarine.Load(string.Join(" ", commands.Skip(1)), true);
                break;

            case "cleansub":
                for (int i = MapEntity.mapEntityList.Count - 1; i >= 0; i--)
                {
                    MapEntity me = MapEntity.mapEntityList[i];

                    if (me.SimPosition.Length() > 2000.0f)
                    {
                        DebugConsole.NewMessage("Removed " + me.Name + " (simposition " + me.SimPosition + ")", Color.Orange);
                        MapEntity.mapEntityList.RemoveAt(i);
                    }
                    else if (me.MoveWithLevel)
                    {
                        DebugConsole.NewMessage("Removed " + me.Name + " (MoveWithLevel==true)", Color.Orange);
                        MapEntity.mapEntityList.RemoveAt(i);
                    }
                    else if (me is Item)
                    {
                        Item item = me as Item;
                        var  wire = item.GetComponent <Wire>();
                        if (wire == null)
                        {
                            continue;
                        }

                        if (wire.GetNodes().Count > 0 && !wire.Connections.Any(c => c != null))
                        {
                            wire.Item.Drop(null);
                            DebugConsole.NewMessage("Dropped wire (ID: " + wire.Item.ID + ") - attached on wall but no connections found", Color.Orange);
                        }
                    }
                }
                break;

            case "messagebox":
                if (commands.Length < 3)
                {
                    break;
                }
                new GUIMessageBox(commands[1], commands[2]);
                break;

            case "debugdraw":
                GameMain.DebugDraw = !GameMain.DebugDraw;
                break;

            case "disablehud":
            case "hud":
                GUI.DisableHUD = !GUI.DisableHUD;
                GameMain.Instance.IsMouseVisible = !GameMain.Instance.IsMouseVisible;
                break;

            case "followsub":
                Camera.FollowSub = !Camera.FollowSub;
                break;

            case "drawaitargets":
            case "showaitargets":
                AITarget.ShowAITargets = !AITarget.ShowAITargets;
                break;

            case "killmonsters":
                foreach (Character c in Character.CharacterList)
                {
                    if (!(c.AIController is EnemyAIController))
                    {
                        continue;
                    }
                    c.AddDamage(CauseOfDeath.Damage, 10000.0f, null);
                }
                break;

            case "netstats":
                if (GameMain.Server == null)
                {
                    return;
                }

                GameMain.Server.ShowNetStats = !GameMain.Server.ShowNetStats;
                break;

#if DEBUG
            case "spamevents":
                foreach (Item item in Item.ItemList)
                {
                    for (int i = 0; i < item.components.Count; i++)
                    {
                        if (item.components[i] is IServerSerializable)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, i });
                        }
                        var itemContainer = item.GetComponent <ItemContainer>();
                        if (itemContainer != null)
                        {
                            GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState });
                        }

                        GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });

                        item.NeedsPositionUpdate = true;
                    }
                }

                foreach (Character c in Character.CharacterList)
                {
                    GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status });
                }

                foreach (Structure wall in Structure.WallList)
                {
                    GameMain.Server.CreateEntityEvent(wall);
                }
                break;

            case "spamchatmessages":
                int msgCount = 1000;
                if (commands.Length > 1)
                {
                    int.TryParse(commands[1], out msgCount);
                }
                int msgLength = 50;
                if (commands.Length > 2)
                {
                    int.TryParse(commands[2], out msgLength);
                }

                for (int i = 0; i < msgCount; i++)
                {
                    if (GameMain.Server != null)
                    {
                        GameMain.Server.SendChatMessage(ToolBox.RandomSeed(msgLength), ChatMessageType.Default);
                    }
                    else
                    {
                        GameMain.Client.SendChatMessage(ToolBox.RandomSeed(msgLength));
                    }
                }
                break;
#endif
            case "cleanbuild":
                GameMain.Config.MusicVolume = 0.5f;
                GameMain.Config.SoundVolume = 0.5f;
                DebugConsole.NewMessage("Music and sound volume set to 0.5", Color.Green);

                GameMain.Config.GraphicsWidth  = 0;
                GameMain.Config.GraphicsHeight = 0;
                GameMain.Config.WindowMode     = WindowMode.Fullscreen;
                DebugConsole.NewMessage("Resolution set to 0 x 0 (screen resolution will be used)", Color.Green);
                DebugConsole.NewMessage("Fullscreen enabled", Color.Green);

                GameSettings.VerboseLogging = false;

                if (GameMain.Config.MasterServerUrl != "http://www.undertowgames.com/baromaster")
                {
                    DebugConsole.ThrowError("MasterServerUrl \"" + GameMain.Config.MasterServerUrl + "\"!");
                }

                GameMain.Config.Save("config.xml");

                var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder);

                foreach (string saveFile in saveFiles)
                {
                    System.IO.File.Delete(saveFile);
                    DebugConsole.NewMessage("Deleted " + saveFile, Color.Green);
                }

                if (System.IO.Directory.Exists(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp")))
                {
                    System.IO.Directory.Delete(System.IO.Path.Combine(SaveUtil.SaveFolder, "temp"), true);
                    DebugConsole.NewMessage("Deleted temp save folder", Color.Green);
                }

                if (System.IO.Directory.Exists(ServerLog.SavePath))
                {
                    var logFiles = System.IO.Directory.GetFiles(ServerLog.SavePath);

                    foreach (string logFile in logFiles)
                    {
                        System.IO.File.Delete(logFile);
                        DebugConsole.NewMessage("Deleted " + logFile, Color.Green);
                    }
                }

                if (System.IO.File.Exists("filelist.xml"))
                {
                    System.IO.File.Delete("filelist.xml");
                    DebugConsole.NewMessage("Deleted filelist", Color.Green);
                }


                if (System.IO.File.Exists("Submarines/TutorialSub.sub"))
                {
                    System.IO.File.Delete("Submarines/TutorialSub.sub");

                    DebugConsole.NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
                }

                if (System.IO.File.Exists(GameServer.SettingsFile))
                {
                    System.IO.File.Delete(GameServer.SettingsFile);
                    DebugConsole.NewMessage("Deleted server settings", Color.Green);
                }

                if (System.IO.File.Exists(GameServer.ClientPermissionsFile))
                {
                    System.IO.File.Delete(GameServer.ClientPermissionsFile);
                    DebugConsole.NewMessage("Deleted client permission file", Color.Green);
                }

                if (System.IO.File.Exists("crashreport.txt"))
                {
                    System.IO.File.Delete("crashreport.txt");
                    DebugConsole.NewMessage("Deleted crashreport.txt", Color.Green);
                }

                if (!System.IO.File.Exists("Content/Map/TutorialSub.sub"))
                {
                    DebugConsole.ThrowError("TutorialSub.sub not found!");
                }

                break;

            default:
                NewMessage("Command not found", Color.Red);
                break;
            }
        }