private void StartRepairJob(Pawn pawn)
        {
            List <Thing> foundIngredients;
            List <int>   foundIngredientsCount;
            List <Thing> foundIngredients2;
            List <int>   foundIngredients2Count;

            if (!AIRobot_Helper.GetAllNeededIngredients(pawn, DefDatabase <ThingDef> .GetNamed(ingredientDefName), this.ingredientNeedCount, out foundIngredients, out foundIngredientsCount) ||
                foundIngredients == null || foundIngredients.Count == 0)
            {
                return;
            }
            if (!AIRobot_Helper.GetAllNeededIngredients(pawn, DefDatabase <ThingDef> .GetNamed(ingredient2DefName), this.ingredient2NeedCount, out foundIngredients2, out foundIngredients2Count) ||
                foundIngredients == null || foundIngredients.Count == 0)
            {
                return;
            }

            //Log.Error("foundIngredients="+foundIngredients.Count.ToString() + " " + "foundIngredientsCount="+foundIngredientsCount.Count.ToString());

            List <LocalTargetInfo> ingredientsLTI = new List <LocalTargetInfo>();

            foreach (Thing t in foundIngredients)
            {
                ingredientsLTI.Add(t);
            }
            foreach (Thing t in foundIngredients2)
            {
                ingredientsLTI.Add(t);
            }

            X2_JobDriver_RepairDamagedRobot repairRobot = new X2_JobDriver_RepairDamagedRobot();
            Job job = new Job(DefDatabase <JobDef> .GetNamed(this.jobDefName_repair), this.rechargestation, foundIngredients[0], this);

            job.targetQueueB = ingredientsLTI;
            job.countQueue   = foundIngredientsCount;
            pawn.jobs.StopAll();
            pawn.jobs.StartJob(job);

            Log.Error("Pawn.CurJob:" + pawn.CurJob.def.defName);
            //Log.Error("Job: "+ job.def.defName + " Ingredients: "+ foundIngredientsCount[0].ToString());
        }
        public override string GetInspectString()
        {
            if (DebugSettings.godMode)
            {
                string workString = base.GetInspectString();

                if (Position != null && Position != IntVec3.Invalid &&
                    rechargeStation != null && rechargeStation.Position != null && rechargeStation.Position != IntVec3.Invalid)
                {
                    if (!workString.NullOrEmpty())
                    {
                        workString += "\n";
                    }
                    workString += "Distance to base: " + AIRobot_Helper.GetDistance(Position, rechargeStation.Position).ToString("0") + " cells";
                    workString += " -- Remaining charge: " + needs.rest.CurLevel.ToStringPercent();
                }
                return(workString);
            }
            return(base.GetInspectString());
        }
Exemple #3
0
        private static Boolean AreAllNeededResourcesAvailable(Dictionary <ThingDef, int> resources, Pawn pawn)
        {
            List <string> missingResources = new List <string>();

            foreach (ThingDef ingredientDef in resources.Keys)
            {
                int availableResources;
                AIRobot_Helper.FindAvailableNearbyResources(ingredientDef, pawn, out availableResources);

                if (availableResources < resources[ingredientDef])
                {
                    missingResources.Add("(" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")");
                }
            }

            if (missingResources.Count == 0)
            {
                return(true);
            }
            return(false);
        }
Exemple #4
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);
        }
Exemple #5
0
        public static List <string> GetStationRepairJobMissingThingStrings(Dictionary <ThingDef, int> resources, Pawn pawn)
        {
            List <string> missingResources = new List <string>();

            if (resources == null)
            {
                return(missingResources);
            }

            foreach (ThingDef ingredientDef in resources.Keys)
            {
                int availableResources;
                AIRobot_Helper.FindAvailableNearbyResources(ingredientDef, pawn, out availableResources);

                if (availableResources < resources[ingredientDef])
                {
                    missingResources.Add("(" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + GetThingDefLabel(ingredientDef) + ")");
                    //return new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst() + ": " + "NotEnoughStoredLower".Translate() + " (" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")", null);
                }
            }
            return(missingResources);
        }
