private void Button_CallAllBotsForShutdown()
        {
            List <X2_Building_AIRobotRechargeStation> buildings = Map.listerThings.AllThings.OfType <X2_Building_AIRobotRechargeStation>().ToList();

            for (int i = buildings.Count; i > 0; i--)
            {
                X2_Building_AIRobotRechargeStation building = buildings[i - 1];
                building.Notify_CallBotForShutdown();
            }
        }
        private void Button_SpawnAllAvailableBots()
        {
            List <X2_Building_AIRobotRechargeStation> buildings = Map.listerThings.AllThings.OfType <X2_Building_AIRobotRechargeStation>().ToList();

            for (int i = buildings.Count; i > 0; i--)
            {
                X2_Building_AIRobotRechargeStation building = buildings[i - 1];
                building.Notify_SpawnBot();
            }
        }
Ejemplo n.º 3
0
        public static Job TryCreateJob(Pawn pawn, Thing t, bool forced = false)
        {
            if (!CanPawnWorkThisJob(pawn, t, forced))
            {
                return(null);
            }

            X2_Building_AIRobotRechargeStation t1 = (t as X2_Building_AIRobotRechargeStation);

            return(AIRobot_Helper.GetStationRepairJob(pawn, t1, t1.isRepairRequestCosts));
        }
        // 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));
        }
        public override void Destroy(DestroyMode mode = DestroyMode.Vanish)
        {
            IntVec3 oldPos = this.Position != IntVec3.Invalid ? this.Position : this.PositionHeld;
            Map     oldMap = this.Map != null ? this.Map : this.MapHeld;
            X2_Building_AIRobotRechargeStation oldRechargeStation = this.rechargeStation;

            ThingDef wDef = null;

            if (this != null && this.def2 != null && this.def2.destroyedDef != null)
            {
                wDef = this.def2.destroyedDef;
            }

            try
            {
                base.Destroy(DestroyMode.Vanish);
            } catch (Exception ex)
            {
                Log.Warning(ex.Message + "\n" + ex.StackTrace);
            }



            // --- !!! NEW Approach !!! ---
            TrySpawnResources(oldMap, oldPos);

            try
            {
                IEnumerable <Thing> corpses = oldMap.listerThings.AllThings.Where <Thing>(t => t.Spawned && t == this.Corpse);
                foreach (Thing corpse in corpses)
                {
                    corpse.Destroy(DestroyMode.Vanish);
                }
            } catch (Exception ex)
            {
                Log.Warning("Couldn't destroy corpses.\n" + ex.StackTrace);
            }



            // --- !!! OLD Approach !!! ---
            //// spawn destroyed object here
            //if (mode != DestroyMode.Vanish && wDef != null)
            //{
            //    X2_AIRobot_disabled thing = (X2_AIRobot_disabled)GenSpawn.Spawn(wDef, oldPos, oldMap);
            //    thing.stackCount = 1;
            //    thing.rechargestation = oldRechargeStation;
            //    thing.SetFactionDirect(this.Faction);

            //    // set the disabled robot in the recharge station
            //    oldRechargeStation.disabledRobot = thing;
            //}
        }
Ejemplo n.º 6
0
        public static void StartStationRepairJob(Pawn pawn, X2_Building_AIRobotRechargeStation station, Dictionary <ThingDef, int> resources)
        {
            Job job = GetStationRepairJob(pawn, station, resources);

            if (job == null)
            {
                return;
            }

            pawn.jobs.StopAll();
            pawn.jobs.StartJob(job);
        }
Ejemplo n.º 7
0
        public override void Tick()
        {
            // Prevent ticks, if you aren't living anymore!
            if (this.DestroyedOrNull())
            {
                //Log.Error("I'm destroyed but ticking..");
                return;
            }
            if (Spawned && (Dead || Downed || needs.rest.CurLevel <= 0.02f))
            {
                this.Destroy(DestroyMode.KillFinalize);
                return;
            }


            base.Tick();

            // needed?
            if (needs.food != null && needs.food.CurLevel < 1.0f)
            {
                needs.food.CurLevel = 1f;
            }

            // Learning disabled?
            if (def2 == null || !def2.allowLearning)
            {
                foreach (SkillRecord skill in skills.skills)
                {
                    if (skill.xpSinceLastLevel > 1)
                    {
                        skill.xpSinceLastLevel = 1;
                        skill.xpSinceMidnight  = 1;
                    }
                }
            }

            if (this.Spawned)
            {
                if (rechargeStation == null)
                {
                    rechargeStation = TryFindRechargeStation(this, Map);
                }

                // Remove unwanted HeDiffs
                if (!Gen.IsHashIntervalTick(this, 500))
                {
                    RemoveUnwantedHediffs(this);
                }
            }
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
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);
        }
        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);
        }
