Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jsonify Limb Scores & Character Modifiers #53069

Merged
merged 15 commits into from
Dec 4, 2021

Conversation

dseguin
Copy link
Member

@dseguin dseguin commented Nov 27, 2021

Summary

None

Purpose of change

Fixes #52846
Also inspired by Venera's awesome work on #53004.

I wanted to have the limb encumbrance descriptions be automatically associated to the appropriate body parts, but there are a couple of roadblocks that I want to address first:

  • Encumbrance descriptions are tied to specific body parts, so moving around the limb scores causes a discrepancy between what is displayed and what the actual values are.
  • Limb scores are added ad-hoc to the body part struct, so it's not scalable to iterate over them (or to add new ones).
  • Most limb scores are calculated the same way, so there's a lot of duplication.

Describe the solution

The goal is to create a generic method for defining limb scores, which can be used to generate the encumbrance descriptions for associated body parts, completely defined in JSON.

I created a new JSON type "limb_score" with this format:

{
  "type": "limb_score",
  "id": "lift",
  "name": "Lifting",
  "affected_by_wounds": true,
  "affected_by_encumb": false
}

"name" is a translatable string that identifies the score in the UI. "affected_by_*" indicates that this limb score is passed through bodypart::wound_adjusted_limb_value() and/or bodypart::encumb_adjusted_limb_value().


These limb score types are referenced in "body_part" using the "limb_scores" array:

{
  "id": "arm_l",
  "type": "body_part",
  "name": "left arm",
  ...
  "limb_scores": [
    [ "manip", 0.1, 0.2 ],
    [ "lift", 0.5 ],
    [ "block", 1.0 ],
    [ "swim", 0.1 ]
  ]
}

The array has 2 mandatory fields and one optional field:

  1. The id of the limb score
  2. The limb score value
  3. The max value (mostly just for manipulation score)

Since character modifiers are generally tied to limb scores, I decided to jsonify them too:

{
  "type": "character_mod",
  "id": "melee_stamina_cost_mod",
  "description": "Melee stamina cost",
  "mod_type": "x",
  "value": { "limb_score": "lift", "limb_type": "arm", "max": "max_move_cost", "nominator": 1.0 }
},
{
  "type": "character_mod",
  "id": "stamina_move_cost_mod",
  "description": "Stamina move cost modifier",
  "mod_type": "x",
  "value": { "builtin": "stamina_move_cost_modifier" }
}

"value" is the magic JSON object that defines how the character modifier is calculated. The fields in "value" are as follows:

  • limb_score: Mandatory. Defines the limb score that derives this modifier.
  • limb_type: Optional. If present, only sum up the limb scores from this limb type.
  • override_encumb: Optional. If present, overrides the limb score's affected_by_encumb to force the score to be affected/unaffected by limb encumbrance.
  • override_wounds: Optional. If present, overrides the limb score's affected_by_wounds to force the score to be affected/unaffected by limb health.
  • max: Optional. Can be any float or the special value "max_move_cost". Defines the upper limit of a cost modifier.
  • min: Optional. Can be any float. Defines the lower bound of the limb score. (ex: melee attack roll modifier has a minimum of 0.2)
  • nominator: Optional. If present, divide the value by the limb score (essentially nominator / limb_score).
  • subtract: Optional. If present, subtract the resulting modifier by this value (essentially (nominator / limb_score) - subtract).

Alternatively, the "value" can be specified as a "builtin" which refers to a hardcoded function in character_modifier.cpp.


Limb scores can be iterated using limb_score::get_all(), which I'm using to generate the encumbrance descriptions:

2021-11-28.00-32-37.mp4

Describe alternatives you've considered

It would be easy to move the encumbrance descriptions around to reflect the current effects, but that doesn't solve the underlying problem. It also wouldn't scale once new body parts start being added.

Testing

Ensure that these are working properly:

  • copy-from, extend and delete on all affected types
  • Validation catches invalid entries
  • Scrolling in the information box doesn't omit any rows
  • Limb scores and modifiers are unchanged between before and after this fix
  • Unit tests

Additional context

TODO:

  • Move limb scores to JSON type
  • Create generic methods for calculating limb scores
  • Create generic methods for generating limb encumbrance text
  • Scroll information box to accommodate longer descriptions
  • Jsonify modifiers as well
  • Documentation
  • Testing

@Maleclypse Maleclypse added [C++] Changes (can be) made in C++. Previously named `Code` [JSON] Changes (can be) made in JSON Items / Item Actions / Item Qualities Items and how they work and interact Mechanics: Character / Player Character / Player mechanics labels Nov 28, 2021
@github-actions github-actions bot added astyled astyled PR, label is assigned by github actions json-styled JSON lint passed, label assigned by github actions labels Nov 28, 2021
@Venera3
Copy link
Member

Venera3 commented Nov 28, 2021

Oh, that's fancy! It should streamline me klutzing together new scores at the drop of a hat nicely. Two things:

Do you think there's a way to overwrite the affected_by under the hood for certain calculations? E.g. while lifting_score shouldn't be scaled by armor when calculating it for damage or y'know lifting, armor impacting its effect on swing stamina cost makes sense (the first two aren't hooked up yet, but they'll probably be when I do arms).

How well do they play with copy-from on bodyparts? It's not a giant problem, but it's always nice when lists support extend and delete.

@dseguin
Copy link
Member Author

dseguin commented Nov 28, 2021

Do you think there's a way to overwrite the affected_by under the hood for certain calculations? E.g. while lifting_score shouldn't be scaled by armor when calculating it for damage or y'know lifting, armor impacting its effect on swing stamina cost makes sense (the first two aren't hooked up yet, but they'll probably be when I do arms).

Sure, it shouldn't be hard to add a new field to give it a little more control. I'll try to keep it open so that I (or anyone else) can easily expand it later on.

How well do they play with copy-from on bodyparts? It's not a giant problem, but it's always nice when lists support extend and delete.

I don't think I've ever had a problem with copy-from, but I'll definitely add it to my tests.

Venera3 added a commit to Venera3/Cataclysm-DDA that referenced this pull request Nov 28, 2021
Hands are pretty crowded, but CleverRaven#53069 will take care if it anyway
@dseguin dseguin changed the title Jsonify Limb Scores Jsonify Limb Scores & Character Modifiers Nov 29, 2021
@dseguin dseguin force-pushed the jsonify_limb_scores branch 2 times, most recently from b1479d3 to 0551dbe Compare December 1, 2021 04:02
@dseguin dseguin marked this pull request as ready for review December 1, 2021 04:06
@Venera3
Copy link
Member

Venera3 commented Dec 1, 2021

One other thing that could either be moved to a limb score (or limb field in general) would be the function of avatar::limb_dodge_encumbrance - something like enc_dodge_modifier defined in the BP definition. Alternatively, just showing it in the list of limb modifiers would be nice already, though it takes hardcoded limb IDs so it won't play nice with custom limbs down the line.

@dseguin
Copy link
Member Author

dseguin commented Dec 1, 2021

@Venera3 Cheers! After one hell of a rebase, your changes should be properly jsonified. I've added new fields to character_mod to override how the limb score is affected by encumbrance and/or wounds (currently using it for "melee_stamina_cost_mod").

One other thing that could either be moved to a limb score (or limb field in general) would be the function of avatar::limb_dodge_encumbrance - something like enc_dodge_modifier defined in the BP definition. Alternatively, just showing it in the list of limb modifiers would be nice already, though it takes hardcoded limb IDs so it won't play nice with custom limbs down the line.

I refactored avatar::limb_dodge_encumbrance to take an arbitrary number of body part types. I created a new field for body_part called "encumb_impacts_dodge" that will include it in the calculation. I also included the modifier in the player's display for any limb where "encumb_impacts_dodge" is true.

I've updated the documentation, so you can check JSON_INFO.md in this PR to see a summary of all the changes.

@github-actions github-actions bot added BasicBuildPassed This PR builds correctly, label assigned by github actions and removed BasicBuildPassed This PR builds correctly, label assigned by github actions labels Dec 2, 2021
@github-actions github-actions bot added the BasicBuildPassed This PR builds correctly, label assigned by github actions label Dec 3, 2021
@kevingranade kevingranade merged commit 427c1c6 into CleverRaven:master Dec 4, 2021
@dseguin dseguin deleted the jsonify_limb_scores branch December 4, 2021 06:25
@alp7292
Copy link
Contributor

alp7292 commented Dec 6, 2021

maybe insignificant but hand encumbrance also affects when you try to put pressure on your bleeding wound and torso encumbrance can throw you off balance when melee attacking even if you didnt past the threshold maybe it can be jsonified

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
astyled astyled PR, label is assigned by github actions BasicBuildPassed This PR builds correctly, label assigned by github actions [C++] Changes (can be) made in C++. Previously named `Code` Items / Item Actions / Item Qualities Items and how they work and interact [JSON] Changes (can be) made in JSON json-styled JSON lint passed, label assigned by github actions Mechanics: Character / Player Character / Player mechanics
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Arm encumbrance effects are not shown in character menu
5 participants