Beispiel #1
0
        public static void RemoveCommUnit(X2_AIRobot pawn)
        {
            // Do not remove, if one of the following work types:
            if (pawn.workSettings.GetPriority(WorkTypeDefOf.Doctor) > 0 ||
                pawn.workSettings.GetPriority(WorkTypeDefOf.Handling) > 0 ||
                pawn.workSettings.GetPriority(WorkTypeDefOf.Warden) > 0)
            {
                return;
            }

            PawnCapacityDef activity = PawnCapacityDefOf.Talking;

            if (pawn.health.capacities.CapableOf(activity))
            {
                HediffSet hediffSet = pawn.health.hediffSet;
                IEnumerable <BodyPartRecord> notMissingParts = hediffSet.GetNotMissingParts();

                BodyPartRecord bodyPart = notMissingParts.Where(p => p.def.defName == "AIRobot_CommUnit").FirstOrDefault();

                if (bodyPart != null)
                {
                    DamageInfo damageInfo = new DamageInfo(DamageDefOf.EMP, Mathf.RoundToInt(hediffSet.GetPartHealth(bodyPart)), 0f, -1f, null, bodyPart, null, DamageInfo.SourceCategory.ThingOrUnknown, null);
                    //pawn.TakeDamage(damageInfo);


                    Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null);
                    hediff_MissingPart.IsFresh    = false;
                    hediff_MissingPart.lastInjury = null;
                    pawn.health.AddHediff(hediff_MissingPart, bodyPart, damageInfo);
                    pawn.health.Notify_HediffChanged(hediff_MissingPart);

                    pawn.apparel.Notify_LostBodyPart();
                }
            }
        }
        public static X2_Building_AIRobotRechargeStation TryFindRechargeStation(X2_AIRobot bot, Map map)
        {
            X2_Building_AIRobotRechargeStation foundBase;

            if (map == null && bot.rechargeStation != null)
            {
                map = bot.rechargeStation.Map;
            }
            if (map == null)
            {
                map = Find.VisibleMap;
            }
            if (map == null)
            {
                return(default(X2_Building_AIRobotRechargeStation));
            }

            IEnumerable <X2_Building_AIRobotRechargeStation> allBases = map.listerBuildings.AllBuildingsColonistOfClass <X2_Building_AIRobotRechargeStation>();

            if (allBases == null)
            {
                return(default(X2_Building_AIRobotRechargeStation));
            }

            foundBase = allBases.Where(t => t.robot == bot).FirstOrDefault();

            return(foundBase);
        }
Beispiel #3
0
        private Toil DespawnIntoContainer(bool doDespawn)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                X2_AIRobot robot = toil.actor as X2_AIRobot;
                if (robot != null && robot.rechargeStation != null)
                {
                    if (doDespawn)
                    {
                        // Despawn active --> robot into the container
                        robot.rechargeStation.AddRobotToContainer(robot);
                    }
                    else
                    {
                        // Only recharge --> robot waits and let recharge
                        robot.rechargeStation.isRechargeActive = true;
                    }
                }
            };

            toil.defaultCompleteMode = ToilCompleteMode.Instant;

            return(toil);
        }
        public void AddRobotToContainer(X2_AIRobot bot)
        {
            if (bot.HasAttachment(ThingDefOf.Fire))
            {
                bot.GetAttachment(ThingDefOf.Fire).Destroy(DestroyMode.Vanish);
            }

            isRechargeActive = false;

            bot.stances.CancelBusyStanceHard();
            bot.jobs.StopAll(false);
            bot.pather.StopDead();
            if (bot.Drafted)
            {
                bot.drafter.Drafted = false;
            }

            if (!container.Contains(bot))
            {
                container.Add(bot);
            }

            List <Map> maps = Find.Maps;

            for (int i = 0; i < maps.Count; i++)
            {
                maps[i].designationManager.RemoveAllDesignationsOn(bot, false);
            }

            DespawnRobot(bot, false);
        }
        private void Button_SpawnBot()
        {
            if (this.robot != null || robotIsDestroyed)
            {
                return;
            }

            if (spawnThingDef.NullOrEmpty())
            {
                Log.Error("Robot Recharge Station: Wanted to spawn robot, but spawnThingDef is null or empty!");
                return;
            }

            X2_AIRobot spawnedRobot = null;

            if (!IsRobotInContainer())
            {
                spawnedRobot = X2_Building_AIRobotCreator.CreateRobot(spawnThingDef, this.Position, this.Map, Faction.OfPlayer);
            }
            else
            {
                spawnedRobot = container[0] as X2_AIRobot;
                container.Remove(spawnedRobot);
                spawnedRobot = GenSpawn.Spawn(spawnedRobot, this.Position, this.Map) as X2_AIRobot;
            }

            this.robot = spawnedRobot;
            this.robot.rechargeStation = this;
            this.robotSpawnedOnce      = true;

            this.SpawnRobotAfterRecharge = true;
        }
