public override void DoWindowContents(Rect inRect)   //todo: much better info
        //make big
        {
            Rect r  = new Rect(0, 0, inRect.width, 22);
            Rect rl = new Rect(0, 22, inRect.width / 2, 22);
            Rect rr = new Rect(inRect.width / 2, 22, inRect.width / 2, 22);

            Widgets.Label(r, "Are the contents of this storage");
            Widgets.Label(rl, "ALWAYS accessible to");
            Widgets.Label(rr, "NEVER accessible to");

            r = new Rect(1, 44, inRect.width - 1, inRect.height - 48 - 48);  //-height-button
            Rect innerRect = new Rect(0, 0, inRect.width - 20, totalHeight); // room for scroll bar

            Widgets.BeginScrollView(r, ref scrollPos, innerRect);

            //make small a
            float y = 0f;

            Widgets.Label(new Rect(0, y, inRect.width, 22), "Humans");
            y += 22f;
            foreach (Pawn p in Find.ColonistBar.GetColonistsInOrder())
            {
                DoPawnRow(ref y, inRect.width, p);
            }

            Widgets.Label(new Rect(0, y, inRect.width, 22), "Animals");
            y += 22;
            // This is trickier than I first thought for one reason:
            //   Sorting.
            // I want the animals to move in order as viewed in the Animals
            // main tab window (similar to pawns in the pawn bar). It's not
            // an easy sort to do by hand, and since I can grab it directly
            // from the main tab window...why not?
            // #SlightlyDeepMagic #Reflection

            // Note: this might be slightly slow, but game isn't running anyway,
            // so ...okay?

            // The MaintabWindow_... is *the* actual window; it sticks around and one can grab it:
            //   use "as" to make sure it CAN be cast to MTW_A:
            MainTabWindow_Animals mtw = (MainTabWindow_Animals)
                                        (DefDatabase <MainButtonDef> .GetNamed("Animals").TabWindow as MainTabWindow_Animals);

            if (mtw != null)
            {
                // The MainTabWindow_Animals(Wildlife, etc) is a MainTabWindow_PawnTable
                // Getting the PawnTable takes a little work:
                var table = (PawnTable)typeof(MainTabWindow_PawnTable).GetField("table",
                                                                                BindingFlags.Instance |
                                                                                BindingFlags.NonPublic |
                                                                                BindingFlags.GetField)
                            .GetValue(mtw as MainTabWindow_PawnTable); // because table is a ..._PawnTable var
                if (table == null)
                {
                    // If the player has never opened the Animals window, there's no table!
                    // But we can force building the table:
                    mtw.Notify_ResolutionChanged();
                    table = (PawnTable)typeof(MainTabWindow_PawnTable).GetField("table",
                                                                                BindingFlags.Instance |
                                                                                BindingFlags.NonPublic |
                                                                                BindingFlags.GetField)
                            .GetValue(mtw as MainTabWindow_PawnTable);
                }
                foreach (Pawn p in table.PawnsListForReading)
                {
                    DoPawnRow(ref y, inRect.width, p);
                }
            }
            else     // no MainTabWindow_Animals available?
            // This might happen if some modder really breaks the main tab window for animals?
            // fall back on just counting them all and being happy
            {
                foreach (Map m in Find.Maps)
                {
                    foreach (Pawn p in m.mapPawns.AllPawns)
                    {
                        if (p.RaceProps.Animal && p.Faction == Faction.OfPlayer)
                        {
                            DoPawnRow(ref y, inRect.width, p);
                        }
                    }
                }
            }
            this.totalHeight = y; // quick and dirty way to handle this
            Widgets.EndScrollView();
        }
        public static bool DetourToSelectXPawn(bool goToNext)
        {
            if (!LoadedModManager.GetMod <MinorChangesMod>()
                .GetSettings <Settings>().selectNextAnimal)
            {
                return(true);                                           // vanilla
            }
            Thing selThing = Find.Selector.SingleSelectedThing;

            if (selThing == null)
            {
                return(true);
            }
            Pawn selPawn = selThing as Pawn;

            if (selPawn == null)
            {
                return(true);
            }
            if (selPawn.Map != Find.CurrentMap)
            {
                Debug.Log("Selection: pawn " + selPawn + " is not in the same map");
                return(true);
            }
            List <Pawn> listOfSimilarPawns;

            //if (!p.RaceProps.Animal) return true; // also get wildppl:
            if (!selPawn.AnimalOrWildMan())
            {
                Debug.Warning("SelectXPawn: " + selPawn + " is humanlike");
                // human-ish
                if (selPawn.Faction == Faction.OfPlayer)
                {
                    Debug.Log("  but is player's faction.");
                    return(true);
                }
                if (selPawn.IsPrisoner)
                {
                    Debug.Log("  and is a Prisoner");
                    // there is no in-game list of prisoners, so we make one
                    // and sort it how we please and use it:
                    listOfSimilarPawns = Find.CurrentMap.mapPawns.PrisonersOfColonySpawned;
                    // If this is not correct, we'll still default to vanilla later, so all good.
                }
                else     //non player faction, non prisoner.
                {
                    Debug.Log("  and is a member of faction " + selPawn.Faction);
                    // cycle through all pawns of this faction:
                    listOfSimilarPawns = Find.CurrentMap.mapPawns.FreeHumanlikesSpawnedOfFaction(selPawn.Faction);
                }
            }
            else     //animal (or wildperson, which is counted with the animals)
            {
                if (selPawn.Faction == Faction.OfPlayer)
                {
                    Debug.Warning("SelectXPawn: " + selPawn + " is tamed animal!");
                    // tamed animal!!
                    // This is trickier than I first thought for one reason:
                    //   Sorting.
                    // I want the animals to move in order as viewed in the Animals
                    // main tab window (similar to pawns in the pawn bar). It's not
                    // an easy sort to do by hand, and since I can grab it directly
                    // from the main tab window...why not?
                    // #SlightlyDeepMagic #Reflection

                    // The MaintabWindow_... is *the* actual window; it sticks around and one can grab it:
                    //   use "as" to make sure it CAN be cast to MTW_A:
                    MainTabWindow_Animals mtw = (MainTabWindow_Animals)
                                                (DefDatabase <MainButtonDef> .GetNamed("Animals").TabWindow as MainTabWindow_Animals);
                    if (mtw == null)
                    {
                        Log.Message("LWM:Minor changes: could not get MainTabWindow_Animals, as it's a " +
                                    DefDatabase <MainButtonDef> .GetNamed("Animals").GetType().ToString());
                        return(true);
                    }                  // fail gracefully.
                    // The MainTabWindow_Animals(Wildlife, etc) is a MainTabWindow_PawnTable
                    // Getting the PawnTable takes a little work:
                    var table = (PawnTable)typeof(MainTabWindow_PawnTable).GetField("table",
                                                                                    BindingFlags.Instance |
                                                                                    BindingFlags.NonPublic |
                                                                                    BindingFlags.GetField)
                                .GetValue(mtw as MainTabWindow_PawnTable); // because table is a ..._PawnTable var
                    if (table == null)
                    {
                        // If the player has never opened the Animals window, there's no table!
                        // But we can force building the table:
                        mtw.Notify_ResolutionChanged();
                        table = (PawnTable)typeof(MainTabWindow_PawnTable).GetField("table",
                                                                                    BindingFlags.Instance |
                                                                                    BindingFlags.NonPublic |
                                                                                    BindingFlags.GetField)
                                .GetValue(mtw as MainTabWindow_PawnTable);
                    }
                    listOfSimilarPawns = table.PawnsListForReading;
                }
                else    // one animal selected, but is not tame - Wildlife!
                {
                    Debug.Warning("SelectXPawn: " + selPawn + " is wild animal!");
                    // grabbed straight from MainTabWindow_Wildlife:
                    MainTabWindow_Wildlife mtw = (MainTabWindow_Wildlife)
                                                 (DefDatabase <MainButtonDef> .GetNamed("Wildlife").TabWindow as MainTabWindow_Wildlife);
                    if (mtw == null)
                    {
                        Log.Message("LWM:Minor changes: could not get MainTabWindow_Wildlife");
                        return(true);
                    }                  // fail gracefully.
                    var table = (PawnTable)typeof(MainTabWindow_PawnTable).GetField("table",
                                                                                    BindingFlags.Instance |
                                                                                    BindingFlags.NonPublic |
                                                                                    BindingFlags.GetField)
                                .GetValue(mtw as MainTabWindow_PawnTable); // because table is a _PawnTable var
                    if (table == null)
                    {
                        // If the player has never opened the Wildlife window:
                        mtw.Notify_ResolutionChanged(); // force building table
                        table = (PawnTable)typeof(MainTabWindow_PawnTable).GetField("table",
                                                                                    BindingFlags.Instance |
                                                                                    BindingFlags.NonPublic |
                                                                                    BindingFlags.GetField)
                                .GetValue(mtw as MainTabWindow_PawnTable);
                    }
                    listOfSimilarPawns = table.PawnsListForReading;
                }
            } // end else //animal
            int index = listOfSimilarPawns.IndexOf(selPawn);

            if (index == -1)
            {
                return(true);           // not found; who knows what went wrong
            }
            if (goToNext)
            {
                index++; // go to next, eh?
                if (index >= listOfSimilarPawns.Count)
                {
                    index = 0;
                }
            }
            else
            {
                index--;
                if (index < 0)
                {
                    index = listOfSimilarPawns.Count - 1;
                }
            }
            CameraJumper.TryJumpAndSelect(listOfSimilarPawns[index]);
            return(false);
        }