private void UpdateTicking_LoadContentPacks(object sender, UpdateTickingEventArgs e) { // Remove this event handler so it only fires once this.Helper.Events.GameLoop.UpdateTicking -= this.UpdateTicking_LoadContentPacks; // Load content packs ContentPackLoader contentPackLoader = new ContentPackLoader(this._coreApiFactory.GetApi(this)); contentPackLoader.LoadContentPacks(); }
private static void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { // Relax max casting power timing tolerance if (!Config.DisableFishingAdjust && Game1.player.CurrentTool is FishingRod rod && rod.isTimingCast && LeftButtonReleased(Reflection.GetField <bool>(rod, "usedGamePadToCast").GetValue()) && (1.01f - rod.castingPower < Config.RelaxCasting / 100.0)) { rod.castingPower = 1.01f; // maximum casting power } }
private static void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { foreach (QueuedAction QA in QueuedActions.OrderByDescending(x => x.Priority)) { if (QA.GameLoop_UpdateTicking()) { QueuedActions.Remove(QA); } } }
/// <summary>Raised before the game state is updated (≈60 times per second).</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event arguments.</param> private void onUpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Context.IsPlayerFree) { return; } // track toolbar info before the game handles any user input this.previousHeldChest = Game1.player.CurrentItem as Chest; }
private static void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { if (Context.IsWorldReady) { PreviousInventoryCursorSlotItem = Game1.player.CursorSlotItem; // Geode menu if (Game1.activeClickableMenu is GeodeMenu GM) { PreviousGeodeMenuCursorSlotItem = GM.heldItem; } else { PreviousGeodeMenuCursorSlotItem = null; } // Fishing Treasure menu if (IsFishingTreasureChestMenu(Game1.activeClickableMenu, out Item FishingChestHeldItem)) { PreviousFishingChestCursorSlotItem = FishingChestHeldItem; } else { PreviousFishingChestCursorSlotItem = null; } try { // Chest menu if (ItemBagsMod.UserConfig.AllowAutofillInsideChest && IsChestMenu(Game1.activeClickableMenu, out Item ChestHeldItem)) { ItemGrabMenu IGM = Game1.activeClickableMenu as ItemGrabMenu; Chest Chest = IGM.context as Chest; // Compare previous chest items to current chest items to see if any items were just added to chest List <Item> CurrentChestMenuContents = Chest.items.Where(x => x != null).ToList(); if (PreviousChestMenuContents != null) { List <Item> AddedItems = CurrentChestMenuContents.Where(x => !PreviousChestMenuContents.Contains(x)).ToList(); if (AddedItems.Any()) { OnItemsAddedToChest(IGM, Chest, AddedItems); } } PreviousChestMenuContents = CurrentChestMenuContents; } } catch (Exception ex) { PreviousChestMenuContents = null; ItemBagsMod.ModInstance.Monitor.Log(string.Format("Error while attempting to autofill bags inside of the active chest: {0}\n\n{1}", ex.Message, ex.ToString()), LogLevel.Error); } } }
private void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Context.IsWorldReady) { return; } if (Game1.isDarkOut() && Game1.currentSong.Name.Contains(Game1.currentSeason) && !Game1.currentSong.Name.Contains("ambient")) { if (Game1.getMusicTrackName(Game1.MusicContext.Default).StartsWith(Game1.currentSeason) && !Game1.getMusicTrackName(Game1.MusicContext.Default).Contains("ambient") && (!Game1.eventUp && Game1.isDarkOut())) { Game1.changeMusicTrack("none", true, Game1.MusicContext.Default); } if (Game1.currentLocation.IsOutdoors && !Game1.isRaining && (!Game1.eventUp && Game1.getMusicTrackName(Game1.MusicContext.Default).Contains("day")) && Game1.isDarkOut()) { Game1.changeMusicTrack("none", true, Game1.MusicContext.Default); } Game1.currentLocation.checkForMusic(Game1.currentGameTime); } if (Game1.timeOfDay > GetSunriseTime() && !firstDaybreakTick && daybreakTickCount > 0) { daybreakTickCount--; } if (Game1.timeOfDay > GetSunriseTime() && !firstDaybreakTick && daybreakTickCount == 0) { if (Game1.currentSong.Name.Contains(Game1.currentSeason) && !Game1.currentSong.Name.Contains("ambient") && Game1.currentSong.IsStopped) { Game1.currentSong.Resume(); } else { //check base flags if (!Game1.isRaining || !Game1.isLightning || !Game1.eventUp) { //check locations if ((Game1.currentLocation.IsOutdoors && !(Game1.currentLocation is Desert) || Game1.currentLocation is FarmHouse || Game1.currentLocation is AnimalHouse || Game1.currentLocation is Shed)) { //check game config if (Game1.options.musicVolumeLevel > 0.025 && Game1.timeOfDay < 1200) { //check song restrictions if (Game1.currentSong.Name.Contains("ambient")) { Game1.changeMusicTrack(Game1.currentSeason + Math.Max(1, Game1.currentSongIndex), true, Game1.MusicContext.Default); } } } } } firstDaybreakTick = true; } }
private void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Context.IsMainPlayer) { return; } if (e.IsMultipleOf(this.Config.UpdateInterval)) { configureAllMachines(); } }
private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { //if( isTimeFrozen ) //{ // Game1.gameTimeInterval = 0; // //Game1.UpdateGameClock( Game1.currentGameTime ); // // NOTE: Can use this function to skip time super fast! // //Game1.performTenMinuteClockUpdate(); //} }
/// <summary> /// On each update, if the world is loaded, we should run our logic /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Context.IsWorldReady || Game1.currentLocation == null) { return; } foreach (KeyValuePair <Guid, HorseStatus> kvp in horses) { kvp.Value.OnUpdateTicking(sender, e); } }
private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Context.IsWorldReady) { return; } if (_castingCooldown > 0) { RefreshUI(); } }
/// <summary>Raised before the game state is updated (≈60 times per second).</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event arguments.</param> private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { if (Game1.player.usingSlingshot && Game1.player.CurrentTool is Slingshot slingshot && this.isActionButtonDown && this.nameToConfigName.TryGetValue(slingshot.BaseName, out string configName) && this.Config.AutomaticSlingshots.Contains(configName) && this.configNameToFireRate.TryGetValue(configName, out int rate) && e.IsMultipleOf((uint)(this.Config.RapidFire ? rate / 2 : rate)) && slingshot.attachments[0] != null) { this.IsAutoFire = true; SlingshotFinishPatch.ShouldRun(slingshot, false); slingshot.DoFunction(Game1.currentLocation, Game1.getMouseX(), Game1.getMouseY(), 1, slingshot.getLastFarmerToUse()); SlingshotFinishPatch.ShouldRun(slingshot, true); this.IsAutoFire = false; } }
private static void UpdateTicking_ManageEffects(object sender, UpdateTickingEventArgs e) { GameLocation location = Game1.player.currentLocation; //get the local player's current location string locationName = Game1.player.currentLocation?.NameOrUniqueName; //get the current location's name (note: faster than repeatedly checking the net-synched values) foreach (CauldronEffect effect in CauldronEffects) //for each existing effect { if (!Context.IsWorldReady || !Game1.game1.IsActive) //if the game is currently paused or inactive { effect.PreviousTick++; //increment this effect's previous tick (effectively skipping this tick) } else if (effect.PreviousTick + effect.TickRate <= e.Ticks) //if this effect should spawn during this tick { effect.PreviousTick = e.Ticks; //set this tick as the effect's "previous" tick if (effect.LocationName == locationName) //if this effect is for the player's current location { float randomSpin = Game1.random.Next(-5, 6); //get a random left/right spin value (shared by motion.X and rotationChange) location.temporarySprites.Add //create a sprite for this effect ( new TemporaryAnimatedSprite ( "LooseSprites\\Cursors", //tilesheet new Rectangle(372, 1956, 10, 10), //x, y, width, height on tilesheet effect.Position + new Vector2(Game1.random.Next(-32, 33), Game1.random.Next(-16, 17)), //in-game position false, //true to flip sprite horizontally 0.002f, //transparency added each tick effect.TintColor //sprite tint color (Color.White = no tint) ) { alpha = 0.75f, //starting transparency (0 = invisible, 1 = opaque) motion = new Vector2(0f, -0.5f), //X, Y pixel movement each tick acceleration = new Vector2(0f, 0f), //X, Y added to "motion" each tick interval = 99999f, //animation framerate? (currently not applicable to this class) layerDepth = 0.144f - (float)Game1.random.Next(100) / 10000f, //draw layer, a.k.a. Z-level scale = 3f, //sprite size multiplier (1 = original size) scaleChange = 0.01f, //value added to "scale" each tick rotationChange = (float)Game1.random.Next(-5, 6) * (float)Math.PI / 256f, //value added to "rotation" per tick (in radians?) drawAboveAlwaysFront = true //true to draw this effect in front of anything else (if possible) } ); } } } }
private static void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { try { // Swaps the current CursorSlotItem with the inventory item at index=QueueCursorSlotIndex if (QueuePlaceCursorSlotItem && QueueCursorSlotIndex.HasValue) { if (Game1.activeClickableMenu is GameMenu GM && GM.currentTab == GameMenu.inventoryTab) { Item Temp = Game1.player.Items[QueueCursorSlotIndex.Value]; Game1.player.Items[QueueCursorSlotIndex.Value] = Game1.player.CursorSlotItem; Game1.player.CursorSlotItem = Temp; } } } finally { QueuePlaceCursorSlotItem = false; QueueCursorSlotIndex = null; } }
/// <summary> /// Apply fertilizer to crops that have started growing but aren't /// yet harvestable if the user is clicking /// </summary> /// <param name="sender">The event sender</param> /// <param name="e">The event arguments</param> private void UpdateTicking(object sender, UpdateTickingEventArgs e) { if (Game1.hasLoadedGame && Clicking) { GameLocation location = Game1.currentLocation; Farmer player = Game1.player; ICursorPosition cursor = Helper.Input.GetCursorPosition(); Vector2 tileToFertilize = cursor.GrabTile; if (location.isCropAtTile((int)tileToFertilize.X, (int)tileToFertilize.Y) && IsValidTileAndItem(location, tileToFertilize, player.CurrentItem, out HoeDirt dirt)) { location.playSound("dirtyHit"); dirt.fertilizer.Value = player.CurrentItem.ParentSheetIndex; player.removeItemsFromInventory(player.CurrentItem.ParentSheetIndex, 1); } } }
//Attempt to smooth out button animations private void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Context.IsWorldReady) { return; } var menu = GetValidButtonSmashMenu(); if (menu == null || !config.EnableUISmashButtons) { return; } var scaledMousePos = Game1.getMousePosition(true); buttonSmashHandler.TryHover(scaledMousePos.X, scaledMousePos.Y); }
private void UpdateTicking(object sender, UpdateTickingEventArgs e) { // ignore if player hasn't loaded a save yet if (!Context.IsWorldReady) { return; } if (Game1.player.CurrentTool is FishingRod rod) { if (Game1.activeClickableMenu is BobberBar bobberBar) { float bobberBarHeight = Helper.Reflection.GetField <int>(bobberBar, "bobberBarHeight", true).GetValue(); Helper.Reflection.GetField <int>(bobberBar, "bobberBarHeight", true).SetValue(2000); } } }
private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Config.EnableMod || !Context.IsWorldReady) { return; } int delta = Helper.Input.IsDown(Config.UpButton) ? 1 : (Helper.Input.IsDown(Config.DownButton) ? -1 : 0); if (delta != 0 && typeof(DecoratableLocation).IsAssignableFrom(Game1.currentLocation.GetType()) && Game1.currentLocation.objects.TryGetValue(Game1.currentCursorTile, out Object obj) && obj is IndoorPot && (Game1.currentLocation as DecoratableLocation).isTileOnWall((int)obj.TileLocation.X, (int)obj.TileLocation.Y)) { int offset = Config.OffsetY; string key = Helper.Input.IsDown(Config.ModKey) ? "aedenthorn.WallPlanter/innerOffset" : "aedenthorn.WallPlanter/offset"; if (obj.modData.TryGetValue(key, out string offsetString)) { int.TryParse(offsetString, out offset); } obj.modData[key] = (offset + delta) + ""; } }
/********* ** Private methods *********/ /**** ** Event handlers ****/ /// <summary>The method called before a tick update.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event arguments.</param> private void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { GameLocation location = Game1.currentLocation; Farmer player = Game1.player; // mark tiles under hoe diggable if (Context.IsWorldReady && player.UsingTool && player.CurrentTool is Hoe hoe) { Vector2 tilePos = player.GetToolLocation() / Game1.tileSize; IList <Vector2> tilesAffected = this.Helper.Reflection.GetMethod(hoe, "tilesAffected").Invoke <List <Vector2> >(tilePos, player.toolPower, player); foreach (Vector2 tile in tilesAffected) { if (this.ShouldMakeTillable(location, tile)) { location.setTileProperty((int)tile.X, (int)tile.Y, "Back", "Diggable", "T"); } } } }
private void OnUpdateTicking(object?sender, UpdateTickingEventArgs e) { if (Game1.player is null) { return; } foreach (var manager in this.fishingApi.fishingEffectManagers) { var info = new FishingInfo(Game1.player); switch (manager.UpdateEnabled(info)) { case true: manager.Effect.Apply(info); break; case false: manager.Effect.Unapply(info); break; } } }
private static void UpdateTicking_ManageEffects(object sender, UpdateTickingEventArgs e) { foreach (CauldronEffect effect in CauldronEffects.Value) //for each of the current player's existing effects { if (!Context.IsWorldReady || !Game1.game1.IsActive) //if the game is currently paused or inactive { effect.NextTick++; //increment this effect's previous tick (effectively skipping this tick) } else if (effect.NextTick <= e.Ticks) //if this effect should spawn during this tick { effect.NextTick = e.Ticks + (uint)Game1.random.Next(effect.MinTickRate, effect.MaxTickRate + 1); //randomly assign this effect's next spawn tick Game1.player.currentLocation?.temporarySprites.Add //create a sprite for this effect at the player's current location ( new TemporaryAnimatedSprite ( effect.TextureName, effect.SourceRect, effect.Position + new Vector2(Game1.random.Next(-32, 33), Game1.random.Next(-16, 17)), //randomize the new sprite's position in a limited range effect.Flipped, effect.AlphaFade, effect.TintColor ) { alpha = effect.Alpha, motion = effect.Motion, acceleration = effect.Acceleration, interval = 99999f, //animation framerate? (currently not applicable to this class) layerDepth = 0.144f - (float)Game1.random.Next(100) / 10000f, //draw layer depth, a.k.a. Z-level (should only affect other effects, not map layers/etc) scale = effect.Scale, scaleChange = effect.ScaleChange, rotation = Game1.random.Next(effect.MinRotation, effect.MaxRotation + 1) * (float)Math.PI / 256f, //randomize starting rotation speed (applying pi/256 to imitate SDV speeds) rotationChange = Game1.random.Next(effect.MinRotationChange, effect.MaxRotationChange + 1) * (float)Math.PI / 256f, //randomize rotation acceleration (applying pi/256 to imitate SDV speeds) drawAboveAlwaysFront = effect.DrawAboveAlwaysFront } ); } } }
/// <summary> /// When move buildings is exited, on default it returns the player to Robin's house /// and the menu becomes the menu to choose buildings /// This detects when that happens and returns the player to their original location and closs the menu /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { //if we're not currently moving buildings from our mod, ignore if (!isArranging) { return; } if (Game1.locationRequest?.Name == "ScienceHouse") { //change location to source location Game1.locationRequest.Location = loc; //no longer arranging so set our trackers to defaults isArranging = false; loc = null; //close the menu so players aren't gonna be asked to keep buying buildings Game1.exitActiveMenu(); } }
private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) //adds item to inv { if (!Context.IsWorldReady || !Game1.player.IsLocalPlayer) { return; } if (minigame.Value == null) { minigame.Value = new Minigames(this); } try { minigame.Value.GameLoop_UpdateTicking(sender, e); } catch (Exception ex) { Monitor.Log("Handled Exception in UpdateTicking. Festival: " + Game1.isFestival() + ", Message: " + ex.Message + " in: " + exception.Match(ex.StackTrace).Value, LogLevel.Trace); minigame.Value.EmergencyCancel(); } }
private static void UpdateTicking(object sender, UpdateTickingEventArgs e) { CurrentPlayerTile = Game1.player.getTileLocation(); //update cached tile position of the current local player }
internal void OnUpdateTicking(object sender, UpdateTickingEventArgs args) { OverwriteRogueRandomIfNeeded(); }
/// <summary>Raised before the game state is updated (≈60 times per second).</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event arguments.</param> private void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { this.ChangeOverlayIfNeeded(); }
/// <summary> /// Updates the local Farmer's stored money value before the game state is updated (~60 times per second) /// </summary> /// <param name="sender">The sender of the UpdateTicking event</param> /// <param name="args">Event arguments for the UpdateTicking event</param> public void OnUpdateTicking(object sender, UpdateTickingEventArgs args) { PersistantFarmerData.PocketMoney = Game1.player.Money; }
private static void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { PreviousHeldItem = Game1.player.CurrentItem; }
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); } }
/********* ** Private methods *********/ /// <summary>Raised before the game state is updated</summary> private void OnUpdateTicking(object sender, UpdateTickingEventArgs e) { if (Game1.getFarm() is null) { return; } // Create a smoke sprite if (smokeAnimationData.Enabled && e.IsMultipleOf(smokeAnimationData.SpawnFrequency * 60 / 1000)) { GameLocation location = Game1.player.currentLocation; if (location != null && location.IsFarm && location.IsOutdoors) { for (int i = 0; i < furnaces.Count; i++) { if (!furnaces[i].CurrentlyOn) { continue; } int x = furnaces[i].furnace.tileX.Value; int y = furnaces[i].furnace.tileY.Value; TemporaryAnimatedSprite sprite; // See if we should do a custom sprite, or use the default if (customSmokeSpriteExists) { sprite = new TemporaryAnimatedSprite(smokeAnimationSpritePath, new Rectangle(0, 0, smokeAnimationData.SpriteSizeX, smokeAnimationData.SpriteSizeY), new Vector2(x * 64 + smokeAnimationData.SpawnXOffset, y * 64 + smokeAnimationData.SpawnYOffset), false, 1f / 500f, Color.Gray) { alpha = 0.75f, motion = new Vector2(0.0f, -0.5f), acceleration = new Vector2(1f / 500f, 0.0f), interval = 99999f, layerDepth = 1f, scale = smokeAnimationData.SmokeScale, scaleChange = smokeAnimationData.SmokeScaleChange, rotationChange = (float)(Game1.random.Next(-5, 6) * 3.14159274101257 / 256.0) }; } else { sprite = new TemporaryAnimatedSprite(Path.Combine("LooseSprites", "Cursors"), new Rectangle(372, 1956, 10, 10), new Vector2(x * 64 + smokeAnimationData.SpawnXOffset, y * 64 + smokeAnimationData.SpawnYOffset), false, 1f / 500f, Color.Gray) { alpha = 0.75f, motion = new Vector2(0.0f, -0.5f), acceleration = new Vector2(1f / 500f, 0.0f), interval = 99999f, layerDepth = 1f, scale = smokeAnimationData.SmokeScale, scaleChange = smokeAnimationData.SmokeScaleChange, rotationChange = (float)(Game1.random.Next(-5, 6) * 3.14159274101257 / 256.0) }; } // Add smoke sprite location.temporarySprites.Add(sprite); } } } // Create a fire sprite if (fireAnimationData.Enabled && e.IsMultipleOf(fireAnimationData.SpawnFrequency * 60 / 1000)) { GameLocation location = Game1.player.currentLocation; if (location != null && location.IsFarm && location.IsOutdoors) { for (int i = 0; i < furnaces.Count; i++) { if (!furnaces[i].CurrentlyOn) { continue; } int x = furnaces[i].furnace.tileX.Value; int y = furnaces[i].furnace.tileY.Value; TemporaryAnimatedSprite sprite; if (customFireSpriteExists) { // Spark only randomly if (Game1.random.NextDouble() >= fireAnimationData.SpawnChance) { continue; } double randomX = 2 * Game1.random.NextDouble() * fireAnimationData.SpawnXRandomOffset - fireAnimationData.SpawnXRandomOffset; double randomY = 2 * Game1.random.NextDouble() * fireAnimationData.SpawnYRandomOffset - fireAnimationData.SpawnYRandomOffset; Vector2 pos = new Vector2(x * 64f + fireAnimationData.SpawnXOffset + (float)randomX, y * 64f + fireAnimationData.SpawnYOffset + (float)randomY); sprite = new TemporaryAnimatedSprite(fireAnimationSpritePath, new Rectangle(0, 0, fireAnimationData.SpriteSizeX, fireAnimationData.SpriteSizeY), fireAnimationData.AnimationSpeed, fireAnimationData.AnimationLength, 10, pos, false, false, (float)((y + 1.0) * 64.0 / 10000.0 + 9.99999974737875E-05 + (x + 1.0) * 64.0 / 10000.0), 0.005f, Color.White, 1f, 0f, 0f, 0f) { light = true, lightcolor = Color.Black }; // Puff only randomlierly if (Game1.random.NextDouble() < fireAnimationData.SoundEffectChance) { Game1.playSound("fireball"); } } else { // Spark only randomly if (Game1.random.NextDouble() >= 0.2) { continue; } double randomX = 2 * Game1.random.NextDouble() * fireAnimationData.SpawnXRandomOffset - fireAnimationData.SpawnXRandomOffset; double randomY = 2 * Game1.random.NextDouble() * fireAnimationData.SpawnYRandomOffset - fireAnimationData.SpawnYRandomOffset; Vector2 pos = new Vector2(x * 64f + fireAnimationData.SpawnXOffset + (float)randomX, y * 64f + fireAnimationData.SpawnYOffset + (float)randomY); sprite = new TemporaryAnimatedSprite(30, pos, Color.White, fireAnimationData.AnimationLength, false, fireAnimationData.AnimationSpeed, 10, 64, (float)((y + 1.0) * 64.0 / 10000.0 + 9.99999974737875E-05 + (x + 1.0) * 64.0 / 10000.0), -1, 0) { alphaFade = 0.005f, light = true, lightcolor = Color.Black }; // Puff only randomlierly if (Game1.random.NextDouble() < fireAnimationData.SoundEffectChance) { Game1.playSound("fireball"); } } location.temporarySprites.Add(sprite); } } } }
private void GameLoop_UpdateTicking(object sender, UpdateTickingEventArgs e) { if (!Config.EnableMod || !Context.IsWorldReady) { return; } foreach (var kvp in objectTriggerDataDict) { switch (kvp.Value.tripperType) { case "farmer": foreach (var farmer in Game1.getAllFarmers()) { CheckTrigger(farmer, farmer.currentLocation, farmer.getTileLocation(), kvp.Key); } break; } } foreach (var key in farmerTrippingDict.Keys.ToArray()) { for (int j = farmerTrippingDict[key].Count - 1; j >= 0; j--) { Farmer farmer = Game1.getFarmer(key); if (farmer != null && !CheckObjectTrigger(farmer.currentLocation, farmer.getTileLocation(), farmerTrippingDict[farmer.UniqueMultiplayerID][j].triggerKey, farmerTrippingDict[farmer.UniqueMultiplayerID][j].tilePosition)) { ResetTrigger(farmer, farmerTrippingDict[farmer.UniqueMultiplayerID][j].tilePosition, farmerTrippingDict[farmer.UniqueMultiplayerID][j].triggerKey); } } } var keyArray = farmerTrippingDict.Keys.ToArray(); for (int i = 0; i < keyArray.Length; i++) { var key = keyArray[i]; Farmer farmer = Game1.getFarmer(key); if (farmer == null) { continue; } for (int j = 0; j < farmerTrippingDict[key].Count; j++) { var oti = farmerTrippingDict[key][j]; var otd = objectTriggerDataDict[oti.triggerKey]; if (otd.interval <= 0) { continue; } oti.elapsed++; if (oti.elapsed > otd.interval) { oti.elapsed = 0; if (Game1.random.NextDouble() > otd.tripChance) { continue; } farmerTrippingDict[key][j].elapsed = 0; float amount = objectTriggerDataDict[oti.triggerKey].effectAmountMin + (float)Game1.random.NextDouble() * (objectTriggerDataDict[oti.triggerKey].effectAmountMax - objectTriggerDataDict[oti.triggerKey].effectAmountMin); switch (otd.triggerEffectType) { case "damage": farmer.takeDamage((int)amount, true, null); if (otd.tripSound != null) { farmer.currentLocation.playSound(otd.tripSound); } break; case "sound": if (otd.tripSound != null) { farmer.currentLocation.playSound(otd.tripSound); } break; case "heal": amount = Math.Min(farmer.maxHealth - farmer.health, amount); if (amount > 0) { if (otd.tripSound != null) { farmer.currentLocation.playSound(otd.tripSound); } farmer.health += (int)amount; farmer.currentLocation.debris.Add(new Debris((int)amount, new Vector2((farmer.getStandingX() + 8), farmer.getStandingY()), Color.Green, 1f, farmer)); } break; case "energize": amount = Math.Min(farmer.MaxStamina - farmer.Stamina, amount); if (amount > 0) { if (otd.tripSound != null) { farmer.currentLocation.playSound(otd.tripSound); } farmer.Stamina += amount; farmer.currentLocation.debris.Add(new Debris((int)amount, new Vector2((farmer.getStandingX() + 8), farmer.getStandingY()), Color.Yellow, 1f, farmer)); } break; case "exhaust": amount = Math.Min(farmer.Stamina, amount); if (amount > 0) { if (otd.tripSound != null) { farmer.currentLocation.playSound(otd.tripSound); } farmer.Stamina += amount; farmer.currentLocation.debris.Add(new Debris((int)amount, new Vector2((farmer.getStandingX() + 8), farmer.getStandingY()), Color.Yellow, 1f, farmer)); } break; } } } } }