static bool Prefix(ref Pawn __instance, DamageInfo?dinfo, Verse.Hediff exactCulprit = null) { bool hasBondageBed = false;//没有被束缚床束缚 for (int i = 0; i < __instance.health.hediffSet.hediffs.Count; i++) { if (__instance.health.hediffSet.hediffs[i].def == SR.DA.Hediff.HediffDefOf.SR_Hediff_BondageBed) { hasBondageBed = true; break; } } //如果已经被束缚 if (hasBondageBed) { Building_BondageBed bbb = (Building_BondageBed)__instance.CurrentBed();//获取当前躺着的束缚床 CompRemoveEffectBondageBed crebb = bbb.GetComp <CompRemoveEffectBondageBed>(); if (crebb != null) { crebb.DoEffect(__instance); //解除束缚 return(false); //解除成功是会通知Pawn_HealthTracker重新检测死亡性,所以本次跳过,否则会多次kill } } return(true); }
/// <summary> /// 作用效果 束缚 /// </summary> /// <param name="usedBy"></param> public override void DoEffect(Pawn usedBy) { base.DoEffect(usedBy); Building_BondageBed building_BondageBed = (Building_BondageBed)parent; HediffDef hediffBed = Hediff.HediffDefOf.SR_Hediff_BondageBed; List <Verse.Hediff> .Enumerator enumerator; enumerator = (from x in usedBy.health.hediffSet.hediffs where x.def == hediffBed select x).ToList().GetEnumerator();//获取小人身上所有hediffBed while (enumerator.MoveNext()) { Verse.Hediff h = enumerator.Current;//当前的hediffBed usedBy.health.RemoveHediff(h); } building_BondageBed.RemoveOccupant(); }
/// <summary> /// 行为过程 /// </summary> /// <returns></returns> protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); this.FailOnDestroyedOrNull(TargetIndex.B); this.FailOnAggroMentalStateAndHostile(TargetIndex.B); //B精神不正常 yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch)); //走到囚犯身边 yield return(Toils_Haul.StartCarryThing(TargetIndex.B, false, false, false)); //搬运囚犯 yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnForbidden(TargetIndex.A)); //走到dark家具旁边 Pawn prisoner = (Pawn)Target; //捆绑操作 if (!prisoner.Dead) { yield return(Toils_General.WaitWith(TargetIndex.A, 60, true, true)); //交互1秒 //接下来的工作中包含了另一个job laydown,以及床,所以要释放床给laydown使用 yield return(Toils_Reserve.Release(TargetIndex.A)); yield return(new Toil { initAction = delegate() { //床没坏 if (!Thing.Destroyed) { pawn.carryTracker.TryDropCarriedThing(Thing.Position, ThingPlaceMode.Direct, out Verse.Thing thing, null); //把囚犯扔下去 Building_BondageBed bb = (Building_BondageBed)Thing ?? throw new System.Exception("cant find Building_BondageBed"); bb.SetOccupant(prisoner); //设置拥有者 一定要在notify之前 prisoner.jobs.Notify_TuckedIntoBed(bb); //小人被扔到床上 } else { pawn.jobs.EndCurrentJob(JobCondition.Incompletable);//床毁了 不能扔床上 } }, defaultCompleteMode = ToilCompleteMode.Instant });
/// <summary> /// 选项菜单 /// </summary> /// <param name="pawn"></param> /// <returns></returns> public override IEnumerable <FloatMenuOption> CompFloatMenuOptions(Pawn pawn) { Building_BondageBed bbb = parent as Building_BondageBed; if (bbb == null) { yield break; } //地图不存在 if (pawn.Map == null || pawn.Map != Find.CurrentMap) { yield break; } //无法接触床 if (!pawn.CanReach(this.parent, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)) { yield return(new FloatMenuOption(this.FloatMenuOptionLabel(pawn) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } //无法保留 //else if (!pawn.CanReserve(this.parent, 1, -1, null, false)) //{ // yield return new FloatMenuOption(this.FloatMenuOptionLabel(pawn) + " (" + "Reserved".Translate() + ")", null, MenuOptionPriority.DisabledOption, null, null, 0f, null, null); //} //无法操作 else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { yield return(new FloatMenuOption(this.FloatMenuOptionLabel(pawn) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } //监管工作被禁用 else if (pawn.WorkTagIsDisabled(WorkTypeDefOf.Warden.workTags)) { yield return(new FloatMenuOption(this.FloatMenuOptionLabel(pawn) + " (" + "SR_Forbid".Translate() + ")", null, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } //存在使用者 else if (bbb.occupant != null) { //囚犯被使用中 if (!pawn.CanReserve(bbb.occupant, 1, -1, null, false)) { yield return(new FloatMenuOption(this.FloatMenuOptionLabel(bbb.occupant) + " (" + "SR_Reserved".Translate() + ")", null, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } //解除束缚 else { Action action = delegate() { TryReleasePrisoner(pawn, bbb.occupant); }; string str = TranslatorFormattedStringExtensions.Translate("SR_Release_BondageBed", bbb.occupant.Label); yield return(new FloatMenuOption(str, action, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } } //不存在使用者 else { bool hasPrisoner = false; foreach (Pawn prisoner in pawn.Map.mapPawns.AllPawns) { //存在可用的囚犯 if (prisoner != pawn && prisoner.Spawned && prisoner.IsPrisonerOfColony) { hasPrisoner = true; //囚犯被使用中 if (!pawn.CanReserve(prisoner, 1, -1, null, false)) { yield return(new FloatMenuOption(this.FloatMenuOptionLabel(prisoner) + " (" + "SR_Reserved".Translate(prisoner.Label) + ")", null, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } //束缚囚犯 else { Action action = delegate() { TryStartUseJob(pawn, prisoner); }; string str = TranslatorFormattedStringExtensions.Translate("SR_BondageBed", pawn.Named(pawn.Name.ToString()), prisoner.Named(prisoner.Name.ToString())); yield return(new FloatMenuOption(str, action, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } } } //没有可用囚犯 if (!hasPrisoner) { yield return(new FloatMenuOption(this.FloatMenuOptionLabel(pawn) + " (" + "SR_NoPrisoner".Translate() + ")", null, MenuOptionPriority.DisabledOption, null, null, 0f, null, null)); } } }