CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.66k stars 4.18k forks source link

JSONify trait-based fun modifiers #45757

Closed hjk321 closed 3 years ago

hjk321 commented 3 years ago

Is your feature request related to a problem? Please describe.

Let's paint a picture.

You're a past-threshold mutant that has been roaming the land for months, your previous life a distant memory. You've long since discarded your humanity in favor of becoming one of the most feared hunters in the area. You come across prey and made your kill, ready to dig in and eat but... what the--?! Negative 20 morale?! But you have the carnivore, apex predator, and sapiovore traits, why in the heck would eating raw meat make you sad? And now you're "not in the mood" to butcher your next victim!

So... using this item makes sense to decrease your morale in most situations, but sometimes not. How do we fix this? The solution, of course, is to conditionally alter the fun value based on traits.

Describe the solution you'd like

What I propose, is to add JSON support for trait-based fun modifiers. In addition to the default fun value, it adds or subtracts bonuses to the default based on having certain traits. This all stacks with non-trait modifiers such as the monotony penalty.

In addition to solving the problem above, I'm sure there could be plenty of other interactions benefiting from this addition, not to mention the potential modding opportunities. I think some interactions like this already sort of exist in the game (cannibalism comes to mind, for example), but right now they are hardcoded in C++. Making this behavior accessible in JSON would standardize it into the data files as well as open the system up to easy modification. Easy modification means more of these interactions, and generally more interesting traits.

Essentially, this takes a feature that is kinda sorta implemented and makes it a lot more accessible. See below for a JSON mockup that shows just how simple it actually is. Existing interactions can be converted super-easily, and new ones can be added as well.

Describe alternatives you've considered

One solution I thought of would be to put these relationships between entries in the trait's entry instead of the item's entry. Or perhaps, the relationships are defined in their own file! I am pretty sure this version is the most straightforward, however. I also considered making these trait modifiers set the fun value instead of add to them, but this way lets traits stack.

Additional context

Potential data structure mockup:

{
  "type": "BOOK",
  "id": "cookbook_human",
  "fun": -5,
  "fun_traits": [ [ "CANNIBAL", 30 ], [ "SQUEAMISH", -10 ] ],
  "//1": "This makes the cookbook cause -5 fun normally, +25 with the cannibal trait, and -15 with the squeamish trait.",
  "//2": "If you have both traits, it stacks to +15 fun. You could experiment here with psychopath and spiritual traits too."
}

I know squeamish is related to clothes, but this is just an example. (And besides, this kind of PR might allow the squeamish trait to broaden its horizons anyway...)

Xaleth commented 3 years ago

I'm all in on this idea.

hjk321 commented 3 years ago

I can go ahead and implement this myself but I need input/advice on exactly what the scope of this should be. For example, how would you handle modifiers that spread across many items of the same category, or don't follow the standard formulas? (For example, HATES_BOOKS trait).

My current plan is to add support for individual items in JSON but keep things that can't be done with a simple addition/subtraction in C++. Should I add support for say, "If it's above zero set to zero, else subtract 2" to the JSON, or would that make it too complicated? I think I should stick with the simple stuff and port what I can to JSON. Things like the chapters formula for books will DEFINITELY stay in C++ (because that's not trait based and therefore out of scope).

Xaleth commented 3 years ago

https://discord.com/channels/598523535169945603/598529174302490644/783419625827336202

for slightly more context

hjk321 commented 3 years ago

Unfortunately, after more research, I realize that even under the best circumstances this could only be halfway implemented, causing a weird mishmash of C++-based modifiers and JSON-based modifiers. Therefore, I think it's best not to JSONify this.