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!
Instructor
Original Poster
#1 Old 6th Dec 2014 at 2:13 PM
Help Regarding Chocolate Maker Modding
Hello guys,

I am back for another project. But I'm stuck and in need of your help.
My idea is to iterate through Ingredient objects through the list in the Actor's Inventory, and then adding those that are Cocoa or Milk (from Cooking Overhaul) into two different lists respectively. Then, open up a picker for player to choose one ingredient.

1. In the example of Milk Chocolate, I require 3 Cocoa ingredients and 1 Milk Ingredient to be chosen. However, no two lists can pop up in one interaction. What should I do...??

2. I have no way to show a list consisting of both Ingredient and Quality of it, using default lists. I read icarus's code, and saw that he used a custom constructed dialog to build a list that supports both.

Do you guys have any other methods to achieve the same results??
I mean, maybe I'm stuck at using lists and inventories only. Since this is cloned from a NectarMaker, I have thought of asking player to drag Ingredients into the Inventory, like the original AddFruit interaction, but I have no idea how to call methods related to Inventory. I have no experience working with them. So please help!
Advertisement
Inventor
#2 Old 6th Dec 2014 at 3:31 PM
Can you drag and drop ingredients from a sim's inventory to the ChocolateMaker's inventory?
If yes, why don't you make "chocolate types" available depending on what's in the ChocholateMaker?
What I mean is: when you click on the ChocholateMaker it shows only the interactions to make the kind of
chocolate that the current content of the object's inventory allows to make.
Maybe checking if there are other kind of ingredients/objects inside it to make the "recipe" fail/spoiled.

But maybe you wanted suggestions on how to actually implement that?

I've no experience in browsing inventories either but I'm currently working with ObjectPickers and Dialogs too.
I'll check back later.
Field Researcher
#3 Old 6th Dec 2014 at 4:00 PM
How about a custom "ChocolateRecipe" class that you instantiate with the type of ingredients and quantity or quality needed, then a Test method to check if the Sim's inventory contains them. You can then keep a list of all the classes you created with different recipes and when you click the interaction an object picker appears with all the recipes that passed the Test, then when you click one the ingredients are removed from the Sim's Inventory and the whole creation process begins. That is unless you want the players to discover the different combinations by themselves.

Nothing's real. Nothing's unreal either.
The frontier between true and untrue is a shady fuzzy line.
Destiny, or maybe the long flight's time-span, shall decide the issue.
Instructor
Original Poster
#4 Old 6th Dec 2014 at 4:00 PM
Much thanks! For now, I definitely do not want to write up a custom picker. Just from reading up Icarus's code, I can see it's so complicated. Yeah, what I want is suggestion is how to open up the inventory panel. I read the original AddFruit interaction, I seem to understand the flow but not so on how to adapt it to my mod. Would love to hear from you.
Field Researcher
#5 Old 6th Dec 2014 at 4:26 PM
Quote: Originally posted by SimsMatthew
Much thanks! For now, I definitely do not want to write up a custom picker. Just from reading up Icarus's code, I can see it's so complicated. Yeah, what I want is suggestion is how to open up the inventory panel. I read the original AddFruit interaction, I seem to understand the flow but not so on how to adapt it to my mod. Would love to hear from you.


I don't have experience with the Nectar Maker or inventory stuff, I've never even used it in my game, but from what I see in the code the AddFruit interaction opens the Nectar Maker inventory, you put stuff in there and when you close it the interaction ends and those ingredients are stored. Then when you click the Nectar Maker you get interactions based on the stored ingredients. Personally I'd create an identical NectarMaker class and then change all the parts to adapt it, by going back and forth ingame to see how everything works and then change one thing at a time to see what happens. I hope someone else can help better with this

