Skip to content

Commit

Permalink
Add faction switcher
Browse files Browse the repository at this point in the history
Fix sending drop pods to empty tiles
Fix players receiving notification sounds of other factions
  • Loading branch information
Zetrith committed Dec 16, 2023
1 parent 637b518 commit d03a1b8
Show file tree
Hide file tree
Showing 8 changed files with 255 additions and 17 deletions.
95 changes: 95 additions & 0 deletions Source/Client/Factions/FactionsWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Linq;
using Multiplayer.Client.Util;
using Multiplayer.Common;
using RimWorld;
using UnityEngine;
using Verse;

namespace Multiplayer.Client.Factions;

public class FactionsWindow : Window
{
public override Vector2 InitialSize { get; } = new(700, 600);

private static Vector2 scroll;

public FactionsWindow()
{
doCloseX = true;
}

public override void DoWindowContents(Rect inRect)
{
var group = DragAndDropWidget.NewGroup();

Layouter.BeginArea(inRect);
Layouter.BeginScroll(ref scroll, spacing: 0f);

var factions = Find.FactionManager.AllFactions.Where(f => f.IsPlayer).ToList();

void DrawFactionInLastRect(Faction faction)
{
DragAndDropWidget.DropArea(group, Layouter.LastRect(), playerId =>
{
Multiplayer.Client.Send(Packets.Client_SetFaction, (int)playerId, faction.loadID);
}, null);

Layouter.BeginVerticalInLastRect(spacing: 1f);

Layouter.BeginHorizontal();
{
Layouter.BeginVertical(spacing: 0f, false);
Layouter.Rect(0f, 5f);

if (Layouter.Button(">", 20f, 20f))
Multiplayer.Client.Send(Packets.Client_SetFaction, Multiplayer.session.playerId, faction.loadID);

TooltipHandler.TipRegion(Layouter.LastRect(), "Switch faction");

Layouter.EndVertical();

using (MpStyle.Set(GameFont.Medium))
Layouter.Label(faction.Name);
}
Layouter.EndHorizontal();

foreach (var p in Multiplayer.session.players)
{
if (p.factionId != faction.loadID)
continue;

var rect = Layouter.ContentRect(p.username);

if (Multiplayer.LocalServer != null && DragAndDropWidget.Draggable(group, rect, p.id))
Widgets.Label(rect with { position = Event.current.mousePosition }, p.username);
else
Widgets.Label(rect, p.username);
}

Layouter.EndVertical();
}

for (int i = 0; i < factions.Count; i++)
{
Layouter.BeginHorizontal();

float height = 23 * Multiplayer.session.players.Count(p => p.factionId == factions[i].loadID) + 30f;
if (i + 1 < factions.Count)
height = Math.Max(23 * Multiplayer.session.players.Count(p => p.factionId == factions[i+1].loadID) + 30f, height);
height = Math.Max(200, height);

Layouter.FixedHeight(height);
DrawFactionInLastRect(factions[i]);
i++;

Layouter.FixedHeight(height);
if (i < factions.Count) DrawFactionInLastRect(factions[i]);

Layouter.EndHorizontal();
}

Layouter.EndScroll();
Layouter.EndArea();
}
}
27 changes: 27 additions & 0 deletions Source/Client/Factions/MultifactionPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using UnityEngine;
using Verse;
using Verse.AI;
using Verse.Sound;

namespace Multiplayer.Client.Patches;

Expand Down Expand Up @@ -332,6 +333,32 @@ static void Postfix(LetterStack __instance, Letter let)
}
}

[HarmonyPatch(typeof(LetterStack), nameof(LetterStack.ReceiveLetter), typeof(Letter), typeof(string))]
static class LetterStackReceiveSoundOnlyMyFaction
{
private static MethodInfo PlayOneShotOnCamera =
typeof(SoundStarter).GetMethod(nameof(SoundStarter.PlayOneShotOnCamera));

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> insts)
{
foreach (var inst in insts)
{
if (inst.operand == PlayOneShotOnCamera)
yield return new CodeInstruction(
OpCodes.Call,
SymbolExtensions.GetMethodInfo((SoundDef s, Map m) => PlaySoundReplacement(s, m)));
else
yield return inst;
}
}

