/*
         * public static void DebugMsg(Sim sim, Common.StringBuilder msg, string text)
         * {
         *  if (text != null)
         *  {
         *      msg += Common.NewLine + text;
         *  }
         *
         *  if ((sim != null) && (sim.FirstName == "Roberto"))
         *  {
         *      Common.Notify(msg);
         *  }
         * }
         */
        public override bool DoRoute(Route r)
        {
            Sim routeSim = null;

            if (!GoHere.Settings.mAllowCarRouting)
            {
                r.SetOption(Route.RouteOption.EnablePlanningAsCar, false);
                r.SetOption(Route.RouteOption.BeginAsCar, false);
            }

            Common.StringBuilder msg = new Common.StringBuilder("DoRoute");

            try
            {
                if (r.Follower != null)
                {
                    routeSim = r.Follower.Target as Sim;
                }

                if (!GoHere.Settings.mAllowBoatRouting)
                {
                    Houseboat boat;
                    if (!Houseboat.IsPointOnHouseboat(mOwnerSim.Position, out boat))
                    {
                        r.SetOption2(Route.RouteOption2.EnablePlanningAsBoat, false);
                        r.SetOption2(Route.RouteOption2.BeginAsBoat, false);
                        r.SetOption2(Route.RouteOption2.EndAsBoat, false);

                        bool water = false;
                        if (mOwnerSim.InteractionQueue != null)
                        {
                            Terrain.GoHere interaction = mOwnerSim.InteractionQueue.GetHeadInteraction() as Terrain.GoHere;

                            if (interaction != null && interaction.mDestinationType == Terrain.GoHere.DestinationType.OnSeaWater)
                            {
                                water = true;
                            }
                        }

                        if (mOwnerSim.Posture is Ocean.PondAndOceanRoutingPosture || mOwnerSim.Posture is SwimmingInPool)
                        {
                            water = true;
                        }

                        if (water)
                        {
                            r.SetOption(Route.RouteOption.EnableWaterPlanning, true);
                            r.SetOption(Route.RouteOption.DoNotEmitDegenerateRoutesForRadialRangeGoals, true);
                            r.SetOption(Route.RouteOption.DisallowGoalsOnBridges, true);
                        }
                    }
                }

                if (!GoHere.Settings.mAllowMermaidRouting)
                {
                    r.SetOption2(Route.RouteOption2.RouteAsMermaid, false);
                }

                // why did he use routeSim here? It seems to always be null...
                if ((routeSim != null) && (routeSim.Occupation != null))
                {
                    if (routeSim.SimDescription.GetOutfitCount(OutfitCategories.Career) == 0)
                    {
                        routeSim.Occupation.SetOccupationOutfitForCurrentLevel();
                    }
                }

                if (!r.PlanResult.Succeeded())
                {
                    msg += Common.NewLine + "A: " + r.PlanResult + " False";

                    DoRouteFailureBehavior(r);
                    mOwnerSim.AddExitReason(ExitReason.RouteFailed);
                    return(false);
                }

                bool        flag    = false;
                IGameObject destObj = r.DestObj as IGameObject;
                try
                {
                    if (destObj != null)
                    {
                        destObj.AddToRoutingReferenceList(mOwnerSim);
                        mOwnerSim.LookAtManager.SetRoutingLookAt(destObj as GameObject);
                    }

                    mbIgnoreAllObstaclesStartTimeValid = false;
                    if (mOwnerSim.IsActiveSim)
                    {
                        Route.SetFadePriority(mOwnerSim.ObjectId, 0x186a3);
                    }
                    else if (mOwnerSim.IsInActiveHousehold)
                    {
                        Route.SetFadePriority(mOwnerSim.ObjectId, 0x186a2);
                    }
                    else
                    {
                        Route.SetFadePriority(mOwnerSim.ObjectId, 0x186a1);
                    }

                    while (true)
                    {
                        flag = false;
                        if (mbPushRequested)
                        {
                            if ((!(mOwnerSim.Posture is SittingInVehicle) && !(mOwnerSim.Posture is SittingInBoat)) && (mOwnerSim.RoutingComponent.RoutingParent == null))
                            {
                                try
                                {
                                    MidRouteBePushed(r.ExecutionFromNonSimTaskIsSafe);
                                }
                                catch (ResetException)
                                {
                                    throw;
                                }
                                catch (Exception e)
                                {
                                    Common.Exception(routeSim, e);
                                }

                                r.Replan();
                            }
                            else
                            {
                                mbPushRequested = false;
                            }

                            continue;
                        }

                        StartPushImmunity(OnRouteStartedImmuneToPushesDuration);
                        flag  = DoSingleRouteEx(r, true);
                        flag &= r.PlanResult.Succeeded();
                        if (mbPushRequested)
                        {
                            continue;
                        }

                        if (r.GetOption(Route.RouteOption.CheckForFootprintsNearGoals))
                        {
                            ObjectGuid guid = r.IsPointObstructedBySim(mOwnerSim.PositionOnFloor);
                            if (guid != ObjectGuid.InvalidObjectGuid)
                            {
                                ObjectGuid runningTargetId = ObjectGuid.InvalidObjectGuid;
                                if (((mOwnerSim.InteractionQueue != null) && (mOwnerSim.InteractionQueue.RunningInteraction != null)) && (mOwnerSim.InteractionQueue.RunningInteraction.Target != null))
                                {
                                    runningTargetId = mOwnerSim.InteractionQueue.RunningInteraction.Target.ObjectId;
                                }

                                if ((guid != runningTargetId) && !PushSims(mOwnerSim.PositionOnFloor, 0.5f, false))
                                {
                                    bool option = r.GetOption(Route.RouteOption.BlockedByPeople);
                                    r.SetOption(Route.RouteOption.BlockedByPeople, true);
                                    r.Replan();
                                    r.SetOption(Route.RouteOption.BlockedByPeople, option);
                                    if (r.PlanResult.Succeeded() && (r.IsPointObstructedBySim(mOwnerSim.PositionOnFloor) == ObjectGuid.InvalidObjectGuid))
                                    {
                                        continue;
                                    }

                                    StartPushImmunity(OnEmergencyGetAwayRouteStartedImmuneToPushesDuration);
                                    Route route = PlanRouteForPush(mOwnerSim, null, PushSimsAwayDistanceMin, PushSimsAwayDistanceMax);
                                    DoSingleRouteEx(route, false);
                                    flag = false;
                                    if (r.DoRouteFail)
                                    {
                                        Sim sim = guid.ObjectFromId <Sim>();
                                        PlayRouteFailureIfAppropriate(sim);
                                    }

                                    RouteFailureTurnJigBlocker = ObjectGuid.InvalidObjectGuid;
                                    HasRouteFailureFromTurnJig = false;

                                    msg += Common.NewLine + "B: " + r.PlanResult + " " + flag;

                                    return(flag);
                                }
                            }
                        }

                        break;
                    }

                    if (HasRouteFailureFromTurnJig && r.DoRouteFail)
                    {
                        GameObject obj3 = GameObject.GetObject(RouteFailureTurnJigBlocker);
                        PlayRouteFailureIfAppropriate(obj3);
                    }
                }
                finally
                {
                    if (destObj != null)
                    {
                        destObj.RemoveFromRoutingReferenceList(mOwnerSim);
                    }

                    mbIgnoreAllObstaclesStartTimeValid = false;
                    mbPushImmunityStartTimeValid       = false;
                    Route.SetFadePriority(mOwnerSim.ObjectId, 0x186a0);
                    mOwnerSim.LookAtManager.SetRoutingLookAt(null);
                }

                RouteFailureTurnJigBlocker = ObjectGuid.InvalidObjectGuid;
                HasRouteFailureFromTurnJig = false;

                msg += Common.NewLine + "C: " + flag;

                return(flag);
            }
            catch (ResetException)
            {
                throw;
            }
            catch (Exception e)
            {
                Common.Exception(routeSim, e);
                throw;
            }
            finally
            {
                //Common.DebugNotify(msg, routeSim);
            }
        }