diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index a631c51..3f3203c 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml b/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml index b48046f..699bcd6 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_WormholeDefs.xml @@ -23,7 +23,6 @@ Normal Building 50 - 0.5 250 8000 @@ -61,6 +60,9 @@ false + + Message_FleshbeastsDiscovered + @@ -90,6 +92,9 @@
  • None + + Message_FleshbeastsDiscovered + diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index c4d3371..9f760d3 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -209,7 +209,6 @@ - diff --git a/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_A.cs b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_A.cs index a126ad8..a753ca8 100644 --- a/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_A.cs +++ b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_A.cs @@ -11,7 +11,7 @@ namespace ArachnaeSwarm Linked } - public class Building_WormholePortal_A : Building + public class Building_WormholePortal_A : MapPortal { private Building_WormholePortal_B linkedPortalB; public WormholePortalStatus status = WormholePortalStatus.Idle; @@ -32,6 +32,68 @@ namespace ArachnaeSwarm base.SpawnSetup(map, respawningAfterLoad); refuelableComp = GetComp(); } + + // --- MapPortal Overrides --- + + public override bool IsEnterable(out string reason) + { + if (status != WormholePortalStatus.Linked) + { + reason = "WormholeNotLinked".Translate(); + return false; + } + if (linkedPortalB == null || linkedPortalB.Destroyed) + { + reason = "WormholeLinkLost".Translate(); + Notify_B_Destroyed(); + return false; + } + reason = ""; + return true; + } + + public override Map GetOtherMap() + { + return linkedPortalB?.Map; + } + + public override IntVec3 GetDestinationLocation() + { + return linkedPortalB.Position; + } + + public override void OnEntered(Pawn pawn) + { + // The base class handles adding the pawn to the container. + base.OnEntered(pawn); + + // Now, transfer everything in the container to the destination. + if (linkedPortalB != null && !linkedPortalB.Destroyed) + { + // Transfer pawns first + List pawnsInPortal = new List(); + foreach (Thing item in GetDirectlyHeldThings()) + { + if (item is Pawn p) + { + pawnsInPortal.Add(p); + } + } + + foreach(Pawn p in pawnsInPortal) + { + p.DeSpawn(); + GenSpawn.Spawn(p, CellFinder.RandomClosewalkCellNear(linkedPortalB.Position, linkedPortalB.Map, 5), linkedPortalB.Map, WipeMode.Vanish); + GetDirectlyHeldThings().Remove(p); + } + + // Transfer items + GetDirectlyHeldThings().TryDropAll(linkedPortalB.Position, linkedPortalB.Map, ThingPlaceMode.Near); + } + + // Custom sound/effect can be played here. + EffecterDefOf.Skip_Exit.Spawn(pawn.Position, pawn.Map); + } public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) { @@ -67,29 +129,11 @@ namespace ArachnaeSwarm public override IEnumerable GetGizmos() { + // Use the base (MapPortal) gizmos, which include "Enter" and "Cancel Load" foreach (Gizmo g in base.GetGizmos()) { yield return g; } - - if (status == WormholePortalStatus.Linked) - { - if (linkedPortalB == null || linkedPortalB.Destroyed) - { - // 安全检查,处理幽灵链接 - Notify_B_Destroyed(); - yield break; - } - - Command_Action enterCommand = new Command_Action - { - defaultLabel = "EnterWormhole".Translate(), - defaultDesc = "EnterWormholeDesc".Translate(), - icon = ContentFinder.Get("UI/Commands/EnterCave"), - action = BeginTeleportation - }; - yield return enterCommand; - } } public override string GetInspectString() @@ -103,9 +147,5 @@ namespace ArachnaeSwarm return text; } - private void BeginTeleportation() - { - Find.WindowStack.Add(new Dialog_WormholeTransfer(this, this.LinkedPortal)); - } } } \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_B.cs b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_B.cs index 841707d..7117118 100644 --- a/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_B.cs +++ b/Source/ArachnaeSwarm/Wormhole/Building_WormholePortal_B.cs @@ -1,10 +1,11 @@ +using RimWorld; using RimWorld.Planet; using System.Collections.Generic; using Verse; namespace ArachnaeSwarm { - public class Building_WormholePortal_B : Building + public class Building_WormholePortal_B : MapPortal { private Building_WormholePortal_A linkedPortalA; @@ -41,22 +42,66 @@ namespace ArachnaeSwarm public override IEnumerable GetGizmos() { + // Use the base (MapPortal) gizmos foreach (Gizmo g in base.GetGizmos()) { yield return g; } - + } + + // --- MapPortal Overrides --- + + public override bool IsEnterable(out string reason) + { + if (linkedPortalA == null || linkedPortalA.Destroyed) + { + reason = "WormholeLinkLost".Translate(); + if (linkedPortalA != null) linkedPortalA.Notify_B_Destroyed(); + this.Destroy(DestroyMode.Vanish); + return false; + } + reason = ""; + return true; + } + + public override Map GetOtherMap() + { + return linkedPortalA?.Map; + } + + public override IntVec3 GetDestinationLocation() + { + return linkedPortalA.Position; + } + + public override void OnEntered(Pawn pawn) + { + base.OnEntered(pawn); + if (linkedPortalA != null && !linkedPortalA.Destroyed) { - Command_Action enterCommand = new Command_Action + // Transfer pawns first + List pawnsInPortal = new List(); + foreach (Thing item in GetDirectlyHeldThings()) { - defaultLabel = "EnterWormhole".Translate(), - defaultDesc = "EnterWormholeDesc".Translate(), - icon = ContentFinder.Get("UI/Commands/EnterCave"), - action = BeginTeleportation - }; - yield return enterCommand; + if (item is Pawn p) + { + pawnsInPortal.Add(p); + } + } + + foreach(Pawn p in pawnsInPortal) + { + p.DeSpawn(); + GenSpawn.Spawn(p, CellFinder.RandomClosewalkCellNear(linkedPortalA.Position, linkedPortalA.Map, 5), linkedPortalA.Map, WipeMode.Vanish); + GetDirectlyHeldThings().Remove(p); + } + + // Transfer items + GetDirectlyHeldThings().TryDropAll(linkedPortalA.Position, linkedPortalA.Map, ThingPlaceMode.Near); } + + EffecterDefOf.Skip_Exit.Spawn(pawn.Position, pawn.Map); } public override string GetInspectString() @@ -73,9 +118,5 @@ namespace ArachnaeSwarm return text; } - private void BeginTeleportation() - { - Find.WindowStack.Add(new Dialog_WormholeTransfer(this, this.LinkedPortal)); - } } } \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Wormhole/Dialog_WormholeTransfer.cs b/Source/ArachnaeSwarm/Wormhole/Dialog_WormholeTransfer.cs deleted file mode 100644 index 1eeeba8..0000000 --- a/Source/ArachnaeSwarm/Wormhole/Dialog_WormholeTransfer.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using RimWorld; -using RimWorld.Planet; -using UnityEngine; -using Verse; -using Verse.Sound; - -namespace ArachnaeSwarm -{ - public class Dialog_WormholeTransfer : Window - { - private enum Tab - { - Pawns, - Items - } - - private const float TitleRectHeight = 35f; - private const float BottomAreaHeight = 55f; - private readonly Vector2 BottomButtonSize = new Vector2(160f, 40f); - - private Building sourcePortal; // 通用源传送门 - private Building destinationPortal; // 通用目标传送门 - - private List transferables; - private TransferableOneWayWidget pawnsTransfer; - private TransferableOneWayWidget itemsTransfer; - private Tab tab; - - private static List tabsList = new List(); - - public override Vector2 InitialSize => new Vector2(1024f, UI.screenHeight); - protected override float Margin => 0f; - - public Dialog_WormholeTransfer(Building sourcePortal, Building destinationPortal) - { - this.sourcePortal = sourcePortal; - this.destinationPortal = destinationPortal; - forcePause = true; - absorbInputAroundWindow = true; - } - - public override void PostOpen() - { - base.PostOpen(); - CalculateAndRecacheTransferables(); - } - - public override void DoWindowContents(Rect inRect) - { - Rect rect = new Rect(0f, 0f, inRect.width, TitleRectHeight); - Text.Font = GameFont.Medium; - Text.Anchor = TextAnchor.MiddleCenter; - Widgets.Label(rect, "EnterWormhole".Translate()); - Text.Font = GameFont.Small; - Text.Anchor = TextAnchor.UpperLeft; - - tabsList.Clear(); - tabsList.Add(new TabRecord("PawnsTab".Translate(), () => tab = Tab.Pawns, tab == Tab.Pawns)); - tabsList.Add(new TabRecord("ItemsTab".Translate(), () => tab = Tab.Items, tab == Tab.Items)); - - inRect.yMin += 67f; - Widgets.DrawMenuSection(inRect); - TabDrawer.DrawTabs(inRect, tabsList); - inRect = inRect.ContractedBy(17f); - - Widgets.BeginGroup(inRect); - Rect rect2 = inRect.AtZero(); - DoBottomButtons(rect2); - Rect inRect2 = rect2; - inRect2.yMax -= 76f; - - bool anythingChanged = false; - switch (tab) - { - case Tab.Pawns: - pawnsTransfer.OnGUI(inRect2, out anythingChanged); - break; - case Tab.Items: - itemsTransfer.OnGUI(inRect2, out anythingChanged); - break; - } - if (anythingChanged) - { - // 可以添加一些计数或质量更新的逻辑 - } - Widgets.EndGroup(); - } - - private void DoBottomButtons(Rect rect) - { - float buttonY = rect.height - BottomAreaHeight + 17; - - if (Widgets.ButtonText(new Rect(rect.width / 2f - BottomButtonSize.x / 2f, buttonY, BottomButtonSize.x, BottomButtonSize.y), "ResetButton".Translate())) - { - SoundDefOf.Tick_Low.PlayOneShotOnCamera(); - CalculateAndRecacheTransferables(); - } - if (Widgets.ButtonText(new Rect(0f, buttonY, BottomButtonSize.x, BottomButtonSize.y), "CancelButton".Translate())) - { - Close(); - } - if (Widgets.ButtonText(new Rect(rect.width - BottomButtonSize.x, buttonY, BottomButtonSize.x, BottomButtonSize.y), "AcceptButton".Translate())) - { - if (TryAccept()) - { - SoundDefOf.Tick_High.PlayOneShotOnCamera(); - Close(doCloseSound: false); - } - } - } - - private bool TryAccept() - { - List toTransfer = transferables.Where(x => x.CountToTransfer > 0).ToList(); - if (!toTransfer.Any()) - { - Messages.Message("NothingToTransfer".Translate(), MessageTypeDefOf.RejectInput); - return false; - } - - foreach (var trans in toTransfer) - { - // 传送逻辑 - var things = trans.things.Take(trans.CountToTransfer).ToList(); - foreach (var thing in things) - { - Pawn pawn = thing as Pawn; - if (pawn != null) - { - pawn.DeSpawn(); - GenSpawn.Spawn(pawn, CellFinder.RandomClosewalkCellNear(destinationPortal.Position, destinationPortal.Map, 5), destinationPortal.Map, WipeMode.Vanish); - } - else - { - thing.DeSpawn(); - GenSpawn.Spawn(thing, CellFinder.RandomClosewalkCellNear(destinationPortal.Position, destinationPortal.Map, 5), destinationPortal.Map, WipeMode.Vanish); - } - } - } - - // 切换视角 - if (toTransfer.Any(x => x.ThingDef.category == ThingCategory.Pawn)) - { - var firstPawn = toTransfer.First(x => x.ThingDef.category == ThingCategory.Pawn).AnyThing as Pawn; - CameraJumper.TryJump(new GlobalTargetInfo(destinationPortal.Position, destinationPortal.Map)); - if (firstPawn != null) - { - CameraJumper.TrySelect(firstPawn); - } - } - - Messages.Message("WormholeTransferComplete".Translate(), MessageTypeDefOf.PositiveEvent); - return true; - } - - private void CalculateAndRecacheTransferables() - { - transferables = new List(); - AddPawnsToTransferables(); - AddItemsToTransferables(); - - pawnsTransfer = new TransferableOneWayWidget(transferables.Where(x => x.ThingDef.category == ThingCategory.Pawn), null, null, "TransferableCount".Translate(), - drawMass: true, - ignorePawnInventoryMass: IgnorePawnsInventoryMode.Ignore, - includePawnsMassInMassUsage: true, - availableMassGetter: () => float.MaxValue, // 无质量限制 - extraHeaderSpace: 0f, - ignoreSpawnedCorpseGearAndInventoryMass: false, - tile: sourcePortal.Map.Tile, - drawMarketValue: true, - drawEquippedWeapon: true); - - itemsTransfer = new TransferableOneWayWidget(transferables.Where(x => x.ThingDef.category != ThingCategory.Pawn), null, null, "TransferableCount".Translate(), - drawMass: true, - ignorePawnInventoryMass: IgnorePawnsInventoryMode.Ignore, - includePawnsMassInMassUsage: true, - availableMassGetter: () => float.MaxValue, - extraHeaderSpace: 0f, - ignoreSpawnedCorpseGearAndInventoryMass: false, - tile: sourcePortal.Map.Tile, - drawMarketValue: true); - } - - private void AddToTransferables(Thing t) - { - var transferable = TransferableUtility.TransferableMatching(t, transferables, TransferAsOneMode.PodsOrCaravanPacking); - if (transferable == null) - { - transferable = new TransferableOneWay(); - transferables.Add(transferable); - } - transferable.things.Add(t); - } - - private void AddPawnsToTransferables() - { - foreach (Pawn p in sourcePortal.Map.mapPawns.AllPawnsSpawned.Where(p => p.Faction == Faction.OfPlayer)) - { - AddToTransferables(p); - } - } - - private void AddItemsToTransferables() - { - foreach (Thing t in sourcePortal.Map.listerThings.AllThings.Where(t => t.def.category == ThingCategory.Item && t.def.EverHaulable && t.Position.IsValid && !t.Position.Fogged(t.Map))) - { - AddToTransferables(t); - } - } - } -} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/build.ps1 b/Source/ArachnaeSwarm/build.ps1 new file mode 100644 index 0000000..4fca6f6 --- /dev/null +++ b/Source/ArachnaeSwarm/build.ps1 @@ -0,0 +1,38 @@ +# Find the latest installed .NET SDK and build the project. +try { + Write-Host "Finding latest .NET SDK..." + $sdkList = dotnet --list-sdks + $latestSdk = $sdkList.Split([Environment]::NewLine) | Select-Object -Last 1 + + if ($null -eq $latestSdk -or $latestSdk -eq "") { + Write-Host "No .NET SDKs found. Please install the .NET SDK." + exit 1 + } + + $sdkVersion = ($latestSdk.Split(' '))[0] + Write-Host "Using .NET SDK version: $sdkVersion" + + # Since the project is .NET Framework 4.8, msbuild is more suitable. + # We need to find msbuild.exe location. + # A common path for Visual Studio's MSBuild: + $vsWherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if(Test-Path $vsWherePath) { + $vsPath = & $vsWherePath -latest -property installationPath + $msBuildPath = Join-Path $vsPath "MSBuild\Current\Bin\MSBuild.exe" + if(Test-Path $msBuildPath) { + Write-Host "Found MSBuild at: $msBuildPath" + & $msBuildPath "ArachnaeSwarm.sln" /t:Rebuild /p:Configuration=Debug + } else { + Write-Host "MSBuild.exe not found at the expected path. Falling back to dotnet build." + dotnet build "ArachnaeSwarm.sln" + } + } else { + Write-Host "vswhere.exe not found. Falling back to dotnet build." + dotnet build "ArachnaeSwarm.sln" + } + +} catch { + Write-Host "An error occurred during the build process." + Write-Host $_ + exit 1 +}