Nothing's real. Nothing's unreal either.
The frontier between true and untrue is a shady fuzzy line.
Destiny, or maybe the long flight's time-span, shall decide the issue.
Instructor
Original Poster
#6 Old 7th Dec 2014 at 10:46 AM Last edited by SimsMatthew : 7th Dec 2014 at 11:08 AM.
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Sims3.SimIFace;
using Sims3.Gameplay.Actors;
using Sims3.Gameplay.Autonomy;
using Sims3.Gameplay.EventSystem;
using Sims3.Gameplay.Interactions;
using Sims3.Gameplay.Utilities;
using Sims3.UI;
using Sims3.Gameplay.CAS;
using Sims3.Gameplay.Interfaces;
using Sims3.Gameplay.Abstracts;
using Sims3.SimIFace.Enums;
using Sims3.Gameplay.ActorSystems;
using Sims3.Gameplay.Objects.HobbiesSkills;
using Sims3.Gameplay.UI;
using Sims3.Gameplay.Objects.FoodObjects;
using Sims3.Gameplay.Core;

namespace Sims3.Gameplay.Objects.Simsmatthew
{
	public class Simsmatthew_Chocolate : NectarMaker
	{
		//Independent Variables for each Simsmatthew_Chocolate
		public List<ObjectGuid> mList1 = new List<ObjectGuid>();
		public List<ObjectGuid> mList2 = new List<ObjectGuid>();
		public Ingredient mFinalIng1;
		public Ingredient mFinalIng2;
		public Ingredient mFinalIng3;
		public Ingredient mFinalIng4;
		public double mChocScore;
		public bool mAddedChoc;
		public string mChocType;

		[Tunable]
		public static bool kInstantiator = true;
		[Tunable]
		public static int kHorrifyingScore = -4;
		[Tunable]
		public static int kPerfectScore = 8;

		public static string WhiteChocolate = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:WhiteChocolate", new object[0]);
		public static string MilkChocolate = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:MilkChocolate", new object[0]);
		public static string DarkChocolate = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:DarkChocolate", new object[0]);
		public static string Add = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:Add", new object[0]);
		public static string GenericFailMsg = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:GenericFailMsg", new object[0]);

		public override void OnStartup()
		{
			base.OnStartup();
			base.AddInteraction (AddWhiteChocolate.Singleton);
			base.RemoveInteractionByType (NectarMaker.AddFruit.Singleton);
			base.RemoveInteractionByType (NectarMaker.PlaceGrapesFor.Singleton);
			base.RemoveInteractionByType (NectarMaker.Repair.Singleton);
			base.RemoveInteractionByType (NectarMaker.TakeNectar.Singleton);
			base.RemoveInteractionByType (NectarMaker.SquishGrapes.Singleton);
			base.RemoveInteractionByType (NectarMaker.MakeNectar.Singleton);
			base.RemoveInteractionByType (NectarMaker.PredictComboEffectiveness.Singleton);
			base.RemoveInteractionByType (NectarMaker.UpgradePreventBreakage.Singleton);
			base.RemoveInteractionByType (NectarMaker.UpgradeImprovedPressing.Singleton);
			base.RemoveInteractionByType (NectarMaker.UpgradeFlavorEnhancement.Singleton);
			base.RemoveInteractionByType (NectarMaker.Tinker.Singleton);
		}

		public override void OnCreation()
		{
			base.OnCreation ();
			this.mAddedChoc = false;
			this.mChocScore = 0;
			this.mChocType = "";
		}

		public static double CalScore (Quality quality)
		{
			switch (quality) 
			{
			case Quality.Horrifying:
				return kHorrifyingScore; //=-4

			case Quality.Putrid:
				return kHorrifyingScore + 1; //=-3

			case Quality.Foul:
				return kHorrifyingScore + 2;  //=-2

			case Quality.Bad:
				return kHorrifyingScore + 3;  //=-1

			case Quality.Perfect:
				return kPerfectScore; //=8
			
			case Quality.Outstanding:
				return kPerfectScore - 2;  //=6

			case Quality.Excellent:
				return kPerfectScore - 4;  //=4

			case Quality.Great:
				return kPerfectScore - 5;  //=3

			case Quality.VeryNice:
				return kPerfectScore - 5.5;  //=2.5

			case Quality.Nice:
				return kPerfectScore - 6;  //=2

			case Quality.Neutral:
				return kPerfectScore - 7;  //=1
			}

			return 0;
		}

		//To-be-done Interactions

		public new bool CanAddToInventory(GameObject obj)
		{
			Ingredient ingredient = obj as Ingredient;
			return (ingredient != null && (ItemTypes.IsOfType (ingredient.IngredientKey, "Cocoa") || ItemTypes.IsOfType (ingredient.IngredientKey, "Milk")) && (ingredient.Plantable == null || !ingredient.Plantable.IsSeed));
		}