Exemple #6
0
        private static Boolean AreAllNeededResourcesAvailable(Dictionary <ThingDef, int> resources, Pawn pawn)
        {
            List <string> missingResources = new List <string>();

            foreach (ThingDef ingredientDef in resources.Keys)
            {
                int availableResources;
                AIRobot_Helper.FindAvailableNearbyResources(ingredientDef, pawn, out availableResources);

                if (availableResources < resources[ingredientDef])
                {
                    missingResources.Add("(" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")");
                    //return new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst() + ": " + "NotEnoughStoredLower".Translate() + " (" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")", null);
                }
            }

            if (missingResources.Count == 0)
            {
                return(true);
            }
            return(false);
        }
        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);
                    }
                }
            }
        }
        public override string GetInspectString()
        {
            string workString = base.GetInspectString();

            if (DebugSettings.godMode)
            {
                if (Position != null && Position != IntVec3.Invalid &&
                    rechargeStation != null && rechargeStation.Position != null && rechargeStation.Position != IntVec3.Invalid)
                {
                    if (!workString.NullOrEmpty())
                    {
                        workString += "\n";
                    }
                    workString += "Distance to base: " + AIRobot_Helper.GetDistance(Position, rechargeStation.Position).ToString("0") + " cells";
                    workString += " -- ";
                    workString += "AIRobot_Battery".Translate() + " " + needs.rest.CurLevel.ToStringPercent();
                }
            }
            else
            {
                if (!workString.NullOrEmpty())
                {
                    workString += "\n";
                }
                workString += "AIRobot_Battery".Translate() + " " + needs.rest.CurLevel.ToStringPercent();
            }

            if (isSleepModeActive)
            {
                if (!workString.NullOrEmpty())
                {
                    workString += "\n";
                }
                workString += "AIRobot_SleepMode".Translate();
            }
            return(workString.TrimEndNewlines());
        }
        //private static Designator_Deconstruct designatorDeconstruct = new Designator_Deconstruct();

        /// <summary>
        /// This creates new selection buttons with a new graphic
        /// </summary>
        /// <returns></returns>
        public override IEnumerable <Gizmo> GetGizmos()
        {
            int groupBaseKey = 31367676;

            foreach (Gizmo gizmo in base.GetGizmos())
            {
                yield return(gizmo);
            }


            if (robot == null && !robotIsDestroyed)
            {
                // Key-Binding N - Start robot
                Command_Action act2;
                act2 = new Command_Action();
                act2.defaultLabel  = lbSpawnOwner.Translate();
                act2.defaultDesc   = txtSpawnOwner.Translate();
                act2.icon          = UI_ButtonStart;
                act2.hotKey        = KeyBindingDefOf.Misc4;
                act2.activateSound = SoundDef.Named("Click");
                act2.action        = Button_SpawnBot;
                if (!Map.IsPlayerHome || Map.IsTempIncidentMap)
                {
                    act2.disabled       = true;
                    act2.disabledReason = txtDisabledBecauseNotHomeMap.Translate();
                }
                else
                {
                    act2.disabled = (powerComp != null && !powerComp.PowerOn) || isRepairRequestActive;
                    if (!isRepairRequestActive)
                    {
                        act2.disabledReason = txtNoPower.Translate();
                    }
                    else
                    {
                        act2.disabledReason = txtRapairRequested.Translate();
                    }
                }
                act2.groupKey = groupBaseKey + 1;
                yield return(act2);
            }

            if ((robot != null || robotSpawnedOnce) && !robotIsDestroyed)
            {
                // Key-Binding M - Deactivate robot
                Command_Action act1;
                act1 = new Command_Action();
                //act1.disabled = owner == null;
                //act1.disabledReason = txtNoOwner.Translate();
                act1.defaultLabel  = lbSendOwnerToRecharge.Translate();
                act1.defaultDesc   = txtSendOwnerToRecharge.Translate();
                act1.icon          = UI_ButtonForceRecharge;
                act1.hotKey        = KeyBindingDefOf.Misc7;
                act1.activateSound = SoundDef.Named("Click");
                act1.action        = Notify_CallBotForShutdown;
                act1.disabled      = (powerComp != null && !powerComp.PowerOn) || isRepairRequestActive;
                if (!isRepairRequestActive)
                {
                    act1.disabledReason = txtNoPower.Translate();
                }
                else
                {
                    act1.disabledReason = txtRapairRequested.Translate();
                }
                act1.groupKey = groupBaseKey + 2;
                yield return(act1);
            }

            {
                // Key-Binding K - Deactivate ALL robots
                Command_Action act3;
                act3 = new Command_Action();
                act3.defaultLabel   = lbRecallAllRobots.Translate();
                act3.defaultDesc    = txtRecallAllRobots.Translate();
                act3.icon           = UI_ButtonForceRechargeAll;
                act3.hotKey         = KeyBindingDefOf.Misc8;
                act3.activateSound  = SoundDef.Named("Click");
                act3.action         = Button_CallAllBotsForShutdown;
                act3.disabled       = powerComp != null && !powerComp.PowerOn;
                act3.disabledReason = txtNoPower.Translate();
                act3.groupKey       = groupBaseKey + 3;
                yield return(act3);
            }

            {
                // Key-Binding L - Activate ALL robots
                Command_Action act4;
                act4 = new Command_Action();
                act4.defaultLabel   = lbActivateAllRobots.Translate();
                act4.defaultDesc    = txtActivateAllRobots.Translate();
                act4.icon           = UI_ButtonForceActivateAll;
                act4.hotKey         = KeyBindingDefOf.Misc10;
                act4.activateSound  = SoundDef.Named("Click");
                act4.action         = Button_SpawnAllAvailableBots;
                act4.disabled       = powerComp != null && !powerComp.PowerOn;
                act4.disabledReason = txtNoPower.Translate();
                act4.groupKey       = groupBaseKey + 4;
                yield return(act4);
            }

            float health = GetHealthOfRobot(GetRobot, -1f);

            if (health != -1f && health < 0.90f || GetRobot == null && robotSpawnedOnce)
            {
                Dictionary <ThingDef, int> resources = CalculateResourcesNeededForRepairingRobot(this, robotSpawnedOnce);
                string hintText = txtRepairRobot.Translate();
                bool   first    = true;
                foreach (ThingDef thingDef in resources.Keys)
                {
                    int count = resources[thingDef];
                    if (!first)
                    {
                        hintText = hintText + ", ";
                    }
                    else
                    {
                        hintText = hintText + "\n";
                    }

                    hintText = hintText + count.ToString() + "x " + AIRobot_Helper.GetThingDefLabel(thingDef);
                    first    = false;
                }
                hintText += "\n";
                hintText += AIRobot_Helper.GetPossiblePawnsForRobotRepair(Map);

                // Key-Binding O - Request repair of damaged robot
                Command_Action act6;
                act6 = new Command_Action();
                act6.defaultLabel = lbRepairRobot.Translate();
                act6.defaultDesc  = hintText;
                if (!isRepairRequestActive)
                {
                    act6.icon = UI_ButtonRepair_NotActive;
                }
                else
                {
                    act6.icon = UI_ButtonRepair_Active;
                }
                act6.hotKey         = KeyBindingDefOf.Misc9;
                act6.activateSound  = SoundDef.Named("Click");
                act6.action         = Button_RequestRepair4Robot;
                act6.disabled       = this.robot != null && !this.robotIsDestroyed; // Disable when the robot is up and running
                act6.disabledReason = txtRobotNotDeactivated.Translate();
                act6.groupKey       = groupBaseKey + 6;
                yield return(act6);
            }

            {
                // Key-Binding O - Find robot
                Command_Action act5;
                act5 = new Command_Action();
                act5.defaultLabel   = lbFindRobot.Translate();
                act5.defaultDesc    = txtFindRobot.Translate();
                act5.icon           = UI_ButtonSearch;
                act5.hotKey         = KeyBindingDefOf.Misc11;
                act5.activateSound  = SoundDef.Named("Click");
                act5.action         = Button_FindRobot;
                act5.disabled       = powerComp != null && !powerComp.PowerOn;
                act5.disabledReason = txtNoPower.Translate();
                act5.groupKey       = groupBaseKey + 5;
                yield return(act5);
            }


            if (DebugSettings.godMode)
            {
                // Key-Binding  - (DEBUG) Reset robot
                Command_Action act9;
                act9 = new Command_Action();
                act9.defaultLabel   = "(DEBUG) Reset destroyed robot";
                act9.defaultDesc    = "";
                act9.icon           = BaseContent.BadTex;
                act9.hotKey         = null;
                act9.activateSound  = SoundDef.Named("Click");
                act9.action         = Button_ResetDestroyedRobot;
                act9.disabled       = false;
                act9.disabledReason = "";
                act9.groupKey       = groupBaseKey + 9;
                yield return(act9);


                // Key-Binding  - (DEBUG) Repair damaged robot
                Command_Action act10;
                act10 = new Command_Action();
                act10.defaultLabel   = "(DEBUG) Repair damaged robot";
                act10.defaultDesc    = "";
                act10.icon           = BaseContent.BadTex;
                act10.hotKey         = null;
                act10.activateSound  = SoundDef.Named("Click");
                act10.action         = Button_RepairDamagedRobot;
                act10.disabled       = false;
                act10.disabledReason = "";
                act10.groupKey       = groupBaseKey + 10;
                yield return(act10);
            }
        }
        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();
            }
        }
        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();
                }

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

                return;
            }

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

            X2_AIRobot spawnedRobot;

            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;

            // Check/update faction
            if (robot != null)
            {
                if (this.Faction != null && (robot.Faction == null || robot.Faction != this.Faction))
                {
                    robot.SetFactionDirect(this.Faction);
                }
                if (robot.Faction == null && Faction.OfPlayerSilentFail != null)
                {
                    robot.SetFactionDirect(Faction.OfPlayerSilentFail);
                }
            }
        }
        private void Button_RepairDamagedRobot()
        {
            NameTriple name = null;
            string     first = null, nick = null, last = null;

            Area area = null;

            X2_AIRobot bot = this.robot;

            if (bot == null && this.container.FirstOrDefault() != null)
            {
                bot = this.container.FirstOrDefault();
            }

            if (bot != null)
            {
                name = AIRobot_Helper.GetRobotName(bot);
            }
            if (bot != null && bot.playerSettings != null)
            {
                area = bot.playerSettings.AreaRestriction;
            }

            if (name != null)
            {
                first = name.First;
                nick  = name.Nick;
                last  = name.Last;
                name  = null;
            }

            if (bot != null && !bot.Destroyed && bot.Spawned)
            {
                bot.Destroy(DestroyMode.Vanish);
            }

            this.container.Clear();
            this.robot                 = null;
            this.robotIsDestroyed      = false;
            this.isRepairRequestActive = false;

            Button_SpawnBot();

            this.disabledRobot = null;

            if (first != null && nick != null && last != null)
            {
                name = new NameTriple(first, nick, last);
            }

            // Robot should again be filled (with the new robot)
            if (this.robot != null)
            {
                if (name != null)
                {
                    AIRobot_Helper.SetRobotName(this.robot, name);
                }
                if (area != null)
                {
                    this.robot.playerSettings.AreaRestriction = area;
                }
            }
        }
        public override float GetPriority(Pawn pawn)
        {
            if (pawn == null || pawn.needs == null)
            {
                return(0f);
            }

            Need_Rest needRest = pawn.needs.rest;

            if (needRest == null)
            {
                return(0f);
            }

            float             curLevel          = needRest.CurLevel;
            TimeAssignmentDef timeAssignmentDef = (pawn.timetable != null ? pawn.timetable.CurrentAssignment : TimeAssignmentDefOf.Anything);

            if (timeAssignmentDef == TimeAssignmentDefOf.Anything || timeAssignmentDef == TimeAssignmentDefOf.Work)
            {
                if ((pawn as X2_AIRobot) == null || (pawn as X2_AIRobot).rechargeStation == null || (pawn as X2_AIRobot).rechargeStation.Position == null)
                {
                    return(0f);
                }

                double distance = AIRobot_Helper.GetDistance(pawn.Position, (pawn as X2_AIRobot).rechargeStation.Position);

                // Own implementation: When level < 45% && dist > 25
                bool isOutsideMaxDistance = distance > 25f;
                if (curLevel < 0.40f && pawn as X2_AIRobot != null && isOutsideMaxDistance)
                {
                    return(8f);
                }

                //// Own implementation: When level < 70% && idle
                //bool isInsideCloseCallRange = distance < 15f && distance > 0f;
                //if (curLevel < 0.70f && pawn as X2_AIRobot != null && isInsideCloseCallRange &&
                //        (pawn.CurJobDef == null || pawn.CurJobDef == JobDefOf.Wait_Wander || pawn.CurJobDef == JobDefOf.GotoWander || pawn.CurJobDef == JobDefOf.Wait))
                //    return 8f;

                if (curLevel < 0.25f)
                {
                    return(8f);
                }

                return(0f);
            }
            if (timeAssignmentDef == TimeAssignmentDefOf.Joy)
            {
                if (curLevel < 0.3f)
                {
                    return(8f);
                }

                return(0f);
            }
            if (timeAssignmentDef == TimeAssignmentDefOf.Sleep)
            {
                if (curLevel < 0.75f)
                {
                    return(8f);
                }

                return(0f);
            }
            return(0f);
        }
        public override void Tick()
        {
            base.Tick();

            //Handle graphic update
            UpdateGraphic();

            // robot in container => recharge or release needed?
            if (robot == null && 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;
            }

            if (robotIsDestroyed)
            {
                // TODO: What do we do, when the robot is destroyed?


                // 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 (!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
            }
            //Log.Error("Max allowed distance: " + calcDistanceRestCheck.ToString("0.##") + " / MoveSpeed: " + robot.GetStatValue(StatDefOf.MoveSpeed, true).ToString());

            // 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)
            {
                Button_CallBotForShutdown();
                SpawnRobotAfterRecharge = true;
            }
        }