CleverRaven / Cataclysm-DDA

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

Proposed armor changes to accomodate custom bodyparts #54939

Open Venera3 opened 2 years ago

Venera3 commented 2 years ago

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

A pretty big stumbling block holding back the limb rework is the way armor coverage is defined - every piece of armor defines every covered bodypart explicitly, and errors out when it can't find the part(s) in question. I'm fairly certain utilizing the new shiny sublimb coverage stuff offers a relatively organic solution to this problem, but hooking it (or any alternative solution) up is beyond my abilities.

Solution you would like.

This combination would mean that adding a new limb would only need to append it to the relevant sublimb_set(s), while adding a new armor would just need to choose a suitable sublimb "scheme".

Describe alternatives you have considered.

Defining optional bodyparts in armor definition, either using the same coverage data:

      { "covers": [ [ "leg_l", "leg_r" ], [ "leg_spider_1_l", "leg_spider_1_r" ] ], "coverage": 97, "encumbrance": [ 10, 12 ] },

meaning "this piece of armor covers either both normal legs or a set of spider legs with 97 coverage", or with their own coverage array:

      { "covers": [ "leg_tentacle_1_l", "leg_tentacle_2_l", "leg_tentacle_1_r", "leg_tentacle_2_r  ], "coverage": 80, "cover_melee": 95, "encumbrance": [ 6, 7 ] }
    ],

meaning "if this covers a double set of leg tentacles it does so with 80 coverage etc". This would be very JSON-heavy, since it would need updating every piece of armor for every conceivable mutant limb, and turns adding new armor or new custom limbs into a considerable chore. However it would let different limbs be covered by the same armor differently.

Filtering based on size + bodypart type, but those are a bit too narrow as categories.

Additional context

I have no idea of the feasibility of this, of course, but I think this would be robust enough to deal with most shenanigans I can think up. @KorGgenT @bombasticSlacks

bombasticSlacks commented 2 years ago

Thanks for writing this up. To add some thoughts to this:

As far as additional scope not mentioned this will require completely overhauling the side code or at least extending it for multilimb. Currently it's hard coded to be left, right or both. It would need to be more generalized, also ideally with a menu added for change side/limb so you don't have to cycle.

All the stuff your describing with varying coverage can already be handled with the "Max Coverage" defined in the sublimbs. so if arm guards cover 100% of the forearm and forearms are 25% of your arm the game already calcs that the armor covers 25% of your arm.

Encumbrance isn't dynamic about this yet but I'm hoping to make encumbrance dynamic in general instead of hard coded though that will be next release I imagine.

A suggestion instead of the sublimb sets to cut down on JSON churn what do you think of having a sublimb entry like "similar" so that for example tentacle_r_lower could be:

  {
    "id": "tentacle_1_r_lower",
    "type": "sub_body_part",
    "max_coverage": 50,
    "parent": "tentacle_1_right",
    "side": 2,
    "name": "Lower Right Tentacle",
    "opposite": "tentacle_1_l_lower",
    "name_multiple": "Lower Tentacles",
    "similar": [ "arm_r_lower", "arm_r_elbow" ]
  },
  {
    "id": "tentacle_1_r_upper",
    "type": "sub_body_part",
    "max_coverage": 50,
    "parent": "tentacle_1_right",
    "side": 2,
    "name": "Upper Right Tentacle",
    "opposite": "tentacle_1_l_lower",
    "name_multiple": "Upper Tentacles",
    "similar": [ "arm_r_upper", "arm_r_shoulder" ]
  },

and so with that if you had a piece of armor that covered the elbows + lower arms, you could wear it with tentacles. The max coverage of lower arm (35) + elbow (5) is 40. So you could do max_coverage intended limbs / max_coverage avatar limbs to get a modifier on how much of you current limb is covered. So in this case it would be 40/50 or 80%. So you get 80% of the intended coverage of the original piece. This could also go the other way with things that over cover your limbs either giving negatives or being impossible to put on depending on if they are flexible, or hard armor.

For example I imagine tentacle socks would awkwardly dangle off the end of human arms and be awkward to work with, however crazy segmented semi rigid tentacle armor dangling off the hands in a similar way would completely eliminate the use of the hands.

So specific tentacle armor could define the tentacles in its armor definition, whereas normal armor would define human limbs and there would be a function to resolve wear_as_best_you_can where it figures out how it would work with your limbs instead. It could even do two steps of this where it goes from

mutant style limb a -> human limb -> mutant style limb b 

Since each of the mutant limbs will explicitly describe how they interact compared to human limbs.

Also for now the proportional coverage could also scale encumbrance. It's not perfect but it would be a start.

I'm looking to add a JSON flag to items called something like Rigid which would restrict layering multiple hard armor sets (since that doesn't make sense) but I think would apply just as well to this stuff for determining how "inflexible" the definitions are.

Also maybe restricted could be expanded to "restricted soft" and "restricted hard" since tentacles for example might have trouble wearing something intended as a rigid elbow or shoulder piece (restricted hard) but wouldn't have trouble with a long sleeve. Or a cute little bunny tail might be able to fit in cotton pants but not plate mail.