static void PlaySoundReplacement(SoundDef sound, Map map)
{
if (Multiplayer.RealPlayerFaction == Faction.OfPlayer)
sound.PlayOneShotOnCamera(map);
}
}

[HarmonyPatch]
static class DontClearDialogBeginRitualCache
{
Expand Down
30 changes: 30 additions & 0 deletions Source/Client/MultiplayerStatic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Multiplayer.Client.Util;
using Multiplayer.Common;
using RimWorld;
using RimWorld.Planet;
using Steamworks;
using UnityEngine;
using Verse;
Expand Down Expand Up @@ -403,6 +404,35 @@ void LogError(string str)
}
}

// Set FactionContext in common WorldObject methods
{
var prefix = new HarmonyMethod(typeof(WorldObjectMethodPatches).GetMethod(nameof(WorldObjectMethodPatches.Prefix)));
var finalizer = new HarmonyMethod(typeof(WorldObjectMethodPatches).GetMethod(nameof(WorldObjectMethodPatches.Finalizer)));

var thingMethods = new[]
{
("SpawnSetup", Type.EmptyTypes),
("Tick", Type.EmptyTypes)
};

foreach (Type t in typeof(WorldObject).AllSubtypesAndSelf())
{
foreach ((string m, Type[] args) in thingMethods)
{
MethodInfo method = t.GetMethod(m, BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly, null, args, null);
if (method != null)
{
try
{
harmony.PatchMeasure(method, prefix, finalizer: finalizer);
} catch (Exception e) {
LogError($"FAIL: {method.DeclaringType.FullName}:{method.Name} with {e}");
}
}
}
}
}

// Full precision floating point saving
{
var doubleSavePrefix = new HarmonyMethod(typeof(ValueSavePatch).GetMethod(nameof(ValueSavePatch.DoubleSave_Prefix)));
Expand Down
25 changes: 25 additions & 0 deletions Source/Client/Patches/WorldObjectMethodPatches.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using HarmonyLib;
using RimWorld.Planet;

namespace Multiplayer.Client.Patches;

public static class WorldObjectMethodPatches
{
[HarmonyPriority(MpPriority.MpFirst)]
public static void Prefix(WorldObject __instance)
{
if (Multiplayer.Client == null) return;

if (__instance.def.canHaveFaction)
FactionContext.Push(__instance.Faction);
}

[HarmonyPriority(MpPriority.MpLast)]
public static void Finalizer(WorldObject __instance)
{
if (Multiplayer.Client == null) return;

if (__instance.def.canHaveFaction)
FactionContext.Pop();
}
}
85 changes: 71 additions & 14 deletions Source/Client/UI/Layouter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,13 @@ private static El GetNextChild()
#region Groups
private static void PushGroup(El el)
{
var parent = currentGroup;
currentGroup = el;

if (parent != null)
if (currentGroup != null)
{
currentGroup.parent = parent;
parent.children.Add(currentGroup);
el.parent = currentGroup;
currentGroup.children.Add(el);
}

currentGroup = el;
}

private static void PopGroup()
Expand Down Expand Up @@ -184,6 +183,18 @@ public static void EndHorizontal()
PopGroup();
}

public static void BeginHorizontalCenter()
{
BeginHorizontal();
FlexibleWidth();
}

public static void EndHorizontalCenter()
{
FlexibleWidth();
EndHorizontal();
}

public static void BeginVertical(float spacing = 10f, bool stretch = true)
{
if (Event.current.type == EventType.Layout)
Expand All @@ -192,6 +203,19 @@ public static void BeginVertical(float spacing = 10f, bool stretch = true)
currentGroup = GetNextChild();
}

public static void BeginVerticalInLastRect(float spacing = 10f)
{
if (Event.current.type == EventType.Layout)
{
LastEl().parent = currentGroup;
currentGroup = LastEl();
currentGroup.spacing = spacing;
} else
{
currentGroup = LastEl();
}
}

