Skip to main content
  1. Posts/

Day 79 - Shielded Resistance

OldDays seitan-spin cucumber ruby

Never got around to playing the sequel.
Never got around to playing the sequel.

In which we offer some temporary resistance.

Test Every Day
#

What’s next?

DragonsSpine/GameSystems/Effects/Effect.cs
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  Shield,
  Regenerate_Hits,
  Regenerate_Mana,
  Regenerate_Stamina,
  Protection_from_Fire, // 40
  Protection_from_Cold,
  Protection_from_Poison,
  Protection_from_Fire_and_Ice,
  Protection_from_Blind_and_Fear,
  Protection_from_Stun_and_Death, // 45
  Resist_Fear,
  Resist_Blind,
  Resist_Stun,
  Resist_Lightning,
  Resist_Death, // 50
  Resist_Zonk,

Lots of resistance and protection stuff. We’ll take care of shielding first:

features/player_effects.feature
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
## Shield

# Notes:
# Temporary character attribute "Shielding"; there is a Land.MaxShielding.
# Land max is 9 in the current db.
# Visible via command 'show effects' as "Total Shielding = <value>".
# Value is subtracted from armor class for ranged attacks, half for melee.

Scenario: Temporary shield potion increases shield temporarily
  Given I use the "minimal" database as-is
  And I add player and character "TestTS02"
  And I create a "shield" potion of amount "5" and duration "2"
  And I put the item in the character's left hand
  And I start the server and play
  And I have a shielding of "0"
  When I open and drink "bottle"
  Then I have a shielding of "5"
  And I rest
  And I have a shielding of "0"

Scenario: Temporary shield potion maxes out at Land max
  Given I use the "minimal" database as-is
  And I add player and character "TestTS03"
  And I create a "shield" potion of amount "10" and duration "2"
  And I put the item in the character's left hand
  And I start the server and play
  And I have a shielding of "0"
  When I open and drink "bottle"
  Then I have a shielding of "9"
  And I rest
  And I have a shielding of "0"

Rather than starting a fight, I’m just using the “show effects” command to see what the effect is. Everything works well until I try multiple potions on a whim, and instead of combining or overriding, the effect drops to zero..? Couldn’t immediately figure it out, so tag the test and move on.

features/player_effects.feature
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
# bug - rather than having the amount updated, we wind up with 0?
@bug
Scenario: Multiple temporary shield potions
  Given I use the "minimal" database as-is
  And I add player and character "TestTS04"
  And I create a "shield" potion of amount "6" and duration "99"
  And I put the item in the character's right hand
  And I create a "shield" potion of amount "9" and duration "99"
  And I put the item in the character's left hand
  And I start the server and play
  And I have a shielding of "0"
  When I open and drink "bottle"
  Then I have a shielding of "6"
  And I drop "right"
  And I open and drink "bottle"
  And I have a shielding of "9"

For the protection and resistance stuff, let’s make some generic steps:

