about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--AnodyneArchipelago/ArchipelagoManager.cs65
-rw-r--r--AnodyneArchipelago/ArchipelagoTreasure.cs2
-rw-r--r--AnodyneArchipelago/Menu/ConnectionState.cs118
-rw-r--r--AnodyneArchipelago/Menu/MenuState.cs38
-rw-r--r--AnodyneArchipelago/Patches/GameplayPatches.cs10
-rw-r--r--AnodyneArchipelago/Patches/StatePatches.cs22
-rw-r--r--AnodyneArchipelago/Plugin.cs1
7 files changed, 214 insertions, 42 deletions
diff --git a/AnodyneArchipelago/ArchipelagoManager.cs b/AnodyneArchipelago/ArchipelagoManager.cs index 0b7c478..7c67114 100644 --- a/AnodyneArchipelago/ArchipelagoManager.cs +++ b/AnodyneArchipelago/ArchipelagoManager.cs
@@ -11,53 +11,48 @@ using Archipelago.MultiClient.Net.Packets;
11using System; 11using System;
12using System.Collections.Generic; 12using System.Collections.Generic;
13using System.Linq; 13using System.Linq;
14using System.Threading.Tasks;
14 15
15namespace AnodyneArchipelago 16namespace AnodyneArchipelago
16{ 17{
17 internal class ArchipelagoManager 18 public class ArchipelagoManager
18 { 19 {
19 private static ArchipelagoSession _session; 20 private ArchipelagoSession _session;
20 private static int _itemIndex = 0; 21 private int _itemIndex = 0;
22 private string _seedName;
21 23
22 private static readonly Queue<NetworkItem> _itemsToCollect = new(); 24 private readonly Queue<NetworkItem> _itemsToCollect = new();
23 25
24 public static void Connect(string url, string slotName, string password) 26 public async Task<LoginResult> Connect(string url, string slotName, string password)
25 { 27 {
26 LoginResult result; 28 LoginResult result;
27 try 29 try
28 { 30 {
29 _session = ArchipelagoSessionFactory.CreateSession(url); 31 _session = ArchipelagoSessionFactory.CreateSession(url);
30 _session.MessageLog.OnMessageReceived += OnMessageReceived; 32 _session.MessageLog.OnMessageReceived += OnMessageReceived;
31 result = _session.TryConnectAndLogin("Anodyne", slotName, ItemsHandlingFlags.AllItems, null, null, null, password == "" ? null : password); 33
34 RoomInfoPacket roomInfoPacket = await _session.ConnectAsync();
35 _seedName = roomInfoPacket.SeedName;
36
37 result = await _session.LoginAsync("Anodyne", slotName, ItemsHandlingFlags.AllItems, null, null, null, password == "" ? null : password);
32 } 38 }
33 catch (Exception e) 39 catch (Exception e)
34 { 40 {
35 result = new LoginFailure(e.GetBaseException().Message); 41 result = new LoginFailure(e.GetBaseException().Message);
36 } 42 }
37 43
38 if (!result.Successful)
39 {
40 LoginFailure failure = result as LoginFailure;
41 string errorMessage = $"Failed to connect to {url} as {slotName}:";
42 foreach (string error in failure.Errors)
43 {
44 errorMessage += $"\n {error}";
45 }
46 foreach (ConnectionRefusedError error in failure.ErrorCodes)
47 {
48 errorMessage += $"\n {error}";
49 }
50
51 Plugin.Instance.Log.LogError(errorMessage);
52
53 return;
54 }
55
56 _itemIndex = 0; 44 _itemIndex = 0;
57 _itemsToCollect.Clear(); 45 _itemsToCollect.Clear();
46
47 return result;
48 }
49
50 ~ArchipelagoManager()
51 {
52 Disconnect();
58 } 53 }
59 54
60 public static void Disconnect() 55 public void Disconnect()
61 { 56 {
62 if (_session == null) 57 if (_session == null)
63 { 58 {
@@ -68,7 +63,17 @@ namespace AnodyneArchipelago
68 _session = null; 63 _session = null;
69 } 64 }
70 65
71 public static void SendLocation(string location) 66 public string GetSeed()
67 {
68 return _seedName;
69 }
70
71 public int GetPlayer()
72 {
73 return _session.ConnectionInfo.Slot;
74 }
75
76 public void SendLocation(string location)
72 { 77 {
73 if (_session == null) 78 if (_session == null)
74 { 79 {
@@ -79,7 +84,7 @@ namespace AnodyneArchipelago
79 _session.Locations.CompleteLocationChecks(_session.Locations.GetLocationIdFromName("Anodyne", location)); 84 _session.Locations.CompleteLocationChecks(_session.Locations.GetLocationIdFromName("Anodyne", location));
80 } 85 }
81 86
82 public static void Update() 87 public void Update()
83 { 88 {
84 if (_session == null) 89 if (_session == null)
85 { 90 {
@@ -104,7 +109,7 @@ namespace AnodyneArchipelago
104 } 109 }
105 } 110 }
106 111
107 if (_itemsToCollect.Count > 0 && (GlobalState.Dialogue == null || GlobalState.Dialogue == "") && !GlobalState.ScreenTransition) 112 if (_itemsToCollect.Count > 0 && (GlobalState.Dialogue == null || GlobalState.Dialogue == "") && !GlobalState.ScreenTransition && Plugin.Player != null && GlobalState.black_overlay.alpha == 0f)
108 { 113 {
109 NetworkItem item = _itemsToCollect.Dequeue(); 114 NetworkItem item = _itemsToCollect.Dequeue();
110 HandleItem(item); 115 HandleItem(item);
@@ -125,7 +130,7 @@ namespace AnodyneArchipelago
125 } 130 }
126 } 131 }
127 132
128 private static void HandleItem(NetworkItem item) 133 private void HandleItem(NetworkItem item)
129 { 134 {
130 if (item.Player == _session.ConnectionInfo.Slot) 135 if (item.Player == _session.ConnectionInfo.Slot)
131 { 136 {
@@ -223,7 +228,7 @@ namespace AnodyneArchipelago
223 GlobalState.Dialogue = message; 228 GlobalState.Dialogue = message;
224 } 229 }
225 230
226 private static void OnMessageReceived(LogMessage message) 231 private void OnMessageReceived(LogMessage message)
227 { 232 {
228 switch (message) 233 switch (message)
229 { 234 {
diff --git a/AnodyneArchipelago/ArchipelagoTreasure.cs b/AnodyneArchipelago/ArchipelagoTreasure.cs index b3812f2..90f979c 100644 --- a/AnodyneArchipelago/ArchipelagoTreasure.cs +++ b/AnodyneArchipelago/ArchipelagoTreasure.cs
@@ -33,7 +33,7 @@ namespace AnodyneArchipelago
33 base.GetTreasure(); 33 base.GetTreasure();
34 } 34 }
35 35
36 ArchipelagoManager.SendLocation(_location); 36 Plugin.ArchipelagoManager.SendLocation(_location);
37 } 37 }
38 } 38 }
39} 39}
diff --git a/AnodyneArchipelago/Menu/ConnectionState.cs b/AnodyneArchipelago/Menu/ConnectionState.cs new file mode 100644 index 0000000..877213f --- /dev/null +++ b/AnodyneArchipelago/Menu/ConnectionState.cs
@@ -0,0 +1,118 @@
1using AnodyneSharp.Input;
2using AnodyneSharp.Resources;
3using AnodyneSharp.Sounds;
4using AnodyneSharp.States;
5using AnodyneSharp.UI;
6using AnodyneSharp.UI.Font;
7using AnodyneSharp.UI.Text;
8using Archipelago.MultiClient.Net;
9using Archipelago.MultiClient.Net.Enums;
10using Microsoft.Xna.Framework;
11using System.Reflection;
12using System.Threading.Tasks;
13
14namespace AnodyneArchipelago.Menu
15{
16 internal class ConnectionState : State
17 {
18 public delegate void SuccessEvent(ArchipelagoManager archipelagoManager);
19
20 private readonly SuccessEvent _successFunc;
21
22 private Task<LoginResult> _connectionTask;
23 private ArchipelagoManager _archipelago = new();
24
25 private TextWriter _textWriter;
26 private UIEntity _bgBox;
27 private readonly SpriteFont _font;
28
29 private string _text = "Connecting...";
30
31 public ConnectionState(string apServer, string apSlot, string apPassword, SuccessEvent successFunc)
32 {
33 _successFunc = successFunc;
34
35 _connectionTask = Task.Run(() => _archipelago.Connect(apServer, apSlot, apPassword));
36
37 _font = FontManager.InitFont(new Color(226, 226, 226), true);
38
39 _textWriter = new(20, 44, 128, 100)
40 {
41 drawLayer = AnodyneSharp.Drawing.DrawOrder.TEXT
42 };
43 _textWriter.SetSpriteFont(_font, ResourceManager.GetTexture("consoleButtons"));
44
45 _bgBox = new UIEntity(new Vector2(16f, 40f), "pop_menu", 16, 16, AnodyneSharp.Drawing.DrawOrder.TEXTBOX);
46 UpdateDisplay();
47 }
48
49 public override void Update()
50 {
51 if (_connectionTask != null && _connectionTask.IsCompleted)
52 {
53 LoginResult result = _connectionTask.Result;
54
55 if (result.Successful)
56 {
57 Exit = true;
58 _successFunc(_archipelago);
59 return;
60 }
61 else
62 {
63 LoginFailure failure = result as LoginFailure;
64 string errorMessage = "";
65 foreach (string error in failure.Errors)
66 {
67 errorMessage += error;
68 errorMessage += "\n";
69 }
70 foreach (ConnectionRefusedError error in failure.ErrorCodes)
71 {
72 errorMessage += error.ToString();
73 errorMessage += "\n";
74 }
75
76 if (errorMessage.Length > 0)
77 {
78 errorMessage = errorMessage.Substring(0, errorMessage.Length - 1);
79 }
80 else
81 {
82 errorMessage = "Unknown error during connection.";
83 }
84
85 _text = errorMessage;
86 _connectionTask = null;
87
88 UpdateDisplay();
89 }
90 }
91
92 if (KeyInput.JustPressedRebindableKey(KeyFunctions.Accept) || KeyInput.JustPressedRebindableKey(KeyFunctions.Cancel))
93 {
94 Exit = true;
95 SoundManager.PlaySoundEffect("menu_select");
96 }
97 }
98
99 public override void DrawUI()
100 {
101 _bgBox.Draw();
102 _textWriter.Draw();
103 }
104
105 private void UpdateDisplay()
106 {
107 _textWriter.Text = _text;
108 _textWriter.ProgressTextToEnd();
109
110 FieldInfo linesField = typeof(TextWriter).GetField("_line", BindingFlags.NonPublic | BindingFlags.Instance);
111 int lineValue = (int)linesField.GetValue(_textWriter);
112
113 int innerHeight = (lineValue + 1) * _font.lineSeparation;
114
115 _bgBox = new UIEntity(new Vector2(16f, 40f), "pop_menu", 136, innerHeight + 8, AnodyneSharp.Drawing.DrawOrder.TEXTBOX);
116 }
117 }
118}
diff --git a/AnodyneArchipelago/Menu/MenuState.cs b/AnodyneArchipelago/Menu/MenuState.cs index b9ee0dd..cabb94b 100644 --- a/AnodyneArchipelago/Menu/MenuState.cs +++ b/AnodyneArchipelago/Menu/MenuState.cs
@@ -33,6 +33,9 @@ namespace AnodyneArchipelago.Menu
33 33
34 private int _selectorIndex = 0; 34 private int _selectorIndex = 0;
35 35
36 private bool _fadingOut = false;
37 private bool _isNewGame;
38
36 public override void Create() 39 public override void Create()
37 { 40 {
38 _selector = new(); 41 _selector = new();
@@ -65,6 +68,18 @@ namespace AnodyneArchipelago.Menu
65 68
66 public override void Update() 69 public override void Update()
67 { 70 {
71 if (_fadingOut)
72 {
73 GlobalState.black_overlay.ChangeAlpha(0.72f);
74
75 if (GlobalState.black_overlay.alpha == 1.0)
76 {
77 ChangeStateEvent(_isNewGame ? AnodyneSharp.AnodyneGame.GameState.Intro : AnodyneSharp.AnodyneGame.GameState.Game);
78 }
79
80 return;
81 }
82
68 if (_substate != null) 83 if (_substate != null)
69 { 84 {
70 _substate.Update(); 85 _substate.Update();
@@ -217,6 +232,9 @@ namespace AnodyneArchipelago.Menu
217 case 2: 232 case 2:
218 _substate = new TextEntry("Password:", _apPassword, (string value) => { _apPassword = value; UpdateLabels(); }); 233 _substate = new TextEntry("Password:", _apPassword, (string value) => { _apPassword = value; UpdateLabels(); });
219 break; 234 break;
235 case 4:
236 _substate = new ConnectionState(_apServer, _apSlot, _apPassword, OnConnected);
237 break;
220 case 6: 238 case 6:
221 GlobalState.ClosingGame = true; 239 GlobalState.ClosingGame = true;
222 break; 240 break;
@@ -231,5 +249,25 @@ namespace AnodyneArchipelago.Menu
231 { 249 {
232 250
233 } 251 }
252
253 private void OnConnected(ArchipelagoManager archipelagoManager)
254 {
255 Plugin.ArchipelagoManager = archipelagoManager;
256
257 GlobalState.Save saveFile = GlobalState.Save.GetSave(string.Format("{0}Saves/Save_zzAP{1}_{2}.dat", GameConstants.SavePath, Plugin.ArchipelagoManager.GetSeed(), Plugin.ArchipelagoManager.GetPlayer()));
258
259 GlobalState.ResetValues();
260 if (saveFile != null)
261 {
262 GlobalState.LoadSave(saveFile);
263 _isNewGame = false;
264 }
265 else
266 {
267 _isNewGame = true;
268 }
269
270 _fadingOut = true;
271 }
234 } 272 }
235} 273}
diff --git a/AnodyneArchipelago/Patches/GameplayPatches.cs b/AnodyneArchipelago/Patches/GameplayPatches.cs index ada4159..9db87a5 100644 --- a/AnodyneArchipelago/Patches/GameplayPatches.cs +++ b/AnodyneArchipelago/Patches/GameplayPatches.cs
@@ -69,15 +69,15 @@ namespace AnodyneArchipelago.Patches
69 69
70 if (preset.Frame == 0) 70 if (preset.Frame == 0)
71 { 71 {
72 ArchipelagoManager.SendLocation("Temple of the Seeing One - Green Key"); 72 Plugin.ArchipelagoManager.SendLocation("Temple of the Seeing One - Green Key");
73 } 73 }
74 else if (preset.Frame == 1) 74 else if (preset.Frame == 1)
75 { 75 {
76 ArchipelagoManager.SendLocation("Red Grotto - Red Key"); 76 Plugin.ArchipelagoManager.SendLocation("Red Grotto - Red Key");
77 } 77 }
78 else if (preset.Frame == 2) 78 else if (preset.Frame == 2)
79 { 79 {
80 ArchipelagoManager.SendLocation("Mountain Cavern - Blue Key"); 80 Plugin.ArchipelagoManager.SendLocation("Mountain Cavern - Blue Key");
81 } 81 }
82 } 82 }
83 } 83 }
@@ -134,7 +134,7 @@ namespace AnodyneArchipelago.Patches
134 134
135 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID)) 135 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID))
136 { 136 {
137 ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]); 137 Plugin.ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]);
138 } 138 }
139 } 139 }
140 } 140 }
@@ -221,7 +221,7 @@ namespace AnodyneArchipelago.Patches
221 221
222 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID)) 222 if (Locations.LocationsByGuid.ContainsKey(preset.EntityID))
223 { 223 {
224 ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]); 224 Plugin.ArchipelagoManager.SendLocation(Locations.LocationsByGuid[preset.EntityID]);
225 } 225 }
226 } 226 }
227 } 227 }
diff --git a/AnodyneArchipelago/Patches/StatePatches.cs b/AnodyneArchipelago/Patches/StatePatches.cs index 4b29295..40b30fe 100644 --- a/AnodyneArchipelago/Patches/StatePatches.cs +++ b/AnodyneArchipelago/Patches/StatePatches.cs
@@ -8,6 +8,7 @@ using AnodyneSharp.Drawing.Effects;
8using AnodyneSharp.States.MainMenu; 8using AnodyneSharp.States.MainMenu;
9using static AnodyneSharp.AnodyneGame; 9using static AnodyneSharp.AnodyneGame;
10using AnodyneSharp.Drawing; 10using AnodyneSharp.Drawing;
11using System.IO;
11 12
12namespace AnodyneArchipelago.Patches 13namespace AnodyneArchipelago.Patches
13{ 14{
@@ -16,7 +17,10 @@ namespace AnodyneArchipelago.Patches
16 { 17 {
17 static void Postfix() 18 static void Postfix()
18 { 19 {
19 ArchipelagoManager.Update(); 20 if (Plugin.ArchipelagoManager != null)
21 {
22 Plugin.ArchipelagoManager.Update();
23 }
20 } 24 }
21 } 25 }
22 26
@@ -63,6 +67,17 @@ namespace AnodyneArchipelago.Patches
63 } 67 }
64 } 68 }
65 69
70 [HarmonyPatch(typeof(GlobalState.Save), nameof(GlobalState.Save.SaveTo))]
71 class SaveToPatch
72 {
73 static bool Prefix(GlobalState.Save __instance)
74 {
75 File.WriteAllText(string.Format("{0}Saves/Save_zzAP{1}_{2}.dat", GameConstants.SavePath, Plugin.ArchipelagoManager.GetSeed(), Plugin.ArchipelagoManager.GetPlayer()), __instance.ToString());
76
77 return false;
78 }
79 }
80
66 [HarmonyPatch(typeof(PlayState), nameof(PlayState.Create))] 81 [HarmonyPatch(typeof(PlayState), nameof(PlayState.Create))]
67 class PlayStateCreatePatch 82 class PlayStateCreatePatch
68 { 83 {
@@ -76,11 +91,6 @@ namespace AnodyneArchipelago.Patches
76 GlobalState.events.SetEvent("red_cave_l_ss", 999); 91 GlobalState.events.SetEvent("red_cave_l_ss", 999);
77 GlobalState.events.SetEvent("red_cave_n_ss", 999); 92 GlobalState.events.SetEvent("red_cave_n_ss", 999);
78 GlobalState.events.SetEvent("red_cave_r_ss", 999); 93 GlobalState.events.SetEvent("red_cave_r_ss", 999);
79
80 // Connect to archipelago.
81 Plugin.Instance.Log.LogInfo("Connecting to Archipelago!");
82
83 ArchipelagoManager.Connect("localhost:38281", "Anodyne", "");
84 } 94 }
85 } 95 }
86} 96}
diff --git a/AnodyneArchipelago/Plugin.cs b/AnodyneArchipelago/Plugin.cs index 66f020d..10a30b9 100644 --- a/AnodyneArchipelago/Plugin.cs +++ b/AnodyneArchipelago/Plugin.cs
@@ -13,6 +13,7 @@ namespace AnodyneArchipelago
13 { 13 {
14 public static Plugin Instance = null; 14 public static Plugin Instance = null;
15 public static Player Player = null; 15 public static Player Player = null;
16 public static ArchipelagoManager ArchipelagoManager = null;
16 17
17 public static string GetVersion() 18 public static string GetVersion()
18 { 19 {