		public void AddToChocAndMilkLists(Simsmatthew_Chocolate ChocolateMaker)
		{
			foreach (Ingredient ingredient in ChocolateMaker.Inventory.GetCookableIngredients()) 
			{
				if (ingredient.IngredientKey == "Cocoa") 
				{
					ChocolateMaker.mList1.Add (ingredient.ObjectId);
					ChocolateMaker.mChocScore += CalScore (ingredient.GetQuality ());
				} 

				else if (ingredient.IngredientKey == "Milk") 
				{
					ChocolateMaker.mList2.Add (ingredient.ObjectId);
				}
			}
		}


		public sealed class AddWhiteChocolate : Interaction<Sim, Simsmatthew_Chocolate>
		{
			public static readonly InteractionDefinition Singleton = new Definition();

			public void LoopDel(StateMachineClient smc, InteractionInstance.LoopData loopData)
			{
				if (HudModel.CurrentSecondaryInventoryOwner != this.Target)
				{
					this.Actor.AddExitReason(ExitReason.Finished);
				}
			}

			public override bool Run()
			{
				HudModel.OpenObjectInventoryForOwner(this.Target);
				bool result = this.DoLoop(ExitReason.Default, new InteractionInstance.InsideLoopFunction(this.LoopDel), null);
				if (HudModel.CurrentSecondaryInventoryOwner == this.Target)
				{
					HudModel.OpenObjectInventoryForOwner(null);
				}

				Target.AddToChocAndMilkLists (Target);

				if (Target.Inventory.NumItemsStored == 4 && Target.mList1.Count == 1 && Target.mList2.Count == 3 && !Target.InUse) 
				{
					Target.Inventory.DestroyItems ();
					Target.mList1.Clear ();
					Target.mList2.Clear ();

					base.AcquireStateMachine ("NectarMaker");
					base.SetActor ("nectarMaker", this.Target);
					base.SetActorAndEnter ("x", this.Actor, "Enter Add Fruit");
					base.AnimateSim ("Exit");
				} 

				else 
				{
					StyledNotification.Show (new StyledNotification.Format (GenericFailMsg, Actor.ObjectId, StyledNotification.NotificationStyle.kGameMessagePositive));
					Target.mList1.Clear ();
					Target.mList2.Clear ();
					Target.mChocScore = 0;
					Target.Inventory.MoveObjectsTo (Actor.Inventory);
				}

				return result;
						
			}

