public EquipmentStatKey(ThingWithComps equipment)
 {
     equipmentDef = equipment.def;
     if (!equipment.TryGetQuality(out quality))
     {
         quality = QualityCategory.Normal;
     }
 }
        static private int CalculateTotalLootAffixPoints(ThingWithComps thing)
        {
            float ptsF = 0f;

            // Up to 6 points based on total wealth (1M max)
            float wealth = 0f;

            if (Current.ProgramState == ProgramState.Playing)    // don't bother while initializing
            {
                if (thing.Map != null && thing.Map.wealthWatcher != null)
                {
                    wealth = thing.Map.wealthWatcher.WealthTotal;
                }
                else if (Find.CurrentMap != null && Find.CurrentMap.wealthWatcher != null)
                {
                    wealth = Find.CurrentMap.wealthWatcher.WealthTotal;
                }
                else if (Find.World != null)
                {
                    wealth = Find.World.PlayerWealthForStoryteller;
                }
            }

            ptsF += Mathf.Min(wealth / 166_666, 6);

            // Up to 8 points based on item quality
            QualityCategory qc;

            thing.TryGetQuality(out qc);

            // Normal = 1, Good = 2, Excellent = 4, Masterwork = 6, Legendary = 8
            ptsF += Mathf.Pow((int)qc, 2f) / 4.5f;

            // Capped at 12
            ptsF = Mathf.Clamp(ptsF, 0, 12);

            return(Mathf.RoundToInt(ptsF));
        }
        public static void SpawnMeeseeks(Pawn creator, ThingWithComps creatingThing, Map map)
        {
            PawnKindDef pawnKindDef = MeeseeksDefOf.MeeseeksKind;

            Pawn mrMeeseeksLookAtMe = PawnGenerator.GeneratePawn(pawnKindDef, Faction.OfPlayer);

            lastCreatedMeeseeks = mrMeeseeksLookAtMe;

            QualityCategory boxQuality = QualityCategory.Normal;

            creatingThing.TryGetQuality(out boxQuality);

            int qualityInt = (int)boxQuality;

            float multiplier = ((float)qualityInt + 1.0f) / ((int)QualityCategory.Legendary + 1);
            int   skillLevel = Mathf.RoundToInt(multiplier * multiplier * 20.0f);

            // Enable all work types
            foreach (WorkTypeDef item in from w in DefDatabase <WorkTypeDef> .AllDefs
                     where !w.alwaysStartActive && !mrMeeseeksLookAtMe.WorkTypeIsDisabled(w)
                     select w)
            {
                // Our patch overrides the priority, but we need to make sure they are all on
                mrMeeseeksLookAtMe.workSettings.SetPriority(item, 3);
            }

            foreach (SkillRecord skill in mrMeeseeksLookAtMe.skills.skills)
            {
                skill.Level   = skillLevel;
                skill.passion = Passion.None;
            }

            // Max out needs
            foreach (Need need in mrMeeseeksLookAtMe.needs.AllNeeds)
            {
                if (need.def.defName != "Mood")
                {
                    need.CurLevelPercentage = 1.0f;
                }
            }

            IntVec3 summonPosition = MeeseeksUtility.FindSpawnPosition(creatingThing);

            GenSpawn.Spawn(mrMeeseeksLookAtMe, summonPosition, map);
            mrMeeseeksLookAtMe.Rotation = Rot4.South;

            CompMeeseeksMemory compMeeseeksMemory = mrMeeseeksLookAtMe.GetComp <CompMeeseeksMemory>();

            compMeeseeksMemory.SetQuality(boxQuality);
            compMeeseeksMemory.SetCreator(creator);

            // The voices for greeting and task acceptance can overlap depending on the speed the game is running,
            //   especially if another Meeseeks created us, so just don't do it in that case
            CompMeeseeksMemory creatorMemory = creator.GetComp <CompMeeseeksMemory>();
            bool creatorIsMeeseeks           = creatorMemory != null;

            if (!creatorIsMeeseeks)
            {
                MeeseeksUtility.PlayGreetingSound(mrMeeseeksLookAtMe, compMeeseeksMemory.Voice);
            }
            else
            {
                compMeeseeksMemory.temporarilyBlockTask = true;
            }

            Thing smoke = ThingMaker.MakeThing(ThingDefOf.Gas_Smoke);

            GenSpawn.Spawn(smoke, summonPosition, map);
            MeeseeksUtility.PlayPoofInSound(smoke);

            //ThingDef moteDef = DefDatabase<ThingDef>.GetNamedSilentFail("Mote_PsycastSkipOuterRingExit");
            //if (moteDef != null)
            //    MoteMaker.MakeAttachedOverlay(mrMeeseeksLookAtMe, moteDef, Vector3.zero, 1.0f);

            //GenExplosion.DoExplosion(mrMeeseeksLookAtMe.PositionHeld, mrMeeseeksLookAtMe.MapHeld, 1.0f, DamageDefOf.Smoke, null, -1, -1f, MeeseeksDefOf.CM_Meeseeks_Box_Poof_In, null, null, null, ThingDefOf.Gas_Smoke, 1f);

            GlobalTargetInfo meeseeksGlobalTarget = new GlobalTargetInfo(mrMeeseeksLookAtMe);

            if (!creatorIsMeeseeks && creator.IsColonistPlayerControlled && MeeseeksMod.settings.cameraJumpOnCreation)
            {
                CameraJumper.TryJump(meeseeksGlobalTarget);
            }

            if (!creatorIsMeeseeks && MeeseeksMod.settings.autoSelectOnCreation)
            {
                CameraJumper.TrySelect(meeseeksGlobalTarget);
            }

            if (!creatorIsMeeseeks && MeeseeksMod.settings.autoPauseOnCreation)
            {
                Find.TickManager.Pause();
            }
        }