feat: 添加区域传送功能,模仿逆重飞船机制

This commit is contained in:
2025-12-07 18:24:21 +08:00
parent 6db39c8352
commit 1607946af8
10 changed files with 353 additions and 218 deletions

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using UnityEngine;
using Verse;
@@ -9,14 +10,18 @@ namespace WulaFallenEmpire
{
private CompMapTeleporter teleporter;
private Map targetMap;
private WULA_TeleportLandingMarker marker;
private List<Thing> thingsToTeleport = new List<Thing>();
private IntVec3 sourceCenter;
public override string Label => "WULA_SelectArrivalPoint".Translate();
public override string Desc => "WULA_SelectArrivalPointDesc".Translate();
public Designator_TeleportArrival(CompMapTeleporter teleporter, Map targetMap)
public Designator_TeleportArrival(CompMapTeleporter teleporter, Map targetMap, WULA_TeleportLandingMarker marker = null)
{
this.teleporter = teleporter;
this.targetMap = targetMap;
this.marker = marker;
this.useMouseIcon = true;
this.soundDragSustain = SoundDefOf.Designate_DragStandard;
this.soundDragChanged = SoundDefOf.Designate_DragStandard_Changed;
@@ -27,9 +32,9 @@ namespace WulaFallenEmpire
{
if (!loc.InBounds(targetMap)) return false;
// 检查半径区域是否有效
float radius = teleporter.Props.radius;
foreach (IntVec3 cell in GenRadial.RadialCellsAround(loc, radius, true))
// 检查区域是否有效
CellRect rect = CellRect.CenteredOn(loc, teleporter.Props.areaSize.x, teleporter.Props.areaSize.z);
foreach (IntVec3 cell in rect)
{
if (!cell.InBounds(targetMap)) return "WULA_OutOfBounds".Translate();
@@ -71,19 +76,92 @@ namespace WulaFallenEmpire
public override void DesignateSingleCell(IntVec3 c)
{
teleporter.ConfirmArrival(c, targetMap);
Find.DesignatorManager.Deselect();
if (marker != null)
{
marker.Position = c;
Find.DesignatorManager.Deselect();
Find.Selector.ClearSelection();
Find.Selector.Select(marker);
}
else
{
teleporter.ConfirmArrival(c, targetMap);
Find.DesignatorManager.Deselect();
}
}
public override void Selected()
{
GenDraw.DrawRadiusRing(UI.MouseCell(), teleporter.Props.radius);
CacheThings();
DrawRect();
}
public override void SelectedUpdate()
{
DrawRect();
DrawGhosts();
}
public override void DrawMouseAttachments()
{
base.DrawMouseAttachments();
GenDraw.DrawRadiusRing(UI.MouseCell(), teleporter.Props.radius);
DrawRect();
}
private void DrawRect()
{
GenDraw.DrawFieldEdges(CellRect.CenteredOn(UI.MouseCell(), teleporter.Props.areaSize.x, teleporter.Props.areaSize.z).Cells.ToList());
}
private void CacheThings()
{
thingsToTeleport.Clear();
if (teleporter.parent == null || teleporter.parent.Map == null) return;
sourceCenter = teleporter.parent.Position;
Map sourceMap = teleporter.parent.Map;
CellRect rect = CellRect.CenteredOn(sourceCenter, teleporter.Props.areaSize.x, teleporter.Props.areaSize.z);
foreach (IntVec3 cell in rect)
{
if (!cell.InBounds(sourceMap)) continue;
foreach (Thing t in sourceMap.thingGrid.ThingsListAt(cell))
{
if (t.def.category == ThingCategory.Building || t.def.category == ThingCategory.Item || t.def.category == ThingCategory.Pawn)
{
if (t != teleporter.parent) thingsToTeleport.Add(t);
}
}
}
// 添加自身
thingsToTeleport.Add(teleporter.parent);
}
private void DrawGhosts()
{
IntVec3 mouseCell = UI.MouseCell();
if (!mouseCell.InBounds(targetMap)) return;
foreach (Thing t in thingsToTeleport)
{
if (t == null || t.Destroyed) continue;
if (t.Graphic == null) continue;
IntVec3 relativePos = t.Position - sourceCenter;
IntVec3 drawPos = mouseCell + relativePos;
if (drawPos.InBounds(targetMap))
{
try
{
GhostUtility.GhostGraphicFor(t.Graphic, t.def, Color.white).DrawFromDef(drawPos.ToVector3ShiftedWithAltitude(AltitudeLayer.Blueprint), t.Rotation, t.def);
}
catch
{
// 忽略绘制错误防止UI崩溃
}
}
}
}
}
}