Beispiel #6
0
 public static void SetRobotName(X2_AIRobot robot, NameTriple name)
 {
     if (robot == null)
     {
         return;
     }
     robot.Name = name;
 }
Beispiel #7
0
        // When the robot is idle, check if it is inside the room of the recharge station. If not, return there.
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            X2_AIRobot robot = pawn as X2_AIRobot;

            if (robot.DestroyedOrNull())
            {
                return(ThinkResult.NoJob);
            }
            if (!robot.Spawned)
            {
                return(ThinkResult.NoJob);
            }

            X2_Building_AIRobotRechargeStation rechargeStation = robot.rechargeStation;

            if (rechargeStation.DestroyedOrNull())
            {
                return(ThinkResult.NoJob);
            }
            if (!rechargeStation.Spawned)
            {
                return(ThinkResult.NoJob);
            }


            Need_Rest needRest = pawn.needs.rest;

            if (needRest == null)
            {
                return(ThinkResult.NoJob);
            }

            float curLevel = needRest.CurLevel;

            Job jobIdle = new Job(DefDatabase <JobDef> .GetNamed("AIRobot_GoAndWait"), rechargeStation);

            jobIdle.locomotionUrgency = LocomotionUrgency.Amble;

            if (curLevel > 0.751f)
            {
                return(new ThinkResult(jobIdle, this, JobTag.Idle, false));
            }

            //double distance = AIRobot_Helper.GetDistance(pawn.Position, (pawn as X2_AIRobot).rechargeStation.Position);
            //
            //if (distance > 5f)
            //    return ThinkResult.NoJob;

            //Boolean isInDistance = AIRobot_Helper.IsInDistance(pawn.Position, (pawn as X2_AIRobot).rechargeStation.Position, 5);
            //if (isInDistance)
            //    return ThinkResult.NoJob;

            Job job = new Job(DefDatabase <JobDef> .GetNamed("AIRobot_GoRecharge"), rechargeStation);

            job.locomotionUrgency = LocomotionUrgency.Amble;

            return(new ThinkResult(job, this, JobTag.SatisfyingNeeds, false));
        }
Beispiel #8
0
        // Self healing
        //private int timerRepairDamage = 0;
        private void TryHealDamagedBodyPartOfRobot(X2_AIRobot robot)
        {
            //timerRepairDamage--;
            //if (timerRepairDamage > 0)
            //    return;
            //timerRepairDamage = 300;

            if (robot == null || !Verse.Gen.IsHashIntervalTick(robot, 300))
            {
                return;
            }


            IEnumerable <Hediff_Injury> hediff_injuries = (from x in robot.health.hediffSet.GetHediffs <Hediff_Injury>()
                                                           where x.CanHealFromTending() || x.CanHealNaturally()
                                                           select x);


            // Apply Treated, but not healing!
            if (robot.health.HasHediffsNeedingTend(false))
            {
                float quality       = (Rand.Value);
                int   batchPosition = 0;
                foreach (Hediff_Injury injury in from x in robot.health.hediffSet.GetInjuriesTendable()
                         orderby x.Severity descending
                         select x)
                {
                    injury.Tended(quality, batchPosition);
                    batchPosition++;
                    if (batchPosition >= 1)
                    {
                        break;
                    }
                }
            }

            // Apply healing
            if (hediff_injuries != null && hediff_injuries.Count() > 0)
            {
                Hediff_Injury hediff_Injury2 = hediff_injuries.RandomElement();

                float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality;
                float num2        = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality));

                ////hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.01f); -> At quality 0.5 --> 0.066 healed.
                //Log.Error("Calculation: " + (GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)).ToString()));
                //Log.Error("Healing: " + (22f * num2 * robot.HealthScale * 0.1f).ToString());
                //Log.Error("PRE:" + hediff_Injury2.Severity.ToString());

                //hediff_Injury2.Heal(1f);
                hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.1f * 0.5f);

                //Log.Error("POST:" + hediff_Injury2.Severity.ToString());

                // Throw Healing Mote
                MoteMaker.ThrowMetaIcon(this.Position, this.Map, ThingDefOf.Mote_HealingCross);
            }
        }
