My Seasonal Wardrobe mod is working!!!

Started by Friedmutant, February 12, 2015, 12:13:47 AM

Previous topic - Next topic

Friedmutant

I'm really jazzed about my progress so far.  My mod adds a wardrobe to the game, which is essentially just a re-purposed equipment rack, but only for apparel.

I've implemented a state-machine with the wardrobe so that during warm seasons (Spring, Summer) cold-weather clothing will be stored in the wardrobe.  During cold seasons (Fall, Winter) warm-weather clothing will be stored.  When the seasons change, the pawn that owns the wardrobe will change clothing as appropriate.  Further, the state-machine allows only one head item and one torso item at a time.  Cold weather clothing is anything that has a negative value for ComfyTemperatureMax, which is currently just tuques and parkas for vanilla apparel.

I owe a large amount of thanks to Haplo and Rikiki and some others whose code I've been studying.  Thank you for sharing!

Some things left to do:

  • Figure out how to present dialogs.  I want to re-use the AssignOwner dialog for beds to allow players to manually re-assign wardrobes.
  • Implement ExposeData() for game saving
  • Figure out the magic sauce behind JobDrivers.  My is working perfectly, but I don't understand why.  I call it with an instance of my wardrobe Building, but the constructor takes a Pawn.  How does that even work?
  • Probably other little tweaks

It's been a really fun project to work on.

mrofa

Did something similar in clutter mod maybe it will help


using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
using Verse.AI;
using Verse.Noise;
using Verse.Sound;
using VerseBase;
using RimWorld;
using System;

namespace ClutterModule
{
    class ClothLocker : Building
    {
        private int counter = 0;
        private Pawn OwnerPawn;
        private int TxtCounter = 0;
        private int txtpos = 0;
        private bool Stored = false;
        private bool PawnArrival = false;
        private bool ChangeClothArrival = false;
        private int WornCount = 0;
        private List<Apparel> NewClothSetList = new List<Apparel>();
        private List<Apparel> StoredClothSetList = new List<Apparel>();
        private List<string> EmptyTxt = new List<string>
{
            " Empty",
            " Only darkness",
            " Concentrated dust",
            " Reverse engineered sock"
           
};

        public override void SpawnSetup()
        {
            base.SpawnSetup();
            txtpos = UnityEngine.Random.Range(1, EmptyTxt.Count);
        }
        public override void ExposeData()
        {
            base.ExposeData();
           
            Scribe_Values.LookValue<int>(ref counter, "counter");
            Scribe_Values.LookValue<int>(ref txtpos, "txtpos");
            Scribe_Values.LookValue<int>(ref TxtCounter, "TxtCounter");
            Scribe_Values.LookValue<bool>(ref PawnArrival, "PawnArrival");
            Scribe_Values.LookValue<bool>(ref ChangeClothArrival, "ChangeClothArrival");
            Scribe_Collections.LookList<Apparel>(ref this.NewClothSetList, "NewClothSetList", LookMode.Deep, null);
            Scribe_Collections.LookList<Apparel>(ref this.StoredClothSetList, "StoredClothSetList", LookMode.Deep, null);
            Scribe_References.LookReference<Pawn>(ref OwnerPawn, "OwnerPawn");



        }
        private void ClothChange()
        {
            if(!Stored)
            {
                if (NewClothSetList.Count == WornCount || WornCount == 0)
                {
                    Stored = true;
                    OwnerPawn.drawer.rotator.FaceSquare(this.Position);
                }
               
                if (OwnerPawn.apparel.WornApparelListForReading.Count > 0)
                {
                    Apparel s = OwnerPawn.apparel.WornApparelListForReading.First();
                    NewClothSetList.Add(s);
                    OwnerPawn.apparel.TryDrop(s, out s, base.Position, true);
                    s.DeSpawn();
                }
               
            }

            else if (Stored)
            {
                if(StoredClothSetList.Count>0)
                {
                    foreach(Apparel thing in StoredClothSetList)
                    {
                        OwnerPawn.apparel.Wear(thing, false);
                       
                    }
                    StoredClothSetList.Clear();
                   
                }
                else if (StoredClothSetList.Count <=0)
                {
                    StoredClothSetList=NewClothSetList;
                    NewClothSetList = new List<Apparel>();
                    ChangeClothArrival=false;
                    Stored = false;
                    WornCount = 0;
                    txtpos = UnityEngine.Random.Range(1, EmptyTxt.Count);
                    counter = 0;
                }
           
             
            }
            this.OwnerPawn.drawer.renderer.graphics.ResolveApparelGraphics();
        }

        //Puff stuff
        public void PuffThing()
        {

            for (int i = 0; i < 30; i++)
            {
                MoteMaker.ThrowAirPuffUp(this.DrawPos, AltitudeLayer.PawnState);
            }
        }

