private static RoomObject DeepCopyRoomObject(RoomObject obj, Room room, Game game, Player user)
        {
            RoomObject copy = null;

            if (obj != null)
            {
                switch (obj.GetType().Name)
                {
                case "StructureSpawn":
                    var spawn = (StructureSpawn)obj;
                    copy = new StructureSpawn()
                    {
                        Game = game,
                        My   = spawn.Owner != null && spawn.Owner.ID == user.ID,
                        Pos  = room.GetPositionAt(spawn.Pos.X, spawn.Pos.Y),
                        Room = room,

                        Energy         = spawn.Energy,
                        EnergyCapacity = spawn.EnergyCapacity,
                        HitPoints      = spawn.HitPoints,
                        HitPointsMax   = spawn.HitPointsMax,
                        ID             = spawn.ID,
                        IsActive       = spawn.IsActive,
                        Name           = spawn.Name,
                        Owner          = spawn.Owner,
                        Spawning       = spawn.Spawning,
                        Type           = spawn.Type,
                        Memory         = new Dictionary <string, object>(),
                    };

                    game.Memory.Add(copy.ID, ((StructureSpawn)copy).Memory);

                    if (spawn.Memory != null)
                    {
                        foreach (string key in spawn.Memory.Keys)
                        {
                            ((StructureSpawn)copy).Memory.Add(key, room.Memory[key]);
                        }

                        ((StructureSpawn)copy).Memory["#"] = 2;
                    }
                    break;

                case "StructureController":
                    var controller = (StructureController)obj;
                    copy = new StructureController()
                    {
                        Game = game,
                        Room = room,

                        Owner = controller.Owner,
                        My    = controller.Owner != null && controller.Owner.ID == user.ID,

                        HitPoints    = controller.HitPoints,
                        HitPointsMax = controller.HitPointsMax,
                        ID           = controller.ID,
                        IsActive     = controller.IsActive,
                        Pos          = controller.Pos,
                        Type         = controller.Type,

                        Progress         = controller.Progress,
                        ProgressTotal    = controller.ProgressTotal,
                        Level            = controller.Level,
                        TicksToDowngrade = controller.TicksToDowngrade,
                    };
                    break;

                case "Source":
                    var source = (Source)obj;
                    copy = new Source()
                    {
                        Game = game,
                        Room = room,

                        Energy            = source.Energy,
                        EnergyCapacity    = source.EnergyCapacity,
                        ID                = source.ID,
                        Pos               = source.Pos,
                        TicksToRegenerate = source.TicksToRegenerate,
                    };
                    break;

                case "Creep":
                    var creep = (Creep)obj;

                    // TODO: Player-defined child class

                    copy = new Creep()
                    {
                        Game = game,
                        My   = (creep.Owner.ID == user.ID),
                        Room = room,

                        Body               = creep.Body,
                        Fatigue            = creep.Fatigue,
                        HitPoints          = creep.HitPoints,
                        HitPointsMax       = creep.HitPointsMax,
                        ID                 = creep.ID,
                        Name               = creep.Name,
                        NotifyWhenAttacked = creep.NotifyWhenAttacked,
                        Owner              = creep.Owner,
                        Pos                = creep.Pos,
                        Saying             = creep.Saying,
                        Spawning           = creep.Spawning,
                        TicksToLive        = creep.TicksToLive,

                        Memory    = new Dictionary <string, object>(),
                        _carrying = new Dictionary <ResourceTypes, int>(),
                    };

                    game.Memory.Add(copy.ID, ((Creep)copy).Memory);

                    foreach (string key in creep.Memory.Keys)
                    {
                        ((Creep)copy).Memory.Add(key, creep.Memory[key]);
                    }

                    ((Creep)copy).Memory["#"] = 2;

                    foreach (var key in creep._carrying.Keys)
                    {
                        ((Creep)copy)._carrying.Add(key, creep._carrying[key]);
                    }
                    break;

                default:
                    string type = obj.GetType().Name;
                    break;
                }
            }

            return(copy);
        }