- Site Map >
- Modding and Creation >
- Sims 4 Creation >
- Modding Discussion >
- Creating New Reward Traits without overriding?
- Site Map >
- Modding and Creation >
- Sims 4 Creation >
- Modding Discussion >
- Creating New Reward Traits without overriding?
Replies: 12 (Who?), Viewed: 4506 times.
#1
16th Nov 2017 at 3:50 AM
Posts: 91
Thanks: 2580 in 6 Posts
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
#2
16th Nov 2017 at 10:50 AM
Posts: 2,671
Thanks: 62741 in 190 Posts
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:
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())
#3
9th Dec 2017 at 7:06 AM
Last edited by konansock : 9th Dec 2017 at 8:29 AM.
Posts: 91
Thanks: 2580 in 6 Posts
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!
#4
9th Dec 2017 at 9:33 AM
Posts: 91
Thanks: 2580 in 6 Posts
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.
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.
#5
10th Dec 2017 at 2:57 AM
Posts: 2,671
Thanks: 62741 in 190 Posts
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.
#6
6th May 2019 at 9:14 AM
Posts: 91
Thanks: 2580 in 6 Posts
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?
#7
6th May 2019 at 9:22 AM
Posts: 91
Thanks: 2580 in 6 Posts
Oh well, I just found that I included the variants when defining the function...I'll try again.
#8
6th May 2019 at 9:39 AM
Posts: 91
Thanks: 2580 in 6 Posts
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...
#9
7th May 2019 at 7:09 PM
Posts: 2,671
Thanks: 62741 in 190 Posts
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.
#10
9th May 2019 at 5:20 PM
Posts: 91
Thanks: 2580 in 6 Posts
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...
#11
9th May 2019 at 10:00 PM
Posts: 2,671
Thanks: 62741 in 190 Posts
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.
#12
12th May 2019 at 1:59 PM
Posts: 91
Thanks: 2580 in 6 Posts
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!
#13
15th Nov 2019 at 5:29 PM
Posts: 39
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.
Who Posted
|