internal void SaveDeathContent(InventoryGeneric inventory, IPlayer player) { ICoreAPI api = player.Entity?.Api; if (api == null) { throw new NullReferenceException("player.Entity.api is null"); } string datapath = api.GetOrCreateDataPath($"ModData/{api.GetWorldId()}/{ConstantsCore.ModId}/{player.PlayerUID}"); string[] files = Directory.GetFiles(datapath).OrderByDescending(f => new FileInfo(f).Name).ToArray(); for (int i = files.Count() - 1; i > Config.Current.MaxDeathContentSavedPerPlayer.Val - 2; i--) { File.Delete(files[i]); } TreeAttribute tree = new TreeAttribute(); inventory.ToTreeAttributes(tree); string name = "inventory-" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".dat"; File.WriteAllBytes($"{datapath}/{name}", tree.ToBytes()); }
internal InventoryGeneric LoadLastDeathContent(IPlayer player, int offset = 0) { ICoreAPI api = player.Entity?.Api; if (api == null) { throw new NullReferenceException("player.Entity.api is null"); } if (Config.Current.MaxDeathContentSavedPerPlayer.Val <= offset) { throw new IndexOutOfRangeException("offset is too large or save data disabled"); } string datapath = api.GetOrCreateDataPath($"ModData/{api.GetWorldId()}/{ConstantsCore.ModId}/{player.PlayerUID}"); string file = Directory.GetFiles(datapath).OrderByDescending(f => new FileInfo(f).Name).ToArray().ElementAt(offset); TreeAttribute tree = new TreeAttribute(); tree.FromBytes(File.ReadAllBytes(file)); InventoryGeneric inv = new InventoryGeneric(tree.GetInt("qslots"), "playercorpse-" + player.PlayerUID, api); inv.FromTreeAttributes(tree); return(inv); }
public override void GetHeldItemInfo(ItemSlot inSlot, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo) { base.GetHeldItemInfo(inSlot, dsc, world, withDebugInfo); float[] chances = new float[10]; ItemStack[] stacks = new ItemStack[10]; int i = 0; foreach (var val in inSlot.Itemstack.Attributes) { if (!val.Key.StartsWith("stack") || !(val.Value is TreeAttribute)) { continue; } TreeAttribute subtree = val.Value as TreeAttribute; if (i == 0) { dsc.AppendLine("Contents: "); } ItemStack cstack = subtree.GetItemstack("stack"); cstack.ResolveBlockOrItem(world); dsc.AppendLine(cstack.StackSize + "x " + cstack.GetName() + ": " + subtree.GetFloat("chance") + "%"); i++; } }
public bool MergeWith(TreeAttribute blockEntityAttributes) { InventoryGeneric otherinv = new InventoryGeneric(1, BlockCode, null, null, null); otherinv.FromTreeAttributes(blockEntityAttributes.GetTreeAttribute("inventory")); otherinv.Api = Api; otherinv.ResolveBlocksOrItems(); if (!inventory[0].Empty && otherinv[0].Itemstack.Equals(Api.World, inventory[0].Itemstack, GlobalConstants.IgnoredStackAttributes)) { int quantityToMove = Math.Min(otherinv[0].StackSize, Math.Max(0, MaxStackSize - inventory[0].StackSize)); inventory[0].Itemstack.StackSize += quantityToMove; otherinv[0].TakeOut(quantityToMove); if (otherinv[0].StackSize > 0) { BlockPos uppos = Pos.UpCopy(); Block upblock = Api.World.BlockAccessor.GetBlock(uppos); if (upblock.Replaceable > 6000) { ((IBlockItemPile)Block).Construct(otherinv[0], Api.World, uppos, null); } } MarkDirty(true); TriggerPileChanged(); } return(true); }
public override void FromBytes(BinaryReader reader, bool forClient) { base.FromBytes(reader, forClient); initialPos = new BlockPos(); initialPos.X = reader.ReadInt32(); initialPos.Y = reader.ReadInt32(); initialPos.Z = reader.ReadInt32(); blockCode = new AssetLocation(reader.ReadString()); bool beIsNull = reader.ReadBoolean(); if (!beIsNull) { blockEntityAttributes = new TreeAttribute(); blockEntityAttributes.FromBytes(reader); blockEntityClass = reader.ReadString(); } if (WatchedAttributes.HasAttribute("fallSound")) { fallSound = new AssetLocation(WatchedAttributes.GetString("fallSound")); } canFallSideways = WatchedAttributes.GetBool("canFallSideways"); dustIntensity = WatchedAttributes.GetFloat("dustIntensity"); DoRemoveBlock = reader.ReadBoolean(); }
public override void OnStoreCollectibleMappings(IWorldAccessor world, ItemSlot inSlot, Dictionary <int, AssetLocation> blockIdMapping, Dictionary <int, AssetLocation> itemIdMapping) { base.OnStoreCollectibleMappings(world, inSlot, blockIdMapping, itemIdMapping); foreach (var val in inSlot.Itemstack.Attributes) { if (!val.Key.StartsWith("stack") || !(val.Value is TreeAttribute)) { continue; } TreeAttribute subtree = val.Value as TreeAttribute; ItemStack cstack = subtree.GetItemstack("stack"); cstack.ResolveBlockOrItem(world); if (cstack.Class == EnumItemClass.Block) { blockIdMapping[cstack.Id] = cstack.Collectible.Code; } else { itemIdMapping[cstack.Id] = cstack.Collectible.Code; } } }
public override void OnHeldInteractStart(IItemSlot itemslot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, ref EnumHandHandling handling) { if (byEntity.World.Side != EnumAppSide.Server) { handling = EnumHandHandling.PreventDefault; return; } IPlayer byPlayer = null; if (byEntity is IEntityPlayer) { byPlayer = byEntity.World.PlayerByUid(((IEntityPlayer)byEntity).PlayerUID); } if (!(byPlayer is IServerPlayer)) { return; } IServerPlayer serverplayer = byPlayer as IServerPlayer; TreeAttribute tree = new TreeAttribute(); tree.SetString("playeruid", byPlayer?.PlayerUID); tree.SetString("category", itemslot.Itemstack.Attributes.GetString("category")); tree.SetItemstack("itemstack", itemslot.Itemstack.Clone()); api.Event.PushEvent("loreDiscovery", tree); itemslot.TakeOut(1); itemslot.MarkDirty(); handling = EnumHandHandling.PreventDefault; }
protected void SyncToNetworkInventory() { TreeAttribute tree = new TreeAttribute(); Inventory.ToTreeAttributes(tree); Api.ModLoader.GetModSystem <TradeRoutesSystem>().TradeRoutesHandler.SyncInventories(this.blockEnityId, this.networkId, tree.ToBytes()); }
private void OnLoreDiscovery(string eventName, ref EnumHandling handling, IAttribute data) { TreeAttribute tree = data as TreeAttribute; string playerUid = tree.GetString("playeruid"); string category = tree.GetString("category"); IServerPlayer plr = sapi.World.PlayerByUid(playerUid) as IServerPlayer; LoreDiscovery discovery = TryGetRandomLoreDiscovery(sapi.World, plr, category); if (discovery == null) { plr.SendMessage(GlobalConstants.GeneralChatGroup, Lang.Get("Nothing new in these pages"), EnumChatType.Notification); return; } ItemSlot itemslot = plr.InventoryManager.ActiveHotbarSlot; itemslot.TakeOut(1); itemslot.MarkDirty(); plr.Entity.World.PlaySoundAt(new AssetLocation("sounds/effect/writing"), plr.Entity); handling = EnumHandling.PreventDefault; DiscoverLore(discovery, plr); }
public static void SetBlockPosArray(this TreeAttribute tree, string key, BlockPos[] value) { lock (tree.attributesLock) { tree[key] = new BlockPosArrayAttribute(value); } }
private IDictionary <string, TreeSearchResult> GetTreeSearchResultStructure() { Dictionary <string, TreeSearchResult> result = new Dictionary <string, TreeSearchResult>(); string[] allowedSections = Security.CurrentUser.AllowedSections.ToArray(); IReadOnlyDictionary <string, SearchableApplicationTree> searchableTrees = SearchableTreeResolver.Current.GetSearchableTrees(); foreach (var searchableTree in searchableTrees) { if (allowedSections.Contains(searchableTree.Value.AppAlias)) { ApplicationTree tree = Services.ApplicationTreeService.GetByAlias(searchableTree.Key); if (tree == null) { continue; //shouldn't occur } SearchableTreeAttribute searchableTreeAttribute = searchableTree.Value.SearchableTree.GetType().GetCustomAttribute <SearchableTreeAttribute>(false); TreeAttribute treeAttribute = GetTreeAttribute(tree); result[GetRootNodeDisplayName(treeAttribute, Services.TextService)] = new TreeSearchResult { Results = Enumerable.Empty <SearchResultItem>(), TreeAlias = searchableTree.Key, AppAlias = searchableTree.Value.AppAlias, JsFormatterService = searchableTreeAttribute == null ? "" : searchableTreeAttribute.ServiceName, JsFormatterMethod = searchableTreeAttribute == null ? "" : searchableTreeAttribute.MethodName }; } } return(result); }
internal void ResolveLoot(ItemSlot slot, InventoryBase inventory, IWorldAccessor worldForResolve) { double diceRoll = worldForResolve.Rand.NextDouble(); ItemStack ownstack = slot.Itemstack; slot.Itemstack = null; IAttribute[] vals = ownstack.Attributes.Values; vals.Shuffle(worldForResolve.Rand); foreach (var val in vals) { if (!(val is TreeAttribute)) { continue; } TreeAttribute subtree = val as TreeAttribute; float chance = subtree.GetFloat("chance") / 100f; if (chance > diceRoll) { ItemStack cstack = subtree.GetItemstack("stack"); cstack.ResolveBlockOrItem(worldForResolve); slot.Itemstack = cstack; return; } diceRoll -= chance; } }
public override void FromTreeAtributes(ITreeAttribute tree, IWorldAccessor worldForResolving) { base.FromTreeAtributes(tree, worldForResolving); nutrients[0] = tree.GetFloat("n"); nutrients[1] = tree.GetFloat("p"); nutrients[2] = tree.GetFloat("k"); lastWateredTotalHours = tree.GetDouble("lastWateredTotalHours"); originalFertility = tree.GetInt("originalFertility"); if (tree.HasAttribute("totalHoursForNextStage")) { totalHoursForNextStage = tree.GetDouble("totalHoursForNextStage"); totalHoursFertilityCheck = tree.GetDouble("totalHoursFertilityCheck"); } else { // Pre v1.5.1 totalHoursForNextStage = tree.GetDouble("totalDaysForNextStage") * 24; totalHoursFertilityCheck = tree.GetDouble("totalDaysFertilityCheck") * 24; } TreeAttribute cropAttrs = tree["cropAttrs"] as TreeAttribute; if (cropAttrs == null) { cropAttrs = new TreeAttribute(); } }
public override void Initialize(EntityProperties properties, JsonObject typeAttributes) { inv = new InventoryGeneric(typeAttributes["quantitySlots"].AsInt(4), "harvestableContents-" + entity.EntityId, entity.Api); TreeAttribute tree = entity.WatchedAttributes["harvestableInv"] as TreeAttribute; if (tree != null) { inv.FromTreeAttributes(tree); } inv.PutLocked = true; if (entity.World.Side == EnumAppSide.Server) { inv.SlotModified += Inv_SlotModified; inv.OnInventoryClosed += Inv_OnInventoryClosed; } base.Initialize(properties, typeAttributes); if (entity.World.Side == EnumAppSide.Server) { jsonDrops = typeAttributes["drops"].AsObject <BlockDropItemStack[]>(); } baseHarvestDuration = typeAttributes["duration"].AsFloat(5); }
public override void ToTreeAttributes(ITreeAttribute tree) { base.ToTreeAttributes(tree); ITreeAttribute invtree = new TreeAttribute(); Inventory.ToTreeAttributes(invtree); tree["inventory"] = invtree; tree.SetFloat("inputGrindTime", inputGrindTime); tree.SetInt("nowOutputFace", nowOutputFace); List <int> vals = new List <int>(); foreach (var val in playersGrinding) { IPlayer plr = Api.World.PlayerByUid(val.Key); if (plr == null) { continue; } vals.Add(plr.ClientId); } tree["clientIdsGrinding"] = new IntArrayAttribute(vals.ToArray()); }
private void PickupFarmland(ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel) { Block block = byEntity.World.BlockAccessor.GetBlock(blockSel.Position); if (block is BlockFarmland) { BlockEntity blockEntity = byEntity.World.BlockAccessor.GetBlockEntity(blockSel.Position); if (blockEntity is BlockEntityFarmland) { TreeAttribute tree = new TreeAttribute(); blockEntity.ToTreeAttributes(tree); slot.Itemstack.Attributes["farmland"] = tree; slot.Itemstack.Attributes.SetInt("farmId", byEntity.World.BlockAccessor.GetBlock(blockSel.Position).Id); byEntity.World.BlockAccessor.SetBlock(0, blockSel.Position); // BlockPos cropPos = blockSel.Position.AddCopy(0, 1, 0); byEntity.World.BlockAccessor.TriggerNeighbourBlockUpdate(blockSel.Position); // Block seedBlock = byEntity.World.BlockAccessor.GetBlock(cropPos); // if (seedBlock is BlockCrop) // { // byEntity.World.BlockAccessor.BreakBlock(cropPos, byEntity as IPlayer); // } slot.MarkDirty(); } } }
public override void OnReceivedClientPacket(IServerPlayer player, int packetid, byte[] data) { if (packetid < 1000) { Inventory.InvNetworkUtil.HandleClientPacket(player, packetid, data); return; } if (packetid == 1000) { EnumTransactionResult result = Inventory.TryBuySell(player); if (result == EnumTransactionResult.Success) { (Api as ICoreServerAPI).WorldManager.GetChunk(ServerPos.AsBlockPos)?.MarkModified(); AnimManager.StopAnimation("idle"); AnimManager.StartAnimation(new AnimationMetaData() { Animation = "nod", Code = "nod", Weight = 10, EaseOutSpeed = 10000, EaseInSpeed = 10000 }); TreeAttribute tree = new TreeAttribute(); Inventory.ToTreeAttributes(tree); (Api as ICoreServerAPI).Network.BroadcastEntityPacket(EntityId, 1234, tree.ToBytes()); } } }
public override void OnReceivedServerPacket(int packetid, byte[] data) { if (packetid == (int)EnumBlockStovePacket.OpenGUI) { using (MemoryStream ms = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(ms); string dialogClassName = reader.ReadString(); string dialogTitle = reader.ReadString(); TreeAttribute tree = new TreeAttribute(); tree.FromBytes(reader); Inventory.FromTreeAttributes(tree); Inventory.ResolveBlocksOrItems(); IClientWorldAccessor clientWorld = (IClientWorldAccessor)api.World; //clientWorld.OpenDialog(dialogClassName, dialogTitle, Inventory); } } if (packetid == (int)EnumBlockContainerPacketId.CloseInventory) { IClientWorldAccessor clientWorld = (IClientWorldAccessor)api.World; clientWorld.Player.InventoryManager.CloseInventory(Inventory); } }
/// <summary> Update the internal tree </summary> public void UpdateTree() { if (Entity != null) { allomancyTree = (TreeAttribute)Entity.WatchedAttributes.GetTreeAttribute("allomancy"); } }
public override void OnReceivedServerPacket(int packetid, byte[] data) { if (packetid == (int)EnumBlockStovePacket.OpenGUI) { using (MemoryStream memoryStream = new MemoryStream(data)) { BinaryReader stream = new BinaryReader((Stream)memoryStream); stream.ReadString(); string DialogTitle = stream.ReadString(); TreeAttribute treeAttribute = new TreeAttribute(); treeAttribute.FromBytes(stream); Inventory.FromTreeAttributes(treeAttribute); Inventory.ResolveBlocksOrItems(); IClientWorldAccessor world = (IClientWorldAccessor)api.World; SyncedTreeAttribute tree = new SyncedTreeAttribute(); SetDialogValues(tree); clientDialog = new GuiDialogBlockEntityQuern(DialogTitle, Inventory, pos, tree, api as ICoreClientAPI); clientDialog.TryOpen(); clientDialog.OnClosed += (Vintagestory.API.Common.Action)(() => clientDialog = null); } } if (packetid == (int)EnumBlockContainerPacketId.CloseInventory) { IClientWorldAccessor clientWorld = (IClientWorldAccessor)api.World; clientWorld.Player.InventoryManager.CloseInventory(Inventory); } }
private bool OnHotkeyJournal(KeyCombination comb) { if (dialog != null) { dialog.TryClose(); dialog = null; return(true); } TreeAttribute tree = new TreeAttribute(); foreach (var entry in ownJournal.Entries) { string[] chapters = new string[entry.Chapters.Count]; for (int i = 0; i < chapters.Length; i++) { chapters[i] = entry.Chapters[i].Text; } tree[entry.Title] = new StringArrayAttribute(chapters); } dialog = new GuiDialogJournal(tree, capi); dialog.TryOpen(); dialog.OnClosed += () => dialog = null; return(true); }
public EntityBehaviorEmotionStates(Entity entity) : base(entity) { try { if (entity.Attributes.HasAttribute("emotionstatesById")) { entityAttrById = (TreeAttribute)entity.Attributes["emotionstatesById"]; foreach (var val in entityAttrById) { ActiveStatesById[val.Key.ToInt(0)] = (float)val.Value.GetValue(); } } else { entity.Attributes["emotionstatesById"] = entityAttrById = new TreeAttribute(); } } catch { entity.Attributes["emotionstatesById"] = entityAttrById = new TreeAttribute(); } if (entity.Attributes.HasAttribute("emotionstates")) { entityAttr = entity.Attributes["emotionstates"] as TreeAttribute; } else { entity.Attributes["emotionstates"] = entityAttr = new TreeAttribute(); } }
public override bool OnPlayerRightClick(IPlayer byPlayer, BlockSelection blockSel) { if (blockSel.SelectionBoxIndex == 1) { return(false); } if (api.World is IServerWorldAccessor) { byte[] data; using (MemoryStream ms = new MemoryStream()) { BinaryWriter writer = new BinaryWriter(ms); writer.Write("BEMortarAndPestle"); writer.Write(DialogTitle); TreeAttribute tree = new TreeAttribute(); inventory.ToTreeAttributes(tree); tree.ToBytes(writer); data = ms.ToArray(); } ((ICoreServerAPI)api).Network.SendBlockEntityPacket( (IServerPlayer)byPlayer, pos.X, pos.Y, pos.Z, (int)EnumBlockStovePacket.OpenGUI, data ); byPlayer.InventoryManager.OpenInventory(inventory); } return(true); }
private MeshRef CreateModel(ItemStack forStack) { ITreeAttribute tree = forStack.Attributes; if (tree == null) { tree = new TreeAttribute(); } int[] materials = BlockEntityChisel.MaterialIdsFromAttributes(tree, capi.World); uint[] cuboids = (tree["cuboids"] as IntArrayAttribute)?.AsUint; // When loaded from json if (cuboids == null) { cuboids = (tree["cuboids"] as LongArrayAttribute)?.AsUint; } List <uint> voxelCuboids = cuboids == null ? new List <uint>() : new List <uint>(cuboids); MeshData mesh = BlockEntityChisel.CreateMesh(capi, voxelCuboids, materials); //mesh.Rgba2 = null; return(capi.Render.UploadMesh(mesh)); }
public void MountableToTreeAttributes(TreeAttribute tree) { tree.SetString("className", "bed"); tree.SetInt("posx", pos.X); tree.SetInt("posy", pos.Y); tree.SetInt("posz", pos.Z); }
public override void OnReceivedServerPacket(int packetid, byte[] data) { if (packetid == (int)EnumBlockStovePacket.OpenGUI) { using (MemoryStream ms = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(ms); string dialogClassName = reader.ReadString(); string dialogTitle = reader.ReadString(); TreeAttribute tree = new TreeAttribute(); tree.FromBytes(reader); Inventory.FromTreeAttributes(tree); Inventory.ResolveBlocksOrItems(); IClientWorldAccessor clientWorld = (IClientWorldAccessor)api.World; SyncedTreeAttribute dtree = new SyncedTreeAttribute(); SetDialogValues(dtree); clientDialog = new GuiDialogBlockEntityQuern(dialogTitle, Inventory, pos, dtree, api as ICoreClientAPI); clientDialog.TryOpen(); } } if (packetid == (int)Vintagestory.API.Client.EnumBlockContainerPacketId.CloseInventory) { IClientWorldAccessor clientWorld = (IClientWorldAccessor)api.World; clientWorld.Player.InventoryManager.CloseInventory(Inventory); } }
public override void OnBlockPlaced(ItemStack byItemStack = null) { BlockCookedContainer blockpot = byItemStack?.Block as BlockCookedContainer; if (blockpot != null) { TreeAttribute tempTree = byItemStack.Attributes?["temperature"] as TreeAttribute; ItemStack[] stacks = blockpot.GetNonEmptyContents(Api.World, byItemStack); for (int i = 0; i < stacks.Length; i++) { ItemStack stack = stacks[i].Clone(); Inventory[i].Itemstack = stack; // Clone temp attribute if (tempTree != null) { stack.Attributes["temperature"] = tempTree.Clone(); } } RecipeCode = blockpot.GetRecipeCode(Api.World, byItemStack); QuantityServings = blockpot.GetServings(Api.World, byItemStack); } if (Api.Side == EnumAppSide.Client) { currentMesh = GenMesh(); MarkDirty(true); } }
public override void ToBytes(BinaryWriter writer, bool forClient) { if (!forClient) { ITreeAttribute ctree = new TreeAttribute(); WatchedAttributes["commandQueue"] = ctree; ITreeAttribute commands = new TreeAttribute(); ctree["commands"] = commands; int i = 0; foreach (var val in Commands) { ITreeAttribute attr = new TreeAttribute(); val.ToAttribute(attr); attr.SetString("type", val.Type); commands["cmd" + i] = attr; i++; } } base.ToBytes(writer, forClient); }
public override bool OnPlayerRightClick(IPlayer byPlayer, BlockSelection blockSel) { if (api.World is IServerWorldAccessor) { byte[] data; using (MemoryStream ms = new MemoryStream()) { BinaryWriter writer = new BinaryWriter(ms); writer.Write("BlockEntityInventory"); writer.Write(Lang.Get(dialogTitleLangCode)); writer.Write((byte)4); TreeAttribute tree = new TreeAttribute(); inventory.ToTreeAttributes(tree); tree.ToBytes(writer); data = ms.ToArray(); } ((ICoreServerAPI)api).Network.SendBlockEntityPacket( (IServerPlayer)byPlayer, pos.X, pos.Y, pos.Z, (int)EnumBlockContainerPacketId.OpenInventory, data ); byPlayer.InventoryManager.OpenInventory(inventory); } return(true); }
public override void OnReceivedServerPacket(int packetid, byte[] data) { IClientWorldAccessor clientWorld = (IClientWorldAccessor)Api.World; if (packetid == (int)EnumBlockContainerPacketId.OpenInventory) { if (invDialog != null) { if (invDialog?.IsOpened() == true) { invDialog.TryClose(); } invDialog?.Dispose(); invDialog = null; return; } string dialogClassName; string dialogTitle; int cols; TreeAttribute tree = new TreeAttribute(); using (MemoryStream ms = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(ms); dialogClassName = reader.ReadString(); dialogTitle = reader.ReadString(); cols = reader.ReadByte(); tree.FromBytes(reader); } Inventory.FromTreeAttributes(tree); Inventory.ResolveBlocksOrItems(); invDialog = new GuiDialogBlockEntityInventory(dialogTitle, Inventory, Pos, cols, Api as ICoreClientAPI); Block block = Api.World.BlockAccessor.GetBlock(Pos); string os = block.Attributes?["openSound"]?.AsString(); string cs = block.Attributes?["closeSound"]?.AsString(); AssetLocation opensound = os == null ? null : AssetLocation.Create(os, block.Code.Domain); AssetLocation closesound = cs == null ? null : AssetLocation.Create(cs, block.Code.Domain); invDialog.OpenSound = opensound ?? this.OpenSound; invDialog.CloseSound = closesound ?? this.CloseSound; invDialog.TryOpen(); } if (packetid == (int)EnumBlockEntityPacketId.Close) { clientWorld.Player.InventoryManager.CloseInventory(Inventory); if (invDialog?.IsOpened() == true) { invDialog?.TryClose(); } invDialog?.Dispose(); invDialog = null; } }