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 2nd Jun 2015 at 12:16 PM
Default Problems with Petrol Mod
Hi everyone, as you should know I have released an update for the petrol mod to make data survive save and reload. I just did what I did in the past, but this time the whole mod is not working anymore. I have absolutely no idea what has happened and I don't want my head to crack before exams (ok, I admit that my head HAS CRACKED already just because of revision... )

It was working alright before I added in [assembly:PersistableStatic] in assemblyinfo.cs .
Code:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Sims3.SimIFace;
using Sims3.Gameplay.Objects.Vehicles;
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.ActorSystems;

namespace Simsmatthew
{
	public class Simsmatthew_PetrolNew
	{
		[Tunable]
		public static bool kInstantiator = true;
		[Tunable]
		public static int kStartupFuelAmount = 25;
		[Tunable]
		public static int kAutoRefillCharge = 395;
		[Tunable]
		public static int kManualRefillChargeNormal = 325;
		[Tunable]
		public static int kManualRefillChargeEco = 365;

		[PersistableStatic]
		public static Dictionary<ObjectGuid, int> FuelLeftDict = new Dictionary<ObjectGuid, int>();

		public static EventListener CarListener;
		public static EventListener BoughtObjectListener;
		public static EventListener InventoryObjectAddedListener;
		public static EventListener ObjectStateChangedListener;

		static Simsmatthew_PetrolNew()
		{
			World.OnWorldLoadFinishedEventHandler += new EventHandler(OnWorldLoadFinished);
			World.OnWorldQuitEventHandler += new EventHandler(OnWorldQuitEvent);
		}

		public static void OnWorldLoadFinished(object sender, EventArgs e)
		{
			//OnCarUsed
			CarListener = EventTracker.AddListener(EventTypeId.kUsedVehicle, new ProcessEventDelegate(OnCarUsed));

			//OnObjectChanged
			BoughtObjectListener = EventTracker.AddListener(EventTypeId.kBoughtObject, new ProcessEventDelegate(OnObjectChanged));
			InventoryObjectAddedListener = EventTracker.AddListener(EventTypeId.kInventoryObjectAdded, new ProcessEventDelegate(OnObjectChanged));
			ObjectStateChangedListener = EventTracker.AddListener(EventTypeId.kObjectStateChanged, new ProcessEventDelegate(OnObjectChanged));
		}

		public static void OnWorldQuitEvent(object sender, EventArgs e)
		{
			EventTracker.RemoveListener(CarListener);
			EventTracker.RemoveListener(BoughtObjectListener);
			EventTracker.RemoveListener(InventoryObjectAddedListener);
			EventTracker.RemoveListener(ObjectStateChangedListener);
		}

		public static ListenerAction OnObjectChanged(Event e)
		{
			try
			{
				CarOwnable carownable = e.TargetObject as CarOwnable;
				if (carownable != null && carownable.GetOwnerLot() == Sim.ActiveActor.LotHome)
				{
					carownable.AddInteraction(ManualRefillNormal.Singleton, true);
					carownable.AddInteraction(ManualRefillEco.Singleton, true);
				}
			}
			catch (Exception exception)
			{
				Exception(exception);
			}
			return ListenerAction.Keep;
		}

