Hi there! You are currently browsing as a guest. Why not create an account? Then you get less ads, can thank creators, post feedback, keep a list of your favourites, and more!
Quick Reply
Search this Thread
Field Researcher
Original Poster
#1 Old 26th Mar 2023 at 8:02 AM
Default I would like to make a shopping list UI for a Social Interaction between two sims.
I was wondering if anyone has ever made a custom shopping list. Similar to the grocery store. I am hoping to make a social interaction between two sims. In which a Arms Dealer sim (A NPC) can sells firearms to your sim. When your sim performs the purchase firearms interaction on a NPC Arms Dealer. A list will pop up with the firearms that you can purchase. alongside the prices for the firearms. I have looked in ILSpy to see how grocery stores perform this. However, I have questions. How do I make my own list of items with prices? This is the code I have looked at and believe is relevant.
Code:
public static void StartShopping(Sim customer, Dictionary<string, List<StoreItem>> itemDictionary, float percentPriceModifier, float salePercentage, int markupPercentage, string couponItemID, Inventory inventory, List<string> savedShoppingCart, ShoppingFinished finishedCallback, CreateSellableCallback createSellableCallback, bool sortedByDefault)
{
	IShoppingUIItem couponItem = null;
	List<IShopItem> loadedShoppingCart = new List<IShopItem>();
	Dictionary<string, List<IShoppingUIItem>> storeItemDictionary = CreateShoppingItemDictionary(customer, itemDictionary, loadedShoppingCart, savedShoppingCart, percentPriceModifier, salePercentage, markupPercentage, couponItemID, out couponItem, null);
	GameStates.TransitionToShoppingMode(storeItemDictionary, null, finishedCallback, createSellableCallback, customer, inventory, loadedShoppingCart, savedShoppingCart, couponItem, sortedByDefault);
}
//I believe this is in charge of getting the actual items for the list.
Code:
protected static Dictionary<string, List<IShoppingUIItem>> CreateShoppingItemDictionary(Sim customer, Dictionary<string, List<StoreItem>> itemDictionary, List<IShopItem> loadedShoppingCart, List<string> savedShoppingCart, float percentPriceModifier, float salePercentage, int markupPercentage, string couponItemID, out IShoppingUIItem couponItem, ItemValidityDelegate validityDelegate)
{
	Dictionary<string, List<IShoppingUIItem>> dictionary = new Dictionary<string, List<IShoppingUIItem>>();
	List<IShoppingUIItem> list = null;
	Dictionary<string, ShoppingCoupon> couponMap = CreateItemToCouponMap(customer);
	Dictionary<string, IShoppingUIItem> dictionary2 = new Dictionary<string, IShoppingUIItem>();
	WorldName currentWorld = GameUtils.GetCurrentWorld();
	WorldType currentWorldType = GameUtils.GetCurrentWorldType();
	foreach (KeyValuePair<string, List<StoreItem>> item in itemDictionary)
	{
		list = new List<IShoppingUIItem>();
		foreach (StoreItem item2 in item.Value)
		{
			if (item2.AllowedInWorld(currentWorldType) && (item2.AllowedWorlds == null || item2.AllowedWorlds.Count == 0 || item2.AllowedWorlds.Contains(currentWorld) || item2.AllowedWorlds.Contains(WorldName.Undefined)) && (validityDelegate == null || validityDelegate(item2)))
			{
				ShoppingUIItem shoppingUIItem = CreateUIItemFromStoreItem(item2, percentPriceModifier, salePercentage, markupPercentage, couponMap);
				list.Add(shoppingUIItem);
				if (!dictionary2.ContainsKey(shoppingUIItem.StoreUIItemID))
				{
					dictionary2.Add(shoppingUIItem.StoreUIItemID, shoppingUIItem);
				}
			}
		}
		if (list.Count > 0)
		{
			dictionary.Add(item.Key, list);
		}
	}
	if (savedShoppingCart != null)
	{
		foreach (string item3 in savedShoppingCart)
		{
			if (dictionary2.TryGetValue(item3, out var value))
			{
				loadedShoppingCart.Add(value);
			}
		}
	}
	if (couponItemID != null && dictionary2.ContainsKey(couponItemID))
	{
		couponItem = dictionary2[couponItemID];
	}
	else
	{
		couponItem = null;
	}
	return dictionary;
}
//These two classes I believe make the UI for the shopping list pop up.
Code:
public static void TransitionToShoppingMode(Dictionary<string, List<IShoppingUIItem>> storeItemDictionary, List<IShoppingUIRecipe> recipeList, ShoppingRabbitHole.ShoppingFinished finishedCallback, ShoppingRabbitHole.CreateSellableCallback createSellableCallback, Sim curCustomer, Inventory inventory, List<IShopItem> loadedShoppingCart, List<string> savedCart, IShopItem couponItem, bool sortedByDefault)
{
	if (sSingleton.mStateMachine.CurStateId == 4)
	{
		sSingleton.mInWorldState.GotoShoppingMode(storeItemDictionary, recipeList, finishedCallback, createSellableCallback, curCustomer, inventory, loadedShoppingCart, savedCart, couponItem, sortedByDefault);
	}
}
Code:
internal void GotoShoppingMode(Dictionary<string, List<IShoppingUIItem>> storeItemDictionary, List<IShoppingUIRecipe> recipeList, ShoppingRabbitHole.ShoppingFinished finishedCallback, ShoppingRabbitHole.CreateSellableCallback createSellableCallback, Sim curCustomer, Inventory inventory, List<IShopItem> loadedShoppingCart, List<string> savedCart, IShopItem couponItem, bool sortedByDefault)
{
	if (mSubStates[12] is ShoppingModeState shoppingModeState)
	{
		shoppingModeState.Populate(storeItemDictionary, recipeList, finishedCallback, createSellableCallback, curCustomer, inventory, loadedShoppingCart, savedCart, couponItem, sortedByDefault);
	}
	GotoSubState(SubState.ShoppingMode);
}
Any help or directions would be appreciated. Thanks.
Advertisement
Field Researcher
Original Poster
#2 Old 26th Mar 2023 at 8:13 PM Last edited by MonocoDoll : 26th Mar 2023 at 9:18 PM.
I found this mod that adds shopping interactions to objects such as computers and phones. I will be looking to see how JunJayMdM did it. Hopefully then I can make it work between two sims.