			[DoesntRequireTuning]
			public sealed class Definition : InteractionDefinition<Sim, Simsmatthew_Chocolate, AddWhiteChocolate>
			{
				public override string GetInteractionName(Sim a, Simsmatthew_Chocolate target, InteractionObjectPair interaction)
				{
					return Add + WhiteChocolate;
				}
				public override bool Test(Sim a, Simsmatthew_Chocolate target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
				{
					return (a != null && target != null && !target.InUse && a.SimDescription.YoungAdultOrAbove && !a.IsPet);
				}
			}
		}
	}
}


I tried to use the CanAddToInventory method, but still Milk ingredient (from BlackCat's cooking overhaul) cannot be put into the inventory. Why? The only solution I can think of is to make Milk nectar-addable as well in the RecipeMasterList in the mod. I should be able to get permission but the main concern is that, milk will appear in nectars as well! So..... And the more important problem is that, for my expansion of mod, I plan to let people choose some default "recipes" to add other ingredients. Then, whipped cream and peanut butter will have to become nectar ingredients as well!!!

BTW other stuff should be working well (I don't know if the animation plays since the check for Cocoa and Milk contained is blocking it, but the fail msg does show, and the inventory panel does show up which is what I thought would fail!
Field Researcher
#7 Old 7th Dec 2014 at 11:10 AM
Code:
public new bool CanAddToInventory(GameObject obj)
{
	Ingredient ingredient = obj as Ingredient;
	return (ingredient != null && (ItemTypes.IsOfType (ingredient.IngredientKey, "Cocoa") || ItemTypes.IsOfType (ingredient.IngredientKey, "Milk")) && (ingredient.Plantable == null || !ingredient.Plantable.IsSeed));
}


This method is called from the base class, not yours (as far as I can see). By using the "new" keyword you're not overriding it, your new method will be called only by your class, which could be why it's not working. Also, EA doesn't like when you inherit from an object to create another one. I don't know why but it has to do with a Common dll that we can't see. So for the above reason and this one, I suggest you inherit from "GameObject, ILiveDragOutOfMyInventoryAvailableOnCommunityLot, IFairyRepairable" (which is what NectarMaker inherits from, except the INectarMaker interface). I know it's more work but this is the correct way to do it, especially since you need to remove the INectarMaker interface from there

Nothing's real. Nothing's unreal either.
The frontier between true and untrue is a shady fuzzy line.
Destiny, or maybe the long flight's time-span, shall decide the issue.
Instructor
Original Poster
#8 Old 7th Dec 2014 at 11:15 AM
Oh well, I have guess this already... Then I'd have to add Inventories components all by myself????
BTW, since I may not implement breaking / upgrading components anyway, by removing IFairyRemovable, it compiles successfully. However, now there's a question: how will the code read my CanAddToInventory method?
Field Researcher
#9 Old 7th Dec 2014 at 11:49 AM
Quote: Originally posted by SimsMatthew
Oh well, I have guess this already... Then I'd have to add Inventories components all by myself????
BTW, since I may not implement breaking / upgrading components anyway, by removing IFairyRemovable, it compiles successfully. However, now there's a question: how will the code read my CanAddToInventory method?


We've just came across one of famous EA stunts about code reusability, the worst nightmare for a coder (and for them, if they needed to make a similar object, they'd have to release a new patch just to modify the code, how clever of them). As bad as it sounds, you're going to have to leave the INectarMaker interface in there, since it's used by the IngredientItemComponent class, I've noticed that now.
As for the rest, I'm afraid you will have to add all the stuff required manually, but you can see how it's done in NectarMaker

Nothing's real. Nothing's unreal either.
The frontier between true and untrue is a shady fuzzy line.
Destiny, or maybe the long flight's time-span, shall decide the issue.
Instructor
Original Poster
#10 Old 7th Dec 2014 at 12:39 PM
I've just thought of a new method: this requires certain player engagement, but hey, I'd say it's better for me to avoid putting in non-understood code.

Perhaps I can add in an interaction, specifically just to transfer milk ingredients into the Target's inventory, using ForceAdd (this should bypass game check, I guess, will need to test), perhaps with popup allowing user to pick how many to put inside. Then, when the user opens up the inventory panel again, using the AddWhiteChocolate interaction, the user will find milk inside, and then they can remove the amount of milk to the desired amount (depending on what the user is choosing the make) (though the user cannot add back in unless he uses the said ForceAdd again)

(OK, I'll just make up some excuses: the Chocolate maker can't accept milk being put with cocoa together. oh so well.... )

At least, it seems to be an easy and fast solution.
Instructor
Original Poster
#11 Old 7th Dec 2014 at 1:07 PM
Code:
public void ForceAddMilk(Simsmatthew_Chocolate ChocolateMaker, Sim Actor)
		{
			foreach (Ingredient ingredient in Actor.Inventory.GetCookableIngredients()) 
			{
				if (ingredient.IngredientKey == "Milk") 
				{
					ChocolateMaker.Inventory.ForceAdd ((IGameObject)ingredient);				
				}
			}			
		}


Does it seem sensible? (I know, it currently adds all milk ingredients at once, if it does work. It is to be worked on later, if this would suffice for now)
Inventor
#12 Old 7th Dec 2014 at 1:47 PM
First of all, you have to teach me the trick to use the CODE tag without getting an empty line between lines of code.

Sorry if I take a step back, but why the Milk doesn't pass the CanAddToInventory check? Is it not of class Ingredient?
Are you using the wrong key? Or that method return true but the object isn't added anyway because of another
check somewhere else?
Instructor
Original Poster
#13 Old 7th Dec 2014 at 1:49 PM
Thanks! To stop the codes from using alternate lines, usually I type "code" and "/code" (without quotations and with [ ] enclosing "code") at the start and end of my block respectively.

BTW I'm so sorry for PM-ing you.

It does not pass the check, because the original check only accepts ingredients that can be added into nectars, while I cannot override CanAddToInventory check (as explained by JunJayMDM in theory).

In practice, I find out this does not work, because other ingredients such as Blueberry, Blackberry and so on can all be added, while I did specify that they won't pass.
Inventor
#14 Old 7th Dec 2014 at 2:09 PM
Oh, you are still deriving your class from the NectarMaker? Why?

Ehm... let me try...
Code:
line 1
line 2
Sonovatag!
Field Researcher
#15 Old 7th Dec 2014 at 2:13 PM
Quote: Originally posted by SimsMatthew
It does not pass the check, because the original check only accepts ingredients that can be added into nectars, while I cannot override CanAddToInventory check (as explained by JunJayMDM in theory).

In practice, I find out this does not work, because other ingredients such as Blueberry, Blackberry and so on can all be added, while I did specify that they won't pass.


That doesn't apply anymore since you're no longer inheriting from NectarMaker. It shouldn't have mattered anyway cos I later found out CanAddToInventory is not a base class method but an interface implementation. The method is called by the IngedientItemComponent class. I checked and I think the only use for the INectarMaker interface is for implementing that method, so it should be safe to use in your class (if ForceAdd won't work). This tells us that the cause of that ingredient not being added is something else and should be investigated

Nothing's real. Nothing's unreal either.
The frontier between true and untrue is a shady fuzzy line.
Destiny, or maybe the long flight's time-span, shall decide the issue.
Instructor
Original Poster
#16 Old 7th Dec 2014 at 2:28 PM
Thanks MDM! My concern now is whether ForceAdd will accept ingredient converted into IGameObject. Honestly I have no idea on the difference between IGameObject and GameObject. If it doesn't work, then I will have to nail down the cause of ingredient limited to fruit.
Field Researcher
#17 Old 7th Dec 2014 at 2:34 PM
Quote: Originally posted by SimsMatthew
Thanks MDM! My concern now is whether ForceAdd will accept ingredient converted into IGameObject. Honestly I have no idea on the difference between IGameObject and GameObject. If it doesn't work, then I will have to nail down the cause of ingredient limited to fruit.


IGameObject is an implementation of GameObject. When you cast to IGameObject you will have access to all IGameObject members, but if you need to call something from the GameObject class, then you should cast to GameObject (provided the object is derived from GameObject, so check carefully). It does not affect what you're casting, if that's what you're concerned about, it will still be the same object since it's a reference type

Nothing's real. Nothing's unreal either.
The frontier between true and untrue is a shady fuzzy line.
Destiny, or maybe the long flight's time-span, shall decide the issue.
Instructor
Original Poster
#18 Old 8th Dec 2014 at 1:25 PM Last edited by SimsMatthew : 8th Dec 2014 at 1:59 PM.
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Sims3.SimIFace;
using Sims3.Gameplay.Actors;
using Sims3.Gameplay.Autonomy;
using Sims3.Gameplay.EventSystem;
using Sims3.Gameplay.Interactions;
using Sims3.Gameplay.Utilities;
using Sims3.UI;
using Sims3.Gameplay.CAS;
using Sims3.Gameplay.Interfaces;
using Sims3.Gameplay.Abstracts;
using Sims3.SimIFace.Enums;
using Sims3.Gameplay.ActorSystems;
using Sims3.Gameplay.Objects.HobbiesSkills;
using Sims3.Gameplay.UI;
using Sims3.Gameplay.Objects.FoodObjects;
using Sims3.Gameplay.Core;

namespace Sims3.Gameplay.Objects.Simsmatthew
{
	public class Simsmatthew_Chocolate : NectarMaker
	{
		//Independent Variables for each Simsmatthew_Chocolate
		public List<ObjectGuid> mList1 = new List<ObjectGuid>();
		public List<ObjectGuid> mList2 = new List<ObjectGuid>();
		public List<Ingredient> mInvItemList = new List<Ingredient> ();
		public Ingredient mFinalIng1;
		public Ingredient mFinalIng2;
		public Ingredient mFinalIng3;
		public Ingredient mFinalIng4;
		public double mChocScore;
		public bool mAddedChoc;
		public string mChocType;
		public int mAddNonDraggableIngCount;