		public static ListenerAction OnCarUsed(Event e)
		{
			try
			{
				CarOwnable carownable = e.TargetObject as CarOwnable;
				Sim sim = e.Actor as Sim;

				if (carownable != null && sim != null && sim.IsInActiveHousehold && carownable.Driver == sim)
				{	
					if (!FuelLeftDict.ContainsKey(carownable.ObjectId)) //Check if the dictionary has an entry for this car. If it doesn't the following line is run.
					{
						FuelLeftDict.Add (carownable.ObjectId, kStartupFuelAmount); //Add a new entry for the car
						carownable.AddInteraction(ManualRefillNormal.Singleton, true);
						carownable.AddInteraction(ManualRefillEco.Singleton, true);
					}

					FuelLeftDict[carownable.ObjectId]--;
					//Auto Refill is necessary
					if (FuelLeftDict[carownable.ObjectId] == -1)
					{
						if (sim.Household.FamilyFunds >= kAutoRefillCharge) 
						{
							sim.Household.ModifyFamilyFunds (-kAutoRefillCharge);
							string AutoRefillChargeMsg = Localization.LocalizeString ("Simsmatthew/Simsmatthew_PetrolNew:AutoRefillChargeMsg", new object[] 
								{
								sim.FullName,
								UIUtils.FormatMoney (kAutoRefillCharge)
							});
							StyledNotification.Show (new StyledNotification.Format (AutoRefillChargeMsg, carownable.ObjectId, StyledNotification.NotificationStyle.kGameMessageNegative));
						}

						else if (sim.Household.FamilyFunds < kAutoRefillCharge) 
						{
							sim.Household.UnpaidBills += kAutoRefillCharge;
							string AutoRefillChargeBillsMsg = Localization.LocalizeString("Simsmatthew/Simsmatthew_PetrolNew:AutoRefillChargeBillsMsg", new object[]
								{
									sim.FullName,
									UIUtils.FormatMoney(kAutoRefillCharge)
								});
							StyledNotification.Show(new StyledNotification.Format(AutoRefillChargeBillsMsg, carownable.ObjectId, StyledNotification.NotificationStyle.kGameMessageNegative));
						}

						FuelLeftDict[carownable.ObjectId] = kStartupFuelAmount;

						if (sim.HasTrait (TraitNames.EnvironmentallyConscious)) 
						{
							sim.BuffManager.AddElement (BuffNames.WastingNaturalResources, -15, 180f, Origin.None);
							string FuelNotEco = Localization.LocalizeString ("Simsmatthew/Simsmatthew_PetrolNew:FuelNotEco", new object[] {
								sim.FullName
							});
							StyledNotification.Show (new StyledNotification.Format (FuelNotEco, sim.ObjectId, StyledNotification.NotificationStyle.kGameMessageNegative));
						}
					}

					//Reporting amount of fuel
					else 
					{
						string ReportFuel = Localization.LocalizeString("Simsmatthew/Simsmatthew_PetrolNew:ReportFuel", new object[]
							{
								sim.FullName,
								FuelLeftDict[carownable.ObjectId].ToString()
							});

						StyledNotification.Show (new StyledNotification.Format (ReportFuel, carownable.ObjectId, StyledNotification.NotificationStyle.kGameMessagePositive));
					}
				}
			}

			catch (Exception exception)
			{
				Exception(exception);
			}

			return ListenerAction.Keep;
		}


		//ManualRefill Interactions
		public sealed class ManualRefillNormal : Interaction<Sim, CarOwnable>
		{
			public static readonly InteractionDefinition Singleton = new Definition();

			public override bool RunFromInventory()
			{
				return false;
			}

			public override bool Run()
			{
				Actor.RouteToObjectRadialRange (Target, 0.4f, 0.8f);
				Actor.PlaySoloAnimation("a2o_urinal_clean_loop1_x");
				Actor.PlaySoloAnimation("a2o_urinal_clean_stop_x");

				FuelLeftDict[Target.ObjectId] = kStartupFuelAmount;
				Actor.Household.ModifyFamilyFunds (-kManualRefillChargeNormal);

				if (Actor.HasTrait (TraitNames.EnvironmentallyConscious))
				{
					Actor.BuffManager.AddElement (BuffNames.WastingNaturalResources, -15, 180f, Origin.None);
					string FuelNotEco = Localization.LocalizeString ("Simsmatthew/Simsmatthew_PetrolNew:FuelNotEco", new object[] {
						Actor.FullName
					});
					StyledNotification.Show (new StyledNotification.Format (FuelNotEco, Actor.ObjectId, StyledNotification.NotificationStyle.kGameMessageNegative));
				}
				return true;
			}

			[DoesntRequireTuning]
			private sealed class Definition : InteractionDefinition<Sim, CarOwnable, ManualRefillNormal>
			{
				public override string GetInteractionName(Sim a, CarOwnable target, InteractionObjectPair interaction)
				{
					return Localization.LocalizeString("Simsmatthew/Simsmatthew_PetrolNew:ManualRefillNormal", new object[0]);
				}

				public override bool Test(Sim actor, CarOwnable target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
				{
					return (target != null && actor != null && target.CanBeUsedBy (actor, false) && FuelLeftDict.ContainsKey(target.ObjectId) && !actor.IsPet && actor.Household.FamilyFunds >= kManualRefillChargeNormal);
				}
			}
		}

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

			public override bool RunFromInventory()
			{
				return false;
			}

			public override bool Run()
			{
				Actor.RouteToObjectRadialRange (Target, 0.4f, 0.8f);
				Actor.PlaySoloAnimation("a2o_urinal_clean_loop1_x");
				Actor.PlaySoloAnimation("a2o_urinal_clean_stop_x");

				FuelLeftDict[Target.ObjectId] = kStartupFuelAmount;
				Actor.Household.ModifyFamilyFunds (-kManualRefillChargeEco);

				if (Actor.HasTrait (TraitNames.Frugal) && !Actor.HasTrait (TraitNames.EnvironmentallyConscious)) 
				{
					Actor.BuffManager.AddElement (BuffNames.GotRippedOff, -15, 180f, Origin.None);
					string FuelEcoExp = Localization.LocalizeString ("Simsmatthew/Simsmatthew_PetrolNew:FuelEcoExp", new object[] {
						Actor.FullName
					});
					StyledNotification.Show (new StyledNotification.Format (FuelEcoExp, Actor.ObjectId, StyledNotification.NotificationStyle.kGameMessageNegative));
				}

				else 
				{
					Actor.BuffManager.AddElement (BuffNames.SavingTheEnvironment, 15, 180f, Origin.None);
				}			
				return true;
			}

