private void UpdateTicking(object sender, UpdateTickingEventArgs e)
        {
            if (!Context.IsWorldReady)
            {
                return;
            }
            GameLocation location = Game1.getPlayerOrEventFarmer().currentLocation;

            Netcode.NetCollection <Debris> debris = location.debris;
            GameTime time      = new GameTime();
            float    rangeMult = magnetRangeMult;
            bool     infRange  = (rangeMult < 0 ? true : false);
            int      speedMult = magnetSpeedMult;
            bool     noBounce  = noLootBounce;
            bool     noWave    = noLootWave;

            for (int j = 0; j < debris.Count; j++)
            {
                Debris d = debris[j];
                NetObjectShrinkList <Chunk> chunks = (NetObjectShrinkList <Chunk>) typeof(Debris).GetField("chunks", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(d);

                if (chunks.Count == 0)
                {
                    continue;
                }
                d.timeSinceDoneBouncing += (float)time.ElapsedGameTime.Milliseconds;
                if (d.timeSinceDoneBouncing >= (d.floppingFish ? 2500f : ((d.debrisType == Debris.DebrisType.SPRITECHUNKS || d.debrisType == Debris.DebrisType.NUMBERS) ? 1800f : (noBounce ? 0f : 600f))))
                {
                    if (d.debrisType == Debris.DebrisType.LETTERS || d.debrisType == Debris.DebrisType.NUMBERS || d.debrisType == Debris.DebrisType.SQUARES || d.debrisType == Debris.DebrisType.SPRITECHUNKS || (d.debrisType == Debris.DebrisType.CHUNKS && chunks[0].debrisType - chunks[0].debrisType % 2 != 8))
                    {
                        continue;
                    }
                    if (d.debrisType == Debris.DebrisType.ARCHAEOLOGY || d.debrisType == Debris.DebrisType.OBJECT || d.debrisType == Debris.DebrisType.RESOURCE || d.debrisType == Debris.DebrisType.CHUNKS)
                    {
                        d.chunksMoveTowardPlayer = true;
                    }
                    d.timeSinceDoneBouncing = 0f;
                }
                if (location.farmers.Count == 0)
                {
                    continue;
                }
                Vector2 total = default(Vector2);
                foreach (Chunk chunk in chunks)
                {
                    total += chunk.position.Value;
                }
                Vector2 position = total / (float)chunks.Count;
                if (d.player.Value != null && (d.player.Value.currentLocation != location || !infRange && !(Math.Abs(position.X + 32f - (float)d.player.Value.getStandingX()) <= (float)d.player.Value.MagneticRadius * rangeMult && Math.Abs(position.Y + 32f - (float)d.player.Value.getStandingY()) <= (float)d.player.Value.MagneticRadius * rangeMult)))
                {
                    d.player.Value = null;
                }
                Farmer farmer = d.player.Value;
                if (farmer == null && (Game1.IsMasterGame || location.isTemp()))
                {
                    float  bestDistance = float.MaxValue;
                    Farmer bestFarmer   = null;
                    foreach (Farmer f in location.farmers)
                    {
                        bool pir = infRange || (Math.Abs(position.X + 32f - (float)f.getStandingX()) <= (float)f.MagneticRadius * rangeMult && Math.Abs(position.Y + 32f - (float)f.getStandingY()) <= (float)f.MagneticRadius * rangeMult);
                        if ((f.UniqueMultiplayerID != d.DroppedByPlayerID || bestFarmer == null) && pir)
                        {
                            float distance = (f.Position - position).LengthSquared();
                            if (distance < bestDistance || (bestFarmer != null && bestFarmer.UniqueMultiplayerID == d.DroppedByPlayerID))
                            {
                                bestFarmer   = f;
                                bestDistance = distance;
                            }
                        }
                    }
                    farmer = bestFarmer;
                }

                bool anyCouldMove = false;
                for (int i = chunks.Count - 1; i >= 0; i--)
                {
                    Chunk chunk = chunks[i];
                    chunk.position.UpdateExtrapolation(chunk.getSpeed());
                    if (chunk.alpha > 0.1f && (d.debrisType == Debris.DebrisType.SPRITECHUNKS || d.debrisType == Debris.DebrisType.NUMBERS) && d.timeSinceDoneBouncing > 600f)
                    {
                        chunk.alpha = (1800f - d.timeSinceDoneBouncing) / 1000f;
                    }
                    if (chunk.position.X < -128f || chunk.position.Y < -64f || chunk.position.X >= (float)(location.map.DisplayWidth + 64) || chunk.position.Y >= (float)(location.map.DisplayHeight + 64))
                    {
                        chunks.RemoveAt(i);
                    }
                    else
                    {
                        bool canMoveTowardPlayer = farmer != null;
                        if (canMoveTowardPlayer)
                        {
                            Debris.DebrisType value = d.debrisType.Value;
                            if (value - Debris.DebrisType.ARCHAEOLOGY > 1)
                            {
                                canMoveTowardPlayer = (value != Debris.DebrisType.RESOURCE || farmer.couldInventoryAcceptThisObject(chunk.debrisType - chunk.debrisType % 2, 1, 0));
                            }
                            else if (d.item != null)
                            {
                                canMoveTowardPlayer = farmer.couldInventoryAcceptThisItem(d.item);
                            }
                            else
                            {
                                if (chunk.debrisType < 0)
                                {
                                    canMoveTowardPlayer = farmer.couldInventoryAcceptThisItem(new StardewValley.Object(Vector2.Zero, chunk.debrisType * -1, false));
                                }
                                else
                                {
                                    canMoveTowardPlayer = farmer.couldInventoryAcceptThisObject(chunk.debrisType, 1, d.itemQuality);
                                }
                                if (chunk.debrisType == 102 && farmer.hasMenuOpen)
                                {
                                    canMoveTowardPlayer = false;
                                }
                            }
                            anyCouldMove = (anyCouldMove || canMoveTowardPlayer);
                            if (canMoveTowardPlayer)
                            {
                                d.player.Value = farmer;
                            }
                        }
                        if ((d.chunksMoveTowardPlayer || d.isFishable) && canMoveTowardPlayer)
                        {
                            if (d.player.Value.IsLocalPlayer)
                            {
                                if (speedMult < 0)
                                {
                                    chunk.position.X = d.player.Value.Position.X;
                                    chunk.position.Y = d.player.Value.Position.Y;
                                }
                                else
                                {
                                    for (int l = 1; l < speedMult; l++)
                                    {
                                        if (noWave)
                                        {
                                            if (chunk.position.X < d.player.Value.Position.X - 12f)
                                            {
                                                chunk.xVelocity.Value = 8f;
                                            }
                                            else if (chunk.position.X > d.player.Value.Position.X + 12f)
                                            {
                                                chunk.xVelocity.Value = -8f;
                                            }
                                            if (chunk.position.Y < d.player.Value.Position.Y - 12f)
                                            {
                                                chunk.yVelocity.Value = -8f;
                                            }
                                            else if (chunk.position.Y > d.player.Value.Position.Y + 12f)
                                            {
                                                chunk.yVelocity.Value = 8f;
                                            }
                                        }
                                        else
                                        {
                                            if (chunk.position.X < d.player.Value.Position.X - 12f)
                                            {
                                                chunk.xVelocity.Value = Math.Min(chunk.xVelocity + 0.8f, 8f);
                                            }
                                            else if (chunk.position.X > d.player.Value.Position.X + 12f)
                                            {
                                                chunk.xVelocity.Value = Math.Max(chunk.xVelocity - 0.8f, -8f);
                                            }
                                            if (chunk.position.Y + 32f < (float)(d.player.Value.getStandingY() - 12))
                                            {
                                                chunk.yVelocity.Value = Math.Max(chunk.yVelocity - 0.8f, -8f);
                                            }
                                            else if (chunk.position.Y + 32f > (float)(d.player.Value.getStandingY() + 12))
                                            {
                                                chunk.yVelocity.Value = Math.Min(chunk.yVelocity + 0.8f, 8f);
                                            }
                                        }
                                        chunk.position.X += chunk.xVelocity;
                                        chunk.position.Y -= chunk.yVelocity;
                                    }
                                }
                            }
                        }
                    }
                }
                typeof(Debris).GetField("chunks", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(d, chunks);
            }
        }
示例#2
0
        public bool updateChunks(GameTime time, GameLocation location)
        {
            if (chunks.Count == 0)
            {
                return(true);
            }
            timeSinceDoneBouncing += time.ElapsedGameTime.Milliseconds;
            if (timeSinceDoneBouncing >= (floppingFish ? 2500f : (((DebrisType)debrisType == DebrisType.SPRITECHUNKS || (DebrisType)debrisType == DebrisType.NUMBERS) ? 1800f : 600f)))
            {
                if ((DebrisType)debrisType == DebrisType.LETTERS || (DebrisType)debrisType == DebrisType.NUMBERS || (DebrisType)debrisType == DebrisType.SQUARES || (DebrisType)debrisType == DebrisType.SPRITECHUNKS || ((DebrisType)debrisType == DebrisType.CHUNKS && chunks[0].debrisType - chunks[0].debrisType % 2 != 8))
                {
                    return(true);
                }
                if ((DebrisType)debrisType == DebrisType.ARCHAEOLOGY || (DebrisType)debrisType == DebrisType.OBJECT || (DebrisType)debrisType == DebrisType.RESOURCE || (DebrisType)debrisType == DebrisType.CHUNKS)
                {
                    chunksMoveTowardPlayer = true;
                }
                timeSinceDoneBouncing = 0f;
            }
            if (!location.farmers.Any() && !location.isTemp())
            {
                return(false);
            }
            Vector2 position = approximatePosition();
            Farmer  farmer   = player.Value;

            if (isEssentialItem() && shouldControlThis(location) && farmer == null)
            {
                farmer = findBestPlayer(location);
            }
            if (chunksMoveTowardPlayer && !isEssentialItem())
            {
                if (player.Value != null && player.Value == Game1.player && !playerInRange(position, player.Value))
                {
                    player.Value = null;
                    farmer       = null;
                }
                if (shouldControlThis(location))
                {
                    if (player.Value != null && player.Value.currentLocation != location)
                    {
                        player.Value = null;
                        farmer       = null;
                    }
                    if (farmer == null)
                    {
                        farmer = findBestPlayer(location);
                    }
                }
            }
            bool anyCouldMove = false;

            for (int i = chunks.Count - 1; i >= 0; i--)
            {
                Chunk chunk = chunks[i];
                chunk.position.UpdateExtrapolation(chunk.getSpeed());
                if (chunk.alpha > 0.1f && ((DebrisType)debrisType == DebrisType.SPRITECHUNKS || (DebrisType)debrisType == DebrisType.NUMBERS) && timeSinceDoneBouncing > 600f)
                {
                    chunk.alpha = (1800f - timeSinceDoneBouncing) / 1000f;
                }
                if (chunk.position.X < -128f || chunk.position.Y < -64f || chunk.position.X >= (float)(location.map.DisplayWidth + 64) || chunk.position.Y >= (float)(location.map.DisplayHeight + 64))
                {
                    chunks.RemoveAt(i);
                }
                else
                {
                    bool canMoveTowardPlayer = farmer != null;
                    if (canMoveTowardPlayer)
                    {
                        switch (debrisType.Value)
                        {
                        case DebrisType.ARCHAEOLOGY:
                        case DebrisType.OBJECT:
                            if (item != null)
                            {
                                canMoveTowardPlayer = farmer.couldInventoryAcceptThisItem(item);
                                break;
                            }
                            canMoveTowardPlayer = ((chunk.debrisType >= 0) ? farmer.couldInventoryAcceptThisObject(chunk.debrisType, 1, itemQuality) : farmer.couldInventoryAcceptThisItem(new Object(Vector2.Zero, chunk.debrisType * -1)));
                            if (chunk.debrisType == 102 && (bool)farmer.hasMenuOpen)
                            {
                                canMoveTowardPlayer = false;
                            }
                            break;

                        case DebrisType.RESOURCE:
                            canMoveTowardPlayer = farmer.couldInventoryAcceptThisObject(chunk.debrisType - chunk.debrisType % 2, 1);
                            break;

                        default:
                            canMoveTowardPlayer = true;
                            break;
                        }
                        anyCouldMove |= canMoveTowardPlayer;
                        if (canMoveTowardPlayer && shouldControlThis(location))
                        {
                            player.Value = farmer;
                        }
                    }
                    if (((chunksMoveTowardPlayer || isFishable) & canMoveTowardPlayer) && player.Value != null)
                    {
                        if (player.Value.IsLocalPlayer)
                        {
                            if (chunk.position.X < player.Value.Position.X - 12f)
                            {
                                chunk.xVelocity.Value = Math.Min((float)chunk.xVelocity + 0.8f, 8f);
                            }
                            else if (chunk.position.X > player.Value.Position.X + 12f)
                            {
                                chunk.xVelocity.Value = Math.Max((float)chunk.xVelocity - 0.8f, -8f);
                            }
                            if (chunk.position.Y + 32f < (float)(player.Value.getStandingY() - 12))
                            {
                                chunk.yVelocity.Value = Math.Max((float)chunk.yVelocity - 0.8f, -8f);
                            }
                            else if (chunk.position.Y + 32f > (float)(player.Value.getStandingY() + 12))
                            {
                                chunk.yVelocity.Value = Math.Min((float)chunk.yVelocity + 0.8f, 8f);
                            }
                            chunk.position.X += chunk.xVelocity;
                            chunk.position.Y -= chunk.yVelocity;
                            if (Math.Abs(chunk.position.X + 32f - (float)player.Value.getStandingX()) <= 64f && Math.Abs(chunk.position.Y + 32f - (float)player.Value.getStandingY()) <= 64f)
                            {
                                Item old = item;
                                if (collect(player, chunk))
                                {
                                    if (Game1.debrisSoundInterval <= 0f)
                                    {
                                        Game1.debrisSoundInterval = 10f;
                                        if ((old == null || (int)old.parentSheetIndex != 73) && chunk.debrisType != 73)
                                        {
                                            location.localSound("coin");
                                        }
                                    }
                                    chunks.RemoveAt(i);
                                }
                            }
                        }
                    }
                    else
                    {
                        if ((DebrisType)debrisType == DebrisType.NUMBERS && toHover != null)
                        {
                            relativeXPosition += chunk.xVelocity;
                            chunk.position.X   = toHover.Position.X + 32f + relativeXPosition;
                            chunk.scale        = Math.Min(2f, Math.Max(1f, 0.9f + Math.Abs(chunk.position.Y - (float)chunkFinalYLevel) / 128f));
                            chunkFinalYLevel   = toHover.getStandingY() + 8;
                            if (timeSinceDoneBouncing > 250f)
                            {
                                chunk.alpha = Math.Max(0f, chunk.alpha - 0.033f);
                            }
                            if (!(toHover is Farmer) && !nonSpriteChunkColor.Equals(Color.Yellow) && !nonSpriteChunkColor.Equals(Color.Green))
                            {
                                nonSpriteChunkColor.R = (byte)Math.Max(Math.Min(255, 200 + (int)chunkType), Math.Min(Math.Min(255, 220 + (int)chunkType), 400.0 * Math.Sin((double)timeSinceDoneBouncing / (Math.PI * 256.0) + Math.PI / 12.0)));
                                nonSpriteChunkColor.G = (byte)Math.Max(150 - (int)chunkType, Math.Min(255 - (int)chunkType, (nonSpriteChunkColor.R > 220) ? (300.0 * Math.Sin((double)timeSinceDoneBouncing / (Math.PI * 256.0) + Math.PI / 12.0)) : 0.0));
                                nonSpriteChunkColor.B = (byte)Math.Max(0, Math.Min(255, (nonSpriteChunkColor.G > 200) ? (nonSpriteChunkColor.G - 20) : 0));
                            }
                        }
                        chunk.position.X += chunk.xVelocity;
                        chunk.position.Y -= chunk.yVelocity;
                        if (movingFinalYLevel)
                        {
                            chunkFinalYLevel -= (int)Math.Ceiling((float)chunk.yVelocity / 2f);
                            if (chunkFinalYLevel <= chunkFinalYTarget)
                            {
                                chunkFinalYLevel  = chunkFinalYTarget;
                                movingFinalYLevel = false;
                            }
                        }
                        if ((DebrisType)debrisType == DebrisType.SQUARES && chunk.position.Y < (float)(chunkFinalYLevel - 96) && Game1.random.NextDouble() < 0.1)
                        {
                            chunk.position.Y      = chunkFinalYLevel - Game1.random.Next(1, 21);
                            chunk.yVelocity.Value = (float)Game1.random.Next(30, 80) / 40f;
                            chunk.position.X      = Game1.random.Next((int)(chunk.position.X - chunk.position.X % 64f + 1f), (int)(chunk.position.X - chunk.position.X % 64f + 64f));
                        }
                        if ((DebrisType)debrisType != DebrisType.SQUARES && chunk.bounces <= (floppingFish ? 65 : 2))
                        {
                            chunk.yVelocity.Value -= 0.4f;
                        }
                        bool destroyThisChunk = false;
                        if (chunk.position.Y >= (float)chunkFinalYLevel && (bool)chunk.hasPassedRestingLineOnce && chunk.bounces <= (floppingFish ? 65 : 2))
                        {
                            Point tile_point = new Point((int)chunk.position.X / 64, chunkFinalYLevel / 64);
                            if (Game1.currentLocation is IslandNorth && (debrisType.Value == DebrisType.ARCHAEOLOGY || debrisType.Value == DebrisType.OBJECT || debrisType.Value == DebrisType.RESOURCE || debrisType.Value == DebrisType.CHUNKS) && Game1.currentLocation.isTileOnMap(tile_point.X, tile_point.Y) && Game1.currentLocation.getTileIndexAt(tile_point, "Back") == -1)
                            {
                                chunkFinalYLevel += 48;
                            }
                            if ((DebrisType)debrisType != DebrisType.LETTERS && (DebrisType)debrisType != DebrisType.NUMBERS && (DebrisType)debrisType != DebrisType.SPRITECHUNKS && ((DebrisType)debrisType != 0 || chunk.debrisType - chunk.debrisType % 2 == 8) && shouldControlThis(location))
                            {
                                location.playSound("shiny4");
                            }
                            chunk.bounces++;
                            if ((bool)floppingFish)
                            {
                                chunk.yVelocity.Value = Math.Abs(chunk.yVelocity) * ((movingUp && chunk.bounces < 2) ? 0.6f : 0.9f);
                                chunk.xVelocity.Value = (float)Game1.random.Next(-250, 250) / 100f;
                            }
                            else
                            {
                                chunk.yVelocity.Value  = Math.Abs((float)chunk.yVelocity * 2f / 3f);
                                chunk.rotationVelocity = ((Game1.random.NextDouble() < 0.5) ? (chunk.rotationVelocity / 2f) : ((0f - chunk.rotationVelocity) * 2f / 3f));
                                chunk.xVelocity.Value -= (float)chunk.xVelocity / 2f;
                            }
                            Vector2 chunkTile = new Vector2((int)((chunk.position.X + 32f) / 64f), (int)((chunk.position.Y + 32f) / 64f));
                            if ((DebrisType)debrisType != DebrisType.LETTERS && (DebrisType)debrisType != DebrisType.SPRITECHUNKS && (DebrisType)debrisType != DebrisType.NUMBERS && location.doesTileSinkDebris((int)chunkTile.X, (int)chunkTile.Y, debrisType))
                            {
                                destroyThisChunk = location.sinkDebris(this, chunkTile, chunk.position);
                            }
                        }
                        int tile_x = (int)((chunk.position.X + 32f) / 64f);
                        int tile_y = (int)((chunk.position.Y + 32f) / 64f);
                        if ((!chunk.hitWall && location.Map.GetLayer("Buildings").Tiles[tile_x, tile_y] != null && location.doesTileHaveProperty(tile_x, tile_y, "Passable", "Buildings") == null) || location.Map.GetLayer("Back").Tiles[tile_x, tile_y] == null)
                        {
                            chunk.xVelocity.Value = 0f - (float)chunk.xVelocity;
                            chunk.hitWall         = true;
                        }
                        if (chunk.position.Y < (float)chunkFinalYLevel)
                        {
                            chunk.hasPassedRestingLineOnce.Value = true;
                        }
                        if (chunk.bounces > (floppingFish ? 65 : 2))
                        {
                            chunk.yVelocity.Value  = 0f;
                            chunk.xVelocity.Value  = 0f;
                            chunk.rotationVelocity = 0f;
                        }
                        chunk.rotation += chunk.rotationVelocity;
                        if (destroyThisChunk)
                        {
                            chunks.RemoveAt(i);
                        }
                    }
                }
            }
            if (!anyCouldMove && shouldControlThis(location))
            {
                player.Value = null;
            }
            if (chunks.Count == 0)
            {
                return(true);
            }
            return(false);
        }