		[Tunable]
		public static bool kInstantiator = true;
		[Tunable]
		public static int kHorrifyingScore = -4;
		[Tunable]
		public static int kPerfectScore = 8;

		public static string WhiteChocolate = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:WhiteChocolate", new object[0]);
		public static string MilkChocolate = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:MilkChocolate", new object[0]);
		public static string DarkChocolate = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:DarkChocolate", new object[0]);
		public static string Add = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:Add", new object[0]);
		public static string GenericFailMsg = Localization.LocalizeString ("Simsmatthew/Simsmatthew_Chocolate:GenericFailMsg", new object[0]);

		public override void OnStartup()
		{
			base.OnStartup();
			base.AddInteraction (AddWhiteChocolate.Singleton);
			base.RemoveInteractionByType (NectarMaker.AddFruit.Singleton);
			base.RemoveInteractionByType (NectarMaker.PlaceGrapesFor.Singleton);
			base.RemoveInteractionByType (NectarMaker.Repair.Singleton);
			base.RemoveInteractionByType (NectarMaker.TakeNectar.Singleton);
			base.RemoveInteractionByType (NectarMaker.SquishGrapes.Singleton);
			base.RemoveInteractionByType (NectarMaker.MakeNectar.Singleton);
			base.RemoveInteractionByType (NectarMaker.PredictComboEffectiveness.Singleton);
			base.RemoveInteractionByType (NectarMaker.UpgradePreventBreakage.Singleton);
			base.RemoveInteractionByType (NectarMaker.UpgradeImprovedPressing.Singleton);
			base.RemoveInteractionByType (NectarMaker.UpgradeFlavorEnhancement.Singleton);
			base.RemoveInteractionByType (NectarMaker.Tinker.Singleton);
		}

