123 lines
4.3 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|