-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MapHours.cs
319 lines (306 loc) · 16 KB
/
MapHours.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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
// Project: MapHours for Daggerfall Unity (http://www.dfworkshop.net)
// Copyright: Copyright (C) 2024 Arshvir Goraya
// License: MIT License (http://www.opensource.org/licenses/mit-license.php)
// Author: Arshvir Goraya
// Origin Date: September 6 2024
// Source Code: https://github.com/ArshvirGoraya/Map-Hours
using System;
using System.Collections.Generic;
using UnityEngine;
using DaggerfallWorkshop;
using DaggerfallWorkshop.Game;
using DaggerfallWorkshop.Game.Utility.ModSupport;
using DaggerfallWorkshop.Game.UserInterfaceWindows;
using static DaggerfallWorkshop.Game.ExteriorAutomap;
using static DaggerfallWorkshop.DaggerfallLocation;
using DaggerfallWorkshop.Game.Utility.ModSupport.ModSettings;
using static DaggerfallConnect.DFLocation;
using DaggerfallConnect.Utility;
namespace MapHoursMod
{
public class MapHours : MonoBehaviour
{
public BuildingNameplate[] buildingNameplatesRef;
static readonly Dictionary<BuildingSummary, string[]> buildingsList = new Dictionary<BuildingSummary, string[]>();
const string OPEN_TEXT = "(OPEN)";
const string CLOSED_TEXT = "(CLOSED)";
static bool justOpenedMap = false;
static string locationDungeonName = null;
////////////////////////////////////
static ModSettings MapHoursSettings;
private static Mod mod;
[Invoke(StateManager.StateTypes.Start, 0)]
public static void Init(InitParams initParams){
mod = initParams.Mod;
var go = new GameObject(mod.Title);
go.AddComponent<MapHours>();
mod.LoadSettingsCallback = LoadSettings;
mod.LoadSettings();
mod.IsReady = true;
}
static void LoadSettings(ModSettings modSettings, ModSettingsChange change){
MapHoursSettings = modSettings;
ExteriorAutomap.instance.RevealUndiscoveredBuildings = MapHoursSettings.GetBool("ToolTips", "RevealUndiscoveredBuildings");
ResetStorage();
}
void Start(){
DaggerfallUI.UIManager.OnWindowChange += UIManager_OnWindowChangeHandler;
DaggerfallWorkshop.PlayerGPS.OnMapPixelChanged += OnMapPixelChanged;
}
private void UIManager_OnWindowChangeHandler(object sender, EventArgs e){
justOpenedMap = true;
}
static private void OnMapPixelChanged(DFPosition mapPixel){
if (!GameManager.Instance.StateManager.GameInProgress) { return; } // * Required or will generate errors in Player.log
ResetStorage();
}
static private void ResetStorage(){
justOpenedMap = true;
locationDungeonName = null;
if (GameManager.Instance.PlayerGPS.CurrentLocation.HasDungeon){
locationDungeonName = GetSpecialDungeonName(GameManager.Instance.StreamingWorld.CurrentPlayerLocationObject.Summary);
}
buildingsList.Clear();
}
////////////////////////////////////
private void LateUpdate(){
if (!(DaggerfallUI.UIManager.TopWindow is DaggerfallExteriorAutomapWindow)){
return;
}
foreach (var buildingNameplate in ExteriorAutomap.instance.buildingNameplates){
if (IsBuildingSupported(((BuildingSummary)buildingNameplate.textLabel.Tag).BuildingType)){
// * If first building has the same Label as the stored.
if (buildingNameplate.textLabel.ToolTipText.EndsWith(")")){
// * If there is an event that triggers when automap is re-rendered, use that instead instead of checking ")".
return;
}
SetToolTip(buildingNameplate, (BuildingSummary)buildingNameplate.textLabel.Tag);
}
}
justOpenedMap = false;
}
// public StaticDoor[] FindAllDungeonDoors(){ // not optimal but more accurate
// DaggerfallStaticDoors[] doorCollections = GameManager.Instance.StreamingWorld.CurrentPlayerLocationObject.StaticDoorCollections;
// return DaggerfallStaticDoors.FindDoorsInCollections(doorCollections, DoorTypes.DungeonEntrance);
// }
void SetToolTip(BuildingNameplate buildingNameplate, BuildingSummary buildingSummary){
if (buildingsList.TryGetValue(buildingSummary, out _)){
// * Building is stored: Check if need to update the open/close text:
if (justOpenedMap){
buildingsList[buildingSummary][1] = GetBuildingOpenClosedText(buildingNameplate, buildingSummary);
}
}else{
string[] buildingQuality = GetBuildingQualityText(buildingSummary);
// * Building is NOT stored: Create time and open/close text and quality text.
buildingsList.Add(
buildingSummary,
new string[4]{
GetBuildingHours(buildingNameplate, buildingSummary), // * Create Open/Close time for building.
GetBuildingOpenClosedText(buildingNameplate, buildingSummary), // * Get if building is open/closed.
buildingQuality[0],
buildingQuality[1],
}
);
}
// * Set tooltips text.
buildingNameplate.textLabel.ToolTipText += GetStoredToolTipText(buildingSummary);
}
string GetStoredToolTipText(BuildingSummary buildingSummary){
if (
buildingsList[buildingSummary][0].Length == 0 &&
buildingsList[buildingSummary][1].Length == 0 &&
buildingsList[buildingSummary][2].Length == 0 &&
buildingsList[buildingSummary][3].Length == 0
){
return "";
}
string returnText = "";
string hours = buildingsList[buildingSummary][0];
string openClosed = buildingsList[buildingSummary][1];
string qualityText = GetQualityText(buildingSummary);
if (qualityText.Length > 0 && MapHoursSettings.GetBool("ToolTips", "ShowQualityNextToBuildingName")){
returnText += " " + qualityText;
}
if (MapHoursSettings.GetBool("ToolTips", "HoursBeforeOpenClosed")){
if (hours.Length != 0){
returnText += Environment.NewLine + hours;
if (MapHoursSettings.GetBool("ToolTips", "ShowHoursAndOpenClosedInSameLine")){
if (openClosed.Length != 0){ returnText += " " + openClosed; }
}else{
if (openClosed.Length != 0){ returnText += Environment.NewLine + openClosed; }
}
}else{
if (openClosed.Length != 0){ returnText += Environment.NewLine + openClosed; }
}
}else{
if (openClosed.Length != 0){
returnText += Environment.NewLine + openClosed;
if (MapHoursSettings.GetBool("ToolTips", "ShowHoursAndOpenClosedInSameLine")){
if (hours.Length != 0){ returnText += " " + hours; }
}else{
if (hours.Length != 0){ returnText += Environment.NewLine + hours; }
}
}else{
if (hours.Length != 0){ returnText += Environment.NewLine + hours; }
}
}
if (qualityText.Length > 0 && !MapHoursSettings.GetBool("ToolTips", "ShowQualityNextToBuildingName")){
returnText += Environment.NewLine + qualityText;
}
return returnText;
}
string GetQualityText(BuildingSummary buildingSummary){
if (buildingsList[buildingSummary][2].Length == 0 && buildingsList[buildingSummary][3].Length == 0){
return "";
}
string returnText = "";
string qualityNumber = buildingsList[buildingSummary][2];
string qualityText = buildingsList[buildingSummary][3];
if (MapHoursSettings.GetBool("ToolTips", "QualityNumberBeforeQualityText")){
if (qualityNumber.Length != 0){
returnText += qualityNumber;
}
if (qualityText.Length != 0){
if (qualityNumber.Length != 0){
returnText += " ";
}
returnText += qualityText;
}
}else{
if (qualityText.Length != 0){
returnText += qualityText;
}
if (qualityNumber.Length != 0){
if (qualityText.Length != 0){
returnText += " ";
}
returnText += qualityNumber;
}
}
return returnText;
}
////////////////////////////////////
string[] GetBuildingQualityText(BuildingSummary buildingSummary){
string[] qualityText = {"", ""};
// if (!IsBuildingStore(buildingSummary)){
// return qualityText;
// }
if (!IsQualityTextSupported(buildingSummary.BuildingType)){
return qualityText;
}
//
int shopQuality = GetShopQualityNumber(buildingSummary);
if (MapHoursSettings.GetBool(buildingSummary.BuildingType.ToString(), "ShowQualityNumber")){
qualityText[0] = $"({shopQuality})";
}
if (MapHoursSettings.GetBool(buildingSummary.BuildingType.ToString(), "ShowQualityText")){
qualityText[1] = GetShopQualityText(shopQuality);
}
return qualityText;
}
int GetShopQualityNumber(BuildingSummary buildingSummary){
if (buildingSummary.Quality <= 3) return 1;
else if (buildingSummary.Quality <= 7) return 2;
else if (buildingSummary.Quality <= 13) return 3;
else if (buildingSummary.Quality <= 17) return 4;
else return 5;
}
string GetShopQualityText(int quality){
switch (quality){
case 1: return "(Rusty)";
case 2: return "(Sturdy)";
case 3: return "(Practical)";
case 4: return "(Appointed)";
default: return "(Soothing)";
}
}
bool IsQualityTextSupported(BuildingTypes buildingType){
return (
MapHoursSettings.GetBool(buildingType.ToString(), "ShowQualityNumber") ||
MapHoursSettings.GetBool(buildingType.ToString(), "ShowQualityText")
);
}
// bool IsBuildingStore(BuildingSummary buildingSummary){
// return (
// buildingSummary.BuildingType == BuildingTypes.Alchemist ||
// buildingSummary.BuildingType == BuildingTypes.Armorer ||
// buildingSummary.BuildingType == BuildingTypes.Bookseller ||
// buildingSummary.BuildingType == BuildingTypes.GeneralStore ||
// buildingSummary.BuildingType == BuildingTypes.ClothingStore ||
// buildingSummary.BuildingType == BuildingTypes.GemStore ||
// buildingSummary.BuildingType == BuildingTypes.PawnShop ||
// buildingSummary.BuildingType == BuildingTypes.WeaponSmith ||
// buildingSummary.BuildingType == BuildingTypes.FurnitureStore
// );
// }
bool IsBuildingAlwaysAccessible(BuildingNameplate buildingNameplate, BuildingSummary buildingSummary){
// * If opening and closing hours are the same (e.g., Taverns, Temples)
if (PlayerActivate.openHours[(int)buildingSummary.BuildingType] == PlayerActivate.closeHours[(int)buildingSummary.BuildingType] % 25){ // If 25 reset to 0.
return true;
}
// * Depends on Guild rank:
if (GameManager.Instance.GuildManager.GetGuild(buildingSummary.FactionId).HallAccessAnytime()){
return true;
}
// * Is a dungeon (e.g., Castle Daggerfall, Palace Sentinel, etc.)
if (buildingNameplate.textLabel.ToolTipText.Equals(locationDungeonName)){
return true;
}
return false;
}
// * Taken from: DaggerfallDungeon.cs
static public string GetSpecialDungeonName(LocationSummary summary){
string dungeonName;
if (summary.RegionName == "Daggerfall" && summary.LocationName == "Daggerfall")
dungeonName = DaggerfallUnity.Instance.TextProvider.GetText(475);
else if (summary.RegionName == "Wayrest" && summary.LocationName == "Wayrest")
dungeonName = DaggerfallUnity.Instance.TextProvider.GetText(476);
else if (summary.RegionName == "Sentinel" && summary.LocationName == "Sentinel")
dungeonName = DaggerfallUnity.Instance.TextProvider.GetText(477);
else
dungeonName = summary.LocationName;
return dungeonName.TrimEnd('.');
}
string GetBuildingOpenClosedText(BuildingNameplate buildingNameplate, BuildingSummary buildingSummary){
if (!MapHoursSettings.GetBool(buildingSummary.BuildingType.ToString(), "ShowOpenClosed")){ return ""; }
if (MapHoursSettings.GetBool("ToolTips", "DontShowOpenClosedForAlwaysAccessible") &&
IsBuildingAlwaysAccessible(buildingNameplate, buildingSummary)
){ return ""; }
if (MapHoursSettings.GetBool("ToolTips", "OpenIfUnlocked")){
if (IsBuildingLocked(buildingNameplate, buildingSummary)){ return CLOSED_TEXT; }
else { return OPEN_TEXT; }
}else{
if (!PlayerActivate.IsBuildingOpen(buildingSummary.BuildingType)){ return CLOSED_TEXT; }
else { return OPEN_TEXT; }
}
}
string GetBuildingHours(BuildingNameplate buildingNameplate, BuildingSummary buildingSummary){
if (!MapHoursSettings.GetBool(buildingSummary.BuildingType.ToString(), "ShowHours")){ return ""; }
// * House2 should NOT show up here unless you are a member of DB/TG.
bool isDBTG = buildingSummary.BuildingType == BuildingTypes.House2; //&& buildingSummary.FactionId != 0 && GameManager.Instance.GuildManager.GetGuild(buildingSummary.FactionId).IsMember();
if (MapHoursSettings.GetBool("ToolTips", "DontShowHoursForAlwaysAccessible")){
if (isDBTG || IsBuildingAlwaysAccessible(buildingNameplate, buildingSummary)) { return ""; }
}
if (isDBTG){ return $"({ConvertTime(0)} - {ConvertTime(25)})"; } // * DB/TG open 24/7 (cant get through (int)buildingSummary.BuildingType).
return $"({ConvertTime(PlayerActivate.openHours[(int)buildingSummary.BuildingType])} - {ConvertTime(PlayerActivate.closeHours[(int)buildingSummary.BuildingType])})";
}
bool IsBuildingLocked(BuildingNameplate buildingNameplate, BuildingSummary buildingSummary){
if (buildingNameplate.textLabel.ToolTipText.Equals(locationDungeonName)){ return false; }
// * See if open right now: (includes holidays + guild membership + quest)]
return !GameManager.Instance.PlayerActivate.BuildingIsUnlocked(buildingSummary);
}
string ConvertTime(int hour){
if (hour >= 24) {hour = 0;}
if (MapHoursSettings.GetBool("ToolTips", "Use12HourTimeFormatting")){
return new DateTime(1, 1, 1, hour, 0, 0).ToString("hh:mm tt");
}else{
return new DateTime(1, 1, 1, hour, 0, 0).ToString("HH:mm");
}
}
bool IsBuildingSupported(BuildingTypes buildingType){
if (MapHoursSettings.GetBool(buildingType.ToString(), "ShowHours") || MapHoursSettings.GetBool(buildingType.ToString(), "ShowOpenClosed")){ return true; }
if (IsQualityTextSupported(buildingType)){ return true; }
return false;
}
}
}