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!
One horse disagreer of the Apocalypse
Original Poster
#1 Old 14th Feb 2016 at 7:36 PM
Default What links an interaction tuning to some python script?
Most examples just point onwards to yet another xml, there are several examples where the outcome is that an animation runs, but I have never found any example of just running some script. Does it never happen or something? Surely at some point some python should be called else what are all the scripts taking up space on the disk for?

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Advertisement
Pettifogging Legalist!
retired moderator
#2 Old 14th Feb 2016 at 7:39 PM
What exactly are you trying to acheive?

Stuff for TS2 · TS3 · TS4 | Please do not PM me with technical questions – we have Create forums for that.

In the kingdom of the blind, do as the Romans do.
One horse disagreer of the Apocalypse
Original Poster
#3 Old 14th Feb 2016 at 7:43 PM
Just an overview of how the interaction tuning relates to the scripts. I am wondering if I am just too stuck in the past or something, when interactions did stuff other than giving you a buff lol

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Pettifogging Legalist!
retired moderator
#4 Old 14th Feb 2016 at 7:52 PM
Did you read the EAxian CC guide? From what I recall their example mod has an interaction which they explain in quite a bit of detail. Also check out outcomes, like loot actions / continuations .. maybe that helps you do whatever it is you want do to.

Stuff for TS2 · TS3 · TS4 | Please do not PM me with technical questions – we have Create forums for that.

In the kingdom of the blind, do as the Romans do.
One horse disagreer of the Apocalypse
Original Poster
#5 Old 14th Feb 2016 at 8:03 PM
Yes I read it, but like I say all it did in the end was link to an animation. Not to a python script. Hopefully someone is reading this who has actually done it!

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
One horse disagreer of the Apocalypse
Original Poster
#6 Old 14th Feb 2016 at 9:17 PM
After looking at some other poeple's mods that I expected to run something, I am beginning to understand they just don't. All the xmls can do is give tokens such as buffs. Then the game engine tests for the buffs - but it's basically client/server, with the xmls the client side and the python the server side, the client does not directly trigger processes on the server. AIUI at the moment.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Deceased
#7 Old 15th Feb 2016 at 2:36 AM
Maybe I'm not following exactly what the original question is, but if you're just wanting to call a script from an interaction that can be easily accomplished with a CommandSuperInteraction, of which there are quite a few examples in the cheat interactions in the game, e.g. 195D0 "cheat_set_as_head". With that tuning the target's object id is sent as an argument to the command. I also use this in several of my mods, SimLotto for example.

That works well for cheats, although I use it for other purposes by doing a regular interaction first and pushing the command interaction - because the other method didn't use to work. However, EA started using it with Get To Work so it's working fine now and can be used. That's the "do_command" and it's available as part of a standard SuperInteraction. This has the advantage also of being able to specify multiple arguments defined in the XML to the command script, see for instance the "retail_Register_SetPrices_XXXX" interactions, 1AC8B-1AC8F in EP01.

Or if you're asking what script exactly runs as part of a standard interaction to, for example, start an animation... that's much more complex, but it is controlled by the Python scripts and I "kind of" understand what goes on at some stages and I'm "kind of" thoroughly clueless at some of the other stages. So the question would have to be pretty specific for me to answer anything. It's pretty much all in the Python though when it comes to scheduling, testing, setup and execution for the interactions.
Deceased
#8 Old 15th Feb 2016 at 2:44 AM
BTW, if you were asking just how to call a Python script from an interaction - I actual wrote a tutorial way back that demonstrates calling a Python command from a mailbox interaction: http://modthesims.info/showthread.p...110#post4710110
One horse disagreer of the Apocalypse
Original Poster
#9 Old 15th Feb 2016 at 8:35 AM
Oh thanks scumbumbo! I haven't got an exact requirement yet as I wanted to get an overview of the flow before even deciding what type of modding I am willing to tackle. But obviously I have in mind the typical TS2 interactions I was used to for so long, where you add an interaction to the pie menu, and it names a specific script for the test, returning true and false, and then one which runs, and the script itself handles all the animations and results. TS3 was really pretty much similar except in C# and xml. I am sure your tutorial will enlighten me.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Deceased
#10 Old 15th Feb 2016 at 5:45 PM
Well, both types of modding are pretty powerful. Handling results in a script can be pretty easy, for instance in SimLotto v2 now I'm assigning loot buffs in the script after it runs. But if you don't need to something terribly special the XML modding is quite flexible and typically less error prone.

I've never messed with triggering animations in a script, although it should be doable particularly for a one-shot. I think I'd probably try to avoid scripting for that and come at it from a different direction - that direction dependent on exactly what you are trying to accomplish. For instance, if I wanted a sim to do an arm pump or other reaction based on the results of the SimLotto, I could add a loot to them to perform a reaction. The loot itself and the actual reaction animations would all be in XML, all the script would have to do is tell the client to add that loot action to the sim.

On the other hand, if I wanted the results from the script to trigger an animation on an object, perhaps shoot fireworks out of the PC when they jackpot the lotto, I would probably come at it by adding an object state to the object itself and adding a state trigger to the object that then triggers the animation. Again, all of that would be in XML and all I would do in the script is to set the object into that state and let the XML handle the nitty gritty details of the animation itself.

So really, the only reason to turn to scripting is when you are doing something that the XML just plain can't handle, and with a bit of investigation into the tuning descriptions and experience you'll be able to figure out which approach to take. So I'd suggest diving in and we'll help out if needed!
One horse disagreer of the Apocalypse
Original Poster
#11 Old 15th Feb 2016 at 5:59 PM
What I am most hoping to be possible is a mod for restock bakery from... not from owner's inventory as the food will probably be rotten by the time it's taken. But possibly create a bakery display with a storage facility inside it to drag the stuff to, or even some special modded freezer which is seperate. Now I do want the restocking points, so I don't want to simply automate the restocking. But basically when someone restocks a food item, the game will look for one of these special storage places, and if there is a matching foodstuff in there, will use that instead of paying the restocking cost.

What I am not quite decided on is whether I want "restock from storage" as a seperate option added to the restocking signs or whether to simply assume that if the mod is installed that's the automatic preferred action.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
One horse disagreer of the Apocalypse
Original Poster
#12 Old 15th Feb 2016 at 7:23 PM Last edited by Inge Jones : 15th Feb 2016 at 8:54 PM.
So, in "retail_RestockItem" there is a bit that goes:

Code:
  <L n="basic_extras">
    <V t="payment">
      <U n="payment">
        <V t="base_retail_value" n="cost" />
        <U n="cost_modifiers">
          <L n="multipliers">
            <U>
              <T n="multiplier">0.75</T>
              <L n="tests">
                <L>
                  <V t="bucks_perks_test">
                    <U n="bucks_perks_test">
                      <T n="bucks_perk">112338<!--retailPerks_DescreaseRestockingCost--></T>
                    </U>
                  </V>
                </L>
              </L>
            </U>
            <U>
              <T n="multiplier">0.75</T>
              <L n="tests">
                <L>
                  <V t="bucks_perks_test">
                    <U n="bucks_perks_test">
                      <T n="bucks_perk">112337<!--retailPerks_DecreaseRestocking_Temporary--></T>
                    </U>
                  </V>
                </L>
              </L>
            </U>
          </L>
        </U>
        <V t="retail" n="source">
          <U n="retail">
            <E n="funds_category">RESTOCKING</E>
          </U>
        </V>
        <V t="at_end" n="timing">
          <U n="at_end">
            <E n="criticality">NotCritical</E>
          </U>
        </V>
      </U>
    </V>
  </L>


And presumably I'd want to add something to the tests like:

Code:
            <U>
              <T n="multiplier">0</T>
              <L n="tests">
                <L>
                  <V t="foodInFreezer_test">
                    <U n="foodInFreezer_test">
                      <T n="call my scripted test">>?????<!--and might as well remove the food from freezer in the same script while I am testing--></T>
                    </U>
                  </V>
                </L>
              </L>
            </U>


So I have no idea if I can hook a scripted test into one of these sets of tests, and how to catch the result?

Edit: I think I see an example in a "snippet" xml. I will try doing something with that.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Deceased
#13 Old 16th Feb 2016 at 4:50 AM
I think it would be easiest to work it out as a completely new pie menu choice as a separate interaction and would likely have to be a chain of interactions - first step get the item out of the freezer into the Sim's inventory (or as a carry item if possible), then go to the destination and transfer it from the Sim to the shelf.