			[DoesntRequireTuning]
			private sealed class Definition : InteractionDefinition<Sim, CarOwnable, ManualRefillEco>
			{
				public override string GetInteractionName(Sim a, CarOwnable target, InteractionObjectPair interaction)
				{
					return Localization.LocalizeString("Simsmatthew/Simsmatthew_PetrolNew:ManualRefillEco", new object[0]);
				}

				public override bool Test(Sim actor, CarOwnable target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
				{
					return (target != null && actor != null && target.CanBeUsedBy (actor, false) && FuelLeftDict.ContainsKey(target.ObjectId) && !actor.IsPet && actor.Household.FamilyFunds >= kManualRefillChargeEco);
				}
			}
		}

		public static bool Exception(Exception exception)
		{
			try
			{
				new ScriptError(null, exception, 0).WriteMiniScriptError();
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
}


And the assemblyinfo.cs just in case:
Code:
using System.Reflection;
using System.Runtime.CompilerServices;
using Sims3.SimIFace;

// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.

[assembly: AssemblyTitle ("Simsmatthew_PetrolNew")]
[assembly: AssemblyDescription ("")]
[assembly: AssemblyConfiguration ("")]
[assembly: AssemblyCompany ("")]
[assembly: AssemblyProduct ("")]
[assembly: AssemblyCopyright ("Administrator")]
[assembly: AssemblyTrademark ("")]
[assembly: AssemblyCulture ("")]
[assembly: Tunable]
[assembly: PersistableStatic] 

// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.

[assembly: AssemblyVersion ("1.0.*")]

// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.

//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]


Can anyone help me out?
Advertisement
Inventor
#2 Old 2nd Jun 2015 at 6:31 PM
It's just a wild guess, but maybe it's not working because you imported in the S3SA the dll of the chocolate maker ;P

Your code works fine ^^

Also, check this post by Buzzler: http://modthesims.info/showthread.p...475#post3855475
I'm not sure but I think he means to assign null to the PersistableStatic variable in OnWorldQuitEvent
(in case the user goes back to the main menu to load a game or start a new one).
Instructor
Original Poster
#3 Old 3rd Jun 2015 at 4:03 AM
By "works fine", do you mean that in your game the code is okay or do you mean that it LOOKS fine?
I read through it many times, just imported exactly the dll of this file, but the code suddenly stops working.
I mean that interactions aren't loaded at all and the counter isn't as well, as if the package disappeared.

Good lord, I'm confused. Let me make the PersistableStatic variable null OnWordQuitEvent, reimport the package and try again.

The real problem is I can't see why a simple [assembly:PersistableStatic} can stop things working at once, while my previous Horse Temperament Mod uses exactly the same approach (though, honestly I haven't been touching that mod much since I have little gameplay for now, I am not sure if that mod handles data surviving save and reload properly )
Inventor
#4 Old 3rd Jun 2015 at 8:19 AM
I mean that it works: I compiled it, imported in the S3SA and tried in game: it does what it's supposed to do.
If you don't mind me saying this, it's a bit weird that interactions are added to vehicles only after using them, though.
And maybe you should add an interaction to check how much fuel is left (instead of getting a message when you
stop using the car). But, hey, just my un-requested opinion.

Maybe I wasn't clear before. The package you uploaded on MTS has the .dll of your chocolate maker in the S3SA
instead of the .dll of the petrolMod. You imported the wrong dll in the S3SA. That's why it doesn't work.

EDIT: I didn't checked the code carefully and maybe it already does this, but you should implement something to
check for unused entries in the dictionary. If Sims die, their entry will stay there forever otherwise. If a car is
deleted, its entry is not removed from the dictionary.
Instructor
Original Poster
#5 Old 3rd Jun 2015 at 9:44 AM
Never thought I was this stupid to import a wrong .dll! Thanks! There's a saying that the watcher / bystander often has a clearer mind than the one in the business or matter. I find it really true.

I will change the check fuel thingy to an interaction, and I'll need some time to figure out how to do an entry removal on the object's destruction. I'll manage this... right...
Inventor
#6 Old 3rd Jun 2015 at 9:55 AM
I can see how that mistake can happen, don't be too hard on yourself. Keep up the good work ^^
Back to top