Beispiel #1
0
        public override StateGraph CreateGraph()
        {
            StateGraph       stateGraph       = new StateGraph();
            LordToil_HangOut lordToil_HangOut = new LordToil_HangOut(new Pawn[] { initiator, recipient });

            stateGraph.AddToil(lordToil_HangOut);
            LordToil_End lordToil_End = new LordToil_End();

            stateGraph.AddToil(lordToil_End);
            Transition transition = new Transition(lordToil_HangOut, lordToil_End);

            transition.AddTrigger(new Trigger_TickCondition(() => this.ShouldBeCalledOff()));
            transition.AddTrigger(new Trigger_TickCondition(() => this.initiator.health.summaryHealth.SummaryHealthPercent < 1f || this.recipient.health.summaryHealth.SummaryHealthPercent < 1f));
            transition.AddTrigger(new Trigger_TickCondition(() => this.initiator.Drafted || this.recipient.Drafted));
            transition.AddTrigger(new Trigger_PawnLost());
            stateGraph.AddTransition(transition);
            this.timeoutTrigger = new Trigger_TicksPassed(Rand.RangeInclusive(GenDate.TicksPerHour * 4, GenDate.TicksPerHour * 6));
            Transition transition2 = new Transition(lordToil_HangOut, lordToil_End);

            transition2.AddTrigger(this.timeoutTrigger);
            transition2.AddPreAction(new TransitionAction_Custom((Action) delegate
            {
                this.Finished();
            }));
            stateGraph.AddTransition(transition2);
            return(stateGraph);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            LordToil_HangOut toil   = pawn.GetLord().CurLordToil as LordToil_HangOut;
            Pawn             friend = (pawn == toil.friends[0] ? toil.friends[1] : toil.friends[0]);

            if (friend == null)
            {
                return(null);
            }
            /* If they are partners, possibly send them to lay down together so they'll do lovin'. */
            if (LovePartnerRelationUtility.LovePartnerRelationExists(pawn, friend) && pawn.ownership.OwnedBed != null && !pawn.GetPosture().Laying() && (pawn.IsHashIntervalTick(GenDate.TicksPerHour) || friend.IsHashIntervalTick(GenDate.TicksPerHour)))
            {
                return(new Job(JobDefOf.LayDown, pawn.ownership.OwnedBed, GenDate.TicksPerHour));
            }
            /* If they have no joy activity assigned, or they've been doing it for 1-3 hours, give them a new one. */
            if (toil.hangOut == null || toil.ticksToNextJoy < Find.TickManager.TicksGame)
            {
                toil.hangOut        = base.TryGiveJob(pawn);
                toil.ticksToNextJoy = Find.TickManager.TicksGame + Rand.RangeInclusive(GenDate.TicksPerHour, GenDate.TicksPerHour * 3);
            }
            /* If they need joy, go do the joy activity.*/
            if (toil.hangOut != null && friend.needs.food.CurLevel > 0.33f && pawn.needs.joy.CurLevel < 0.8f)
            {
                /* Sometimes the joy activity can't be reserved because it's for one person only. */
                Job job = new Job(toil.hangOut.def);
                job.targetA           = toil.hangOut.targetA;
                job.targetB           = toil.hangOut.targetB;
                job.targetC           = toil.hangOut.targetC;
                job.targetQueueA      = toil.hangOut.targetQueueA;
                job.targetQueueB      = toil.hangOut.targetQueueB;
                job.count             = toil.hangOut.count;
                job.countQueue        = toil.hangOut.countQueue;
                job.expiryInterval    = toil.hangOut.expiryInterval;
                job.locomotionUrgency = toil.hangOut.locomotionUrgency;
                if (job.TryMakePreToilReservations(pawn, false))
                {
                    return(job);
                }
                else
                {
                    pawn.ClearAllReservations(false);
                }
            }
            if (((pawn.Position - friend.Position).LengthHorizontalSquared >= 54 || !GenSight.LineOfSight(pawn.Position, friend.Position, pawn.Map, true)))
            { /* Make sure they are close to each other if they're not actively doing a joy activity. */
              /* If the other pawn is already walking over, just hang around until they get there. */
                if (friend.CurJob.def != JobDefOf.Goto)
                {
                    return(new Job(JobDefOf.Goto, friend));
                }
                else
                {
                    pawn.rotationTracker.FaceCell(friend.Position);
                    return(null);
                }
            }
            else
            {
                /* If they are already standing close enough, but can't do the joy activity together, then wander around. */
                IntVec3 result;
                /* Make sure they only wander within conversational distance. */
                Predicate <IntVec3> validator = (IntVec3 x) => x.Standable(pawn.Map) && x.InAllowedArea(pawn) && !x.IsForbidden(pawn) && pawn.CanReserveAndReach(x, PathEndMode.OnCell, Danger.None, 1, -1, null, false) &&
                                                (x - friend.Position).LengthHorizontalSquared < 50 && GenSight.LineOfSight(x, friend.Position, pawn.Map, true) && x != friend.Position;
                if (CellFinder.TryFindRandomReachableCellNear(pawn.Position, pawn.Map, 12f, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false), (IntVec3 x) => validator(x), null, out result))
                {
                    if ((pawn.Position - friend.Position).LengthHorizontalSquared >= 5 || (LovePartnerRelationUtility.LovePartnerRelationExists(pawn, friend) && pawn.Position != friend.Position))
                    {
                        /* Sending them to goto a friend ends with them standing right next to/on top of them. So make them respect personal space a little more. */
                        pawn.mindState.nextMoveOrderIsWait = !pawn.mindState.nextMoveOrderIsWait;
                        if (!result.IsValid || pawn.mindState.nextMoveOrderIsWait)
                        {
                            /* Alternate between relaxing socially and wandering. */
                            pawn.rotationTracker.FaceCell(friend.Position);
                            return(null);
                        }
                    }
                    Job wander = new Job(JobDefOf.GotoWander, result);
                    pawn.Map.pawnDestinationReservationManager.Reserve(pawn, wander, result);
                    return(wander);
                }
                /* If we can't find a valid spot, just relax socially. */
                pawn.rotationTracker.FaceCell(friend.Position);
                return(null);
            }
        }
Beispiel #3
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            LordToil_HangOut toil   = pawn.GetLord().CurLordToil as LordToil_HangOut;
            Pawn             friend = (pawn == toil.friends[0] ? toil.friends[1] : toil.friends[0]);

            if (pawn.needs.food.CurLevel < 0.33f)
            {
                return(null);
            }
            if (friend.needs.food.CurLevel < 0.33f)
            {
                return(null);
            }
            if (LovePartnerRelationUtility.LovePartnerRelationExists(pawn, friend) && pawn.jobs.curDriver != null && pawn.jobs.curDriver.layingDown == LayingDownState.NotLaying && (pawn.IsHashIntervalTick(GenDate.TicksPerHour) || friend.IsHashIntervalTick(GenDate.TicksPerHour)))
            {
                return(new Job(JobDefOf.LayDown, pawn.ownership.OwnedBed));
            }
            if (toil.hangOut != null && toil.hangOut.GetTarget(TargetIndex.A) != null && !pawn.CanReserve(toil.hangOut.GetTarget(TargetIndex.A), toil.hangOut.def.joyMaxParticipants, 0, null))
            {
                Log.Message("can't reserve the target of the hangout");
                /* Try our best to figure out which JoyGiver was used for the unreservable job. */
                int prefix = "JoyGiver".Count();
                var def    = (
                    from j in DefDatabase <JoyGiverDef> .AllDefs
                    where j.jobDef == toil.hangOut.def ||
                    (j.jobDef == null && DefDatabase <JobDef> .GetNamedSilentFail(nameof(j.giverClass).Substring(prefix)) == toil.hangOut.def)
                    select j
                    ).FirstOrDefault();
                if (def != null)
                {
                    Log.Message("giving job of def " + def.defName);
                    do
                    {
                        toil.hangOut = base.TryGiveJobFromJoyGiverDefDirect(def, pawn);
                    } while (toil.hangOut.GetTarget(TargetIndex.A).Thing.GetRoom() != friend.GetRoom());
                }
                else
                {
                    toil.hangOut = null;
                }
            }
            if (toil.hangOut == null || toil.ticksToNextJoy < Find.TickManager.TicksGame)
            {
                toil.hangOut        = base.TryGiveJob(pawn);
                toil.ticksToNextJoy = Find.TickManager.TicksGame + Rand.RangeInclusive(GenDate.TicksPerHour, GenDate.TicksPerHour * 3);
            }
            if (pawn.needs.joy.CurLevel < 0.8f)
            {
                return(toil.hangOut);
            }
            Log.Message("no joy hangout available");
            IntVec3 root = WanderUtility.BestCloseWanderRoot(toil.hangOut.targetA.Cell, pawn);
            Func <Pawn, IntVec3, bool> validator = delegate(Pawn wanderer, IntVec3 loc)
            {
                IntVec3 wanderRoot = root;
                Room    room       = wanderRoot.GetRoom(pawn.Map);
                return(room == null || WanderUtility.InSameRoom(wanderRoot, loc, pawn.Map));
            };

            pawn.mindState.nextMoveOrderIsWait = !pawn.mindState.nextMoveOrderIsWait;
            IntVec3 wanderDest = RCellFinder.RandomWanderDestFor(pawn, root, 5f, validator, PawnUtility.ResolveMaxDanger(pawn, Danger.Some));

            if (!wanderDest.IsValid || pawn.mindState.nextMoveOrderIsWait)
            {
                if ((pawn.Position - friend.Position).LengthHorizontalSquared >= 42f && friend.jobs.curJob.def != JobDefOf.Goto)
                {
                    Log.Message("friend not nearby, going to friend");
                    IntVec3 friendDest = RCellFinder.RandomWanderDestFor(pawn, friend.Position, 5f, validator, PawnUtility.ResolveMaxDanger(pawn, Danger.Some));
                    pawn.Map.pawnDestinationManager.ReserveDestinationFor(pawn, friendDest);
                    return(new Job(JobDefOf.Goto, friendDest));
                }
                Log.Message("waiting");
                return(null);
            }
            Log.Message("wandering");
            pawn.Map.pawnDestinationManager.ReserveDestinationFor(pawn, wanderDest);
            return(new Job(JobDefOf.GotoWander, wanderDest));
        }