Beispiel #9
0
        public override void ExposeData()
        {
            try
            {
                try
                {
                    base.ExposeData();
                }
                catch (Exception ex)
                {
                    Log.Warning("Warning: X2_Building_AIRobot_RechargeStation -- Unknown error while loading base->ExposeData:\n" + ex.Message + "\n" + ex.StackTrace);
                }

                Scribe_Values.Look <bool>(ref this.robotSpawnedOnce, "robotSpawned", false);
                Scribe_Values.Look <bool>(ref this.robotIsDestroyed, "robotDestroyed", false);
                Scribe_Values.Look <bool>(ref this.SpawnRobotAfterRecharge, "autospawn", true);
                Scribe_Values.Look <bool>(ref this.isRechargeActive, "isRechargeActive", false);
                Scribe_Values.Look <bool>(ref this.isRepairRequestActive, "isRepairRequestActive", false);

                try
                {
                    if (Scribe.mode == LoadSaveMode.Saving && robot != null && robot.DestroyedOrNull())
                    {
                        robot = null;
                    }
                    Scribe_References.Look <X2_AIRobot>(ref robot, "robot", false); // must be before Scribe_Collections -> Else errors!
                }
                catch (Exception ex)
                {
                    Log.Warning("Warning: X2_Building_AIRobot_RechargeStation -- Error while loading 'robot':\n" + ex.Message + "\n" + ex.StackTrace);
                }

                try
                {
                    Scribe_Collections.Look <X2_AIRobot>(ref this.container, "container", LookMode.Deep, null); // new object[0]); -> Throws errors!
                }
                catch (Exception ex)
                {
                    Log.Warning("Warning: X2_Building_AIRobot_RechargeStation -- Error while loading 'container':\n" + ex.Message + "\n" + ex.StackTrace);
                }
            }
            catch (Exception ex)
            {
                Log.Error("X2_Building_AIRobot_RechargeStation -- Unknown error while loading:\n" + ex.Message + "\n" + ex.StackTrace);
            }

            if (Scribe.mode == LoadSaveMode.PostLoadInit)
            {
                updateGraphicForceNeeded = true;

                if (container == null)
                {
                    ClearContainer();
                }
            }
        }
        public float GetHealthOfRobot(X2_AIRobot robot, float invalidValue = -1f)
        {
            float health = invalidValue;

            if (robot != null && robot.health != null && robot.health.summaryHealth != null)
            {
                health = robot.health.summaryHealth.SummaryHealthPercent;
            }

            return(health);
        }
        // When the robot is idle, check if it is inside the room of the recharge station. If not, return there.
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            X2_AIRobot robot = pawn as X2_AIRobot;

            if (robot.DestroyedOrNull())
            {
                return(ThinkResult.NoJob);
            }
            if (!robot.Spawned)
            {
                return(ThinkResult.NoJob);
            }

            X2_Building_AIRobotRechargeStation rechargeStation = robot.rechargeStation;

            if (rechargeStation.DestroyedOrNull())
            {
                return(ThinkResult.NoJob);
            }
            if (!rechargeStation.Spawned)
            {
                return(ThinkResult.NoJob);
            }

            Room roomRecharge = rechargeStation.Position.GetRoom(rechargeStation.Map);
            Room roomRobot    = robot.Position.GetRoom(robot.Map);

            if (roomRecharge == roomRobot)
            {
                return(ThinkResult.NoJob);
            }

            // Find target pos, but max 10 cells away!
            Map     mapRecharge = rechargeStation.Map;
            IntVec3 posRecharge = rechargeStation.Position;
            IntVec3 cell        = roomRecharge.Cells.Where(c =>
                                                           c.Standable(mapRecharge) && !c.IsForbidden(pawn) &&
                                                           AIRobot_Helper.IsInDistance(c, posRecharge, 10) &&
                                                           pawn.CanReach(c, PathEndMode.OnCell, Danger.Some, false, TraverseMode.ByPawn)
                                                           )
                                  .FirstOrDefault();

            if (cell == null || cell == IntVec3.Invalid)
            {
                return(ThinkResult.NoJob);
            }

            Job jobGoto = new Job(JobDefOf.Goto, cell);

            jobGoto.locomotionUrgency = LocomotionUrgency.Amble;

            return(new ThinkResult(jobGoto, this, JobTag.Misc, false));
        }
        private void Button_ResetDestroyedRobot(bool spawn = true)
        {
            if (robot != null && !robot.Destroyed)
            {
                robot.Destroy(DestroyMode.Vanish);
            }

            this.robot       = null;
            robotIsDestroyed = false;
            if (spawn)
            {
                Button_SpawnBot();
            }
        }
