Files
ArachnaeSwarm/Source/Documents/Milira_Fortress.cs
2025-09-11 18:38:21 +08:00

123 lines
4.3 KiB
C#

using AncotLibrary;
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using Verse;
using Verse.AI;
namespace Milira
{
public class JobDriver_FortressMode : JobDriver
{
private Thing thing;
public virtual ThingDef TurretDef => MiliraDefOf.Milian_Fortress;
public CompThingContainer CompThingContainer => thing?.TryGetComp<CompThingContainer>();
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return true;
}
protected override IEnumerable<Toil> MakeNewToils()
{
// 检查部署区域是否合适
Toil check = Toils_General.Do(() =>
{
foreach (var cell in GenRadial.RadialCellsAround(pawn.Position, 1.5f, false))
{
if (!cell.IsValid || !cell.InBounds(pawn.Map) || !cell.Walkable(pawn.Map) ||
!cell.GetEdifice(pawn.Map).DestroyedOrNull() || cell.Roofed(pawn.Map))
{
// 空间不足或有障碍,技能冷却重置并结束任务
var ability = pawn.abilities.abilities.FirstOrDefault(a => a.def.defName == "Milira_Fortress");
ability?.StartCooldown(0);
EndJobWith(JobCondition.Incompletable);
return;
}
}
});
yield return check;
// 部署炮台
yield return Toils_General.Do(DeployPod);
// 角色进入炮台
Toil enterPod = ToilMaker.MakeToil("EnterPod");
enterPod.initAction = () =>
{
if (thing == null)
{
EndJobWith(JobCondition.Incompletable);
return;
}
bool pawnSelected = Find.Selector.IsSelected(pawn);
// 角色从地图消失并进入炮台容器
if (pawn.DeSpawnOrDeselect())
{
CompThingContainer?.GetDirectlyHeldThings().TryAdd(pawn);
}
// 如果之前选中了角色,现在改为选中炮台
if (pawnSelected)
{
Find.Selector.Select(thing, playSound: false, forceDesignatorDeselect: false);
}
};
yield return enterPod;
}
private void DeployPod()
{
var carrierComp = pawn.TryGetComp<CompThingCarrier_Custom>();
if (carrierComp == null) return;
FleckMaker.Static(pawn.TrueCenter(), pawn.Map, FleckDefOf.Milian_FortressFormed);
thing = GenSpawn.Spawn(TurretDef, pawn.Position, pawn.Map);
thing.SetFaction(pawn.Faction);
bool hasRapidDeployment = ModsConfig.IsActive("Ancot.MilianModification") &&
pawn.health.hediffSet.GetFirstHediffOfDef(MiliraDefOf.MilianFitting_RapidDeployment) != null;
if (hasRapidDeployment)
{
SetHitPointAndRemoveResourceInCarrier(carrierComp, 200, 60);
}
else
{
SetHitPointAndRemoveResourceInCarrier(carrierComp, 1200, 600);
}
var containerMilian = thing.TryGetComp<CompThingContainer_Milian>();
if (containerMilian != null)
{
containerMilian.hitPointMax = thing.HitPoints;
}
}
private void SetHitPointAndRemoveResourceInCarrier(CompThingCarrier_Custom comp, int hitPoint, int initiationDelayTicks)
{
if (comp.IngredientCount > hitPoint + 400)
{
comp.TryRemoveThingInCarrier(hitPoint);
thing.HitPoints = hitPoint;
}
else
{
int halfResources = comp.IngredientCount / 2;
comp.TryRemoveThingInCarrier(halfResources);
thing.HitPoints = halfResources;
}
var initiatableComp = thing.TryGetComp<CompInitiatable>();
if (initiatableComp != null)
{
initiatableComp.initiationDelayTicksOverride = initiationDelayTicks;
}
}
}
}