		public override void OnCreation()
		{
			base.OnCreation ();
			this.mAddedChoc = false;
			this.mChocScore = 0;
			this.mChocType = "";
			this.mAddNonDraggableIngCount = 0;
		}

		public static double CalScore (Quality quality)
		{
			switch (quality) 
			{
			case Quality.Horrifying:
				return kHorrifyingScore; //=-4

			case Quality.Putrid:
				return kHorrifyingScore + 1; //=-3

			case Quality.Foul:
				return kHorrifyingScore + 2;  //=-2

			case Quality.Bad:
				return kHorrifyingScore + 3;  //=-1

			case Quality.Perfect:
				return kPerfectScore; //=8
			
			case Quality.Outstanding:
				return kPerfectScore - 2;  //=6

			case Quality.Excellent:
				return kPerfectScore - 4;  //=4

			case Quality.Great:
				return kPerfectScore - 5;  //=3

			case Quality.VeryNice:
				return kPerfectScore - 5.5;  //=2.5

			case Quality.Nice:
				return kPerfectScore - 6;  //=2

			case Quality.Neutral:
				return kPerfectScore - 7;  //=1
			}

			return 0;
		}

		//To-be-done Interactions

		public void AddToChocAndMilkLists(Simsmatthew_Chocolate ChocolateMaker)
		{
			foreach (Ingredient ingredient in ChocolateMaker.Inventory.GetCookableIngredients()) 
			{
				if (ingredient.IngredientKey == "Cocoa") 
				{
					ChocolateMaker.mList1.Add (ingredient.ObjectId);
					ChocolateMaker.mChocScore += CalScore (ingredient.GetQuality ());
				} 

				else if (ingredient.IngredientKey == "Milk") 
				{
					ChocolateMaker.mList2.Add (ingredient.ObjectId);
				}
			}
		}

		public void ForceAddNonDraggableIng(Simsmatthew_Chocolate ChocolateMaker, Sim Actor, string IngredientKey, int AddIngNum)
		{
			foreach (Ingredient ingredient in Actor.Inventory.GetCookableIngredients()) 
			{
				if (ingredient.IngredientKey == IngredientKey && ChocolateMaker.mAddNonDraggableIngCount <= AddIngNum) 
				{
					ChocolateMaker.Inventory.ForceAdd ((IGameObject)ingredient);	
					ChocolateMaker.mAddNonDraggableIngCount += 1;
				}
			}			
		}