Beispiel #13
0
        public static NameTriple GetRobotName(X2_AIRobot robot)
        {
            if (robot == null || robot.Name == null)
            {
                return(null);
            }

            NameTriple nameTriple = robot.Name as NameTriple;

            if (nameTriple != null)
            {
                return(new NameTriple(nameTriple.First, nameTriple.Nick, nameTriple.Last));
            }
            return(null);
        }
        private Toil DespawnIntoContainer()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                X2_AIRobot robot = toil.actor as X2_AIRobot;
                if (robot != null && robot.rechargeStation != null)
                {
                    robot.rechargeStation.AddRobotToContainer(robot);
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Instant;
            return(toil);
        }
        public static X2_AIRobot CreateRobot(string pawnDefName, IntVec3 position, Map map, Faction faction)
        {
            PawnKindDef kind = DefDatabase <PawnKindDef> .GetNamed(pawnDefName);

            PawnGenerationRequest request = new PawnGenerationRequest(kind, faction, PawnGenerationContext.NonPlayer, -1, true, true, false, false, false, false, 0f, false, false, false, false, false, false, false, false, 0, 0, null, 0, null, null, null, null, null, 0f, 0f, Gender.None);

            X2_AIRobot robot = (X2_AIRobot)PawnGenerator.GeneratePawn(request);

            robot.workSettings = new X2_AIRobot_Pawn_WorkSettings(robot);

            if (robot.inventory == null)
            {
                robot.inventory = new Pawn_InventoryTracker(robot);
            }
            if (true) // robot.RaceProps.ToolUser
            {
                if (robot.equipment == null)
                {
                    robot.equipment = new Pawn_EquipmentTracker(robot);
                }
                if (robot.apparel == null)
                {
                    robot.apparel = new Pawn_ApparelTracker(robot);
                }
            }

            robot.workSettings.EnableAndInitializeIfNotAlreadyInitialized();

            //// Check/update faction
            //if (robot != null)
            //{
            //    if (faction != null && (robot.Faction == null || robot.Faction != faction))
            //        robot.SetFactionDirect(faction);
            //    if (robot.Faction == null && Faction.OfPlayerSilentFail != null)
            //        robot.SetFactionDirect(Faction.OfPlayerSilentFail);
            //}

            ////DEBUG
            //if (robot.workSettings == null)
            //    Log.Error("Worksettings == null!");
            //else
            //    Log.Error("Worksettings == OK, EverWork:" + robot.workSettings.EverWork.ToString());

            //AIRobot robot = RobotGenerator.GeneratePawn(pawnDefName, faction);
            IntVec3 spawnPos = position; // GenCellFinder.RandomStandableClosewalkCellNear(position, 1);

            return((X2_AIRobot)Spawn(robot, spawnPos, map));
        }
 public void DespawnRobot(X2_AIRobot bot, bool destroying = false)
 {
     if (bot != null && !bot.Destroyed)
     {
         if (destroying)
         {
             bot.Destroy(DestroyMode.Vanish);
         }
         else
         if (bot.Spawned)
         {
             bot.DeSpawn();
         }
     }
     robot = null;
 }
        private void TryUpdateAllowedArea(X2_AIRobot robot)
        {
            if (robot.DestroyedOrNull() || !robot.Spawned)
            {
                return;
            }
            if (ForbidUtility.InAllowedArea(this.Position, robot))
            {
                return;
            }

            Messages.Message("AIRobot_MessageRechargeStationOutsideAreaRestriction".Translate(), robot, MessageTypeDefOf.RejectInput);

            //Remove area from robot
            robot.playerSettings.Notify_AreaRemoved(robot.playerSettings.AreaRestriction);
        }
Beispiel #18
0
        public static X2_Building_AIRobotRechargeStation FindRechargeStationFor(X2_AIRobot sleeper, X2_AIRobot traveler, bool sleeperWillBePrisoner, bool checkSocialProperness, bool medicalBedNeeded = false)
        {
            Predicate <Thing> predicate = (Thing t) =>
            {
                if (!traveler.CanReserveAndReach(t, PathEndMode.OnCell, Danger.Some, 1))
                {
                    return(false);
                }

                X2_Building_AIRobotRechargeStation foundRechargeStation = t as X2_Building_AIRobotRechargeStation;
                if (foundRechargeStation == null)
                {
                    return(false);
                }

                if (foundRechargeStation.robot != null && foundRechargeStation.robot != sleeper)
                {
                    return(false);
                }

                if (foundRechargeStation.IsForbidden(traveler))
                {
                    return(false);
                }

                if (foundRechargeStation.IsBurning())
                {
                    return(false);
                }

                return(true);
            };

            if (sleeper.rechargeStation != null && predicate(sleeper.rechargeStation))
            {
                X2_Building_AIRobotRechargeStation rStation = sleeper.rechargeStation;

                if (rStation != null)
                {
                    return(rStation);
                }
            }

            return(null);
        }
