|
Post by boopidoop on Jun 20, 2020 10:54:34 GMT -5
Hiya,
I'm still experimenting with Sims mods to see what is possible and what isn't. Does anyone know a way to repeat a command in an interaction every few sim-minutes? I'm trying to make a silly cheat mod where you get one simoleon every 3 minutes while talking to another Sim
EDIT: Or if it can be ran repeatedly until a buff runs out, something like that
Thanks!
EDIT 2: Found a solution! Check page 2!
|
|
|
Post by BethA on Jun 20, 2020 17:44:44 GMT -5
Hey there,
My first instinct would be to run an infinite loop with a timer, but that would just hang the python interpreter. We can solve that by running the loop on another thread:
import time import threading import sims4.commands
# This is the main loop function we are going to run. def my_loop(conn): # I'm adding the ouput just so we can see the result on the console. output = sims4.commands.CheatOutput(conn)
# Here is the loop. while True:
# Run everything you want here, you can call other functions if you need. output('Testing game loop')
# Set your wait time accordingly, don't make it too short or it can be heavy on the game. time.sleep(10)
# Here is the cheat command, it will start the new thread with our loop. @sims4.commands.Command('loop_test', command_type=sims4.commands.CommandType.Live) def run_loop(_connection=None):
# We are creating a new thread and passing our loop function as target. # I'm also passing the connection for the output as an argument. # Notice that it must be a tuple. I have just a single argument, so I'm forced to use a singleton tuple: (val,) thread = threading.Thread(target=my_loop, args=(_connection,))
# Daemonizng the thread will make sure it gets properly shut down when the game ends. thread.daemon = True
# Starting the thread. This will start our loop function, since it is the thread target. thread.start()
return True
It is not a lot of code, most of it are comments.
To test it, yon can run loop_test on the console and wait, it should print a message every 10 seconds.
|
|
|
Post by boopidoop on Jun 20, 2020 17:54:03 GMT -5
Ah perfect, I forgot about threading! I'm fairly new to python, sorry :D
This uses real-time seconds though, any way to make it use in-game seconds?
|
|
|
Post by BethA on Jun 20, 2020 18:26:55 GMT -5
I'm certain there is a way, but I have not looked at the game time primitives. I know the clock module deals with conversion between real and game time. In particular, there is a function called interval_in_sim_minutes which seems to take real time as argument, but I'm not certain which unit of time. About testing for a buff, as you mentioned, I recently helped my sister with that in a thread at modthesims. You could test during the loop if the sim has the buff to give her the money. To actually get the buff on the sim, you could either check for interactions or add a broadcaster through tuning.
|
|
|
Post by boopidoop on Jun 20, 2020 18:37:46 GMT -5
Thank you, I think I'll just use the easy way and create a hidden buff that lasts for 3 minutes, then when it's removed add a new buff that runs a script that removes it instantly and adds the first buff again. With a break-state obviously
|
|
|
Post by BethA on Jun 20, 2020 18:48:08 GMT -5
That should work.
I didn't show in that thread, but you can test if a sim has a buff like this:
buff_test = # Get the buff like I showed on the thread.
# Test for the buff. if sim_info.has_buff(buff_test):
# Do something here.
This should help you remove the buff safely.
|
|
|
Post by boopidoop on Jun 20, 2020 21:09:08 GMT -5
Ok I got it working kinda, the command does remove and add the correct buffs but the buff isn't running the command, so it's not looping
<U n="game_effect_modifier"> <L n="_game_effect_modifiers"> <V t="affordance_modifier"> <U n="affordance_modifier"> <L n="basic_extras"> <V t="do_command"> <U n="do_command"> <V n="timing" t="at_beginning"/> <T n="command">test_command</T> <L n="arguments"> <V t="participant"> <U n="participant"> <E n="argument">Actor</E> </U> </V> </L> </U> </V> </L> </U> </V> </L> </U>
|
|
|
Post by boopidoop on Jun 21, 2020 1:39:46 GMT -5
Worked out my mistake, I misread the Tdesc. These are basic_extras that are applied to a list of affordances that the modder provides, not commands that run in the buff itself
In that case, any way to make buffs run hidden interactions? Eg. Buff 1 is 60 sim-minutes long, adds Buff 2 when removed, then Buff 2 runs a hidden Interaction with a command in it?
|
|
|
Post by BethA on Jun 21, 2020 7:14:24 GMT -5
I know this is possible, and I remember I did that once, however, I couldn't find it on my old packages :\.
To be honest, nowadays I try to stay away from tuning as much as I can, I simply hate having to track down the IDs through a bunch of XMLs. Being a programmer, I try to do everything in Python.
|
|
|
Post by MizoreYukii on Jun 21, 2020 12:31:33 GMT -5
Worked out my mistake, I misread the Tdesc. These are basic_extras that are applied to a list of affordances that the modder provides, not commands that run in the buff itself In that case, any way to make buffs run hidden interactions? Eg. Buff 1 is 60 sim-minutes long, adds Buff 2 when removed, then Buff 2 runs a hidden Interaction with a command in it? I don't know about interactions, but this buff to buff thing can be accomplished with either commodities, or have the buff run a loot upon removal that runs the other buff. xD If I remember this correctly.
|
|
|
Post by boopidoop on Jun 21, 2020 17:20:02 GMT -5
I know this is possible, and I remember I did that once, however, I couldn't find it on my old packages :\. To be honest, nowadays I try to stay away from tuning as much as I can, I simply hate having to track down the IDs through a bunch of XMLs. Being a programmer, I try to do everything in Python. I'm a programmer too, just wanted to see what is possible with almost entirely tuning :p Still haven't figured out how to do this unfortunately, and I can barely understand the python files to even hope to get it working that way
|
|
|
Post by boopidoop on Jun 21, 2020 17:22:44 GMT -5
Worked out my mistake, I misread the Tdesc. These are basic_extras that are applied to a list of affordances that the modder provides, not commands that run in the buff itself In that case, any way to make buffs run hidden interactions? Eg. Buff 1 is 60 sim-minutes long, adds Buff 2 when removed, then Buff 2 runs a hidden Interaction with a command in it? I don't know about interactions, but this buff to buff thing can be accomplished with either commodities, or have the buff run a loot upon removal that runs the other buff. xD If I remember this correctly. Oh the buff part works fine, got 2 buffs named Test and Bepis, and 10 sim-minutes after Test is added it's removed and adds Bepis
|
|
|
Post by BethA on Jun 22, 2020 14:18:05 GMT -5
I'm a programmer too, just wanted to see what is possible with almost entirely tuning :p Still haven't figured out how to do this unfortunately, and I can barely understand the python files to even hope to get it working that way About the Python files, this has been my greatest frustration with the Sims. I think it is absolutely ridiculous that they can't provide us with a proper API. Instead, we have to actually decompile the python code and figure everything by ourselves. I mean, if we are going to decompile everything anyway, why can't they just provide us with the python source? If it is licensed properly and we can access it anyway, what is the problem? This reeks of corporate ignorance of code licensing and fear of anything open-source. They could at least give us some python documentation, but no. Sorry for the rant.
|
|
|
Post by boopidoop on Jun 22, 2020 16:48:15 GMT -5
No worries, I agree completely. EA claims that the whole series is mod-friendly but it's really not. God, could you imagine if they put comments in the code?
|
|
|
Post by BethA on Jun 23, 2020 7:44:16 GMT -5
I found an old package with an interaction coming from a buff. I can't tell what it does or even if it works, but I thought I should share.
On the buff, besides the usual entries, I have this:
<V n="interactions" t="enabled"> <U n="enabled"> <L n="interaction_items"> <T>13291524115860492665</T> <T>13715471078655243982</T> </L> </U> </V>
On the interaction, again, besides the basic, I have this:
<V n="outcome" t="single"> <U n="single"> <U n="actions"> <V t="disabled" n="animation_ref"/> <L n="loot_list"> <T>11763869515135664706</T> </L> </U> </U> </V>
And the loot action looks like this:
<I c="LootActions" i="action" m="interactions.utils.loot" n="BA_adaptation_action" s="11763869515135664706"> <L n="loot_actions"> <V t="buff"> <U n="buff"> <U n="buff"> <V t="enabled" n="buff_reason"> <T n="enabled">0x290D497E</T> </V> <T n="buff_type">15760989983124606934</T> </U> <E n="subject">Actor</E> </U> </V> <V t="buff_removal"> <U n="buff_removal"> <L n="buffs_to_remove"> <T>17645122340701409117</T> </L> <E n="subject">Actor</E> </U> </V> </L> </I>
It seems the interaction somehow just performs a buff swap. I have no idea what was my intention there, but perhaps you can change the action for doing what you need, instead of dealing with buffs.
|
|