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!
Lab Assistant
Original Poster
#1 Old 16th Nov 2017 at 3:50 AM
Default Creating New Reward Traits without overriding?
I'm currently working on something and would love to add some achievements/reward traits to the reward store, but I need to override the file 'whims_whimsTracker' file and although I can make sure I update it constantly, it will likely conflict with other mods.

I tried some Python myself but didn't get it to work.
Code:
import services from sims4.collections
import make_immutable_slots_class, FrozenAttributeDict
from sims4.resources import Types, get_resource_key
from whims.whims_tracker import WhimsTracker
def add_reward_trait_sharer(self): reward_manager = services.get_instance_manager(Types.REWARD)
reward_tuning = reward_manager.get(7199758815256132942)
if reward_tuning is None:
return
immutable_slots_class = sims4.collections.make_immutable_slots_class(['award_type', 'cost'])
Rex_ActiveCareer_Aspiration_Reward_Trait = immutable_slots_class(dict(award_type = WhimAwardTypes.TRAIT, cost = 500))
trait_dict = dict(WhimsTracker.SATISFACTION_STORE_ITEMS)
trait_dict[reward_tuning] = Rex_ActiveCareer_Aspiration_Reward_Trait WhimsTracker.SATISFACTION_STORE_ITEMS = trait_dict

I also tried to inject tags to the game but that's a whole other story and now I'm really curious if tags can be injected, but I knew reward trait can be added since I noticed WW managed to do that. :/

Thanks in advance!
Advertisement
Deceased
#2 Old 16th Nov 2017 at 10:50 AM
I've never worked with these myself so I'm not sure that your approach is even valid for what you're wanting to accomplish, but I'd suggest starting by logging any exceptions generated to a log file as you have at least one class you are referencing that appears not to have been imported -- WhimAwardTypes.

When I hit a brick wall I almost always use a try/except block around what I'm working on and use traceback and a custom log function to log any exceptions, and quite often something ends up in my log file to at least point me in the right direction. Use something like this:
Code:
import traceback
import os.path

def writelog(str, logname=None):
    if logname is None:
        logname = "__log.log"
    filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), logname)
    with open(filename, "a") as fp:
        fp.write('{}\n'.format(str))

def your_function():
    try:
        YOUR PROBLEM CODE HERE
    except:
        writelog(traceback.format_exc())
Lab Assistant
Original Poster
#3 Old 9th Dec 2017 at 7:06 AM Last edited by konansock : 9th Dec 2017 at 8:29 AM.
Quote: Originally posted by scumbumbo
I've never worked with these myself so I'm not sure that your approach is even valid for what you're wanting to accomplish, but I'd suggest starting by logging any exceptions generated to a log file as you have at least one class you are referencing that appears not to have been imported -- WhimAwardTypes.

When I hit a brick wall I almost always use a try/except block around what I'm working on and use traceback and a custom log function to log any exceptions, and quite often something ends up in my log file to at least point me in the right direction. Use something like this:
Code:
import traceback
import os.path

def writelog(str, logname=None):
    if logname is None:
        logname = "__log.log"
    filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), logname)
    with open(filename, "a") as fp:
        fp.write('{}\n'.format(str))

def your_function():
    try:
        YOUR PROBLEM CODE HERE
    except:
        writelog(traceback.format_exc())


Wow! I never expected Sumbumbo to reply to my silly question!

Actually I tried to make this code according to your injecting whims to whimsets code, because the two are highly similar

I haven't tried again these days, but I'll try when I got time! Thanks for your suggestion!

Edit: Actually I looked into your Inventory Type override as well, since this is a module file instead of other file like the whimsets, so I need to look into how to inject a script into the module files. I think some code must be incorrect so... As for the WhimAwardType, that function was defined inside the class WhimsTracker so I wasn't sure if I should import it, I'll definitely try!
Lab Assistant
Original Poster
#4 Old 9th Dec 2017 at 9:33 AM
OK, I edited the code some more and it now looks like this:

import services
import rex_teencriminal_injector
import sims4.collections
import sims4.resources
import services
from sims4.resources import Types
from sims4.tuning.instance_manager import InstanceManager
from whims.whims_tracker import WhimsTracker