Since I've ended up typing a lot just wanted to say I do want your feedback on this. I'm just trying to bring my expertise. At the end of the day this is your overhaul not mine so I'm happy to offer some suggestions and perhaps at some point get saddled with coding all of this but it should be handled in the way that best works for you.

PatrikLundell commented 2 years ago

It can be noted that creatures with multiple torsos already exist in the game, but they're zombies...

KorGgenT commented 2 years ago

It can be noted that creatures with multiple torsos already exist in the game, but they're zombies...

that's irrelevant because monsters are far different in code than characters

PatrikLundell commented 2 years ago

Yes, that's why I pointed out that they're zombies (and I could have been clearer about the implications of that). However, that means you don't have to invent something new in the game to get things with multiple torsos, you'd "just" have to treat zombies as characters, so the forward looking part might not have to look that far conceptually (implementation is a completely different matter).

KorGgenT commented 2 years ago

so i don't want this to turn into a long drawn-out discussion about zombies having bodyparts, because it's a nonstarter for a variety of reasons. i'll try to answer as many of them as i can think of in one post so we can move on to the actual implementation of bodyparts in Character which is what this issue is about.

  1. What is the benefit of having bodyparts on zombies? We don't need to have a detailed display in the UI for their various injuries, nor do we need a detailed display of their bonuses and negatives since the player does not know that information. The alternative here, which I still think is the option we should be going with, is clever usages of effects like bleeding for those effects that the player knows.

  2. What are the implications of zombies being a Character? First of all, we'd have to throw out all of the json definitions for all the zombies. Additionally, we would have to either implement such bonuses as damage types and damage rolls into bare-handed melee for Characters, or give them special items that use the enchantment code that also don't drop when they die. Second of all, they would be using the npc AI which is far heavier than the monster ai. you know the lag when you sleep at the refugee center? or maybe you could try spawning 100 npcs nearby and see how quickly time passes. We still do have issues with performance with monsters (sleeping in labs) but it's much less pronounced. We also have lots of special code for monsters that we'd have to throw out and reimplement for Character, which is a whole lot of churn and a whole lot of opportunity to introduce a bunch of bugs.

  3. What are the implications of zombies having bodyparts? Well, with our current system, each bodypart of an npc has hp, and people already know how hard it is to kill them. Now every zombie gets the same thing? Additionally with the new wound system that'll be implemented for Characters and not monsters, there'd have to be special considerations for exactly what circumstances zombies would die, since some might not incur blood loss the same way a Character might.

In conclusion, giving zombies (and other monsters) bodyparts is a lot more trouble than it's actually worth. We've got plenty of infrastructure to simulate it from the player's perspective with a little bit of clever usage, and the player would never know.

Venera3 commented 2 years ago

As far as additional scope not mentioned this will require completely overhauling the side code or at least extending it for multilimb.

For a first pass I'm going with nice and symmetric abominations to sidestep that can of worms. It will still be a messy enough when it gets to "Upper first arm tentacle (left)".

A suggestion instead of the sublimb sets to cut down on JSON churn what do you think of having a sublimb entry like "similar" so that for example tentacle_r_lower could be:

Yeah, that does the job and doesn't involve 1k lines of JSON - I'm a fan already. The max coverage solution would be very clever.

For example I imagine tentacle socks would awkwardly dangle off the end of human arms and be awkward to work with, however crazy segmented semi rigid tentacle armor dangling off the hands in a similar way would completely eliminate the use of the hands.

I could see that as something like a strict_fit bool in the armor coverage disallowing substitutions (or maybe a few levels of it mapping to partial substitutions, though I'm struggling to come up with a use case for that) - in this case the custom tentacle armor only fitting on tentacles.

Since I've ended up typing a lot just wanted to say I do want your feedback on this. I'm just trying to bring my expertise. At the end of the day this is your overhaul not mine so I'm happy to offer some suggestions and perhaps at some point get saddled with coding all of this but it should be handled in the way that best works for you.

You've been very active in this part of the code, so I'm very thankful for the help and the expert opinion. I have a rough idea of what the system would have to deal with, but the exact way it does so is pretty much a non-issue for me. Also, like all chunky projects it's Our Overhaul - I'm not going to take too much credit for my rampage through the codebase stapling limb scores to whatever catches my eye, and the heavy lifting was always done by somebody actually competent.

bombasticSlacks commented 2 years ago

For a first pass I'm going with nice and symmetric abominations to sidestep that can of worms. It will still be a messy enough when it gets to "Upper first arm tentacle (left)".

My though is that the different arms will all be "sides". So you would use the system that currently swaps between your left and right arms to also swap between your first, second, third, fourth, fifth, and sixth tentacles. and when you hit change sides in the UI it would bring up a lil menu that asks which limb (or for more traditional human armors) pair of limbs you wish to cover.

heavy lifting was always done by somebody actually competent.

The body part code keeps looking better every time I look at it after a few of your PRs 😄

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. Please do not bump or comment on this issue unless you are actively working on it. Stale issues, and stale issues that are closed are still considered.

Venera3 commented 10 months ago

State of the system in the far future of 2024: