Example #1
0
        // Mini update is done even when not the active location
        public void miniUpdate()
        {
            NPCMonitor.check(loc);
            checkBuildings();

#if false
            // Apparently this is causing A LOT of lag. Let's skip it when we can.
            if (Game1.locationAfterWarp != loc || Game1.fadeToBlackAlpha <= 0.97)
            {
                return;
            }

            var layer     = loc.map.GetLayer("Buildings");
            NPC checkWith = Game1.getCharacterFromName("Penny");

            // This bug has something to do with GameLocation.openDoor (I think).
            // Investigate actual cause later, instead of this messy patch
            /**/ Tile firstValid    = null;
            Tile      firstNonsolid = null;
            Vector2   nonSolidPos   = new Vector2();
            for (int ix = 0; ix < layer.LayerWidth; ++ix)
            {
                for (int iy = 0; iy < layer.LayerHeight; ++iy)
                {
                    Tile tmp = layer.Tiles[ix, iy];

                    if (tmp != null)
                    {
                        if (firstValid != null)
                        {
                            firstValid = tmp;
                        }

                        Rectangle rect = checkWith.GetBoundingBox();
                        rect = new Rectangle(ix * Game1.tileSize + Game1.tileSize / 8, iy * Game1.tileSize + Game1.tileSize / 8, rect.Width, rect.Height);
                        if (tmp.TileIndex != 0 && !loc.isCollidingPosition(rect, Game1.viewport, checkWith))
                        {
                            Log.Async("Found non-solid pos: " + ix + ", " + iy);
                            firstNonsolid = tmp;
                            nonSolidPos   = new Vector2(ix, iy);
                            ix            = layer.LayerWidth;
                            break;
                        }
                    }
                }
            }

            Tile tileFix = firstValid;
            if (firstNonsolid != null)
            {
                tileFix = firstNonsolid;//*/
            }
Example #2
0
        public static void update()
        {
            if (Multiplayer.mode == Mode.Singleplayer)
            {
                return;
            }

            if (MultiplayerUtility.latestID > prevLatestId)
            {
                sendFunc(new LatestIdPacket());
            }
            prevLatestId = MultiplayerUtility.latestID;

            //Log.Async("pos:" + Game1.player.position.X + " " + Game1.player.position.Y);
            // Clients sometimes get stuck in the top-right corner and can't move on second day+
            if (Game1.player.currentLocation != null && Game1.player.currentLocation.name == "FarmHouse" &&
                Game1.player.currentLocation == Game1.currentLocation && Game1.player.currentLocation != Game1.getLocationFromName(Game1.player.currentLocation.name))
            {
                Game1.player.currentLocation = Game1.getLocationFromName(Game1.player.currentLocation.name);
                Game1.currentLocation        = Game1.player.currentLocation;
                Game1.currentLocation.resetForPlayerEntry();
            }

            // Really don't understand why it breaks without this
            // But as soon as you get to the second day, it does. Ugh.
            Game1.player.FarmerSprite.setOwner(Game1.player);

            if (Game1.newDay)
            {
                didNewDay            = true;
                Game1.freezeControls = prevFreezeControls = true;
                Game1.player.CanMove = false;
                if (!sentNextDayPacket)
                {
                    ChatMenu.chat.Add(new ChatEntry(null, Game1.player.name + " is in bed."));
                    if (mode == Mode.Host)
                    {
                        server.broadcast(new ChatPacket(255, Game1.player.name + " is in bed."));
                    }
                    else if (mode == Mode.Client)
                    {
                        client.stage = Client.NetStage.Waiting;

                        SaveGame oldLoaded = SaveGame.loaded;
                        var      it        = NewSaveGame.Save(true);
                        while (it.Current < 100)
                        {
                            it.MoveNext();
                            Thread.Sleep(5);
                        }

                        MemoryStream tmp = new MemoryStream();
                        SaveGame.serializer.Serialize(tmp, SaveGame.loaded);
                        sendFunc(new NextDayPacket());
                        sendFunc(new ClientFarmerDataPacket(Encoding.UTF8.GetString(tmp.ToArray())));
                        //SaveGame.loaded = oldLoaded;
                    }
                    sentNextDayPacket = true;
                }

                if (waitingOnOthers() && Game1.fadeToBlackAlpha > 0.625f)
                {
                    Game1.fadeToBlackAlpha = 0.625f;
                }
            }
            else
            {
                sentNextDayPacket = false;
            }

            // We want people to wait for everyone
            //Log.Async("menu:"+Game1.activeClickableMenu);
            if (Game1.activeClickableMenu is SaveGameMenu && Game1.activeClickableMenu.GetType() != typeof(NewSaveGameMenu))
            {
                Game1.activeClickableMenu = new NewSaveGameMenu();
            }
            else if (Game1.activeClickableMenu is ShippingMenu)
            {
                //Log.Async("Savegame:" + Util.GetInstanceField(typeof(ShippingMenu), Game1.activeClickableMenu, "saveGameMenu"));
                SaveGameMenu menu = ( SaveGameMenu )Util.GetInstanceField(typeof(ShippingMenu), Game1.activeClickableMenu, "saveGameMenu");
                if (menu != null && menu.GetType() != typeof(NewSaveGameMenu))
                {
                    Util.SetInstanceField(typeof(ShippingMenu), Game1.activeClickableMenu, "saveGameMenu", new NewSaveGameMenu());
                }
            }

            if (Game1.currentLocation != null && Game1.currentLocation.currentEvent != null)
            {
                Events.fix();
            }
            else
            {
                Events.reset();
            }

            // Causing issues after going a day? Maybe?
            // Plus it only fixes a few of the time pauses

            /*Game1.player.forceTimePass = true;
             * Game1.paused = false;
             * if ( prevFreezeControls != Game1.freezeControls )
             * {
             *  sendFunc( new PauseTimePacket() );
             * }
             * prevFreezeControls = Game1.freezeControls;*/

            if (Multiplayer.mode == Mode.Host && server != null)
            {
                server.update();
                if (server == null)
                {
                    return;
                }

                if (server.clients == null)
                {
                    return;
                }
                foreach (Server.Client client_ in server.clients)
                {
                    if (client_.stage != Server.Client.NetStage.Playing)
                    {
                        continue;
                    }
                    if (client_.farmer == null)
                    {
                        continue;
                    }
                    doUpdatePlayer(client_.farmer);
                }
            }
            else if (Multiplayer.mode == Mode.Client && client != null)
            {
                client.update();
                if (client == null)
                {
                    return;
                }

                if (client.others == null)
                {
                    return;
                }
                foreach (KeyValuePair <byte, Farmer> other in client.others)
                {
                    if (other.Value == null)
                    {
                        continue;
                    }
                    doUpdatePlayer(other.Value);
                }
            }

            if (Game1.gameMode == 6)
            {
                return;                      // Loading?
            }
            // ^ TODO: Check if != 3 works

            if (Multiplayer.mode == Mode.Host && server != null && server.playing ||
                Multiplayer.mode == Mode.Client && client != null && client.stage == Client.NetStage.Playing)
            {
                if (Game1.newDay)
                {
                    return;
                }
                NPCMonitor.startChecks();
                foreach (GameLocation loc in Game1.locations)
                {
                    if (!locations.ContainsKey(loc.name))
                    {
                        locations.Add(loc.name, new LocationCache(loc));
                    }

                    locations[loc.name].miniUpdate();
                    if (Game1.player.currentLocation == loc)
                    {
                        locations[loc.name].update();
                    }

                    if (loc is Farm)
                    {
                        BuildableGameLocation farm = loc as BuildableGameLocation;
                        foreach (Building building in farm.buildings)
                        {
                            if (building.indoors == null)
                            {
                                continue;
                            }

                            if (!locations.ContainsKey(building.nameOfIndoors))
                            {
                                locations.Add(building.nameOfIndoors, new LocationCache(building.indoors));
                            }

                            locations[loc.name].miniUpdate();
                            if (Game1.currentLocation != loc)
                            {
                                locations[building.nameOfIndoors].update();
                            }

                            NPCMonitor.check(building.indoors);
                        }
                    }

                    if (loc.name == "FarmHouse")
                    {
                        //Log.Async("Terrain features count for " + loc.name + " " + loc + ": " + loc.terrainFeatures.Count);
                        //Log.Async("Object count for " + loc.name + " " + loc + ": " + loc.objects.Count);
                    }
                }
                NPCMonitor.endChecks();
            }
        }
Example #3
0
        public LocationCache(GameLocation theLoc)
        {
            loc = theLoc;

            // This could be done even better with macros.
            // (Although it wouldn't be as bad in the first place if I could use templates.)
            // Sigh. Still cleaner than copying those methods for every new TerrainFeature/Object type.
            monitors.Add(typeof(HoeDirt),
                         new SpecificMonitor <TerrainFeature, HoeDirt, HoeDirtState, TerrainFeatureUpdatePacket <HoeDirt> > (
                             this, loc.terrainFeatures,
                             (obj) => new HoeDirtState(obj),
                             (loc_, pos) => new TerrainFeatureUpdatePacket <HoeDirt>(loc_, pos)
                             ));
            monitors.Add(typeof(Tree),
                         new SpecificMonitor <TerrainFeature, Tree, TreeState, TerrainFeatureUpdatePacket <Tree> >(
                             this, loc.terrainFeatures,
                             (obj) => new TreeState(obj),
                             (loc_, pos) => new TerrainFeatureUpdatePacket <Tree>(loc_, pos)
                             ));
            monitors.Add(typeof(FruitTree),
                         new SpecificMonitor <TerrainFeature, FruitTree, FruitTreeState, TerrainFeatureUpdatePacket <FruitTree> >(
                             this, loc.terrainFeatures,
                             (obj) => new FruitTreeState(obj),
                             (loc_, pos) => new TerrainFeatureUpdatePacket <FruitTree>(loc_, pos)
                             ));
            monitors.Add(typeof(Door),
                         new SpecificMonitor <Object, Door, DoorState, ObjectUpdatePacket <Door> >(
                             this, loc.objects,
                             (obj) => new DoorState(obj),
                             (loc_, pos) => new ObjectUpdatePacket <Door>(loc_, pos)
                             ));
            monitors.Add(typeof(Fence),
                         new SpecificMonitor <Object, Fence, FenceState, FenceUpdatePacket>(
                             this, loc.objects,
                             (obj) => new FenceState(obj),
                             (loc_, pos) => new FenceUpdatePacket(loc_, pos)
                             ));
            monitors.Add(typeof(Object),
                         new SpecificMonitor <Object, Object, ObjectState, ObjectUpdatePacket <Object> >(
                             this, loc.objects,
                             (obj) => new ObjectState(obj),
                             (loc_, pos) => new ObjectUpdatePacket <Object>(loc_, pos)
                             ));
            monitors.Add(typeof(CrabPot),
                         new SpecificMonitor <Object, CrabPot, CrabPotState, ObjectUpdatePacket <CrabPot> >(
                             this, loc.objects,
                             (obj) => new CrabPotState(obj),
                             (loc_, pos) => new ObjectUpdatePacket <CrabPot>(loc_, pos)
                             ));
            monitors.Add(typeof(Chest), new ChestMonitor(this));

            loc.terrainFeatures.CollectionChanged += new NotifyCollectionChangedEventHandler(terrainFeaturesChanged);
            loc.objects.CollectionChanged         += new NotifyCollectionChangedEventHandler(objectsChanged);

            // Pre-populate monitor caches so it knows what to watch. Otherwise it would only do new things
            foreach (KeyValuePair <Vector2, TerrainFeature> tf in loc.terrainFeatures)
            {
                Type type = tf.Value.GetType();
                if (monitors.ContainsKey(type))
                {
                    monitors[type].addCache(tf.Key, tf.Value);
                }
            }

            foreach (KeyValuePair <Vector2, Object> obj in loc.objects)
            {
                Type type = obj.Value.GetType();
                if (monitors.ContainsKey(type))
                {
                    monitors[type].addCache(obj.Key, obj.Value);
                }
            }

            ignoreUpdates = true;
            checkBuildings();
            checkLocationSpecificStuff();
            ignoreUpdates = false;

            NPCMonitor.ignoreUpdates = true;
            NPCMonitor.check(loc);
            NPCMonitor.ignoreUpdates = false;
        }