Ludeon Forums

RimWorld => Mods => Help => Topic started by: WorldOfIllusion on April 26, 2014, 11:17:20 AM

Title: On Storage (SlotGroupParent) and ITab_Storage
Post by: WorldOfIllusion on April 26, 2014, 11:17:20 AM
I have been working on making something with functionality similar to a hopper. In doing so, I have implemented the interface SlotGroupParent that seems to be responsible for storage in rimworld. I have implemented all the methods as they have been implemented in Building_Storage (I think, will add code below).
Here's where the issue is. I want to then implement the ITab_Storage so that users can designate what will be stored in the building.
XML Excerpt:
<fixedStorageSettings>
<priority>Normal</priority>
<allowances>
<categories>
<li>Manufactured</li>
<li>ResourcesRaw</li>
</categories>
</allowances>
</fixedStorageSettings>
<defaultStorageSettings>
<priority>Normal</priority>
<allowances>
<categories>
<li>Manufactured</li>
<li>ResourcesRaw</li>
</categories>
</allowances>
</defaultStorageSettings>
<inspectorTabs>
<li>UI.ITab_Storage</li>
</inspectorTabs>


Code implementing SlotGroupParent:
    public class Accessor : DBuilding, SlotGroupParent
    {
        public Enum.accessorMode mode
        {
            get
            {
                return ((Digitisation.AccessorProperties)def).mode;
            }
        }
        public int speed
        {
            get
            {
                return ((Digitisation.AccessorProperties)def).speed;
            }
        }
        public ThingDef item;
        public StorageSettings settings;
        public SlotGroup slotGroup;
        private List<IntVec3> cachedOccupiedSquares;

        public override void SpawnSetup()
        {
            base.SpawnSetup();
            slotGroup = new SlotGroup(this);
            cachedOccupiedSquares = this.AllSlotSquares().ToList<IntVec3>();
        }

        public override void PostMake()
        {
            base.PostMake();
            settings = new StorageSettings(this);
            if (def.defaultStorageSettings != null)
                settings.CopyFrom(def.defaultStorageSettings);
        }

        public override void Tick()
        {
            base.Tick();
        }

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_Deep.LookDeep<StorageSettings>(ref settings, "settings", this);
        }

        public override void Destroy()
        {
            slotGroup.Notify_ParentDestroying();
            base.Destroy();
        }

        public virtual IEnumerable<IntVec3> AllSlotSquares()
        {
            foreach (IntVec3 sq in GenAdj.SquaresOccupiedBy(this))
            {
                yield return sq;
            }
        }

        public List<IntVec3> AllSlotSquaresListFast()
        {
            return cachedOccupiedSquares;
        }

        public StorageSettings GetParentStoreSettings()
        {
            return def.fixedStorageSettings;
        }

        public StorageSettings GetStoreSettings()
        {
            return settings;
        }

        public void Notify_LostThing(Thing newItem)
        {
           
        }

        public void Notify_ReceivedThing(Thing newItem)
        {
           
        }

        public string SlotYielderLabel()
        {
            return Label;
        }

*note* DBuilding just extends Building

Now, when I click to open the UI the game's control freezes (colonists move in background but I can't click anything) and the log gets filled with the following over and over:
InvalidCastException: Cannot cast from source type to destination type.
  at UI.ITab_Storage.FillTab () [0x00000] in <filename unknown>:0

  at UI.ITab.DoTabGui () [0x00000] in <filename unknown>:0

  at UI.InspectPane.DoTabs (IEnumerable`1 tabs) [0x00000] in <filename unknown>:0

  at UI.InspectPane.InspectPaneOnGUI () [0x00000] in <filename unknown>:0

  at UI.TabInspect.PanelOnGUI (Rect fillRect) [0x00000] in <filename unknown>:0

  at UI.UIPanel.PanelOnGUI () [0x00000] in <filename unknown>:0

  at UI.MainTabsRoot.GameControlsOnGUI () [0x00000] in <filename unknown>:0

  at UI.UIMapRoot.UIRootOnGUI () [0x00000] in <filename unknown>:0

  at Root.OnGUI () [0x00000] in <filename unknown>:0

(Filename:  Line: -1)


Not sure what I'm doing wrong or what's really going on here. Any help at all would be appreciated.
Title: Re: On Storage (SlotGroupParent) and ITab_Storage
Post by: Tynan on April 26, 2014, 01:02:20 PM
This is the FillTab code. All I could suggest is that you're passing something that is not a SlotGroupParent and it fails on the cast to SlotGroupParent. Make sure your thing is actually using the correct ThingClass.



protected override void FillTab()
{
KnowledgeDatabase.KnowledgeDemonstrated( ConceptDefOf.StorageTab, KnowledgeAmount.GuiFrame );

Find.ConceptTracker.TeachOpportunity( ConceptDefOf.StorageTabCategories, OpportunityType.GuiFrame );
Find.ConceptTracker.TeachOpportunity( ConceptDefOf.StoragePriority, OpportunityType.GuiFrame );


StorageSettings settings = ((SlotGroupParent)Find.Selector.Selected.First()).GetStoreSettings();

Rect inRect = new Rect(0,0,WinSize.x, WinSize.y).GetInnerRect(GenUI.Pad);
GUI.BeginGroup(inRect);
{

//Priority setting
{
GenFont.SetFontSmall();

Rect labRect = new Rect(0,0,150,TopAreaHeight-6);
GUI.Label( labRect, "Priority".Translate() + ": " );

Rect butRect = new Rect(100,0,130,TopAreaHeight-6);
if( Widgets.TextButton( butRect, settings.priority.Label() ) )
{
List<FloatMenuOption> opts = new List<FloatMenuOption>();

foreach( StoragePriority pr in System.Enum.GetValues( typeof(StoragePriority)))
{
if( pr == StoragePriority.Unstored )
continue;

StoragePriority localPr = pr;
opts.Add( new FloatMenuOption( localPr.Label(), ()=>
{
settings.priority = localPr;
KnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.StoragePriority, KnowledgeAmount.Total);
}) );
}

Find.LayerStack.Add( new Layer_FloatMenu(opts) );
}

TutorUIHighlighter.HighlightOpportunity( "StoragePriority", butRect );
}

ThingFilter parentAllowances = null;
if (settings.owner.GetParentStoreSettings() != null)
parentAllowances = settings.owner.GetParentStoreSettings().allowances;


//Configure allowances
Rect outRect = new Rect(0,TopAreaHeight,inRect.width,inRect.height-TopAreaHeight);

ThingFilterGui.DoThingFilterConfigWindow( outRect,
  ref scrollPosition,
  settings.allowances,
  parentAllowances);

}
GUI.EndGroup();

}