Skip to content

Commit 7612908

Browse files
committed
Implemented rings of protection.
1 parent c46cdae commit 7612908

File tree

6 files changed

+58
-9
lines changed

6 files changed

+58
-9
lines changed

simalq/tile/item.hy

+13-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@
258258
:flavor "A star-shaped pendant with two black spots in the center. Its magic is short-lived but potent indeed.")
259259
260260
(deftile "! " "a passwall amulet" StatusEffectItem
261-
:color 'dark-orange
261+
:color 'purple
262262
:iq-ix 151
263263
:acquirement-points 150
264264
@@ -293,6 +293,18 @@
293293
f"Makes you invisible for {@duration} more turns. Most monsters can't track or shoot you while you're invisible, unless you're adjacent to them.")
294294
:flavor "A cape enchanted with the power of the night sky. Try not to get it snagged on any loose flagstones (especially when it's invisible).")
295295
296+
(deftile "! " "a ring of protection" StatusEffectItem
297+
:color 'dark-orange
298+
:iq-ix 158
299+
:acquirement-points 150
300+
301+
:effect StatusEffect.Prot
302+
:duration 25
303+
304+
:help (meth []
305+
f"Protects you (for {@duration} more turns) from harmful status effects and disenchantment.")
306+
:flavor "Also known as a ring of anti-anti-magic. Fortunately, anti-anti-anti-magic traps are still in dungeon R&D.")
307+
296308
297309
(defclass Usable [Item]
298310
"An item that's added to your inventory and can thereafter be

simalq/tile/monster.hy

+1-1
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@
799799
:sees-invisible T
800800
801801
:act (meth []
802-
(doc (.format "Disenchant — If it's not adjacent but has line of effect to you, the monster removes the first beneficial status effect that you have from the following list: {}. Otherwise, it behaves per `Approach`."
802+
(doc (.format "Disenchant — If it's not adjacent but has line of effect to you, the monster disenchants you, removing the first beneficial status effect that you have from the following list: {}. Otherwise, it behaves per `Approach`."
803803
(.join ", " (gfor e (StatusEffect.disenchantable) e.name))))
804804
(if (and
805805
(not (adjacent? @pos G.player.pos))

simalq/tile/scenery.hy

+1-1
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@
780780
:iq-ix 169
781781

782782
:hook-player-walked-into (meth []
783-
(doc (.format "Removes the first beneficial status effect that you have from the following list: {}."
783+
(doc (.format "Disenchants you, removing the first beneficial status effect that you have from the following list: {}."
784784
(.join ", " (gfor e (StatusEffect.disenchantable) e.name))))
785785
(StatusEffect.disenchant-player))
786786

simalq/tile/unimplemented.hy

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
[132 "golem"]
3232
[134 "siren"]
3333
[152 "random_gate"]
34-
[158 "ring_of_protection"]
3534
[159 "amulet_of_poisonous_touch"]
3635
[164 "cyclops"]
3736
[165 "dark_prince"]

simalq/util.hy

+7-5
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@
144144
(bool (get G.player.status-effects @)))
145145

146146
(defmeth add [duration]
147+
(when (and (@bad?) (.player-has? StatusEffect.Prot))
148+
; Protection prevents harmful effects.
149+
(return))
147150
(+= (get G.player.status-effects @) duration))
148151

149152
(defn [classmethod] disenchantable [cls]
@@ -157,13 +160,12 @@
157160

158161
(defn [classmethod] disenchant-player [cls]
159162
"Try to remove a beneficial status effect from the player. Return
160-
`True` on success."
161-
(when (.player-has? StatusEffect.Prot)
162-
; Protection prevents disenchantment.
163-
(return F))
163+
`True` if there was a removable beneficial effect; under
164+
protection, it still won't actually be removed."
164165
; Remove the first eligible effect that the player actually has.
165166
(for [effect (.disenchantable cls) :if (.player-has? effect)]
166-
(setv (get G.player.status-effects effect) 0)
167+
(unless (.player-has? StatusEffect.Prot)
168+
(setv (get G.player.status-effects effect) 0))
167169
(return T))
168170
F)
169171

tests/test_item.hy

+36
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
tests.lib [init init-boot-camp assert-at assert-player-at assert-hp assert-textmap set-square mv-player wk shoot wait use-item top]
77
simalq.geometry [Pos Direction at]
88
simalq.game-state [G]
9+
simalq.util [StatusEffect]
910
simalq.quest-definition [mk-tile])
1011
(setv T True F False)
1112

@@ -317,6 +318,41 @@
317318
(assert-at [1 4] "devil"))
318319

319320

321+
(defn test-ring-of-protection []
322+
(init [
323+
:height 1
324+
:tiles [
325+
"passwall amulet" "ring of protection"
326+
"anti-magic trap" "weakness trap"
327+
"pile of gold" "hole" "archmage"]])
328+
(defn check [player-hp pass prot]
329+
(assert (= G.player.hp player-hp))
330+
(assert (= (.player-has? StatusEffect.Pass) pass))
331+
(assert (= (.player-has? StatusEffect.Prot) prot)))
332+
333+
; A ring of protection makes an anti-magic trap ineffective.
334+
(wk 'E 3)
335+
(check 100 T T)
336+
; Likewise a weakness trap.
337+
(wk 'E)
338+
(assert (not (.player-has? StatusEffect.Weak)))
339+
; The archmage's shots have no effect, since we have an effect to
340+
; disenchant (`Pass`), but he can't actually remove it due to
341+
; `Prot`.
342+
(wk 'E)
343+
(check 100 T T)
344+
; Just before `turn-n` advances to 20, `Pass` ends. `Prot` is still
345+
; in effect, but doesn't do anything about damaging shots from the
346+
; archmage.
347+
(wait 14)
348+
(assert (= G.turn-n 19))
349+
(check 100 T T)
350+
(wait)
351+
(check 100 F T)
352+
(wait)
353+
(check 88 F T))
354+
355+
320356
(defn test-inventory []
321357
(init [:tiles [
322358
"wand of shielding" "wall-making wand"

0 commit comments

Comments
 (0)