Btw, as far as I know (and it's possible this has changed), there's no way to run a command script as a test, only as part of the basic extras. They run at the end of the interaction, but they don't really return anything back to the interaction XML to look at for further testing.

Theoretically it would be possible to add a new test type to the TunableTestSet, but ... well, it's never been actually tried to the best of my knowledge. Probably not necessary for this though, you can search an object's inventory easily in a test.
Screenshots
One horse disagreer of the Apocalypse
Original Poster
#14 Old 16th Feb 2016 at 8:43 AM Last edited by Inge Jones : 16th Feb 2016 at 9:10 AM.
Well there must be at least a true or false implied after running the bucks_perk_test since they won't use the 0.75 cost multiplier unless they have that perk. And the test condition there is of course the identity of an xml, so I could have put a snippet xml identity in there, and hope for that to evaluate to true or false in some way. Do you happen to know whether anyone has actually asked the guru outright whether the snippet xml takes on the return value of the snippet it's running - in at least a boolean sense?

My idea was not to return anything to the rest of the interaction but simply to use the fact of there being stock in the freezer as a cost multiplier (0 in this case, so restocking will be free). While I was testing for the presence of the food, I thought I might as well do the deletion of that item from the freezer at the same time to save me running a script twice. So really the only thing I am left in uncertainty about is whether the boolean return value of the snippet is somehow caught by the xml test. I guess trial and error might answer that if it's not generally known yet.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Deceased
#15 Old 16th Feb 2016 at 5:05 PM
Quote: Originally posted by Inge Jones
Well there must be at least a true or false implied after running the bucks_perk_test since they won't use the 0.75 cost multiplier unless they have that perk.

OK, I think I see some of the confusion here... "bucks_perk_test" isn't really a script, it's just the name of a node in the tuning. It does run a Python script internally which returns a true or false result, of course, but when I'm in "XML mode" I don't really think of it as script - it's just a built-in test. All of these tests are described in the Tuning Descriptions, which is a must-read (well, browse at least, you wouldn't want to read it all). If you're using my TDesc browser, then you'll find all of these tests in the "TDescFrag" section under "TunableTestSet" in an easy-to-browse format as the raw file is a pain to look through.

Quote:
And the test condition there is of course the identity of an xml, so I could have put a snippet xml identity in there, and hope for that to evaluate to true or false in some way. Do you happen to know whether anyone has actually asked the guru outright whether the snippet xml takes on the return value of the snippet it's running - in at least a boolean sense?

You cannot just take a snippet (or any other XML node) and stick it somewhere and expect it to work. They are in a class hierarchy and that hierarchy specifies what other nodes are valid children of a specific node.

Quote:
My idea was not to return anything to the rest of the interaction but simply to use the fact of there being stock in the freezer as a cost multiplier (0 in this case, so restocking will be free). While I was testing for the presence of the food, I thought I might as well do the deletion of that item from the freezer at the same time to save me running a script twice. So really the only thing I am left in uncertainty about is whether the boolean return value of the snippet is somehow caught by the xml test. I guess trial and error might answer that if it's not generally known yet.

In the XML you are referencing, that test you want to add (and you would want to use the inventory test I showed in the earlier screenshot for that as you can't just use your own script for a test) is applying only to the parent nodes of that XML - in this case the "payment" node, so it would only affect the payment and would not be able to remove something from the freezer. If you want to specify that additional effect it would have to be in another area that allows for a delete item tuning, ideally the "outcome" of the interaction and the same test would then need to be repeated there.

I'm just not sure though how you would tell it which object type to delete from the freezer (it may possibly be quite easy, I just haven't researched how it might be done). You may notice that the restocking action doesn't really create a new object, if you look at the outcome it is just changing the object state from "sold" to "for sale". This is why I thought it might be easier to have it be done as a new multi-stage interaction - removing the item from the freezer, carrying it over and restocking.

ETA - I think this may be doable as part of the regular single-stage interaction -- there is an inventory check for "has_object_of_participant_type" which should be the target object of the whole interaction. You would then use a "do_command" in your outcome to perform the actual deletion from the freezer inventory. The difficulty there was that the two variants of the destroy object node want to either destroy a SPECIFIC object (we know the actual object's instance id - which we don't) or the contents of a SPECIFIC inventory object (we know the freezer's actual object id - which, again, we don't).

With the do_command in the outcome we can send it the object id of the target (the item being restocked) and you can then write a script that would search for any freezer on the lot (the inventory is shared so we don't care which one) and remove one item of that object's type from its inventory.

Yup, definitely doable, but a pretty complex choice for a first mod. Sounds like a good idea for one though.
One horse disagreer of the Apocalypse
Original Poster
#16 Old 16th Feb 2016 at 8:38 PM
I have spent my spare time today getting to grips with Tdescs and the xml elements, and reading your posts, thanks. It's beginning to make some sort of sense....

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
One horse disagreer of the Apocalypse
Original Poster
#17 Old 18th Feb 2016 at 8:25 PM
In a do-command, is the instance implicitly known to the script via the do_command or must I set it up as a argument? If the latter, how does one refer to "this" or "self" in a tuning file?

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Deceased
#18 Old 19th Feb 2016 at 5:11 AM
The instance of the interaction? It's very likely possible for the script to determine what the current running interaction is, but I would have to do some poking around to reseach how. Probably easiest to just pass it as one of the arguments if you need the script to know what interaction is calling the script.

As for refering to the interaction from the tuning file, you could just pass the interaction by number (since you're writing the interaction you certainly know it), or if you wanted to generalize it you could use the participant type Affordance maybe (not sure, I haven't played with many of these as that enum doesn't seem to get defined in the unzipped .pyo files - so I dumped it in game to find some interesting things). And here they all are
One horse disagreer of the Apocalypse
Original Poster
#19 Old 19th Feb 2016 at 8:16 AM Last edited by Inge Jones : 19th Feb 2016 at 8:36 AM.
Ah I will discuss participants in general in your new thread then

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
One horse disagreer of the Apocalypse
Original Poster
#20 Old 20th Feb 2016 at 1:29 PM
In my instance of your TDesc browser, Tuning doesn't have any expander - ie presents like nothing under it. I do have those TDescs on disk however, where I think your tool should expect to find them along with everything else it is showing.

I see in your download Tools thread (I couldn't find the browser in your actual downloads for some reason) you say that Tuning tdescs won't load, however they obviously have in the version you are using, as evidenced by your screenshot. That would seem to indicate you *did* update it, but I'll be blowed if I can find any thread with the later version in...

Also some items are picked out in yellow or green what does that mean?

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Deceased
#21 Old 21st Feb 2016 at 12:34 AM
That should be fixed in the last version 0.4, which should be the only download available in the thread. The yellow and green highlighting is based on the MUID change information that EA supplies, which doesn't seem to be always updated, I know I've seen things that have changed that end up not being highlighted. Could just be buggy code too, the program is pretty hacked together. I think there's a red highlight too for removed tunings.
One horse disagreer of the Apocalypse
Original Poster
#22 Old 21st Feb 2016 at 8:27 AM
That's the version I have, dated 21st May.

Oh wrt running a snippet as a test, there *is* a testglobal template for a snippet in the tdescs. But I have also asked the simguru about scripted tests as well, to make sure.

Do they explain somewhere what muid means? I assume its something to do with a unique ID but not sure of the significance of 'm'. I googled and gather it might mean something to do with multi, in which case it's not all that unique lol.

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Deceased
#23 Old 22nd Feb 2016 at 5:13 AM
Quote: Originally posted by Inge Jones
Do they explain somewhere what muid means? I assume its something to do with a unique ID but not sure of the significance of 'm'. I googled and gather it might mean something to do with multi, in which case it's not all that unique lol.
They started including the MUID and version history info in the May patch last year. They included a readme with that TDESC to explain them.
One horse disagreer of the Apocalypse
Original Poster
#24 Old 27th Feb 2016 at 7:02 PM
ok... I have got my custom interaction running, it tests the RETAIL_FRIDGE inventory for one of the meals to be replaced, and the result is correct. It is also making the restocking cost zero. So basically the xml functions.

However I am having much more trouble getting the meal to be removed/deleted from the retail_fridge inventory. I have identified two possible ways of doing it:

1) via interaction tuning as in line 25913 of Interaction.tdesc eg
Code:
<U n="destroy_specified_objects_from_target_inventory">
	<V n="count" t="number">
		<T n="number">1</T>
	</V>
	<E n="inventory_owner">
		What do I need for this TunableEnum to say it's the lot's RETAIL_FRIDGE inventory I am wanting?
	</E>
	<TdescFragTag n="object_tests" />  (this is meant to be a <L /> list in its final form
	<U n="success_chance"> don't need any of this as using default
		<T n="base_chance">100</T>
		<L n="multipliers" />
	</U>
</U>


And another way using a script:
Code:
import services
import sims4
import ui.ui_dialog
from objects.components.inventory_enums import InventoryType
from ui.ui_dialog_notification import UiDialogNotification, TunableUiDialogNotificationSnippet
from ui.ui_dialog import UiDialogResponse
from ui.ui_dialog_notification import UiDialogNotification


@sims4.commands.Command('ijRSFF.ijRemoveFromFreezer', command_type=sims4.commands.CommandType.Live)
def ijRemoveFromFreezer(dish, _connection=None):
    # note1 = dish.FAILED_PLACEMENT_NOTIFICATION(dish, SingleSimResolver(self.sim_info))
    note2 = dish.dialog
    note1 = dish.definition
    note1.show_dialog()
    freezer_inventory = services.active_lot().get_object_inventories(InventoryType.RETAIL_FRIDGE)[0]
    if freezer_inventory is not None:
        freezer_inventory.try_destroy_object_by_definition(dish.definition.id)
    return True


The problem with the xml way is I have failed to understand the tdesc enough to tell it I want the retail-fridge shared inventory. The problem with the script is it doesn't appear to be running - or at least I get no popup notification. What is a good way to prove whether or not a script runs?

"You can do refraction by raymarching through the depth buffer" (c. Reddeyfish 2017)
Lab Assistant
#25 Old 27th Feb 2016 at 10:38 PM
I'm not sure if it helps, but what you want to do seems functionally similar to how the game handles grafting. Look at the tuning Gardening_Graft (0x0000000000003463) and the script simulation/crafting/gardening_interactions.py .
(More specifically, that script destroys the object by setting it's transient property to True, which should destroy the object as soon as the interaction ends.)
Page 1 of 2
Back to top