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(); public override bool TryMakePreToilReservations(bool errorOnFailed) { return true; } protected override IEnumerable 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(); 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(); 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(); if (initiatableComp != null) { initiatableComp.initiationDelayTicksOverride = initiationDelayTicks; } } } }