features/steps/character_steps.rb
384
385
386
387
388
389
390
391
392
393
394
Then(/^I have a "([^"]*)" resistance of "([^"]*)"$/) do |type, desired_value|
  resp = telnet_command(@connection, "show resists", / ->/)
  waited_for = /#{type}\s*:\s*#{desired_value}\b/i
  expect(@last_resp).to match(waited_for)
end

Then(/^I have a "([^"]*)" protection of "([^"]*)"$/) do |type, desired_value|
  resp = telnet_command(@connection, "show protection", / ->/)
  waited_for = /#{type}\s*:\s*#{desired_value}\b/i
  expect(@last_resp).to match(waited_for)
end
features/player_effects.feature
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
## Resistance and Protection effects
# TODO - verify no unintended resistance/protection
Scenario Outline: Resistance and protection potions have desired effects
  Given I use the "minimal" database as-is
  And I add player and character "TestRP01"
  And I create an "<effect>" potion of amount "<amt>" and duration "3"
  And I put the item in the character's left hand
  And I start the server and play
  And I have a "<resist>" resistance of "0"
  And I have a "<protect>" protection of "0"
  When I open and drink "bottle"
  And I have a "<resist>" resistance of "<resistamt>"
  And I have a "<protect>" protection of "<protectamt>"
  And I rest
  And I have a "<resist>" resistance of "0"
  And I have a "<protect>" protection of "0"
Examples:
| effect                         | amt | resist    | resistamt | protect | protectamt |
| Protection_from_Fire           | 2   | Fire      | 1         | Fire    | 2          |
| Protection_from_Cold           | 3   | Ice       | 1         | Ice     | 3          |
| Protection_from_Fire_and_Ice   | 4   | Fire      | 1         | Fire    | 4          |
| Protection_from_Fire_and_Ice   | 5   | Ice       | 1         | Ice     | 5          |
| Protection_from_Poison         | 6   | Poison    | 1         | Poison  | 6          |
| Protection_from_Stun_and_Death | 8   | Death     | 1         | Death   | 8          |
| Protection_from_Stun_and_Death | 9   | Stun      | 1 | | |
| Protection_from_Blind_and_Fear | 7   | Blind     | 1 | | |
| Protection_from_Blind_and_Fear | 8   | Fear      | 1 | | |
| Resist_Fear                    | 7   | Fear      | 1 | | |
| Resist_Blind                   | 0   | Blind     | 1 | | |
| Resist_Stun                    | 5   | Stun      | 1 | | |
| Resist_Lightning               | 0   | Lightning | 1 | | |

Resist_Death seems to have an interesting issue. In CreateCharacterEffect:

DragonsSpine/GameSystems/Effects/Effect.cs
807
808
809
  case EffectType.Resist_Death:
    target.DeathResistance++;
    break;

But in StopCharacterEffect:

DragonsSpine/GameSystems/Effects/Effect.cs
537
538
539
  case EffectType.Resist_Death:
    this.target.DeathProtection -= effectAmount;
    break;

So we’ll split that off into a separate test and bug-tag it until it’s fixed:

features/player_effects.feature
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
# bug? - Resist_Death adds death resistance but removes death protection when it wears off
# NOTE: Merge with other test when fixed.
@bug
Scenario Outline: Death resistance potion has desired effect
  Given I use the "minimal" database as-is
  And I add player and character "TestRP02"
  And I create an "<effect>" potion of amount "<amt>" and duration "3"
  And I put the item in the character's left hand
  And I start the server and play
  And I have a "<resist>" resistance of "0"
  And I have a "<protect>" protection of "0"
  When I open and drink "bottle"
  And I have a "<resist>" resistance of "<resistamt>"
  And I have a "<protect>" protection of "<protectamt>"
  And I rest
  And I have a "<resist>" resistance of "0"
  And I have a "<protect>" protection of "0"
Examples:
| effect                         | amt | resist    | resistamt | protect | protectamt |
| Resist_Death                   | 3   | Death     | 1 | | |

Zonk?
#

I initially skipped over it; what the heck is Resist_Zonk?

In the DoDamage method, we find:

DragonsSpine/GameSystems/Rules/Rules.cs
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
 if (target.Stunned <= 0 && critical && !target.immuneStun)
  {
    int saveMod = -(target.ZonkResistance);
    // damager used a bash
    if (damager.CommandType == Command.CommandType.Bash)
    {
      saveMod += Math.Max(target.Level, Skills.GetSkillLevel(damager.GetSkillExperience(Globals.eSkillType.Bash))) -
        Math.Min(target.Level, Skills.GetSkillLevel(damager.GetSkillExperience(Globals.eSkillType.Bash)));
    }
    
    if (!DND_GetSavingThrow(target, SavingThrow.PetrificationPolymorph, saveMod))
    {
      // stun for 1 round if bash save failed, 1 - 2 for others
      if (damager.CommandType == Command.CommandType.Bash)
        target.Stunned = 1;
      else target.Stunned += (short)RollD(1, 2);

It also partially protects from spell-based stuns. But then what does StunResistance do?

DragonsSpine/GameSystems/Rules/Rules.cs
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
  case "stun":
    #region Immune to Stun
    if (target.immuneStun)
    {
      if (caster != null)
      {
        if (target.race != "")
        {
          caster.WriteToDisplay(target.Name + " is immune to stun based magic.");
        }
        else
        {
          caster.WriteToDisplay("The " + target.Name + " is immune to stun based magic.");
        }
      }
      return 0;
    }
    #endregion
    else if (DND_GetSavingThrow(target, savingThrow, -(target.StunResistance) + casterSL))
    {
      if (caster != null)
      {
        if (target.race != "")
        {
          caster.WriteToDisplay(target.Name + " resists your Stun spell.");
        }
        else
        {
          caster.WriteToDisplay("The " + target.Name + " resists your Stun spell.");
        }

So StunResistance is just for a “stun” spell, and ZonkResistance is for all other ways you might get stunned. Interesting. I guess I should add a test for ZonkResistance.

…which fails. Turns out it’s an effect for worn items only, even if I make a potion for it. I’ll have to tackle the worn effect thing, once I’ve exhausted all the potioning. Tomorrow.


Interesting Stuff
#


More to come
More to come

Day 79 code - tests