-
Notifications
You must be signed in to change notification settings - Fork 2
/
modUtilities.cs
183 lines (157 loc) · 7.93 KB
/
modUtilities.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
using System;
using System.Reflection;
using System.Globalization;
using System.Collections.Generic;
using StardewValley;
using StardewValley.Objects;
using StardewValley.Menus;
using StardewValley.Locations;
using Microsoft.Xna.Framework;
using System.Collections.Specialized;
using System.Runtime.InteropServices;
using StardewModdingAPI;
namespace ExpandedFridgeAGAIN
{
//* Collections of static methods and variables.
class modUtilities
{
public const int MiniFridgeSheetIndex = 216;
private const int OutOfBoundsTileY = -300;
//* Wrapper for getting players current location.
public static GameLocation CurrentLocation { get { return Game1.player.currentLocation; } }
//* Wrapper for checking point inside map bounds.
private static bool IsPointInsideMapBounds(Vector2 point, GameLocation location)
{
return location.isTileOnMap(point);
}
//* Get a free tile for chest placement in a location.
//WARNING: This can return a value outside the map bounds.
private static Vector2 GetFreeTileInLocation(GameLocation location)
{
for (int h = 0; h <= location.map.Layers[0].LayerHeight; h++)
for (int w = 0; w <= location.map.Layers[0].LayerWidth; w++)
//* check if tile in width and height is placeable and not on wall
if (!location.IsTileBlockedBy(new Vector2(w, h)) && (!(location is DecoratableLocation) || !(location as DecoratableLocation).isTileOnWall(w, h)))
return new Vector2(w, h);
int y = 0;
int x = 0;
//* move in y direction untill no other potential offmap objects are there
while (location.isObjectAtTile(x, y))
y++;
ModEntry.DebugLog("WARNING: Object might become placed out of bounds at tile X:" + x + " Y:" + y + " in " + location.NameOrUniqueName, LogLevel.Warn);
//* return that position
return new Vector2(x, y);
}
//* Creates a new inventory menu from a chest with option for showing the color picker.
public static ItemGrabMenu GetNewItemGrabMenuFromChest(Chest chest, bool showColorPicker)
{
var igm = new ItemGrabMenu((IList<Item>)chest.Items, false, true, new
InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems),
new ItemGrabMenu.behaviorOnItemSelect(chest.grabItemFromInventory), (string)null,
new ItemGrabMenu.behaviorOnItemSelect(chest.grabItemFromChest), false, true, true, true, true, 1,
!showColorPicker ? (Item)null : (Item)chest, !showColorPicker ? -1 : 1, (object)chest);
if (igm.chestColorPicker != null)
{
var r = igm.colorPickerToggleButton.bounds;
r.Y -= 128+32;
igm.colorPickerToggleButton.bounds = r;
igm.chestColorPicker.itemToDrawColored = null;
}
if (igm.fillStacksButton != null)
{
igm.fillStacksButton.bounds = new Rectangle(igm.xPositionOnScreen + igm.width, igm.yPositionOnScreen + igm.height / 3 - 64 - 64 - 16, 64, 64);
}
return igm;
}
//* Get an array of mini fridge chests that exists in given location. They are sorted by their tile coordinates with Y as higher priority.
public static Chest[] GetAllMiniFridgesInLocation(GameLocation location)
{
List<Chest> miniFridges = new List<Chest>();
foreach(StardewValley.Object obj in location.Objects.Values){
if (obj != null && obj.bigCraftable.Value && obj is Chest && obj.ParentSheetIndex == MiniFridgeSheetIndex){
Chest chest_tmp = obj as Chest;
miniFridges.Add(chest_tmp);
}
}
return miniFridges.ToArray();
}
//* Moves all mini fridges in all farmhouses out of the map bounds.
public static void HideMiniFridgesInLocation(GameLocation location)
{
List<Vector2> miniFridgePositions = new List<Vector2>();
//* find all mini-fridges positions.
foreach(StardewValley.Object obj in location.objects.Values){
if (obj != null && obj.bigCraftable.Value && obj is Chest && obj.ParentSheetIndex == MiniFridgeSheetIndex){
if (IsPointInsideMapBounds(obj.TileLocation, location)){
miniFridgePositions.Add(obj.TileLocation);
}
}
}
//* Quit here if we dont have any mini-fridges
if (miniFridgePositions.Count == 0){
ModEntry.DebugLog("No mini-fridges found!");
return;
}
//* move them.
ModEntry.DebugLog("Moving mini-fridges out of view..");
foreach (var v in miniFridgePositions)
{
int x = 0;
Vector2 newPosition = new Vector2(x, OutOfBoundsTileY);
while (location.objects.ContainsKey(newPosition))
newPosition.X = ++x;
StardewValley.Object obj = location.objects[v];
obj.TileLocation = newPosition;
location.objects.Remove(v);
location.objects.Add(newPosition, obj);
ModEntry.DebugLog("Moved mini-fridge from X:" + v.X + " Y:" + v.Y + " to X:" + newPosition.X + " Y:" + newPosition.Y);
}
ModEntry.DebugLog(location.NameOrUniqueName + " Finished!");
}
//* Moves all mini fridges in the location back into map bounds.
public static void ShowMiniFridgesInLocation(GameLocation location)
{
//* find all mini-fridges positions.
List<Vector2> miniFridgePositions = new List<Vector2>();
foreach(StardewValley.Object obj in location.objects.Values){
if (obj != null && obj.bigCraftable.Value && obj is Chest && obj.ParentSheetIndex == MiniFridgeSheetIndex){
if (!IsPointInsideMapBounds(obj.TileLocation, location)){
miniFridgePositions.Add(obj.TileLocation);
}
}
}
//* Quit here if we dont have any mini-fridges
if (miniFridgePositions.Count == 0){
ModEntry.DebugLog("No mini-fridges found!");
return;
}
//* Move them
ModEntry.DebugLog("Moving mini-fridges back into view..");
foreach (Vector2 v in miniFridgePositions)
{
Vector2 newPosition = GetFreeTileInLocation(location);
StardewValley.Object obj = location.objects[v];
obj.TileLocation = newPosition;
location.objects.Remove(v);
location.objects.Add(newPosition, obj);
ModEntry.DebugLog("Moved mini-fridge from X:" + v.X + " Y:" + v.Y + " to X:" + newPosition.X + " Y:" + newPosition.Y);
}
ModEntry.DebugLog(location.NameOrUniqueName + " Finished!");
}
public static DateTime GetBuildDate(Assembly assembly){
const string BuildVersionMetadataPrefix = "+build";
var attribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
if (attribute?.InformationalVersion != null){
var value = attribute.InformationalVersion;
var index = value.IndexOf(BuildVersionMetadataPrefix);
if (index > 0){
value = value.Substring(index + BuildVersionMetadataPrefix.Length);
if (DateTime.TryParseExact(value, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result)){
return result;
}
}
}
return default;
}
}
}