Skip to content

Commit f1a12cb

Browse files
SaberShipSaberShip
andauthored
Disable Trade/Transport/Caravan Session Buttons for Other Factions (#507)
* Disable trade/caravan session buttons for other factions * Display correct faction name in trade UI * Disable "M<" button. --------- Co-authored-by: SaberShip <sabership.noreply@github.com>
1 parent 5209354 commit f1a12cb

File tree

7 files changed

+275
-16
lines changed

7 files changed

+275
-16
lines changed

Source/Client/Comp/Map/MultiplayerMapComp.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ public MultiplayerMapComp(Map map)
3535
sessionManager = new(map);
3636
}
3737

38-
public CaravanFormingSession CreateCaravanFormingSession(bool reform, Action onClosed, bool mapAboutToBeRemoved, IntVec3? meetingSpot = null)
38+
public CaravanFormingSession CreateCaravanFormingSession(Faction faction, bool reform, Action onClosed, bool mapAboutToBeRemoved, IntVec3? meetingSpot = null)
3939
{
4040
var caravanForming = sessionManager.GetFirstOfType<CaravanFormingSession>();
4141
if (caravanForming == null)
4242
{
43-
caravanForming = new CaravanFormingSession(map, reform, onClosed, mapAboutToBeRemoved, meetingSpot);
43+
caravanForming = new CaravanFormingSession(faction, map, reform, onClosed, mapAboutToBeRemoved, meetingSpot);
4444
if (!sessionManager.AddSession(caravanForming))
4545
{
4646
// Shouldn't happen if the session doesn't exist already, show an error just in case
@@ -51,12 +51,12 @@ public CaravanFormingSession CreateCaravanFormingSession(bool reform, Action onC
5151
return caravanForming;
5252
}
5353

54-
public TransporterLoading CreateTransporterLoadingSession(List<CompTransporter> transporters)
54+
public TransporterLoading CreateTransporterLoadingSession(Faction faction, List<CompTransporter> transporters)
5555
{
5656
var transporterLoading = sessionManager.GetFirstOfType<TransporterLoading>();
5757
if (transporterLoading == null)
5858
{
59-
transporterLoading = new TransporterLoading(map, transporters);
59+
transporterLoading = new TransporterLoading(faction, map, transporters);
6060
if (!sessionManager.AddSession(transporterLoading))
6161
{
6262
// Shouldn't happen if the session doesn't exist already, show an error just in case

Source/Client/Persistent/CaravanFormingPatches.cs

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using UnityEngine;
88
using Verse;
99
using static Verse.Widgets;
10+
using System.Reflection;
1011

1112
namespace Multiplayer.Client.Persistent
1213
{
@@ -168,25 +169,27 @@ static void Prefix(Dialog_FormCaravan __instance, Map map, bool reform, Action o
168169
if (__instance.GetType() != typeof(Dialog_FormCaravan))
169170
return;
170171

172+
Faction faction = Faction.OfPlayer;
173+
171174
// Handles showing the dialog from TimedForcedExit.CompTick -> TimedForcedExit.ForceReform
172175
// (note TimedForcedExit is obsolete)
173176
if (Multiplayer.ExecutingCmds || Multiplayer.Ticking)
174177
{
175178
var comp = map.MpComp();
176179
if (comp.sessionManager.GetFirstOfType<CaravanFormingSession>() == null)
177-
comp.CreateCaravanFormingSession(reform, onClosed, mapAboutToBeRemoved, designatedMeetingPoint);
180+
comp.CreateCaravanFormingSession(faction, reform, onClosed, mapAboutToBeRemoved, designatedMeetingPoint);
178181
}
179182
else // Handles opening from the interface: forming gizmos, reforming gizmos and caravan hitching spots
180183
{
181-
StartFormingCaravan(map, reform, designatedMeetingPoint);
184+
StartFormingCaravan(faction, map, reform, designatedMeetingPoint);
182185
}
183186
}
184187

185188
[SyncMethod]
186-
internal static void StartFormingCaravan(Map map, bool reform = false, IntVec3? designatedMeetingPoint = null, int? routePlannerWaypoint = null)
189+
internal static void StartFormingCaravan(Faction faction, Map map, bool reform = false, IntVec3? designatedMeetingPoint = null, int? routePlannerWaypoint = null)
187190
{
188191
var comp = map.MpComp();
189-
var session = comp.CreateCaravanFormingSession(reform, null, false, designatedMeetingPoint);
192+
var session = comp.CreateCaravanFormingSession(faction, reform, null, false, designatedMeetingPoint);
190193

191194
if (TickPatch.currentExecutingCmdIssuedBySelf)
192195
{
@@ -224,7 +227,7 @@ static bool Prefix(Map origin, int tile)
224227
return true;
225228

226229
// Override behavior in multiplayer
227-
DialogFormCaravanCtorPatch.StartFormingCaravan(origin, routePlannerWaypoint: tile);
230+
DialogFormCaravanCtorPatch.StartFormingCaravan(Faction.OfPlayer, origin, routePlannerWaypoint: tile);
228231

229232
return false;
230233
}
@@ -241,4 +244,101 @@ static bool Prefix(TimedForcedExit __instance)
241244
return true;
242245
}
243246
}
247+
248+
[HarmonyPatch()]
249+
static class DisableCaravanFormCheckboxForOtherFactions
250+
{
251+
static MethodInfo TargetMethod() {
252+
return typeof(Widgets).GetMethod("Checkbox", [
253+
typeof(Vector2), typeof(bool).MakeByRefType(), typeof(float), typeof(bool), typeof(bool), typeof(Texture2D), typeof(Texture2D)
254+
]);
255+
}
256+
257+
static bool Prefix(Vector2 topLeft, bool checkOn, bool disabled)
258+
{
259+
if (CaravanFormingProxy.drawing == null || CaravanFormingProxy.drawing.Session?.faction == Multiplayer.RealPlayerFaction)
260+
return true;
261+
262+
if (disabled)
263+
return true;
264+
265+
Widgets.Checkbox(topLeft, ref checkOn, disabled: true);
266+
return false;
267+
}
268+
}
269+
270+
[HarmonyPatch()]
271+
static class DisableCaravanFormSuppliesCheckboxForOtherFactions
272+
{
273+
static MethodInfo TargetMethod() {
274+
return typeof(Widgets).GetMethod("CheckboxLabeled", [
275+
typeof(Rect), typeof(string), typeof(bool).MakeByRefType(), typeof(bool), typeof(Texture2D), typeof(Texture2D), typeof(bool), typeof(bool)
276+
]);
277+
}
278+
279+
static bool Prefix(Rect rect, string label, bool checkOn, bool disabled)
280+
{
281+
if (CaravanFormingProxy.drawing == null || CaravanFormingProxy.drawing.Session?.faction == Multiplayer.RealPlayerFaction)
282+
return true;
283+
284+
if (disabled || label != "AutomaticallySelectTravelSupplies".Translate())
285+
return true;
286+
287+
Widgets.CheckboxLabeled(rect, label, ref checkOn, disabled: true, null, null, placeCheckboxNearText: true);
288+
return false;
289+
}
290+
}
291+
292+
[HarmonyPatch(typeof(Widgets), nameof(Widgets.ButtonText), typeof(Rect), typeof(string), typeof(bool), typeof(bool), typeof(bool), typeof(TextAnchor))]
293+
static class DisableCaravanFormControlButtonsForOtherFactions
294+
{
295+
static bool Prefix(Rect rect, string label, ref bool __result)
296+
{
297+
if (CaravanFormingProxy.drawing == null || CaravanFormingProxy.drawing.Session?.faction == Multiplayer.RealPlayerFaction)
298+
return true;
299+
300+
if (label != "ResetButton".Translate() && label != "CancelButton".Translate() && label != "ChangeRouteButton".Translate() && label != "Send".Translate())
301+
return true;
302+
303+
__result = false;
304+
return false;
305+
}
306+
}
307+
308+
[HarmonyPatch(typeof(Widgets), nameof(Widgets.ButtonText))]
309+
[HarmonyPatch(new[] { typeof(Rect), typeof(string), typeof(bool), typeof(bool), typeof(bool), typeof(TextAnchor) })]
310+
static class DisableCaravanFormCountButtonsForOtherFactions
311+
{
312+
static bool Prefix(Rect rect, string label, ref bool __result)
313+
{
314+
if (CaravanFormingProxy.drawing == null || CaravanFormingProxy.drawing.Session?.faction == Multiplayer.RealPlayerFaction)
315+
return true;
316+
317+
if (label != "0" && label != "M<" && label != "<<" && label != "<" && label != ">" && label != ">>" && label != ">M")
318+
return true;
319+
320+
GUI.color = Widgets.InactiveColor;
321+
Widgets.TextArea(rect, label, true);
322+
GUI.color = Color.white;
323+
__result = false;
324+
return false;
325+
}
326+
}
327+
328+
[HarmonyPatch()]
329+
static class DisableCaravanFormCountTextBoxForOtherFactions
330+
{
331+
static MethodInfo TargetMethod() {
332+
return typeof(Widgets).GetMethod("TextFieldNumeric", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(typeof(int));
333+
}
334+
static bool Prefix(Rect rect, int val)
335+
{
336+
if (CaravanFormingProxy.drawing == null || CaravanFormingProxy.drawing.Session?.faction == Multiplayer.RealPlayerFaction)
337+
return true;
338+
339+
GUI.color = Color.white;
340+
Widgets.TextArea(rect, val.ToString(), true);
341+
return false;
342+
}
343+
}
244344
}

Source/Client/Persistent/CaravanFormingSession.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public class CaravanFormingSession : ExposableSession, ISessionWithTransferables
1111
{
1212
public Map map;
1313

14+
public Faction faction;
15+
1416
public bool reform;
1517
public Action onClosed;
1618
public bool mapAboutToBeRemoved;
@@ -24,12 +26,13 @@ public class CaravanFormingSession : ExposableSession, ISessionWithTransferables
2426

2527
public override Map Map => map;
2628

27-
public CaravanFormingSession(Map map) : base(map)
29+
public CaravanFormingSession(Faction faction, Map map) : base(map)
2830
{
2931
this.map = map;
32+
this.faction = faction;
3033
}
3134

32-
public CaravanFormingSession(Map map, bool reform, Action onClosed, bool mapAboutToBeRemoved, IntVec3? meetingSpot = null) : this(map)
35+
public CaravanFormingSession(Faction faction, Map map, bool reform, Action onClosed, bool mapAboutToBeRemoved, IntVec3? meetingSpot = null) : this(faction, map)
3336
{
3437
this.reform = reform;
3538
this.onClosed = onClosed;

Source/Client/Persistent/Trading.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public class MpTradeSession : ExposableSession, ISessionWithTransferables, ISess
2222
public MpTradeDeal deal;
2323
public bool giftsOnly;
2424

25+
public Faction NegotiatorFaction => playerNegotiator?.Faction;
26+
2527
public string Label
2628
{
2729
get

Source/Client/Persistent/TradingUI.cs

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ public override void DoWindowContents(Rect inRect)
4848
if (selectedTab == -1 && trading.Count > 0)
4949
selectedTab = 0;
5050

51-
if (selectedTab == -1)
51+
if (selectedTab == -1 || tabs.Count == 0)
5252
{
5353
Close();
5454
return;
5555
}
5656

5757
int rows = Mathf.CeilToInt(tabs.Count / 3f);
5858
inRect.yMin += rows * TabDrawer.TabHeight + 3;
59-
TabDrawer.DrawTabs(inRect, tabs, rows);
59+
TabDrawer.DrawTabs(inRect, tabs);
6060

6161
inRect.yMin += 10f;
6262

@@ -67,8 +67,10 @@ public override void DoWindowContents(Rect inRect)
6767
selectedSession = session.SessionId;
6868
}
6969

70+
Faction factionContext = session.NegotiatorFaction;
7071
try
7172
{
73+
factionContext = FactionContext.Push(factionContext);
7274
MpTradeSession.SetTradeSession(session);
7375
drawingTrade = this;
7476

@@ -124,6 +126,9 @@ public override void DoWindowContents(Rect inRect)
124126
{
125127
drawingTrade = null;
126128
MpTradeSession.SetTradeSession(null);
129+
if (factionContext != null) {
130+
FactionContext.Pop();
131+
}
127132
}
128133
}
129134

@@ -246,6 +251,77 @@ public static List<Tradeable> AllTradeables()
246251
}
247252
}
248253

254+
[HarmonyPatch(typeof(Widgets), nameof(Widgets.ButtonText), typeof(Rect), typeof(string), typeof(bool), typeof(bool), typeof(bool), typeof(TextAnchor))]
255+
static class DisableTradeControlButtonsForOtherFactions
256+
{
257+
static bool Prefix(Rect rect, string label, ref bool __result)
258+
{
259+
if (TradingWindow.drawingTrade == null || MpTradeSession.current.NegotiatorFaction == Multiplayer.RealPlayerFaction)
260+
return true;
261+
262+
if (label != "ResetButton".Translate() && label != "CancelButton".Translate() && label != "OfferGifts".Translate() && label != "AcceptButton".Translate())
263+
return true;
264+
265+
__result = false;
266+
return false;
267+
}
268+
}
269+
270+
[HarmonyPatch(typeof(Widgets), nameof(Widgets.ButtonImageWithBG))]
271+
static class DisableTradeModeButtonForOtherFactions
272+
{
273+
private static readonly Texture2D GiftModeIcon = ContentFinder<Texture2D>.Get("UI/Buttons/GiftMode");
274+
private static readonly Texture2D TradeModeIcon = ContentFinder<Texture2D>.Get("UI/Buttons/TradeMode");
275+
276+
static bool Prefix(Rect butRect, Texture2D image, ref bool __result)
277+
{
278+
if (TradingWindow.drawingTrade == null || MpTradeSession.current.NegotiatorFaction == Multiplayer.RealPlayerFaction)
279+
return true;
280+
281+
if (image != GiftModeIcon && image != TradeModeIcon)
282+
return true;
283+
284+
__result = false;
285+
return false;
286+
}
287+
}
288+
289+
[HarmonyPatch(typeof(Widgets), nameof(Widgets.ButtonText), typeof(Rect), typeof(string), typeof(bool), typeof(bool), typeof(bool), typeof(TextAnchor))]
290+
static class DisableTradeCountButtonsForOtherFactions
291+
{
292+
static bool Prefix(Rect rect, string label, ref bool __result)
293+
{
294+
if (TradingWindow.drawingTrade == null || MpTradeSession.current.NegotiatorFaction == Multiplayer.RealPlayerFaction)
295+
return true;
296+
297+
if (label != "0" && label != "M<" && label != "<<" && label != "<" && label != ">" && label != ">>" && label != ">M")
298+
return true;
299+
300+
GUI.color = Widgets.InactiveColor;
301+
Widgets.TextArea(rect, label, true);
302+
GUI.color = Color.white;
303+
__result = false;
304+
return false;
305+
}
306+
}
307+
308+
[HarmonyPatch()]
309+
static class DisableTradeCountTextBoxForOtherFactions
310+
{
311+
static MethodInfo TargetMethod() {
312+
return typeof(Widgets).GetMethod("TextFieldNumeric", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(typeof(int));
313+
}
314+
static bool Prefix(Rect rect, int val)
315+
{
316+
if (TradingWindow.drawingTrade == null || MpTradeSession.current.NegotiatorFaction == Multiplayer.RealPlayerFaction)
317+
return true;
318+
319+
GUI.color = Color.white;
320+
Widgets.TextArea(rect, val.ToString(), true);
321+
return false;
322+
}
323+
}
324+
249325
[HarmonyPatch(typeof(Widgets), nameof(Widgets.ButtonTextWorker))]
250326
static class MakeCancelTradeButtonRed
251327
{

0 commit comments

Comments
 (0)