public void sendAvailableFarmhands(string userID, Action <OutgoingMessage> sendMessage) { List <NetRef <Farmer> > availableFarmhands = new List <NetRef <Farmer> >(); Game1.getFarm(); foreach (Cabin cabin in cabins()) { NetRef <Farmer> farmhand2 = cabin.getFarmhand(); if ((!farmhand2.Value.isActive() || Game1.multiplayer.isDisconnecting(farmhand2.Value.UniqueMultiplayerID)) && !cabin.isInventoryOpen()) { availableFarmhands.Add(farmhand2); } } using MemoryStream stream = new MemoryStream(); using BinaryWriter writer = new BinaryWriter(stream); writer.Write(Game1.year); writer.Write(Utility.getSeasonNumber(Game1.currentSeason)); writer.Write(Game1.dayOfMonth); writer.Write((byte)availableFarmhands.Count); foreach (NetRef <Farmer> farmhand in availableFarmhands) { try { farmhand.Serializer = SaveGame.farmerSerializer; farmhand.WriteFull(writer); } finally { farmhand.Serializer = null; } } stream.Seek(0L, SeekOrigin.Begin); sendMessage(new OutgoingMessage(9, Game1.player, stream.ToArray())); }
public void drawItem(NetRef <Item> i, float x, float y, SpriteBatch spriteBatch, float layerDepth) { if (i.Value != null) { //this.monitor.Log($"draw [ {i.Get().Name}, {x}, {y} LD: {layerDepth}]"); switch (this.displayType.Value) { case 1: i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x + 2f, (float)(y + 8 - 1))), 0.75f, 0.45f, layerDepth, false, Color.Black, false); i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x + 2f, (float)(y + 4 - 1))), 0.75f, 1f, layerDepth + 1E-05f, false, Color.White, false); break; case 3: i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x, (float)(y + 4 - 1))), 0.75f, 1f, layerDepth, false, Color.White, false); break; case 2: i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x + 6f, (float)(y + 16 - 1))), 0.75f, 0.45f, layerDepth, false, Color.Black, false); i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x + 6f, (float)(y + 12 - 1))), 0.75f, 1f, layerDepth + 1E-05f, false, Color.White, false); break; case 4: i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x - 1f, (float)(y + 8 - 1))), 0.75f, 0.45f, layerDepth, false, Color.Black, false); i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x - 1f, (float)(y + 4 - 1))), 0.75f, 1f, layerDepth + 1E-05f, false, Color.White, false); break; case 5: i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x, (float)(y + 8 - 1))), 0.75f, 0.45f, layerDepth, false, Color.Black, false); i.Value.drawInMenu(spriteBatch, Game1.GlobalToLocal(Game1.viewport, new Vector2(x, (float)(y + 4 - 1))), 0.75f, 1f, layerDepth + 1E-05f, false, Color.White, false); break; } } }
/// <summary> /// Sets up listeners on NetRef values for when a waterable item changes /// </summary> /// <param name="tilledDirt">Tilled dirt plot to listen for changes to</param> /// <param name="indoorPot">Garden pot to listen for changes to</param> private void SetupWaterableLocationListener(HoeDirt tilledDirt, IndoorPot indoorPot = null) { try { NetRef <Crop> netRefCrop = Helper.Reflection.GetField <NetRef <Crop> >(tilledDirt, "netCrop", true).GetValue(); if (netRefCrop.Value != null) { TrackAndWater(tilledDirt, indoorPot); } netRefCrop.fieldChangeVisibleEvent += (_, __, crop) => { if (crop != null) { TrackAndWater(tilledDirt, indoorPot); } else { RemoveTrack(tilledDirt, indoorPot); } }; } catch (Exception ex) { Monitor.Log($"Could not read crop data on dirt; possible new game version?\n{ex}", LogLevel.Error); } }
public void OnDepositedItemChange(NetRef <Object> field, Object old_value, Object new_value) { if (Game1.gameMode != 6 && new_value != null) { shakeTimer = 1000; _isAnimatingChip = true; } }
public ItemFrame(ItemFrameData itemFrameData, Vector2 tile, IMonitor monitor, Item dispItem = null) : base(itemFrameData.id, tile) { this.monitor = monitor; if (dispItem != null) { this.displayItem = new NetRef <Item>(dispItem.getOne()); this.setDisplayType(); } this.setDataFromJson(); }
private void hookField(int index, NetRef <TValue> field) { if (field == default) { return; } field.fieldChangeVisibleEvent += (f, oldValue, newValue) => { this.OnElementChanged(this.Field, index, oldValue, newValue); }; }
internal static NetRef <Farmer> getNewFarmHand() { NetRef <Farmer> farmhand = new NetRef <Farmer>(); farmhand.Value = new Farmer(new FarmerSprite((string)null), new Vector2(0.0f, 0.0f), 1, "", Farmer.initialTools(), true); farmhand.Value.UniqueMultiplayerID = Utility.RandomLong(rnd); farmhand.Value.questLog.Add((Quest)(Quest.getQuestFromId(9) as SocializeQuest)); farmhand.Value.farmName.Value = Game1.MasterPlayer.farmName.Value; farmhand.Value.homeLocation.Value = "FarmHouse"; farmhand.Value.currentLocation = Game1.getLocationFromName("FarmHouse"); farmhand.Value.Position = new Vector2(640f, 320f); return(farmhand); }
/// <summary> /// Checks to see if the Farmer is wearing the Leprechaun boots /// </summary> /// <returns></returns> public static bool IsWearingLeprechaunBoots() { NetRef <Boots> currentBootsRef = Game1.player.boots; // If the Farmer has no boots on, or they aren't the Leprechaun Boots their luck isn't increased if (currentBootsRef == null || currentBootsRef.Value == null || currentBootsRef.Value.indexInTileSheet.Value != 806) { return(false); } else { return(true); } }
private void TemporarilyFakeInteraction(Action action) { // get references // (Note: change net values directly to avoid sync bugs, since the value will be reset when we're done.) Farmer player = Game1.player; NetRef <Horse> mountField = this.Reflection.GetField <NetRef <Horse> >(Game1.player, "netMount").GetValue(); IReflectedField <Horse> mountFieldValue = this.Reflection.GetField <Horse>(mountField, "value"); IReflectedField <Vector2> mountPositionValue = this.Reflection.GetField <Vector2>(player.mount.position.Field, "value"); // save current state Horse mount = mountField.Value; Vector2 mountPosition = mount.Position; WateringCan wateringCan = player.CurrentTool as WateringCan; int waterInCan = wateringCan?.WaterLeft ?? 0; float stamina = player.stamina; Vector2 position = player.Position; int facingDirection = player.FacingDirection; int currentToolIndex = player.CurrentToolIndex; bool canMove = player.canMove; // fix player frozen due to animations when performing an action // move mount out of the way mountFieldValue.SetValue(null); mountPositionValue.SetValue(new Vector2(-5, -5)); // perform action try { action(); } finally { // move mount back mountPositionValue.SetValue(mountPosition); mountFieldValue.SetValue(mount); // restore previous state if (wateringCan != null) { wateringCan.WaterLeft = waterInCan; } player.stamina = stamina; player.Position = position; player.FacingDirection = facingDirection; player.CurrentToolIndex = currentToolIndex; player.canMove = canMove; } }
public ItemFrame(int which, Vector2 tile, IMonitor monitor, Item dispItem = null) : base(which, tile) { this.monitor = monitor; this.monitor.Log($"Creating new itemFrame with id {which}", LogLevel.Trace); if (dispItem != null && dispItem is Item item) { this.monitor.Log($"displayItem set to {dispItem.Name}", LogLevel.Trace); this.displayItem = new NetRef <Item>(item.getOne()); this.setDisplayType(); } else { this.monitor.Log($"displayItem not set.", LogLevel.Trace); } this.setDataFromJson(); }
/// <summary>Temporarily dismount and set up the player to interact with a tile, then return it to the previous state afterwards.</summary> /// <param name="action">The action to perform.</param> private void TemporarilyFakeInteraction(Action action) { // get references SFarmer player = Game1.player; NetRef <Horse> mountField = this.Reflection.GetField <NetRef <Horse> >(Game1.player, "netMount").GetValue(); // change value directly to bypass the game's on-dismount logic // save current state Horse mount = mountField.Value; Vector2 mountPosition = this.Position; WateringCan wateringCan = player.CurrentTool as WateringCan; int waterInCan = wateringCan?.WaterLeft ?? 0; float stamina = player.stamina; Vector2 position = player.Position; int facingDirection = player.FacingDirection; int currentToolIndex = player.CurrentToolIndex; bool canMove = Game1.player.canMove; // fix player frozen due to animations when performing an action // move mount out of the way mountField.Value = null; this.Position = new Vector2(-5, -5); // perform action try { action(); } finally { // move mount back this.Position = mountPosition; mountField.Value = mount; // restore previous state if (wateringCan != null) { wateringCan.WaterLeft = waterInCan; } player.stamina = stamina; player.Position = position; player.FacingDirection = facingDirection; player.CurrentToolIndex = currentToolIndex; Game1.player.canMove = canMove; } }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="field">The field to watch.</param> public NetListWatcher(NetList <TValue, NetRef <TValue> > field) { this.Field = field; #if SMAPI_FOR_MOBILE this.innerArray = (NetRef <NetArray <TValue, NetRef <TValue> > >) this.Field.GetType().GetField("array", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(this.Field); this.hookArray(this.innerArray.Value); this.innerArray.fieldChangeVisibleEvent += (arrayRef, oldArray, newArray) => { if (newArray != null) { this.hookArray(newArray); } this.OnArrayReplaced(this.Field, oldArray, newArray); }; #else field.OnElementChanged += this.OnElementChanged; field.OnArrayReplaced += this.OnArrayReplaced; #endif }
public void sendAvailableFarmhands(string userID, Action <OutgoingMessage> sendMessage) { List <NetRef <Farmer> > list = new List <NetRef <Farmer> >(); Game1.getFarm(); foreach (Cabin cabin in this.cabins()) { NetRef <Farmer> farmhand = cabin.getFarmhand(); if ((!farmhand.Value.isActive() || ModCore.multiplayer.isDisconnecting(farmhand.Value.UniqueMultiplayerID)) && this.authCheck(userID, farmhand.Value)) { list.Add(farmhand); } } using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter((Stream)memoryStream)) { writer.Write(Game1.year); writer.Write(Utility.getSeasonNumber(Game1.currentSeason)); writer.Write(Game1.dayOfMonth); writer.Write((byte)list.Count); foreach (NetRef <Farmer> netRef in list) { try { netRef.Serializer = SaveGame.farmerSerializer; netRef.WriteFull(writer); } finally { netRef.Serializer = (XmlSerializer)null; } } memoryStream.Seek(0L, SeekOrigin.Begin); sendMessage(new OutgoingMessage((byte)9, Game1.player, new object[1] { (object)memoryStream.ToArray() })); } } }
private void UpdateRemoteNetRef(NetRef<object> obj) { valueGetter = obj.Value; bool finalize = false; if (valueGetter is float) { obj.Value = (float)Mathf.Lerp((float)valueGetter, (float)obj.LerpTo, lerpT); if (Math.Abs((float)obj.LerpTo - (float)valueGetter) <= lerpStopOffset) finalize = true; } else if (valueGetter is double) { obj.Value = BeardedMath.Lerp((double)valueGetter, (double)obj.LerpTo, lerpT); if (Math.Abs((double)obj.LerpTo - (double)valueGetter) <= lerpStopOffset) finalize = true; } else if (valueGetter is Vector2) { obj.Value = Vector2.Lerp((Vector2)valueGetter, (Vector2)obj.LerpTo, lerpT); if (Vector2.Distance((Vector2)valueGetter, (Vector2)obj.LerpTo) <= lerpStopOffset) finalize = true; } else if (valueGetter is Vector3) { obj.Value = Vector3.Lerp((Vector3)valueGetter, (Vector3)obj.LerpTo, lerpT); if (Vector3.Distance((Vector3)valueGetter, (Vector3)obj.LerpTo) <= lerpStopOffset) finalize = true; } else if (valueGetter is Vector4) { obj.Value = Vector4.Lerp((Vector4)valueGetter, (Vector4)obj.LerpTo, lerpT); if (Vector4.Distance((Vector4)valueGetter, (Vector4)obj.LerpTo) <= lerpStopOffset) finalize = true; } else if (valueGetter is Quaternion) { obj.Value = Quaternion.Slerp((Quaternion)valueGetter, (Quaternion)obj.LerpTo, lerpT); if (Quaternion.Angle((Quaternion)valueGetter, (Quaternion)obj.LerpTo) <= lerpAngleStopOffset) finalize = true; } else finalize = true; if (finalize) { obj.AssignToLerp(); obj.Callback(this, true); } }
internal static bool sendAvailableFarmhands(string userID, Action <OutgoingMessage> sendMessage) { Multiplayer multiplayer = (Multiplayer)typeof(Game1).GetField("multiplayer", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); List <NetRef <Farmer> > netRefList = new List <NetRef <Farmer> >(); foreach (Cabin cabin in cabins()) { if (cabin.getFarmhand() is NetRef <Farmer> farmhand && ((!farmhand.Value.isActive() || multiplayer.isDisconnecting(farmhand.Value.UniqueMultiplayerID)) && authCheck(userID, farmhand.Value))) { netRefList.Add(farmhand); } } if (netRefList.Count > 0) { return(true); } foreach (NetRef <Farmer> f in farmers) { if ((!f.Value.isActive() || multiplayer.isDisconnecting(f.Value.UniqueMultiplayerID)) && authCheck(userID, f.Value)) { f.Value.currentLocation = Game1.getLocationFromName("FarmHouse"); f.Value.homeLocation.Value = "FarmHouse"; f.Value.Position = new Vector2(640f, 320f); netRefList.Add(f); } } if (netRefList.Count < 1) { NetRef <Farmer> newF = getNewFarmHand(); farmers.Add(newF); netRefList.Add(newF); } using (MemoryStream memoryStream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter((Stream)memoryStream)) { writer.Write(Game1.year); writer.Write(Utility.getSeasonNumber(Game1.currentSeason)); writer.Write(Game1.dayOfMonth); writer.Write((byte)netRefList.Count); foreach (NetRef <Farmer> netRef in netRefList) { try { netRef.Serializer = SaveGame.farmerSerializer; netRef.WriteFull(writer); } catch (Exception e) { mon.Log(e.Message + ":" + e.StackTrace); } finally { netRef.Serializer = (XmlSerializer)null; } } memoryStream.Seek(0L, SeekOrigin.Begin); sendMessage(new OutgoingMessage((byte)9, Game1.player, new object[1] { (object)memoryStream.ToArray() })); } } return(false); }
public string Generate(bool indent) { var i = indent ? " " : ""; var sb = new StringBuilder(); sb.Append($"{i}nuget_package(\n"); if (Variable == null) { sb.Append($"{i} name = \"{PackageIdentity.Id.ToLower()}\",\n"); } else { sb.Append($"{i} name = {Variable},\n"); } sb.Append($"{i} package = \"{PackageIdentity.Id.ToLower()}\",\n"); sb.Append($"{i} version = \"{PackageIdentity.Version}\",\n"); if (!String.IsNullOrEmpty(Sha256)) { sb.Append($"{i} sha256 = \"{Sha256}\",\n"); } if (NugetSourceCustom) { sb.Append($"{i} source = source,\n"); } if (CoreLib != null && CoreLib.Any()) { sb.Append($"{i} core_lib = {{\n"); foreach (var pair in CoreLib) { sb.Append($"{i} \"{pair.Key}\": \"{pair.Value}\",\n"); } sb.Append($"{i} }},\n"); } if (CoreRef != null && CoreRef.Any()) { sb.Append($"{i} core_ref = {{\n"); foreach (var pair in CoreRef) { sb.Append($"{i} \"{pair.Key}\": \"{pair.Value}\",\n"); } sb.Append($"{i} }},\n"); } if (NetLib != null && NetLib.Any()) { sb.Append($"{i} net_lib = {{\n"); foreach (var pair in NetLib) { sb.Append($"{i} \"{pair.Key}\": \"{pair.Value}\",\n"); } sb.Append($"{i} }},\n"); } if (NetRef != null && NetRef.Any()) { sb.Append($"{i} net_ref = {{\n"); foreach (var pair in NetRef) { sb.Append($"{i} \"{pair.Key}\": \"{pair.Value}\",\n"); } sb.Append($"{i} }},\n"); } if (!String.IsNullOrEmpty(MonoLib)) { sb.Append($"{i} mono_lib = \"{MonoLib}\",\n"); } if (!String.IsNullOrEmpty(MonoRef)) { sb.Append($"{i} mono_ref = \"{MonoRef}\",\n"); } if (CoreTool != null && CoreTool.Sum(x => x.Value.Count()) > 0) { sb.Append($"{i} core_tool = {{\n"); foreach (var pair in CoreTool) { sb.Append($"{i} \"{pair.Key}\": \"{pair.Value}\",\n"); } sb.Append($"{i} }},\n"); } if (NetTool != null && NetTool.Sum(x => x.Value.Count()) > 0) { sb.Append($"{i} net_tool = {{\n"); foreach (var pair in NetTool) { sb.Append($"{i} \"{pair.Key}\": \"{pair.Value}\",\n"); } sb.Append($"{i} }},\n"); } if (!String.IsNullOrEmpty(MonoTool)) { sb.Append($"{i} mono_tool = \"{MonoTool}\",\n"); } if (Core_Deps != null && Core_Deps.Sum(x => x.Value.Count()) > 0) { sb.Append($"{i} core_deps = {{\n"); foreach (var pair in Core_Deps) { if (!pair.Value.Any()) { continue; } sb.Append($"{i} \"{pair.Key}\": [\n"); foreach (var s in pair.Value) { sb.Append($"{i} \"{s}\",\n"); } sb.Append($"{i} ],\n"); } sb.Append($"{i} }},\n"); } if (Net_Deps != null && Net_Deps.Sum(x => x.Value.Count()) > 0) { sb.Append($"{i} net_deps = {{\n"); foreach (var pair in Net_Deps) { if (!pair.Value.Any()) { continue; } sb.Append($"{i} \"{pair.Key}\": [\n"); foreach (var s in pair.Value) { sb.Append($"{i} \"{s}\",\n"); } sb.Append($"{i} ],\n"); } sb.Append($"{i} }},\n"); } if (Mono_Deps != null && Mono_Deps.Any()) { sb.Append($"{i} mono_deps = [\n"); foreach (var s in Mono_Deps) { sb.Append($"{i} \"{s}\",\n"); } sb.Append($"{i} ],\n"); } if (Core_Files != null && Core_Files.Sum(x => x.Value.Count()) > 0) { sb.Append($"{i} core_files = {{\n"); foreach (var pair in Core_Files) { if (!pair.Value.Any()) { continue; } sb.Append($"{i} \"{pair.Key}\": [\n"); foreach (var s in pair.Value) { sb.Append($"{i} \"{s}\",\n"); } sb.Append($"{i} ],\n"); } sb.Append($"{i} }},\n"); } if (Net_Files != null && Net_Files.Sum(x => x.Value.Count()) > 0) { sb.Append($"{i} net_files = {{\n"); foreach (var pair in Net_Files) { if (!pair.Value.Any()) { continue; } sb.Append($"{i} \"{pair.Key}\": [\n"); foreach (var s in pair.Value) { sb.Append($"{i} \"{s}\",\n"); } sb.Append($"{i} ],\n"); } sb.Append($"{i} }},\n"); } if (Mono_Files != null && Mono_Files.Any()) { sb.Append($"{i} mono_files = [\n"); foreach (var s in Mono_Files) { sb.Append($"{i} \"{s}\",\n"); } sb.Append($"{i} ],\n"); } sb.Append($"{i})\n"); return(sb.ToString()); }
public static global::StardewValley.AnimalHouse GetIndoors(Building building) { NetRef <GameLocation> indoors = Utilities.Reflection.GetFieldValue <NetRef <GameLocation> >(building, "indoors"); return(indoors.Value as global::StardewValley.AnimalHouse); }
/// <summary>Opens the kitchen menu using any available containers. Imitates <see cref="GameLocation.ActivateKitchen"/> but avoids issues with a null "fridge" parameter.</summary> /// <param name="location">The location of the kitchen.</param> /// <returns>True if the menu successfully opened. False otherwise, e.g. if no storage containers exist or one is currently in use.</returns> private static void ActivateKitchen(GameLocation location) { //get the current location's static fridge if applicable NetRef <Chest> fridge = null; if (location is FarmHouse farmhouse) { fridge = farmhouse.fridge; } else if (location is IslandFarmHouse islandfarmhouse) { fridge = islandfarmhouse.fridge; } //imitate GameLocation.ActivateKitchen except where otherwise noted List <NetMutex> muticies = new List <NetMutex>(); List <Chest> mini_fridges = new List <Chest>(); foreach (StardewValley.Object item in location.objects.Values) { if (item != null && item is Chest chest) { if ((chest.bigCraftable.Value && chest.ParentSheetIndex == 216) || chest.fridge.Value) //if this chest is a Mini-Fridge OR has "fridge" set to true (the original method only checks for Mini-Fridge) { mini_fridges.Add(chest); muticies.Add(chest.mutex); } } } if (fridge != null && fridge.Value.mutex.IsLocked()) { Game1.showRedMessage(Game1.content.LoadString("Strings\\UI:Kitchen_InUse")); return; } MultipleMutexRequest multiple_mutex_request = null; multiple_mutex_request = new MultipleMutexRequest(muticies, delegate { if (fridge != null) //if this location has a fridge, use the original code { fridge.Value.mutex.RequestLock(delegate { List <Chest> list = new List <Chest>(); //skip redundant null check on the fridge list.Add(fridge); list.AddRange(mini_fridges); Vector2 topLeftPositionForCenteringOnScreen = Utility.getTopLeftPositionForCenteringOnScreen(800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2); Game1.activeClickableMenu = new CraftingPage((int)topLeftPositionForCenteringOnScreen.X, (int)topLeftPositionForCenteringOnScreen.Y, 800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, cooking: true, standalone_menu: true, list); Game1.activeClickableMenu.exitFunction = delegate { fridge.Value.mutex.ReleaseLock(); multiple_mutex_request.ReleaseLocks(); }; }, delegate { Game1.showRedMessage(Game1.content.LoadString("Strings\\UI:Kitchen_InUse")); multiple_mutex_request.ReleaseLocks(); }); } else //if this location does NOT have a fridge, only use mini-fridges { //don't RequestLock the fridge mutex List <Chest> list = new List <Chest>(); //don't add the fridge to this list list.AddRange(mini_fridges); Vector2 topLeftPositionForCenteringOnScreen = Utility.getTopLeftPositionForCenteringOnScreen(800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2); Game1.activeClickableMenu = new CraftingPage((int)topLeftPositionForCenteringOnScreen.X, (int)topLeftPositionForCenteringOnScreen.Y, 800 + IClickableMenu.borderWidth * 2, 600 + IClickableMenu.borderWidth * 2, cooking: true, standalone_menu: true, mini_fridges); Game1.activeClickableMenu.exitFunction = delegate { //don't ReleaseLock the fridge mutex multiple_mutex_request.ReleaseLocks(); }; } }, delegate { Game1.showRedMessage(Game1.content.LoadString("Strings\\UI:Kitchen_InUse")); }); }