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

Add support for partial armor coverage for monsters #51304

Merged
merged 16 commits into from
Sep 4, 2021

Conversation

Joshua-Chin
Copy link
Contributor

@Joshua-Chin Joshua-Chin commented Sep 2, 2021

Summary

Features "Add support for monsters weakpoints: Part 1"

Purpose of change

The change lets contributors specify partial armor coverage for monsters using JSON fields. This also acts as the first pass of #51305.

Many monster have armor that should offers only partial protection. For example, the zombie soldier wears a ESAPI vest that should cover only a part of the torso. However, armor values for monsters currently offer 100% coverage.

In particular, this negatively effects the performance of archery. Many have complained about the inability of bows to deal with even moderately armored monsters. This pull request, combined with several JSON changes, would make archery capable of damaging lightly armored enemies.

This change does not modify any in-game monsters. Determining appropriate coverage and unarmored resistances should be handled in a separate discussion. Given the interest around archery balance, contributors willing to make the JSON only changes should be forthcoming.

Describe the solution

Let contributors specify a list of weakpoints as follows:

    "weakpoints": [
      {
        "name": "the knee",
        "armor_mult": { "bullet": 0.0 },
        "armor_offset": { "bullet": 20 },
        "coverage": 0.5
      }
    ],

Each weakpoint has the following fields:

  • name: The name of the weakpoint. Should fit into the sentence: "You hit the zombie in for 13 damage".
  • id: The ID of the weakpoint. Currently unused, but may become important for weakpoint inheritance. Defaults to name.
  • armor_mult: An object that can be parsed by load_damage_array. Specifies the multiplier in armor when hitting the weak point.
  • armor_offset: An object that can be parsed by load_damage_array. Specifies the offset in the armor when hitting the weak point.
  • coverage: The probability of hitting the weakpoint. In the future, this could be increased by high skill levels.
Under the hood

We create a new compilation unit "weakpoint". It contains two structs: weakpoint and weakpoints. The weakpoints struct has methods for selecting the weakpoint to hit, and the weakpoint struct has methods for modifying resistance values. Both have methods for reading from JSON.

We add a weakpoints field to mtype and make the necessary modification to "monstergeneration" to support parsing. The reduction in resistances / weakpoint selection is handled in Monster::absorb_hit.

Describe alternatives you've considered

Previously considered solution

Monsters now have an "armor_coverage" field that determines the probability of their armor protecting them. Armor coverage only effects kinetic damage types (blunt/cut/pierce/bullet); acid and fire are unaffected.

In addition, monsters can have "unarmored" resistances. These represent protection that cannot be avoided. For example a soldier zombie's skin is probably as strong as a tough zombie's. Either armored or unarmored resistance is used for protection; they are added together.

Other alternatives
  • Only introduce the "armor_coverage" field and treat unarmored resistances as 0.
    • This solution would be too restrictive. A creature with an unarmored resistance of 0 could be damaged by weapon as weak as the foam bat.
  • Introduce a "armor_bypass", that reduces the armor by a percentage if hitting an uncovered area.
    • The unarmored resistance of humanoid zombies is not related to the armor they are wearing (riot gear, turnout gear, etc.)
  • Add support for arbitrary layers of armor.
    • While this solution is strictly more general, it seems unnecessarily complex. There's not much to gain, gameplay-wise, from adding a third or fourth layer of armor.

Testing

Verify unarmored resistances

  1. Spawn a debug monster (with "armor_bullet": 100, "armor_coverage": 50, and "unarmored_bullet": 10)
  2. Fire at the monster with a M110 (~60 damage)
  3. Roughly half the bullets deal damage
  4. Fire at the monster with a Ruger 22 Rifle (~15 damage)
  5. Roughly half the bullets deal minimal (~5 damage)

Verify no changes to existing monsters

  1. Spawn a Kevlar hulk
  2. Punch it
  3. Exactly what you expect (0 damage)

Additional context

We still need to add messaging support (printing message like " hit in the "). That will involve plumbing the weakpoint selected back into the melee / projectile attack methods. This pull request is already getting rather large, so I'd prefer to handle weakpoint messaging in a subsequent pull request.

@actual-nh actual-nh added <Enhancement / Feature> New features, or enhancements on existing [C++] Changes (can be) made in C++. Previously named `Code` Game: Mechanics Change Code that changes how major features work Monsters Monsters both friendly and unfriendly. labels Sep 2, 2021
@I-am-Erk
Copy link
Member

I-am-Erk commented Sep 2, 2021

Oh, this is great! I have some very specific implementation details for this that I think we should either include at the start, or make sure we future-proof our design for at least. Do you mind switching to draft so I can write that up?

@Venera3
Copy link
Member

Venera3 commented Sep 2, 2021

Lovely! Do remember to add documentation of these fields to MONSTERS.md - monsters are mostly JSON, so most contributors seeking to add them won't go scouring C++ on the lookout for undocumented variables.

@I-am-Erk I-am-Erk mentioned this pull request Sep 2, 2021
@I-am-Erk
Copy link
Member

I-am-Erk commented Sep 2, 2021

#51305 is a hastily constructed implementation suggestion. This accomplishes what we need for the first pass, but I hope you can change the JSON formatting and algorithm to fit without too much trouble? It's important so that we can continue onward without getting a giant spaghetti tangle.

@Joshua-Chin Joshua-Chin marked this pull request as draft September 2, 2021 13:28
@Joshua-Chin Joshua-Chin marked this pull request as ready for review September 3, 2021 04:29
doc/MONSTERS.md Outdated Show resolved Hide resolved
doc/MONSTERS.md Outdated Show resolved Hide resolved
@Joshua-Chin Joshua-Chin requested a review from I-am-Erk September 3, 2021 16:45
@I-am-Erk I-am-Erk merged commit 5fb0289 into CleverRaven:master Sep 4, 2021
@I-am-Erk
Copy link
Member

I-am-Erk commented Sep 4, 2021

Phenomenal! I will see if I can find time to add coverage data to some monsters today

Venera3 pushed a commit to Venera3/Cataclysm-DDA that referenced this pull request Sep 21, 2021
* Modify load_damage_array to specify default

* Add weakpoint.h

* Implement weakpoint.cpp

* Various compiler fixes

* Add weakpoints to mtype.

* Let weakpoints modify monster armor.

* Compiler fixes

* weakpoint bugfixes.

* Run astyle

* Add json documentation

* Run json_formatter

* Run clang tidy

* Fix GCC-only warning

* clang-tidy

* Clarify weakpoint docs and switch to percentage coverage.

* Rename armor offset to armor penalty, flipping the sign.
@LyleSY
Copy link
Contributor

LyleSY commented Sep 23, 2021

Hello, I'm starting to add this to DinoMod. One thing I've wanted a long time is to set "the soft underbelly" as a weak point, but only available when the monster is knocked to the ground. This is how every apex dino predator appears to have hunted, especially against ankylosaurids and ceratopsians. Any chance you want to do the code to enable that? https://books.google.com.ph/books?id=IJ9nBUq_hKkC&printsec=frontcover&source=gbs_atb&hl=en#v=onepage&q=tipping&f=false

@I-am-Erk
Copy link
Member

I-am-Erk commented Sep 24, 2021

Ooh, an effect that adds a weak point temporarily would be nifty. The underbelly suggestion would have to be by monster though. You should suggest it in #51305

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[C++] Changes (can be) made in C++. Previously named `Code` <Enhancement / Feature> New features, or enhancements on existing Game: Mechanics Change Code that changes how major features work Monsters Monsters both friendly and unfriendly.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants