rjw-whoring/1.4/Source/Mod/JobDrivers/JobDriver_WhoreInvitingVisitors.cs
2022-10-26 13:25:26 +03:00

172 lines
No EOL
7.6 KiB
C#

using System.Collections.Generic;
using RimWorld;
using rjw;
using Verse;
using Verse.AI;
namespace rjwwhoring
{
public class JobDriver_WhoreInvitingVisitors : JobDriver
{
// List of jobs that can be interrupted by whores.
public static readonly List<JobDef> allowedJobs = new List<JobDef> { null, JobDefOf.Wait_Wander, JobDefOf.GotoWander, JobDefOf.Clean, JobDefOf.ClearSnow,
JobDefOf.CutPlant, JobDefOf.HaulToCell, JobDefOf.Deconstruct, JobDefOf.Harvest, JobDefOf.LayDown, JobDefOf.Research, JobDefOf.SmoothFloor, JobDefOf.SmoothWall,
JobDefOf.SocialRelax, JobDefOf.StandAndBeSociallyActive, JobDefOf.RemoveApparel, JobDefOf.Strip, JobDefOf.Tame, JobDefOf.Wait, JobDefOf.Wear, JobDefOf.FixBrokenDownBuilding,
JobDefOf.FillFermentingBarrel, JobDefOf.DoBill, JobDefOf.Sow, JobDefOf.Shear, JobDefOf.BuildRoof, JobDefOf.DeliverFood, JobDefOf.HaulToContainer, JobDefOf.Hunt, JobDefOf.Mine,
JobDefOf.OperateDeepDrill, JobDefOf.OperateScanner, JobDefOf.RearmTurret, JobDefOf.Refuel, JobDefOf.RefuelAtomic, JobDefOf.RemoveFloor, JobDefOf.RemoveRoof, JobDefOf.Repair,
JobDefOf.TakeBeerOutOfFermentingBarrel, JobDefOf.Train, JobDefOf.Uninstall, xxx.Masturbate};
public bool successfulPass = true;
private Pawn Whore => GetActor();
private Pawn TargetPawn => TargetThingA as Pawn;
private Building_Bed TargetBed => TargetThingB as Building_Bed;
private readonly TargetIndex TargetPawnIndex = TargetIndex.A;
private readonly TargetIndex TargetBedIndex = TargetIndex.B;
private bool DoesTargetPawnAcceptAdvance()
{
if (WhoringBase.DebugWhoring) ModLog.Message($"JobDriver_InvitingVisitors::DoesTargetPawnAcceptAdvance() - {xxx.get_pawnname(TargetPawn)}");
//if (RJWSettings.WildMode) return true;
if (PawnUtility.EnemiesAreNearby(TargetPawn))
{
if (WhoringBase.DebugWhoring) ModLog.Message($" fail - enemy near");
return false;
}
if (!allowedJobs.Contains(TargetPawn.jobs.curJob.def))
{
if (WhoringBase.DebugWhoring) ModLog.Message($" fail - not allowed job");
return false;
}
if (WhoringBase.DebugWhoring)
{
ModLog.Message("Will try hookup " + WhoringHelper.WillPawnTryHookup(TargetPawn));
ModLog.Message("Is whore appealing " + WhoringHelper.IsHookupAppealing(TargetPawn, Whore));
ModLog.Message("Can afford whore " + WhoringHelper.CanAfford(TargetPawn, Whore));
ModLog.Message("Need sex " + (xxx.need_some_sex(TargetPawn) >= 1));
}
if (WhoringHelper.WillPawnTryHookup(TargetPawn) && WhoringHelper.IsHookupAppealing(TargetPawn, Whore) && WhoringHelper.CanAfford(TargetPawn, Whore) && xxx.need_some_sex(TargetPawn) >= 1f)
{
if (!Whore.IsPrisoner)
Whore.skills.Learn(SkillDefOf.Social, 1.2f);
return true;
}
return false;
}
public override bool TryMakePreToilReservations(bool errorOnFailed) => true;
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedOrNull(TargetPawnIndex);
this.FailOnDespawnedNullOrForbidden(TargetBedIndex);
this.FailOn(() => Whore is null || !WhoreBed_Utility.CanUseForWhoring(Whore, TargetBed));//|| !Whore.CanReserve(TargetPawn)
this.FailOn(() => pawn.Drafted);
if (!Whore.IsPrisoner)
{
yield return Toils_Goto.GotoThing(TargetPawnIndex, PathEndMode.Touch);
Toil TryItOn = new Toil();
TryItOn.AddFailCondition(() => !xxx.IsTargetPawnOkay(TargetPawn));
TryItOn.defaultCompleteMode = ToilCompleteMode.Delay;
TryItOn.initAction = delegate
{
//ModLog.Message("JobDriver_InvitingVisitors::MakeNewToils - TryItOn - initAction is called");
Whore.jobs.curDriver.ticksLeftThisToil = 50;
FleckMaker.ThrowMetaIcon(Whore.Position, Whore.Map, FleckDefOf.Heart);
};
yield return TryItOn;
}
Toil AwaitResponse = new Toil();
AwaitResponse.defaultCompleteMode = ToilCompleteMode.Delay;
AwaitResponse.defaultDuration = 10;
AwaitResponse.initAction = delegate
{
List<RulePackDef> extraSentencePacks = new List<RulePackDef>();
successfulPass = DoesTargetPawnAcceptAdvance();
//ModLog.Message("JobDriver_InvitingVisitors::MakeNewToils - AwaitResponse - initAction is called");
if (successfulPass)
{
FleckMaker.ThrowMetaIcon(TargetPawn.Position, TargetPawn.Map, FleckDefOf.Heart);
TargetPawn.jobs.EndCurrentJob(JobCondition.Incompletable);
if (xxx.RomanceDiversifiedIsActive)
{
extraSentencePacks.Add(RulePackDef.Named("HookupSucceeded"));
}
if (Whore.health.HasHediffsNeedingTend())
{
successfulPass = false;
string key = "RJW_VisitorSickWhore";
string text = key.Translate(TargetPawn.LabelIndefinite(), Whore.LabelIndefinite()).CapitalizeFirst();
Messages.Message(text, Whore, MessageTypeDefOf.TaskCompletion);
}
else
{
string key = "RJW_VisitorAcceptWhore";
if (Whore.IsPrisoner)
{
key = "RJW_VisitorSolicitWhore";
}
string text = key.Translate(TargetPawn.LabelIndefinite(), Whore.LabelIndefinite()).CapitalizeFirst();
Messages.Message(text, TargetPawn, MessageTypeDefOf.TaskCompletion);
}
}
if (!successfulPass)
{
// remove bed reservation
TargetBed.UnreserveForWhoring();
FleckMaker.ThrowMetaIcon(TargetPawn.Position, TargetPawn.Map, FleckDefOf.IncapIcon);
TargetPawn.needs.mood.thoughts.memories.TryGainMemory(
TargetPawn.Faction == Whore.Faction
? ThoughtDef.Named("RJWTurnedDownWhore")
: ThoughtDef.Named("RJWFailedSolicitation"), Whore);
if (xxx.RomanceDiversifiedIsActive)
{
Whore.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("RebuffedMyHookupAttempt"), TargetPawn);
TargetPawn.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("FailedHookupAttemptOnMe"), Whore);
extraSentencePacks.Add(RulePackDef.Named("HookupFailed"));
}
//Disabled rejection notifications
//Messages.Message("RJW_VisitorRejectWhore".Translate(new object[] { xxx.get_pawnname(TargetPawn), xxx.get_pawnname(Whore) }), TargetPawn, MessageTypeDefOf.SilentInput);
}
if (xxx.RomanceDiversifiedIsActive)
{
Find.PlayLog.Add(new PlayLogEntry_Interaction(DefDatabase<InteractionDef>.GetNamed("TriedHookupWith"), pawn, TargetPawn, extraSentencePacks));
}
//Log.Message("[RJW] AwaitResponse initAction - successfulPass: " + successfulPass.ToString());
};
yield return AwaitResponse;
Toil BothGoToBed = new Toil();
BothGoToBed.AddFailCondition(() => !successfulPass || !WhoreBed_Utility.CanUseForWhoring(Whore, TargetBed));
BothGoToBed.defaultCompleteMode = ToilCompleteMode.Instant;
BothGoToBed.initAction = delegate
{
//ModLog.Message("JobDriver_InvitingVisitors::MakeNewToils - BothGoToBed - initAction is called0");
if (!successfulPass) return;
if (!WhoreBed_Utility.CanUseForWhoring(Whore, TargetBed) && Whore.CanReserve(TargetPawn, 1, 0))
{
//ModLog.Message("JobDriver_InvitingVisitors::MakeNewToils - BothGoToBed - cannot use the whore bed");
return;
}
//ModLog.Message("JobDriver_InvitingVisitors::MakeNewToils - BothGoToBed - initAction is called1");
TargetBed.ReserveForWhoring(Whore, 1800);//is 1800 ticks long enough to go to the bed (until next reservation is made?)
Whore.jobs.jobQueue.EnqueueFirst(JobMaker.MakeJob(xxx.whore_is_serving_visitors, TargetPawn, TargetBed));
//TargetPawn.jobs.jobQueue.EnqueueFirst(JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("WhoreIsServingVisitors"), Whore, TargetBed, (TargetBed.MaxAssignedPawnsCount>1)?TargetBed.GetSleepingSlotPos(1): TargetBed.)), null);
Whore.jobs.curDriver.EndJobWith(JobCondition.InterruptOptional);
//TargetPawn.jobs.curDriver.EndJobWith(JobCondition.InterruptOptional);
};
yield return BothGoToBed;
}
}
}