manager = services.get_instance_manager(Types.REWARD)
reward_tuning = manager.get(7199758815256132942)
immutable_slots_class = sims4.collections.make_immutable_slots_class(set(['award_type', 'cost']))
reward_value = immutable_slots_class({'award_type':WhimsTracker.WhimAwardTypes.TRAIT , 'cost':500})

WhimsTracker.SATISFACTION_STORE_ITEMS = WhimsTracker.SATISFACTION_STORE_ITEMS + {reward_tuning:reward_value}

This way the game finally recognized the WhimsAwardType class and stop giving me script errors...
However, when I load up the reward store, it now shows nothing but blank...I think I should still try it some time later.
Deceased
#5 Old 10th Dec 2017 at 2:57 AM
Seems like to add to a FrozenAttributeDict I had to "thaw" it first by converting it to something else (plain dict, most likely), adding the new values, and then converting that back again. Best guess without trying is that the "+" operation is failing and so the result applied to the WhimsTracker.SATISFACTION_STORE_ITEMS at the end is None, or possibly a regular dict which the game doesn't recognize properly as it's not the FrozenAttributeDict it's expecting.
Lab Assistant
Original Poster
#6 Old 6th May 2019 at 9:14 AM
Quote: Originally posted by scumbumbo
Seems like to add to a FrozenAttributeDict I had to "thaw" it first by converting it to something else (plain dict, most likely), adding the new values, and then converting that back again. Best guess without trying is that the "+" operation is failing and so the result applied to the WhimsTracker.SATISFACTION_STORE_ITEMS at the end is None, or possibly a regular dict which the game doesn't recognize properly as it's not the FrozenAttributeDict it's expecting.


Code:
import services
import sims4.collections
from sims4.tuning.instance_manager import InstanceManager
from whims.whims_tracker import WhimsTracker
from sims4.collections import FrozenAttributeDict
from sims4.resources import get_resource_key, Types

REWRAD_BLACK_TECH_GURU=7199758815256132942

def register_satisfaction_BTG_reward(REWRAD_BLACK_TECH_GURU, 1500, WhimAwardTypes.TRAIT):
instance_manager = services.get_instance_manager(sims4.resources.Types.REWARD)
key = sims4.resources.get_resource_key(REWRAD_BLACK_TECH_GURU, sims4.resources.Types.REWARD)
reward_tuning_instance = instance_manager.get(key)
if reward_tuning_instance is None:
return
immutable_slots_class = sims4.collections.make_immutable_slots_class(['cost', 'award_type'])
immutable_slots = immutable_slots_class(dict(cost=cost, award_type=award_type))
items_dict = dict(WhimsTracker.SATISFACTION_STORE_ITEMS)
items_dict[reward_tuning_instance] = immutable_slots
WhimsTracker.SATISFACTION_STORE_ITEMS = FrozenAttributeDict(items_dict)



OK, I finally get back to this...And this time every other reward show up but mine. At least I know this time, the game is properly reading my code. But the dict[new_instance] seems to be failing.
I guess there's something more I need to do?
Lab Assistant
Original Poster
#7 Old 6th May 2019 at 9:22 AM
Oh well, I just found that I included the variants when defining the function...I'll try again.
Lab Assistant
Original Poster
#8 Old 6th May 2019 at 9:39 AM
Code:

import services
import injector
import sims4.collections
from sims4.tuning.instance_manager import InstanceManager
from whims.whims_tracker import WhimsTracker
from sims4.collections import FrozenAttributeDict
from sims4.resources import get_resource_key, Types

REWRAD_BLACK_TECH_GURU=7199758815256132942

def register_satisfaction_BTG_reward(reward_instance, cost, award_type):
    instance_manager = services.get_instance_manager(sims4.resources.Types.REWARD)
    key = sims4.resources.get_resource_key(reward_instance, sims4.resources.Types.REWARD)
    reward_tuning_instance = instance_manager.get(key)
    if reward_tuning_instance is None:
        return
    immutable_slots_class = sims4.collections.make_immutable_slots_class(['cost', 'award_type'])
    immutable_slots = immutable_slots_class(dict(cost=cost, award_type=award_type))
    items_dict = dict(WhimsTracker.SATISFACTION_STORE_ITEMS)
    items_dict[reward_tuning_instance] = immutable_slots
    WhimsTracker.SATISFACTION_STORE_ITEMS = FrozenAttributeDict(items_dict)

