You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(15) |
Sep
(131) |
Oct
(149) |
Nov
(216) |
Dec
(222) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(152) |
Feb
(58) |
Mar
(184) |
Apr
(249) |
May
(96) |
Jun
(207) |
Jul
(248) |
Aug
(87) |
Sep
(232) |
Oct
(440) |
Nov
(248) |
Dec
(212) |
2008 |
Jan
(216) |
Feb
(118) |
Mar
(508) |
Apr
(796) |
May
(597) |
Jun
(896) |
Jul
(475) |
Aug
(124) |
Sep
(200) |
Oct
(248) |
Nov
(377) |
Dec
(373) |
2009 |
Jan
(807) |
Feb
(430) |
Mar
(276) |
Apr
(138) |
May
(161) |
Jun
(210) |
Jul
(390) |
Aug
(141) |
Sep
(286) |
Oct
(826) |
Nov
(1123) |
Dec
(419) |
2010 |
Jan
(671) |
Feb
(625) |
Mar
(328) |
Apr
(349) |
May
(296) |
Jun
(485) |
Jul
(396) |
Aug
(113) |
Sep
(582) |
Oct
(414) |
Nov
(248) |
Dec
(377) |
2011 |
Jan
(400) |
Feb
(225) |
Mar
(321) |
Apr
(264) |
May
(148) |
Jun
(249) |
Jul
(270) |
Aug
(217) |
Sep
(262) |
Oct
(356) |
Nov
(426) |
Dec
(359) |
2012 |
Jan
(203) |
Feb
(131) |
Mar
(317) |
Apr
(313) |
May
(170) |
Jun
(272) |
Jul
(363) |
Aug
(364) |
Sep
(330) |
Oct
(188) |
Nov
(178) |
Dec
(141) |
2013 |
Jan
(177) |
Feb
(258) |
Mar
(459) |
Apr
(352) |
May
(443) |
Jun
(364) |
Jul
(185) |
Aug
(175) |
Sep
(242) |
Oct
(237) |
Nov
(359) |
Dec
(300) |
2014 |
Jan
(331) |
Feb
(272) |
Mar
(446) |
Apr
(301) |
May
(577) |
Jun
(435) |
Jul
(365) |
Aug
(358) |
Sep
(306) |
Oct
(617) |
Nov
(863) |
Dec
(466) |
2015 |
Jan
(295) |
Feb
(165) |
Mar
(319) |
Apr
(201) |
May
(158) |
Jun
(148) |
Jul
(62) |
Aug
(91) |
Sep
(147) |
Oct
(203) |
Nov
(346) |
Dec
(382) |
2016 |
Jan
(242) |
Feb
(280) |
Mar
(229) |
Apr
(157) |
May
(297) |
Jun
(335) |
Jul
(157) |
Aug
(219) |
Sep
(307) |
Oct
(212) |
Nov
(177) |
Dec
(112) |
2017 |
Jan
(100) |
Feb
(203) |
Mar
(112) |
Apr
(124) |
May
(81) |
Jun
(43) |
Jul
(39) |
Aug
(49) |
Sep
(24) |
Oct
(55) |
Nov
(68) |
Dec
(95) |
2018 |
Jan
(130) |
Feb
(73) |
Mar
(47) |
Apr
(57) |
May
(62) |
Jun
(76) |
Jul
(159) |
Aug
(158) |
Sep
(81) |
Oct
(100) |
Nov
(62) |
Dec
(75) |
2019 |
Jan
(130) |
Feb
(138) |
Mar
(80) |
Apr
(61) |
May
(88) |
Jun
(65) |
Jul
(61) |
Aug
(37) |
Sep
(85) |
Oct
(155) |
Nov
(133) |
Dec
(91) |
2020 |
Jan
(59) |
Feb
(123) |
Mar
(121) |
Apr
(155) |
May
(300) |
Jun
(136) |
Jul
(330) |
Aug
(84) |
Sep
(56) |
Oct
(87) |
Nov
(154) |
Dec
(200) |
2021 |
Jan
(205) |
Feb
(203) |
Mar
(292) |
Apr
(165) |
May
(56) |
Jun
(135) |
Jul
(248) |
Aug
(218) |
Sep
(165) |
Oct
(150) |
Nov
(135) |
Dec
(266) |
2022 |
Jan
(194) |
Feb
(149) |
Mar
(49) |
Apr
(38) |
May
(145) |
Jun
(213) |
Jul
(150) |
Aug
(126) |
Sep
(188) |
Oct
(121) |
Nov
(34) |
Dec
(142) |
2023 |
Jan
(105) |
Feb
(82) |
Mar
(138) |
Apr
(125) |
May
(112) |
Jun
(90) |
Jul
(222) |
Aug
(279) |
Sep
(157) |
Oct
(100) |
Nov
(85) |
Dec
(295) |
2024 |
Jan
(123) |
Feb
(353) |
Mar
(155) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <gi...@cr...> - 2024-03-19 05:00:17
|
via 362cfcae2ad6f95cb9e102ab4319368a4d5ae6b0 (commit) from a6a9c15173b0f0bbbadc9db7991ce6bc28d693c6 (commit) ----------------------------------------------------------------------- commit 362cfcae2ad6f95cb9e102ab4319368a4d5ae6b0 Author: Edgar A. Bering IV <tr...@gm...> Date: Mon Mar 18 21:53:14 2024 -0700 docs: clarify the prohibition against wishes (Alkali Man) This sentence in the manual aims to explain why acquirement does not offer wishes, but the wording is confusing for people not coming to crawl from nethack. Re-write it to make it in the positive framing about the randomization of acquirement instead. ----------------------------------------------------------------------- Summary of changes: crawl-ref/docs/crawl_manual.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crawl-ref/docs/crawl_manual.rst b/crawl-ref/docs/crawl_manual.rst index cfc6309506..76c1ad157a 100644 --- a/crawl-ref/docs/crawl_manual.rst +++ b/crawl-ref/docs/crawl_manual.rst @@ -1372,10 +1372,10 @@ Examples for this are the resistances: there are very few permanent sources, most involve a choice (like rings or specific armour) or are only semi-permanent (like mutations). Another example is the absence of clear-cut best items, which comes from the fact that most artefacts are randomly generated. Furthermore, -even non-random artefacts cannot be wished for, as scrolls of acquirement -produce random items in general. Likewise, there are no sure-fire means of life -saving (the closest equivalents are scrolls of blinking, and good religious -standings for some deities). +scrolls of acquirement offer a random selection of items instead of a specific +wish. Likewise, there are no sure-fire means of life saving (the closest +equivalents are scrolls of blinking, and good religious standings for some +deities). Anti-grinding ======================================== -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-19 02:45:19
|
was 28d28ec0cfce781c4ad97ee9278be4eb87e05cea ----------------------------------------------------------------------- 28d28ec0cfce781c4ad97ee9278be4eb87e05cea New Mines enemy: obsidian bat ----------------------------------------------------------------------- -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-19 02:40:19
|
via a6a9c15173b0f0bbbadc9db7991ce6bc28d693c6 (commit) via ec90db9d9c0c489ca2d94fe009f59e046bc9e1b6 (commit) via 03d5c243759842903024d1fe3d723e697b4c05f7 (commit) via 9ccf1647ab71ef40cf840884d4d2de727bcdcd93 (commit) via a2165e0cdb531cc81731a8e1decffc5c4df0dbbd (commit) via 281c7690d9a3f3242da1b51ed295e242a46f4080 (commit) from 33df2375a9eebbd1ff02e02975626d768218fbd3 (commit) ----------------------------------------------------------------------- commit a6a9c15173b0f0bbbadc9db7991ce6bc28d693c6 Author: orjb1 <or...@li...> Date: Mon Mar 18 20:00:56 2024 +0000 Add guarded unrand Arga vault (#3702) [Committer's note: Recoloured the metal in tiles, didn't do much else. Quicksilvers are a good fit together with Arga (fast, non-elemental, Will+ on the axe and scales both), so a straightforward vault's plenty fine. Closes #3702.] commit ec90db9d9c0c489ca2d94fe009f59e046bc9e1b6 Author: regret-index <clo...@ho...> Date: Mon Mar 18 23:47:46 2024 -0230 Throw together a placeholder Permafrost Explosion tile. Mixes together the original RLTiles icon for Shatter, roctavian's icons for Bolt of Cold and Ozocubu's Refridgeration, and ontoclasm's icon for Hailstorm. Should at least emphasize it's an earth spell alongside ice. commit 03d5c243759842903024d1fe3d723e697b4c05f7 Author: regret-index <clo...@ho...> Date: Mon Mar 18 23:39:15 2024 -0230 Decorative boulders -> decorative piles of debris There's been some consternation around the use of unmoving decorative boulders in d9500d9. They list a speed if they actually moved (the speed of BBB's use of the boulder) but don't move in and of themselves, and they also show up in the monster list (because for some reason this isn't innate to firewood). Outside of lingering implementation issues, they're awkwardly not quite as difficult to destroy as bushes but still require manual effort compared to the withering away of plants. They also collected a fairly large amount of confusion and paranoia about them being made to roll in some trap function or another, and while I'd like all of Crawl's unique vault traps to rely on pressure plates eventually (c.f. e446cd8), players will always have some confusion attached to such a re-use. As such, I am replacing most of their uses with an entirely different decorative feature altogether, to fulfill and further extend some of the same spirit of earthen decor beyond different wall and statue tiles or yet more and more piles of large rocks items and stone items around. Piles of debris are meant to fulfill a immotile non-living rubble and ruin position, akin to the expanded uses of pillars of salt. They behaves mostly like plants (in that they will die several turns after being first hit), with some minor tweaks. They have 40% of plant HP but light omniresistance and non-zero AC, which makes it somewhat more plausible for them to be destroyed advance of such collapsing if one can work around those defenses. They count as amphibious, so they can be placed in deep water in vaults for e.g. Shoals and Swamp. Finally, they also collapse into dust (sidestepping the inquiries about it dropping stones or large rocks), which also means a brief cloud of sparse dust when it's destroyed akin to chaos spawn and simulacra. Hopefully, adding what is essentially another type of rare firewood that more specifically implies wrecked ruins rather than overgrown ones shouldn't raise the same issues re-using spell boulders did. Their name and description are ironically enough somewhat up in the air: I'm somewhat dissatisfied with both, and other devs may find-replace a better name as long as the intent of "half-broken stonework" survives. The tiles use a mix of the RLTiles earth magic spell icons (Sandblast, Passwall, LRD, Shatter) and PleasingFungus's original placeholder tile for rockslimes. Possibly some recolours would be reasonable for making them fit into Slime or Desolation too, though I'm a little cautious about spreading firewood a little too far in the broader scope of things. commit 9ccf1647ab71ef40cf840884d4d2de727bcdcd93 Author: regret-index <clo...@ho...> Date: Fri Mar 15 22:13:30 2024 -0230 New Mines enemy: obsidian bat Obsidian bats in both name and form are meant to further emphasize the cave parts of the Orcish Mines, as well as emphasis the varied demonic threat attached to both orc high priests and orc sorcerers. Aside from these fits, they're also meant to punish how it's regularly easy (and slow) to flee across the Orc:$ level away from the endvault unless a summoner rolls the faster demons, a sorcerer rolls on paralysis, or the player's actually weak enough to care much about (even post-buff) wargs post-Lair. They're non-living faceless bats with rF++ that have a derivative of the broodmother special- a AF_HELL_HUNT that summons either hell hounds or hell rats on hit 66% of the time, capped at 3 out at once. They're quite a ways weaker than broodmothers otherwise- in stats and damage somewhere between unseen horrors and wargs, or possibly a blink frog band with heavy resists if the player has no EV. Still, by being batty, they regularly step away from the player to let their summons get in the way, a distinguishing feature for a summoner that will probably also rather vex players. Their defenses are probably their most notable feature- with passable AC and EV on top of resists- but by the time one enters Orc a god or floor drops should allow even alchemists to have some other option when facing them. These spawn alone by themselves, taking a small chunk out of wargs as we currently can't adjust due to CCF and ogres as people see plenty of much earlier than Orc. (Possibly we should consider lowering Orc's monster count the same way Lair does to handle the two new Orc enemies being a little stronger than the average normal spawn.) A couple of thematically appropriate demonic and lava orc vaults and ends place them, one of the Volcano sets uses them on rare occasion, and they take yet another (much smaller) slice out of Abyss abominations. Since we've got a lot of demons already, I'd prefer these to stay relatively early and fire-centered rather than used freely in most other vaults otherwise- anything that escaped out of Hell from which pours out Hell itself should be a little special. Their tile is by Sastreii. commit a2165e0cdb531cc81731a8e1decffc5c4df0dbbd Author: regret-index <clo...@ho...> Date: Thu Mar 14 19:19:07 2024 -0230 Recentish tile / decor adjustments * Porkolator: A border fix plus hex sparkles so it's not just A Pig. * Fathomless Shackles: Chain tweaks to emphasize their size in contrast to the smaller chains of Bind Soul. * Canine Familiar: A quick recolour to use the inugami's palette. * Coglin Gizmos: Chroma adjustments to help move the purple-pink-red options away from one another. * Scintillating statues: Animate them far less often, and tweak a placement, since they're evidently very distracting as entirely decorative features. commit 281c7690d9a3f3242da1b51ed295e242a46f4080 Author: regret-index <clo...@ho...> Date: Thu Mar 14 17:59:44 2024 -0230 Another small vault batch Really should clean out more of my drafts files at some later point. * Two Abyss entries, with thematically appropriate and Depths appropriate spawns, meant to vary up Abyss entries since mostly don't have enemies attached to them compared to the Pan and Hells entries. * A decorative Snake vault, trying to help reach the higher Snake decor count needed to make them always appear on Snake:$ to help vary up those floors more tangibly. * A couple more removed vault layouts revamped for other uses. A volcano layout used for a game-wide fire and earth vault, a dwarf vault used for another misc_elf_vault, and a Zotdef layout used for a Zot stairs vault. Would be nice to convert another two layouts of Zotdef into stair vaults with the same monster set set-up, eventually. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/dat/database/monspeak.txt | 8 + crawl-ref/source/dat/des/altar/ecumenical.des | 4 +- crawl-ref/source/dat/des/altar/overflow.des | 21 +-- crawl-ref/source/dat/des/branches/abyss.des | 66 ++++++++- crawl-ref/source/dat/des/branches/elf.des | 43 +++++- crawl-ref/source/dat/des/branches/lair.des | 16 +- crawl-ref/source/dat/des/branches/orc.des | 85 +++++------ crawl-ref/source/dat/des/branches/shoals.des | 81 +++++----- crawl-ref/source/dat/des/branches/snake.des | 30 ++++ crawl-ref/source/dat/des/branches/swamp.des | 58 +++++--- crawl-ref/source/dat/des/branches/tomb.des | 2 +- crawl-ref/source/dat/des/branches/zot.des | 78 +++++++++- crawl-ref/source/dat/des/builder/shops.des | 8 +- crawl-ref/source/dat/des/builder/uniques.des | 3 +- crawl-ref/source/dat/des/portals/volcano.des | 50 ++++--- crawl-ref/source/dat/des/portals/ziggurat.des | 11 +- crawl-ref/source/dat/des/serial/column_ruins.des | 4 +- crawl-ref/source/dat/des/serial/magic_research.des | 3 +- crawl-ref/source/dat/des/sprint/arena_sprint.des | 2 +- crawl-ref/source/dat/des/variable/float.des | 30 ++-- crawl-ref/source/dat/des/variable/large_themed.des | 164 ++++++++++++++++++++- .../source/dat/des/variable/lemuel_castle.des | 4 +- .../source/dat/des/variable/mini_features.des | 12 +- .../source/dat/des/variable/mini_monsters.des | 54 +++++-- crawl-ref/source/dat/descript/features.txt | 2 +- crawl-ref/source/dat/descript/monsters.txt | 11 ++ crawl-ref/source/dat/mons/obsidian-bat.yaml | 18 +++ crawl-ref/source/dat/mons/pile-of-debris.yaml | 16 ++ crawl-ref/source/describe.cc | 3 + crawl-ref/source/melee-attack.cc | 13 ++ crawl-ref/source/mon-death.cc | 8 + crawl-ref/source/mon-ench.cc | 3 + crawl-ref/source/mon-enum.h | 1 + crawl-ref/source/mon-pick-data.h | 20 +-- crawl-ref/source/monster-type.h | 4 + crawl-ref/source/monster.cc | 2 + crawl-ref/source/rltiles/dc-feat.txt | 3 +- crawl-ref/source/rltiles/dc-mon.txt | 5 +- crawl-ref/source/rltiles/dc-spells.txt | 7 +- .../gui/invocations/yred_fathomless_shackles.png | Bin 8125 -> 7831 bytes .../rltiles/gui/spells/ice/permafrost_eruption.png | Bin 0 -> 8751 bytes .../rltiles/gui/spells/monster/porkalator.png | Bin 7118 -> 8587 bytes .../gui/spells/summoning/call_canine_familiar.png | Bin 375 -> 7513 bytes crawl-ref/source/rltiles/item/gizmo/gizmo0.png | Bin 7333 -> 1159 bytes crawl-ref/source/rltiles/item/gizmo/gizmo1.png | Bin 7374 -> 1213 bytes crawl-ref/source/rltiles/item/gizmo/gizmo3.png | Bin 7409 -> 1197 bytes crawl-ref/source/rltiles/item/gizmo/gizmo4.png | Bin 7851 -> 1231 bytes crawl-ref/source/rltiles/item/gizmo/gizmo5.png | Bin 7486 -> 1252 bytes crawl-ref/source/rltiles/item/gizmo/gizmo6.png | Bin 7558 -> 1264 bytes crawl-ref/source/rltiles/item/gizmo/gizmo7.png | Bin 7487 -> 1264 bytes crawl-ref/source/rltiles/item/gizmo/gizmo8.png | Bin 7802 -> 1227 bytes crawl-ref/source/rltiles/item/gizmo/gizmo9.png | Bin 1648 -> 1636 bytes .../animals/obsidian_bat.png} | Bin 22986 -> 23612 bytes .../rltiles/mon/statues/pile_of_debris_00.png | Bin 0 -> 7524 bytes .../rltiles/mon/statues/pile_of_debris_01.png | Bin 0 -> 7778 bytes crawl-ref/source/spl-damage.cc | 3 + crawl-ref/source/spl-data.h | 2 +- crawl-ref/source/spl-summoning.cc | 25 ++++ crawl-ref/source/spl-summoning.h | 1 + crawl-ref/source/util/monster/monster-main.cc | 3 + 60 files changed, 773 insertions(+), 214 deletions(-) create mode 100644 crawl-ref/source/dat/mons/obsidian-bat.yaml create mode 100644 crawl-ref/source/dat/mons/pile-of-debris.yaml create mode 100644 crawl-ref/source/rltiles/gui/spells/ice/permafrost_eruption.png copy crawl-ref/source/rltiles/{dngn/floor/depthstone_floor0.png => mon/animals/obsidian_bat.png} (90%) create mode 100644 crawl-ref/source/rltiles/mon/statues/pile_of_debris_00.png create mode 100644 crawl-ref/source/rltiles/mon/statues/pile_of_debris_01.png diff --git a/crawl-ref/source/dat/database/monspeak.txt b/crawl-ref/source/dat/database/monspeak.txt index cb260c0d88..3b7b3f7702 100644 --- a/crawl-ref/source/dat/database/monspeak.txt +++ b/crawl-ref/source/dat/database/monspeak.txt @@ -7486,6 +7486,14 @@ moth of wrath VISUAL:@The_monster@ angrily waves @possessive@ antennae. %%%% +################## Obsidian bat ############################ +obsidian bat + +VISUAL:@The_monster@ flits into the dungeon's darkness for a moment. + +w:40 +__NONE +%%%% ################## Obsidian statue ######################### default obsidian statue diff --git a/crawl-ref/source/dat/des/altar/ecumenical.des b/crawl-ref/source/dat/des/altar/ecumenical.des index 322a637661..ca9bf8ed2e 100644 --- a/crawl-ref/source/dat/des/altar/ecumenical.des +++ b/crawl-ref/source/dat/des/altar/ecumenical.des @@ -372,7 +372,7 @@ NAME: shapermc_ecumenical_altar_hornbeckon TAGS: transparent KMONS: p = plant KMONS: f = fungus -KMONS: B = boulder dbname:still_boulder +KMONS: B = pile of debris NSUBST: ' = 8:pf / 12=ppf... / . SUBST: G = GGB : ecumenical_altar_setup(_G) @@ -857,7 +857,7 @@ MONS: orc : else MONS: rat / giant cockroach / dart slug : end -KMONS: d = boulder dbname:still_boulder / nothing w:30 +KMONS: d = pile of debris / nothing w:30 KITEM: d = human skeleton / kobold skeleton / elf skeleton / gnoll skeleton / \ ogre skeleton / naga skeleton / minotaur skeleton / \ merfolk skeleton / tengu skeleton / draconian skeleton diff --git a/crawl-ref/source/dat/des/altar/overflow.des b/crawl-ref/source/dat/des/altar/overflow.des index 9f03b9a71a..fe9f42d097 100644 --- a/crawl-ref/source/dat/des/altar/overflow.des +++ b/crawl-ref/source/dat/des/altar/overflow.des @@ -2265,14 +2265,16 @@ ENDMAP NAME: nicolae_qazlal_general_emergency TAGS: temple_overflow_qazlal temple_overflow_1 uniq_altar_qazlal TAGS: no_monster_gen no_pool_fixup transparent decor no_descent +KMONS: 1 = pile of debris +KFEAT: B = altar_qazlal +KFEAT: 1 = w SHUFFLE: xXY / xXY / xXY / abc SHUFFLE: XY -SUBST: z = w.., X = +++w., Y = xxxxw., x = wxxx, a = w, b = w, c = w +SUBST: z = w.., X = +++w., Y = 11xxw., x = wxxx, a = w, b = w, c = w SHUFFLE: ABCD SUBST: A = >, C = 'GTU, D = ' -KFEAT: B = altar_qazlal +SHUFFLE: 1w / ll / ll KMASK: B>'GTU = opaque -SHUFFLE: wll : interest_check(_G) MAP ...........z. @@ -3565,12 +3567,13 @@ NAME: regret_index_xom_buried_treasure TAGS: transparent temple_overflow_1 temple_overflow_xom TAGS: uniq_altar_xom extra decor ITEM: stone q:1 no_pickup -KMONS: ! = boulder dbname:still_boulder +KMONS: ! = pile of debris KITEM: ! = plate armour randart plus:-12 ident:all / \ kite shield randart plus:-12 ident:all / mundane club w:9980 KITEM: ? = mundane club / gold q:1 w:9970, large rock q:1 KFEAT: _ = altar_xom -SUBST: b : bcc, y : xx., z : xx., Y : xxd, Z : xxd, ? = ! +SHUFFLE: ?" / ?" / !! +SUBST: b : bcc, y : xx., z : xx., Y : xxd, Z : xxd, " = . MAP xx@. ..xx xbx...zbx @@ -3579,9 +3582,9 @@ xbx...zbx ..xxx..@ ..xxYxx.xxxxx @xxx.xccccccx -xbx...cxdd_cx +xbx...cx"d_cx xx..Z.cdx?dcx - ..+ddxdcx@..xx + ..+ddx"cx@..xx .cdddxc...xbx .cc+cccx.xxx. @.....xxYxx.. @@ -4456,12 +4459,12 @@ NAME: grunt_temple_overflow_forces_of_nature TAGS: temple_overflow_2 temple_overflow_fedhas temple_overflow_qazlal TAGS: transparent MONS: fungus / plant / bush +KMONS: D = pile of debris SUBST: 2 = 1. KFEAT: _ = altar_fedhas KFEAT: O = altar_qazlal KPROP: 12Ll = no_tele_into -SUBST: L = ll^. -SUBST: l = cll. +SUBST: L = ll^., l = cll., c : cD : if you.depth() ~= dgn.br_depth(you.branch()) then KFEAT: ^ = shaft trap : end diff --git a/crawl-ref/source/dat/des/branches/abyss.des b/crawl-ref/source/dat/des/branches/abyss.des index d399e3d2b3..8d769c2839 100644 --- a/crawl-ref/source/dat/des/branches/abyss.des +++ b/crawl-ref/source/dat/des/branches/abyss.des @@ -182,6 +182,64 @@ MAP ...... ENDMAP +NAME: regret_index_abyss_entry_already_here +TAGS: nolayout_encompass transparent no_monster_gen patrolling +WEIGHT: 5 +MONS: tentacled monstrosity / lich, glowing shapeshifter, glass eye +NSUBST: 1 = 1:1 / 1:2 / 1:3 / *:., b = 1:O / *:b +TILE: b = bedeviled_crystal_abyss +: set_feature_name("crystal_wall", "bedeviled crystal wall") +: abyss_entry(_G, 'O') +MAP + ..xxx.. +x.x...x.. +.x..b..x. +..x..1x...xxx... + ..xxx...x...x.x + ......x..b..x. + .......x1..x.. + ..xxx....xxx.. +..x..1x....... +.x..b..x...... +x.x...x...xxx.. +...xxx...x1..x.. + .x..b..x. + ..x...x.x + ..xxx... +ENDMAP + +NAME: regret_index_abyss_entry_earlier_magic +TAGS: nolayout_encompass transparent +MONS: occultist, rakshasa, glowing orange brain +KFEAT: G = metal_statue +SUBST: - : xc++., 0 = 123, D : x.., E : x.. +SHUFFLE: AO +COLOUR: G = warp +TILE: G = dimensional_conduit +: set_feature_name("metal_statue", "dimensional conduit") +: abyss_entry(_G, 'O') +MAP + x...@..xx.. + xxx....xx....@ + xx.xx..cc...... + xx...xx++........ +xx..D..+-+..E...xxx +.x.....++xx....xxAx +..x...cc..x...xx0.x + ..x.xx...xx.xx1..x + @..xx..G..xxx....x + .x2.....+.....3x. + x....xxx..G..xx..@ + x..1xx.xx...xx.x.. + x.0xx...x..cc...x.. + xOxx....xx++.....x. + xxx...E..+-+..D..xx + ........++xx...xx + ......cc..xx.xx + @....xx....xxx + ..xx..@...x +ENDMAP + ############################################################################### # abyss random vaults ############################################################################### @@ -428,7 +486,7 @@ ENDMAP NAME: hangedman_abyss_feature_spike TAGS: extra no_item_gen no_pool_fixup allow_dup -MONS: fungus, plant, bush +MONS: fungus, plant, bush, pile of debris ITEM: stone q:1, large rock q:1, human skeleton KFEAT: - = altar_lugonu KMASK: wWl = no_monster_gen @@ -439,7 +497,7 @@ SHUFFLE: JKLMN / JJJJJ / JJJJJ / JJJJJ / JJJJJ / JKLKJ / JKJKJ / JJLMM / JJLMM SHUFFLE: OPQRS / OOOOO / OOOOO / OOOOO / OOOOO / OPQPO / OPOPO / OOQRR / OOQRR SUBST: g = C, h = T, i = U, j = V SUBST: o = t, p = G, q = w, r = W, s = l -SUBST: J = x, K = c, L = v, MN = m, O = 1, P = 2, Q = 3, RS = b +SUBST: J = x, K = c, L = v, MN = m, O = 1, P = 2, Q = 3, R = 4, S = b CLEAR: - SHUFFLE: AACCTTUUVYYdeefghi, tGGwWlI, xxccvvbbmm+123 MAP @@ -542,8 +600,8 @@ MAP ENDMAP NAME: hangedman_abyss_batty_box -MONS: bat / fire bat / vampire bat, butterfly, hellwing -MONS: spatial vortex, sky beast, harpy, unseen horror +MONS: fire bat / vampire bat, butterfly, hellwing +MONS: spatial vortex, sky beast, obsidian bat, unseen horror KMONS: 8 = wind drake perm_ench:glowing_shapeshifter KITEM: 8 = rapier ego:electrocution randart / \ staff of air / cloak good_item diff --git a/crawl-ref/source/dat/des/branches/elf.des b/crawl-ref/source/dat/des/branches/elf.des index a87bde7de3..73fc348925 100644 --- a/crawl-ref/source/dat/des/branches/elf.des +++ b/crawl-ref/source/dat/des/branches/elf.des @@ -1686,7 +1686,7 @@ ENDMAP NAME: nicolae_elf_deep_mausoleum TAGS: transparent patrolling no_monster_gen DEPTH: Elf -KMONS: B = boulder dbname:still_boulder +KMONS: B = pile of debris KITEM: S = large rock q:1 / stone KITEM: % = % / * w:5 KITEM: * = * / | w:5 @@ -2026,6 +2026,47 @@ xxc...cxx @@@ ENDMAP +# Layout modified from the long-gone evilmike_dwarf_pyromaniacs. +NAME: regret_index_elf_centigrade +TAGS: no_monster_gen no_pool_fixup misc_elf_vault +DEPTH: Elf +MONS: fire elemental, dancing weapon ; short sword ego:freezing +MONS: deep elf pyromancer, deep elf knight, thermic dynamo +ITEM: ring of fire, ring of ice +ITEM: staff of fire no_pickup, staff of cold no_pickup +KFEAT: - = closed_clear_door +KFEAT: G = metal_statue +SUBST: 0 = 12, 9 = 33344455 +SHUFFLE: df, df / eg +: if crawl.coinflip() then +SUBST: ! = l, ? = G, ~ = w +TILE: G = icy_conduit +: set_feature_name("metal_statue", "icy conduit") +: else +SUBST: ! = G, ? = w, ~ = l +TILE: G = fiery_conduit +: set_feature_name("metal_statue", "fiery conduit") +: end +MAP + xxxxxxxx + x!x...$x + xx...x3xxxx + x....1.xxxx + x...1x---xxxxx + x...xxxx..x0dx +xxxxx+xxb.xx..fxxxxx +@......xx..x$.9xbbbx +....0x.+..5x%5.5-~bx +@......xx..x$.9xbbbx +xxxxx+xxb.xx..dxxxxx + x...xxxx..x0fx + x...2x---xxxxx + x....2.xxx + xx...x4x + x?x...$x + xxxxxxxx +ENDMAP + ############################################################################## # # <<4>> Elf:2 Hall of Blades entry vaults. diff --git a/crawl-ref/source/dat/des/branches/lair.des b/crawl-ref/source/dat/des/branches/lair.des index 43e57a50b0..1e976f3173 100644 --- a/crawl-ref/source/dat/des/branches/lair.des +++ b/crawl-ref/source/dat/des/branches/lair.des @@ -2238,8 +2238,10 @@ NAME: kennysheep_abandoned_house TAGS: ruin transparent DEPTH: Lair MONS: rat, river rat, hell rat +KMONS: D = pile of debris KITEM: d = gold -NSUBST: d = 1:d / 1:* / 1:9 / 1:3 / * = d11223....... +KFEAT: C = cache of fruit +NSUBST: d = 1:d / 1:C / 1:* / 1:9 / 1:3 / * = d11223......., c = 5:Dc / *:c MAP ....... .......ccccc......... @@ -2288,8 +2290,10 @@ ENDMAP NAME: kennysheep_basilisk_garden TAGS: transparent DEPTH: Lair:3- -MONS: basilisk -NSUBST: . = 2:1 / 3 = 111G / *:. +MONS: basilisk, pile of debris +NSUBST: . = 2:1 / 3 = 11G / *:., G = 2:G2 / *:G +TILE: G = dngn_statue_axe / dngn_statue_cat / dngn_statue_centaur / \ + dngn_statue_dwarf / dngn_statue_polearm / dngn_statue_tengu MAP ..... ....G.... @@ -2504,10 +2508,10 @@ NAME: minmay_guarded_unrand_snakebite TAGS: ruin DEPTH: Lair ORIENT: southeast -ITEM: snakebite no_pickup KMONS: A = adder KMONS: B = water moccasin KMONS: C = black mamba +ITEM: snakebite no_pickup SUBST: 1 = A B:2 .:48, 2 = A B:5 .:60, 3 = A B C:2 .:88, 4 = A:2 B C:4 .:64 SUBST: 5 = A:1 B C .:84, 6 = B:5 C .:60, 7 = B. MAP @@ -2708,8 +2712,8 @@ ENDMAP NAME: nicolae_lair_lil_pond TAGS: transparent ruin decor extra DEPTH: Lair -NSUBST: D = . / x -SUBST: - = . / W +NSUBST: D = 1:. / *:x +SUBST: - = .W MAP ............ ....xxxx.... diff --git a/crawl-ref/source/dat/des/branches/orc.des b/crawl-ref/source/dat/des/branches/orc.des index 73d03e0725..6dde6dc77c 100644 --- a/crawl-ref/source/dat/des/branches/orc.des +++ b/crawl-ref/source/dat/des/branches/orc.des @@ -560,12 +560,11 @@ ENDMAP NAME: nicolae_orc_tapped_out TAGS: no_item_gen no_trap_gen luniq_orc_cave DEPTH: Orc -MONS: boulder dbname:still_boulder ITEM: stone q:1 / large rock q:1 w:3 / gold q:1 w:3 KFEAT: ^ = shaft trap SUBST: X = 'xx, ' = .:5 d:4 ^:1 : if you.depth() == dgn.br_depth(you.branch()) then -SUBST: ^ = 1:5 d:4 +SUBST: ^ = .:5 d:4 : end MAP xxx. @@ -761,10 +760,9 @@ ENDMAP NAME: nicolae_orc_rockfall TAGS: transparent extra decor no_item_gen DEPTH: Orc -MONS: boulder dbname:still_boulder ITEM: stone q:1, stone q:2, large rock q:1 : dgn.delayed_decay_extra(_G, 'o', 'orc corpse', 'stone q:1, large rock q:1') -NSUBST: R = 2:11f / * = ddeef, r = 1:d / * = d .:5 f:3 +NSUBST: R = 1:f / * = ddeef, r = 1:d / * = d .:5 f:3 MAP ..... ..rrr.. @@ -794,11 +792,10 @@ MAP ...xxxxxx ENDMAP -NAME: nicolae_orc_stony_grotto -TAGS: extra decor transparent +NAME: nicolae_orc_stony_grotto +TAGS: extra decor transparent DEPTH: Orc -MONS: boulder dbname:still_boulder -SUBST: X = xxxc...., C = x1cc, D = ..1c +SUBST: X = xxxc...., C = xc, D = ...c MAP @Cxxxx @..xCcxxxx @@ -1073,11 +1070,11 @@ ENDMAP # mage tower -- either orc with assistants, or ogre with guards NAME: mines4_lemuel TAGS: no_rotate -SUBST: d = $d -SUBST: I = IG -SHUFFLE: 112/334 -MONS: orc sorcerer, orc / orc wizard, ogre mage, ogre / nothing +MONS: orc sorcerer, orc / orc wizard, ogre mage, two-headed ogre / ogre w:15 ITEM: any book +SHUFFLE: 12 / 34 +SUBST: d = $d, I = IG +NSUBST: 4 = 3:4 / 2:. / * = 4. MAP xxxx@xxxx xx2.....2xx @@ -1149,13 +1146,15 @@ ENDMAP ################################### # treasure chamber # -NAME: mines2_lemuel +NAME: mines2_lemuel +KMONS: 1 = obsidian bat +KFEAT: 1 = lava SUBST: ? = x@ MAP ?x+x? - ?xx.xx? -?xx$$$xx? + ?xx$xx? ?xx$$$xx? +?xx$1$xx? ?xxxxx? ??? ENDMAP @@ -1387,7 +1386,7 @@ ENDMAP NAME: guppyfry_orc_lava_fort TAGS: no_item_gen no_monster_gen transparent DEPTH: Orc -MONS: orc high priest / orc sorcerer, orc knight +MONS: orc high priest / orc sorcerer, orc knight / obsidian bat w:2 MONS: orc warrior / kobold blastminer w:2 MONS: orc wizard, orc priest, orc, warg KMONS: 8 = ogre / two-headed ogre / troll / deep troll / ogre mage @@ -1413,13 +1412,12 @@ ENDMAP NAME: blackcustard_mines_bat_river TAGS: no_item_gen no_monster_gen no_pool_fixup DEPTH: Orc -MONS: bat, kobold blastminer +MONS: bat, obsidian bat, kobold blastminer MONS: generate_awake orc ; shortbow ego:flaming | shortbow ego:freezing | \ shortbow ego:heavy -NSUBST: . = 1:2 / 2:3 / 2:c -NSUBST: c = *: 2 . +NSUBST: . = 1:3 / 2:4 / 2 : 4. # There were arrows here. They're gone now. Sorry -NSUBST: b = 3:1 / 10:d / 4:e / *: .:20 1:1 d:2 e:2 +NSUBST: b = 3:1 / 1:2 / 10:d / 4:e / *: .:20 1:1 d:2 e:2 : dgn.delayed_decay(_G, 'e', 'bat corpse') SHUFFLE: ABC SUBST: A = @ @@ -1645,15 +1643,17 @@ xxx..@..xxx ENDMAP NAME: nicolae_orc_all_along_the_watchtower -TAGS: transparent no_descent +TAGS: transparent no_descent patrolling DEPTH: Orc, !Orc:$ WEIGHT: 5 KMONS: 1 = orc wizard / orc priest KMONS: 2 = orc warrior ; chain mail | plate armour . arbalest | longbow +KMONS: 3 = obsidian bat +KFEAT: 3 = l KFEAT: - = iron_grate SHUFFLE: c1, !I, -Ic` SUBST: } = }]), ! = 1 -NSUBST: 1 = 2:1 / 2:2 / 2 = 12``` / ` +NSUBST: 1 = 2:1 / 2:2 / 2 = 12``` / `, l = 1:3l / *:l KPROP: l = no_cloud_gen KMASK: `Ic-}])12 = opaque KMASK: `Ic-}])12 = no_monster_gen @@ -1849,16 +1849,19 @@ PLACE: Orc:$ ORIENT: float MONS: orc, orc wizard, orc sorcerer MONS: orc priest, orc high priest, orc warrior +KMONS: 7 = obsidian bat +KFEAT: 7 = lava KFEAT: S = any shop -SHUFFLE: 23 / 45 -SUBST: 1 = 11., 2 = 22., 4 = 44. +SHUFFLE: 23 / 45, 7l / "" +SUBST: 1 = 111.., 2 = 222.., 4 = 444.. +KPROP: 7l = no_cloud_gen MAP ................... ...ccccccccccccccc... ...cc4.4...6...4.4cc... ..cc4.2.4..6..4.2.4cc.. ..c2.4.2.ccccc.2.4.2c.. -..c.2.2.2.c.c.2.2.2.c.. +..c.2.2.2.clc.2.2.2.c.. ..c..2.2c.....c2.2..c.. ..c...2ccc.3.ccc2...c.. ..c..c..c5....c..c..c.. @@ -1868,7 +1871,7 @@ MAP ..c..c..c....5c..c..c.. ..c...2ccc.3.ccc2...c.. ..c..2.2c.....c2.2..c.. -..c.2.2.2.c.c.2.2.2.c.. +..c.2.2.2.c7c.2.2.2.c.. ..c2.4.2.ccccc.2.4.2c.. ..cc4.2.4..6..4.2.4cc.. ...cc4.4...6...4.4cc... @@ -2173,15 +2176,14 @@ ENDMAP NAME: grunt_orc_community_house_1 TAGS: grunt_orc_community_house allow_dup transparent no_monster_gen TAGS: no_item_gen -MONS: orc warrior / orc priest / orc wizard, orc -SHUFFLE: def, I_ / I- / -_ / _- / -I -SUBST: d = +, ef = c, 2 = 2. -KFEAT: - = floor +MONS: obsidian bat, warg KFEAT: _ = altar_beogh +SHUFFLE: def, I_ / I- / -_ / _- / -I, 1l / 1l / 0' +SUBST: d = +, ef = c, 2 = 2., - = . MAP ....... .ccccc. -.c1_1c. +.c1_lc. .c2I2c. .c.2.c. .cdefc. @@ -2237,11 +2239,10 @@ ORIENT: float MONS: orc knight, orc high priest, orc sorcerer / ogre mage w:2 MONS: orc warrior / kobold blastminer w:4 / two-headed ogre w:2 MONS: orc priest, orc wizard, orc +ITEM: yak skeleton, wyvern skeleton +KFEAT: A = any shop MARKER: O = lua:fog_machine { cloud_type='flame', pow_min = 10, pow_max = 10, \ delay = 10, size = 1, excl_rad = 0 } -ITEM: yak skeleton -ITEM: wyvern skeleton -KFEAT: A = any shop MAP ccccccc cce.6.5ccc @@ -2315,7 +2316,7 @@ ORIENT: float MONS: orc / nothing w:6, orc warrior / nothing w:6 MONS: orc priest / nothing w:6, common demon / nothing w:6 MONS: orc knight / kobold blastminer w:1 -MONS: demonspawn / nothing w:6 +MONS: demonspawn / obsidian bat w:2 / nothing w:8 MONS: orc high priest / orc sorcerer KFEAT: A = w:20 general shop / distillery shop / scroll shop KFEAT: B = book shop / jewellery shop @@ -2362,9 +2363,10 @@ NAME: kennysheep_orc_mage_school TAGS: patrolling no_item_gen no_monster_gen PLACE: Orc:$ ORIENT: float -MONS: orc sorcerer / ogre mage w:2, orc wizard, orc / ogre +MONS: orc sorcerer / ogre mage w:2, orc wizard, orc / ogre w:12 KMONS: 4 = Erolcha / ogre mage, ogre mage KMONS: 5 = Nergalle / orc sorcerer, orc sorcerer +KMONS: 6 = obsidian bat KFEAT: A = distillery shop / scroll shop KFEAT: B = book shop / jewellery shop KFEAT: C = antique weapon shop / antique armour shop @@ -2372,7 +2374,7 @@ KFEAT: D = altar_beogh KFEAT: E = altar_kikubaaqudgha KFEAT: F = altar_vehumet KFEAT: mn = rock_wall -NSUBST: . = 8:1 / 18:2 / 10:3 +NSUBST: . = 8:1 / 16:2 / 8:3, 6 = 1:6 / 1:6. / *:. NSUBST: Y = 1:A / 1:B / 1:C / 1:ABC / *:I COLOUR: n = black TILE: n = wall_hall_darkgray @@ -2386,7 +2388,7 @@ MAP lllccllllllll...cc...llbbcc llllcccI.lll....+..Immmlbbc llccc.........I.c....Fmllbc - lllc.............+.....m.lbccccc + lllc.............+.....m6lbccccc llcc..lll...lll..c.....I.lccbbbcccc ''''' llcY.cbbbc..lccccc......4ccbbYbbbbcc ''''''''' llcc..lll...lcbbbc......cclll.lllbbcc @@ -2395,7 +2397,7 @@ MAP ''''''cc''cc'lcclllcccc...lcI...ll..c...I.l.l.I.llbc ''''''''''''''llllllll....lc...cbl..c....ll.ll...lbcc '''''''''''''''''''.......lc...cbl..+...ll...ll..lbbc -@'''''''''''''''''''...I..lcY..cbl..+..Il..D...I..Ybc +@'''''''''''''''''''...I..lcY.6cbl..+..Il..D...I6.Ybc '''''''''''''''''''.......lc...cbl..+...ll...ll..lbbc ''''''''''''''llllllll....lc...cbl..c....ll.ll...lbcc ''''''cc''cc'lcclllcccc...lcI...ll..c...I.l.l.I.llbc @@ -2404,7 +2406,7 @@ MAP ''''''''' llcc..lll...lcbbbc......cclll.lllbbcc ''''' llcY.cbbbc..lccccc......5ccbbYbbbbcc llcc..lll...lll..c.....I.lccbbbcccc - lllc.............+.....n.lbccccc + lllc.............+.....n6lbccccc llccc.........I.c....Enllbc llllcccI.lll....+..Innnlbbc lllccllllllll...cc...llbbcc @@ -2425,6 +2427,7 @@ MONS: orc priest, orc warrior, orc warrior band MONS: ogre w:8 / two-headed ogre w:4 / kobold blastminer w:4 / \ troll w:1 / warg w:1 / nothing w:8 MONS: orc knight, orc sorcerer +KMONS: 8 = obsidian bat KMONS: D = orc high priest KMONS: E = Saint Roka band w:1 / orc warlord band, orc warlord band KMONS: P = plant / nothing @@ -2503,7 +2506,7 @@ xxxvvv$$$vxc.ccccc..0..c....$..xxxxxwwxwwwwxwwwxwwxxxxxxxxxxxxxxxxxxx xxxxxvvvvvxc.c...c.....c..xxx...xxxxxxwwwxxxwwwwwxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxc.c2.0ccc+cccccccccccccxxxxxwwwxwwwwwxxxxxxxxxxxxxxxxxxxxx xxxxxccccccc.+._.+.........+.....cccccccwwwwwwwxxxxxxxxxxxxxxxxxxxxxx -xxxxxllll0.ccc2.0c.cc+ccc+cc.....c.0Wwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxllll8.ccc2.0c.cc+ccc+cc.....c.0Wwwwwwwwxxxxxxxxxxxxxxxxxxxxxxxxx xlxxlllll..+.c...c.c...c...c.....+..WWwwwwwxxxxxxxxxxxxxxxxxxxxxxxxxx xxlllllll0.c.cc+cc.c0.0c0.0ccccccc.0Wwwwxxxwwxxxxxxxxxxxxxxxxxxxxxxxx xllllccccccc.......cs6.c.6scxxxxccccccccxxxxwxxxxxxxxxxxxxxxxxxxxxxxx diff --git a/crawl-ref/source/dat/des/branches/shoals.des b/crawl-ref/source/dat/des/branches/shoals.des index 8c08c7fc6e..3c2f714c7f 100644 --- a/crawl-ref/source/dat/des/branches/shoals.des +++ b/crawl-ref/source/dat/des/branches/shoals.des @@ -861,18 +861,17 @@ ENDMAP # NAME: overgrown_hall WEIGHT: 2 -MONS: plant, fungus +MONS: plant, fungus, pile of debris MONS: cyclops / stone giant w:2 -SUBST: x = x:20 . -SUBST: G = G:40 . +SUBST: x = xx., G = GG33. SUBST: . = .:90 1:19 x:1 -SUBST: 1 = 1 2:1 +SUBST: 1 = 1 2:1, ' = . MAP xxxxxxxxxxx x.........x -x.G.G.G.G.x -+....3....+ -x.G.G.G.G.x +x.G'G.G'G.x ++''.'4'.'.+ +x.G'G.G'G.x x.........x xxxxxxxxxxx ENDMAP @@ -986,9 +985,10 @@ TAGS: no_pool_fixup MONS: cyclops, frost giant, stone giant KMONS: P = plant KMONS: f = fungus +KMONS: D = pile of debris KFEAT: Pfp = shallow_water -KFEAT: 5 = deep_water -SUBST: p = ppWw, p = Pf, y = xxxxcccPPPfw, f = PPwW, x = x:10 c:1 +KFEAT: D5 = deep_water +SUBST: p = ppWw, p = Pf, y = xxxcccPPfDDw, f = PPwW, x = x:10 c:1 SHUFFLE: 23 SUBST: 2 = 2:15 1:10, 3 = 3:15 1:10 MAP @@ -1050,13 +1050,15 @@ KMONS: 6 = cyclops KMONS: 7 = stone giant KMONS: 8 = frost giant KMONS: 9 = titan -KFEAT: 123456789 = deep_water +KMONS: D = pile of debris +KFEAT: 123456789D = deep_water KITEM: | = | KITEM: * = * KFEAT: |* = shallow_water SHUFFLE: 12345 / 86769 NSUBST: Z = 1:w / *:c -SUBST: G = GGGwwW, 7 = 667, 8 = 688, 9 = 7899, x = c +SUBST: G = GGDwwW, 7 = 667, 8 = 688, 9 = 7899, x = c +KPROP: |* = no_tele_into MAP xxxxxxxxxxx xxGxGxGxGxGxx @@ -1343,23 +1345,26 @@ xxr----WWmwW--rx xxxxxxxx ENDMAP -NAME: wheals_shoals_ruined_temple -TAGS: water_ok -DEPTH: Shoals, !Shoals:$ -KPROP: c.GWuw1 = no_tide -KMONS: 1 = kraken -KFEAT: 1 = w -SUBST: u = Ww -SUBST: . = .:500 0 +NAME: wheals_shoals_ruined_temple +TAGS: water_ok +DEPTH: Shoals, !Shoals:$ +KPROP: c.GWuw1 = no_tide +KMONS: D = pile of debris +KMONS: 1 = kraken +KFEAT: 1D = w +SUBST: u = Ww, . = .:500 0 +TILE: G = dngn_statue_centaur w:5 / dngn_statue_maw / dngn_statue_mermaid / \ + dngn_statue_orb w:5 / dngn_statue_princess / \ + dngn_statue_polearm / dngn_statue_tentacles MAP ccccccccccccccccccccccccccccccccc +c...c................$WWWWWWuwwwc +@.c...c..G....G...G...DWWWWWuwwwc c...c.................WWWWWWuwwwc -@.c...c..G....G...G...GWWWWWuwwwc -c...c.................WWWWWWuwwwc -@.c...c..G....G...G...GWWCWWuw1wc -c...c.................WWWWWWuwwwc -@.c...c..G....G...G...GWWWWWuwwwc +@.c...c..G....G...G...DWWCWWuw1wc c...c.................WWWWWWuwwwc +@.c...c..G....G...G...DWWWWWuwwwc +c...c................$WWWWWWuwwwc ccccccccccccccccccccccccccccccccc ENDMAP @@ -2092,28 +2097,30 @@ DDDD DDDDE.132...EDDD DDDDD ENDMAP -NAME: nicolae_shoals_raging_river -TAGS: transparent no_tide patrolling -KMONS: 1 = water elemental -KMONS: 2 = elemental wellspring -KITEM: L = * w:20 / | -KFEAT: L = W / . -KFEAT: 12 = w -SUBST: M = Wx, w = W x 1:5 2:5 w:70, W = . W:70, ~ = w:90 1 -SUBST: ' = L', x = x:60 c +NAME: nicolae_shoals_raging_river +TAGS: transparent no_tide patrolling +KMONS: 1 = water elemental +KMONS: 2 = elemental wellspring +KMONS: D = pile of debris +KITEM: L = * w:20 / | +KFEAT: L = W / . +KFEAT: 123 = w +NSUBST: w = 1:2.. / 3:1 / 10 = W x w:70 / * = 1:5 W x w:70 +SUBST: M = Wx, W = . W:70, ~ = w:90 1 +SUBST: ' = L', x = x:60 c MAP xxxxxxxx xxxxxx xxccccccxxxMMMMxxx xccLW2wccxMWWWWWMxxx -xcL''WWwcxWW~~~WWWMxx +xcL''WWwcxWW1~~WWWMxx xc'...WwcxWwwWW~~WWMx xc'...WwcxWwWxxW~~WMx xcc..Ww2cxWwwWxWW~WMx xxccWwWccxxWwWxxW~WMx - xxxWwWxxxWwwWxxW~WMx + xxxWDWxxxWwwWxxW~WMx xMWwWxxxWwWxxMW~Wxx - xxWwwWxxxWwWxxW~WWx -xxWwwWxxxWwwWxMW~W.. + xxWwDWxxxWwWxxW~WWx +xxWDwWxxxWwwWxMW~W.. xWwwWxxxWwwWxxWW~W.@ xWwWxxxWwwWxxxW~WW.. xWwWxxxWwWMxxxx~xxxx diff --git a/crawl-ref/source/dat/des/branches/snake.des b/crawl-ref/source/dat/des/branches/snake.des index cc49d50bcf..daaa46fa81 100644 --- a/crawl-ref/source/dat/des/branches/snake.des +++ b/crawl-ref/source/dat/des/branches/snake.des @@ -1022,6 +1022,36 @@ Nxx......xx..xx......xxP .....MM..........LL..... ENDMAP + +NAME: regret_index_snakedec_diamondback +TAGS: transparent extra decor +DEPTH: Snake +KFEAT: C = altar_cheibriados / altar_gozag w:5 +KFEAT: F = cache of fruit / cache of meat +SHUFFLE: '"yY`~zZ / yY'"zZ`~ / yY'"`~zZ / yY'"`~zZ / '"yYzZ`~ / '"yYzZ`~, ?! +SUBST: '` = ., yYzZ = x, ! : bb+, - : x:5 . +NSUBST: "~ = 1:{([])}}<<<<>>>>CCCFFTTUUVV +SUBST: " : bblG, ~ : bblG, ?b : ccx, ^ : ^x... +TILE: G = dngn_statue_naga / dngn_statue_archer w:6 +CLEAR: ^ +MAP + .@.^^ x + ..x..^x ^^^^^ ..x.. + ..xxx..^^ ^^...^^ ^^..xxx.. ^^... + ..x'.yx..^ ^..x..^ ^..x'.yx.. ^..x.. +..x''.yyx.. ..xxx.. ..x''.yyx.. ..xxx.. +.x'''Yyyyx....x`.zx....x'''Yyyyx....x`.zx.. +xx.."?"..xx..x``.zzx..xx.."?"..xx..x``.zzx.. +.xyyyY'''x--x```Zzzzx..xyyyY'''x--x```Zzzzx. +..xyy.''x..xx..~!~..xx..xyy.''x..xx..~!~..xx + ..xy.'x....xzzzZ```x....xy.'x....xzzzZ```x. + ..xxx.. ..xzz.``x.. ..xxx.. ..xzz.``x.. + ..x..^ ..xz.`x..^ ^..x..^ ^..xz.`x.. + ...^^ ..xxx..^^ ^^...^^ ^^..xxx.. + ..x.. ^^^^^ x^..x.. + x ^^.@. +ENDMAP + ############################################################################### # # <<3>> Monster-placing vaults. diff --git a/crawl-ref/source/dat/des/branches/swamp.des b/crawl-ref/source/dat/des/branches/swamp.des index e12efca88f..fbd3fa1434 100644 --- a/crawl-ref/source/dat/des/branches/swamp.des +++ b/crawl-ref/source/dat/des/branches/swamp.des @@ -40,6 +40,8 @@ function swamp_ruins(e) e.tags('serial_swamp_ruin extra transparent unrand') e.depth('Swamp') e.weight('6') + e.mons('pile of debris') + e.item('human skeleton') e.tile('x = wall_brick_vines') e.ftile('- = floor_sandstone') e.subst('- = .') @@ -824,10 +826,9 @@ ENDMAP # and skeletons. These vaults are just to give swamp some variety... # There are no monsters or loot placed here. NAME: evilmike_swamp_ruin_house_1 -NSUBST: x = 1:+ / *:x +NSUBST: x = 1 = x:260 + / *:x SUBST: yx = xxxxx-, - = ----. NSUBST: - = 1:d / *:- -ITEM: human skeleton : swamp_ruins(_G) MAP ........ @@ -861,10 +862,9 @@ MAP ENDMAP NAME: evilmike_swamp_ruin_house_3 -NSUBST: x = 1:+ / *:x +NSUBST: x = 1 = x:260 + / *:x SUBST: y = x, x = xxxxx-, - = ----. NSUBST: - = 1:d / *:- -ITEM: human skeleton : swamp_ruins(_G) MAP ..... @@ -899,7 +899,7 @@ MAP ENDMAP NAME: evilmike_swamp_ruin_house_5 -NSUBST: x = 1:+ / *:x +NSUBST: x = 1 = x:260 + / *:x SUBST: yx = xxxxx-, - = ----. NSUBST: - = 2:d / *:- ITEM: human skeleton @@ -1023,7 +1023,7 @@ ENDMAP NAME: hangedman_swamp_ruin_hall SHUFFLE: yYzZ / yYzZ / zZyY -NSUBST: - = 2:d- / *:-, z = 1:+ / *:X, Z = 1:. / *:X +NSUBST: - = 2:d- / *:-, z = 1 = x:260 + / *:X, Z = 1:. / *:X SUBST: XyY = xxxx-, - = -----. : swamp_ruins(_G) WEIGHT: 2 @@ -1255,10 +1255,12 @@ ENDMAP NAME: nicolae_swamp_well_well_well TAGS: transparent extra decor -NSUBST: x = . / xxxx. -SUBST: p = p..., x : xxxxt, . = ...W KMONS: p = plant -KFEAT: p = . w:30 / W +KMONS: C = pile of debris +KFEAT: p = . / W +KFEAT: C = w +NSUBST: w = 1 = w:130 C / *:w, x = 1 = .:130 C / * = xxxx. +SUBST: p = p..., x : xxxxt, . = ...W MAP ........ ..pppppp.. @@ -1350,8 +1352,9 @@ ENDMAP # http://i.imgur.com/H7nvQFo.jpg NAME: nicolae_swamp_little_tower TAGS: transparent extra no_pool_fixup decor +KMONS: C = pile of debris KMONS: P = plant -NSUBST: X = - / x +NSUBST: X = 1 = -:260 C / *:x SUBST: T = t-, - = ....P, z = WWw, _ = __w CLEAR: _ MAP @@ -1432,8 +1435,10 @@ ENDMAP NAME: nicolae_swamp_reclaimed_castle TAGS: transparent decor extra DEPTH: Swamp +KMONS: C = pile of debris NSUBST: D = + / x, E = + / x, F = + / x, H = + / x, J = + / x NSUBST: K = + / x, L = + / x, M = + / x, N = + / x, O = + / x +NSUBST: + = 1 = +:260 C / *:+ SUBST: ` = .:20 _, ' = .:50 _, + = +:20 ., x = x:110 _, . = .:70 W CLEAR: _ MAP @@ -1651,8 +1656,9 @@ DEPTH: Swamp, !Swamp:$ KMONS: 1 = hydra KMONS: 2 = swamp dragon KMONS: 3 = swamp drake +KMONS: D = pile of debris KFEAT: 123 = shallow_water -SUBST: . = wwwWWW...t, c = c:17 .:1 t:1 w:1 W:1, C:GC., G=GG., C=cc. +SUBST: . = wwwWWW...t, c = c:17 .:1 t:1 w:1 W:1, C:GC., G = GGGD..., C = cc. SUBST: 0:45, 4=1112...., 5=1222...., 6=3. MAP ...C.C.C.C... @@ -1670,14 +1676,16 @@ C.cc.....cc.C ...C.C.C.C... ENDMAP -NAME: st_swamp_ruins_2 -DEPTH: Swamp, !Swamp:$ -KMONS: 1 = hydra -KMONS: 2 = swamp dragon -KMONS: 3 = swamp drake -KFEAT: 123 = shallow_water -SUBST: . = wwwWWW...t, c = c:15 .:1 t:1 w:1 W:1, C=c. -SUBST: 0:45, 4=11123....., 5=12223..... +NAME: st_swamp_ruins_2 +DEPTH: Swamp, !Swamp:$ +KMONS: d = pile of debris +KMONS: 1 = hydra +KMONS: 2 = swamp dragon +KMONS: 3 = swamp drake +KFEAT: 123 = shallow_water +NSUBST: C = 1 = .:120 d / *:C +SUBST: . = wwwWWW...t, c = c:15 .:1 t:1 w:1 W:1, C=c. +SUBST: 0:45, 4=11123....., 5=12223..... MAP ...... .......... @@ -1841,15 +1849,17 @@ wwwww.wwwwwww ENDMAP NAME: grunt_ruined_hall +TAGS: no_pool_fixup MONS: swamp dragon, hydra, patrolling bog body -NSUBST: : = 1:1 / 2:2 / 3:3 / 6:0 / *:- -SUBST: - = .W -SUBST: C = c:20 . W -SUBST: + = +. -SUBST: G = Gg +KMONS: d = pile of debris KITEM: g = stone w:40 / large rock q:1 +KFEAT: d = w KFEAT: g = floor KFEAT: _ = altar_yredelemnul / altar_kikubaaqudgha +KFEAT: d = w +NSUBST: : = 1:1 / 2:2 / 3:3 / 6:0 / *:-, C = 1 = W:120 d / * = cc.W +SUBST: - = .W, + = +. +SUBST: G = Gg MAP -------------------- -CCCCCCCCCCcccCCCcCCc- diff --git a/crawl-ref/source/dat/des/branches/tomb.des b/crawl-ref/source/dat/des/branches/tomb.des index 1e8478cd66..594ecfe97b 100644 --- a/crawl-ref/source/dat/des/branches/tomb.des +++ b/crawl-ref/source/dat/des/branches/tomb.des @@ -341,7 +341,7 @@ ENDMAP NAME: nicolae_tomb_entry_rubble_hallway TAGS: tomb_entry no_monster_gen no_item_gen no_wall_fixup ORIENT: float -MONS: boulder dbname:still_boulder +MONS: pile of debris KITEM: s = stone q:1 / large rock q:1 w:5 KFEAT: O = enter_tomb NSUBST: R = 7:r / *:. diff --git a/crawl-ref/source/dat/des/branches/zot.des b/crawl-ref/source/dat/des/branches/zot.des index e1692a7b3a..98ee7d6f87 100644 --- a/crawl-ref/source/dat/des/branches/zot.des +++ b/crawl-ref/source/dat/des/branches/zot.des @@ -1492,7 +1492,7 @@ ENDMAP NAME: regret_index_zotdec_under_construction TAGS: extra transparent zotdec luniq_zotdec_large DEPTH: Zot, !Zot:$ -MONS: boulder dbname:still_boulder +MONS: pile of debris NSUBST: x = 4 = x. / *:x, + = 1:xxx1.. / 3 = +.. / *:+ NSUBST: ' = 1:Gxx / *:., . = 1:G1x / 1:{([})]TUV<>>> SUBST: X = xx1.... @@ -3984,7 +3984,7 @@ NSUBST: - = 2 / 3 = 3.. / *:. NSUBST: > = 1 = }:80 > / 1 = ):80 > / 1 = ]:80 >, G = 4:G / *:U SUBST: 1 = 1 0:30 . : else -NSUBST: G = 3={[( / *:G +NSUBST: G = 3 = {[( / 3:G / *:U NSUBST: 1 = 6 = 1. / *=0... NSUBST: > = >. / *:. : end @@ -4393,6 +4393,80 @@ vvv+vv....v...vv+vvv..x..xxxx7.x.....x..x. vvvvvvv... . ............ ENDMAP +NAME: chapayev_index_zotdef_columnade +TAGS: no_monster_gen no_rotate no_pool_fixup +ORIENT: south +DEPTH: Zot, !Zot:$ +MONS: 0 band +MONS: red draconian / will-o-the-wisp w:2 +MONS: red draconian scorcher, orb of fire / golden dragon +MONS: white draconian / blizzard demon w:2 +MONS: white draconian knight, golden dragon +KMONS: 8 = black draconian / spark wasp w:2 +KMONS: 9 = black draconian stormcaller +KMONS: 0 = electric golem / storm dragon +KMONS: A = green draconian / green death w:2 +KMONS: B = green draconian monk +KMONS: C = protean progenitor band +KMONS: d = purple draconian / ghost moth w:4 +KMONS: e = purple draconian shifter +KMONS: f = quicksilver dragon +KMONS: g = death cob / storm dragon zombie w:4 +KMONS: h = shadow dragon +KMONS: i = curse toe / ancient lich w:2 +KMONS: z = 0 band +KMONS: W = withered plant +KFEAT: jk = m +KFEAT: s = metal_statue +NSUBST: D = 1:< / 2:x. / *:x, . = 3:1 / *:. +SHUFFLE: 234j / 567k / 890s / ABCW / defU / ghiG +SUBST: j : jjl, k : kkw +SHUFFLE: 369Beh / 369Beh / heB963 / Beh369, HIJKLMNO, }]) +SUBST: HIJ = x, K : x., L : x., MNO = ., } = }:70, ] = ]:40 > +MARKER: U = lua:fog_machine { cloud_type = "purple smoke", \ + pow_min = 4, pow_max = 5, \ + delay_min = 85, delay_max = 95, size = 1, \ + walk_dist = 1, spread_rate = 10 } +COLOUR: s = electricity +TILE: j = dngn_transparent_wall_red +TILE: k = dngn_transparent_wall_blue +TILE: m = dngn_transparent_wall_magenta +TILE: G = dngn_gravestone +TILE: s = storm_conduit +: set_feature_name("metal_statue", "storm conduit") +: set_feature_name("granite_statue", "a gravestone") +MAP + xccccccccccccccx + xxccccccccsccWcccWcckccccccccxx +xc@.@xxxxxxxccccccccjccsc%.............%ckccjccccccccxxxxxxx@.@cx +xc...xxxxxxxb.....+.............).............+.....bxxxxxxx...cx +xc..1.......+..b..+......xx...........xx......+..b..+.......1..cx +xc>.........b.....+.....xxx...........xxx.....+.....b.........>cx +xcccxxxx....xxxxxxc...cxxxx...x...x...xxxxc...cxxxxxx....xxxxcccx +xxxcxxxx....xxxxxxc..Hcxxxx...........xxxxc.O.cxxxxxx....xxxxcxxx + xc%..........%mmcH..cxxxj...x...x...jxxxc...cmm%..........%cx + xc..x......xk.ccc...cxxxx.3.......3.xxxxc...ccc.sx......x..cx + xc............mmc.I.cxxxj...x...x...jxxxc.N.cmm............cx + xc.kx......x..ccc...cxxxx2....2....2xxxxc...ccc..x......xs.cx + xc..5..xx7.5...mc...cxxxx...x...x...xxxxc..Mcm...8.0xx..8..cx + xc..x......xk.ccc.J.cxxxx%....4....%xxxxcM..ccc.sx......x..cx + xc.6........6.mmc...cxxxxxxxb+++bxxxxxxxc...cmm.9........9.cx + xc.kx......x..ccc.K.cxxxxxxx.....xxxxxxxc.L.ccc..x......xs.cx + xc%..........%mmc...cxxxxxxx..x..xxxxxxxc...cmm%..........%cx + xccccc....xxxxxxc..Kcxxxxxxx..D..xxxxxxxc...cxxxxxx....cccccx + xxxxxc.}..xxxxxxcK5.cxxxxxxx..D..xxxxxxxcK8Kcxxxxxx..].cxxxxx + xxxc....xxxxxxc...cxxxxxxx..D..xxxxxxxc...cxxxxxx....cxxx + xxcc.O...N......L.ccxxxxxx..D..xxxxxxcc......I.......ccxx + xcc......N.5.M.....ccxxxxx..D..xxxxxcc.....J.8.H......ccx + xc..O........M...L..ccxxx...x...xxxcc...............x..cx + xc....cccc++cccc.....ccx...xxx...xcc.....cccc++cccc....cx + xc<..ccxxc++cxxcc+++++c...x.x.x...c+++++ccxxc++cxxcc..<cx + xcccccxxxc$$cxxxccc......xB%A%Bx......cccxxxc$$cxxxcccccx + xxxxxxxxxc$$cxxxxxcc..A.W.%.C.%.W.A..ccxxxxxc$$cxxxxxxxxx + xxxxxxxxxccccxxxxxxcccccccccccccccccccxxxxxxccccxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +ENDMAP + ############################################################################## ############################################################################## # diff --git a/crawl-ref/source/dat/des/builder/shops.des b/crawl-ref/source/dat/des/builder/shops.des index c0fa949f39..12d77b2cd8 100644 --- a/crawl-ref/source/dat/des/builder/shops.des +++ b/crawl-ref/source/dat/des/builder/shops.des @@ -908,7 +908,7 @@ DEPTH: D:11-, Depths KMONS: 1 = gargoyle / basilisk / boulder beetle / cyclops w:3 KMONS: 2 = stone giant / catoblepas / deep troll earth mage / \ iron dragon w:4 -KMONS: B = boulder dbname:still_boulder +KMONS: D = pile of debris ITEM: stone KFEAT: S = general shop type:Pet suffix:Rocks count:7 ; \ stone w:15 | large rock w:15 | sling w:8 | \ @@ -921,7 +921,7 @@ SUBST: ? = 2dd : if you.absdepth() < 16 then SUBST: 2 = 1 : end -SUBST: B : B., C : B. +SUBST: B : D., C : D. MAP B.....C .xx+xx. @@ -1073,9 +1073,9 @@ ENDMAP NAME: nicolae_elemental_shop TAGS: no_monster_gen no_item_gen no_pool_fixup transparent extra DEPTH: D:4-, Depths -KMONS: b = boulder dbname:still_boulder +KMONS: D = pile of debris SHUFFLE: AB -NSUBST: A = 1:a / 1:l / 1:w / *:xxb +NSUBST: A = 1:a / 1:l / 1:w / *:xxD SUBST: B = . KPROP: l = no_cloud_gen MARKER: a = lua:fog_machine { cloud_type = "thin mist", \ diff --git a/crawl-ref/source/dat/des/builder/uniques.des b/crawl-ref/source/dat/des/builder/uniques.des index dec5f251f6..630e7d0af0 100644 --- a/crawl-ref/source/dat/des/builder/uniques.des +++ b/crawl-ref/source/dat/des/builder/uniques.des @@ -529,7 +529,6 @@ TAGS: place_unique no_monster_gen no_item_gen DEPTH: D:2-7 MONS: Crazy Yiuf MONS: fungus / bush w:1 -KMONS: B = boulder dbname:still_boulder ITEM: mace tile:wpn_hammer wtile:hammer itemname:hammer KFEAT: e = cache of fruit # Randomisation 1: Some chance for a gate. @@ -550,7 +549,7 @@ SUBST: ; = .:10 d:2 : if crawl.one_chance_in(300) then SUBST: t = " : end -SUBST: e = eB'', ':.......' , "=' , ':d' , '=..d +SUBST: e = e''', ':.......' , "=' , ':d' , '=..d # Randomisation 4: trees or rock SUBST: t : ttx MAP diff --git a/crawl-ref/source/dat/des/portals/volcano.des b/crawl-ref/source/dat/des/portals/volcano.des index 9dd356481a..ef16658a75 100644 --- a/crawl-ref/source/dat/des/portals/volcano.des +++ b/crawl-ref/source/dat/des/portals/volcano.des @@ -267,7 +267,7 @@ function fiery_guardians (e, intelligent, village) else -- "Elemental" monster pack. e.mons("fire elemental w:12 / earth elemental / gargoyle w:8") - e.mons("efreet") + e.mons("efreet / obsidian bat w:4") e.mons("stone giant") end end @@ -581,7 +581,9 @@ WEIGHT: 50 SUBVAULT: B : volcano_grotto_subvault KMONS: 5 = lava snake KMONS: 6 = fire bat +KMONS: D = pile of debris KFEAT: 56 = lava +SUBST: z = Dccx. NSUBST: l = 3:5 / 3 = 5l / 3:6 / 3 = 66lll / *:l : volcano_setup(_G) : place_tiny_volcano(_G) @@ -592,14 +594,14 @@ MAP BBBBBBBBBBB xxxx BBBBBBBBBBB xxxxxxyyxxxx BBBBBBBBBBB - xxxxy......yyyxx BBBBBBBBBBB - xxxxyyy.LLLLL....yxxx BBBBBBBBBBB + xxxxy......yzyxx BBBBBBBBBBB + xxxxyyy.LLLLL....zxxx BBBBBBBBBBB xxxyyy...LlllllL.....GxxBBBBBBBBBBB xxxyy....LLlllllllL......BBBBBBBBBBBB xxxyy....LLlllllllllL....GxxBBBBBBBBBBB - xxyy.....LllllllllllllL..yxx BBBBBBBBBBB + xxyy.....LllllllllllllL..zxx BBBBBBBBBBB xxy......LlllllllllllllL..yxxxBBBBBBBBBBB - xxy......LlllllllllllllllL..yyxBBBBBBBBBBB + xxy......LlllllllllllllllL..zyxBBBBBBBBBBB xxy.....LllllllllllllllllllL..yyBBBBBBBBBBB xxy.....LllllllllllllllllllllL...BBBBBBBBBBB xxy....LllllllllllVlllllllllllL...BBBBBBBBBBB @@ -647,7 +649,7 @@ NAME: vgs_dualism TAGS: volcano_grotto_subvault no_item_gen no_monster_gen no_vmirror unrand KFEAT: BC = altar_makhleb / altar_trog / altar_vehumet : fiery_guardians(_G) -KMONS: 4 = obsidian statue / molten gargoyle +KMONS: 4 = obsidian statue / obsidian bat w:5 / molten gargoyle w:5 # Loot: 8 items, 2 gold piles. NSUBST: X = 1:+ / *:c : volcano_setup(_G) @@ -838,27 +840,28 @@ MAP xxxxxxxxxxxx ENDMAP -NAME: vl_original -TAGS: volcano_lake_subvault no_item_gen no_monster_gen unrand -: fiery_guardians(_G) -KMONS: 4 = molten gargoyle w:90 / gargoyle -KMONS: B = boulder dbname:still_boulder +NAME: vl_original +TAGS: volcano_lake_subvault no_item_gen no_monster_gen unrand +: fiery_guardians(_G) +KMONS: 4 = molten gargoyle w:90 / gargoyle +KMONS: B = pile of debris +KITEM: b = large rock q:1 KFEAT: _ = altar_makhleb / altar_trog / altar_vehumet # Loot: 10 items, 6 gold piles. : volcano_setup(_G) -SUBST: B : B., b : B. +SHUFFLE: bB / Bb / bb / '' / '' / '' MAP ccccccccccccccccc -c....+.121.+....c +cb...+.121.+...bc c.<1.c.G_G.c.3<.c cB...c..1..c...Bc ccc++ccc+ccc++ccc n......c.c......n cccccc.c.c.cccccc -cb$f$c.c.c.cgd$bc +cB$f$c.c.c.cgd$Bc c.$gec.c.c.c$e$.c c.4dgc.c.c.cfg4.c -c......c.c......c +cb.....c.c.....bc cccccccc+cccccccc ... ENDMAP @@ -875,15 +878,13 @@ NAME: volcano_pools TAGS: no_item_gen no_monster_gen no_rotate ORIENT: encompass WEIGHT: 50 -KMONS: B = boulder dbname:still_boulder : fiery_guardians(_G) SHUFFLE: QRSTU # Two pools with loot (ten items, six gold) and bosses, # two nearly empty pools, and an empty entrance pool. NSUBST: Q = 2:1 / 1:2 / 1:d / 1:e / 2:$ / 2:f / 2:g NSUBST: R = 2 = 1. / 1:3 / 2:d / 2:e / 2:$ / 1:f / 1:g -NSUBST: S = 1:1 / 1:B.. / *:., T = 1 = 1. / 1:B.. / *:. -NSUBST: U = 1:A / *:. +NSUBST: S = 1:1 / *:., T = 1:1. / *:., U = 1:A / *:. : volcano_setup(_G) : place_tiny_volcano(_G) KFEAT: J = l @@ -982,20 +983,21 @@ MONS: alligator skeleton / harpy skeleton / anaconda skeleton MONS: skeletal warrior ; halberd ego:flaming ident:type | \ dire flail ego:flaming ident:type | \ great sword ego:flaming ident:type +KMONS: D = pile of debris KFEAT: ? = broken_door # Only one loot chamber. Scatter tomb residents. NSUBST: 4 = 1:l / 4:3 / *:4, ? = 1:? / 1:+? / *:+ SHUFFLE: 23, a-| / b_* -SUBST: a = v, - = +, b_* = c +SUBST: a = v, - = +, b_* = c, D = Dyy NSUBST: | = 2:d / 3:e / 2:f / 3:g # Loot: 3 gold, 8 items. : volcano_setup(_G) MAP xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxyyxxx -xxxxxxxxxxxxxxxxxxy.y.$Lxx -xxxxxxxxxcccccccxy.y.1Lllx -xxxxxxxxxc..Y..cy.xxx.lllx +xxxxxxxxxxxxxxxxxxD.y.$Lxx +xxxxxxxxxcccccccx..y.1Lllx +xxxxxxxxxc..Y..cD.xxx.lllx cccccccccc.....+.xxx.xllJx +...G....+..2..cccxxx.x.xx +...$....+.1<1.?4cxxxx.xxx @@ -1058,9 +1060,9 @@ TAGS: no_item_gen no_monster_gen ORIENT: encompass WEIGHT: 20 MONS: lindwurm, efreet -MONS: molten gargoyle w:20 / earth elemental w:18 / toenail golem w:2 +MONS: molten gargoyle w:40 / earth elemental w:38 / \ + toenail golem w:2 / obsidian bat w:2 MONS: fire elemental / nothing w:6 -KMONS: B = boulder dbname:still_boulder KFEAT: K = l NSUBST: R = 2:1 / * = ll' NSUBST: Y = 2:2 / 1:24 / 6:4 / 6:J / *:. diff --git a/crawl-ref/source/dat/des/portals/ziggurat.des b/crawl-ref/source/dat/des/portals/ziggurat.des index 0a94d016c9..e02f7f213e 100644 --- a/crawl-ref/source/dat/des/portals/ziggurat.des +++ b/crawl-ref/source/dat/des/portals/ziggurat.des @@ -259,14 +259,15 @@ z.y.z z'z'z ENDMAP -NAME: ziggurat_pillar_centre_h -TAGS: ziggurat_pillar centered no_dump unrand no_exits -MONS: laughing skull w:1 / crimson imp w:31 / pandemonium lord w:1 +NAME: ziggurat_pillar_centre_h +TAGS: ziggurat_pillar centered no_dump unrand no_exits +MONS: laughing skull w:1 / crimson imp w:31 / pandemonium lord w:1 +KFEAT: % : cache of meat / cache of fruit MAP ccncc -c...c +c%..c n.1.n -c...c +c..%c ccncc ENDMAP diff --git a/crawl-ref/source/dat/des/serial/column_ruins.des b/crawl-ref/source/dat/des/serial/column_ruins.des index 63f81e5872..a83a8cb594 100644 --- a/crawl-ref/source/dat/des/serial/column_ruins.des +++ b/crawl-ref/source/dat/des/serial/column_ruins.des @@ -28,7 +28,7 @@ {{ function init_column_ruins(e) e.kfeat('B = altar_ecumenical') - e.kmons('b = boulder dbname:still_boulder') + e.kmons('d = pile of debris') e.subst('J = _____.') e.subst('K = ____..') e.subst('L = ___...') @@ -37,7 +37,7 @@ function init_column_ruins(e) e.subst('p = GGGG_') e.subst('q = GGG__') e.subst('r = GG__.') - e.subst('s = Gb_..') + e.subst('s = Gd_..') e.ftile('_$%*90GTUVB = floor_rough_brown') e.colour('_$%*90V = brown') e.tile('G = dngn_crumbled_column') diff --git a/crawl-ref/source/dat/des/serial/magic_research.des b/crawl-ref/source/dat/des/serial/magic_research.des index d3472cc6fd..846062c0a2 100644 --- a/crawl-ref/source/dat/des/serial/magic_research.des +++ b/crawl-ref/source/dat/des/serial/magic_research.des @@ -116,7 +116,6 @@ ENDMAP NAME: hangedman_research_geology MONS: boulder beetle / catoblepas, crystal guardian, iron dragon KMONS: D = caustic shrike -KMONS: B = boulder dbname:still_boulder KITEM: B = large rock q:1 COLOUR: .xB012345D = brown FTILE: .+xB012345D = floor_pebble_brown @@ -129,7 +128,7 @@ MAP @'''@'''@ abcd+dcba bB..x..Bb -c0B1.1B0c +c0x1.1x0c d.2xxx2.d a.xxDxx.a b.x3.3x.b diff --git a/crawl-ref/source/dat/des/sprint/arena_sprint.des b/crawl-ref/source/dat/des/sprint/arena_sprint.des index 9afe0931a9..661bebbfe2 100644 --- a/crawl-ref/source/dat/des/sprint/arena_sprint.des +++ b/crawl-ref/source/dat/des/sprint/arena_sprint.des @@ -365,7 +365,7 @@ function arena_sprint_get_monster_set(round, boss) "ghoul / bog body w:20", "shapeshifter", -- Gimmicks - "neqoxec", + "neqoxec", "obsidian bat", "moth of wrath / w:20 two-headed ogre", "boulder beetle", "orb spider", "redback / sea snake w:3", "shining eye" diff --git a/crawl-ref/source/dat/des/variable/float.des b/crawl-ref/source/dat/des/variable/float.des index 73dfad2208..9588df0644 100644 --- a/crawl-ref/source/dat/des/variable/float.des +++ b/crawl-ref/source/dat/des/variable/float.des @@ -69,8 +69,11 @@ function grunt_megastairs_setup(e) elseif not you.in_branch("Lair") then e.subst("x = c") end - if you.in_branch("Depths") or you.in_branch("Lair") or - you.in_branch("Snake") or you.in_branch("Elf") then + if you.in_branch("Lair") then + e.mons("pile of debris") + e.subst("G : GG11VVtt") + elseif you.in_branch("Depths") or you.in_branch("Snake") or + you.in_branch("Elf") then e.subst("G : GGGGTTVt") else e.subst("G : GGGGTTV") @@ -1364,6 +1367,8 @@ TAGS: transparent ruin DEPTH: D:6-, Depths WEIGHT: 5 ORIENT: float +MONS: pile of debris +SUBST: + : 1++++ TILE: c = wall_stone_smooth TILE: G = dngn_crumbled_column MAP @@ -1676,7 +1681,7 @@ TAGS: no_descent DEPTH: D:10- ORIENT: float WEIGHT: 5 -MONS: boulder dbname:still_boulder +MONS: pile of debris KMONS: 2 = earth elemental KITEM: 2 = any scroll / any potion MAP @@ -4626,12 +4631,12 @@ ORIENT: float MONS: ogre / two-headed ogre KMONS: 2 = stone giant / frost giant w:3 / fire giant w:3 KMONS: PB = plant -KMONS: b = boulder dbname:still_boulder +KMONS: p = pile of debris KMONS: C = cyclops KFEAT: A = granite_statue KFEAT: C = W KFEAT: 2 = cache of fruit / cache of meat / floor w:30 -SUBST: b : bPP, P = PPP.. +SUBST: p : pPP, P = PPP.. NSUBST: " = 2:C / 2=CW / *:W, ' = 2:1 / 2=1., ` = 2:1 / 2=1. NSUBST: ; = 2:1 / 2=1., _ = 2:1 / 2=1., - = 1:| / 2=|* / 2:* / 1=*% / *:% FTILE: 2$|*%AB = floor_grass @@ -4640,21 +4645,21 @@ MAP ....._.c.'..... @..c__c_G'c''c..@ @..c__c_PWP'c''c..@ -....____bWWWb''''.... +....____pWWWp''''.... ..c__c_GWW"WWG'c''c.. .c__c_PWWWWWWWP'c''c. .____PWWWWWWWWWP''''. ._c_GWW"WWAWW"WWG'c'. -_c_bWWWWWB-BWWWWWb'c' -._PWWWWWB-$-BWWWWWP'. +_c_pWWWWWB-BWWWWWb'c' +._PWWWWWB-$-BWWWWWp'. cGWW"WWA-$2$-AWW"WWGc -.;PWWWWWB-$-BWWWWWP`. -;c;bWWWWWB-BWWWWWb`c` +.;PWWWWWB-$-BWWWWWp`. +;c;pWWWWWB-BWWWWWb`c` .;c;GWW"WWAWW"WWG`c`. .;;;;PWWWWWWWWWP````. .c;;c;PWWWWWWWP`c``c. ..c;;c;GWW"WWG`c``c.. -....;;;;bWWWb````.... +....;;;;pWWWp````.... @..c;;c;PWP`c``c..@ @..c;;c;G`c``c..@ .....;.c.`..... @@ -6488,7 +6493,6 @@ TAGS: vaults_hard vaults_orient_s DEPTH: D:9-, Vaults WEIGHT: 20 (Vaults), 10 ORIENT: float -KMONS: B = boulder dbname:still_boulder : if you.in_branch("D") then : if you.depth() < 12 then MONS: orc wizard, deep elf pyromancer, deep elf archer @@ -6517,7 +6521,7 @@ KFEAT: ^ = teleport trap KITEM: | = any book w:5 / any magical staff / any ring / any amulet /... [truncated message content] |
From: <gi...@cr...> - 2024-03-18 22:05:15
|
via 33df2375a9eebbd1ff02e02975626d768218fbd3 (commit) from 4004213054c0c92f448d7cddf89708ab1c0f4ef7 (commit) ----------------------------------------------------------------------- commit 33df2375a9eebbd1ff02e02975626d768218fbd3 Author: Kyle Rawlins <ra...@gm...> Date: Mon Mar 18 18:00:21 2024 -0400 fix: various issues with webtiles idle timers Since sometime around 2a3aa404fa2d, the play idle timer has been broken. The issue is essentially race conditions in checking whether a game has actually started/stopped, where the idle timer was reset during game startup but before it had fully started. This commit should make both timers work in a way that is more robust to this issue. The other problem is that 2a3aa404fa2d seems to have assumed that the connection life check was only happening during play, which was incorrect. This lets it work in the lobby, while spectating, and during play again. The overall implementation is still somewhat painful, because no time is really tracked in the lobby; possibly it should be. I also changed the semantics of `max_lobby_idle_time` to match `max_idle_time` a little better. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/webserver/config.py | 17 +++-- crawl-ref/source/webserver/webtiles/config.py | 2 +- crawl-ref/source/webserver/webtiles/ws_handler.py | 76 ++++++++++++++++------- 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/crawl-ref/source/webserver/config.py b/crawl-ref/source/webserver/config.py index e09b7a2e93..d04431f2cf 100644 --- a/crawl-ref/source/webserver/config.py +++ b/crawl-ref/source/webserver/config.py @@ -237,14 +237,19 @@ ssl_port = 8081 # ("localhost", 8083), # ) -# how often to check for an active connection while playing: -# connection_timeout = 600 - -# the maximum allowed idle time while playing: +# how often to check for an active connection while playing; this has an effect +# on how often a connection is checked for basic life, as well as the following +# two idle timer settings. +# connection_timeout = 10 * 60 + +# the maximum allowed idle time while playing. This timer is checked in +# intervals determined by `connection_timout`, so values will essentially be +# rounded up to that setting # max_idle_time = 5 * 60 * 60 -# the maximum allowed idle time in the lobby. Values less than 10 minutes -# (or negative) will disable lobby idle timeouts altogether. +# the maximum allowed idle time in the lobby. Negative values will disable the +# lobby idle timer. This timer is rounded up to the value of the +# `connection_timeout` setting, similar to `max_idle_time`. # max_lobby_idle_time = 3 * 60 * 60 # use_gzip = True diff --git a/crawl-ref/source/webserver/webtiles/config.py b/crawl-ref/source/webserver/webtiles/config.py index 7fd5623814..de3c9fe8c6 100644 --- a/crawl-ref/source/webserver/webtiles/config.py +++ b/crawl-ref/source/webserver/webtiles/config.py @@ -71,7 +71,7 @@ defaults = { 'lobby_update_rate': 2, 'recording_term_size': (80, 24), 'max_connections': 100, - 'connection_timeout': 600, + 'connection_timeout': 10 * 60, 'max_idle_time': 5 * 60 * 60, 'max_lobby_idle_time': 3 * 60 * 60, 'use_gzip': True, diff --git a/crawl-ref/source/webserver/webtiles/ws_handler.py b/crawl-ref/source/webserver/webtiles/ws_handler.py index 95995febb4..987c86e109 100644 --- a/crawl-ref/source/webserver/webtiles/ws_handler.py +++ b/crawl-ref/source/webserver/webtiles/ws_handler.py @@ -425,7 +425,7 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): compression) sockets.add(self) - self.reset_timeout() + self.reset_idle_timeouts() if config.get('max_connections') < len(sockets): self.append_message("connection_closed('The maximum number of " @@ -447,11 +447,16 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): def idle_time(self): return self.process.idle_time() - def is_running(self): - return self.process is not None and self.process.process + def is_running(self, partial=False): + # during setup, and for a short interval after close, self.process + # is set, but self.process.process may be unset or indeterminate. + # after close, `try_cleanup` provides a safe point for this check. + return self.process is not None and (partial or self.process.process) def is_in_lobby(self): - return not self.is_running() and self.watched_game is None + # caveat: this will return True while a player is logging in directly + # via a play link... + return not self.is_running(partial=True) and self.watched_game is None def send_lobby_data(self): self.queue_message("lobby_clear") @@ -643,26 +648,32 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): send_game_links() self.collect_save_info(send_game_links) - def clear_timeouts(self, lobby=True): - if self.timeout: + def clear_timeouts(self, lobby=None): + if not lobby and self.timeout: IOLoop.current().remove_timeout(self.timeout) self.timeout = None - if self.lobby_timeout: + if lobby != False and self.lobby_timeout: IOLoop.current().remove_timeout(self.lobby_timeout) self.lobby_timeout = None - def should_lobby_timeout(self): - return self.is_in_lobby() and not self.is_admin() - def reset_lobby_timeout(self): - self.clear_timeouts() - if not self.should_lobby_timeout(): + self.clear_timeouts(lobby=True) + # warning: there is a somewhat painful interval at game start while + # self.process is partly set up, but before self.process.process is + # still unset. Don't call this function during that time... + time_limit = config.get('max_lobby_idle_time') > 0 + if not self.is_in_lobby() or self.is_admin() or time_limit <= 0: + # this can be triggered on callbacks; if the player is now playing, + # leave things with this timeout no longer set at all return - min_lobby_idle = 60 * 10 # ignore values less than this - if config.get('max_lobby_idle_time') > min_lobby_idle: - self.lobby_timeout = IOLoop.current().add_timeout( - time.time() + config.get('max_lobby_idle_time'), - self.check_lobby_connection) + + # don't check more often than the overall connection timeout setting + time_limit = max(time_limit, config.get('connection_timeout')) + # lobby doesn't track idle time, so we just use a timeout directly; + # this gets reset on actions + self.lobby_timeout = IOLoop.current().add_timeout( + time.time() + time_limit, + self.check_lobby_connection) def check_lobby_connection(self): if self.is_running(): # sanity check, but this shouldn't be possible @@ -673,7 +684,7 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): self.close() def reset_timeout(self): - self.clear_timeouts() + self.clear_timeouts(lobby=False) self.received_pong = False self.send_message("ping") @@ -681,16 +692,24 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): time.time() + config.get('connection_timeout'), self.check_connection) + def reset_idle_timeouts(self): + self.reset_lobby_timeout() + self.reset_timeout() + def check_connection(self): self.timeout = None if not self.received_pong: self.logger.info("Connection timed out.") self.close() - else: - if self.is_running() and self.process.idle_time() > config.get('max_idle_time'): + elif self.is_running(): + if self.process.idle_time() > config.get('max_idle_time'): self.logger.info("Stopping crawl after idle time limit.") self.process.stop() + elif self.is_in_lobby(): + if not self.lobby_timeout: + reset_lobby_timeout() + # XX none of these covers watchers if not self.client_closed: self.reset_timeout() @@ -768,6 +787,10 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): else: self.process = process_handler.DGLLessCrawlProcessHandler(self.logger) + # now that `process` is set, clear the lobby timeout and reset the + # play timeout + self.reset_idle_timeouts() + # self.clear_timeouts(lobby=True) self.process.end_callback = self._on_crawl_end self.process.add_watcher(self) try: @@ -1206,7 +1229,9 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): if self.is_running(): self.process.stop() - self.reset_lobby_timeout() + # note -- lobby timer is not guaranteed to be started here, because + # process stop is async + self.reset_idle_timeouts() if self.username and userdb.dgl_is_banned(self.user_flags): # force a logout. Note that this doesn't check the db at this point @@ -1455,9 +1480,12 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): # be cleaned up. if not self.is_running(): self.process = None - self.clear_timeouts(lobby=self.client_closed) - if self.client_closed and self in sockets: - sockets.remove(self) + if self.client_closed: + self.clear_timeouts() + if self in sockets: + sockets.remove(self) + else: + self.reset_idle_timeouts() if self.watched_game: self.watched_game.remove_watcher(self) -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-18 19:05:10
|
via 4004213054c0c92f448d7cddf89708ab1c0f4ef7 (commit) from ce6887170de209603a1fb9265dc40421892a1dec (commit) ----------------------------------------------------------------------- commit 4004213054c0c92f448d7cddf89708ab1c0f4ef7 Author: Kyle Rawlins <ra...@gm...> Date: Mon Mar 18 14:58:34 2024 -0400 fix: remove debug code ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/webserver/webtiles/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crawl-ref/source/webserver/webtiles/server.py b/crawl-ref/source/webserver/webtiles/server.py index 672c6b859d..2fb8f3f730 100755 --- a/crawl-ref/source/webserver/webtiles/server.py +++ b/crawl-ref/source/webserver/webtiles/server.py @@ -195,7 +195,7 @@ def stop_everything(shutdown_event): def do_stop(tries=0): if len(ws_handler.sockets) == 0: shutdown_event.set() - elif tries > 10: # 60: # 30s + elif tries > 60: # 30s # try something a bit stronger logging.error("Stop failed after 30s, cancelling remaining tasks.") logging.error("Remaining sockets: %s", ws_handler.describe_sockets(names=True)) -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-18 19:00:13
|
via ce6887170de209603a1fb9265dc40421892a1dec (commit) via 1b414cbff7c4b9d2063e70fe8bc53ac6566e4375 (commit) from 0f6f1dd4b9273ad70c2c0f737dad5444d255bb93 (commit) ----------------------------------------------------------------------- commit ce6887170de209603a1fb9265dc40421892a1dec Author: Kyle Rawlins <ra...@gm...> Date: Mon Mar 18 14:48:17 2024 -0400 refactor: modernize/fix webtiles signal handling The Tornado 6.4 release notes say: "`IOLoop.add_callback_from_signal` is suspected to have been broken since Tornado 5.0 and will be removed in version 7.0. Use `asyncio.loop.add_signal_handler` instead." This commit is a direct reaction to that; we've certainly had some pretty flaky shutdown behavior with the existing approaches. To update the signal handlers with this suggestion, a bunch of other changes were necessary: * Move all callback setup into an async function, start the ioloop with an asyncio call. This is Tornado's current recommended approach, so really this is a long-needed modernization. * separate socket binding (non-async) from tornado server startup (async) * it's no longer safe to directly call IOLoop.current().stop(); the means of triggering shutdown is therefore converted to (i) an Event that waits for sockets to close (fixing some other issues with the previous approach), and then (ii) code that cancels remaining tasks if this takes too long. * a bunch of old back-compat is removed. This patch is relatively conservative, but does definitely assume asyncio. This patch is still really far from any sort of asyncio conversion; nothing except the main server start function is async. commit 1b414cbff7c4b9d2063e70fe8bc53ac6566e4375 Author: Kyle Rawlins <ra...@gm...> Date: Mon Mar 18 11:54:38 2024 -0400 refactor: update stale lock code This modernizes this code a little bit for python 3, and also checks for the existence of the process first before prompting the user about "stale processes". When a server is force-shudown via kill -9, lockfiles aren't cleared, and the previous version wouldn't actually check if the pid was real until the 10s prompt had elapsed. ----------------------------------------------------------------------- Summary of changes: .../source/webserver/webtiles/process_handler.py | 66 +++-- crawl-ref/source/webserver/webtiles/server.py | 293 +++++++++++---------- crawl-ref/source/webserver/webtiles/ws_handler.py | 6 +- 3 files changed, 196 insertions(+), 169 deletions(-) diff --git a/crawl-ref/source/webserver/webtiles/process_handler.py b/crawl-ref/source/webserver/webtiles/process_handler.py index 4aff38bcbc..e615d4f6a1 100644 --- a/crawl-ref/source/webserver/webtiles/process_handler.py +++ b/crawl-ref/source/webserver/webtiles/process_handler.py @@ -743,6 +743,7 @@ class CrawlProcessHandler(CrawlProcessHandlerBase): self._purge_locks_and_start(True) def stop(self): + # n.b. the super call here is partly async super(CrawlProcessHandler, self).stop() self._stop_purging_stale_processes() self._stale_pid = None @@ -767,14 +768,18 @@ class CrawlProcessHandler(CrawlProcessHandlerBase): self._stale_pid = pid self._stale_lockfile = lockfile if firsttime: - hup_wait = 10 - self.send_to_all("stale_processes", - timeout=hup_wait, - # is name really correct here? - game=self.game_params.templated("name", username=self.username)) - to = IOLoop.current().add_timeout(time.time() + hup_wait, - self._kill_stale_process) - self._process_hup_timeout = to + if self._kill_stale_process(check_pid_only=True): + # if we get here, the pid is real + hup_wait = 10 + self.send_to_all("stale_processes", + timeout=hup_wait, + # is name really correct here? + game=self.game_params.templated("name", username=self.username)) + to = IOLoop.current().add_timeout(time.time() + hup_wait, + self._kill_stale_process) + self._process_hup_timeout = to + # else: _purge_stale_locks recurses to this function, so no + # need to do anything more here else: self._kill_stale_process() except Exception: @@ -807,32 +812,47 @@ class CrawlProcessHandler(CrawlProcessHandlerBase): path) return None - def _kill_stale_process(self, signal=subprocess.signal.SIGHUP): + def _kill_stale_process(self, signal=subprocess.signal.SIGHUP, check_pid_only=False): + if check_pid_only: + signal = 0 self._process_hup_timeout = None - if self._stale_pid == None: return + if self._stale_pid == None: + return if signal == subprocess.signal.SIGHUP: self.logger.info("Purging stale lock at %s, pid %s.", self._stale_lockfile, self._stale_pid) elif signal == subprocess.signal.SIGABRT: self.logger.warning("Terminating pid %s forcefully!", self._stale_pid) + # intentional missing `else`, don't message on 0 + try: os.kill(self._stale_pid, signal) + except ProcessLookupError as e: + # Process doesn't exist + self._purge_stale_lock() + if check_pid_only: + return False + except PermissionError as e: + # Process does exist, but we don't have permissions. Unlikely + # coincidence between an unrelated process + a stale lock? + self.logger.error("Clearing stale(?) lock on permission error for pid %i", self._stale_pid) + self._purge_stale_lock() + if check_pid_only: + return False except OSError as e: - if e.errno == errno.ESRCH: - # Process doesn't exist - self._purge_stale_lock() - else: - self.logger.error("Error while killing process %s.", self._stale_pid, - exc_info=True) - errmsg = ("Error while trying to terminate a stale process.\n" + - "Please contact an administrator.") - self.exit_reason = "error" - self.exit_message = errmsg - self.exit_dump_url = None - self.handle_process_end() - return + self.logger.error("Error while killing process %s.", self._stale_pid, + exc_info=True) + errmsg = ("Error while trying to terminate a stale process.\n" + + "Please contact an administrator.") + self.exit_reason = "error" + self.exit_message = errmsg + self.exit_dump_url = None + self.handle_process_end() + return False else: + if check_pid_only: + return True if signal == subprocess.signal.SIGABRT: self._purge_stale_lock() else: diff --git a/crawl-ref/source/webserver/webtiles/server.py b/crawl-ref/source/webserver/webtiles/server.py index 86c0d8b305..672c6b859d 100755 --- a/crawl-ref/source/webserver/webtiles/server.py +++ b/crawl-ref/source/webserver/webtiles/server.py @@ -1,8 +1,7 @@ -from __future__ import absolute_import -from __future__ import print_function - import argparse +import asyncio import errno +import functools import logging import logging.handlers import os @@ -13,15 +12,21 @@ import time import tornado.httpserver import tornado.ioloop +import tornado.netutil import tornado.template import tornado.web from tornado.ioloop import IOLoop +from tornado.netutil import bind_sockets # do not add tornado.platform here without changing do_chroot() import webtiles from webtiles import auth, load_games, process_handler, userdb, config from webtiles import game_data_handler, util, ws_handler, status + +servers = None + + class MainHandler(tornado.web.RequestHandler): # async def _execute(self, transforms, *args, **kwargs): # await tornado.web.RequestHandler._execute(self, transforms, *args, **kwargs) @@ -166,37 +171,80 @@ def shed_privileges(): if config.get('uid') is not None: os.setuid(config.get('uid')) -def stop_everything(): + +def all_tasks_compat(): + try: + # only present since py37; maybe safe to assume? + return asyncio.all_tasks() + except AttributeError: + # removed in py39 + return asyncio.Task.all_tasks() + + +def stop_everything(shutdown_event): + global servers + # shut down servers first -- stop accepting new connections for server in servers: server.stop() + # shut down ongoing games ws_handler.shutdown() - # TODO: shouldn't this actually wait for everything to close?? - if len(ws_handler.sockets) == 0: - IOLoop.current().stop() - else: - IOLoop.current().add_timeout(time.time() + 2, IOLoop.current().stop) -def signal_handler(signum, frame): - logging.info("Received signal %i, shutting down.", signum) - try: - IOLoop.current().add_callback_from_signal(stop_everything) - except AttributeError: - # This is for compatibility with ancient versions < Tornado 3. It - # probably won't shutdown correctly and is *definitely* incorrect for - # modern versions of Tornado; but this is how it was done on the - # original implementation of webtiles + Tornado 2.4 that was in use - # through about 2020. - stop_everything() - -def reload_signal_handler(signum, frame): - logging.info("Received signal %i, reloading config.", signum) - try: - IOLoop.current().add_callback_from_signal(config.reload) - except AttributeError: - logging.error("Incompatible Tornado version") + # an open question -- are there cases where even stronger measures might be + # needed for stuck processes? task.cancel() handled everything I could think + # of locally. + def do_stop(tries=0): + if len(ws_handler.sockets) == 0: + shutdown_event.set() + elif tries > 10: # 60: # 30s + # try something a bit stronger + logging.error("Stop failed after 30s, cancelling remaining tasks.") + logging.error("Remaining sockets: %s", ws_handler.describe_sockets(names=True)) + for task in all_tasks_compat(): + task.cancel() + else: + IOLoop.current().add_timeout(time.time() + 0.5, + functools.partial(do_stop, tries=tries + 1)) + + do_stop() + +def stop_handler(signum, shutdown_event): + logging.info("Received signal %i, beginning shutdown.", signum) + IOLoop.current().add_callback(functools.partial(stop_everything, shutdown_event)) + + +def reload_config_handler(signum): + logging.info("Received signal %i, reloading all config data.", signum) + IOLoop.current().add_callback(config.reload) + + +def reload_games_handler(signum): + logging.info("Received signal %i, reloading game config data.", signum) + IOLoop.current().add_callback_from_signal(config.load_game_data) + + +def bind_server_sockets(): + nonsecure = [] + secure = [] + if config.get('bind_nonsecure'): + if config.get('bind_pairs'): + listens = config.get('bind_pairs') + else: + listens = ( (config.get('bind_address'), config.get('bind_port')), ) + for (addr, port) in listens: + logging.info("Listening on %s:%d" % (addr, port)) + nonsecure.append(bind_sockets(port, addr)) + if config.get('ssl_options'): + if config.get('ssl_bind_pairs'): + listens = config.get('ssl_bind_pairs') + else: + listens = ( (config.get('ssl_address'), config.get('ssl_port')), ) + for (addr, port) in listens: + logging.info("Listening on %s:%d" % (addr, port)) + secure.append(bind_sockets(port, addr)) + return nonsecure, secure -def bind_server(): +def bind_server(nonsecure_sockets, secure_sockets): settings = { "static_path": config.get('static_path'), "template_loader": util.DynamicTemplateLoader.get(config.get('template_path')), @@ -227,48 +275,26 @@ def bind_server(): if config.get('http_xheaders', False): kwargs["xheaders"] = config.get('http_xheaders') + global servers servers = [] - def server_wrap(**kwargs): - try: - return tornado.httpserver.HTTPServer(application, **kwargs) - except TypeError: - # Ugly backwards-compatibility hack. Removable once Tornado 3 - # is out of the picture (if ever) - del kwargs["idle_connection_timeout"] - server = tornado.httpserver.HTTPServer(application, **kwargs) - logging.error( - "Server configuration sets `idle_connection_timeout` " - "but this is not available in your version of " - "Tornado. Please upgrade to at least Tornado 4 for " - "this to work.""") - return server - - if config.get('bind_nonsecure'): - server = server_wrap(**kwargs) - - if config.get('bind_pairs'): - listens = config.get('bind_pairs') - else: - listens = ( (config.get('bind_address'), config.get('bind_port')), ) - for (addr, port) in listens: - logging.info("Listening on %s:%d" % (addr, port)) - server.listen(port, addr) + if nonsecure_sockets and config.get('bind_nonsecure'): + server = tornado.httpserver.HTTPServer(application, **kwargs) + for s in nonsecure_sockets: + server.add_sockets(s) servers.append(server) - if config.get('ssl_options'): - # TODO: allow different ssl_options per bind pair - server = server_wrap(ssl_options=config.get('ssl_options'), **kwargs) - - if config.get('ssl_bind_pairs'): - listens = config.get('ssl_bind_pairs') - else: - listens = ( (config.get('ssl_address'), config.get('ssl_port')), ) - for (addr, port) in listens: - logging.info("Listening on %s:%d" % (addr, port)) - server.listen(port, addr) + if secure_sockets and config.get('ssl_options'): + # TODO: allow different ssl_options per bind pair? + server = tornado.httpserver.HTTPServer(application, + ssl_options=config.get('ssl_options') **kwargs) + for s in secure_sockets: + server.add_sockets(s) servers.append(server) + if not servers: + # config validation should preempt this, but it's here for robustness + raise ValueError("No ports succesfully configured!") return servers @@ -303,41 +329,6 @@ def init_logging(logging_config): logging.addLevelName(logging.WARNING, "WARN") -def monkeypatch_tornado24(): - # extremely ugly compatibility hack, to ease transition for servers running - # the ancient patched tornado 2.4. - IOLoop.current = staticmethod(IOLoop.instance) - - -def ensure_tornado_current(exit=True): - try: - tornado.ioloop.IOLoop.current() - except AttributeError: - monkeypatch_tornado24() - tornado.ioloop.IOLoop.current() - err = ("You are running a deprecated version of tornado; please update" - " to a current version.") - if exit: - sys.err(err) - else: - logging.error(err) - - -def usr1_handler(signum, frame): - assert signum == signal.SIGUSR1 - logging.info("Received USR1, reloading config.") - try: - IOLoop.current().add_callback_from_signal(config.load_game_data) - except AttributeError: - # This is for compatibility with ancient versions < Tornado 3. - try: - config.load_game_data() - except Exception: - logging.exception("Failed to update games after USR1 signal.") - except Exception: - logging.exception("Failed to update games after USR1 signal.") - - def parse_args_main(): parser = argparse.ArgumentParser( description='Dungeon Crawl webtiles server', @@ -693,6 +684,52 @@ def run_util(): sys.exit(1) +def init_signals(shutdown_event): + # if we can ensure >=py37 (probably?) this should be get_running_loop + loop = asyncio.get_event_loop() + stop_sigs = [signal.SIGTERM, signal.SIGINT] + reload_sigs = [] + reload_game_sigs = [signal.SIGUSR1] + + if config.get('hup_reloads_config'): + reload_sigs.append(signal.SIGHUP) + else: + stop_sigs.append(signal.SIGHUP) + + for s in stop_sigs: + loop.add_signal_handler(s, functools.partial(stop_handler, s, shutdown_event)) + for s in reload_sigs: + loop.add_signal_handler(s, functools.partial(reload_config_handler, s)) + for s in reload_game_sigs: + loop.add_signal_handler(s, functools.partial(reload_games_handler, s)) + + +async def async_run_server(nonsecure_sockets, secure_sockets): + # is this ever set to False by anyone in practice? + dgl_mode = config.get('dgl_mode') + # XX possibly some of this should move into async_run + if dgl_mode: + ws_handler.status_file_timeout() # note: tornado coroutine + auth.purge_login_tokens_timeout() + ws_handler.start_reading_milestones() + + if config.get('watch_socket_dirs'): + process_handler.watch_socket_dirs() + + # set up various timeout loops + ws_handler.do_periodic_lobby_updates() + webtiles.config.init_config_timeouts() + + bind_server(nonsecure_sockets, secure_sockets) + + shutdown_event = tornado.locks.Event() + init_signals(shutdown_event) + + logging.info("DCSS Webtiles server started! (PID: %s)" % os.getpid()) + logging.info(version()) + await shutdown_event.wait() + + # before running, this needs to have its config source set up. See # ../server.py in the official repository for an example. def run(): @@ -735,16 +772,9 @@ def run(): if config.get('daemon', False): daemonize() - signal.signal(signal.SIGTERM, signal_handler) - signal.signal(signal.SIGINT, signal_handler) - if (config.get('hup_reloads_config')): - signal.signal(signal.SIGHUP, reload_signal_handler) - else: - signal.signal(signal.SIGHUP, signal_handler) - if config.get('umask') is not None: os.umask(config.get('umask')) - except SystemExit: + except SystemExit: # err_exit in the try blocks # logging already done, hopefully raise except: @@ -753,49 +783,28 @@ def run(): try: write_pidfile() - global servers - servers = bind_server() - ensure_tornado_current() - + # bind sockets and shed privileges before starting up the ioloop + nonsecure_sockets, secure_sockets = bind_server_sockets() shed_privileges() - # is this ever set to False by anyone in practice? - dgl_mode = config.get('dgl_mode') - userdb.init_db_connections() - - signal.signal(signal.SIGUSR1, usr1_handler) - - try: - IOLoop.current().set_blocking_log_threshold(0.5) # type: ignore - logging.info("Blocking call timeout: 500ms.") - except: - pass - - if dgl_mode: - ws_handler.status_file_timeout() # note: tornado coroutine - auth.purge_login_tokens_timeout() - ws_handler.start_reading_milestones() - - if config.get('watch_socket_dirs'): - process_handler.watch_socket_dirs() - - # set up various timeout loops - ws_handler.do_periodic_lobby_updates() - webtiles.config.init_config_timeouts() - - logging.info("DCSS Webtiles server started! (PID: %s)" % os.getpid()) - logging.info(version()) - - IOLoop.current().start() - - logging.info("Bye!") except SystemExit: - # logging already done, hopefully raise except: err_exit("Server startup failed!", exc_info=True) finally: + remove_pidfile() + + try: + # finally -- start things up for real + asyncio.run(async_run_server(nonsecure_sockets, secure_sockets)) + logging.info("Bye!") + except asyncio.exceptions.CancelledError: + # triggered by the cancel case in stop_everything + err_exit("Normal server stop failed, some tasks were force-cancelled!") + except: + err_exit("Server exited with error!", exc_info=True) + finally: # warning: need to be careful what appears in this finally block, since # it may be called by child processes on fork in terminal.py in the # event of rare bad timing or bugs. (So any global state that may be diff --git a/crawl-ref/source/webserver/webtiles/ws_handler.py b/crawl-ref/source/webserver/webtiles/ws_handler.py index b2cf273939..95995febb4 100644 --- a/crawl-ref/source/webserver/webtiles/ws_handler.py +++ b/crawl-ref/source/webserver/webtiles/ws_handler.py @@ -73,6 +73,8 @@ def describe_sockets(names=False): if names: # this is all a bit brute-force + if playing: + summary += "; Playing: %s" % list_of_names([s.username for s in playing]) watchers = list_of_names([s.username for s in slist if s.watched_game and s.username]) if watchers: summary += "; Watchers: %s" % watchers @@ -1460,10 +1462,6 @@ class CrawlWebSocket(tornado.websocket.WebSocketHandler): if self.watched_game: self.watched_game.remove_watcher(self) - if shutting_down and len(sockets) == 0: - # The last crawl process has ended, now we can go - IOLoop.current().stop() - def on_close(self): # at this point, self.client_closed is guaranteed to be true extra = [] -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-18 04:30:22
|
via 0f6f1dd4b9273ad70c2c0f737dad5444d255bb93 (commit) from b0416c464d86f8ad4f4f762269e034875eaaaed6 (commit) ----------------------------------------------------------------------- commit 0f6f1dd4b9273ad70c2c0f737dad5444d255bb93 Author: SentientSupper <tro...@gm...> Date: Sat Mar 16 20:59:42 2024 +0800 Fix cursed item background not being red In local tiles. Should be fine for ISFLAG_CURSED to be included in get_item_known_info now that the only source of curses is ash. Closes #3683 ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/items.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index e19c1e7f8b..a18be948f8 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -4618,7 +4618,7 @@ item_def get_item_known_info(const item_def& item) ii.flags = item.flags & (0 | ISFLAG_IDENT_MASK | ISFLAG_ARTEFACT_MASK | ISFLAG_DROPPED | ISFLAG_THROWN - | ISFLAG_COSMETIC_MASK); + | ISFLAG_COSMETIC_MASK | ISFLAG_CURSED); if (in_inventory(item)) { -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-18 04:20:17
|
via b0416c464d86f8ad4f4f762269e034875eaaaed6 (commit) from 00dc8146b4e2e6da77b16ec0906181527fc0ad2f (commit) ----------------------------------------------------------------------- commit b0416c464d86f8ad4f4f762269e034875eaaaed6 Author: SentientSupper <tro...@gm...> Date: Sun Mar 17 23:21:06 2024 +0800 Display chance for wand of warping to blink When targeting. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/beam.cc | 2 +- crawl-ref/source/ouch.cc | 3 ++- crawl-ref/source/spl-cast.cc | 8 ++++++++ crawl-ref/source/spl-damage.cc | 5 +++++ crawl-ref/source/spl-damage.h | 2 ++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 2768840279..4ae6437ec6 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1752,7 +1752,7 @@ int mons_adjust_flavoured(monster* mons, bolt &pbolt, int hurted, case BEAM_WARPING: if (doFlavouredEffects - && x_chance_in_y(min(90, 35 + (pbolt.ench_power)), 100)) + && x_chance_in_y(get_warp_space_chance(pbolt.ench_power), 100)) { monster_blink(mons); } diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 498cd45813..25d1c1e9a0 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -61,6 +61,7 @@ #include "shopping.h" #include "shout.h" #include "spl-clouds.h" +#include "spl-damage.h" #include "spl-goditem.h" #include "spl-selfench.h" #include "state.h" @@ -315,7 +316,7 @@ int check_your_resists(int hurted, beam_type flavour, string source, case BEAM_WARPING: if (doEffects - && x_chance_in_y(min(90, 35 + (beam->ench_power)), 100)) + && x_chance_in_y(get_warp_space_chance(beam->ench_power), 100)) { you.blink(); } diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index 94f7ec3ba9..686831dd24 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -1596,6 +1596,12 @@ static vector<string> _desc_vapor_weak_chance(const monster_info& mi, int pow) get_mercury_weaken_chance(mi.hd, pow))}; } +static vector<string> _desc_warp_space_chance(int pow) +{ + return vector<string>{make_stringf("chance to blink: %d%%", + get_warp_space_chance(pow))}; +} + static vector<string> _desc_meph_chance(const monster_info& mi) { if (get_resist(mi.resists(), MR_RES_POISON) >= 1 || mi.is(MB_CLARITY)) @@ -1840,6 +1846,8 @@ desc_filter targeter_addl_desc(spell_type spell, int powc, spell_flags flags, return bind(_desc_plasma_hit_chance, placeholders::_1, powc); case SPELL_MERCURY_VAPOURS: return bind(_desc_vapor_weak_chance, placeholders::_1, powc); + case SPELL_WARP_SPACE: + return bind(_desc_warp_space_chance, powc); default: break; } diff --git a/crawl-ref/source/spl-damage.cc b/crawl-ref/source/spl-damage.cc index 5dfa755054..0dd044f1c7 100644 --- a/crawl-ref/source/spl-damage.cc +++ b/crawl-ref/source/spl-damage.cc @@ -4878,3 +4878,8 @@ dice_def electrolunge_damage(int pow) { return dice_def(2, pow / 6); } + +int get_warp_space_chance(int pow) +{ + return min(90, 35 + pow); +} diff --git a/crawl-ref/source/spl-damage.h b/crawl-ref/source/spl-damage.h index 00c58dad56..07ca5961da 100644 --- a/crawl-ref/source/spl-damage.h +++ b/crawl-ref/source/spl-damage.h @@ -161,3 +161,5 @@ dice_def boulder_damage(int pow, bool random); void do_boulder_impact(monster& boulder, actor& victim); dice_def electrolunge_damage(int pow); + +int get_warp_space_chance(int pow); -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-18 01:30:22
|
via 00dc8146b4e2e6da77b16ec0906181527fc0ad2f (commit) from fba4d74c8c6943720a6cf22ddde001757be003b6 (commit) ----------------------------------------------------------------------- commit 00dc8146b4e2e6da77b16ec0906181527fc0ad2f Author: David Lawrence Ramsey <poo...@gm...> Date: Sun Mar 17 20:26:36 2024 -0500 Fix spelling. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/dat/descript/items.txt | 2 +- crawl-ref/source/dat/descript/spells.txt | 4 ++-- crawl-ref/source/dat/descript/status.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crawl-ref/source/dat/descript/items.txt b/crawl-ref/source/dat/descript/items.txt index 59c82415f8..88f7666598 100644 --- a/crawl-ref/source/dat/descript/items.txt +++ b/crawl-ref/source/dat/descript/items.txt @@ -631,7 +631,7 @@ dealing enormous damage which increases with the user's Shapeshifting skill. However, this instability makes the user unable to use weapons, shields or body armour. They also glow, reducing stealth and preventing invisibility, and their -melee damage is reduced, as their limbs sometimes destabilize mid-swing. +melee damage is reduced, as their limbs sometimes destabilise mid-swing. %%%% gem diff --git a/crawl-ref/source/dat/descript/spells.txt b/crawl-ref/source/dat/descript/spells.txt index d7d9bb3b2c..fcba87c6bd 100644 --- a/crawl-ref/source/dat/descript/spells.txt +++ b/crawl-ref/source/dat/descript/spells.txt @@ -464,7 +464,7 @@ attack anything and everything nearby with great strength and speed. %%%% Disjunction spell -Destabilizes the space in a sphere around the caster for a while, causing +Destabilises the space in a sphere around the caster for a while, causing anyone nearby to blink away from the caster. The chance of blinking depends on the distance from the caster, being nearly certain when directly adjacent. %%%% @@ -1078,7 +1078,7 @@ Orb of Destruction spell Conjures an orb made of pure destructive magic. Compared to most other projectiles, these orbs travel at a relatively slow pace. The orbs home onto their targets, yet because of their huge inertia, especially agile opponents -may be able to outmanoeuvre them. The orbs need some time to stabilize, and a +may be able to outmanoeuvre them. The orbs need some time to stabilise, and a nascent orb will deal reduced damage. Residents of the dungeon are able to maintain the orb until it impacts a diff --git a/crawl-ref/source/dat/descript/status.txt b/crawl-ref/source/dat/descript/status.txt index 317052914b..4028752a4b 100644 --- a/crawl-ref/source/dat/descript/status.txt +++ b/crawl-ref/source/dat/descript/status.txt @@ -511,7 +511,7 @@ causes a highly localized meltdown, dealing enormous damage. However, this instability makes you unable to use weapons, shields, or body armour. You also glow, reducing stealth and preventing invisibility, -and you do less damage in melee, as your limbs sometimes destabilize mid-swing. +and you do less damage in melee, as your limbs sometimes destabilise mid-swing. %%%% Blade status -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 22:40:24
|
via fba4d74c8c6943720a6cf22ddde001757be003b6 (commit) via 77bb6d37f39031d24ac3ae9e723cf1a7d0662a4d (commit) via 5810ea11cc8d25f82317bb29715a5bc1e2584cc5 (commit) via 903ea0f9b0b40ee60ec6fdb25e1756b2960dfed4 (commit) via 2cddf732a967105a6b570d6d6ac5417e8400652c (commit) from 6b6a0ea73c861b9cea2e558127cb866c388e7007 (commit) ----------------------------------------------------------------------- commit fba4d74c8c6943720a6cf22ddde001757be003b6 Author: Nicholas Feinberg <ple...@gm...> Date: Sun Mar 17 15:38:08 2024 -0700 Update CREDITS for bjo* Per request: https://github.com/crawl/crawl/pull/3688#issuecomment-2002327035. commit 77bb6d37f39031d24ac3ae9e723cf1a7d0662a4d Author: SentientSupper <tro...@gm...> Date: Sun Mar 17 14:14:34 2024 +0800 Show undead players as immune to polymorph commit 5810ea11cc8d25f82317bb29715a5bc1e2584cc5 Author: SentientSupper <tro...@gm...> Date: Sun Mar 17 13:43:54 2024 +0800 Show player as immune to charming with clarity commit 903ea0f9b0b40ee60ec6fdb25e1756b2960dfed4 Author: Aliscans <cr...@th...> Date: Sun Mar 17 16:44:27 2024 +0000 Correct how the display_char option handles gems and gold. DCHAR_ITEM_GOLD and DCHAR_ITEM_GEM were in a different order in dchar_names[] (used by the "display_char" option) to the one in dungeon_char_type, meaning that the option had unexpected effects. Fix this, and add item_gem to the docs for this option. commit 2cddf732a967105a6b570d6d6ac5417e8400652c Author: DracoOmega <dra...@gm...> Date: Sun Mar 17 20:04:31 2024 -0230 Fix a crash with ending constriction after level transit If the constricted actor no longer existed, it would try to dereference a null pointer. There's already checks deeper down to prevent the mid of an nonexistant actor from doing things. ----------------------------------------------------------------------- Summary of changes: crawl-ref/CREDITS.txt | 2 +- crawl-ref/docs/options_guide.txt | 2 +- crawl-ref/source/actor.cc | 4 ++-- crawl-ref/source/player.cc | 2 ++ crawl-ref/source/viewchar.cc | 6 +++--- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/crawl-ref/CREDITS.txt b/crawl-ref/CREDITS.txt index b710a20aa5..d160c7e8bb 100644 --- a/crawl-ref/CREDITS.txt +++ b/crawl-ref/CREDITS.txt @@ -107,7 +107,7 @@ Alexander Beisig benadryl biasface - bjobae + Björn Bähre Stu Black blackcustard Peter 'xFleury' Blain diff --git a/crawl-ref/docs/options_guide.txt b/crawl-ref/docs/options_guide.txt index 50b405c15b..2d6d6fb56e 100644 --- a/crawl-ref/docs/options_guide.txt +++ b/crawl-ref/docs/options_guide.txt @@ -2811,7 +2811,7 @@ display_char = <dungeon_character_name : symbol> invis_exposed, item_detected, item_orb, item_rune, item_weapon, item_armour, item_wand, item_scroll, item_ring, item_potion, item_missile, item_book, item_staff, item_rod, item_miscellany, - item_corpse, item_skeleton, item_gold, item_amulet, cloud, + item_corpse, item_skeleton, item_gold, item_gem, item_amulet, cloud, cloud_weak, cloud_fading, cloud_terminal, tree, transporter, transporter_landing, space, fired_bolt, fired_zap, fired_burst, fired_debug, fired_missile, fired_missile, explosion, frame_horiz, diff --git a/crawl-ref/source/actor.cc b/crawl-ref/source/actor.cc index c9ba4cf6f6..a64bb16acf 100644 --- a/crawl-ref/source/actor.cc +++ b/crawl-ref/source/actor.cc @@ -581,7 +581,7 @@ void actor::stop_directly_constricting_all(bool intentional, bool quiet) if (_invalid_constricting_map_entry(constrictee) || constrictee->get_constrict_type() == CONSTRICT_MELEE) { - end_constriction(constrictee->mid, intentional, quiet); + end_constriction((*constricting)[i], intentional, quiet); constricting->erase(constricting->begin() + i); } } @@ -664,7 +664,7 @@ void actor::clear_invalid_constrictions(bool move) if (_invalid_constricting_map_entry(constrictee) || constrictee->has_invalid_constrictor()) { - stop_constricting(constrictee->mid, false, false); + stop_constricting((*constricting)[i], false, false); } } } diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index d2a0f75461..6f7c409893 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -8973,6 +8973,7 @@ bool player::immune_to_hex(const spell_type hex) const case SPELL_PARALYSE: case SPELL_SLOW: return stasis(); + case SPELL_CHARMING: case SPELL_CONFUSE: case SPELL_CONFUSION_GAZE: case SPELL_MASS_CONFUSION: @@ -8989,6 +8990,7 @@ bool player::immune_to_hex(const spell_type hex) const return clarity() || !(holiness() & MH_NATURAL) || berserk(); case SPELL_PETRIFY: return res_petrify(); + case SPELL_POLYMORPH: case SPELL_PORKALATOR: return is_lifeless_undead(); case SPELL_VIRULENCE: diff --git a/crawl-ref/source/viewchar.cc b/crawl-ref/source/viewchar.cc index f984ce09f1..8be6c9b175 100644 --- a/crawl-ref/source/viewchar.cc +++ b/crawl-ref/source/viewchar.cc @@ -116,9 +116,9 @@ dungeon_char_type dchar_by_name(const string &name) #if TAG_MAJOR_VERSION == 34 "item_rod", #endif - "item_talisman", "item_miscellany", "item_corpse", "item_skeleton", "item_gem", "item_gold", - "item_amulet", "cloud", "cloud_weak", "cloud_fading", "cloud_terminal", - "tree", + "item_talisman", "item_miscellany", "item_corpse", "item_skeleton", + "item_gold", "item_gem", "item_amulet", "cloud", "cloud_weak", + "cloud_fading", "cloud_terminal", "tree", #if TAG_MAJOR_VERSION == 34 "teleporter", #endif -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 20:10:20
|
via 6b6a0ea73c861b9cea2e558127cb866c388e7007 (commit) via 1cb27b7edc3340bc0bfc9646a27d863390774e9a (commit) via 8d7d3c4e6dee1a6b90b5a011c9277ebe6275c1f5 (commit) via c677e9a3103219b0352042c83304a173db43c425 (commit) via e6bea51fa9b55935fc10b96650dadabd7ce779ef (commit) from 6ff4911247d8e431da39d0e179a050177c30bcbd (commit) ----------------------------------------------------------------------- commit 6b6a0ea73c861b9cea2e558127cb866c388e7007 Author: David Lawrence Ramsey <poo...@gm...> Date: Sun Mar 17 11:06:37 2024 -0500 Refactor Upheaval/Disaster Area's target skips. Both will now properly skip over all targets they're harmless to. (Before this, aiming Upheaval directly at a target it shouldn't damage would damage it regardless, whether yourself or an elemental force.) commit 1cb27b7edc3340bc0bfc9646a27d863390774e9a Author: David Lawrence Ramsey <poo...@gm...> Date: Sun Mar 17 08:53:45 2024 -0500 Disable prompt when self-aiming Upheaval. Since it's supposed to be harmless to you. commit 8d7d3c4e6dee1a6b90b5a011c9277ebe6275c1f5 Author: David Lawrence Ramsey <poo...@gm...> Date: Sun Mar 17 13:44:57 2024 -0500 Constify variable. commit c677e9a3103219b0352042c83304a173db43c425 Author: David Lawrence Ramsey <poo...@gm...> Date: Sun Mar 17 14:15:37 2024 -0500 Readd the Disaster Area radius limitation. So it doesn't always blast everything in LOS. commit e6bea51fa9b55935fc10b96650dadabd7ce779ef Author: Monkooky <bui...@gm...> Date: Tue Oct 24 07:03:46 2023 -0500 Remove Upheaval friendly fire Makes Upheaval (and consequently Disaster area) do no damage to Elemental Forces. Other allies are still affected, for thematic and consistency reasons. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/beam-type.h | 1 + crawl-ref/source/beam.cc | 12 +++++++++++ crawl-ref/source/god-abil.cc | 49 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/crawl-ref/source/beam-type.h b/crawl-ref/source/beam-type.h index 3e5b868d9d..ed262dc8c7 100644 --- a/crawl-ref/source/beam-type.h +++ b/crawl-ref/source/beam-type.h @@ -40,6 +40,7 @@ enum beam_type // bolt::flavour BEAM_FOUL_FLAME, BEAM_CRYSTALLIZING, BEAM_WARPING, + BEAM_QAZLAL, // Enchantments BEAM_SLOW, diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 9b1bfb6f58..2768840279 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -3158,6 +3158,9 @@ bool bolt::harmless_to_player() const return agent(true)->is_player() || (bool)!(you.holiness() & (MH_NATURAL | MH_DEMONIC | MH_HOLY)); + case BEAM_QAZLAL: + return true; + default: return false; } @@ -4317,6 +4320,9 @@ bool bolt::ignores_player() const : CONSTRICT_BVC); } + if (flavour == BEAM_QAZLAL) + return true; + return false; } @@ -5533,6 +5539,11 @@ bool bolt::ignores_monster(const monster* mon) const if (flavour == BEAM_WATER && mon->type == MONS_WATER_ELEMENTAL) return true; + int summon_type = 0; + mon->is_summoned(nullptr, &summon_type); + if (flavour == BEAM_QAZLAL && summon_type == MON_SUMM_AID) + return true; + return false; } @@ -7244,6 +7255,7 @@ static string _beam_type_name(beam_type type) case BEAM_UMBRAL_TORCHLIGHT: return "umbral torchlight"; case BEAM_CRYSTALLIZING: return "crystallizing"; case BEAM_WARPING: return "spatial disruption"; + case BEAM_QAZLAL: return "upheaval targetter"; case NUM_BEAMS: die("invalid beam type"); } diff --git a/crawl-ref/source/god-abil.cc b/crawl-ref/source/god-abil.cc index ba52679cde..49967b7137 100644 --- a/crawl-ref/source/god-abil.cc +++ b/crawl-ref/source/god-abil.cc @@ -3526,9 +3526,34 @@ static int _upheaval_radius(int pow) return pow / 100 + 1; } +static bool _qazlal_affected(coord_def pos) +{ + const actor *act = actor_at(pos); + + if (act) + { + if (act->is_player()) + return false; + + if (act->is_monster()) + { + const monster *mon = act->as_monster(); + int summon_type = 0; + // Never fire at elemental forces. + if (mon && mon->is_summoned(nullptr, &summon_type) + && summon_type == MON_SUMM_AID) + { + return false; + } + } + } + + return true; +} + spret qazlal_upheaval(coord_def target, bool quiet, bool fail, dist *player_target) { - int pow = you.skill(SK_INVOCATIONS, 6); + const int pow = you.skill(SK_INVOCATIONS, 6); const int max_radius = _upheaval_radius(pow); bolt beam; @@ -3557,7 +3582,7 @@ spret qazlal_upheaval(coord_def target, bool quiet, bool fail, dist *player_targ args.mode = TARG_HOSTILE; args.needs_path = false; args.top_prompt = "Aiming: <white>Upheaval</white>"; - args.self = confirm_prompt_type::cancel; + args.self = confirm_prompt_type::none; args.hitfunc = &tgt; if (!spell_direction(*player_target, beam, &args)) return spret::abort; @@ -3572,7 +3597,7 @@ spret qazlal_upheaval(coord_def target, bool quiet, bool fail, dist *player_targ bolt tempbeam; tempbeam.source = beam.target; tempbeam.target = beam.target; - tempbeam.flavour = BEAM_MISSILE; + tempbeam.flavour = BEAM_QAZLAL; tempbeam.ex_size = max_radius; tempbeam.hit = AUTOMATIC_HIT; tempbeam.damage = dice_def(AUTOMATIC_HIT, 1); @@ -3621,13 +3646,17 @@ spret qazlal_upheaval(coord_def target, bool quiet, bool fail, dist *player_targ } vector<coord_def> affected; - affected.push_back(beam.target); + if (_qazlal_affected(beam.target)) + affected.push_back(beam.target); for (radius_iterator ri(beam.target, max_radius, C_SQUARE, LOS_SOLID, true); ri; ++ri) { if (!in_bounds(*ri) || cell_is_solid(*ri)) continue; + if (!_qazlal_affected(*ri)) + continue; + int chance = pow; bool adj = adjacent(beam.target, *ri); @@ -3786,18 +3815,22 @@ spret qazlal_disaster_area(bool fail) if (!in_bounds(*ri) || cell_is_solid(*ri)) continue; - const monster_info* m = env.map_knowledge(*ri).monsterinfo(); - if (m && mons_att_wont_attack(m->attitude) - && !mons_is_projectile(m->type)) + if (!_qazlal_affected(*ri)) + continue; + + const monster *mon = monster_at(*ri); + if (mon && mons_att_wont_attack(mon->attitude) + && !mons_is_projectile(mon->type)) { friendlies = true; } const int range = you.pos().distance_from(*ri); - const int dist = grid_distance(you.pos(), *ri); if (range <= upheaval_radius) continue; + const int dist = grid_distance(you.pos(), *ri); + targets.push_back(*ri); // We weight using the square of grid distance, so monsters fewer tiles // away are more likely to be hit. -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 16:40:23
|
via 6ff4911247d8e431da39d0e179a050177c30bcbd (commit) via 14b72cc9fea45df2666a12294d1d6c69c4aad631 (commit) from 424f3ba4f7b419a335c6fe818a39c3c8e20874f1 (commit) ----------------------------------------------------------------------- commit 6ff4911247d8e431da39d0e179a050177c30bcbd Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 12:35:50 2024 -0400 fix: remove 3.12 from ci webserver testing Unfortunately, pinned versions fro 3.8 are broken in 3.12 because of package deprecation. I don't think our current version management for these tests is a very good approach, but I don't have a fix right now. So, temporarily disable 3.12 altogether. These tests currently don't do much so it shouldn't be a big deal. commit 14b72cc9fea45df2666a12294d1d6c69c4aad631 Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 12:33:09 2024 -0400 fix: further update webtiles tests It seems that these tests weren't updated when webtiles code was refactored into a subdirectory. It sort of doesn't matter, because essentially all of our source code is excluded in tox.ini anyways. (What is the point of having these tests when everything is excluded? I have wondered this myself.) ----------------------------------------------------------------------- Summary of changes: .github/workflows/ci.yml | 5 +++-- crawl-ref/source/webserver/.gitignore | 2 ++ crawl-ref/source/webserver/Makefile | 2 +- crawl-ref/source/webserver/mypy.ini | 2 +- crawl-ref/source/webserver/requirements.in/dev.txt | 11 +++++---- .../source/webserver/requirements/dev.py3.txt | 24 ++++++++++++++++++++ crawl-ref/source/webserver/tox.ini | 26 +++++++++++++--------- crawl-ref/source/webserver/webtiles/__init__.py | 4 ++-- 8 files changed, 54 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53973118cc..8190e9c55d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -469,9 +469,10 @@ jobs: runs-on: ubuntu-20.04 # TODO: go back to ubuntu-latest strategy: matrix: - # oldest non-eol security release + current bugfix versions + # oldest non-eol security release + current bugfix version # https://devguide.python.org/versions/ - python-version: [3.8, 3.11, 3.12] + # TODO: 3.12 is currently broken because of requirements.txt brittleness + python-version: [3.8, 3.11] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} diff --git a/crawl-ref/source/webserver/.gitignore b/crawl-ref/source/webserver/.gitignore index 0c2613517e..4c86c436c0 100644 --- a/crawl-ref/source/webserver/.gitignore +++ b/crawl-ref/source/webserver/.gitignore @@ -6,3 +6,5 @@ debug-config.yml banned_players.yml banned_players.txt webtiles/version.txt +Pipfile +Pipfile.lock diff --git a/crawl-ref/source/webserver/Makefile b/crawl-ref/source/webserver/Makefile index 0cd6b14063..fa86723521 100644 --- a/crawl-ref/source/webserver/Makefile +++ b/crawl-ref/source/webserver/Makefile @@ -1,5 +1,5 @@ lint: - flake8 --mypy-config=mypy.ini *.py + flake8 --mypy-config=mypy.ini *.py webtiles/*.py format: diff --git a/crawl-ref/source/webserver/mypy.ini b/crawl-ref/source/webserver/mypy.ini index 9fd595da56..b0ef62d710 100644 --- a/crawl-ref/source/webserver/mypy.ini +++ b/crawl-ref/source/webserver/mypy.ini @@ -3,7 +3,7 @@ strict = True # Specify the target platform details in config, so your developers are # free to run mypy on Windows, Linux, or macOS and get consistent # results. -python_version=3.6 +python_version=3.8 platform=linux # flake8-mypy expects the two following for sensible formatting diff --git a/crawl-ref/source/webserver/requirements.in/dev.txt b/crawl-ref/source/webserver/requirements.in/dev.txt index 677c1beaab..08e7774154 100644 --- a/crawl-ref/source/webserver/requirements.in/dev.txt +++ b/crawl-ref/source/webserver/requirements.in/dev.txt @@ -8,13 +8,12 @@ flake8-commas flake8-isort flake8-mutable flake8-polyfill -flake8-print; python_version >= '3.3' +flake8-print isort pytest -mock; python_version < '3' tox -flake8-mypy; python_version >= '3.5' +flake8-mypy -flake8-bugbear; python_version >= '3' -flake8-comprehensions; python_version >= '3' -flake8-eradicate; python_version >= '3' +flake8-bugbear +flake8-comprehensions +flake8-eradicate diff --git a/crawl-ref/source/webserver/requirements/dev.py3.txt b/crawl-ref/source/webserver/requirements/dev.py3.txt index e34c05c837..085f20dcb3 100644 --- a/crawl-ref/source/webserver/requirements/dev.py3.txt +++ b/crawl-ref/source/webserver/requirements/dev.py3.txt @@ -9,10 +9,14 @@ attrs==23.2.0 # flake8-bugbear # flake8-eradicate # flake8-mypy +build==1.1.1 + # via pip-tools cachetools==5.3.3 # via tox chardet==5.2.0 # via tox +click==8.1.7 + # via pip-tools colorama==0.4.6 # via tox coverage==7.4.4 @@ -60,6 +64,8 @@ flake8-polyfill==1.0.2 # via -r requirements.in/dev.txt flake8-print==5.0.0 # via -r requirements.in/dev.txt +importlib-metadata==7.0.2 + # via build iniconfig==2.0.0 # via pytest isort==5.13.2 @@ -74,9 +80,12 @@ mypy-extensions==1.0.0 # via mypy packaging==24.0 # via + # build # pyproject-api # pytest # tox +pip-tools==7.4.1 + # via -r requirements.in/dev.txt platformdirs==4.2.0 # via # tox @@ -93,14 +102,21 @@ pyflakes==3.2.0 # via flake8 pyproject-api==1.6.1 # via tox +pyproject-hooks==1.0.0 + # via + # build + # pip-tools pytest==8.1.1 # via -r requirements.in/dev.txt pyyaml==6.0.1 # via -r requirements.in/base.txt tomli==2.0.1 # via + # build # mypy + # pip-tools # pyproject-api + # pyproject-hooks # pytest # tox tornado==6.4 @@ -111,3 +127,11 @@ typing-extensions==4.10.0 # via mypy virtualenv==20.25.1 # via tox +wheel==0.43.0 + # via pip-tools +zipp==3.18.1 + # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# pip +# setuptools diff --git a/crawl-ref/source/webserver/tox.ini b/crawl-ref/source/webserver/tox.ini index 95f775ed55..bb90c68640 100644 --- a/crawl-ref/source/webserver/tox.ini +++ b/crawl-ref/source/webserver/tox.ini @@ -11,18 +11,24 @@ commands = pytest [flake8] max-line-length = 90 exclude = - checkoutput.py + wtutil.py config.py - connection.py - game_data_handler.py - inotify.py - process_handler.py - load_games.py server.py - terminal.py - userdb.py - ws_handler.py - wtutil.py + webtiles/checkoutput.py + webtiles/config.py + webtiles/connection.py + webtiles/game_data_handler.py + webtiles/inotify.py + webtiles/process_handler.py + webtiles/load_games.py + webtiles/server.py + webtiles/terminal.py + webtiles/userdb.py + webtiles/ws_handler.py + webtiles/util.py + webtiles/auth.py + webtiles/status.py + webtiles/bans.py [isort] include_trailing_comma = True diff --git a/crawl-ref/source/webserver/webtiles/__init__.py b/crawl-ref/source/webserver/webtiles/__init__.py index 1677cb20c6..53b99b04d8 100644 --- a/crawl-ref/source/webserver/webtiles/__init__.py +++ b/crawl-ref/source/webserver/webtiles/__init__.py @@ -1,3 +1,3 @@ __all__ = ["auth", "checkoutput", "connection", "game_data_handler", "inotify", - "load_games", "process_handler", "terminal", "userdb", "util", - "ws_handler", "server"] + "load_games", "process_handler", "terminal", "userdb", "util", + "ws_handler", "server"] -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 15:55:14
|
via 424f3ba4f7b419a335c6fe818a39c3c8e20874f1 (commit) from bdd6c9c6edabbc43f6cb53f33de5b978f3285f08 (commit) ----------------------------------------------------------------------- commit 424f3ba4f7b419a335c6fe818a39c3c8e20874f1 Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 11:52:09 2024 -0400 fix: update requirements files for webserver tests This is for py38, we'll see if it works for other CI targets. ----------------------------------------------------------------------- Summary of changes: .../source/webserver/requirements/base.py3.txt | 10 +- .../source/webserver/requirements/dev.py3.txt | 154 +++++++++++++++------ 2 files changed, 115 insertions(+), 49 deletions(-) diff --git a/crawl-ref/source/webserver/requirements/base.py3.txt b/crawl-ref/source/webserver/requirements/base.py3.txt index dfedb220e8..ae88aa4aed 100644 --- a/crawl-ref/source/webserver/requirements/base.py3.txt +++ b/crawl-ref/source/webserver/requirements/base.py3.txt @@ -1,8 +1,10 @@ # -# This file is autogenerated by pip-compile -# To update, run: +# This file is autogenerated by pip-compile with Python 3.8 +# by the following command: # # ./requirements.in/sync.sh # -pyyaml==5.3.1 # via -r requirements.in/base.txt -tornado==6.0.4 # via -r requirements.in/base.txt +pyyaml==6.0.1 + # via -r requirements.in/base.txt +tornado==6.4 + # via -r requirements.in/base.txt diff --git a/crawl-ref/source/webserver/requirements/dev.py3.txt b/crawl-ref/source/webserver/requirements/dev.py3.txt index abbddaed4c..e34c05c837 100644 --- a/crawl-ref/source/webserver/requirements/dev.py3.txt +++ b/crawl-ref/source/webserver/requirements/dev.py3.txt @@ -1,49 +1,113 @@ # -# This file is autogenerated by pip-compile -# To update, run: +# This file is autogenerated by pip-compile with Python 3.8 +# by the following command: # # ./requirements.in/sync.sh # -appdirs==1.4.3 # via virtualenv -attrs==19.3.0 # via flake8-bugbear, flake8-eradicate, flake8-mypy, pytest -click==7.1.1 # via pip-tools -coverage==5.0.4 # via -r requirements.in/dev.txt -distlib==0.3.0 # via virtualenv -entrypoints==0.3 # via flake8 -eradicate==1.0 # via flake8-eradicate -filelock==3.0.12 # via tox, virtualenv -flake8-bugbear==20.1.4 ; python_version >= "3" # via -r requirements.in/dev.txt -flake8-builtins==1.5.2 # via -r requirements.in/dev.txt -flake8-commas==2.0.0 # via -r requirements.in/dev.txt -flake8-comprehensions==3.2.2 ; python_version >= "3" # via -r requirements.in/dev.txt -flake8-eradicate==0.3.0 ; python_version >= "3" # via -r requirements.in/dev.txt -flake8-isort==2.9.0 # via -r requirements.in/dev.txt -flake8-mutable==1.2.0 # via -r requirements.in/dev.txt -flake8-mypy==17.8.0 ; python_version >= "3.5" # via -r requirements.in/dev.txt -flake8-pep3101==1.3.0 # via -r requirements.in/dev.txt -flake8-polyfill==1.0.2 # via -r requirements.in/dev.txt -flake8-print==3.1.4 # via -r requirements.in/dev.txt -flake8==3.7.9 # via -r requirements.in/dev.txt, flake8-bugbear, flake8-builtins, flake8-commas, flake8-comprehensions, flake8-eradicate, flake8-isort, flake8-mutable, flake8-mypy, flake8-pep3101, flake8-polyfill, flake8-print -isort[pyproject]==4.3.21 # via -r requirements.in/dev.txt, flake8-isort -mccabe==0.6.1 # via flake8 -more-itertools==8.2.0 # via pytest -mypy-extensions==0.4.3 # via mypy -mypy==0.770 # via flake8-mypy -packaging==20.3 # via pytest, tox -pip-tools==4.5.1 # via -r requirements.in/dev.txt -pluggy==0.13.1 # via pytest, tox -py==1.8.1 # via pytest, tox -pycodestyle==2.5.0 # via flake8, flake8-print -pyflakes==2.1.1 # via flake8 -pyparsing==2.4.6 # via packaging -pytest==5.4.1 # via -r requirements.in/dev.txt -pyyaml==5.3.1 # via -r requirements.in/base.txt -six==1.14.0 # via flake8-print, packaging, pip-tools, tox, virtualenv -testfixtures==6.14.0 # via flake8-isort -toml==0.10.0 # via isort, tox -tornado==6.0.4 # via -r requirements.in/base.txt -tox==3.14.5 # via -r requirements.in/dev.txt -typed-ast==1.4.3 # via mypy -typing-extensions==3.7.4.1 # via mypy -virtualenv==20.0.13 # via tox -wcwidth==0.1.9 # via pytest +attrs==23.2.0 + # via + # flake8-bugbear + # flake8-eradicate + # flake8-mypy +cachetools==5.3.3 + # via tox +chardet==5.2.0 + # via tox +colorama==0.4.6 + # via tox +coverage==7.4.4 + # via -r requirements.in/dev.txt +distlib==0.3.8 + # via virtualenv +eradicate==2.3.0 + # via flake8-eradicate +exceptiongroup==1.2.0 + # via pytest +filelock==3.13.1 + # via + # tox + # virtualenv +flake8==7.0.0 + # via + # -r requirements.in/dev.txt + # flake8-bugbear + # flake8-builtins + # flake8-commas + # flake8-comprehensions + # flake8-eradicate + # flake8-isort + # flake8-mutable + # flake8-mypy + # flake8-polyfill + # flake8-print +flake8-bugbear==24.2.6 + # via -r requirements.in/dev.txt +flake8-builtins==2.2.0 + # via -r requirements.in/dev.txt +flake8-commas==2.1.0 + # via -r requirements.in/dev.txt +flake8-comprehensions==3.14.0 + # via -r requirements.in/dev.txt +flake8-eradicate==1.5.0 + # via -r requirements.in/dev.txt +flake8-isort==6.1.1 + # via -r requirements.in/dev.txt +flake8-mutable==1.2.0 + # via -r requirements.in/dev.txt +flake8-mypy==17.8.0 + # via -r requirements.in/dev.txt +flake8-polyfill==1.0.2 + # via -r requirements.in/dev.txt +flake8-print==5.0.0 + # via -r requirements.in/dev.txt +iniconfig==2.0.0 + # via pytest +isort==5.13.2 + # via + # -r requirements.in/dev.txt + # flake8-isort +mccabe==0.7.0 + # via flake8 +mypy==1.9.0 + # via flake8-mypy +mypy-extensions==1.0.0 + # via mypy +packaging==24.0 + # via + # pyproject-api + # pytest + # tox +platformdirs==4.2.0 + # via + # tox + # virtualenv +pluggy==1.4.0 + # via + # pytest + # tox +pycodestyle==2.11.1 + # via + # flake8 + # flake8-print +pyflakes==3.2.0 + # via flake8 +pyproject-api==1.6.1 + # via tox +pytest==8.1.1 + # via -r requirements.in/dev.txt +pyyaml==6.0.1 + # via -r requirements.in/base.txt +tomli==2.0.1 + # via + # mypy + # pyproject-api + # pytest + # tox +tornado==6.4 + # via -r requirements.in/base.txt +tox==4.14.1 + # via -r requirements.in/dev.txt +typing-extensions==4.10.0 + # via mypy +virtualenv==20.25.1 + # via tox -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 15:45:23
|
via bdd6c9c6edabbc43f6cb53f33de5b978f3285f08 (commit) via 66263ccf9e868b8f52025d15cab20e0874e6372f (commit) from 93cc1272122b719a06f08ef6e39369b0d5e6e058 (commit) ----------------------------------------------------------------------- commit bdd6c9c6edabbc43f6cb53f33de5b978f3285f08 Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 11:39:15 2024 -0400 fix: convert CI macos pyyaml dep to homebrew I have some reservations about this, but once any python stuff at all is installed via homebrew, it becomes hard to go back. commit 66263ccf9e868b8f52025d15cab20e0874e6372f Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 11:34:22 2024 -0400 fix: update some CI python versions Python 3.6 no longer works here. I believe we've gotten all servers past eol python versions at this point, so it's safe to only test current versions. Also, I (conservatively) updated the python 3.7 installs for catch2 tests to 3.8. This could probably go further? ----------------------------------------------------------------------- Summary of changes: .github/workflows/ci.yml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6443932d8a..53973118cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,10 +120,10 @@ jobs: - name: Fix tags for release # work around https://github.com/actions/checkout/issues/882 if: github.event.release.tag_name != null run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # will break on a lightweight tag - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Install requirements.txt run: | python -m pip install --upgrade pip @@ -316,8 +316,7 @@ jobs: | grep -q ^/Library/Frameworks/Python.framework/Versions/' _ {} \; -exec rm -v {} \; - name: Install Dependencies run: | - brew install pkg-config libpng - sudo -H pip3 install PyYAML + brew install pkg-config libpng pyyaml - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 with: @@ -363,10 +362,10 @@ jobs: auth_header="$(git config --local --get http.https://github.com/.extraheader)" git submodule sync --recursive git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Install requirements.txt run: | python -m pip install --upgrade pip @@ -422,10 +421,10 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 # all history - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Install requirements.txt run: | python -m pip install --upgrade pip @@ -470,7 +469,9 @@ jobs: runs-on: ubuntu-20.04 # TODO: go back to ubuntu-latest strategy: matrix: - python-version: [3.6, 3.7, 3.8] + # oldest non-eol security release + current bugfix versions + # https://devguide.python.org/versions/ + python-version: [3.8, 3.11, 3.12] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} @@ -514,10 +515,10 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 # all history - - name: Set up Python 3.7 + - name: Set up Python 3.8 uses: actions/setup-python@v4 with: - python-version: 3.7 + python-version: 3.8 - name: Install requirements.txt run: | python -m pip install --upgrade pip -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 15:25:14
|
via 93cc1272122b719a06f08ef6e39369b0d5e6e058 (commit) from f73a246b04ad4c364ad309e282f57646f2e42811 (commit) ----------------------------------------------------------------------- commit 93cc1272122b719a06f08ef6e39369b0d5e6e058 Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 11:21:16 2024 -0400 fix: possibly unbreak macos CI pip3 call This will probably fix this immediate call, but it's unclear to me whether the fixed version will install pyyaml in the right place. ----------------------------------------------------------------------- Summary of changes: .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4992e9ae2b..6443932d8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -317,7 +317,7 @@ jobs: - name: Install Dependencies run: | brew install pkg-config libpng - sudo pip3 install PyYAML + sudo -H pip3 install PyYAML - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 with: -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 14:55:21
|
via f73a246b04ad4c364ad309e282f57646f2e42811 (commit) from a50f3326c405b0f502dc6d57b52de72be468b04c (commit) ----------------------------------------------------------------------- commit f73a246b04ad4c364ad309e282f57646f2e42811 Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 10:48:11 2024 -0400 fix: reorder some CI steps Homebrew and system installed python have an unfortunate interaction from time to time. Most recent github statement on this: https://github.com/actions/runner-images/issues/9471#issuecomment-1984202712 We already had a workaround in place from c6129fcb3f40, but it is not working for the current round of the bug. I think reordering should be the fix. Previously this CI issue must have triggered later in our build process (currently unclear to me how; maybe the brew calls in the prior step only recently triggered a dependency upgrade; right now the culprit is libpng). This commit should ensure it is always triggered before any brew calls. ----------------------------------------------------------------------- Summary of changes: .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 085bb44f0a..4992e9ae2b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -310,14 +310,14 @@ jobs: auth_header="$(git config --local --get http.https://github.com/.extraheader)" git submodule sync --recursive git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1 - - name: Install Dependencies - run: | - brew install pkg-config libpng - sudo pip3 install PyYAML - name: Python install bug workaround # https://github.com/actions/setup-python/issues/577 run: | find /usr/local/bin -type l -exec sh -c 'readlink -f "$1" \ | grep -q ^/Library/Frameworks/Python.framework/Versions/' _ {} \; -exec rm -v {} \; + - name: Install Dependencies + run: | + brew install pkg-config libpng + sudo pip3 install PyYAML - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 with: -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 14:25:16
|
via a50f3326c405b0f502dc6d57b52de72be468b04c (commit) from c8563f6773ecfd61cef1c4a1ca094e5abb82359e (commit) ----------------------------------------------------------------------- commit a50f3326c405b0f502dc6d57b52de72be468b04c Author: Kyle Rawlins <ra...@gm...> Date: Sun Mar 17 10:21:08 2024 -0400 fix: convert some string `+`s to `make_stringf` Crawl string templating is all over the place, but imo using + for templating is the worst of the available options. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/describe-spells.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/crawl-ref/source/describe-spells.cc b/crawl-ref/source/describe-spells.cc index 54b42b577c..4fa3f2aa6e 100644 --- a/crawl-ref/source/describe-spells.cc +++ b/crawl-ref/source/describe-spells.cc @@ -161,11 +161,9 @@ static void _monster_spellbooks(const monster_info &mi, spellbook_contents output_book; - output_book.label += - "\n" + - uppercase_first(mi.pronoun(PRONOUN_SUBJECTIVE)) + - " " + - _booktype_header(type, mi.pronoun_plurality()); + output_book.label += make_stringf("\n%s %s", + uppercase_first(mi.pronoun(PRONOUN_SUBJECTIVE)).c_str(), + _booktype_header(type, mi.pronoun_plurality()).c_str()); // Does the monster have a spell that allows them to cast Abjuration? bool mons_abjure = false; @@ -205,11 +203,9 @@ static void _monster_wand_spellbook(const monster_info &mi, spellbook_contents book; - book.label += - "\n" + - uppercase_first(mi.pronoun(PRONOUN_SUBJECTIVE)) + - " " + - _booktype_header(MON_SPELL_EVOKE, mi.pronoun_plurality()); + book.label += make_stringf("\n%s %s", + uppercase_first(mi.pronoun(PRONOUN_SUBJECTIVE)).c_str(), + _booktype_header(MON_SPELL_EVOKE, mi.pronoun_plurality()).c_str()); const wand_type wandtyp = static_cast<wand_type>(wand->sub_type); ASSERT(wandtyp < NUM_WANDS); -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 05:30:19
|
via c8563f6773ecfd61cef1c4a1ca094e5abb82359e (commit) from 1ee7915d7e3dd950a708c7ec125693eb2beb0dd4 (commit) ----------------------------------------------------------------------- commit c8563f6773ecfd61cef1c4a1ca094e5abb82359e Author: Nicholas Feinberg <ple...@gm...> Date: Sat Mar 16 22:24:38 2024 -0700 Fix multiple spell list lettering (SentientSupper) Spell lists with three or more sections (e.g. natural + magical + wand spells) would be lettered incorrectly, as would various other cases. Fix this by simplifying lettering. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/describe-spells.cc | 36 ++++++------------------------------ crawl-ref/source/describe-spells.h | 3 +-- crawl-ref/source/describe.cc | 4 ++-- 3 files changed, 9 insertions(+), 34 deletions(-) diff --git a/crawl-ref/source/describe-spells.cc b/crawl-ref/source/describe-spells.cc index c5281cdbea..54b42b577c 100644 --- a/crawl-ref/source/describe-spells.cc +++ b/crawl-ref/source/describe-spells.cc @@ -342,19 +342,6 @@ static string _spell_schools(spell_type spell) } /** - * Should spells from the given source be listed in two columns instead of - * one? - * - * @param source_item The source of the spells; a book, or nullptr in the - * case of monster spellbooks. - * @return source_item == nullptr - */ -static bool _list_spells_doublecolumn(const item_def* const source_item) -{ - return !source_item; -} - -/** * Produce a mapping from characters (used as indices) to spell types in * the given spellset. * @@ -365,24 +352,13 @@ static bool _list_spells_doublecolumn(const item_def* const source_item) * either in original order or column-major order, the * latter in the case of a double-column layout. */ -vector<pair<spell_type,char>> map_chars_to_spells(const spellset &spells, - const item_def* const source_item) +vector<pair<spell_type,char>> map_chars_to_spells(const spellset &spells) { char next_ch = 'a'; const vector<spell_type> flat_spells = _spellset_contents(spells); vector<pair<spell_type,char>> ret; - if (!_list_spells_doublecolumn(source_item)) - { - for (auto spell : flat_spells) - ret.emplace_back(pair<spell_type,char>(spell, next_ch++)); - } - else - { - for (size_t i = 0; i < flat_spells.size(); i += 2) - ret.emplace_back(pair<spell_type,char>(flat_spells[i], next_ch++)); - for (size_t i = 1; i < flat_spells.size(); i += 2) - ret.emplace_back(pair<spell_type,char>(flat_spells[i], next_ch++)); - } + for (auto spell : flat_spells) + ret.emplace_back(pair<spell_type,char>(spell, next_ch++)); return ret; } @@ -606,7 +582,7 @@ static void _describe_book(const spellbook_contents &book, description.cprintf("\n"); // list spells in two columns, instead of one? (monster books) - const bool doublecolumn = _list_spells_doublecolumn(source_item); + const bool doublecolumn = source_item == nullptr; bool first_line_element = true; const int hd = mon_owner ? mon_owner->spell_hd() : 0; @@ -701,7 +677,7 @@ void describe_spellset(const spellset &spells, formatted_string &description, const monster_info *mon_owner) { - auto spell_map = map_chars_to_spells(spells, source_item); + auto spell_map = map_chars_to_spells(spells); for (auto book : spells) _describe_book(book, spell_map, source_item, description, mon_owner); } @@ -757,7 +733,7 @@ void write_spellset(const spellset &spells, const item_def* const source_item, const monster_info *mon_owner) { - auto spell_map = map_chars_to_spells(spells, source_item); + auto spell_map = map_chars_to_spells(spells); tiles.json_open_array("spellset"); for (auto book : spells) _write_book(book, spell_map, source_item, mon_owner); diff --git a/crawl-ref/source/describe-spells.h b/crawl-ref/source/describe-spells.h index 900734cfa8..aab1baf39e 100644 --- a/crawl-ref/source/describe-spells.h +++ b/crawl-ref/source/describe-spells.h @@ -28,8 +28,7 @@ typedef vector<spellbook_contents> spellset; spellset item_spellset(const item_def &item); spellset monster_spellset(const monster_info &mi); -vector<pair<spell_type,char>> map_chars_to_spells(const spellset &spells, - const item_def* const source_item); +vector<pair<spell_type,char>> map_chars_to_spells(const spellset &spells); void describe_spellset(const spellset &spells, const item_def* const source_item, formatted_string &description, diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 5606803f1e..c4140160e0 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -4153,7 +4153,7 @@ command_type describe_item_popup(const item_def &item, else if (scroller->on_event(ev)) return true; - const vector<pair<spell_type,char>> spell_map = map_chars_to_spells(spells, &item); + const vector<pair<spell_type,char>> spell_map = map_chars_to_spells(spells); auto entry = find_if(spell_map.begin(), spell_map.end(), [key](const pair<spell_type,char>& e) { return e.second == key; }); if (entry == spell_map.end()) @@ -6484,7 +6484,7 @@ int describe_monsters(const monster_info &mi, const string& /*footer*/) } if (desc_sw->current_widget()->on_event(ev)) return true; - const vector<pair<spell_type,char>> spell_map = map_chars_to_spells(spells, nullptr); + const vector<pair<spell_type,char>> spell_map = map_chars_to_spells(spells); auto entry = find_if(spell_map.begin(), spell_map.end(), [key](const pair<spell_type,char>& e) { return e.second == key; }); if (entry == spell_map.end()) -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 02:55:20
|
via 1ee7915d7e3dd950a708c7ec125693eb2beb0dd4 (commit) via 66358920a50e90cde4d3eeee5ce5bd6abfe5a50f (commit) from 54de21ab3573ef318df3e5bb85e652e1645e5097 (commit) ----------------------------------------------------------------------- commit 1ee7915d7e3dd950a708c7ec125693eb2beb0dd4 Author: SentientSupper <tro...@gm...> Date: Sat Mar 16 14:57:25 2024 +0800 Display PE center targets with more opacity Display permafrost center targets with more opacity. This includes a nonstandard use of AFF_YES but I don't think any players would complain. commit 66358920a50e90cde4d3eeee5ce5bd6abfe5a50f Author: bjiorn <bj...@gm...> Date: Sat Mar 16 16:15:27 2024 +0100 Fix max HP value in description of your ancestor Previously the value was not up-to-date after gaining a level until your ancestor died and respawned. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/religion.cc | 1 + crawl-ref/source/target.cc | 7 +++++-- crawl-ref/source/target.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index 6a28e2c2ee..782efe7b61 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -1815,6 +1815,7 @@ void upgrade_hepliaklqana_ancestor(bool quiet_force) const int old_mhp = ancestor->max_hit_points; ancestor->max_hit_points = hepliaklqana_ally_hp(); + ancestor->props[KNOWN_MAX_HP_KEY] = ancestor->max_hit_points; ancestor->hit_points = div_rand_round(ancestor->hit_points * ancestor->max_hit_points, old_mhp); diff --git a/crawl-ref/source/target.cc b/crawl-ref/source/target.cc index e8b5347438..6026ef4024 100644 --- a/crawl-ref/source/target.cc +++ b/crawl-ref/source/target.cc @@ -667,7 +667,7 @@ bool targeter_transference::valid_aim(coord_def a) targeter_permafrost::targeter_permafrost(const actor &act, int power) : targeter_smite(&act) { - set<coord_def> possible_centres = permafrost_targets(act, power, false); + possible_centres = permafrost_targets(act, power, false); for (coord_def t : possible_centres) { targets.insert(t); @@ -680,9 +680,12 @@ targeter_permafrost::targeter_permafrost(const actor &act, int power) : aff_type targeter_permafrost::is_affected(coord_def loc) { - // TODO: consider displaying each centre differently from the AOEs. if (targets.count(loc)) + { + if (possible_centres.count(loc)) + return single_target ? AFF_MULTIPLE : AFF_YES; return single_target ? AFF_YES : AFF_MAYBE; + } return AFF_NO; } diff --git a/crawl-ref/source/target.h b/crawl-ref/source/target.h index 3df3e863a6..329ecb4c23 100644 --- a/crawl-ref/source/target.h +++ b/crawl-ref/source/target.h @@ -123,6 +123,7 @@ public: aff_type is_affected(coord_def loc) override; private: set<coord_def> targets; + set<coord_def> possible_centres; bool single_target; }; -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 02:50:13
|
via 54de21ab3573ef318df3e5bb85e652e1645e5097 (commit) from a9a889f0c69d2b368242742f89504324bc5d4789 (commit) ----------------------------------------------------------------------- commit 54de21ab3573ef318df3e5bb85e652e1645e5097 Author: Nicholas Feinberg <ple...@gm...> Date: Sat Mar 16 19:49:36 2024 -0700 Don't crash on \ Broken in 95338c156ce86d7b4b3cb89f98aa10beac2d877e etc. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/item-prop.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crawl-ref/source/item-prop.cc b/crawl-ref/source/item-prop.cc index f5c3778273..53668cccf2 100644 --- a/crawl-ref/source/item-prop.cc +++ b/crawl-ref/source/item-prop.cc @@ -2093,6 +2093,8 @@ bool staff_uses_evocations(const item_def &item) const char* staff_type_name(stave_type s) { + if (s == NUM_STAVES) + return "bugginess"; // used for known items ASSERT_RANGE(s, 0, NUM_STAVES); return Staff_prop[Staff_index[s]].name; } -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 02:40:15
|
via a9a889f0c69d2b368242742f89504324bc5d4789 (commit) via fbd0129fbb88ee18cb3b0869d5882ec24f0bc4ed (commit) from c23bbe546e95ad9409740f9591a39e115f60c5ae (commit) ----------------------------------------------------------------------- commit a9a889f0c69d2b368242742f89504324bc5d4789 Author: Nicholas Feinberg <ple...@gm...> Date: Sat Mar 16 19:37:57 2024 -0700 Remove buggy handling for un-ID'd wands This logic would hide *all* spells for monsters with un-ID'd wands. Players should no longer ever see monsters with un-ID'd wands, so add an assert instead. commit fbd0129fbb88ee18cb3b0869d5882ec24f0bc4ed Author: Nicholas Feinberg <ple...@gm...> Date: Sat Mar 16 19:37:01 2024 -0700 Fix momentarily un-ID'd monster wands (SentientSupper) We had old monster info cached for a turn, meaning that you could see ijyb come into view with 'a wand of flame', xv them immediately, and see them holding 'a forked gold wand' instead. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/delay.cc | 2 ++ crawl-ref/source/describe-spells.cc | 1 + crawl-ref/source/mon-info.cc | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index 26a268f772..6be48226cd 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -1236,7 +1236,9 @@ static inline bool _monster_warning(activity_interrupt ai, god_warning += "shapeshifter."; } + // Refresh our monster info cache, so xv shows the ID'd items. monster_info mi(mon); + env.map_knowledge(mon->pos()).set_monster(mi); const string mweap = get_monster_equipment_desc(mi, DESC_IDENTIFIED, DESC_NONE); diff --git a/crawl-ref/source/describe-spells.cc b/crawl-ref/source/describe-spells.cc index c147846756..c5281cdbea 100644 --- a/crawl-ref/source/describe-spells.cc +++ b/crawl-ref/source/describe-spells.cc @@ -212,6 +212,7 @@ static void _monster_wand_spellbook(const monster_info &mi, _booktype_header(MON_SPELL_EVOKE, mi.pronoun_plurality()); const wand_type wandtyp = static_cast<wand_type>(wand->sub_type); + ASSERT(wandtyp < NUM_WANDS); book.spells.emplace_back(spell_in_wand(wandtyp)); all_books.emplace_back(book); diff --git a/crawl-ref/source/mon-info.cc b/crawl-ref/source/mon-info.cc index 12c4d812ca..97f848acb2 100644 --- a/crawl-ref/source/mon-info.cc +++ b/crawl-ref/source/mon-info.cc @@ -1673,8 +1673,7 @@ bool monster_info::has_spells() const // Wand spells const item_def* wand = inv[MSLOT_WAND].get(); if (itemuse() >= MONUSE_STARTING_EQUIPMENT && wand) - return wand->sub_type < NUM_WANDS; // NUM_WANDS used for unknown wands - // XXX can this ever happen? + return true; const mon_spellbook_type book = get_spellbook(*this); -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 02:15:20
|
via c23bbe546e95ad9409740f9591a39e115f60c5ae (commit) via 79873398bf2fd1621e847949c4d8d6c2ab8eabb9 (commit) from 95338c156ce86d7b4b3cb89f98aa10beac2d877e (commit) ----------------------------------------------------------------------- commit c23bbe546e95ad9409740f9591a39e115f60c5ae Author: Nicholas Feinberg <ple...@gm...> Date: Sat Mar 16 19:14:02 2024 -0700 Wand description refactoring Following 0bf9c4c012e350145fa2752b77bbbcd8f03b9586. commit 79873398bf2fd1621e847949c4d8d6c2ab8eabb9 Author: Nicholas Feinberg <ple...@gm...> Date: Sat Mar 16 19:02:23 2024 -0700 Further revise wand spell descriptions There's no good way to explain why players are affected differently by some spells than monsters are, but we can try to be a little less blunt than 0bf9c4c012e350145fa2752b77bbbcd8f03b9586. Also, fix Fastroot's name. It's a pun! ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/dat/descript/spells.txt | 19 ++++++++++--------- crawl-ref/source/describe-spells.cc | 26 +++++++------------------- crawl-ref/source/mon-info.cc | 3 ++- crawl-ref/source/mon-util.cc | 5 +---- crawl-ref/source/spl-data.h | 2 +- 5 files changed, 21 insertions(+), 34 deletions(-) diff --git a/crawl-ref/source/dat/descript/spells.txt b/crawl-ref/source/dat/descript/spells.txt index 8b6ef0bce1..d7d9bb3b2c 100644 --- a/crawl-ref/source/dat/descript/spells.txt +++ b/crawl-ref/source/dat/descript/spells.txt @@ -179,8 +179,9 @@ Fires a penetrating bolt of flames. %%%% Bolt of Light spell -Fires a ray of searing light, injuring and blinding those struck. Confuses -instead of blinding if you are hit. +Fires a ray of searing light, injuring those struck. Inhabitants of the dungeon +will also be blinded, while adventurers (more accustomed to light) will merely +suffer momentary confusion. %%%% Bolt of Magma spell @@ -306,7 +307,7 @@ The spell bypasses half of defenders' armour and resistance to electricity. Charm spell Causes an otherwise hostile creature to fight on the caster's side for a while. -Confuses instead of charming if you are affected. +Adventurers, set on their quest for the ORB, instead suffer momentary confusion. %%%% Chaos Breath spell @@ -568,6 +569,12 @@ Eruption spell Splits the earth to draw up a localized, short-lived volcano under the target. %%%% +Fastroot spell + +Fire a magical seed, entangling victims in quick-growing tree roots. Those +entangled will be painfully constricted until they escape or the roots wither +away. The roots will only sprout from solid ground. +%%%% Flay spell Opens painful illusionary wounds on the target's body, which disappear after @@ -675,12 +682,6 @@ Briefly redirects gravity around a target point, causing 'down' to be towards that point. All nearby creatures, save the caster, fall helplessly toward that point â typically colliding with each other, or with a victim standing there. %%%% -Germinate Roots spell - -Fire a magical seed, entangling victims in quick-growing tree roots. Those -entangled will be immobilized and take damage over time until they escape or -the roots wither away. The roots will only sprout from solid ground. -%%%% Ghostly Fireball spell Hurls an exploding ball of negative energy which drains any living creature diff --git a/crawl-ref/source/describe-spells.cc b/crawl-ref/source/describe-spells.cc index b65bddcfd2..c147846756 100644 --- a/crawl-ref/source/describe-spells.cc +++ b/crawl-ref/source/describe-spells.cc @@ -141,19 +141,6 @@ static string _booktype_header(mon_spell_slot_flag type, bool pronoun_plural) vulnerabilities.c_str()); } -static spell_type _get_wand_spell(const monster_info &mi) -{ - const item_def* wand = mi.inv[MSLOT_WAND].get(); - if (wand) - { - const wand_type wandtype = static_cast<wand_type>(wand->sub_type); - // Newly spawned wands have an invalid wand type of NUM_WANDS - if (wandtype < NUM_WANDS) - return spell_in_wand(wandtype); - } - return SPELL_NO_SPELL; -} - /** * Append all spells of a given type that a given monster may know to the * provided vector. @@ -212,21 +199,22 @@ static void _monster_wand_spellbook(const monster_info &mi, if (mi.itemuse() < MONUSE_STARTING_EQUIPMENT) return; - const spell_type wandspell = _get_wand_spell(mi); - if (wandspell == SPELL_NO_SPELL) + const item_def* wand = mi.inv[MSLOT_WAND].get(); + if (!wand) return; - spellbook_contents output_book; + spellbook_contents book; - output_book.label += + book.label += "\n" + uppercase_first(mi.pronoun(PRONOUN_SUBJECTIVE)) + " " + _booktype_header(MON_SPELL_EVOKE, mi.pronoun_plurality()); - output_book.spells.emplace_back(wandspell); + const wand_type wandtyp = static_cast<wand_type>(wand->sub_type); + book.spells.emplace_back(spell_in_wand(wandtyp)); - all_books.emplace_back(output_book); + all_books.emplace_back(book); } /** diff --git a/crawl-ref/source/mon-info.cc b/crawl-ref/source/mon-info.cc index e9e5b0b360..12c4d812ca 100644 --- a/crawl-ref/source/mon-info.cc +++ b/crawl-ref/source/mon-info.cc @@ -1673,7 +1673,8 @@ bool monster_info::has_spells() const // Wand spells const item_def* wand = inv[MSLOT_WAND].get(); if (itemuse() >= MONUSE_STARTING_EQUIPMENT && wand) - return static_cast<wand_type>(wand->sub_type) < NUM_WANDS; + return wand->sub_type < NUM_WANDS; // NUM_WANDS used for unknown wands + // XXX can this ever happen? const mon_spellbook_type book = get_spellbook(*this); diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index b75623c196..cc612a746a 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -2768,12 +2768,9 @@ vector<mon_spell_slot> get_unique_spells(const monster_info &mi, drac_breath(mi.draconian_subspecies()); if (breath.flags & flags && breath.spell != SPELL_NO_SPELL) slots.push_back(breath); - // No other spells; quit right away. - if (book == MST_NO_SPELLS) - return slots; } - // Don't fail the assert if the only spell we have is from a wand + // No other spells (e.g. drac and/or wand); quit right away. if (book == MST_NO_SPELLS) return slots; diff --git a/crawl-ref/source/spl-data.h b/crawl-ref/source/spl-data.h index c5bf9c304c..6ed2253337 100644 --- a/crawl-ref/source/spl-data.h +++ b/crawl-ref/source/spl-data.h @@ -3220,7 +3220,7 @@ static const struct spell_desc spelldata[] = }, { - SPELL_FASTROOT, "Germinate Roots", + SPELL_FASTROOT, "Fastroot", spschool::hexes | spschool::earth, spflag::dir_or_target | spflag::needs_tracer, 5, -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-17 02:00:19
|
via 95338c156ce86d7b4b3cb89f98aa10beac2d877e (commit) from 1a05c61809840435dc1fea234906334fbfd84bcc (commit) ----------------------------------------------------------------------- commit 95338c156ce86d7b4b3cb89f98aa10beac2d877e Author: Nicholas Feinberg <ple...@gm...> Date: Sat Mar 16 18:56:17 2024 -0700 Fix randart stave names (various) Partially reverts 55136d7. Closes #3685. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/item-name.cc | 4 ++-- crawl-ref/source/item-prop.cc | 8 ++++++-- crawl-ref/source/item-prop.h | 9 +++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/crawl-ref/source/item-name.cc b/crawl-ref/source/item-name.cc index bdad96d716..a33b33b7b5 100644 --- a/crawl-ref/source/item-name.cc +++ b/crawl-ref/source/item-name.cc @@ -1189,13 +1189,13 @@ string sub_type_string(const item_def &item, bool known) { case OBJ_WEAPONS: // deliberate fall through, as XXX_prop is a local case OBJ_MISSILES: // variable to item-prop.cc. - case OBJ_STAVES: case OBJ_ARMOUR: return item_base_name(type, sub_type); case OBJ_WANDS: return _wand_type_name(sub_type); case OBJ_SCROLLS: return scroll_type_name(sub_type); case OBJ_JEWELLERY: return jewellery_type_name(sub_type); case OBJ_POTIONS: return potion_type_name(sub_type); + case OBJ_STAVES: return staff_type_name(static_cast<stave_type>(sub_type)); case OBJ_BOOKS: { switch (sub_type) @@ -1893,7 +1893,7 @@ string item_def::name_aux(description_level_type desc, bool terse, bool ident, buff << "staff"; } else - buff << "staff of " << item_base_name(OBJ_STAVES, item_typ); + buff << "staff of " << staff_type_name(static_cast<stave_type>(item_typ)); if (cursed() && terse && !dbname && !qualname) buff << " (curse)"; diff --git a/crawl-ref/source/item-prop.cc b/crawl-ref/source/item-prop.cc index 3e90009a03..f5c3778273 100644 --- a/crawl-ref/source/item-prop.cc +++ b/crawl-ref/source/item-prop.cc @@ -2091,6 +2091,12 @@ bool staff_uses_evocations(const item_def &item) return item.base_type == OBJ_STAVES; } +const char* staff_type_name(stave_type s) +{ + ASSERT_RANGE(s, 0, NUM_STAVES); + return Staff_prop[Staff_index[s]].name; +} + skill_type staff_skill(stave_type s) { ASSERT_RANGE(s, 0, NUM_STAVES); @@ -3195,8 +3201,6 @@ string item_base_name(object_class_type type, int sub_type) { case OBJ_WEAPONS: return Weapon_prop[Weapon_index[sub_type]].name; - case OBJ_STAVES: - return Staff_prop[Staff_index[sub_type]].name; case OBJ_MISSILES: return Missile_prop[Missile_index[sub_type]].name; case OBJ_ARMOUR: diff --git a/crawl-ref/source/item-prop.h b/crawl-ref/source/item-prop.h index 0fdaef6a28..64dedb18be 100644 --- a/crawl-ref/source/item-prop.h +++ b/crawl-ref/source/item-prop.h @@ -103,10 +103,11 @@ special_armour_type get_armour_ego_type(const item_def &item) PURE; special_missile_type get_ammo_brand(const item_def &item) PURE; // staff functions: -skill_type staff_skill(stave_type staff); -beam_type staff_damage_type(stave_type staff); -int staff_damage_mult(stave_type staff); -ac_type staff_ac_check(stave_type staff); +const char* staff_type_name(stave_type staff) PURE; +skill_type staff_skill(stave_type staff) PURE; +beam_type staff_damage_type(stave_type staff) PURE; +int staff_damage_mult(stave_type staff) PURE; +ac_type staff_ac_check(stave_type staff) PURE; // armour functions: bool armour_is_enchantable(const item_def &item) PURE; -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-16 20:55:18
|
via 1a05c61809840435dc1fea234906334fbfd84bcc (commit) via 63684f61033a2946b95a2ce839b2c9e8370d068a (commit) from 65a1bb74738f0371fcd4a9f600f899eee04c7603 (commit) ----------------------------------------------------------------------- commit 1a05c61809840435dc1fea234906334fbfd84bcc Author: wheals <whe...@gm...> Date: Sat Mar 16 22:42:56 2024 +0200 Fix a crash after banishing a challenging apostle (Memoria, Ge0ff) commit 63684f61033a2946b95a2ce839b2c9e8370d068a Author: wheals <whe...@gm...> Date: Sat Mar 16 22:01:27 2024 +0200 Update Beogh vengeance accounting when cloning (#3588). Fixes #3588. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/mon-clone.cc | 3 +++ crawl-ref/source/mon-death.cc | 5 ++++- crawl-ref/source/tag-version.h | 1 + crawl-ref/source/tags.cc | 7 +++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/crawl-ref/source/mon-clone.cc b/crawl-ref/source/mon-clone.cc index 1281b6de67..aa0ba432ae 100644 --- a/crawl-ref/source/mon-clone.cc +++ b/crawl-ref/source/mon-clone.cc @@ -332,6 +332,9 @@ monster* clone_mons(const monster* orig, bool quiet, bool* obvious, if (mons->has_ench(ENCH_TOUCH_OF_BEOGH)) mons->del_ench(ENCH_TOUCH_OF_BEOGH); + if (mons->has_ench(ENCH_VENGEANCE_TARGET)) + you.duration[DUR_BEOGH_SEEKING_VENGEANCE] += 1; + // Duplicate objects, or unequip them if they can't be duplicated. for (mon_inv_iterator ii(*mons); ii; ++ii) { diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc index 70c55a9611..5d761fca5e 100644 --- a/crawl-ref/source/mon-death.cc +++ b/crawl-ref/source/mon-death.cc @@ -828,7 +828,10 @@ static bool _monster_avoided_death(monster* mons, killer_type killer, simple_god_message(" pulls their child back from the Abyss.", GOD_BEOGH); win_apostle_challenge(*mons); - mons->hit_points = mons->max_hit_points; + mons->heal(mons->max_hit_points); + // monster::banish sets damage_friendly and not resetting that could + // crash. monster::heal resets it but not if it was at full health. + mons->damage_total = mons->damage_friendly = 0; avoided_death_fineff::schedule(mons); return true; } diff --git a/crawl-ref/source/tag-version.h b/crawl-ref/source/tag-version.h index a71ff48ff2..b600167e21 100644 --- a/crawl-ref/source/tag-version.h +++ b/crawl-ref/source/tag-version.h @@ -303,6 +303,7 @@ enum tag_minor_version TAG_MINOR_NEW_DRACONIAN_BREATH, // Add charges to draconian breaths, revamp effects TAG_MINOR_COGLIN_NO_JEWELLERY, // Remove all jewellery from Coglins TAG_MINOR_TALISMANS_SEEN, // Keep track of seen talismans + TAG_MINOR_FIX_APOSTLE_DAMAGE, // Fix damage tracking of banished apostles #endif NUM_TAG_MINORS, TAG_MINOR_VERSION = NUM_TAG_MINORS - 1 diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 8dc36229a6..df80e4150f 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -7486,6 +7486,13 @@ static void _tag_read_level_monsters(reader &th) dprf("Killed elsewhere companion %s(%d) on %s", m.name(DESC_PLAIN, true).c_str(), m.mid, level_id::current().describe(false, true).c_str()); +#if TAG_MAJOR_VERSION == 34 + if (th.getMinorVersion() < TAG_MINOR_FIX_APOSTLE_DAMAGE + && m.damage_friendly > m.damage_total) + { + m.damage_total = m.damage_friendly = 0; + } +#endif monster_die(m, KILL_RESET, -1, true, false); // avoid "mid cache bogosity" if there's an unhandled clone bug if (dup_m && dup_m->alive()) -- Dungeon Crawl Stone Soup |
From: <gi...@cr...> - 2024-03-16 18:00:23
|
via 65a1bb74738f0371fcd4a9f600f899eee04c7603 (commit) from ad064519fa692f5c0dfafcee26cc02ee7d619f2b (commit) ----------------------------------------------------------------------- commit 65a1bb74738f0371fcd4a9f600f899eee04c7603 Author: David Lawrence Ramsey <poo...@gm...> Date: Sat Mar 16 12:55:44 2024 -0500 Fix comment typo. ----------------------------------------------------------------------- Summary of changes: crawl-ref/source/player-reacts.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crawl-ref/source/player-reacts.cc b/crawl-ref/source/player-reacts.cc index 412389ac08..373ba134ca 100644 --- a/crawl-ref/source/player-reacts.cc +++ b/crawl-ref/source/player-reacts.cc @@ -370,7 +370,7 @@ static void _update_cowardice() mpr("You feel a twist of horror at the sight of this foe."); } -// Uskawyaw piety decays incredibly fast, but only to a baseline level of *. +// Uskayaw piety decays incredibly fast, but only to a baseline level of *. // Using Uskayaw abilities can still take you under *. static void _handle_uskayaw_piety(int time_taken) { -- Dungeon Crawl Stone Soup |