LordJob and LordToil Fininished

Succubus will not when spawned rape target, and afterward will follow target. Succubus will target someone else at random or when target is unreachable or sleeping
This commit is contained in:
Shabakur 2023-01-16 17:16:25 +01:00
parent 84c4587a18
commit 7958f021b9
11 changed files with 270 additions and 4 deletions

Binary file not shown.

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<DutyDef>
<defName>rjw_genes_flirt</defName>
<thinkNode Class="ThinkNode_Priority">
<subNodes>
<!-- first fulfill needs and joy -->
<li Class="ThinkNode_Tagger">
<tagToGive>SatisfyingNeeds</tagToGive>
<subNodes>
<li Class="ThinkNode_PrioritySorter">
<subNodes>
<li Class="JobGiver_GetFood"/>
<li Class="JobGiver_GetRest"/>
<li Class="JobGiver_SatisfyChemicalNeed"/>
<li Class="JobGiver_SatifyChemicalDependency" MayRequire="Ludeon.RimWorld.Biotech" />
<li Class="ThinkNode_Priority_GetJoy">
<subNodes>
<li Class="JobGiver_GetJoy"/>
</subNodes>
</li>
</subNodes>
</li>
</subNodes>
</li>
<!-- switch target randomly or when target is unreachable/sleeping (similar to insults) -->
<li Class="RJW_Genes.ThinkNode_ConditionalCannotInteract">
<subNodes>
<li Class="RJW_Genes.ThinkNode_NewFlirtTarget" />
</subNodes>
</li>
<li Class="ThinkNode_ConditionalRandom">
<chance>0.05</chance>
<subNodes>
<li Class="RJW_Genes.ThinkNode_NewFlirtTarget" />
</subNodes>
</li>
<!--Go to target pawn-->
<li Class="JobGiver_AIFollowEscortee" />
<!--If fertilin or sex_need is really low, try become more forceful (attempt rape)-->
<!--Flirt with target pawn and try hookup with them, increases sexneed in target pawn, maybe flirt has custom text-->
<li Class="JobGiver_WanderNearDutyLocation">
<wanderRadius>5</wanderRadius>
</li>
</subNodes>
</thinkNode>
</DutyDef>
</Defs>

View File

@ -7,4 +7,9 @@
<AlertLowFertilin>Low fertilin</AlertLowFertilin>
<AlertLowFertilinDesc>A colonist has low fertilin. At this point they are becoming desperate enough to consider rape and bestiality to obtain fertilin (if they didn't already). At zero fertilin they will lose all sense and start raping randomly</AlertLowFertilinDesc>
<!--Succubus Events-->
<SuccubusLeaving>The succubus has fed enough on your colonists and will now leave.</SuccubusLeaving>
</LanguageData>

View File

@ -1,6 +1,6 @@
using RimWorld;
using Verse;
using Verse.AI;
namespace RJW_Genes
{
[DefOf]
@ -92,6 +92,7 @@ namespace RJW_Genes
public static readonly XenotypeDef rjw_genes_succubus;
//Other Defs
public static readonly DutyDef rjw_genes_flirt;
}
}

View File

@ -4,6 +4,8 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;
using Verse.AI.Group;
using RimWorld;
using rjw;
namespace RJW_Genes
@ -55,7 +57,20 @@ namespace RJW_Genes
DevelopmentalStage.Adult, null, null, null, false));
succubus.SetFaction(null, null);
GenSpawn.Spawn(succubus, loc, map, WipeMode.Vanish);
//Set succubus behaviour
List<Pawn> list = new List<Pawn> {succubus};
LordMaker.MakeNewLord(parms.faction, this.CreateLordJob(parms, succubus, victim), map, list);
//Make succubus rape victim.
if (RJWSettings.rape_enabled)
{
succubus.pather.StopDead();
succubus.jobs.StopAll();
Job newJob = JobMaker.MakeJob(xxx.RapeRandom, victim);
succubus.jobs.StartJob(newJob, JobCondition.InterruptForced, null, false, true, null, null, false, false, null, false, true);
}
//Broken for now
//Sends letter
//string value = succubus.DevelopmentalStage.Child() ? "FeralChild".Translate().ToString() : succubus.KindLabel;
@ -64,7 +79,7 @@ namespace RJW_Genes
//TaggedString baseLetterText = this.def.letterText.Formatted(succubus.NameShortColored, value2, succubus.Named("PAWN")).AdjustedFor(succubus, "PAWN", true).CapitalizeFirst();
//PawnRelationUtility.TryAppendRelationsWithColonistsInfo(ref baseLetterText, ref baseLetterLabel, succubus);
//base.SendStandardLetter(baseLetterLabel, baseLetterText, this.def.letterDef, parms, succubus, Array.Empty<NamedArgument>());
return true;
}
@ -84,5 +99,10 @@ namespace RJW_Genes
{
return Find.FactionManager.TryGetRandomNonColonyHumanlikeFaction(out formerFaction, false, true, TechLevel.Undefined, false);
}
protected virtual LordJob_SuccubusVisit CreateLordJob(IncidentParms parms, Pawn succubus, Pawn target)
{
return new LordJob_SuccubusVisit(target);
}
}
}

