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();
            }
        }
        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;
            }
        }