From fc4f7351210b357f2618c3236c455b89d61b1457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ki=C3=ABd=20Llaentenn?= Date: Thu, 31 Aug 2023 13:52:48 -0400 Subject: [PATCH] feat: add ring of deception --- data/des/des-main.des | 10 +++++++++- data/des/des-statuses-nonplayer.des | 3 +++ data/des/des-statuses-player.des | 3 +++ data/status_help.tsv | 13 +++++++------ src/ai.zig | 8 +++++++- src/items.zig | 23 +++++++++++++++++++++++ src/types.zig | 1 + 7 files changed, 53 insertions(+), 8 deletions(-) diff --git a/data/des/des-main.des b/data/des/des-main.des index 0cfee710..4bd03d22 100644 --- a/data/des/des-main.des +++ b/data/des/des-main.des @@ -645,7 +645,7 @@ the sword will attack multiple foes in a line in that direction while giving them the $oheld$. status. -The lifespan of the spectral sword is equivalent to your willpower * 2, and its +The lifespan of the spectral sword is equivalent to your $bwillpower * 2$., and its damage is equivalent to $btriple$. the damage your current weapon would deal if you attacked (defaulting to $b1$. damage if you don't have a weapon). @@ -697,3 +697,11 @@ damage, $r§$. == $b100%$. damage). Damage will never be below 1. $cEffect:$. Confers $aimmobility$., $aexplosiveness$., $anoisy$., and $b3$. turns of $alifespan$. on a foe, thus causing it to explode (radius $b2$.) after $b3$. turns. Will-checked. + +% deception +$cEffect:$. While under the ring's effect, undead without nearby non-undead +allies will be deceived into thinking you are an ally. The ring cannot be used +while corrupted. The effect is not will-checked. + + +$cDuration:$. Ring duration lasts for $bwillpower$. turns. diff --git a/data/des/des-statuses-nonplayer.des b/data/des/des-statuses-nonplayer.des index 51dd19c7..984b881a 100644 --- a/data/des/des-statuses-nonplayer.des +++ b/data/des/des-statuses-nonplayer.des @@ -16,6 +16,9 @@ This is supposed to be a player-only status, and is probably a bug. % nonplayer_Status.RingAcceleration This is supposed to be a player-only status, and is probably a bug. +% nonplayer_Status.RingDeception +This is supposed to be a player-only status, and is probably a bug. + % nonplayer_Status.DetectHeat This is supposed to be a player-only status, and is probably a bug. diff --git a/data/des/des-statuses-player.des b/data/des/des-statuses-player.des index 73b51f05..07702110 100644 --- a/data/des/des-statuses-player.des +++ b/data/des/des-statuses-player.des @@ -16,6 +16,9 @@ Refer to the ring's description. % player_Status.RingAcceleration Refer to the ring's description. +% player_Status.RingDeception +Refer to the ring's description. + % player_Status.DetectHeat You are detecting sources of heat, as well as enemies attuned to fire. diff --git a/data/status_help.tsv b/data/status_help.tsv index f0ab3836..3c5cbc2e 100644 --- a/data/status_help.tsv +++ b/data/status_help.tsv @@ -1,12 +1,13 @@ # vim: nowrap # # status status name status name (unliving) mini name -.RingTeleportation "ring: teleportation" - - -.RingDamnation "ring: damnation" - - -.RingElectrocution "ring: electrocution" - - -.RingExcision "ring: excision" - - -.RingConjuration "ring: conjuration" - - -.RingAcceleration "ring: acceleration" - - +.RingTeleportation "ring: teleportation" "dancing" - +.RingDamnation "ring: damnation" "whistling" - +.RingElectrocution "ring: electrocution" "jumping around" - +.RingExcision "ring: excision" "pontificating" - +.RingConjuration "ring: conjuration" "house of pain" - +.RingAcceleration "ring: acceleration" "is in effect" - +.RingDeception "ring: deception" "voting for trump" - .DetectHeat "detect heat" - - .DetectElec "detect electricity" - - .EtherealShield "ethereal shield" - - diff --git a/src/ai.zig b/src/ai.zig index 2076b331..6385bf4e 100644 --- a/src/ai.zig +++ b/src/ai.zig @@ -412,6 +412,10 @@ pub fn checkForHostiles(mob: *Mob) void { return; } + const has_nonundead_ally = for (mob.allies.items) |ally| { + if (ally.life_type != .Undead) break true; + } else false; + for (mob.fov) |row, y| for (row) |cell, x| { if (cell == 0) continue; const fitem = Coord.new2(mob.coord.z, x, y); @@ -425,7 +429,8 @@ pub fn checkForHostiles(mob: *Mob) void { if (!othermob.ai.flag(.IgnoredByEnemies) and mob.isHostileTo(othermob) and - (!mob.ai.flag(.IgnoresEnemiesUnknownToLeader) or mob.squad.?.leader.?.cansee(othermob.coord))) + (!mob.ai.flag(.IgnoresEnemiesUnknownToLeader) or mob.squad.?.leader.?.cansee(othermob.coord)) and + !(othermob.hasStatus(.RingDeception) and !has_nonundead_ally)) { updateEnemyRecord(mob, .{ .mob = othermob, @@ -460,6 +465,7 @@ pub fn checkForHostiles(mob: *Mob) void { enemy.mob.ai.flag(.IgnoredByEnemies) or (mob.ai.flag(.IgnoresEnemiesUnknownToLeader) and !mob.squad.?.leader.?.cansee(enemy.mob.coord)) or + (enemy.mob.hasStatus(.RingDeception) and !has_nonundead_ally) or enemy.mob.is_dead) { alert.reportThreat(mob, .{ .Specific = enemy.mob }, confrontation); diff --git a/src/items.zig b/src/items.zig index 6b658154..dd96b6c7 100644 --- a/src/items.zig +++ b/src/items.zig @@ -211,6 +211,7 @@ pub const RINGS = [_]ItemTemplate{ .{ .w = 9, .i = .{ .r = AccelerationRing } }, .{ .w = 9, .i = .{ .r = TransformationRing } }, .{ .w = 9, .i = .{ .r = DetonationRing } }, + .{ .w = 9, .i = .{ .r = DeceptionRing } }, }; pub const NIGHT_RINGS = [_]ItemTemplate{ .{ .w = 9, .i = .{ .r = ExcisionRing } }, @@ -963,6 +964,28 @@ pub const DetonationRing = Ring{ // {{{ }.f, }; // }}} +pub const DeceptionRing = Ring{ // {{{ + .name = "deception", + .required_MP = 2, + .stats = .{ .Willpower = 1 }, + .effect = struct { + pub fn f() bool { + if (state.player.hasStatus(.Corruption)) { + state.message(.Info, "You cannot use this ring whilst corrupted.", .{}); + return false; + } + + const will = @intCast(usize, state.player.stat(.Willpower)); + const duration = math.max(1, will); + state.player.addStatus(.RingDeception, 0, .{ .Tmp = duration }); + + state.message(.Info, "A strange aura begins to surround you.", .{}); + + return true; + } + }.f, +}; // }}} + pub const ExcisionRing = Ring{ // {{{ .name = "excision", .required_MP = 5, diff --git a/src/types.zig b/src/types.zig index 1cd6b585..f52af7bc 100644 --- a/src/types.zig +++ b/src/types.zig @@ -1128,6 +1128,7 @@ pub const Status = enum { RingExcision, // No power field RingConjuration, // No power field RingAcceleration, // No power field + RingDeception, // No power field // Item-specific effects. DetectHeat, // Doesn't have a power field.