        public override void Tick()
        {

            base.Tick();
            if (OwnerPawn != null)
            {
                                   
                    if (OwnerPawn.Position== this.InteractionCell && PawnArrival)
                    {
                        if (WornCount == 0 || WornCount < OwnerPawn.apparel.WornApparelCount)
                        {
                            WornCount = OwnerPawn.apparel.WornApparelCount;
                        }
                        Job job = new Job(JobDefOf.Wait, 50);
                        if(OwnerPawn.CurJob != job)
                        {
                            OwnerPawn.jobs.StopAll();
                            OwnerPawn.jobs.StartJob(job);
                            PawnArrival = false;
                        }
                       
                       

                    }
                    else if (OwnerPawn.Position == this.InteractionCell && ChangeClothArrival)
                    {
                        ClothChange();
                        if (Math.IEEERemainder((double)counter, (double)10.0f) == 1)
                        {
                            this.PuffThing();
                        }
                                               
                    }
                if(PawnArrival)
                {
                    counter += 1;
                    if (counter > 5000)
                    {
                        PawnArrival = false;
                        ChangeClothArrival = false;
                        Stored = false;
                        WornCount = 0;
                        counter = 0;
                    }
                }
                               
             }
            if(TxtCounter>20000)
            {
                txtpos = UnityEngine.Random.Range(1, EmptyTxt.Count);
                TxtCounter = 0;
            }
            TxtCounter += 1;
           
            }


       

        public override IEnumerable<FloatMenuOption> GetFloatMenuOptionsFor(Pawn myPawn)
        {



            List<FloatMenuOption> list = new List<FloatMenuOption>();

            {
                if (!myPawn.CanReserve(this, ReservationType.Use))
                {

                    FloatMenuOption item = new FloatMenuOption("CannotUseReserved", null);
                    return new List<FloatMenuOption>
{
item
};
                }
                if (!myPawn.CanReach(this, PathMode.Touch, Danger.Some))
                {
                    FloatMenuOption item2 = new FloatMenuOption("CannotUseNoPath", null);
                    return new List<FloatMenuOption>
{
item2
};

                }

                if (myPawn != OwnerPawn)
                {
                    Action action3 = delegate
                    {
                        OwnerPawn = myPawn;
                    };
                    list.Add(new FloatMenuOption("Make "+myPawn.Name.nick+" owner", action3));
                }



                if (StoredClothSetList.Count <= 0 && myPawn == OwnerPawn)
                {
                    Action action1 = delegate
                    {



                        Job job1 = new Job(JobDefOf.Goto, this.InteractionCell);
                        myPawn.playerController.TakeOrderedJob(job1);
                        OwnerPawn = myPawn;
                        myPawn.Reserve(this, ReservationType.Use);
                        PawnArrival = true;
                        ChangeClothArrival = true;
                       

                    };
                    list.Add(new FloatMenuOption("Store Cloth Set", action1));
                }
                if (StoredClothSetList.Count > 0 && myPawn == OwnerPawn)
                {
                    Action action2 = delegate
                      {



                          Job job1 = new Job(JobDefOf.Goto, this.InteractionCell);
                          myPawn.playerController.TakeOrderedJob(job1);
                          myPawn.Reserve(this, ReservationType.Use);
                          ChangeClothArrival = true;
                          PawnArrival = true;


                      };
                    list.Add(new FloatMenuOption("Switch Cloth Sets", action2));
                }

            }
            return list;
        }

        public override string GetInspectString()
        {
            StringBuilder stringBuilder = new StringBuilder();
            if (OwnerPawn != null)
            {
                stringBuilder.Append(this.def.label + " owner is " + OwnerPawn.Name.nick);
            }
            if (OwnerPawn == null)
            {
                stringBuilder.Append(this.def.label + " has no owner.");
            }

            stringBuilder.AppendLine();
           
                stringBuilder.Append("Stored stuff:");
                stringBuilder.AppendLine();
                if (StoredClothSetList.Count > 0 && StoredClothSetList != null)
            {
                for (int i = 0; i < StoredClothSetList.Count; i++)
                {
                    stringBuilder.Append(StoredClothSetList.ElementAt(i).def.label + ", ");
                }
            }
            if (StoredClothSetList.Count <= 0 && StoredClothSetList != null)
            {
                stringBuilder.Append(EmptyTxt.ElementAt(txtpos));
            }
            return stringBuilder.ToString();
        }

        public override void Destroy(DestroyMode mode = DestroyMode.Vanish)
        {
            if (StoredClothSetList.Count > 0 && (mode == DestroyMode.Deconstruct || mode == DestroyMode.Kill))
            {
               
                foreach(Apparel thing in StoredClothSetList)
                {
                  thing.Destroy();
                }
               
            }
            base.Destroy(mode);
        }
    }
}
All i do is clutter all around.

BajtMe

This sounds nothing short of awesome! Good luck with it and i hope to see it in the released section soon.  :)

Havan_IronOak

I just started using your mod the other day and it was SWEET!   But I do have an issue that I'm hoping you can straighten me out on...

I noticed that the PriorityHaul command was missing sometime after I loaded your mod. This was added via a mod called Priorityhaul by Gaesatae. Thinking that there was a conflict I tried moving PriorityHaul to the bottom in my ordered list of mods to add. That restored my ability to designate items for priority hauling but the three leftmost buttons that I see when I click on one of your smart wardrobes show red X icons though the labels beneath them; Assign Owner, Assign Owner of Room, and Reset Wardrobe do still appear.

I did try moving your mod below PriorityHaul in the mod load order but the red x issue remained. I'm NOT sure whether the three buttons still function as they used to. I'll advise more after a few experiments.