PDA

View Full Version : Script mod example: Make all sims in household sleepy, filling other needs


dcrole
26th Apr 2020, 8:36 PM
Those pesky sims, refusing to keep regular sleep schedules! I wanted a quick way to get all my household sims to go and sleep, and not wake up 2 hours later because they needed the bathroom. I settled on creating a debug command using a script mod that I could run on demand whenever I wanted to get the household to sleep. I have attached the compiled script mod (zipped) if you want to just unzip it in your Sims4 mod folder and use it.

UPDATED - fixed another bug, reworked code a bit, updated attached mod.

TL;DR - if you don't want the gory details, the full code snippet will be at the end of this post.

Please note I am still an absolute beginner when it comes to modding, and Python, and I have stumbled my way to achieve a working solution, so I don't claim that this is the best way, or that I'll be able to help anyone else who is stuck with other problems. I learned what I did from reading tutorials, searching through the decompiled EA scripts for example code, experimenting and failing a lot. Disclaimers out of the way, this is what I did.

It took me a while to get set up to make scripting mods, but I found the following tutorial the easiest to get my environment set up:

http://sims4studio.com/thread/15145/started-python-scripting-updated

So I started by trying to make a command that would do what I wanted for the currently played sim, and then once that was working I would do that for all sims in my household. In fact I ended up keeping both, since there may be times I only wanted to do this for the active sim.

What I wanted was for all needs to be filled, and then the Energy need to be brought low enough for the sim to be sleepy. I assumed that the needs would have values from 0 to 100 - with 100 obviously meaning the need is full. I was wrong - needs actually range from -100 to 100 - so if a need is 0 you will see the bar is half-full. Another thing I learned is that the word Sims uses in code to refer to needs is "motives" - this will help you if you research in the EA code.

NB in my code examples below I will include the imports you need to put at the top of your code file for the other code to work.

In order to register a new command that can be run from the cheat console, and write output to it, you need the following:


import sims4.commands

@sims4.commands.Command('mycommand', command_type=sims4.commands.CommandType.Live)
def my_command(_connection=None):
output = sims4.commands.CheatOutput(_connection)
output('Success.')


The code I found to get the currently played sim is:


import services

sim = services.active_sim_info()


If you want to include the values of variables or output of functions in your output, you need to use format().

Example 1: Output the first and last name of the current sim:


import sims4.commands
import services

output = sims4.commands.CheatOutput(_connection)
sim = services.active_sim_info()
if not sim is None:
output('The currently played sim is: {} {}'.format(sim.first_name, sim.last_name))


Then I dug around until I found the following code that will fill all needs (motives) for a sim.


sim.commodity_tracker.set_all_commodities_to_best_value(visible_only=True)


I think the reason only visible motives are affected, is that for some types of occult sims e.g. vampires, not all the motive bars show - I think vampires never need sleep so this bar does not show.

So this was simple enough, but the tricky bit was coming because I needed to get one specific value and set it low enough that my sim would be sleepy.


from server_commands.argument_helpers import get_tunable_instance

cur_stat = get_tunable_instance(sims4.resources.Types.STATISTIC, 'motive_energy', exact_match=True)
sim.commodity_tracker.set_value(cur_stat, -51)


A few notes on the code snippet above:

A motive value between -1 and -50 turns the bar yellow
A motive value below -50 turns the bar red
You need to get the instance of the motive you want to change, then use the commodity_tracker object on your sim_info object to set the value.
Setting your sim's hunger motive to -100 will lead to them dying instantly of hunger.
I added extra code to see what the energy motive value was before I maxed out all the motives. You probably don't need this code, but you may want to keep it for experimental reasons, so I didn't remove it.


One final tweak I made was to check that the sim was a human, and not an NPC (e.g. a butler) so that I did not affect pets and staff. if you want to affect them too just remove the if condition.

My final code adds 2 different commands - sleepy will make only the active sim sleepy, while sleepyhh will make the whole household sleepy, except NPCs and pets.

Final code:


import services
import sims4.commands
from server_commands.argument_helpers import get_tunable_instance


@sims4.commands.Command('sleepyhh', command_type=sims4.commands.CommandType.Live)
def make_household_sleepy(_connection=None):
output = sims4.commands.CheatOutput(_connection)
active_household = services.active_household()
if active_household is None:
output('No household active to make sleepy.')
return False
for sim in active_household:
if sim.is_human and not sim.is_npc:
cur_stat = get_tunable_instance(sims4.resources.Types.STATISTIC, 'motive_energy', exact_match=True)
tracker = sim.get_tracker(cur_stat)
cur_value = tracker.get_value(cur_stat) if tracker is not None else -999
sim.commodity_tracker.set_all_commodities_to_best_value(visible_only=True)
if cur_value != -999:
output('{} {}\'s energy is {:.0f}'.format(sim.first_name, sim.last_name, cur_value))
sim.commodity_tracker.set_value(cur_stat, -51)
else:
output('Unable to get current energy value for {} {}'.format(sim.first_name, sim.last_name))


@sims4.commands.Command('sleepy', command_type=sims4.commands.CommandType.Live)
def make_sim_sleepy(_connection=None):
output = sims4.commands.CheatOutput(_connection)
sim = services.active_sim_info()
if sim is None:
output('No active sim to make sleepy.')
return False
cur_stat = get_tunable_instance(sims4.resources.Types.STATISTIC, 'motive_energy', exact_match=True)
tracker = sim.get_tracker(cur_stat)
cur_value = tracker.get_value(cur_stat) if tracker is not None else -999
sim.commodity_tracker.set_all_commodities_to_best_value(visible_only=True)
if cur_value != -999:
output('{} {}\'s energy is {:.0f}'.format(sim.first_name, sim.last_name, cur_value))
sim.commodity_tracker.set_value(cur_stat, -51)
else:
output('Unable to get current energy value for {} {}'.format(sim.first_name, sim.last_name))