		public sealed class AddWhiteChocolate : Interaction<Sim, Simsmatthew_Chocolate>
		{
			public static readonly InteractionDefinition Singleton = new Definition();

			public void LoopDel(StateMachineClient smc, InteractionInstance.LoopData loopData)
			{
				if (HudModel.CurrentSecondaryInventoryOwner != this.Target)
				{
					this.Actor.AddExitReason(ExitReason.Finished);
				}
			}

			public override bool Run()
			{
				Target.ForceAddNonDraggableIng (Target, Actor, "Milk", 3);

				HudModel.OpenObjectInventoryForOwner(this.Target);
				bool result = this.DoLoop(ExitReason.Default, new InteractionInstance.InsideLoopFunction(this.LoopDel), null);
				if (HudModel.CurrentSecondaryInventoryOwner == this.Target)
				{
					HudModel.OpenObjectInventoryForOwner(null);
				}

				Target.AddToChocAndMilkLists (Target);

				if (Target.Inventory.NumItemsStored == 4 && Target.mList1.Count == 1 && Target.mList2.Count == 3 && !Target.InUse) 
				{
					Target.Inventory.DestroyItems ();
					Target.mList1.Clear ();
					Target.mList2.Clear ();
					Target.mAddNonDraggableIngCount = 0;
					Target.mChocType = WhiteChocolate + "";

					base.AcquireStateMachine ("NectarMaker");
					base.SetActor ("nectarMaker", this.Target);
					base.SetActorAndEnter ("x", this.Actor, "Enter Add Fruit");
					base.AnimateSim ("Exit");
				} 

				else 
				{
					StyledNotification.Show (new StyledNotification.Format (GenericFailMsg, Actor.ObjectId, StyledNotification.NotificationStyle.kGameMessagePositive));
					Target.mList1.Clear ();
					Target.mList2.Clear ();
					Target.mChocScore = 0;
					Target.mAddNonDraggableIngCount = 0;
					Target.Inventory.MoveObjectsTo (Actor.Inventory);
				}

				return result;
						
			}

