View Full Version : Script Solution Successfully "Built" in VS But Interaction Doesn't Appear In-Game
gesimz
30th Jan 2012, 10:45 AM
Last month, I completed a script solution in an attempt to make Stylist and Interior Design portfolios Sellable and Deletable in Live View in an active Sims inventory and also in Build/Buy mode. I stop worked on this due to the stumbling block I hit plus having other commitments but am keen to get it finished as a workable solution for myself and other players. The first part of the mod (as you'll see in the code and attached image below) to be able to delete and sell the portfolio in an active sims inventory works fine, and as intended. But I didn't like how if selling the Portfolio, you would lose the value you would've gotten on photos if you sold them individually (i.e. you'll get zero simelons). So my idea was to take the "Sell All" interaction from the camera and copy it over underneath the Portfolio CanBeSold override to enable selling of all the photos camera style. While I was successfully able to build the solution, for some reason, the new interaction to "Sell All Photos" will not appear in game for the Portfolio. I've obviously missed/failed to include something in the code needed to make the interaction appear in game, but i'm not sure exactly what that is. Here is the current code (in the spoiler tag):
namespace Sims3.Gameplay.Objects.Electronics.Gesimz
{
using Sims3.Gameplay.Actors;
using Sims3.Gameplay.Autonomy;
using Sims3.Gameplay.Interactions;
using Sims3.Gameplay.Objects.Electronics;
using Sims3.Gameplay.Objects.HobbiesSkills;
using Sims3.SimIFace;
using System;
using System.Collections.Generic;
public class SellablePortfolio : PortfolioDigital
{
public override bool CanBeSold()
{
return true;
}
public override void OnStartup()
{
base.OnStartup();
}
}
}
public sealed class PortfolioDigital_SellAll : ImmediateInteraction<Sim, PortfolioDigital>
{
public static readonly InteractionDefinition Singleton = new Definition();
protected override bool RunFromInventory()
{
List<Photograph> list = base.Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
foreach (Photograph photograph2 in list)
{
base.Target.Inventory.RemoveByForce(photograph2);
photograph2.SellImageObject(base.Actor, photograph2.Value);
}
return true;
}
[DoesntRequireTuning]
private sealed class Definition : ImmediateInteractionDefinition<Sim, PortfolioDigital, Camera.Camera_SellAll>
{
protected override string GetInteractionName(Sim Actor, PortfolioDigital Target, InteractionObjectPair interaction)
{
List<Photograph> list = Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
return "SellAll";
}
protected override bool Test(Sim Actor, PortfolioDigital Target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
{
return ((!Actor.SimDescription.ToddlerOrBelow && Actor.IsHuman) && (Target.Inventory.AmountIn<Photograph>() > 0));
}
}
}
}
I've followed all steps correctly in the Object Modding Guide: http://simswiki.info/wiki.php?title=Tutorial:Sims_3_Object_Modding for "Adding The Script To The Package", so the issue I suspect is related to the code above and something being missing from there to make the interaction appear in-game.
Any assistance to resolve this issue and complete the mod would be much appreciated.
Odistant
30th Jan 2012, 02:00 PM
You probably don't have a onworlload event handler. Its not loading existing portfolios and adding the interaction is my guess.
Digitalchaos
30th Jan 2012, 02:36 PM
EDIT: You probably could get away with just updating your OnStartup() method to include AddInventoryInteraction and ignore the links I posted to my source code (which is a more involved form of global mod)
You can look at some code I have here (http://svn.netsolutions.dnsalias.com:81/websvn/sims3/mods/CoreObjectScripts/Sims3.NeoH4x0r.Core/trunk/Sims3.NeoH4x0r.Core.Interactions/Global/)
You should look closely at stdGlobalMod.cs
You can also look at code here (http://svn.netsolutions.dnsalias.com:81/websvn/sims3/mods/GlobalMods/NeoH4x0rGlobalOnlineBankingMod/trunk/NeoH4x0rGlobalOnlineBankingMod/) for ideas on how to use the code in stdGlobalMod.cs.
The only thing you would have to decide on is wether you want an: ActorLessInteraction, ImmediateInteraction, or a standard Interaction.
Moreover:
in SellablePortfolio.OnStartUp():
you never call AddInventoryInteraction(InteractionDefinition def);
public class SellablePortfolio : PortfolioDigital
{
public override bool CanBeSold()
{
return true;
}
public override void OnStartup()
{
base.OnStartup();
base.AddInventoryInteraction(PortfolioDigital_SellAll.Singleton);
}
}
gesimz
1st Feb 2012, 01:09 AM
Digitalchaos, your suggestion of adding base.AddInventoryInteraction(PortfolioDigital_SellAll.Singleton); to the original code in post 1 worked in getting the interaction to appear in-game (see attached image below), but for some reason, when you click on the interaction, it doesn't do anything (it won't even exit out of the pie menu, to attempt the interaction). I've obviously messed up in the code somewhere in post 1 (the opening post) which is preventing the interaction from working properly.
I wonder if the line in the code in post 1 where i've left the word camera here in there is the offending line:
private sealed class Definition : ImmediateInteractionDefinition<Sim, PortfolioDigital, Camera.Camera_SellAll>
The issue is though, when I change camera to PortfolioDigital it says: Error 1 The type name 'PortfolioDigital_SellAll' does not exist in the type 'Sims3.Gameplay.Objects.Electronics.PortfolioDigital' in Visual Studio.
EDIT: I've not attempted anything to do with onworldload event handler as Odistant suggested just yet.
Buzzler
1st Feb 2012, 05:45 PM
The issue is though, when I change camera to PortfolioDigital it says: Error 1 The type name 'PortfolioDigital_SellAll' does not exist in the type 'Sims3.Gameplay.Objects.Electronics.PortfolioDigital' in Visual Studio.If that in the first post is your actual code, it shouldn't compile at all. Please post the most recent version if the problem persist.
The signature of Definition should look like this:
private sealed class Definition : ImmediateInteractionDefinition<Sim, PortfolioDigital, PortfolioDigital_SellAll>
gesimz
1st Feb 2012, 10:10 PM
Buzzler, thank you! The interaction now works in-game!
Here is the successfully compiled code with localized coding (adding using Sims3.Gameplay.Utilities; and the localized code which is also highlighted below underneath the spoiler):
namespace Sims3.Gameplay.Objects.Electronics.Gesimz
{
using Sims3.Gameplay.Actors;
using Sims3.Gameplay.Autonomy;
using Sims3.Gameplay.Interactions;
using Sims3.Gameplay.Objects.Electronics;
using Sims3.Gameplay.Objects.HobbiesSkills;
using Sims3.Gameplay.Utilities;
using Sims3.SimIFace;
using System;
using System.Collections.Generic;
public class SellablePortfolio : PortfolioDigital
{
public override bool CanBeSold()
{
return true;
}
public override void OnStartup()
{
base.OnStartup();
base.AddInventoryInteraction(PortfolioDigital_SellAll.Singleton);
}
}
public sealed class PortfolioDigital_SellAll : ImmediateInteraction<Sim, PortfolioDigital>
{
public static readonly InteractionDefinition Singleton = new Definition();
protected override bool RunFromInventory()
{
List<Photograph> list = base.Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
foreach (Photograph photograph2 in list)
{
base.Target.Inventory.RemoveByForce(photograph2);
photograph2.SellImageObject(base.Actor, photograph2.Value);
}
return true;
}
[DoesntRequireTuning]
private sealed class Definition : ImmediateInteractionDefinition<Sim, PortfolioDigital, PortfolioDigital_SellAll>
{
protected override string GetInteractionName(Sim Actor, PortfolioDigital Target, InteractionObjectPair interaction)
{
List<Photograph> list = Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
return Localization.LocalizeString("LocalizedMod/Sell All Photos:InteractionName", new object[0]);
}
protected override bool Test(Sim Actor, PortfolioDigital Target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
{
return ((!Actor.SimDescription.ToddlerOrBelow && Actor.IsHuman) && (Target.Inventory.AmountIn<Photograph>() > 0));
}
}
}
}
Just to confirm before I upload the finished mod (still need to localize the strings with STBL.exe and S3PE), is this localized string line correct and will produce the intended effect of having the strings in pie menu interaction automatically display the correct language in a non-english game?:
return Localization.LocalizeString("LocalizedMod/Sell All Photos:InteractionName", new object[0]);
gesimz
2nd Feb 2012, 07:02 AM
Also, where can Twallans STBL Converter (exe) be downloaded so I can complete the final steps of the localized coding tutorial to complete the mod? The link in the Localized Coding tutorial is now dead following Twallans move from The Isz to WikiSpaces.
EDIT: Just found the new link for STBL.exe: http://nraas.wikispaces.com/file/view/STBL.zip
gesimz
2nd Feb 2012, 10:04 AM
Ok, I had a go at the Localized Coding bit myself:
Assuming the line in post 6 is correct, this was what I ended up typed for the .txt file to drag onto STBL.exe:
<?xml version="1.0" ?>
<TEXT>
<KEY>LocalizedMod/Sell All Photos:InteractionName</KEY>
<STR>Sell All Photos</STR>
</TEXT>
Then, I just followed the rest of the instructions in the rest of the localized coding tutorial.
Does it matter that the strings do not display in the language other than English to the right in S3PE (see attached image with relevant bits only scrunched to fit within max upload dimensions)? As long as you have the correct locale code for each instance will it still translate the strings in-game?
Also, whats the best way to test localized coding? Earlier today, I changed the language via Regedit, but when I wanted to change back to English, it completely broke my game and I had to reinstall everything, expansion packs and all. Whats the safest way to go about testing the strings in other languages?
EDIT: Going to use Jonha's Any Game Starter to test the strings. If I have any further problems, i'll post below.
Buzzler
3rd Feb 2012, 10:17 AM
<KEY>LocalizedMod/Sell All Photos:InteractionName</KEY>That's not really a good, as in likely unique, key, though. You should always try to make instance names, keys etc. that you use for hashes unique. E.g. by adding your name and the name of your mod to them.
Does it matter that the strings do not display in the language other than English to the right in S3PE (see attached image with relevant bits only scrunched to fit within max upload dimensions)?Doesn't sound right. I always see all strings.
Earlier today, I changed the language via Regedit, but when I wanted to change back to English, it completely broke my game and I had to reinstall everything, expansion packs and all.And that's why I don't do that. ;)
Whats the safest way to go about testing the strings in other languages?Well, I didn't before, but you could upload it to modyourpanties and then ask in #CREATE if someone plays the game in non-English and is willing to test.
PS: There's some redundancy in your code. E.g. you never use that num variable in your Run() method. Same in GetInteractionName().
PPS: I've updated the link to twallan's STBL. Thanks for the heads up.
gesimz
3rd Feb 2012, 10:29 AM
I also noticed something else just now. The script will only work to selling portfolios and selling photos in portfolios generated AFTER the mod has been put into /packages and run in-game.
If a portfolio is already in an active Sims inventory BEFORE the script mod is used, you are unable to sell the portfolio in live view in the active sims inventory or sell the photos already in there.
Could this be due to the code having no onworldload event handler?
Odistant
4th Feb 2012, 04:32 AM
Yep, it is. If you look at the scripting tutorial (world one) that buzzler made it should help you a bit. I will edit this post in the morning tomorrow to give you a better example code. But looking at things like the kolipoki life mod or whatever in reflector or others that use exisiting items should give you a very good idea on how to do it.
So instead of pausing the game you will want to load the interaction with MyInteraction.Singleton. So some check if the item is in Sims inventory. Sorry I can't be much more help, but I don't have Visual Studio on my phone :(
Buzzler
4th Feb 2012, 04:00 PM
I also noticed something else just now. The script will only work to selling portfolios and selling photos in portfolios generated AFTER the mod has been put into /packages and run in-game. {...} Could this be due to the code having no onworldload event handler?Your mod is overriding the OBJK resource of the Portfolio object to make it use your derived class instead of the original one, right? If so, then there's a misunderstanding going on here.
First, like you noticed, changing an OBJK to reference a difference script class, doesn't make the original class go away. Existing objects "know" their script class. The information doesn't get reread from the OBJK everytime the game is started. Thus changing the OBJK only affects new objects. Unless you delete the script cache. ;)
The misundersting is that scripted objects and pure scripting mods differ in an important way. The OnWorldFinished stuff is only necessary for pure scripting mods. It's the way to get your code up and running. For a scripted object you make a script class that is (ultimately) derived from the GameObject class, attach it to an object (not the object as in "instance of a class", but everything else that defines a build/buy object for TS3) and leave it to the EAxian core to get your code running when the object is instantiated.
Is it really a scripted object you're going for? I notice that your script class doesn't add special functionality to the object itself, so a pure scripting mod to add your interaction to all portfolios might be the better (and less invasive) way.
For adding an interaction with a pure scripting mod, you do that OnWorldLoadFinished stuff explained in the pure scripting tutorial. In the callback method you can add the interaction to all objects of your choice. There's a Queries class that lets you query (duh!) for all objects of a class.
private static void OnWorldLoadFinishedHandler(object sender, EventArgs e)
{
foreach (Portfolio p in Sims3.Gameplay.Queries.GetObjects<Portfolio>())
{
AddInteractions(p);
}
}
private static void AddInteractions(Portfolio p)
{
if (p == null)
{
return;
}
foreach (InteractionObjectPair pair in p.Interactions)
{
if (pair.InteractionDefinition.GetType() == Portfolio_SellAll.Singleton.GetType())
{
return;
}
}
p.AddInteraction(Portfolio_SellAll.Singleton);
}Since you need an inventory interaction, it's gonna be a little different. Also, you'll need to do something that catches new portfolios to add the interaction to them as well. I'm not sure if there's an event being raised for that, so you may need to do it alarm-based.
Digitalchaos
4th Feb 2012, 09:32 PM
Since you need an inventory interaction, it's gonna be a little different. Also, you'll need to do something that catches new portfolios to add the interaction to them as well. I'm not sure if there's an event being raised for that, so you may need to do it alarm-based.I use:
World.OnWorldLoadFinishedEventHandler (during what buzzler said, you can add add inventory interactions to all objects of type Portfolio)
World.OnObjectPlacedInLotEventHandler -- I'm not sure if it would work for inventory objects...but it should catch newly created objects
Usage Example: (place all of this code into a class and call from a static constructor, or just call directly from the static constructor)
World.OnWorldLoadFinishedEventHandler += new EventHandler(this.GlobalModEventHandler);
World.OnObjectPlacedInLotEventHandler += new EventHandler(this.GlobalModEventHandler);
Example Code:
public void GlobalModEventHandler(object sender, EventArgs e)
{
List<Sims3.Gameplay.Objects.Electronics.PortfolioDigital> list = new List<Sims3.Gameplay.Objects.Electronics.PortfolioDigital>(Sims3.Gameplay.Queries.GetObjects<Sims3.Gameplay.Objects.Electronics.PortfolioDigital>());
foreach (Sims3.Gameplay.Objects.Electronics.PortfolioDigital target in list)
{
if (!target.Interactions.Contains(new InteractionObjectPair(PortfolioDigital_SellAll.Singleton, target)))
{
target.AddInteraction(PortfolioDigital_SellAll.Singleton);
target.AddInventoryInteraction(PortfolioDigital_SellAll.Singleton);
}
}
}
Static Events Available from World Class:
public static event EventHandler OnDesignModeCancelEventHandler;
public static event World.DesignModeFoundPatternEventHandler OnDesignModeFoundPatternEventHandler;
public static event EventHandler OnDesignModeStartEventHandler;
public static event EventHandler OnEnterNotInWorldEventHandler;
public static event EventHandler<World.OnFinishedLoadingSaveGameEventArgs> OnFinishedLoadingSaveGameEventHandler;
public static event EventHandler OnFinishedLoadingWorldFileEventHandler;
public static event EventHandler OnLeaveNotInWorldEventHandler;
public static event EventHandler OnLotAddedEventHandler;
public static event EventHandler OnLotBoundsChangedEventHandler;
public static event EventHandler OnLotRemovedEventHandler;
public static event EventHandler OnLotTypeChangedEventHandler;
public static event EventHandler OnObjectLotUpdateEventHandler;
public static event EventHandler OnObjectPendingDestructionEventHandler;
public static event EventHandler OnObjectPlacedInLotEventHandler;
public static event EventHandler OnObjectSoundMaterialUpdatedEventHandler;
public static event EventHandler OnObjectVideoStoppedEventHandler;
public static event EventHandler OnQuitAppEventHandler;
public static event EventHandler OnStartupAppEventHandler;
public static event EventHandler OnTextureCompositeFinishedEventHandler;
public static event EventHandler OnTextureCompositeStartedEventHandler;
public static event EventHandler OnWorldLoadFailedEventHandler;
public static event EventHandler OnWorldLoadFinishedEventHandler;
public static event EventHandler OnWorldLoadStartedEventHandler;
public static event EventHandler OnWorldLoadStatusEventHandler;
public static event EventHandler OnWorldQuitEventHandler;
Buzzler
4th Feb 2012, 10:50 PM
World.OnObjectPlacedInLotEventHandler -- I'm not sure if it would work for inventory objects...That's why I didn't mention it. ;)
gesimz
5th Feb 2012, 10:32 PM
Thanks for all the replies RE: World.OnWorldLoadFinishedEventHandler sample codes.
Does a version of both codes need to be put into the final code, or will just one of them suffice (i.e. both sample World.OnWorldLoadFinishedEventHandler achieve the same purpose, hence only needing to use one).
PS: There's some redundancy in your code. E.g. you never use that num variable in your Run() method. Same in GetInteractionName().
When you say redundancy, does that mean that those parts of the code aren't being used and hence can be deleted from the code?
You're right in that I originally had this mod as an object mod that overrided the OBJK resource of the Portfolio object to make it use the derived class instead of the original one, so as advised, i'll attempt to convert this to a pure scripting mod. With the above sample code for the World.OnWorldLoadFinishedEventHandler, i'll see if I can get something (a pure script mod) successfully complied and see if it the intended effect successfully ends up appearing in-game.
gesimz
6th Feb 2012, 12:17 AM
In Visual Studio, adding Digitalchaos's sample code, I was able to compile the following code (in the spoiler tag):
namespace gesimz
{
using Sims3.Gameplay;
using Sims3.Gameplay.Actors;
using Sims3.Gameplay.Abstracts;
using Sims3.Gameplay.Autonomy;
using Sims3.Gameplay.EventSystem;
using Sims3.Gameplay.Interactions;
using Sims3.Gameplay.Objects.Electronics;
using Sims3.Gameplay.Objects.HobbiesSkills;
using Sims3.Gameplay.Utilities;
using Sims3.SimIFace;
using System;
using System.Collections.Generic;
public class SellablePortfolio
{
[Tunable]
protected static bool kInstantiator = false;
static SellablePortfolio()
{
}
public void GlobalModEventHandler(object sender, EventArgs e)
{
List<Sims3.Gameplay.Objects.Electronics.PortfolioDigital> list = new List<Sims3.Gameplay.Objects.Electronics.PortfolioDigital>(Sims3.Gameplay.Queries.GetObjects<Sims3.Gameplay.Objects.Electronics.PortfolioDigital>());
foreach (Sims3.Gameplay.Objects.Electronics.PortfolioDigital target in list)
{
if (!target.Interactions.Contains(new InteractionObjectPair(PortfolioDigital_SellAll.Singleton, target)))
{
target.AddInteraction(PortfolioDigital_SellAll.Singleton);
target.AddInventoryInteraction(PortfolioDigital_SellAll.Singleton);
}
}
}
public sealed class PortfolioDigital_SellAll : ImmediateInteraction<Sim, PortfolioDigital>
{
public static readonly InteractionDefinition Singleton = new Definition();
protected override bool RunFromInventory()
{
List<Photograph> list = base.Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
foreach (Photograph photograph2 in list)
{
base.Target.Inventory.RemoveByForce(photograph2);
photograph2.SellImageObject(base.Actor, photograph2.Value);
}
return true;
}
[DoesntRequireTuning]
private sealed class Definition : ImmediateInteractionDefinition<Sim, PortfolioDigital, PortfolioDigital_SellAll>
{
protected override string GetInteractionName(Sim Actor, PortfolioDigital Target, InteractionObjectPair interaction)
{
List<Photograph> list = Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
return Localization.LocalizeString("LocalizedMod/Sell All Photos:InteractionName", new object[0]);
}
protected override bool Test(Sim Actor, PortfolioDigital Target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
{
return ((!Actor.SimDescription.ToddlerOrBelow && Actor.IsHuman) && (Target.Inventory.AmountIn<Photograph>() > 0));
}
}
}
}
}
But at the moment it is without the World.OnWorldLoadFinishedEventHandler += new EventHandler(this.GlobalModEventHandler); line because when I insert that line after
static SellablePortfolio()
{
<-- between the two curly brackets here
},
An error comes up in Visual Studio preventing compiling saying: Error 1 Keyword 'this' is not valid in a static property, static method, or static field initializer
Also, how do I now incorporate the
public override bool CanBeSold()
{
return true;
}
public override bool LiveDraggingEnabled()
{
return true;
}
public override void OnStartup()
{
base.OnStartup();
base.AddInventoryInteraction(PortfolioDigital_SellAll.Singleton);
}
Which were originally part of the object mod (i.e. the previous code in earlier posts) to the pure script mod?
Buzzler
6th Feb 2012, 07:38 AM
An error comes up in Visual Studio preventing compiling saying: Error 1 Keyword 'this' is not valid in a static property, static method, or static field initializerMake the GlobalModEventHandler method static as well.
Also, how do I now incorporate the {...}You don't. They belong to the object, not the interaction.
gesimz
6th Feb 2012, 07:56 AM
Make the GlobalModEventHandler method static as well.
Removing the word static in front of SellablePortfolio fixed the issue and the pure scipt compiled successfully.
public class SellablePortfolio
{
[Tunable]
protected static bool kInstantiator = false;
SellablePortfolio()
{
World.OnWorldLoadFinishedEventHandler += new EventHandler(this.GlobalModEventHandler);
}
You don't. They belong to the object, not the interaction.
Ok, in that case, is it fine to have two S3SAs (two scripts in the one package) one for the "sell all photos" interaction (which is the pure script) and an object mod for CanBeSold given that CanBeSold (unlike LiveDraggingEnabled) seemingly (unless i've missed something) cannot be adjusted via an OBJD edit of the Stylist and Interior Designer portfolios? CanBeSold for the PortfolioDigital is set to false by default via script and for the purposes of this mod-in-progress and being able to get rid of the portfolio in inventory in live view, must be set to true.
gesimz
7th Feb 2012, 12:57 AM
Just tested the pure script in game, the "sell all photos" interaction won't appear at all for some reason
namespace gesimz
{
using Sims3.Gameplay;
using Sims3.Gameplay.Actors;
using Sims3.Gameplay.Abstracts;
using Sims3.Gameplay.Autonomy;
using Sims3.Gameplay.EventSystem;
using Sims3.Gameplay.Interactions;
using Sims3.Gameplay.Objects.Electronics;
using Sims3.Gameplay.Objects.HobbiesSkills;
using Sims3.Gameplay.Utilities;
using Sims3.SimIFace;
using System;
using System.Collections.Generic;
public class SellablePortfolio
{
[Tunable]
protected static bool kInstantiator = false;
SellablePortfolio()
{
World.OnWorldLoadFinishedEventHandler += new EventHandler(this.GlobalModEventHandler);
}
public void GlobalModEventHandler(object sender, EventArgs e)
{
List<Sims3.Gameplay.Objects.Electronics.PortfolioDigital> list = new List<Sims3.Gameplay.Objects.Electronics.PortfolioDigital>(Sims3.Gameplay.Queries.GetObjects<Sims3.Gameplay.Objects.Electronics.PortfolioDigital>());
foreach (Sims3.Gameplay.Objects.Electronics.PortfolioDigital target in list)
{
if (!target.Interactions.Contains(new InteractionObjectPair(PortfolioDigital_SellAll.Singleton, target)))
{
target.AddInteraction(PortfolioDigital_SellAll.Singleton);
target.AddInventoryInteraction(PortfolioDigital_SellAll.Singleton);
}
}
}
public sealed class PortfolioDigital_SellAll : ImmediateInteraction<Sim, PortfolioDigital>
{
public static readonly InteractionDefinition Singleton = new Definition();
protected override bool RunFromInventory()
{
List<Photograph> list = base.Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
foreach (Photograph photograph2 in list)
{
base.Target.Inventory.RemoveByForce(photograph2);
photograph2.SellImageObject(base.Actor, photograph2.Value);
}
return true;
}
[DoesntRequireTuning]
private sealed class Definition : ImmediateInteractionDefinition<Sim, PortfolioDigital, PortfolioDigital_SellAll>
{
protected override string GetInteractionName(Sim Actor, PortfolioDigital Target, InteractionObjectPair interaction)
{
List<Photograph> list = Target.Inventory.FindAll<Photograph>(true);
int num = 0;
foreach (Photograph photograph in list)
{
num += photograph.Value;
}
return Localization.LocalizeString("LocalizedMod/Sell All Photos:InteractionName", new object[0]);
}
protected override bool Test(Sim Actor, PortfolioDigital Target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
{
return ((!Actor.SimDescription.ToddlerOrBelow && Actor.IsHuman) && (Target.Inventory.AmountIn<Photograph>() > 0));
}
}
}
}
}
I wonder what the issue is...
Odistant
7th Feb 2012, 04:16 AM
I think there's a AddImmediateInteractionToInventory method. If so then use that, it could be your issue.
Buzzler
7th Feb 2012, 08:12 AM
Just tested the pure script in game, the "sell all photos" interaction won't appear at all for some reasonYou don't have a static constructor.
I think there's a AddImmediateInteractionToInventory method.There isn't.
gesimz
7th Feb 2012, 09:12 AM
You don't have a static constructor.
This time I put in a static constructor and removed the word "this" from the GlobalModEventHandler which allowed the code to compile.
[Tunable]
protected static bool kInstantiator = false;
static SellablePortfolio()
{
World.OnWorldLoadFinishedEventHandler += new EventHandler(GlobalModEventHandler);
}
Will see if the code works now in-game.
gesimz
7th Feb 2012, 09:50 AM
Interaction works! Pie menu is blank, but the interaction appears and works retrospectively when a portfolio with photos is already in an active Sims inventory prior to the mod being placed in .packages, that's the main thing, the localized coding stuff to get the string to appear in the pie menu can happen later.
Now the hard bit of the mod is done thanks to all your help above, now for the second (and easier half of this mod), the second S3SA object mod to make CanBeSold = True.
I just wanted to check, can you have both a pure script (sell all photos interaction) and an object mod script (CanBeSold return True) at the same time, in the one .package file (i.e. two S3SAs in the one .package)?
Assuming the answer to the above is yes, then, how do you make an Object Script (to be sellable, in inventory when you drag the portfolio to the sell part on the left and then let go of the mouse button to sell) apply to Portfolios in a Sims inventory prior to the mod being placed in .packages? Basically, what is the equivalent of World.OnWorldLoadFinishedEventHandler for an object mod script so that enabling CanBeSold applies retrospectively to Portfolios already in a Sims inventory PRIOR to placing the mod in .packages?
Buzzler
7th Feb 2012, 11:05 AM
I just wanted to check, can you have both a pure script (sell all photos interaction) and an object mod script (CanBeSold return True) at the same time, in the one .package file (i.e. two S3SAs in the one .package)?Yes, that's no problem.
Assuming the answer to the above is yes, then, how do you make an Object Script (to be sellable, in inventory when you drag the portfolio to the sell part on the left and then let go of the mouse button to sell) apply to Portfolios in a Sims inventory prior to the mod being placed in .packages?If deleting the script cache doesn't do anything, that can't be done at all. Like I said, (game) objects, once instantiated, remember their script class.
gesimz
7th Feb 2012, 01:46 PM
If deleting the script cache doesn't do anything, that can't be done at all. Like I said, (game) objects, once instantiated, remember their script class.
That's a shame. But I did find that when using an OBJD edit combined an object script that Changes CanBeSold to true while achieving the end result and allowing for Portfolios to be deleted, seemed to cause adverse consequences with future portfolios after you quit and join the Stylist or Architectual Designer Professions again, not generating at all in Inventory AND Portfolios in the world (purchased from BuyDebug after the portfolio generated by the profession has been deleted) not being able to be dragged into inventory.
It's for these reasons that the mod-in-progress will ultimately need to be scrapped and Twallans Debug Enabler and the Radius Purge function remains the optimal solution for dealing with "stuck portfolios" in Sims inventory, but I do appreciate the assistance you, Digitalchaos and Odistant provided as it has now made things a little less confusing for future script mod attempts, which I already have an idea or two for.
vBulletin v3.0.14, Copyright ©2000-2013, Jelsoft Enterprises Ltd.