https://modthesims.info/d/541640/on...r-2nd-2014.html

Also found Battery's C# Scipt Utility. https://modthesims.info/d/615096/c-script-utility.html There's even a sim selector. Might just end up using this :D
Field Researcher
Original Poster
#3 Old 30th Mar 2023 at 6:05 AM
So when I was messing around in the sims 3. I found other objects that bring up a shopping list when a sim interacts with the object. First it was the Savvy Seller Register, but then I remembered about the ticket booth. The ticket Booth brings up a shopping list of four tickets when the sim performs the interaction. I thought oh good a objects code that I could reference when trying to make a similar interaction between two sims. Especially since the ticket booth was a more basic object compared to the other options. However, after putting something together. I received an error that states "Cannot cast from source type to destination type." Which I honestly do not know where to begin in regards to coming up with a solution. I will of course share the code related to this.
Code:
 public enum Guns
            {
                Glock17,
                HKp2000,
                EnterpriseWideBody1911,
                HecklarandKockp7m10,
                IntratecTec9Mini,
                UziPistol,
                Skorpian61_3,
                Lupara,
                Beratta,
                AK47,
                CompactAK47
            }
        //gameObject = GlobalFunctions.CreateObjectOutOfWorld(Glock17.kResourceKey) as GameObject;

        private static float kGlock17Price = 200f;

        private bool mGunsCreatedDuringPurchase;

        [Tunable]
        private static int kPercentModifier = 0;
        public float PercentModifier => kPercentModifier;

        public ObjectGuid CreateGunCallBack(object customData, ref Simulator.ObjectInitParameters initData, Quality quality)
        {
            Glock17 glock17 = GlobalFunctions.CreateObjectOutOfWorld(Glock17.kResourceKey) as Glock17;
            Guns gunType = (Guns)customData;
            mGunsCreatedDuringPurchase = true;
            return glock17.ObjectId;
        }
        public Dictionary<string, List<StoreItem>> ItemDictionary(Sim sim)
        {
            Dictionary<string, List<StoreItem>> dictionary = new Dictionary<string, List<StoreItem>>();
            List<StoreItem> list = new List<StoreItem>();
            ThumbnailKey thumb = new ThumbnailKey(new ResourceKey(ResourceUtils.HashString64(""), 1u, ResourceUtils.ProductVersionToGroupId(ProductVersion.BaseGame)), ThumbnailSize.Medium, ResourceUtils.HashString32("thumbnail"), ResourceUtils.HashString32(""));
            Glock17 glock17 = GlobalFunctions.CreateObjectOutOfWorld(Glock17.kResourceKey) as Glock17;

            if(glock17 != null)
            {
                thumb = glock17.GetThumbnailKey();
            }
            StoreItem item = new StoreItem(LocalizeString(false, ""), kGlock17Price, Guns.Glock17, thumb, "", CreateGunCallBack, null, null);

            return dictionary;
        }

        protected float GetSalePercentage(Sim sim)
        {
            float num = 1f;
            if (sim != null && sim.HasTrait(TraitNames.Haggler))
            {
                num *= 1f - TraitTuning.HagglerSalePercentAdd / 100f;
            }
            return num;
        }
        public bool ShowShoppingDialog(Sim sim)
        {
            float num = (1f - GetSalePercentage(sim)) * 100f;
            Dictionary<string, List<StoreItem>> dictionary = ItemDictionary(sim);
            

            mGunsCreatedDuringPurchase = false;
            ShoppingModel.CurrentStore = (IGameObject)this;
            ShoppingRabbitHole.StartShopping(sim, dictionary, PercentModifier, (int)num, 0, null, sim.Inventory, null, FinishedCallBack, CreateSellableObjectsList, sortedByDefault: true);
            return true;
        }

        private void FinishedCallBack(Sim customer, bool boughtItemForFamilyInventory)
        {
        }

        public List<ISellableUIItem> CreateSellableObjectsList(Sim customer)
        {
            List<ISellableUIItem> list = new List<ISellableUIItem>();
            List<Glock17> list2 = customer.Inventory.FindAll<Glock17>(checkInUse: true);
            foreach (Glock17 item2 in list2)
            {
                SellableUIItem item = new SellableUIItem(item2, null, item2.Value);
                list.Add(item);
            }
            return list;
        }