			[DoesntRequireTuning]
			public sealed class Definition : InteractionDefinition<Sim, Simsmatthew_Chocolate, AddWhiteChocolate>
			{
				public override string GetInteractionName(Sim a, Simsmatthew_Chocolate target, InteractionObjectPair interaction)
				{
					return Add + "" + WhiteChocolate;
				}
				public override bool Test(Sim a, Simsmatthew_Chocolate target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
				{
					return (a != null && target != null && !target.InUse && a.SimDescription.YoungAdultOrAbove && !a.IsPet);
				}
			}
		}
	}
}


I'm driven mad! I thought the method would work. Ingredient is definitely a IGameObject as well, I've checked. But how come it doesn't work??? I can't seem to nail down the reason other ingredients cannot be added into that inventory.

I've thought up a new method: what about if I create a new inventory (not that one created as derived from NectarMaker class): perhaps such conditions are applied onto that inventory I created in OnStartup()??
Instructor
Original Poster
#19 Old 8th Dec 2014 at 1:45 PM
Forgive me for double-posting, but I'll have to make it clear: can TryToAdd method work? From its name it seems that it needs to pass such "hidden" conditions. I now find out that ForceAdd(IGameObject) seem to do nothing with adding objects into Inventories, it's just its name that's luring me.... So well....
Inventor
#20 Old 8th Dec 2014 at 1:51 PM Last edited by Arsil : 8th Dec 2014 at 2:01 PM.
Can you just quote the relevant portions of the code? Or at least highlight them.

I've lost the thread of the conversation. what exactly are you trying to do?
Using the same system used by the NectarMaker? I see your class is still
inheriting from it, wasn't that part of the problem? Can you explain how the
NectarMaker works (from a user's prospective point of view) since I never used it in game?

EDIT: I'm not sure I like that
Code:
ingredient.IngredientKey == IngredientKey
are you sure is the same as
Code:
ingredient.IngredientKey.Equals(IngredientKey)
?
Instructor
Original Poster
#21 Old 8th Dec 2014 at 1:59 PM
Well, it works like the following: a user chooses the AddFruit interaction, an inventory panel opens and you drag ingredients into it. And then, choose SquishFruit which the Sim will go inside a barrel and press the fruit with his / her feet. Then, choose MakeNectar (with different variations, such as Basic, ExtendedNectaration......) And then the Sim works with the machine and it starts nectaring, then some time later you can go back and collect made nectars.

The relevant part for now is AddFruit: how does the inventory limit that only fruit can be added? Milk (from Cooking Overhual) becomes a problem to be added, since it's NOT a fruit ingredient and thus, when deriving Simsmatthew_Chocolate from NectarMaker, the inventory will also only accept fruit but definitely NOT Milk.
Instructor
Original Poster
#22 Old 8th Dec 2014 at 2:01 PM
And to differentiate this from the above problem, I'll write it here:

I'm starting to think if Inventory.GetCookableIngredients() won't return Milk in the list at all???? I am not so sure, but for now I can't test (oh gosh, as a 14-year-old student I only have less than an hour to work on it every day!!!)
Instructor
Original Poster
#23 Old 8th Dec 2014 at 2:33 PM
Ah!..From my search it seems to be the culprit!!!! LOVE YOU ARSIL! hopefully it will work when I change it.
Inventor
#24 Old 8th Dec 2014 at 3:39 PM Last edited by Arsil : 8th Dec 2014 at 5:21 PM.
Well, I did nothing but I'll take that love if you wanna share it with me.
Wow, are you fourteen? I feel even older now.
Put those two lines together and they will sound very creepy.

Anyway, I modified your code and wanted to test it but I can't find the Milk anywhere.
Does it come with a premium content item? Oh yeah, the one with the cow probably.
I installed [13/04] BlackCat007's Cooking & Ingredients Overhaul (Compatible with Patch 1.63-1.67),
is this the one you are using? Is it needed?

I'm the last one that can give coding advice, since my code is a mess, but if you are interested, here are the changes I did:
- changed public to protected for some methods (or I couldn't compile it, even with unprotected libraries)
- renamed all occurences of mList1 and mList2 as, respectively, mListCocoa and mListMilk (for easier code reading/understanding)
- changed method AddToChocAndMilkLists: I couldn't find Inventory.GetCookableIngredients() (where that comes from?), so I used
Code:
List<Ingredient> ingList = ChocolateMaker.Inventory.FindAll<Ingredient>(false);
foreach (Ingredient ingredient in ingList)
[are you kidding me? If I use the "code" tag writing it with lowercase letters then there are no extralines, that's the trick?]
- used string1.Equals(string2) (I think string1 == string2 checks the pointers, not the content of the strings)
- added a debug message after calling Target.AddToChocAndMilkList to verify if ingredients were added to those lists
Code:
string debugMessage = "";
debugMessage += "Cocoa count: " + this.Target.mListCocoa.Count + "\n";
debugMessage += "Milk count: " + this.Target.mListMilk.Count + "\n";
StyledNotification.Show(new StyledNotification.Format(debugMessage, StyledNotification.NotificationStyle.kGameMessagePositive));

I created a package with the script and an OBJK that overrides the one of the NectarMaker but other than that I couldn't test it.

Let us know how it's going so I, or someone else, can help you if you need ^^

EDIT

I downloaded the wrong version of the ingredients overhaul mod, lemme try again...
All right, now I have cocoa and milk, so I can test it.

As stated before, the problem is canAddToInventory and there's no way to avoid using the
one of the NectarMaker if your class derives from that class (unless you choose to use a
completely different system that doesn't involve the same UI/system used by it, but if you
have to go that far, I'll ask it again, why inheriting from NectarMaker in the first place?).

I'm doing further tests...
Inventor
#25 Old 8th Dec 2014 at 6:03 PM Last edited by Arsil : 9th Dec 2014 at 10:42 AM.
Ok. I copy/pasted the NectarMaker code, removed all the extra stuff and left only what you need (for the moment).



Notice the name of the class (so I didn't have to rename all its occurences).
The "inventory's window" still shows the NectarMaker string, I didn't bother to
see if I could change that
(EDIT: nevermind, it uses the name of the object
used as parameter, and since I'm using a unmodified nectar maker it shows
to me its name).

Do you plan to use the NectarMaker mesh/animations for your ChocolateMaker?

I'm glad if this can help you. Understanding a bit more how an Inventory works was useful to me too.
Page 1 of 2
Back to top