View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;
using Verse.AI.Group;
using RimWorld;
namespace RJW_Genes
{
//Based on LordJob_VisitColony
public class LordJob_SuccubusVisit : LordJob
{
public LordJob_SuccubusVisit(Pawn target)
{
this.target = target;
}
//
//Stategraph has lordtoils which say what a pawn should be doing
//Transitions say when active lordtoil for pawn should change
//
public override StateGraph CreateGraph()
{
StateGraph stateGraph = new StateGraph();
//Flirt
LordToil_Flirt lordToil_Flirt = new LordToil_Flirt(this.target, 7f);
stateGraph.AddToil(lordToil_Flirt);
stateGraph.StartingToil = lordToil_Flirt;
//Leave
LordToil_ExitMapRandom lordToil_ExitMapRandom = new LordToil_ExitMapRandom();
stateGraph.AddToil(lordToil_ExitMapRandom);
LordToil_ExitMapAndDefendSelf lordToil_ExitMapAndDefendSelf = new LordToil_ExitMapAndDefendSelf();
stateGraph.AddToil(lordToil_ExitMapAndDefendSelf);
//Leave after some time
Transition transition1 = new Transition(lordToil_Flirt, lordToil_ExitMapRandom, false, true);
int tickLimit;
if (this.durationTicks != null)
{
tickLimit = this.durationTicks.Value;
}
else
{
tickLimit = Rand.Range(60000, 180000); //~1-3 days
}
transition1.AddTrigger(new Trigger_TicksPassed(tickLimit));
transition1.AddPreAction(new TransitionAction_Message("SuccubusLeaving".Translate(), null, 1f));
stateGraph.AddTransition(transition1);
//If they become hostile
Transition transition3 = new Transition(lordToil_Flirt, lordToil_ExitMapAndDefendSelf, false, true);
transition3.AddSource(lordToil_ExitMapRandom); //Not sure what this does
transition3.AddTrigger(new Trigger_BecamePlayerEnemy());
transition3.AddTrigger(new Trigger_PawnKilled());
transition3.AddPostAction(new TransitionAction_EndAllJobs());
stateGraph.AddTransition(transition3, false);
Transition transition4 = new Transition(lordToil_ExitMapRandom, lordToil_ExitMapAndDefendSelf, false, true);
transition4.AddSource(lordToil_Flirt); //Not sure what this does
transition4.AddTrigger(new Trigger_PawnHarmed(1f, true, Faction.OfPlayer));
stateGraph.AddTransition(transition4, false);
return stateGraph;
}
//add toggleable gizmo to allow playes to have colonists sex the succubus into joining your colony
//comfort pawn? cooldown?
public override IEnumerable<Gizmo> GetPawnGizmos(Pawn p)
{
return base.GetPawnGizmos(p);
}
public override void ExposeData()
{
Scribe_Values.Look<int?>(ref this.durationTicks, "durationTicks", null, false);
}
public Pawn target;
private int? durationTicks;
public StateGraph exitSubgraph;
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;
using Verse.AI.Group;
using RimWorld;
namespace RJW_Genes
{
//Based on LordToil_EscortPawn
public class LordToil_Flirt : LordToil
{
public LordToil_Flirt(Pawn victim, float followRadius)
{
this.victim = victim;
this.followRadius = followRadius;
}
public override void UpdateAllDuties()
{
for (int i = 0; i < this.lord.ownedPawns.Count; i++)
{
PawnDuty duty = new PawnDuty(GeneDefOf.rjw_genes_flirt, this.victim, this.followRadius);
this.lord.ownedPawns[i].mindState.duty = duty;
}
}
public Pawn victim;
public float followRadius;
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;
namespace RJW_Genes
{
public class ThinkNode_ConditionalCannotInteract : ThinkNode_Conditional
{
protected override bool Satisfied(Pawn pawn)
{
Pawn target = pawn.mindState.duty.focus.Pawn;
if (target == null)
{
return true;
}
return (target.jobs != null && target.jobs.curDriver.asleep) || !pawn.CanReach(target, PathEndMode.InteractionCell, Danger.Deadly);
}
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using Verse.AI;
using rjw;
namespace RJW_Genes
{
public class ThinkNode_NewFlirtTarget : ThinkNode
{
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
{
Pawn new_target = ValidTargets(pawn, pawn.Map).RandomElement();
if (new_target != null)
{
pawn.mindState.duty.focus = new_target;
}
return ThinkResult.NoJob;
}
private IEnumerable<Pawn> ValidTargets(Pawn pawn, Map map)
{
foreach (Pawn pawn2 in map.mapPawns.FreeAdultColonistsSpawned)
{
if (pawn != null && pawn2 != null && pawn != pawn2 && !pawn2.jobs.curDriver.asleep && SexAppraiser.would_fuck(pawn, pawn2) > 0.1f)
{
yield return pawn2;
}
}
//IEnumerator<Pawn> enumerator = null;
yield break;
}
}
}

View File

@ -133,10 +133,14 @@
<Compile Include="Genes\Life_Force\JobDrivers\JobDriver_SexOnSpotReceiver.cs" />
<Compile Include="Genes\Life_Force\JobDrivers\JobDriver_SexOnSpot.cs" />
<Compile Include="Genes\Life_Force\JobDrivers\JobDriver_Seduced.cs" />
<Compile Include="Genes\Life_Force\LordJob_SuccubusVisit.cs" />
<Compile Include="Genes\Life_Force\LordToil_Flirt.cs" />
<Compile Include="Genes\Life_Force\Patch_SexTicks_ChangePsyfocus.cs" />
<Compile Include="Genes\Life_Force\ThinkNode_ConditionalCannotInteract.cs" />
<Compile Include="Genes\Life_Force\ThinkNode_ConditionalLowLifeForce.cs" />
<Compile Include="Genes\Life_Force\ThinkNode_ConditionalCritcalLifeForce.cs" />
<Compile Include="Genes\Life_Force\JobGiver_GetLifeForce.cs" />
<Compile Include="Genes\Life_Force\ThinkNode_NewFlirtTarget.cs" />
<Compile Include="Genes\Special\Patch_AgeDrain.cs" />
<Compile Include="Interactions\CompAbility_SexInteractionRequirements.cs" />
<Compile Include="Genes\Life_Force\Abilities\CompAbilityEffect_PussyHeal.cs" />