Beispiel #19
0
        private void Button_SpawnBot()
        {
            if (isRepairRequestActive)
            {
                return;
            }

            if (this.robot != null || robotIsDestroyed)
            {
                if (this.robot != null && this.robot.Spawned && AIRobot_Helper.IsInDistance(this.Position, robot.Position, 3))
                {
                    this.robot.jobs.ClearQueuedJobs();
                    this.robot.stances.CancelBusyStanceHard();
                    this.robot.jobs.StopAll(false);
                    this.robot.pather.StopDead();
                }

                return;
            }

            if (spawnThingDef.NullOrEmpty())
            {
                Log.Error("Robot Recharge Station: Wanted to spawn robot, but spawnThingDef is null or empty!");
                return;
            }

            X2_AIRobot spawnedRobot = null;

            if (!IsRobotInContainer())
            {
                spawnedRobot = X2_Building_AIRobotCreator.CreateRobot(spawnThingDef, this.Position, this.Map, Faction.OfPlayer);
            }
            else
            {
                spawnedRobot = container[0] as X2_AIRobot;
                container.Remove(spawnedRobot);
                spawnedRobot = GenSpawn.Spawn(spawnedRobot, this.Position, this.Map) as X2_AIRobot;
            }

            this.robot = spawnedRobot;
            this.robot.rechargeStation = this;
            this.robotSpawnedOnce      = true;

            this.SpawnRobotAfterRecharge = true;
        }
        public override void DoCell(Rect rect, Pawn pawn, PawnTable table)
        {
            TipSignal tooltip = pawn.Label;

            // normal mode
            if (pawn != null && !pawn.Destroyed && pawn.Spawned)
            {
                if (Widgets.ButtonImage(rect, texNotRecharging))
                {
                    X2_AIRobot robot = pawn as X2_AIRobot;
                    //if (robot != null && robot.rechargeStation != null)
                    //    robot.rechargeStation.Notify_CallBotForShutdown();

                    CameraJumper.TryJumpAndSelect(robot);
                }
            }
            // Is recharging
            else if (pawn != null && !pawn.Destroyed && !pawn.Spawned)
            {
                if (Widgets.ButtonImage(rect, texRecharging))
                {
                    X2_AIRobot robot = pawn as X2_AIRobot;
                    //if (robot != null && robot.rechargeStation != null)
                    //    robot.rechargeStation.Notify_SpawnBot();  <-- ERROR: Creates a NEW robot wich causes ERRORS!!!

                    if (robot != null && robot.rechargeStation != null)
                    {
                        if (Current.ProgramState == ProgramState.Playing && Event.current.button == 0)
                        {
                            Find.MainTabsRoot.EscapeCurrentTab(false);
                        }

                        CameraJumper.TryJumpAndSelect(robot.rechargeStation);
                    }
                }
                tooltip.text = "AIRobot_RobotIsRecharging".Translate() + "\n" + pawn.Label;
            }
            if (Mouse.IsOver(rect))
            {
                GUI.DrawTexture(rect, TexUI.HighlightTex);
            }

            TooltipHandler.TipRegion(rect, tooltip);
        }
        private void TryThrowBatteryMote(X2_AIRobot robot)
        {
            if (robot == null)
            {
                return;
            }


            timerMoteThrow--;
            if (timerMoteThrow > 0)
            {
                return;
            }
            timerMoteThrow = 300;


            float batteryLevel = robot.needs.rest.CurLevel;

            if (batteryLevel > 0.99f)
            {
                return;
            }

            if (batteryLevel > 0.90f)
            {
                //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryGreen"));
                MoteThrowHelper.ThrowBatteryGreen(this.Position.ToVector3(), Map, 0.8f);
            }
            else if (batteryLevel > 0.70f)
            {
                //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryYellowYellow"));
                MoteThrowHelper.ThrowBatteryYellowYellow(this.Position.ToVector3(), Map, 0.8f);
            }
            else if (batteryLevel > 0.35f)
            {
                //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryYellow"));
                MoteThrowHelper.ThrowBatteryYellow(this.Position.ToVector3(), Map, 0.8f);
            }
            else
            {
                //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryRed"));
                MoteThrowHelper.ThrowBatteryRed(this.Position.ToVector3(), Map, 0.8f);
            }
        }
        public override void DoCell(Rect rect, Pawn pawn, PawnTable table)
        {
            if (Widgets.ButtonImage(rect, texShutDown))
            {
                X2_AIRobot robot = pawn as X2_AIRobot;
                if (robot != null && robot.rechargeStation != null)
                {
                    robot.rechargeStation.Notify_CallBotForShutdown();
                }
            }
            if (Mouse.IsOver(rect))
            {
                GUI.DrawTexture(rect, TexUI.HighlightTex);
            }
            TipSignal tooltip = pawn.Label;

            tooltip.text = "AIRobot_ShutDownRobot".Translate() + "\n" + pawn.Label;
            TooltipHandler.TipRegion(rect, tooltip);
        }
        protected override Job TryGiveJob(Pawn pawn)
        {
            X2_AIRobot aiRobot = pawn as X2_AIRobot;
            X2_Building_AIRobotRechargeStation rechargeStation = AIRobot_Helper.FindRechargeStationFor(aiRobot);

            if (rechargeStation == null)
            {
                return(null);
            }

            if (aiRobot.rechargeStation != rechargeStation)
            {
                return(null);
            }

            Job job = new Job(JobDefOf.Goto, rechargeStation);

            return(job);
        }