Ejemplo n.º 11
0
        public override void DoCell(Rect rect, Pawn pawn, PawnTable table)
        {
            if (Widgets.ButtonImage(rect, texShutDown))
            {
                List <X2_Building_AIRobotRechargeStation> buildings = pawn.Map.listerThings.AllThings.OfType <X2_Building_AIRobotRechargeStation>().ToList();
                for (int i = buildings.Count; i > 0; i--)
                {
                    X2_Building_AIRobotRechargeStation building = buildings[i - 1];
                    building.Notify_CallBotForShutdown();
                }
            }
            if (Mouse.IsOver(rect))
            {
                GUI.DrawTexture(rect, TexUI.HighlightTex);
            }
            TipSignal tooltip = pawn.Label;

            tooltip.text = "AIRobot_ShutDownAllRobots".Translate();
            TooltipHandler.TipRegion(rect, tooltip);
        }
Ejemplo n.º 12
0
        public static Job GetStationRepairJob(Pawn pawn, X2_Building_AIRobotRechargeStation station, Dictionary <ThingDef, int> resources)
        {
            string jobDefName = "AIRobot_RepairStationRobot";

            List <Thing> foundIngredients      = new List <Thing>();
            List <int>   foundIngredientsCount = new List <int>();
            List <Thing> workIngredients       = new List <Thing>();
            List <int>   workIngredientCount   = new List <int>();

            if (resources != null)
            {
                foreach (ThingDef ingredientDef in resources.Keys)
                {
                    if (!AIRobot_Helper.GetAllNeededIngredients(pawn, ingredientDef, resources[ingredientDef], out workIngredients, out workIngredientCount) ||
                        workIngredients == null || workIngredients.Count == 0)
                    {
                        return(null);
                    }
                    foundIngredients.AddRange(workIngredients);
                    foundIngredientsCount.AddRange(workIngredientCount);
                }
            }

            //X2_JobDriver_RepairStationRobot repairRobot = new X2_JobDriver_RepairStationRobot();

            Job job = new Job(DefDatabase <JobDef> .GetNamed(jobDefName), station, null, station.Position);

            job.count        = 1;
            job.targetQueueB = new List <LocalTargetInfo>(); //new List<LocalTargetInfo>(foundIngredients.Count);
            job.countQueue   = new List <int>(foundIngredients.Count);

            for (int i = 0; i < foundIngredients.Count; i++)
            {
                job.targetQueueB.Add(foundIngredients[i]);
                job.countQueue.Add(foundIngredientsCount[i]);
            }
            job.haulMode = HaulMode.ToCellNonStorage;

            return(job);
        }
        public override void Destroy(DestroyMode mode = DestroyMode.Vanish)
        {
            IntVec3 oldPos = this.Position != IntVec3.Invalid ? this.Position : this.PositionHeld;
            Map     oldMap = this.Map != null ? this.Map : this.MapHeld;
            X2_Building_AIRobotRechargeStation oldRechargeStation = this.rechargeStation;

            ThingDef wDef = null;

            if (this != null && this.def2 != null && this.def2.destroyedDef != null)
            {
                wDef = this.def2.destroyedDef;
            }

            base.Destroy(DestroyMode.Vanish);

            // spawn destroyed object here
            if (mode != DestroyMode.Vanish && wDef != null)
            {
                X2_AIRobot_disabled thing = (X2_AIRobot_disabled)GenSpawn.Spawn(wDef, oldPos, oldMap);
                thing.stackCount      = 1;
                thing.rechargestation = oldRechargeStation;
            }
        }
        private void TryThrowNoRobotMote(X2_Building_AIRobotRechargeStation station)
        {
            if (station == null)
            {
                return;
            }


            timerNoRobotMoteThrow--;
            if (timerNoRobotMoteThrow > 0)
            {
                return;
            }
            timerNoRobotMoteThrow = 800;


            if (!station.robotIsDestroyed)
            {
                return;
            }

            MoteThrowHelper.ThrowNoRobotSign(this.Position.ToVector3(), Map, 0.8f);
        }
        public override void Tick()
        {
            base.Tick();

            // needed?
            if (needs.food != null && needs.food.CurLevel < 1.0f)
            {
                needs.food.CurLevel = 1f;
            }

            // Learning disabled?
            if (def2 == null || !def2.allowLearning)
            {
                foreach (SkillRecord skill in skills.skills)
                {
                    if (skill.xpSinceLastLevel > 1)
                    {
                        skill.xpSinceLastLevel = 1;
                        skill.xpSinceMidnight  = 1;
                    }
                }
            }

            if (Spawned && (Dead || Downed || needs.rest.CurLevel <= 0.02f))
            {
                this.Destroy(DestroyMode.KillFinalize);
                return;
            }

            if (this.Spawned)
            {
                if (rechargeStation == null)
                {
                    rechargeStation = TryFindRechargeStation(this, Map);
                }
            }
        }
        public Dictionary <ThingDef, int> CalculateResourcesNeededForRepairingRobot(X2_Building_AIRobotRechargeStation station, bool wasSpawned)
        {
            Dictionary <ThingDef, int> resources = new Dictionary <ThingDef, int>();

            try
            {
                float health = 0f;
                health = GetHealthOfRobot(station.GetRobot, 0f);
                if (health < 0.99f)
                {
                    float missing = 1f - health;
                    List <ThingDefCountClass> costs = null;

                    //1st Try: get robotRepairCost
                    if (station != null && station.def2 != null)
                    {
                        costs = station.def2.robotRepairCosts;
                    }

                    //2nd Try: Get costList * 0.6
                    if (costs == null || costs.Count == 0)
                    {
                        List <ThingDefCountClass> costsCL = station.def2.costList;
                        costs = new List <ThingDefCountClass>();
                        foreach (ThingDefCountClass c in costsCL)
                        {
                            ThingDefCountClass _c = new ThingDefCountClass(c.thingDef, (int)(c.count * 0.6f));
                            costs.Add(c);
                        }
                    }

                    //Log.Error("robotRepairCosts:" + ( costs == null ? "null" : costs.Count.ToString() ));

                    // 3rd Try: If still nothing is set, create a basic cost list with defined values
                    if (costs == null || costs.Count == 0)
                    {
                        costs = new List <ThingDefCountClass>();

                        ThingDefCountClass tDefCC;
                        tDefCC = new ThingDefCountClass(ThingDefOf.Steel, 45);
                        costs.Add(tDefCC);
                        tDefCC = new ThingDefCountClass(ThingDefOf.ComponentIndustrial, 3);
                        costs.Add(tDefCC);
                        //tDefCC = new ThingDefCountClass(ThingDefOf.Gold, 5);
                        //costs.Add(tDefCC);
                    }
                    foreach (ThingDefCountClass cost in costs)
                    {
                        int count = (int)Math.Floor(cost.count * missing);
                        if (count <= 1) //if (count <= 0)
                        {
                            continue;
                        }
                        resources.Add(cost.thingDef, count);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message + "\n" + ex.StackTrace);
            }
            return(resources);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Workbench giver destroyed (only in bill using phase! Not in carry phase)
            this.AddEndCondition(() =>
            {
                var targ = GetActor().jobs.curJob.GetTarget(StationIndex).Thing;
                if (targ == null || (targ is Building && !targ.Spawned))
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(StationIndex);  //Rechargestation is burning

            this.FailOn(() =>
            {
                X2_Building_AIRobotRechargeStation workbench = job.GetTarget(StationIndex).Thing as X2_Building_AIRobotRechargeStation;

                //conditions only apply during the billgiver-use phase
                if (workbench == null)
                {
                    return(true);
                }
                return(false);
            });

            //Go to the recharge station, this is yielded later, but needed here!
            Toil gotoStation = Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch);

            //Jump over ingredient gathering if there are no ingredients needed
            yield return(Toils_Jump.JumpIf(gotoStation, () => this.job.GetTargetQueue(IngredientIndex).NullOrEmpty()));

            {
                //Get to ingredient and pick it up
                //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked
                //   your targetB into another object on the bill giver square.

                Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(IngredientIndex);
                yield return(extract);

                //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked
                //   your targetB into another object on the bill giver square.
                var getToHaulTarget2 = Toils_Goto.GotoThing(IngredientIndex, PathEndMode.Touch)
                                       .FailOnDespawnedNullOrForbidden(IngredientIndex)
                                       .FailOnSomeonePhysicallyInteracting(IngredientIndex);
                yield return(getToHaulTarget2);

                //Carry ingredient to the workbench
                yield return(Toils_Haul.StartCarryThing(IngredientIndex, true));

                //Jump to pick up more in this run if we're collecting from multiple stacks at once
                yield return(JumpToAlsoCollectTargetInQueue(getToHaulTarget2, IngredientIndex));

                //Carry ingredient to the workbench
                yield return(Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch)
                             .FailOnDestroyedOrNull(IngredientIndex));

                //Place ingredient on the appropriate cell
                Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(StationIndex, IngredientIndex, IngredientPlaceCellIndex);
                yield return(findPlaceTarget2);

                yield return(Toils_Haul.PlaceHauledThingInCell(IngredientPlaceCellIndex, findPlaceTarget2, false, false));

                // save the ingredient, so that it can be deleted later on!
                Toil saveIngredient = new Toil();
                saveIngredient.initAction          = delegate { this.ingredients.Add(GetActor().jobs.curJob.GetTarget(IngredientIndex).Thing); };
                saveIngredient.defaultCompleteMode = ToilCompleteMode.Instant;
                yield return(saveIngredient);

                //Jump back if another ingredient is queued, or you didn't finish carrying your current ingredient target
                yield return(Toils_Jump.JumpIfHaveTargetInQueue(IngredientIndex, extract));

                extract          = null;
                getToHaulTarget2 = null;
                findPlaceTarget2 = null;
            }

            //yield return GetDebugToil("goto station", true);

            //Go to the recharge station
            yield return(gotoStation);


            //Do the repair work
            yield return(DoRepairWork(500, "Interact_ConstructMetal")
                         .FailOnDespawnedNullOrForbiddenPlacedThings()
                         .FailOnCannotTouch(StationIndex, PathEndMode.Touch));

            yield break;
        }
        public override void Tick()
        {
            // If idle at station, don't loose charge
            if (this.needs != null && this.needs.rest != null)
            {
                if (this.CurJob != null && this.CurJob.def != null &&
                    (this.CurJob.def.defName == "AIRobot_GoAndWait" || this.CurJob.def == JobDefOf.Wait) &&
                    IsInDistanceToStation(1.5f))
                {
                    if (this.needs.rest.CurLevel <= oldRestLevel - 0.01f)
                    {
                        this.needs.rest.CurLevel = oldRestLevel;
                    }
                    isSleepModeActive = true;
                }
                else
                {
                    oldRestLevel      = this.needs.rest.CurLevel;
                    isSleepModeActive = false;
                }
            }

            // Prevent ticks, if you aren't living anymore!
            if (this.DestroyedOrNull())
            {
                //Log.Error("I'm destroyed but ticking..");
                return;
            }
            // Downed only destroyes, if health is < 5%
            if (Spawned && (Dead || (Downed && health.summaryHealth.SummaryHealthPercent < 0.05f) || needs.rest.CurLevel <= 0.01f))
            {
                this.Destroy(DestroyMode.KillFinalize);
                return;
            }

            base.Tick();

            // needed?
            if (needs.food != null && needs.food.CurLevel < 1.0f)
            {
                needs.food.CurLevel = 1f;
            }

            // Learning disabled --> reset skills every x ticks
            if (def2 == null || !def2.allowLearning)
            {
                if (this.IsHashIntervalTick(4800))
                {
                    SetSkills(true);
                }
            }

            if (this.Spawned)
            {
                if (rechargeStation == null)
                {
                    rechargeStation = TryFindRechargeStation(this, Map);
                }

                // Remove unwanted HeDiffs
                if (Gen.IsHashIntervalTick(this, 500))
                {
                    RemoveUnwantedHediffs(this);
                }
            }
        }
Ejemplo n.º 19
0
        public static FloatMenuOption GetFloatMenuOption4RepairStationRobot(Pawn selPawn, X2_Building_AIRobotRechargeStation station, Dictionary <ThingDef, int> resources)
        {
            if (station.robot != null && !station.robotIsDestroyed)
            {
                return(new FloatMenuOption("AIRobot_CannotRepairRobotIsActive".Translate().CapitalizeFirst(), null));
            }

            if (!selPawn.CanReach(station, PathEndMode.InteractionCell, Danger.Deadly))
            {
                return(new FloatMenuOption("CannotUseNoPath".Translate().CapitalizeFirst(), null));
            }

            if (selPawn.skills.GetSkill(SkillDefOf.Crafting).Level < AIRobot_Helper.jobRepairRobotSkillMin)
            {
                return(new FloatMenuOption("SkillTooLowForConstruction".Translate("WorkTagCrafting".Translate()).CapitalizeFirst() + ": " + "MinSkill".Translate() + " " + AIRobot_Helper.jobRepairRobotSkillMin.ToString(), null));
            }

            List <string> missingResources = GetStationRepairJobMissingThingStrings(resources, selPawn);

            if (missingResources == null || missingResources.Count == 0)
            {
                return(new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst(), delegate { StartStationRepairJob(selPawn, station, resources); }));
            }
            else
            {
                string missingResourcesFull = "";
                foreach (string str in missingResources)
                {
                    missingResourcesFull += "\n" + str;
                }
                //Log.Error(missingResourcesFull);
                return(new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst() + ": " + "NotEnoughStoredLower".Translate() + missingResourcesFull, null));
            }
        }