public static void EndVertical()
{
PopGroup();
Expand All @@ -204,15 +228,19 @@ public static void BeginScroll(ref Vector2 scrollPos, float spacing = 10f)
var outRect = currentGroup!.rect;
currentGroup.scroll = true;

Widgets.BeginScrollView(
outRect,
ref scrollPos,
new Rect(0, 0, outRect.width - currentGroup.paddingRight, currentGroup.childrenHeight));
var viewRect = new Rect(outRect.x, outRect.y, outRect.width - currentGroup.paddingRight, currentGroup.childrenHeight);

if (currentGroup.paddingRight != 0f)
Widgets.BeginScrollView(
outRect,
ref scrollPos,
viewRect);
}

public static void EndScroll()
{
Widgets.EndScrollView();
if (currentGroup.paddingRight != 0f)
Widgets.EndScrollView();
EndVertical();
}
#endregion
Expand Down Expand Up @@ -304,12 +332,29 @@ public static Rect FixedWidth(float width)
return GetNextChild().rect;
}

public static Rect LastRect()
public static Rect FixedHeight(float height)
{
if (Event.current.type == EventType.Layout)
{
currentGroup!.children.Add(new El()
{ rect = new Rect(0, 0, 0, height), widthMode = DimensionMode.Stretch, heightMode = DimensionMode.Fixed });
return DummyRect;
}

return GetNextChild().rect;
}

private static El LastEl()
{
return
Event.current.type == EventType.Layout ?
currentGroup!.children.Last().rect :
currentGroup!.children[currentGroup.currentChild - 1].rect;
currentGroup!.children.Last() :
currentGroup!.children[currentGroup.currentChild - 1];
}

public static Rect LastRect()
{
return LastEl().rect;
}

public static Rect GroupRect()
Expand All @@ -318,6 +363,18 @@ public static Rect GroupRect()
}
#endregion

#region UI elements
public static void Label(string text, bool inheritHeight = false)
{
GUI.Label(inheritHeight ? FlexibleWidth() : ContentRect(text), text, Text.CurFontStyle);
}

public static bool Button(string text, float width, float height = 35f)
{
return Widgets.ButtonText(Rect(width, height), text);
}
#endregion

#region Algorithm
private static void Layout()
{
Expand Down
5 changes: 4 additions & 1 deletion Source/Client/Windows/ChatWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Multiplayer.Client.Factions;
using Multiplayer.Client.Util;
using UnityEngine;
using Verse;
Expand Down Expand Up @@ -91,7 +92,9 @@ public override void DoWindowContents(Rect inRect)
DrawChat(chat);

GUI.BeginGroup(new Rect(chat.xMax + 10f, chat.y, infoWidth, inRect.height));
DrawInfo(new Rect(0, 0, infoWidth, inRect.height));
DrawInfo(new Rect(0, 0, infoWidth, inRect.height - 30f));
if (Widgets.ButtonText(new Rect(50f, inRect.height - 25f, infoWidth - 50f, 25f), "Factions"))
Find.WindowStack.Add(new FactionsWindow());
GUI.EndGroup();

if (KeyBindingDefOf.Cancel.KeyDownEvent && Find.WindowStack.focusedWindow == this)
Expand Down
1 change: 1 addition & 0 deletions Source/Common/Networking/State/ServerPlayingState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ public void HandleSetFaction(ByteReader data)

var player = Server.GetPlayer(playerId);
if (player == null) return;
if (player.FactionId == factionId) return;

player.FactionId = factionId;
Server.SendToPlaying(Packets.Server_SetFaction, new object[] { playerId, factionId });
Expand Down
4 changes: 2 additions & 2 deletions Source/Common/Version.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ namespace Multiplayer.Common
{
public static class MpVersion
{
public const string Version = "0.9.5";
public const int Protocol = 38;
public const string Version = "0.9.6";
public const int Protocol = 39;

public const string ApiAssemblyName = "0MultiplayerAPI";

Expand Down

0 comments on commit d03a1b8

Please sign in to comment.