Beispiel #24
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            X2_AIRobot aiRobot = pawn as X2_AIRobot;
            X2_Building_AIRobotRechargeStation rechargeStation = AIRobot_Helper.FindRechargeStationFor(aiRobot);

            if (rechargeStation == null)
            {
                return(null);
            }

            if (aiRobot.rechargeStation != rechargeStation)
            {
                return(null);
            }

            Job job = new Job(DefDatabase <JobDef> .GetNamed("AIRobot_GoRecharge"), rechargeStation);

            return(job);
        }
Beispiel #25
0
        public static X2_AIRobot CreateRobot(string pawnDefName, IntVec3 position, Map map, Faction faction)
        {
            PawnKindDef kind = DefDatabase <PawnKindDef> .GetNamed(pawnDefName);

            PawnGenerationRequest request = new PawnGenerationRequest(kind, faction, PawnGenerationContext.NonPlayer, -1, true, true, false, false, false, false, 0f, false, false, true, false, false, false, false, null, null, null, null, null, Gender.Male, null, null);

            X2_AIRobot robot = (X2_AIRobot)PawnGenerator.GeneratePawn(request);

            robot.workSettings = new X2_AIRobot_Pawn_WorkSettings(robot);

            ////DEBUG
            //if (robot.workSettings == null)
            //    Log.Error("Worksettings == null!");
            //else
            //    Log.Error("Worksettings == OK, EverWork:" + robot.workSettings.EverWork.ToString());

            //AIRobot robot = RobotGenerator.GeneratePawn(pawnDefName, faction);
            IntVec3 spawnPos = position; // GenCellFinder.RandomStandableClosewalkCellNear(position, 1);

            return((X2_AIRobot)Spawn(robot, spawnPos, map));
        }
        private void TryThrowBatteryMote(X2_AIRobot robot)
        {
            if (robot == null)
            {
                return;
            }


            timerMoteThrow--;
            if (timerMoteThrow > 0)
            {
                return;
            }
            timerMoteThrow = 300;


            float batteryLevel = robot.needs.rest.CurLevel;

            if (batteryLevel > 0.99f)
            {
                return;
            }

            if (batteryLevel > 0.90f)
            {
                MoteThrowHelper.ThrowBatteryGreen(this.Position.ToVector3(), Map, 0.8f);
            }
            else if (batteryLevel > 0.70f)
            {
                MoteThrowHelper.ThrowBatteryYellowYellow(this.Position.ToVector3(), Map, 0.8f);
            }
            else if (batteryLevel > 0.35f)
            {
                MoteThrowHelper.ThrowBatteryYellow(this.Position.ToVector3(), Map, 0.8f);
            }
            else
            {
                MoteThrowHelper.ThrowBatteryRed(this.Position.ToVector3(), Map, 0.8f);
            }
        }
        public override IEnumerable <FloatMenuOption> GetFloatMenuOptions(Pawn selPawn)
        {
            foreach (FloatMenuOption fmo in base.GetFloatMenuOptions(selPawn))
            {
                yield return(fmo);
            }


            X2_AIRobot bot = this.GetRobot;

            if (GetHealthOfRobot(bot) <= 0.99f)
            {
                Dictionary <ThingDef, int> resources = CalculateResourcesNeededForRepairingRobot(this, robotSpawnedOnce);
                if (resources.Count > 0)
                {
                    FloatMenuOption fmoStationRobot = AIRobot_Helper.GetFloatMenuOption4RepairStationRobot(selPawn, this, resources);
                    if (fmoStationRobot != null)
                    {
                        yield return(fmoStationRobot);
                    }
                }
            }
        }
Beispiel #28
0
        protected override bool Satisfied(Pawn pawn)
        {
            if (workType == null)
            {
                return(false);
            }

            X2_AIRobot robot = pawn as X2_AIRobot;

            if (robot == null)
            {
                return(false);
            }

            X2_ThingDef_AIRobot robotdef = robot.def as X2_ThingDef_AIRobot;

            if (robotdef == null)
            {
                return(false);
            }

            return(robot.CanDoWorkType(workType));
        }
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            X2_AIRobot robot = pawn as X2_AIRobot;

            if (robot == null || !robot.Spawned || robot.Destroyed || robot.GetWorkGivers(false) == null)
            {
                return(ThinkResult.NoJob);
            }

            //Profiler.BeginSample("JobGiver_Work");

            //if (emergency && pawn.mindState.priorityWork.IsPrioritized)
            //{
            //	List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority;
            //	for (int i = 0; i < workGiversByPriority.Count; i++)
            //	{
            //		WorkGiver worker = workGiversByPriority[i].Worker;
            //		if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def))
            //		{
            //			Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell);
            //			if (job != null)
            //			{
            //				job.playerForced = true;
            //				return new ThinkResult(job, this, workGiversByPriority[i].tagToGive);
            //			}
            //		}
            //	}
            //	pawn.mindState.priorityWork.Clear();
            //}



            List <WorkGiver> list = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers
            int               num = -999;
            TargetInfo        bestTargetOfLastPriority = TargetInfo.Invalid;
            WorkGiver_Scanner scannerWhoProvidedTarget = null;
            WorkGiver_Scanner scanner;
            IntVec3           pawnPosition;
            bool              prioritized;
            bool              allowUnreachable;
            Danger            maxPathDanger;

            for (int j = 0; j < list.Count; j++)
            {
                WorkGiver workGiver = list[j];
                if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid)
                {
                    break;
                }
                if (!PawnCanUseWorkGiver(pawn, workGiver))
                {
                    continue;
                }
                try
                {
                    Job job2 = workGiver.NonScanJob(pawn);
                    if (job2 != null)
                    {
                        return(new ThinkResult(job2, this, list[j].def.tagToGive));
                    }
                    scanner = (workGiver as WorkGiver_Scanner);
                    float closestDistSquared;
                    float bestPriority;
                    if (scanner != null)
                    {
                        if (scanner.def.scanThings)
                        {
                            Predicate <Thing>   validator  = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t);
                            IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn);
                            Thing thing;
                            try
                            {
                                if (scanner.Prioritized)
                                {
                                    IEnumerable <Thing> enumerable2 = enumerable;
                                    if (enumerable2 == null)
                                    {
                                        enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)));
                                }
                                else if (scanner.AllowUnreachable)
                                {
                                    IEnumerable <Thing> enumerable3 = enumerable;
                                    if (enumerable3 == null)
                                    {
                                        enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest);
                                    }
                                    thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator);
                                }
                                else
                                {
                                    thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null);
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Error("Error in WorkGiver: " + ex.Message);

                                thing = null;
                            }
                            if (thing != null)
                            {
                                bestTargetOfLastPriority = thing;
                                scannerWhoProvidedTarget = scanner;
                            }
                        }

                        if (scanner.def.scanCells)
                        {
                            pawnPosition       = pawn.Position;
                            closestDistSquared = 99999f;
                            bestPriority       = float.MinValue;
                            prioritized        = scanner.Prioritized;
                            allowUnreachable   = scanner.AllowUnreachable;
                            maxPathDanger      = scanner.MaxPathDanger(pawn);
                            IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn);
                            IList <IntVec3>       list2;
                            if ((list2 = (enumerable4 as IList <IntVec3>)) != null)
                            {
                                for (int k = 0; k < list2.Count; k++)
                                {
                                    ProcessCell(list2[k]);
                                }
                            }
                            else
                            {
                                foreach (IntVec3 item in enumerable4)
                                {
                                    ProcessCell(item);
                                }
                            }
                        }
                    }
                    void ProcessCell(IntVec3 c)
                    {
                        bool  flag = false;
                        float num2 = (c - pawnPosition).LengthHorizontalSquared;
                        float num3 = 0f;

                        if (prioritized)
                        {
                            if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                            {
                                if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                                {
                                    return;
                                }
                                num3 = scanner.GetPriority(pawn, c);
                                if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared))
                                {
                                    flag = true;
                                }
                            }
                        }
                        else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c))
                        {
                            if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger))
                            {
                                return;
                            }
                            flag = true;
                        }
                        if (flag)
                        {
                            bestTargetOfLastPriority = new TargetInfo(c, pawn.Map);
                            scannerWhoProvidedTarget = scanner;
                            closestDistSquared       = num2;
                            bestPriority             = num3;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString());
                }
                finally
                {
                }
                if (bestTargetOfLastPriority.IsValid)
                {
                    Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing);
                    if (job3 != null)
                    {
                        job3.workGiverDef = scannerWhoProvidedTarget.def;
                        return(new ThinkResult(job3, this, list[j].def.tagToGive));
                    }
                    Log.ErrorOnce(scannerWhoProvidedTarget + " provided target " + bestTargetOfLastPriority + " but yielded no actual job for pawn " + pawn + ". The CanGiveJob and JobOnX methods may not be synchronized.", 6112651);
                }
                num = workGiver.def.priorityInType;
            }
            return(ThinkResult.NoJob);
        }
        public override void Tick()
        {
            base.Tick();

            //Handle graphic update
            UpdateGraphic();

            // robot in container => recharge or release needed?
            if (robot == null)
            {
                if (notify_spawnRequested)
                {
                    // Don't start all robots at the same time
                    if (!this.IsHashIntervalTick(5))
                    {
                        return;
                    }

                    notify_spawnRequested = false;
                    Button_SpawnBot();
                    return;
                }

                if (IsRobotInContainer())
                {
                    X2_AIRobot containedRobot = container[0] as X2_AIRobot;
                    if (containedRobot == null)
                    {
                        container.Remove(container[0]);
                        return;
                    }

                    if (SpawnRobotAfterRecharge && containedRobot.needs.rest.CurLevel >= 0.99f)
                    {
                        Button_SpawnBot();
                    }
                    else if (containedRobot.needs.rest.CurLevel < 1f)
                    {
                        containedRobot.needs.rest.CurLevel += (0.1f / GenDate.TicksPerHour) * rechargeEfficiency;
                        if (containedRobot.needs.rest.CurLevel > 1f)
                        {
                            containedRobot.needs.rest.CurLevel = 1f;
                        }

                        TryThrowBatteryMote(containedRobot);
                    }

                    // Try to heal robot
                    TryHealDamagedBodyPartOfRobot(containedRobot);
                    return;
                }
            }
            notify_spawnRequested = false;

            if (robotIsDestroyed)
            {
                // What do we do, when the robot is destroyed?
                TryThrowNoRobotMote(this);

                // Last step: do nothing more!
                return;
            }

            if (robot == null && (!robotSpawnedOnce || !IsRobotInContainer()))
            {
                return;
            }

            // if the robot is dead...
            if (robotSpawnedOnce && !IsRobotInContainer() && (robot == null || robot.Destroyed || robot.Dead))
            {
                if ((robot.Destroyed || robot.Dead) && robot.Corpse != null)
                {
                    robot.Corpse.Destroy(DestroyMode.Vanish);
                }

                robotIsDestroyed = true;
                return;
            }

            if (isRechargeActive && robot != null && Gen.IsHashIntervalTick(robot, 30) && !AIRobot_Helper.IsInDistance(robot.Position, this.Position, 3))
            {
                robot.jobs.ClearQueuedJobs();
                isRechargeActive = false;
            }

            if (isRechargeActive)
            {
                if (robot.needs.rest.CurLevel < 1f)
                {
                    robot.needs.rest.CurLevel += (0.1f / GenDate.TicksPerHour) * rechargeEfficiency * 2;
                    if (robot.needs.rest.CurLevel > 1f)
                    {
                        robot.needs.rest.CurLevel = 1f;
                    }

                    TryThrowBatteryMote(robot);
                }
                else
                {
                    robot.jobs.ClearQueuedJobs();
                    robot.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    isRechargeActive = false;
                }
                return;
            }


            if (!Gen.IsHashIntervalTick(robot, 250))
            {
                return;
            }

            TryUpdateAllowedArea(robot);

            if (calcDistanceRestCheck == -1)
            {
                calcDistanceRestCheck = AIRobot_Helper.GetSlopePoint(robot.GetStatValue(StatDefOf.MoveSpeed, true), 1f, 6f, 15f, 40f); // movementspeed slope: speed 1 -> 30 cells, speed 6 -> 50 cells
            }
            // If battery of robot is < 40% and distance > 25 cells => try to recall him
            // Also recall if battery is < 10% (emergency if ThinkTree isn't working)
            if ((robot.needs.rest.CurLevel < 0.40f && !AIRobot_Helper.IsInDistance(this.Position, robot.Position, calcDistanceRestCheck)) ||
                robot.needs.rest.CurLevel < 0.10f)
            {
                Notify_CallBotForRecharge();
            }
        }