register_satisfaction_BTG_reward(REWRAD_BLACK_TECH_GURU, 1500, WhimAwardTypes.TRAIT)


This time the format should be right. Something must be wrong here though, I'll try to use the injector funtion and try...
Deceased
#9 Old 7th May 2019 at 7:09 PM
The only thing that jumps out at me (and not looking further as it's a "show-stopper") is that you're not importing the WhimAwardTypes class, so you can't refer to that in the last line - thus the whole shebang never kicks off this would just throw an exception.
Lab Assistant
Original Poster
#10 Old 9th May 2019 at 5:20 PM
Quote: Originally posted by scumbumbo
The only thing that jumps out at me (and not looking further as it's a "show-stopper") is that you're not importing the WhimAwardTypes class, so you can't refer to that in the last line - thus the whole shebang never kicks off this would just throw an exception.


Thanks, Scumbumbo! I had thought it would work if I import WhimsTracker since WhimsAwardType is a class inside WhimsTracker...
I also tried importing the class, which also didn't work.
But I copied the class WhimsAwardType in my Python files and this time it works perfectly...

Like this :
Code:
import services
import sims4.collections
from injector import inject_to
from sims4.tuning.instance_manager import InstanceManager
from whims.whims_tracker import WhimsTracker
from sims4.collections import FrozenAttributeDict
from sims4.resources import get_resource_key, Types

REWRAD_BLACK_TECH_GURU=7199758815256132942

class WhimAwardTypes:

    def _reference_type(*args):
        try:
            return WhimsTracker.WhimAwardTypes(args[0])
        except:
            return

    MONEY = _reference_type(0)
    BUFF = _reference_type(1)
    OBJECT = _reference_type(2)
    TRAIT = _reference_type(3)
    CASPART = _reference_type(4)


def register_satisfaction_BTG_reward(reward_instance, cost, award_type):
    instance_manager = services.get_instance_manager(sims4.resources.Types.REWARD)
    key = sims4.resources.get_resource_key(reward_instance, sims4.resources.Types.REWARD)
    reward_tuning_instance = instance_manager.get(key)
    if reward_tuning_instance is None:
        return
    immutable_slots_class = sims4.collections.make_immutable_slots_class(['cost', 'award_type'])
    immutable_slots = immutable_slots_class(dict(cost=cost, award_type=award_type))
    items_dict = dict(WhimsTracker.SATISFACTION_STORE_ITEMS)
    items_dict[reward_tuning_instance] = immutable_slots
    WhimsTracker.SATISFACTION_STORE_ITEMS = FrozenAttributeDict(items_dict)

@inject_to(InstanceManager, 'load_data_into_class_instances')
def _add_new_reward_trait_tuning(original, self):
    original(self)
    if self.TYPE == Types.REWARD:
        register_satisfaction_BTG_reward(REWRAD_BLACK_TECH_GURU, 1500, WhimAwardTypes.TRAIT)


It seems we have to 'copy' the class we need if the class is a sub-class inside a class...
Deceased
#11 Old 9th May 2019 at 10:00 PM
Quote: Originally posted by konansock
Thanks, Scumbumbo! I had thought it would work if I import WhimsTracker since WhimsAwardType is a class inside WhimsTracker...
It seems we have to 'copy' the class we need if the class is a sub-class inside a class...

I didn't look to see that WhimAwardTypes was an inner class, you should be able to just refer to it as WhimsTracker.WhimAwardTypes.TYPENAME since you have the WhimsTracker imported. Much more friendly to possible future patches to use EA's copy of that enum.
Lab Assistant
Original Poster
#12 Old 12th May 2019 at 1:59 PM
Quote: Originally posted by scumbumbo
I didn't look to see that WhimAwardTypes was an inner class, you should be able to just refer to it as WhimsTracker.WhimAwardTypes.TYPENAME since you have the WhimsTracker imported. Much more friendly to possible future patches to use EA's copy of that enum.

Ooh! Thanks! Just got that to work!
Test Subject
#13 Old 15th Nov 2019 at 5:29 PM
Default Do you want to share the final version of this?
Hi, I am trying to create a reward-trait as well and I am qurious to see what your final version of the script was to see if I can use something of that if it works, instead of adding xml to the whims tracker. Would be very happy and thankful if you want to do that.
Back to top