And my run method as well. This is in a social interaction between two sims.
Code:
 public override bool Run()
        {
            try
            {



                if (!Actor.IsSelectable)
                {
                    return false;
                }

                if (Target.SimDescription.HasTrait((TraitNames)0x1E8FA9341D90EF76))
                {
                    //Battery.UI.Menus.MenuController.Show("Main", PurchaseFireArmsMenu.MenuTree);

                    ShowShoppingDialog(Actor);

                    return true;
                }

                return false;
            }

            catch(Exception exc)
            {
                uint fileHandle = 0;
                try
                {
                    Simulator.CreateExportFile(ref fileHandle, "ExceptionLog__");
                    if (fileHandle != 0)
                    {
                        CustomXmlWriter xmlWriter = new CustomXmlWriter(fileHandle);
                        xmlWriter.WriteStartDocument();
                        xmlWriter.WriteToBuffer(exc.Message);
                        xmlWriter.FlushBufferToFile();
                    }
                }
                finally
                {
                    if (fileHandle != 0)
                    {
                        Simulator.CloseScriptErrorFile(fileHandle);
                    }
                }
                StyledNotification.Show(new StyledNotification.Format("Exception Logged", StyledNotification.NotificationStyle.kDebugAlert));
                return false;

            }
        }
Any pointers would be appreciated. Thank you.
Field Researcher
Original Poster
#4 Old 1st Apr 2023 at 4:34 AM
Got it to work. I had to make CurrentStore to null in order to fix the "Cannot cast from source type to destination type." error. Big thanks to Gamefreak130 for suggesting this.
Back to top