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

Enchantment/relic cleanup 2 #400

Merged
merged 16 commits into from
Mar 18, 2021
Merged

Conversation

olanti-p
Copy link
Contributor

@olanti-p olanti-p commented Mar 16, 2021

Purpose of change

  1. Tweak the math a bit when multiple enchantments modify the same value.
    Makes it so bonuses don't affect each other in weird ways, but rather are
    calculated based on same baseline and then applied simultaneously.
  2. Check, implement and/or fix enchantments that modify the following values:
    • STRENGTH
    • DEXTERITY
    • PERCEPTION
    • INTELLIGENCE
    • SPEED
    • ATTACK_COST and item-specific ITEM_ATTACK_COST
    • MOVE_COST
    • METABOLISM
    • MANA_CAP
    • MANA_REGEN
  3. Add tests for enchantments, moves gain and mana pool
  4. Update docs for enchantments

Describe alternatives you've considered

Porting the code from DDA repo, but after encountering various merge conflicts, bugs (like CleverRaven#47450) and lack of tests, decided writing everything from scratch would save time on bugfixing later.

Testing

Unit tests; tried relics with these enchantments in-game.

Additional context

Using process_turn() is likely to collect a lot of global state related failures, but I'd rather keep it, as it makes the tests work close to the "real thing".


guy.mod_num_dodges_bonus( get_value_add( enchant_vals::mod::BONUS_DODGE ) );
guy.mod_num_dodges_bonus( mult_bonus( enchant_vals::mod::BONUS_DODGE, guy.get_num_dodges_base() ) );
guy.mod_num_dodges_bonus( calc_bonus( enchant_vals::mod::BONUS_DODGE, guy.get_num_dodges_base() ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"BONUS_DODGE" is another unfortunate name. It sounds like bonus to the ability to dodge, but actually adds dodge attempts before penalty.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is it should've been BONUS_DODGES, which would've conveyed the intended effect.

@@ -419,12 +419,12 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f
}
item &cur_weapon = allow_unarmed ? used_weapon() : weapon;

if( cur_weapon.attack_time() > attack_speed( cur_weapon ) * 20 ) {
if( cur_weapon.attack_cost() > attack_cost( cur_weapon ) * 20 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really changed here, but that sure is a puzzling line.

@Coolthulhu
Copy link
Member

I'm getting test failures in the new tests, all of them off with the character getting +1 in a stat or speed.

Big block
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cata_test is a Catch v2.12.0 host application.
Run with -? for options

Randomness seeded to: 1615917198

-------------------------------------------------------------------------------
Enchantments modify stats
  base stats 8
       When: Character receives relic
   And when: Turn passes
       Then: Stats are modified and don't overflow
-------------------------------------------------------------------------------
enchantment_test.cpp:189
...............................................................................

enchantment_test.cpp:171: FAILED:
  CHECK( guy.get_per() == p )
with expansion:
  6 == 5

-------------------------------------------------------------------------------
Enchantments modify stats
  base stats 8
       When: Character receives relic
   And when: Turn passes
   And when: Character loses relic
       Then: Stats remain unchanged
-------------------------------------------------------------------------------
enchantment_test.cpp:194
...............................................................................

enchantment_test.cpp:171: FAILED:
  CHECK( guy.get_per() == p )
with expansion:
  6 == 5

-------------------------------------------------------------------------------
Enchantments modify stats
  base stats 12
       When: Character receives relic
   And when: Turn passes
       Then: Stats are modified and don't overflow
-------------------------------------------------------------------------------
enchantment_test.cpp:189
...............................................................................

enchantment_test.cpp:171: FAILED:
  CHECK( guy.get_per() == p )
with expansion:
  8 == 7

-------------------------------------------------------------------------------
Enchantments modify stats
  base stats 12
       When: Character receives relic
   And when: Turn passes
   And when: Character loses relic
       Then: Stats remain unchanged
-------------------------------------------------------------------------------
enchantment_test.cpp:194
...............................................................................

enchantment_test.cpp:171: FAILED:
  CHECK( guy.get_per() == p )
with expansion:
  8 == 7

-------------------------------------------------------------------------------
Enchantments modify stats
  base stats 4
       When: Character receives relic
   And when: Turn passes
       Then: Stats are modified and don't overflow
-------------------------------------------------------------------------------
enchantment_test.cpp:189
...............................................................................

enchantment_test.cpp:171: FAILED:
  CHECK( guy.get_per() == p )
with expansion:
  4 == 3

-------------------------------------------------------------------------------
Enchantments modify stats
  base stats 4
       When: Character receives relic
   And when: Turn passes
   And when: Character loses relic
       Then: Stats remain unchanged
-------------------------------------------------------------------------------
enchantment_test.cpp:194
...............................................................................

enchantment_test.cpp:171: FAILED:
  CHECK( guy.get_per() == p )
with expansion:
  4 == 3

-------------------------------------------------------------------------------
Enchantments modify speed
  base = 100
       When: Character receives relic
   And when: Turn passes
       Then: Speed changes, moves gain changes
-------------------------------------------------------------------------------
enchantment_test.cpp:258
...............................................................................

enchantment_test.cpp:238: FAILED:
  REQUIRE( guy.get_speed() == speed )
with expansion:
  76 == 75

-------------------------------------------------------------------------------
Enchantments modify speed
  base = 100
       When: Character receives relic
   And when: Turn passes
   And when: Character loses relic
       Then: Nothing changes
-------------------------------------------------------------------------------
enchantment_test.cpp:263
...............................................................................

enchantment_test.cpp:238: FAILED:
  REQUIRE( guy.get_speed() == speed )
with expansion:
  76 == 75

-------------------------------------------------------------------------------
Enchantments modify speed
  base = 120
       When: Character receives relic
   And when: Turn passes
       Then: Speed changes, moves gain changes
-------------------------------------------------------------------------------
enchantment_test.cpp:258
...............................................................................

enchantment_test.cpp:238: FAILED:
  REQUIRE( guy.get_speed() == speed )
with expansion:
  86 == 85

-------------------------------------------------------------------------------
Enchantments modify speed
  base = 120
       When: Character receives relic
   And when: Turn passes
   And when: Character loses relic
       Then: Nothing changes
-------------------------------------------------------------------------------
enchantment_test.cpp:263
...............................................................................

enchantment_test.cpp:238: FAILED:
  REQUIRE( guy.get_speed() == speed )
with expansion:
  86 == 85

===============================================================================
test cases:   8 |   6 passed |  2 failed
assertions: 410 | 400 passed | 10 failed

Ended test at Tue Mar 16 18:53:30 2021
The test took 3.117 seconds

18:53:30.097 INFO : Randomness seeded to: 1615917198

Platform:

gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

Building with:

make RELEASE=1 TILES=1 SOUND=1 PROFILE=-pg LINTJSON=0 OPTLEVEL=-O3 -k

@olanti-p
Copy link
Contributor Author

olanti-p commented Mar 17, 2021

Turns out JSON double parser produces different values for different compilers.

Parsing -0.5 gives -0.5 for clang version 10.0.0-4ubuntu1 and -0.499999999999999889 for gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04). This difference is enough to screw up truncation...

I guess I'll just limit minimum multiplicative bonus to some reasonable amount (0.00001 should be more than enough).

src/magic_enchantment.cpp Outdated Show resolved Hide resolved
src/creature.cpp Outdated

void Creature::clear_effects_for_testing()
{
effects->clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it need to exist? It may be a bug in how I designed effect removal if it does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea, it was me checking if effects were correctly removed (they seem to)

"add": 13.37,
// Additive bonus. Optional integer number, default is 0.
// May be ignored for some values.
"add": 13,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch there - most of the code pretty clearly tries to imply that it's a double, by using doubles to accumulate it.

Copy link
Contributor Author

@olanti-p olanti-p Mar 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually thought about converting it to double, but there doesn't seem to be any use cases to warrant that (yet?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory, it would work if multiple effects had subtle effects that only make sense when added together.
But it sounds like UI trouble to even try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants