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
(220) |
Apr
(112) |
May
(162) |
Jun
(169) |
Jul
(205) |
Aug
(174) |
Sep
(73) |
Oct
(62) |
Nov
(95) |
Dec
(62) |
| 2025 |
Jan
(125) |
Feb
(90) |
Mar
(127) |
Apr
(188) |
May
(74) |
Jun
(59) |
Jul
(154) |
Aug
(117) |
Sep
(125) |
Oct
(157) |
Nov
(251) |
Dec
(34) |
|
From: <gi...@cr...> - 2025-12-04 19:00:15
|
at d7672b400019cd6ce88e3d3d6d3048f0d791969c (commit)
-----------------------------------------------------------------------
commit d7672b400019cd6ce88e3d3d6d3048f0d791969c
Author: hellmonk <nld...@gm...>
Date: Thu Dec 4 12:49:02 2025 -0600
Sludge Elves
Sludge elves were removed in version 0.13 for largely being worse than other
species in all of their supposed niches. This is an attempt to return them
in a more distinct role.
Sludge elves are slightly good at unarmed combat and shapeshifting as before,
with mostly flat aptitudes elsewhere. However, they begin the game with the
protean grace mutation and a "natural shifter" mutation that provides AC and
intelligence while in any form. Additionally, they get one random good mutation
at level 4 and receive an "innate" high-skill form at level 10. They can freely
transform into their innate form without a talisman and receive a skill bonus
with that form (whether from a talisman or not).
My hope is that this species provides a different take on shapeshifting than
species like octopode and draconian, while remaining somewhat flexible overall.
(TODO before merging: refactor some of this messy code, extensive playtesting,
and tiles.)
-----------------------------------------------------------------------
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-04 18:55:15
|
via 3d4d16ab83bbe094104be8b285b3eb9804d19e27 (commit)
from 5710f06dab9fdb6eec60da92f0b4cf3a83d82427 (commit)
-----------------------------------------------------------------------
commit 3d4d16ab83bbe094104be8b285b3eb9804d19e27
Author: DracoOmega <dra...@gm...>
Date: Thu Dec 4 15:21:31 2025 -0330
Fix player orbs often preventing blocks from working (WizardIke)
An orb the player had equipped would be returned by you.shield(), despite
not being a shield. This had the indirect effect of preventing the player
from blocking many things, due to the block limit of an orb being 0.
(Whereas not having any 'shield' at all gives a block limit of 1). This
meant that, no matter how many other sources of SH the player might have,
such as amulets of reflection, Qazlal, or mutations, they would be unable
to block. Even Divine Shield didn't work on spell projectiles (though, by
coincidental differences in codepath, it did work on melee and ranged
attacks).
Now player::shield() can only return actual shields (amusingly enough,
monster::shield() did already work properly). actor::offhand_item() is
added for the few cases where we just want to know if some non-weapon is
taking up that slot, whether a shield or not.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/actor.h | 1 +
crawl-ref/source/hints.cc | 5 +----
crawl-ref/source/mon-cast.cc | 2 +-
crawl-ref/source/monster.cc | 9 +++++++--
crawl-ref/source/monster.h | 1 +
crawl-ref/source/ng-setup.cc | 2 +-
crawl-ref/source/player-act.cc | 8 +++++++-
crawl-ref/source/player.cc | 7 ++++---
crawl-ref/source/player.h | 1 +
9 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/crawl-ref/source/actor.h b/crawl-ref/source/actor.h
index 99e145e030..90bd728fcd 100644
--- a/crawl-ref/source/actor.h
+++ b/crawl-ref/source/actor.h
@@ -104,6 +104,7 @@ public:
bool rescale = true) const = 0;
virtual int has_claws(bool allow_tran = true) const = 0;
virtual item_def *shield() const = 0;
+ virtual item_def *offhand_item() const = 0;
virtual item_def *body_armour() const = 0;
virtual int wearing(object_class_type obj_type, int sub_type,
bool count_plus = 0, bool check_attuned = false) const = 0;
diff --git a/crawl-ref/source/hints.cc b/crawl-ref/source/hints.cc
index f5f0247f8a..9f18733baf 100644
--- a/crawl-ref/source/hints.cc
+++ b/crawl-ref/source/hints.cc
@@ -1699,11 +1699,8 @@ void learned_something_new(hints_event_type seen_what, coord_def gc)
}
print_hint("HINT_YOU_MISCAST");
- if (!player_effectively_in_light_armour()
- || is_shield(you.shield()))
- {
+ if (!player_effectively_in_light_armour() || you.shield())
print_hint("HINT_MISCAST_ARMOUR");
- }
print_hint("HINT_MISCAST_CONTAMINATION_AND_MP");
break;
diff --git a/crawl-ref/source/mon-cast.cc b/crawl-ref/source/mon-cast.cc
index f38a4f5db1..6e9be72ea8 100644
--- a/crawl-ref/source/mon-cast.cc
+++ b/crawl-ref/source/mon-cast.cc
@@ -7003,7 +7003,7 @@ static void _cast_bestow_arms(monster& caster)
targs.push_back(*mi);
- if (!mi->shield())
+ if (!mi->offhand_item())
two_hand_eligable = true;
// Attempting to give a ranged weapon to a dual-wielder is strange
diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc
index 01cb4d9d5b..68f694d57b 100644
--- a/crawl-ref/source/monster.cc
+++ b/crawl-ref/source/monster.cc
@@ -2025,11 +2025,16 @@ item_def *monster::shield() const
{
item_def *shield = mslot_item(MSLOT_SHIELD);
- if (shield && shield->sub_type != ARM_ORB)
+ if (shield && is_shield(*shield))
return shield;
return nullptr;
}
+item_def *monster::offhand_item() const
+{
+ return mslot_item(MSLOT_SHIELD);
+}
+
item_def* monster::body_armour() const
{
return mslot_item(MSLOT_ARMOUR);
@@ -3030,7 +3035,7 @@ int monster::shield_class() const
{
int sh = 0;
const item_def *shld = shield();
- if (shld && is_shield(*shld))
+ if (shld)
{
// Look, this is all nonsense.
// First, take the item properties.
diff --git a/crawl-ref/source/monster.h b/crawl-ref/source/monster.h
index b8857736b6..60e27a90e5 100644
--- a/crawl-ref/source/monster.h
+++ b/crawl-ref/source/monster.h
@@ -300,6 +300,7 @@ public:
item_def *melee_weapon() const;
item_def *missiles() const;
item_def *shield() const override;
+ item_def *offhand_item() const override;
item_def *body_armour() const override;
item_def *get_defining_object() const;
diff --git a/crawl-ref/source/ng-setup.cc b/crawl-ref/source/ng-setup.cc
index 80e4c950a1..74ed9925c6 100644
--- a/crawl-ref/source/ng-setup.cc
+++ b/crawl-ref/source/ng-setup.cc
@@ -224,7 +224,7 @@ static void _give_job_spells(job_type job)
static void _give_offhand_weapon()
{
const item_def *wpn = you.weapon();
- if (!wpn || you.shield() || you.hands_reqd(*wpn) != HANDS_ONE)
+ if (!wpn || you.offhand_item() || you.hands_reqd(*wpn) != HANDS_ONE)
return;
if (is_range_weapon(*wpn))
{
diff --git a/crawl-ref/source/player-act.cc b/crawl-ref/source/player-act.cc
index d2265a8626..4638b01dd8 100644
--- a/crawl-ref/source/player-act.cc
+++ b/crawl-ref/source/player-act.cc
@@ -354,11 +354,17 @@ hands_reqd_type player::hands_reqd(const item_def &item, bool base) const
item_def *player::shield() const
{
item_def *offhand_item = you.equipment.get_first_slot_item(SLOT_OFFHAND, false);
- if (!offhand_item || offhand_item->base_type != OBJ_ARMOUR)
+ if (!offhand_item || !is_shield(*offhand_item))
return nullptr;
return offhand_item;
}
+// Returns any non-weapon item the player has in their offhand (ie: a shield or an orb)
+item_def *player::offhand_item() const
+{
+ return you.equipment.get_first_slot_item(SLOT_OFFHAND, false);
+}
+
item_def* player::body_armour() const
{
return you.equipment.get_first_slot_item(SLOT_BODY_ARMOUR);
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index c5d3d21751..9265c5990d 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -2296,7 +2296,7 @@ int player_shield_class(int scale, bool random, bool ignore_temporary)
return 0;
const item_def *shield_item = you.shield();
- if (is_shield(shield_item))
+ if (shield_item)
shield += _sh_from_shield(*shield_item);
// mutations
@@ -6111,8 +6111,9 @@ void player::shield_block_succeeded(actor *attacker)
shield_blocks++;
practise_shield_block();
- if (is_shield(shield()))
- count_action(CACT_BLOCK, shield()->sub_type);
+ item_def* sh = shield();
+ if (sh)
+ count_action(CACT_BLOCK, sh->sub_type);
else
count_action(CACT_BLOCK, -1, BLOCK_OTHER); // non-shield block
}
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 75721b3a0b..f61ceb3e64 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -705,6 +705,7 @@ public:
item_def *weapon(int which_attack = -1) const override;
item_def *body_armour() const override;
item_def *shield() const override;
+ item_def *offhand_item() const override;
item_def *offhand_weapon() const override;
item_def *active_talisman() const;
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-04 17:10:15
|
via 5710f06dab9fdb6eec60da92f0b4cf3a83d82427 (commit)
from 9e2179861ec4accfd3ced83639dcd004ba15abcb (commit)
-----------------------------------------------------------------------
commit 5710f06dab9fdb6eec60da92f0b4cf3a83d82427
Author: patrick <xd...@gm...>
Date: Thu Dec 4 12:08:47 2025 -0500
Make a few small fixes to overflow altars
fedhas_altar_fruit_tree: remove a spurious C that got slipped into the
map somehow
vehumet_statue: put back a removed SHUFFLE so now the second kind of
statue can appear
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/des/altar/overflow.des | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/crawl-ref/source/dat/des/altar/overflow.des b/crawl-ref/source/dat/des/altar/overflow.des
index c763f01469..909af20c3a 100644
--- a/crawl-ref/source/dat/des/altar/overflow.des
+++ b/crawl-ref/source/dat/des/altar/overflow.des
@@ -907,7 +907,7 @@ xtttttttttttttttx
xtttttt...ttttttx
xtttttg...gtttttx
xtttt.......ttttx
-xtttf..._C...ftttx
+xtttf..._...ftttx
xttt.........tttx
xtt...e...e...ttx
xttdt.......tdttx
@@ -3429,6 +3429,7 @@ ENDMAP
NAME: vehumet_statue
TAGS: transparent
DEPTH: D:3-12
+SHUFFLE: 12
MONS: statue name:charred name_adjective tile:mons_statue_mage \
hp:12 hd:3 spells:throw_flame.53.magical
MONS: statue name:frost-covered name_adjective tile:mons_statue_mage \
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-04 07:05:15
|
via 9e2179861ec4accfd3ced83639dcd004ba15abcb (commit)
from d7418c7e04b6be3e21a3df9889984769620c3177 (commit)
-----------------------------------------------------------------------
commit 9e2179861ec4accfd3ced83639dcd004ba15abcb
Author: Isaac Clancy <ik...@ya...>
Date: Thu Dec 4 17:17:56 2025 +1300
Fix "input" messages from client being reordered
All the messages that the webtiles client sends back to the server
should arrive in the order they were send. However, due to the way in
which we were converting messages of type "input" into console input, it
could be reordered with respect to other messages. Commit fc0747a made
it common for "input" messages to be reordered before other messages
that give keycodes instead of being extremely rare making this
reordering problem very noticeable. To fix this, add a new "text_input"
message type which doesn't suffer from reordering and use it instead
(the old "input" messages type needs to remain unchanged so that
servers can still run old versions of the game).
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/libunix.cc | 50 +++++++++++++---------
crawl-ref/source/tileweb.cc | 35 +++++++++++++--
crawl-ref/source/tileweb.h | 2 +
.../source/webserver/game_data/static/game.js | 2 +-
.../source/webserver/game_data/static/menu.js | 6 +--
.../source/webserver/game_data/static/textinput.js | 2 +-
.../webserver/game_data/static/ui-layouts.js | 2 +-
7 files changed, 69 insertions(+), 30 deletions(-)
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc
index 2f841a3e26..fb8d0f15bc 100644
--- a/crawl-ref/source/libunix.cc
+++ b/crawl-ref/source/libunix.cc
@@ -502,11 +502,14 @@ static int proc_mouse_event(int c, const MEVENT *me)
}
#endif
-static int pending = 0;
+static int curses_pending_key = 0;
+#ifdef USE_TILE_WEB
+static int tiles_pending_key = 0;
+#endif
static bool _curses_fetch_pending_key(bool blocking)
{
- if (pending)
+ if (curses_pending_key)
return true;
wint_t c;
@@ -532,15 +535,15 @@ static bool _curses_fetch_pending_key(bool blocking)
// a timeout from an error...
if (!blocking)
return false;
- pending = ESCAPE;
+ curses_pending_key = ESCAPE;
return true;
case OK:
// a normal (printable) key
- pending = c;
+ curses_pending_key = c;
return true;
case KEY_CODE_YES:
default:
- pending = -c;
+ curses_pending_key = -c;
return true;
}
}
@@ -562,14 +565,21 @@ static int _get_key_from_curses()
refresh();
tiles.redraw();
+ if (tiles_pending_key)
+ {
+ wint_t c = tiles_pending_key;
+ tiles_pending_key = 0;
+ return c;
+ }
+
wint_t c = tiles.await_input(&_curses_has_key);
if (c != 0)
return c;
#endif
_curses_fetch_pending_key(true);
- int result = pending;
- pending = 0;
+ int result = curses_pending_key;
+ curses_pending_key = 0;
return result;
}
@@ -592,16 +602,16 @@ static int _headless_getchk()
watchdog();
#endif
- if (pending)
+#ifdef USE_TILE_WEB
+ tiles.redraw();
+
+ if (tiles_pending_key)
{
- int c = pending;
- pending = 0;
+ wint_t c = tiles_pending_key;
+ tiles_pending_key = 0;
return c;
}
-
-#ifdef USE_TILE_WEB
- tiles.redraw();
wint_t c = tiles.await_input([]() { return false; });
if (c != 0)
return c;
@@ -1841,14 +1851,13 @@ void delay(unsigned int time)
static bool _headless_kbhit()
{
- if (pending)
- return true;
-
#ifdef USE_TILE_WEB
+ if (tiles_pending_key)
+ return true;
wint_t c = tiles.try_await_input();
if (c != 0)
{
- pending = c;
+ tiles_pending_key = c;
return true;
}
#endif
@@ -1862,17 +1871,16 @@ bool kbhit()
if (_headless_mode)
return _headless_kbhit();
- if (pending)
- return true;
-
if (_curses_has_key())
return true;
#ifdef USE_TILE_WEB
+ if (tiles_pending_key)
+ return true;
wint_t c = tiles.try_await_input();
if (c != 0)
{
- pending = c;
+ tiles_pending_key = c;
return true;
}
#endif
diff --git a/crawl-ref/source/tileweb.cc b/crawl-ref/source/tileweb.cc
index 9edd28bf0d..06b0008a73 100644
--- a/crawl-ref/source/tileweb.cc
+++ b/crawl-ref/source/tileweb.cc
@@ -421,6 +421,19 @@ static int _handle_cell_click(const coord_def &gc, int button, bool force)
return CK_MOUSE_CLICK;
}
+static char32_t _remove_first_character_utf8(string& text)
+{
+ if (text.empty())
+ return 0;
+ char32_t result = 0;
+ int length = utf8towc(&result, text.c_str());
+ if (!length)
+ text.clear();
+ else
+ text.erase(0, length);
+ return result;
+}
+
wint_t TilesFramework::_handle_control_message(sockaddr_un addr, string data)
{
JsonWrapper obj = json_decode(data.c_str());
@@ -433,7 +446,7 @@ wint_t TilesFramework::_handle_control_message(sockaddr_un addr, string data)
fprintf(stderr, "websocket: Received control message '%s' in %d byte.\n", msgtype.c_str(), (int) data.size());
#endif
- int c = 0;
+ wint_t c = 0;
if (msgtype == "attach")
{
@@ -607,6 +620,14 @@ wint_t TilesFramework::_handle_control_message(sockaddr_un addr, string data)
// (possibly just as a string, like the lua API for this)
process_command(CMD_GAME_MENU);
}
+ else if (msgtype == "text_input")
+ {
+ JsonWrapper text = json_find_member(obj.node, "text");
+ text.check(JSON_STRING);
+ ASSERT(m_pending_text_input.empty());
+ m_pending_text_input = text->string_;
+ c = _remove_first_character_utf8(m_pending_text_input);
+ }
return c;
}
@@ -616,6 +637,10 @@ wint_t TilesFramework::try_await_input()
if (m_sock_name.empty())
return 0;
+ wint_t c = _remove_first_character_utf8(m_pending_text_input);
+ if (c != 0)
+ return c;
+
fd_set fds;
int result;
while (true)
@@ -634,7 +659,7 @@ wint_t TilesFramework::try_await_input()
if (result <= 0)
return 0;
- wint_t c = _receive_control_message();
+ c = _receive_control_message();
if (c != 0)
return c;
}
@@ -660,6 +685,10 @@ wint_t TilesFramework::await_input(bool(*has_console_input)())
if (m_sock_name.empty())
return 0;
+ wint_t c = _remove_first_character_utf8(m_pending_text_input);
+ if (c != 0)
+ return c;
+
int result;
fd_set fds;
int maxfd = m_sock;
@@ -690,7 +719,7 @@ wint_t TilesFramework::await_input(bool(*has_console_input)())
{
if (FD_ISSET(m_sock, &fds))
{
- wint_t c = _receive_control_message();
+ c = _receive_control_message();
if (c != 0)
return c;
}
diff --git a/crawl-ref/source/tileweb.h b/crawl-ref/source/tileweb.h
index 54f2c70838..6501d27946 100644
--- a/crawl-ref/source/tileweb.h
+++ b/crawl-ref/source/tileweb.h
@@ -315,6 +315,8 @@ protected:
player_info m_current_player_info;
+ string m_pending_text_input;
+
void _send_version();
void _send_layout();
diff --git a/crawl-ref/source/webserver/game_data/static/game.js b/crawl-ref/source/webserver/game_data/static/game.js
index e8296803d0..56247b1053 100644
--- a/crawl-ref/source/webserver/game_data/static/game.js
+++ b/crawl-ref/source/webserver/game_data/static/game.js
@@ -387,7 +387,7 @@ function ($, exports, comm, client, key_conversion, dungeon_renderer, display,
function handle_mobile_input(e)
{
e.target.value = e.target.defaultValue;
- comm.send_message("input", { text: e.originalEvent.data });
+ comm.send_message("text_input", { text: e.originalEvent.data });
}
function handle_mobile_keydown(e)
diff --git a/crawl-ref/source/webserver/game_data/static/menu.js b/crawl-ref/source/webserver/game_data/static/menu.js
index b7eea1bb49..5657167870 100644
--- a/crawl-ref/source/webserver/game_data/static/menu.js
+++ b/crawl-ref/source/webserver/game_data/static/menu.js
@@ -736,7 +736,7 @@ function ($, comm, client, ui, enums, cr, util, options, scroller) {
input.off("focusout");
var enter = String.fromCharCode(13);
var text = input.val() + enter;
- comm.send_message("input", { text: text });
+ comm.send_message("text_input", { text: text });
restore();
ev.preventDefault();
@@ -1079,14 +1079,14 @@ function ($, comm, client, ui, enums, cr, util, options, scroller) {
if (event.which == 1)
comm.send_message("key", { keycode: 13 });
else if (event.which == 3)
- comm.send_message("input", { text: '\'' });
+ comm.send_message("text_input", { text: '\'' });
}
else if (menu.flags & enums.menu_flag.MULTISELECT)
{
if (event.which == 1)
comm.send_message("key", { keycode: 32 });
else if (event.which == 3)
- comm.send_message("input", { text: '\'' });
+ comm.send_message("text_input", { text: '\'' });
}
}
// TODO: don't rely on hotkeys here
diff --git a/crawl-ref/source/webserver/game_data/static/textinput.js b/crawl-ref/source/webserver/game_data/static/textinput.js
index dd59171242..cdd3759a90 100644
--- a/crawl-ref/source/webserver/game_data/static/textinput.js
+++ b/crawl-ref/source/webserver/game_data/static/textinput.js
@@ -135,7 +135,7 @@ function ($, comm, client, enums, util, options, ui) {
comm.send_message("key", { keycode: 21 });
comm.send_message("key", { keycode: 11 });
}
- comm.send_message("input", { text: text });
+ comm.send_message("text_input", { text: text });
// seed-selection handles this on its own, because there is first
// a validation step -- the input loop only terminates on abort
// or if there is an actual number to be found.
diff --git a/crawl-ref/source/webserver/game_data/static/ui-layouts.js b/crawl-ref/source/webserver/game_data/static/ui-layouts.js
index 2ca94c8b63..26922ede2b 100644
--- a/crawl-ref/source/webserver/game_data/static/ui-layouts.js
+++ b/crawl-ref/source/webserver/game_data/static/ui-layouts.js
@@ -73,7 +73,7 @@ function ($, comm, client, ui, enums, cr, util, scroller, main, gui, player, opt
if (colour)
$item.addClass("fg"+spell.colour);
$item.on("click", function () {
- comm.send_message("input", { text: letter });
+ comm.send_message("text_input", { text: letter });
});
});
$container.append($list);
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-04 01:15:09
|
via d7418c7e04b6be3e21a3df9889984769620c3177 (commit)
from d34c7c2060449724af7987b707ed3f422bae7db0 (commit)
-----------------------------------------------------------------------
commit d7418c7e04b6be3e21a3df9889984769620c3177
Author: David Lawrence Ramsey <poo...@gm...>
Date: Wed Dec 3 18:11:04 2025 -0600
Handle singular "the " names in encounter msgs.
So we get e.g. "You encounter the Serpent of Hell." instead of "You
encounter Serpent of Hell."
Note that a hypothetical unique monster with both a "the " name and a
title (none currently exist) will have its title take precedence.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/player-notices.cc | 3 +++
1 file changed, 3 insertions(+)
diff --git a/crawl-ref/source/player-notices.cc b/crawl-ref/source/player-notices.cc
index 7043f54ec4..01425951fb 100644
--- a/crawl-ref/source/player-notices.cc
+++ b/crawl-ref/source/player-notices.cc
@@ -319,6 +319,9 @@ static string _describe_monsters_from_species(const vector<details> &species)
if (!title.empty())
return title;
+ if (mons_is_unique(det.mon->type) && mons_is_the(det.mon->type))
+ name = "the " + name;
+
return name;
}
else if (det.count > 1 && det.genus)
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-04 00:35:09
|
via d34c7c2060449724af7987b707ed3f422bae7db0 (commit)
from 765122c258c467289150f5aba6333087d248bb2a (commit)
-----------------------------------------------------------------------
commit d34c7c2060449724af7987b707ed3f422bae7db0
Author: DracoOmega <dra...@gm...>
Date: Wed Dec 3 21:04:08 2025 -0330
Fix uniques' titles not being used in encounter messages (Snakku)
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/player-notices.cc | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/crawl-ref/source/player-notices.cc b/crawl-ref/source/player-notices.cc
index d4c7221abc..7043f54ec4 100644
--- a/crawl-ref/source/player-notices.cc
+++ b/crawl-ref/source/player-notices.cc
@@ -9,6 +9,7 @@
#include "act-iter.h"
#include "areas.h"
#include "attitude-change.h"
+#include "database.h"
#include "delay.h"
#include "describe.h"
#include "directn.h"
@@ -312,9 +313,12 @@ static string _describe_monsters_from_species(const vector<details> &species)
[] (const details &det)
{
string name = det.name;
- if (det.mon->is_named() && det.count == 1
- || !you.can_see(*det.mon))
+ if (det.mon->is_named() && det.count == 1)
{
+ string title = getMiscString(det.mon->name(DESC_DBNAME) + " title");
+ if (!title.empty())
+ return title;
+
return name;
}
else if (det.count > 1 && det.genus)
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-03 23:20:22
|
via 765122c258c467289150f5aba6333087d248bb2a (commit)
via 1ffbecd877470ca67287806678e718a4f0a171dc (commit)
via 865ad28f680c46adce4456a57eab127752425f96 (commit)
via a2ad6df00383b53dc1d4e0440c6d8da4bcf94354 (commit)
via a1ef7c00edf5f15cc6caea46c7901ded6828b5e3 (commit)
via 0403af7a578936b118a178e939cda86b8fc9c503 (commit)
from c1c35e67119de8586bf5552ab7b108d2757b6898 (commit)
-----------------------------------------------------------------------
commit 765122c258c467289150f5aba6333087d248bb2a
Author: DracoOmega <dra...@gm...>
Date: Wed Dec 3 19:47:18 2025 -0330
Remove some oddly well-commented dead code
This statement was seemingly never live in trunk, and doesn't seem relevant
for how golem currently operates. It already can act immediately on the
turn you move towards it, regardless of this.
Perhaps this is a remnant of an older version of it that never made it to
trunk at all?
commit 1ffbecd877470ca67287806678e718a4f0a171dc
Author: DracoOmega <dra...@gm...>
Date: Wed Dec 3 19:35:41 2025 -0330
Fix a couple tiny tesseract bugs
Due to function ordering, only one of the two tesseracts was actually being
woken up when they activated (the only effect this had was on stabability,
if that one somehow remained unalerted long enough to walk up to it).
Also, fix the second tesseract still not disappearing from monster memory
when the first was killed.
commit 865ad28f680c46adce4456a57eab127752425f96
Author: DracoOmega <dra...@gm...>
Date: Wed Dec 3 18:28:53 2025 -0330
Make lua you.contaminated() return something more useful
It is renamed you.contamination() and returns the player's current
contamination percentage. (Instead of merely whether this was above 0%)
commit a2ad6df00383b53dc1d4e0440c6d8da4bcf94354
Author: DracoOmega <dra...@gm...>
Date: Wed Dec 3 18:27:16 2025 -0330
Improve the UI regarding contamination explosion damage (Odds)
The % screen now indicates the maximum damage the player could take from
their current level of contamination, if it were to explode. They are also
prevented from resting if this explosion is capable of killing them.
This number is also exposed to lua via you.max_contam_damage() (mostly so
that the Contam status tooltip can also list this number). A very minor bug
with how the tooltips are refreshed means that if the player gains an XL
without any status changes, the tooltip may very slightly underestimate the
max damage (but % will still be accurate).
commit a1ef7c00edf5f15cc6caea46c7901ded6828b5e3
Author: DracoOmega <dra...@gm...>
Date: Wed Dec 3 17:42:18 2025 -0330
Give monster alerts even if a monster causes an interrupt
Many interrupts will cause a prompt on their own, which made this
additional more seem somewhat superfluous, but travel won't, so probably
it's more consistent if it always does.
commit 0403af7a578936b118a178e939cda86b8fc9c503
Author: DracoOmega <dra...@gm...>
Date: Wed Dec 3 17:41:08 2025 -0330
Mark erythrospites as no_poly_to
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/descript/status.txt | 7 +++++++
crawl-ref/source/dat/mons/erythrospite.yaml | 2 +-
crawl-ref/source/l-you.cc | 15 +++++++++++----
crawl-ref/source/mon-abil.cc | 16 ++++++++--------
crawl-ref/source/mon-abil.h | 1 -
crawl-ref/source/mon-act.cc | 6 ------
crawl-ref/source/mon-death.cc | 5 ++---
crawl-ref/source/nearby-danger.cc | 7 +++++++
crawl-ref/source/player-notices.cc | 15 ++++++---------
crawl-ref/source/player.cc | 23 ++++++++++++++++++++++-
crawl-ref/source/player.h | 1 +
11 files changed, 65 insertions(+), 33 deletions(-)
diff --git a/crawl-ref/source/dat/descript/status.txt b/crawl-ref/source/dat/descript/status.txt
index 562df30b86..32e34b02b1 100644
--- a/crawl-ref/source/dat/descript/status.txt
+++ b/crawl-ref/source/dat/descript/status.txt
@@ -110,6 +110,13 @@ You are glowing with mutagenic radiation. This can inflict mutations over time
(usually negative) or even cause you to suffer damage as the unstable magic
explodes violently. In addition, your glow prevents invisibility and reduces
your stealth.
+{{
+ local dmg = you.contam_max_damage();
+ if dmg > 0 then
+ return "\nAn explosion at your current level of contamination could " ..
+ "inflict up to " .. dmg .. " damage."
+ end
+}}
%%%%
Drain status
diff --git a/crawl-ref/source/dat/mons/erythrospite.yaml b/crawl-ref/source/dat/mons/erythrospite.yaml
index 1a4f488f2b..c3c64257cd 100644
--- a/crawl-ref/source/dat/mons/erythrospite.yaml
+++ b/crawl-ref/source/dat/mons/erythrospite.yaml
@@ -1,6 +1,6 @@
name: "erythrospite"
glyph: {char: "E", colour: etc_blood}
-flags: [see_invis, unblindable, amorphous, no_skeleton, speaks, warm_blood]
+flags: [see_invis, unblindable, amorphous, no_skeleton, speaks, warm_blood, no_poly_to]
exp: 42
will: 10
attacks:
diff --git a/crawl-ref/source/l-you.cc b/crawl-ref/source/l-you.cc
index 8afab9df2c..ab94fc60cb 100644
--- a/crawl-ref/source/l-you.cc
+++ b/crawl-ref/source/l-you.cc
@@ -561,11 +561,17 @@ LUARET1(you_silenced, boolean, you.is_silenced())
*/
LUARET1(you_sick, boolean, you.duration[DUR_SICKNESS])
-/*** Are you contaminated?
+/*** How badly are you contaminated?
* @treturn number
- * @function contaminated
+ * @function contamination
*/
-LUARET1(you_contaminated, number, you.magic_contamination > 0)
+LUARET1(you_contamination, number, you.magic_contamination / 10)
+
+/*** How much damage could you take right now if your magic contamination exploded?
+ * @treturn number
+ * @function contam_max_damage
+ */
+LUARET1(you_contam_max_damage, number, contam_max_damage())
/*** Do you feel safe?
* @treturn boolean
@@ -1514,7 +1520,8 @@ static const struct luaL_reg you_clib[] =
{ "brilliant", you_brilliant },
{ "silenced", you_silenced },
{ "sick", you_sick },
- { "contaminated", you_contaminated },
+ { "contamination", you_contamination },
+ { "contam_max_damage", you_contam_max_damage },
{ "feel_safe", you_feel_safe },
{ "deaths", you_deaths },
{ "lives", you_lives },
diff --git a/crawl-ref/source/mon-abil.cc b/crawl-ref/source/mon-abil.cc
index 96152db325..c78189b253 100644
--- a/crawl-ref/source/mon-abil.cc
+++ b/crawl-ref/source/mon-abil.cc
@@ -1479,14 +1479,6 @@ void activate_tesseracts()
if (mi->type != MONS_BOUNDLESS_TESSERACT)
continue;
- behaviour_event(*mi, ME_ALERT);
- env.map_knowledge(mi->pos()).set_monster(monster_info(*mi));
- set_terrain_seen(mi->pos());
- view_update_at(mi->pos());
-#ifdef USE_TILE
- tiles.update_minimap(mi->pos());
-#endif
-
if (!did_activate)
{
mprf(MSGCH_WARN, "You feel the power of Zot begin to gather its forces!");
@@ -1509,6 +1501,14 @@ void activate_tesseracts()
for (int i = 0; i < num; ++i)
_make_tesseract_spawn(false, true);
}
+
+ behaviour_event(*mi, ME_ALERT);
+ env.map_knowledge(mi->pos()).set_monster(monster_info(*mi));
+ set_terrain_seen(mi->pos());
+ view_update_at(mi->pos());
+#ifdef USE_TILE
+ tiles.update_minimap(mi->pos());
+#endif
}
}
diff --git a/crawl-ref/source/mon-abil.h b/crawl-ref/source/mon-abil.h
index 5a07a11c3c..533f2bbe06 100644
--- a/crawl-ref/source/mon-abil.h
+++ b/crawl-ref/source/mon-abil.h
@@ -16,7 +16,6 @@
#define TESSERACT_SPAWN_COUNTER_KEY "tesseract_spawn_count"
#define TESSERACT_SPAWN_TIMER_KEY "tesseract_spawn_timer"
-#define TESSERACT_DUMMY_KEY "tesseract_dummy"
class actor;
class monster;
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index b2bf44918a..556ec831e7 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -1152,12 +1152,6 @@ static void _check_blazeheart_golem_link(monster& mons)
{
mons.del_ench(ENCH_PARALYSIS, true);
simple_monster_message(mons, " core flares to life once more.", true);
-
- // Since we check this at the END of the golem's move, even if it
- // started its turn with the player next to them (due to player
- // movement), grant some instant energy to make it look like it
- // activated first.
- //mons.speed_increment += mons.action_energy(EUT_MOVE);
}
// Give the golem another turn before it goes cold.
diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc
index a8a268e5c8..bbf022506a 100644
--- a/crawl-ref/source/mon-death.cc
+++ b/crawl-ref/source/mon-death.cc
@@ -3380,13 +3380,12 @@ item_def* monster_die(monster& mons, killer_type killer,
{
if (mi->type == MONS_BOUNDLESS_TESSERACT && mi->mid != mons.mid)
{
- monster_die(**mi, KILL_RESET, NON_MONSTER);
- env.map_knowledge(mi->pos()).clear_monster();
- //set_terrain_seen(mi->pos());
+ env.map_knowledge(mi->pos()).clear();
view_update_at(mi->pos());
#ifdef USE_TILE
tiles.update_minimap(mi->pos());
#endif
+ monster_die(**mi, KILL_RESET, NON_MONSTER);
}
else if ((mi->flags & MF_TESSERACT_SPAWN))
{
diff --git a/crawl-ref/source/nearby-danger.cc b/crawl-ref/source/nearby-danger.cc
index 5e1575639a..3d4efd9157 100644
--- a/crawl-ref/source/nearby-danger.cc
+++ b/crawl-ref/source/nearby-danger.cc
@@ -261,6 +261,13 @@ bool i_feel_safe(bool announce, bool want_move, bool just_monsters,
return false;
}
+ if (contam_max_damage() >= you.hp)
+ {
+ if (announce)
+ mprf(MSGCH_WARN, "You are contaminated with a potentially lethal amount of magic!");
+ return false;
+ }
+
if (you.duration[DUR_STICKY_FLAME])
{
if (announce)
diff --git a/crawl-ref/source/player-notices.cc b/crawl-ref/source/player-notices.cc
index 8487fdd373..d4c7221abc 100644
--- a/crawl-ref/source/player-notices.cc
+++ b/crawl-ref/source/player-notices.cc
@@ -94,20 +94,17 @@ void maybe_notice_monster(monster& mons, bool stepped)
const bool already_seen = (bool)(mons.flags & MF_SEEN);
seen_monster(&mons);
+ if (!already_seen)
+ _check_monster_alert(mons);
+
// If the monster has been seen before (and thus won't print an encounter
// message), tell interrupt_activity to print something else if needed.
if (crawl_state.is_repeating_cmd() || you_are_delayed())
{
- if (_try_seen_interrupt(mons, !already_seen ? SC_NEWLY_SEEN
- : stepped ? SC_NONE
- : SC_ALREADY_IN_VIEW))
- {
- return;
- }
+ _try_seen_interrupt(mons, !already_seen ? SC_NEWLY_SEEN
+ : stepped ? SC_NONE
+ : SC_ALREADY_IN_VIEW);
}
-
- if (!already_seen)
- _check_monster_alert(mons);
}
static monster_type _mons_merge_genus(monster_type mc)
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index ad214a25df..c5d3d21751 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -4291,6 +4291,21 @@ bool player_harmful_contamination()
return you.magic_contamination >= 1000;
}
+// Returns the maximum damage the player could take if their current magic
+// contamination exploded.
+int contam_max_damage()
+{
+ if (you.magic_contamination < 1000)
+ return 0;
+
+ const bool severe = you.magic_contamination >= 2000;
+ const int pow = severe ? you.experience_level * 3 / 2
+ : you.experience_level;
+ dice_def dmg = zap_damage(ZAP_CONTAM_EXPLOSION, pow, false, false);
+
+ return dmg.size * dmg.num;
+}
+
/**
* Provide a description of the player's magic contamination.
*
@@ -4322,7 +4337,13 @@ string describe_contamination(bool verbose)
const unsigned int lvl = you.magic_contamination / 1000;
ASSERT(lvl < ARRAYSZ(verbose_desc));
- return verbose ? verbose_desc[lvl] : terse_desc[lvl];
+ string msg = verbose ? verbose_desc[lvl] : terse_desc[lvl];
+
+ const int dmg = contam_max_damage();
+ if (dmg > 0)
+ msg = make_stringf("%s (up to %d damage)", msg.c_str(), dmg);
+
+ return msg;
}
// Controlled is true if the player actively did something to cause
diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h
index 02792aa0e6..75721b3a0b 100644
--- a/crawl-ref/source/player.h
+++ b/crawl-ref/source/player.h
@@ -1181,6 +1181,7 @@ int get_real_hp(bool trans, bool drained = true);
int get_real_mp(bool include_items);
bool player_harmful_contamination();
+int contam_max_damage();
string describe_contamination(bool verbose = true);
bool sanguine_armour_valid();
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-03 08:15:14
|
via c1c35e67119de8586bf5552ab7b108d2757b6898 (commit)
from 38ba4db094337e1656c5d6577936044ed2359221 (commit)
-----------------------------------------------------------------------
commit c1c35e67119de8586bf5552ab7b108d2757b6898
Author: Isaac Clancy <ik...@ya...>
Date: Wed Dec 3 20:45:27 2025 +1300
Don't special case handling of green water
Instead, use the same colour override code used for other tiles to
select the correct tiles for green and light green water.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/rltiles/dc-floor.txt | 8 +++++++
.../source/rltiles/tool/tile_list_processor.cc | 13 ++++-------
.../source/rltiles/tool/tile_list_processor.h | 9 ++++++--
crawl-ref/source/tilecell.cc | 16 +++-----------
crawl-ref/source/tilepick.cc | 25 +++-------------------
5 files changed, 25 insertions(+), 46 deletions(-)
diff --git a/crawl-ref/source/rltiles/dc-floor.txt b/crawl-ref/source/rltiles/dc-floor.txt
index f4d888b72b..663b51e3f5 100644
--- a/crawl-ref/source/rltiles/dc-floor.txt
+++ b/crawl-ref/source/rltiles/dc-floor.txt
@@ -1246,14 +1246,20 @@ shallow_water DNGN_SHALLOW_WATER
shallow_water2
shallow_water_disturbance DNGN_SHALLOW_WATER_DISTURBANCE
shallow_water_disturbance2
+%variation DNGN_DEEP_WATER green
+%variation DNGN_DEEP_WATER lightgreen
%weight 2
deep_water_murky DNGN_DEEP_WATER_MURKY
%weight 1
deep_water_murky2
+%variation DNGN_SHALLOW_WATER green
+%variation DNGN_SHALLOW_WATER lightgreen
%weight 3
shallow_water_murky DNGN_SHALLOW_WATER_MURKY
%weight 1
shallow_water_murky2
+%variation DNGN_SHALLOW_WATER_DISTURBANCE green
+%variation DNGN_SHALLOW_WATER_DISTURBANCE lightgreen
shallow_water_murky_disturbance DNGN_SHALLOW_WATER_MURKY_DISTURBANCE
shallow_water_murky_disturbance2
%weight 120
@@ -1293,6 +1299,8 @@ shallow_bord_bl DNGN_WAVE_SW
shallow_bord_lft DNGN_WAVE_W
shallow_bord_tl DNGN_WAVE_NW
+%variation DNGN_WAVE_N green
+%variation DNGN_WAVE_N lightgreen
murky_bord_top MURKY_WAVE_N
murky_bord_tr MURKY_WAVE_NE
murky_bord_rgt MURKY_WAVE_E
diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.cc b/crawl-ref/source/rltiles/tool/tile_list_processor.cc
index 275956007d..820b9f31e8 100644
--- a/crawl-ref/source/rltiles/tool/tile_list_processor.cc
+++ b/crawl-ref/source/rltiles/tool/tile_list_processor.cc
@@ -22,8 +22,6 @@ tile_list_processor::tile_list_processor() :
m_start_value("0"),
m_start_value_module(""),
m_texture(0),
- m_variation_idx(-1),
- m_variation_col(-1),
m_weight(1),
m_alpha(0.0),
m_domino(0)
@@ -733,8 +731,7 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file,
return false;
}
- m_variation_idx = idx;
- m_variation_col = colour;
+ m_variations.push_back(variation{idx, colour});
}
else if (strcmp(arg, "reset_mirror") == 0)
{
@@ -935,11 +932,9 @@ void tile_list_processor::add_image(tile &img, const char *enumname)
if (!m_categories.empty())
m_ctg_counts[m_categories.size()-1]++;
- if (m_variation_idx != -1)
- {
- m_page.add_variation(m_last_enum, m_variation_idx, m_variation_col);
- m_variation_idx = -1;
- }
+ for (variation v : m_variations)
+ m_page.add_variation(m_last_enum, v.idx, v.col);
+ m_variations.clear();
}
void tile_list_processor::add_abstracts(
diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.h b/crawl-ref/source/rltiles/tool/tile_list_processor.h
index 738e0ada71..570bc07ac9 100644
--- a/crawl-ref/source/rltiles/tool/tile_list_processor.h
+++ b/crawl-ref/source/rltiles/tool/tile_list_processor.h
@@ -30,6 +30,12 @@ protected:
const vector<string> &uc_max_enum,
bool is_js = false);
+ struct variation
+ {
+ int idx;
+ int col;
+ };
+
string m_name;
tile_page m_page;
@@ -53,8 +59,7 @@ protected:
vector<int> m_ctg_counts;
tile m_compose;
tile* m_texture;
- int m_variation_idx;
- int m_variation_col;
+ vector<variation> m_variations;
int m_weight;
double m_alpha;
int m_domino;
diff --git a/crawl-ref/source/tilecell.cc b/crawl-ref/source/tilecell.cc
index 425521f751..6fb1c49eb9 100644
--- a/crawl-ref/source/tilecell.cc
+++ b/crawl-ref/source/tilecell.cc
@@ -395,16 +395,6 @@ static bool _is_seen_shallow(coord_def gc, crawl_view_buffer& vbuf)
return feat == DNGN_SHALLOW_WATER || feat == DNGN_MANGROVE;
}
-static tileidx_t _base_wave_tile(colour_t colour)
-{
- switch (colour)
- {
- case BLACK: return TILE_DNGN_WAVE_N;
- case GREEN: return TILE_MURKY_WAVE_N;
- default: die("no %s deep water wave tiles", colour_to_str(colour).c_str());
- }
-}
-
static void _pack_default_waves(const coord_def &gc, crawl_view_buffer& vbuf)
{
auto& cell = vbuf(gc).tile;
@@ -420,10 +410,10 @@ static void _pack_default_waves(const coord_def &gc, crawl_view_buffer& vbuf)
if (!feat_is_water(feat) && !feat_is_lava(feat))
return;
- if (feat == DNGN_DEEP_WATER && (colour == BLACK || colour == GREEN))
+ if (feat == DNGN_DEEP_WATER)
{
// +7 and -- reverse the iteration order
- int tile = _base_wave_tile(colour) + 7;
+ int tile = tile_dngn_coloured(TILE_DNGN_WAVE_N, colour) + 7;
for (adjacent_iterator ai(gc); ai; ++ai, --tile)
{
if (ai->x < 0 || ai->x >= vbuf.size().x || ai->y < 0 || ai->y >= vbuf.size().y)
@@ -437,7 +427,7 @@ static void _pack_default_waves(const coord_def &gc, crawl_view_buffer& vbuf)
bool west = _is_seen_land(coord_def(gc.x - 1, gc.y), vbuf);
bool east = _is_seen_land(coord_def(gc.x + 1, gc.y), vbuf);
- if (north || west || east && (colour == BLACK || colour == LIGHTGREEN))
+ if (north || west || east)
{
if (north)
cell.add_overlay(TILE_SHORE_N);
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 47102a98d5..46f2753640 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -995,30 +995,11 @@ static tileidx_t _tileidx_feature_no_overrides(const coord_def &gc)
case DNGN_ENTER_SHOP:
return tileidx_shop(shop_at(gc));
- case DNGN_DEEP_WATER:
- if (env.map_knowledge(gc).feat_colour() == GREEN
- || env.map_knowledge(gc).feat_colour() == LIGHTGREEN)
- {
- return TILE_DNGN_DEEP_WATER_MURKY;
- }
- return TILE_DNGN_DEEP_WATER;
case DNGN_SHALLOW_WATER:
- {
- tileidx_t t = TILE_DNGN_SHALLOW_WATER;
- if (env.map_knowledge(gc).feat_colour() == GREEN
- || env.map_knowledge(gc).feat_colour() == LIGHTGREEN)
- {
- t = TILE_DNGN_SHALLOW_WATER_MURKY;
- }
-
- if (env.map_knowledge(gc).invisible_monster())
- {
- // Add disturbance to tile.
- t += tile_dngn_count(t);
- }
+ if (env.map_knowledge(gc).invisible_monster())
+ return TILE_DNGN_SHALLOW_WATER_DISTURBANCE;
+ return TILE_DNGN_SHALLOW_WATER;
- return t;
- }
default:
return tileidx_feature_base(feat);
}
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-03 04:55:16
|
via 38ba4db094337e1656c5d6577936044ed2359221 (commit)
from cf93559967e9fa10e119568d4e0a9f0c938538e2 (commit)
-----------------------------------------------------------------------
commit 38ba4db094337e1656c5d6577936044ed2359221
Author: regret-index <clo...@ho...>
Date: Wed Dec 3 01:20:58 2025 -0330
Yet further very brief vault review
Worthy of note:
* Pan entries now guarantee a tier 2 demon, instead of presenting the
entirely harmless premise of being interrupted in exploration to find
a vault containing exactly one Lair-portal threat of a tier 3 demon.
* muffindrake_necropolis_ghost_three_little_ghosts has had its terrain
shuffles fixed to no longer require as much digging charges to access.
* Orc special rooms in V now match the threat level of Elf's, to match
how the orc warlord bands in V no longer use nearly as much low-tier
orc chaff as previously.
* wad_dig_loot uses a cacodemon in Elf alongside a demonologist, since
the elementalist placed in there can no longer dig itself out.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/des/branches/lair.des | 2 +-
crawl-ref/source/dat/des/branches/pan.des | 6 ++--
crawl-ref/source/dat/des/branches/spider.des | 34 ++++++++--------------
crawl-ref/source/dat/des/builder/rooms.des | 4 +--
crawl-ref/source/dat/des/builder/shops.des | 15 ++++++++--
crawl-ref/source/dat/des/portals/necropolis.des | 2 +-
crawl-ref/source/dat/des/portals/sewer.des | 3 +-
crawl-ref/source/dat/des/variable/arcadia.des | 16 ++++++----
crawl-ref/source/dat/des/variable/float.des | 8 ++---
.../source/dat/des/variable/mini_monsters.des | 15 +++++++---
10 files changed, 58 insertions(+), 47 deletions(-)
diff --git a/crawl-ref/source/dat/des/branches/lair.des b/crawl-ref/source/dat/des/branches/lair.des
index a40af4e2ea..657a6466e0 100644
--- a/crawl-ref/source/dat/des/branches/lair.des
+++ b/crawl-ref/source/dat/des/branches/lair.des
@@ -4579,7 +4579,7 @@ SHUFFLE: ';`, -~ / -~ / ~-
NSUBST: ' = 3:3 / 2 = 3. / 1:5 / 2 = 15. / 1:2. / *:.
NSUBST: ; = 3:5 / 3 = 15. / 1:2. / *:., ` = 3 = 5 / 3 = 15. / 1:2. / .
NSUBST: - = 1:7 / *:", ~ = 2:8 / *:"
-NSUBST: D = 1:R / 1 = ? $:90 / 1:|* / 2 = *% / 3 = $% / *:$
+NSUBST: D = 1:R / 1 = ? %:90 / 1:|* / 1:* / 1 = *% / 3 = $% / *:$
NSUBST: G = 2:4 / 1:4. / *:G, l = 5:Y / l
KMASK: "$%*|78 = no_trap_gen
FTILE: ="$%*|78G = floor_sprouting_squares
diff --git a/crawl-ref/source/dat/des/branches/pan.des b/crawl-ref/source/dat/des/branches/pan.des
index 23ad09c9e8..09060047f2 100644
--- a/crawl-ref/source/dat/des/branches/pan.des
+++ b/crawl-ref/source/dat/des/branches/pan.des
@@ -264,15 +264,15 @@ function pan_entry_vault_contents(e, glyph)
e.kmons(glyph .. "1 = " .. tiertwo)
e.kmons("2 = " .. tierthree)
e.nsubst("2 = 2 = 22. / *:.")
- e.nsubst("1 = 1:112 / *:.")
+ e.nsubst("1 = 1:1 / *:.")
else
e.subst("12 = .")
e.kmons(glyph .. " = " .. tiertwo .. " / " ..
tierthree .. " / " .. tierthree)
end
- e.ftile(".+12O : floor_demonic_red / floor_demonic_blue / " ..
- "floor_demonic_green / floor_demonic_magenta")
+ e.ftile(".+12O$ : floor_demonic_red / floor_demonic_blue / " ..
+ "floor_demonic_green / floor_demonic_magenta")
end
function pan_declare_demonic_rune(holy)
diff --git a/crawl-ref/source/dat/des/branches/spider.des b/crawl-ref/source/dat/des/branches/spider.des
index c64480e262..ea9a8ff7de 100644
--- a/crawl-ref/source/dat/des/branches/spider.des
+++ b/crawl-ref/source/dat/des/branches/spider.des
@@ -1493,40 +1493,30 @@ MAP
...........
ENDMAP
-NAME: cheibrodos_spider_deadly_dance
-TAGS: no_item_gen no_monster_gen
+NAME: cheibrodos_spider_deadly_dance
+TAGS: no_item_gen no_monster_gen
ORIENT: float
-MONS: dancing weapon ; short sword / dancing weapon ; mace \
- / dancing weapon ; war axe / dancing weapon ; trident \
- / dancing weapon ; mace
-MONS: tarantella / redback w:3
-KMONS: - = dancing weapon ; short sword / dancing weapon ; mace \
- / dancing weapon ; war axe / dancing weapon ; trident \
- / dancing weapon ; mace
-KMONS: " = dancing weapon ; rapier / dancing weapon ; scimitar \
- / dancing weapon ; broad axe / dancing weapon ; partisan \
- / dancing weapon ; morningstar
-KITEM: - = plate armour / plate armour good_item w:1 / chain mail \
- / chain mail good_item w:1 / scale mail / scale mail good_item w:1 \
- / ring mail / ring mail good_item w:1
-KITEM: " = plate armour / plate armour good_item w:1 / chain mail \
- / chain mail good_item w:1 / scale mail / scale mail good_item w:1 \
- / ring mail / ring mail good_item w:1
-KFEAT: ^ = web trap
+KMONS: 01 = dancing weapon ; short sword | mace w:15 | war axe | trident
+KMONS: 2 = tarantella / redback w:3
+KMONS: 3 = dancing weapon ; rapier | scimitar | broad axe | \
+ partisan | morningstar
+KITEM: 03 = plate armour / plate armour good_item w:1 / chain mail / \
+ chain mail good_item w:1 / scale mail / scale mail good_item w:1
+KFEAT: ^ = web trap
NSUBST: ` = 4:2 / 4=2., ' = 2=*% / 5=%., . = 2:^ / 4=^.
MAP
ccccccccccccc
- cm"mc'''cm"mc
+ cm3mc'''cm3mc
c2...'''...2c
c2...'''...2c
cccccc+cccGccc+cccccc
cm`.....c2.2c.....`mc
-c-......+.1.+......-c
+c0......+.1.+......0c
cm`.....c...c.....`mc
ccccc...cc=cc...ccccc
c...c...c...c
c`.`c...c`.`c
- cm-mc...cm-mc
+ cm0mc...cm0mc
ccccc.@.ccccc
ENDMAP
diff --git a/crawl-ref/source/dat/des/builder/rooms.des b/crawl-ref/source/dat/des/builder/rooms.des
index e89f7356da..69eb566aea 100644
--- a/crawl-ref/source/dat/des/builder/rooms.des
+++ b/crawl-ref/source/dat/des/builder/rooms.des
@@ -75,11 +75,11 @@ function sroom_orc_lair(e)
local mon
- if level > 20 or you.in_branch("Elf") then
+ if level > 16 or you.in_branch("Elf") then
mon = "orc priest w:7 / orc warrior w:12 / orc knight w:8 / "
.. " orc high priest w:2 / two-headed ogre w:1"
lord_mon = "orc warlord"
- elseif level > 14 or you.in_branch("Orc") then
+ elseif level > 13 or you.in_branch("Orc") then
mon = "orc w:6 / orc warrior w:8 / orc priest w:2 / "
.. "orc knight w:3 / troll w:1 "
lord_mon = "orc knight / orc high priest w:6 / orc warlord w:4"
diff --git a/crawl-ref/source/dat/des/builder/shops.des b/crawl-ref/source/dat/des/builder/shops.des
index 7348d06471..39445d7eab 100644
--- a/crawl-ref/source/dat/des/builder/shops.des
+++ b/crawl-ref/source/dat/des/builder/shops.des
@@ -703,11 +703,18 @@ TAGS: transparent shop extra allow_dup
KFEAT: S = any shop
KFEAT: D = demonic_tree
SUBST: t : t:35 D:1
+: if you.in_branch("Shoals") then
+FTILE: @'tD = floor_rough_lightgreen
+FTILE: .S = floor_grass
+: else
+FTILE: @'tD = floor_moss
+FTILE: .S = floor_grass_dark
+: end
MAP
xxxx
xS.t
-x...
-xt.@
+x..'
+xt'@
ENDMAP
NAME: nicolae_shop_real_fake_doors
@@ -2401,6 +2408,7 @@ SHUFFLE: AB, CD
SUBST: C : .:80 xcvbmGtT
SUBST: D : .:80 xcvbmGtT
SUBST: B : A.
+FTILE: t = floor_moss
MAP
xxx@xxx
xxd...dxx
@@ -2425,6 +2433,9 @@ DEPTH: D:4-, Depths, Orc, Elf, Shoals, Snake
KFEAT: D = general shop type:General suffix:Store
KFEAT: E = general shop type:Specific suffix:Store count:1
SUBST: G : GTUtwx, x : x:120 c:60 bv.
+: if you.in_branch("Orc") then
+KMONS: t = fungus
+: end
MAP
xx...xx
xG...Gx
diff --git a/crawl-ref/source/dat/des/portals/necropolis.des b/crawl-ref/source/dat/des/portals/necropolis.des
index 2004785ac3..87913ca2f0 100644
--- a/crawl-ref/source/dat/des/portals/necropolis.des
+++ b/crawl-ref/source/dat/des/portals/necropolis.des
@@ -2402,7 +2402,7 @@ MONS: stone giant / deep troll earth mage / golden dragon
MONS: iron troll / iron dragon, iron giant
KMONS: pP = pile of debris
KFEAT: ~ = broken_door
-SHUFFLE: xP~ / 'P' / '''
+SHUFFLE: xP~ / "P" / """
SUBST: ' = .
TILE: b = dngn_crystal_cyan
: ghost_good_loot(_G)
diff --git a/crawl-ref/source/dat/des/portals/sewer.des b/crawl-ref/source/dat/des/portals/sewer.des
index ad1b60fadb..9636ebbe0c 100644
--- a/crawl-ref/source/dat/des/portals/sewer.des
+++ b/crawl-ref/source/dat/des/portals/sewer.des
@@ -853,7 +853,7 @@ cc.....cc
cdc cc---..cc
c.c cc---w...cc
cccc.ccccccc---www...cc
-c24........---wwwww.A<c
+c23........---wwwww.A<c
cccc.ccccccc---www...cc
c.c cc---w...cc
c-c cc---..cc
@@ -933,6 +933,7 @@ KMONS: F = patrolling rock fish
: kitem("! = " .. dgn.loot_scrolls)
KFEAT: 1 = W
KFEAT: 2 = w
+KFEAT: F = x
SUBST: QR = .
NSUBST: 2 = 2:2 / 1:w / * = 2w, F = 2:F / 1:Fx / *:x
NSUBST: . = 1:1 / 1 = 1. / * = .WW
diff --git a/crawl-ref/source/dat/des/variable/arcadia.des b/crawl-ref/source/dat/des/variable/arcadia.des
index e4c35224bd..19e16d6b22 100644
--- a/crawl-ref/source/dat/des/variable/arcadia.des
+++ b/crawl-ref/source/dat/des/variable/arcadia.des
@@ -4,6 +4,8 @@
# Only one of these can place per Depths, and are mutually exclusive with
# random Enchantress placement; they've also diluted with appropriate natives.
+: crawl_require('dlua/vault.lua')
+
{{
function old_forest_ends(e)
e.tags('uniq_old_forest_end no_monster_gen')
@@ -210,15 +212,17 @@ MONS: tengu conjurer ; quarterstaff . robe . longbow | arbalest / \
glowing orange brain w:5 / rakshasa / chonchon / eleionoma
KMONS: L = water nymph
KMONS: P = plant
-ITEM: gold q:1 / stone q:1 no_pickup w:20
-ITEM: any potion, potion of moonshine pre_id
+ITEM: stone q:1 no_pickup, any potion, potion of moonshine pre_id
KFEAT: L = deep_water
KFEAT: F = cache_of_fruit
NSUBST: w = 2:L / *:w
SUBST: X = xt, T = t.
-FTILE: efF124+|%*$- = floor_vines
+FTILE: efF124+|%*$!- = floor_vines
+FTILE: d = floor_rough_brown
+FTILE: P = floor_moss
NSUBST: 5 = 1:4 / 3:6 / 1:56 / *:5
-NSUBST: 2 = 1:3 / 1:223 / *:2, e = 3:F / * = e f:35
+NSUBST: 2 = 1:3 / 1:223 / *:2, e = 3:F / 3:! / 2:e / * = e f:35
+: decorative_floor(_G, '!', "set of bottled spirits")
: old_forest_ends(_G)
veto {{
return crawl.game_started() and you.uniques("Enchantress")
@@ -231,14 +235,14 @@ XttTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTtxx
XttT.5..................................0Ttxx
XttT..PdPdP.cccccccccccccccccccccccccccc.Ttxx
XttT..PdPdP.ce-e-e-e-e-e-e-eceeeeee+|||c.Ttxx
-XttT..PdPdP.c-e-e-e-c-e-e-e-c------c|||c.Ttxx
+XttT..PdPdP.c-e-e-e-c-e-e-e-c!-----c|||c.Ttxx
XttT..PdPdP.ce-e2e-ece-e2e-ec------cc+cc.Ttxx
XttT..PdPdP.cc+ccccccc+cccccc---2-4c%**c.Ttxx
XttT..PdPdP5c-----4---4-----+----1-c%**c.Ttxx
XttT..PdPdP.c-------2-------+---2-4c%**c.Ttxx
XtT...PdPdP.c--wwwwwwwwwww--+------c%**c.Ttxx
XtT...PdPdP.c--wwwwwwwwwww--c------c$$$c.Ttxx
-XtT...PdPdP.c-----4---4-----c------c$$$c.Ttxx
+XtT...PdPdP.c-----4---4-----c!-----c$$$c.Ttxx
XtT...PdPdP.c---------------ceeeeee+$$$c.Ttxx
XTT...PdPdP.cc++cccccccccccccccccccccccc.Ttxx
T.......5......5............5...........5Ttxx
diff --git a/crawl-ref/source/dat/des/variable/float.des b/crawl-ref/source/dat/des/variable/float.des
index 3aee3e6ffe..9980ac13af 100644
--- a/crawl-ref/source/dat/des/variable/float.des
+++ b/crawl-ref/source/dat/des/variable/float.des
@@ -4636,12 +4636,10 @@ KITEM: 2 = devastator / eveningstar ego:heavy randart pre_id \
: if you.in_branch("D") then
: if you.depth() < 13 then
MONS: two-headed ogre / basilisk / gargoyle / boulder beetle w:5
-KMONS: 2 = catoblepas w:30 / stone giant / war gargoyle \
- / deep troll earth mage
+KMONS: 2 = catoblepas w:30 / stone giant / deep troll earth mage
: else
MONS: basilisk / gargoyle / boulder beetle / catoblepas
-KMONS: 2 = stone giant / deep troll earth mage / war gargoyle \
- / iron dragon / crystal guardian
+KMONS: 2 = stone giant / deep troll earth mage / crystal guardian
: end
: elseif you.in_branch("Elf") then
MONS: earth elemental w:20 / stone giant / war gargoyle
@@ -11960,7 +11958,7 @@ SUBST: b : cx
SUBST: b : bcvx
: end
NSUBST: ' = d / e / $
-: vaults_hard_standard(_G, false, "-QR189de|*$")
+: vaults_hard_standard(_G, false, "-QR189de|*$G")
MARKER: P = lua:transp_loc("sealed_arena_entry")
MARKER: Q = lua:transp_dest_loc("sealed_arena_entry")
MARKER: R = lua:transp_loc("sealed_arena_exit")
diff --git a/crawl-ref/source/dat/des/variable/mini_monsters.des b/crawl-ref/source/dat/des/variable/mini_monsters.des
index 3a42f82018..efaed73ace 100644
--- a/crawl-ref/source/dat/des/variable/mini_monsters.des
+++ b/crawl-ref/source/dat/des/variable/mini_monsters.des
@@ -4986,8 +4986,8 @@ NAME: wad_dig_loot
TAGS: transparent no_descent
DEPTH: D:8-, Elf, Depths, !Depths:$
WEIGHT: 4
-KPROP: %*8DEF = no_tele_into
-KMASK: %*|8aDEF' = opaque
+KPROP: %*8DEeF = no_tele_into
+KMASK: %*|8aDEeF' = opaque
KITEM: EF = *
KMONS: EF = 8
KMONS: p = plant
@@ -5001,8 +5001,9 @@ KMONS: D = deep troll earth mage
SUBST: EF = '
: elseif you.in_branch("Elf") then
KITEM: D = |
-KMONS: D = deep elf elementalist
-SUBST: F = '
+KMONS: D = patrolling cacodemon
+KMONS: e = patrolling deep elf demonologist
+SUBST: E = e, F = '
: elseif you.in_branch("Depths") then
KITEM: D = |
KMONS: D = deep troll earth mage / cacodemon
@@ -5010,8 +5011,14 @@ KMONS: D = deep troll earth mage / cacodemon
: else
SUBST: DE = v, F = '
: end
+: if you.in_branch("Elf") then
+TILE: v = dngn_metal_wall_red
+FTILE: " = floor_infernal_blank
+COLOUR: " = red
+: else
FTILE: " = floor_pebble_brown
COLOUR: " = brown
+: end
MAP
@....vvvvv..G.@
.""".vvvvvp....
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-02 08:25:14
|
via cf93559967e9fa10e119568d4e0a9f0c938538e2 (commit)
from 40ba7039b06e1722f8741c5272b21c961b46c407 (commit)
-----------------------------------------------------------------------
commit cf93559967e9fa10e119568d4e0a9f0c938538e2
Author: Isaac Clancy <ik...@ya...>
Date: Tue Dec 2 20:54:23 2025 +1300
Fix sometimes getting incorect monster leaves view messages
If a monster enters view and then isn't in view at the start of the
player's next turn, we print a message so that the player isn't confused
about things like auto explore being interrupted with no monster in view
etc. However, because we printed the messages about monster's leaving
view before decaying clouds, a monster could move behind enough fog
clouds to be out of view and then we would print the message and then
the fog clouds would decay putting the monster back in view. This would
leave the player with a confusing message about a monster leaving view
when all the monster's were still in view.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/abyss.cc | 2 ++
crawl-ref/source/main.cc | 5 +++++
crawl-ref/source/mon-act.cc | 3 +--
crawl-ref/source/mon-act.h | 1 +
4 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index 62b42ffa25..3907ebe8c9 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -37,6 +37,7 @@
#include "mapmark.h"
#include "maps.h"
#include "message.h"
+#include "mon-act.h"
#include "mon-cast.h"
#include "mon-death.h"
#include "mon-pathfind.h"
@@ -462,6 +463,7 @@ void check_banished()
if (you.banished)
{
you.banished = false;
+ mons_reset_just_seen();
ASSERT(brdepth[BRANCH_ABYSS] != -1);
if (!player_in_branch(BRANCH_ABYSS))
mprf(MSGCH_BANISHMENT, "You are cast into the Abyss!");
diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc
index 7622b423e2..ca68a25d1e 100644
--- a/crawl-ref/source/main.cc
+++ b/crawl-ref/source/main.cc
@@ -2623,6 +2623,11 @@ void world_reacts()
handle_time();
manage_clouds();
+
+ // This needs to happen after `manage_clouds` is called as fog clouds
+ // decaying will affect whether a monster is still in view
+ print_mons_left_view_messages();
+
if (env.level_state & LSTATE_GOLUBRIA)
_update_golubria_traps(you.time_taken);
if (env.level_state & LSTATE_STILL_WINDS)
diff --git a/crawl-ref/source/mon-act.cc b/crawl-ref/source/mon-act.cc
index ac732199f6..b2bf44918a 100644
--- a/crawl-ref/source/mon-act.cc
+++ b/crawl-ref/source/mon-act.cc
@@ -2681,7 +2681,7 @@ void mons_reset_just_seen()
just_seen_queue.clear();
}
-static void _display_just_seen()
+void print_mons_left_view_messages()
{
// these are monsters that were marked as SC_NEWLY_SEEN at some point since
// last time this was called. We announce any that leave all at once so
@@ -2763,7 +2763,6 @@ void handle_monsters(bool with_noise)
break;
}
}
- _display_just_seen();
// Process noises now (before clearing the sleep flag).
if (with_noise)
diff --git a/crawl-ref/source/mon-act.h b/crawl-ref/source/mon-act.h
index 699c1da382..5718fd1de6 100644
--- a/crawl-ref/source/mon-act.h
+++ b/crawl-ref/source/mon-act.h
@@ -25,6 +25,7 @@ public:
void mons_set_just_seen(monster *mon);
void mons_reset_just_seen();
+void print_mons_left_view_messages();
bool mon_can_move_to_pos(const monster* mons, const coord_def& delta,
bool just_check = false);
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-02 05:55:10
|
via 40ba7039b06e1722f8741c5272b21c961b46c407 (commit)
from fd82ec16b236e790bda0a673db500fa2ae08fe74 (commit)
-----------------------------------------------------------------------
commit 40ba7039b06e1722f8741c5272b21c961b46c407
Author: David Lawrence Ramsey <poo...@gm...>
Date: Mon Dec 1 23:44:43 2025 -0600
Add another name change option for graffiti.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/database/colourname.txt | 3 +++
crawl-ref/source/dat/database/monname.txt | 10 ++++++++++
2 files changed, 13 insertions(+)
diff --git a/crawl-ref/source/dat/database/colourname.txt b/crawl-ref/source/dat/database/colourname.txt
index d104072acf..2ffbe2007e 100644
--- a/crawl-ref/source/dat/database/colourname.txt
+++ b/crawl-ref/source/dat/database/colourname.txt
@@ -987,6 +987,9 @@ w:2
w:2
@rare graffiti author name@ has passed on the name to someone else worthy of it
+
+w:2
+@changeable non-randgen graffiti author name@ has changed names due to Xom's influence and now goes by @RANDGEN@
%%%%
graffiti_fight
diff --git a/crawl-ref/source/dat/database/monname.txt b/crawl-ref/source/dat/database/monname.txt
index 3520746d06..7d6738bf31 100644
--- a/crawl-ref/source/dat/database/monname.txt
+++ b/crawl-ref/source/dat/database/monname.txt
@@ -1896,6 +1896,16 @@ w:2
w:2
@RANDGEN@
%%%%
+# Same as @graffiti author name@ below, but without orc names, randomly
+# generated names, or rare names.
+changeable non-randgen graffiti author name
+
+w:50
+@ancestor name@
+
+w:2
+@bland graffiti author name@
+%%%%
graffiti author name
w:50
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-02 04:45:15
|
via fd82ec16b236e790bda0a673db500fa2ae08fe74 (commit)
via 70931cf0f517ad0923b3b9f860c3abffd85f2b97 (commit)
from cf55fa217008608f276f85e39a38516322c85155 (commit)
-----------------------------------------------------------------------
commit fd82ec16b236e790bda0a673db500fa2ae08fe74
Author: David Lawrence Ramsey <poo...@gm...>
Date: Mon Dec 1 22:29:32 2025 -0600
Add Shapeshifting professors to graffiti.
Use "talismancer" as one of the names for them, so that fewer of them
sound like shapeshifters as in the monster type. (It's taken from an old
Evocations title that was removed in 1880023187 when talismans and
shapeshifting were added. It seems appropriate here since shapeshifting
requires talismans.)
commit 70931cf0f517ad0923b3b9f860c3abffd85f2b97
Author: David Lawrence Ramsey <poo...@gm...>
Date: Mon Dec 1 22:22:36 2025 -0600
Add another ordinary meeting to graffiti.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/database/colourname.txt | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/crawl-ref/source/dat/database/colourname.txt b/crawl-ref/source/dat/database/colourname.txt
index 259c950640..d104072acf 100644
--- a/crawl-ref/source/dat/database/colourname.txt
+++ b/crawl-ref/source/dat/database/colourname.txt
@@ -1082,6 +1082,8 @@ with @graffiti author name@ for [a good time|tips on how to survive in the dunge
of an athletic club playing [cards|darts|hammer throw|javelin throw|Whack-A-Rock-Fish]
+of an artificer club [testing|tinkering with] [devices|evokables|wands]
+
of a master class on insults being taught by imps
of a @graffiti_remedial_class@
@@ -1390,6 +1392,16 @@ w:2
w:2
the necromancer @rare graffiti author name@ (supposedly)
%%%%
+graffiti_professor_shapeshifting
+
+@changeable graffiti author name@ the [shapeshifter|talismancer]
+
+w:2
+@orc graffiti author name@ [shapeshifter|talismancer]
+
+w:2
+the [shapeshifter|talismancer] @rare graffiti author name@ (supposedly)
+%%%%
graffiti_remedial_class
Remedial @random_skill@ class taught by @graffiti_professor_any@
@@ -1411,6 +1423,9 @@ Remedial Necromancy class taught by @graffiti_professor_necromancy@
w:2
Remedial @random_skill_magic@ class taught by @graffiti_professor_necromancy@
+
+w:2
+Remedial Shapeshifting class taught by @graffiti_professor_shapeshifting@
%%%%
graffiti_rumour
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-02 04:15:15
|
via cf55fa217008608f276f85e39a38516322c85155 (commit)
via 7ed2d023a42206fb5ad9ffa41316a4dc04eff0b4 (commit)
from fc0747a1318971587091bcd2982e28368b67a057 (commit)
-----------------------------------------------------------------------
commit cf55fa217008608f276f85e39a38516322c85155
Author: David Lawrence Ramsey <poo...@gm...>
Date: Mon Dec 1 21:59:49 2025 -0600
Add Invocations/Evocations professors to graffiti
commit 7ed2d023a42206fb5ad9ffa41316a4dc04eff0b4
Author: David Lawrence Ramsey <poo...@gm...>
Date: Mon Dec 1 21:55:02 2025 -0600
Reorder a graffiti professor section.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/database/colourname.txt | 42 ++++++++++++++++++++++------
1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/crawl-ref/source/dat/database/colourname.txt b/crawl-ref/source/dat/database/colourname.txt
index 4f37646f58..259c950640 100644
--- a/crawl-ref/source/dat/database/colourname.txt
+++ b/crawl-ref/source/dat/database/colourname.txt
@@ -1340,25 +1340,35 @@ w:2
w:2
@rare graffiti author name@ (supposedly)
%%%%
-graffiti_professor_magic
+graffiti_professor_evocations
-@changeable graffiti author name@ the [mage|sorcerer|spellcaster|wizard]
+@changeable graffiti author name@ the [artificer|tinkerer]
w:2
-@orc graffiti author name@ [mage|sorcerer|spellcaster|wizard]
+@orc graffiti author name@ [artificer|tinkerer]
w:2
-the [mage|sorcerer|spellcaster|wizard] @rare graffiti author name@ (supposedly)
+the [artificer|tinkerer] @rare graffiti author name@ (supposedly)
%%%%
-graffiti_professor_necromancy
+graffiti_professor_invocations
-@changeable graffiti author name@ the necromancer
+@changeable graffiti author name@ the [cleric|high priest|priest|theologian]
w:2
-@orc graffiti author name@ necromancer
+@orc graffiti author name@ [cleric|high priest|priest|theologian]
w:2
-the necromancer @rare graffiti author name@ (supposedly)
+the [cleric|high priest|priest|theologian] @rare graffiti author name@ (supposedly)
+%%%%
+graffiti_professor_magic
+
+@changeable graffiti author name@ the [mage|sorcerer|spellcaster|wizard]
+
+w:2
+@orc graffiti author name@ [mage|sorcerer|spellcaster|wizard]
+
+w:2
+the [mage|sorcerer|spellcaster|wizard] @rare graffiti author name@ (supposedly)
%%%%
graffiti_professor_mundane
@@ -1370,6 +1380,16 @@ w:2
w:2
the [knight|veteran|warlord|warrior] @rare graffiti author name@ (supposedly)
%%%%
+graffiti_professor_necromancy
+
+@changeable graffiti author name@ the necromancer
+
+w:2
+@orc graffiti author name@ necromancer
+
+w:2
+the necromancer @rare graffiti author name@ (supposedly)
+%%%%
graffiti_remedial_class
Remedial @random_skill@ class taught by @graffiti_professor_any@
@@ -1378,6 +1398,12 @@ Remedial @random_skill_magic@ class taught by @graffiti_professor_magic@
Remedial @random_skill_mundane@ class taught by @graffiti_professor_mundane@
+w:2
+Remedial Evocations class taught by @graffiti_professor_evocations@
+
+w:2
+Remedial Invocations class taught by @graffiti_professor_invocations@
+
# Necromancers should be able to teach necromancy or other magic (from
# branching out) the same way other spellcasters can.
w:2
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-02 02:40:15
|
via fc0747a1318971587091bcd2982e28368b67a057 (commit)
from 8a2acc8fe4edb7d8d02b253b7d5b91ab6a2eb48b (commit)
-----------------------------------------------------------------------
commit fc0747a1318971587091bcd2982e28368b67a057
Author: Isaac Clancy <ik...@ya...>
Date: Mon Nov 24 19:33:21 2025 +1300
Fix resizing the console in webtiles
When playing webtiles on a console, the game has to wait for input from
the console as well as from the websocket connection (to handle tiles
spectators joining). We were doing this by using `select` on stdin and
the websocket, however, we wouldn't stop waiting when a window resize
signal was triggered. To fix this, use `pselect` and handle the `EINTR`
result it returns to stop waiting and handle resize signals when they
arrive.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/libunix.cc | 130 +++++++++++++++++++++++---------------------
crawl-ref/source/tileweb.cc | 111 ++++++++++++++++++++++++-------------
crawl-ref/source/tileweb.h | 12 ++--
3 files changed, 145 insertions(+), 108 deletions(-)
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc
index f1f4d688ba..2f841a3e26 100644
--- a/crawl-ref/source/libunix.cc
+++ b/crawl-ref/source/libunix.cc
@@ -504,6 +504,52 @@ static int proc_mouse_event(int c, const MEVENT *me)
static int pending = 0;
+static bool _curses_fetch_pending_key(bool blocking)
+{
+ if (pending)
+ return true;
+
+ wint_t c;
+ int i;
+ if (blocking)
+ i = get_wch(&c);
+ else
+ {
+ nodelay(stdscr, TRUE);
+ // apparently some need this to guarantee non-blocking -- bwr
+ timeout(0);
+ i = get_wch(&c);
+ nodelay(stdscr, FALSE);
+ }
+
+ switch (i)
+ {
+ case ERR:
+ // getch() returns -1 on EOF, convert that into an Escape. Evil hack,
+ // but the alternative is to explicitly check for -1 everywhere where
+ // we might otherwise spin in a tight keyboard input loop.
+ // XXX: this doesn't work with `blocking` false, because we can't tell
+ // a timeout from an error...
+ if (!blocking)
+ return false;
+ pending = ESCAPE;
+ return true;
+ case OK:
+ // a normal (printable) key
+ pending = c;
+ return true;
+ case KEY_CODE_YES:
+ default:
+ pending = -c;
+ return true;
+ }
+}
+
+static bool _curses_has_key()
+{
+ return _curses_fetch_pending_key(false);
+}
+
static int _get_key_from_curses()
{
#ifdef WATCHDOG
@@ -512,38 +558,19 @@ static int _get_key_from_curses()
watchdog();
#endif
- if (pending)
- {
- int c = pending;
- pending = 0;
- return c;
- }
-
- wint_t c;
-
#ifdef USE_TILE_WEB
refresh();
-
tiles.redraw();
- tiles.await_input(c, true);
+ wint_t c = tiles.await_input(&_curses_has_key);
if (c != 0)
return c;
#endif
- switch (get_wch(&c))
- {
- case ERR:
- // getch() returns -1 on EOF, convert that into an Escape. Evil hack,
- // but the alternative is to explicitly check for -1 everywhere where
- // we might otherwise spin in a tight keyboard input loop.
- return ESCAPE;
- case OK:
- // a normal (printable) key
- return c;
- }
-
- return -c;
+ _curses_fetch_pending_key(true);
+ int result = pending;
+ pending = 0;
+ return result;
}
#if defined(KEY_RESIZE) || defined(USE_UNIX_SIGNALS)
@@ -574,10 +601,8 @@ static int _headless_getchk()
#ifdef USE_TILE_WEB
- wint_t c;
tiles.redraw();
- tiles.await_input(c, true);
-
+ wint_t c = tiles.await_input([]() { return false; });
if (c != 0)
return c;
#endif
@@ -591,11 +616,9 @@ static int _headless_getch_ck()
do
{
c = _headless_getchk();
- // TODO: release?
- // XX this should possibly sleep
- } while (
- ((c == CK_MOUSE_MOVE || c == CK_MOUSE_CLICK)
- && !crawl_state.mouse_enabled));
+ }
+ while ((c == CK_MOUSE_MOVE || c == CK_MOUSE_CLICK)
+ && !crawl_state.mouse_enabled);
return c;
}
@@ -1818,21 +1841,19 @@ void delay(unsigned int time)
static bool _headless_kbhit()
{
- // TODO: ??
if (pending)
return true;
#ifdef USE_TILE_WEB
- wint_t c;
- bool result = tiles.await_input(c, false);
-
- if (result && c != 0)
+ wint_t c = tiles.try_await_input();
+ if (c != 0)
+ {
pending = c;
+ return true;
+ }
+#endif
- return result;
-#else
return false;
-#endif
}
/* This is Juho Snellman's modified kbhit, to work with macros */
@@ -1844,32 +1865,17 @@ bool kbhit()
if (pending)
return true;
- wint_t c;
-#ifndef USE_TILE_WEB
- int i;
-
- nodelay(stdscr, TRUE);
- timeout(0); // apparently some need this to guarantee non-blocking -- bwr
- i = get_wch(&c);
- nodelay(stdscr, FALSE);
+ if (_curses_has_key())
+ return true;
- switch (i)
+#ifdef USE_TILE_WEB
+ wint_t c = tiles.try_await_input();
+ if (c != 0)
{
- case OK:
pending = c;
return true;
- case KEY_CODE_YES:
- pending = -c;
- return true;
- default:
- return false;
}
-#else
- bool result = tiles.await_input(c, false);
-
- if (result && c != 0)
- pending = c;
-
- return result;
#endif
+
+ return false;
}
diff --git a/crawl-ref/source/tileweb.cc b/crawl-ref/source/tileweb.cc
index 67b55fa69e..9edd28bf0d 100644
--- a/crawl-ref/source/tileweb.cc
+++ b/crawl-ref/source/tileweb.cc
@@ -7,6 +7,7 @@
#include <cerrno>
#include <cstdarg>
+#include <signal.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -610,61 +611,95 @@ wint_t TilesFramework::_handle_control_message(sockaddr_un addr, string data)
return c;
}
-bool TilesFramework::await_input(wint_t& c, bool block)
+wint_t TilesFramework::try_await_input()
{
+ if (m_sock_name.empty())
+ return 0;
+
+ fd_set fds;
+ int result;
+ while (true)
+ {
+ FD_ZERO(&fds);
+ FD_SET(m_sock, &fds);
+
+ timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ result = select(m_sock + 1, &fds, nullptr, nullptr, &timeout);
+ if (result == -1 && errno == EINTR)
+ continue;
+
+ if (result <= 0)
+ return 0;
+
+ wint_t c = _receive_control_message();
+ if (c != 0)
+ return c;
+ }
+}
+
+struct save_signal_mask
+{
+ save_signal_mask()
+ {
+ sigprocmask(SIG_SETMASK, nullptr, &old);
+ }
+
+ ~save_signal_mask()
+ {
+ sigprocmask(SIG_SETMASK, &old, nullptr);
+ }
+
+ sigset_t old;
+};
+
+wint_t TilesFramework::await_input(bool(*has_console_input)())
+{
+ if (m_sock_name.empty())
+ return 0;
+
int result;
fd_set fds;
- int maxfd = m_sock_name.empty() ? STDIN_FILENO : m_sock;
+ int maxfd = m_sock;
+
+ save_signal_mask saved_sig_mask;
+ sigset_t signals_to_wait_for;
+ sigemptyset(&signals_to_wait_for);
+ sigaddset(&signals_to_wait_for, SIGWINCH);
+ sigprocmask(SIG_BLOCK, &signals_to_wait_for, nullptr);
while (true)
{
- do
- {
- FD_ZERO(&fds);
- FD_SET(STDIN_FILENO, &fds);
- if (!m_sock_name.empty())
- FD_SET(m_sock, &fds);
-
- if (block)
- {
- tiles.flush_messages();
- result = select(maxfd + 1, &fds, nullptr, nullptr, nullptr);
- }
- else
- {
- timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
+ FD_ZERO(&fds);
+ FD_SET(STDIN_FILENO, &fds);
+ FD_SET(m_sock, &fds);
- result = select(maxfd + 1, &fds, nullptr, nullptr, &timeout);
- }
- }
- while (result == -1 && errno == EINTR);
+ tiles.flush_messages();
- if (result == 0)
- return false;
- else if (result > 0)
+ if (has_console_input())
+ return 0;
+ result = pselect(maxfd + 1, &fds, nullptr, nullptr, nullptr,
+ &saved_sig_mask.old);
+ if (has_console_input())
+ return 0;
+ if (result == -1 && errno == EINTR || result == 0)
+ continue;
+ if (result > 0)
{
- if (!m_sock_name.empty() && FD_ISSET(m_sock, &fds))
+ if (FD_ISSET(m_sock, &fds))
{
- c = _receive_control_message();
-
+ wint_t c = _receive_control_message();
if (c != 0)
- return true;
- }
-
- if (FD_ISSET(STDIN_FILENO, &fds))
- {
- c = 0;
- return true;
+ return c;
}
}
else if (errno == EBADF)
{
// This probably means that stdin got closed because of a
// SIGHUP. We'll just return.
- c = 0;
- return false;
+ return 0;
}
else
die("select error: %s", strerror(errno));
diff --git a/crawl-ref/source/tileweb.h b/crawl-ref/source/tileweb.h
index 0d69aa0bf1..54f2c70838 100644
--- a/crawl-ref/source/tileweb.h
+++ b/crawl-ref/source/tileweb.h
@@ -169,6 +169,7 @@ public:
bool has_receivers() { return !m_dest_addrs.empty(); }
bool is_controlled_from_web() { return m_controlled_from_web; }
+ wint_t try_await_input();
/* Webtiles can receive input both via stdin, and on the
socket. Also, while waiting for input, it should be
able to handle other control messages (for example,
@@ -176,15 +177,10 @@ public:
This function waits until input is available either via
stdin or from a control message. If the input came from
- a control message, it will be written into c; otherwise,
- it still has to be read from stdin.
-
- If block is false, await_input will immediately return,
- even if no input is available. The return value indicates
- whether input can be read from stdin; c will be non-zero
- if input came via a control message.
+ a control message, it will be returned; otherwise, zero
+ will be returned and it still has to be read from stdin.
*/
- bool await_input(wint_t& c, bool block);
+ wint_t await_input(bool(*has_console_input)());
void check_for_control_messages();
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 22:50:10
|
at c023d4456c1753ffdf10563ca8900611a637dc03 (commit)
-----------------------------------------------------------------------
commit c023d4456c1753ffdf10563ca8900611a637dc03
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 16:45:50 2025 -0600
Preview attack delay in equip (SentientSupper)
Updated for the past ~2 years of changes and fixed some bugs.
It may be better to expand the existing armour skill delay message
to unworn equipment instead.
Closes #3715.
-----------------------------------------------------------------------
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 21:55:14
|
via 8a2acc8fe4edb7d8d02b253b7d5b91ab6a2eb48b (commit)
from cc70594c8b8144a7f75f881319480037c5ec030c (commit)
-----------------------------------------------------------------------
commit 8a2acc8fe4edb7d8d02b253b7d5b91ab6a2eb48b
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 15:50:45 2025 -0600
Better name finding for Jiyva beam absorption.
Fall back to beam flavor name if the beam name is empty.
Closes #3717.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/beam.cc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 02e074f7fb..fca268707a 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -5507,7 +5507,8 @@ void bolt::affect_monster(monster* mon)
{
mprf(MSGCH_GOD, GOD_JIYVA,
"%s absorbs the %s as it strikes your slime.",
- god_speaker(GOD_JIYVA).c_str(), name.c_str());
+ god_speaker(GOD_JIYVA).c_str(), !name.empty() ? name.c_str()
+ : _beam_type_name(flavour).c_str());
}
finish_beam();
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 21:25:14
|
via db22aed277518ef4212d6b53f37e20187cd4cb06 (commit)
from 37b4dd418daece5aa2a7dea356c5793cae8e34e0 (commit)
-----------------------------------------------------------------------
commit db22aed277518ef4212d6b53f37e20187cd4cb06
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 15:20:40 2025 -0600
update ego desc
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/descript/egos.txt | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/crawl-ref/source/dat/descript/egos.txt b/crawl-ref/source/dat/descript/egos.txt
index 0340c9cb54..ae441ed752 100644
--- a/crawl-ref/source/dat/descript/egos.txt
+++ b/crawl-ref/source/dat/descript/egos.txt
@@ -268,8 +268,9 @@ It protects you from the effects of both fire and cold.
%%%%
resonance (Resonance) armour ego
-It improves the success rate of your Forgecraft spells and enhances your melee
-attacks proportionally to your Forgecraft skill.
+It improves the success rate of your Forgecraft spells, and enhances your melee
+attacks proportionally to your Forgecraft skill when you melee an enemy that is
+adjacent to one of your constructs.
%%%%
see invisible (SInv) armour ego
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 21:20:13
|
at 37b4dd418daece5aa2a7dea356c5793cae8e34e0 (commit)
-----------------------------------------------------------------------
commit 37b4dd418daece5aa2a7dea356c5793cae8e34e0
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 15:17:56 2025 -0600
Alternate resonance ego rework.
Require an adjacent construct for the bonus damage. Maybe annoying to set up?
-----------------------------------------------------------------------
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 20:50:14
|
at 844c54725df64670ba278d4ec550ed12c31f0104 (commit)
-----------------------------------------------------------------------
commit 844c54725df64670ba278d4ec550ed12c31f0104
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 14:45:06 2025 -0600
Rework death ego.
Make it work like command, which was a more successful design.
-----------------------------------------------------------------------
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 20:35:14
|
via cc70594c8b8144a7f75f881319480037c5ec030c (commit)
from b6ab66b0f8b2cfcccb1efa350216c1248c52e1a5 (commit)
-----------------------------------------------------------------------
commit cc70594c8b8144a7f75f881319480037c5ec030c
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 14:31:23 2025 -0600
Reduce resonance damage.
Now provides 1.5% per sklevel, down from 2%.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/fight.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index c95843de5f..55371d552d 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -1788,8 +1788,8 @@ int resonance_damage_mod(int dam, bool random)
{
if (you.wearing_ego(OBJ_ARMOUR, SPARM_RESONANCE))
{
- dam = random ? div_rand_round(dam * (100 + you.skill(SK_FORGECRAFT, 2)), 100)
- : dam * (100 + you.skill(SK_FORGECRAFT, 2)) / 100;
+ dam = random ? div_rand_round(dam * (100 + you.skill_rdiv(SK_FORGECRAFT, 3, 2)), 100)
+ : dam * (100 + you.skill(SK_FORGECRAFT, 3) / 2) / 100;
}
return dam;
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 20:25:14
|
via b6ab66b0f8b2cfcccb1efa350216c1248c52e1a5 (commit)
from f00789f1cf048ec560fd567beaddf22b96ed1149 (commit)
-----------------------------------------------------------------------
commit b6ab66b0f8b2cfcccb1efa350216c1248c52e1a5
Author: Zhang Haocheng <505...@us...>
Date: Tue Dec 2 04:21:50 2025 +0800
feat: show failure rates of abilities in chardump (#4821)
Shows failure rates of abilities in the chardump `a:` list, e.g. `a:
Oozemancy (3%), Slimify (12%)`, similar to the passive effects list in
format.
There were a couple of times that either me or my friends wanted to know
the failure rates of abilities without having to start the game. I'm not
sure if it's intuitive enough so that most people won't mistake it for
success rate, or something else. Maybe showing a table like the spell
library can be better?
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/ability.cc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/crawl-ref/source/ability.cc b/crawl-ref/source/ability.cc
index d332ee5730..2ac849e8c5 100644
--- a/crawl-ref/source/ability.cc
+++ b/crawl-ref/source/ability.cc
@@ -908,9 +908,9 @@ string print_abilities()
{
for (unsigned int i = 0; i < talents.size(); ++i)
{
- if (i)
- text += ", ";
- text += ability_name(talents[i].which);
+ text += make_stringf("%s%s (%s)", i ? ", " : "",
+ ability_name(talents[i].which).c_str(),
+ failure_rate_to_string(talents[i].fail).c_str());
}
}
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 19:55:14
|
at f8a0e38537e2dd799ea26de8453cd55c1d974dc1 (commit)
-----------------------------------------------------------------------
commit f8a0e38537e2dd799ea26de8453cd55c1d974dc1
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 13:52:26 2025 -0600
Improve sticky flame messaging.
Add resist messages for player and monster.
Closes #3885.
-----------------------------------------------------------------------
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 19:35:10
|
via f00789f1cf048ec560fd567beaddf22b96ed1149 (commit)
from 07e17c3bcb62a17a05bd36598782bf5395852c37 (commit)
-----------------------------------------------------------------------
commit f00789f1cf048ec560fd567beaddf22b96ed1149
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 13:30:11 2025 -0600
Fix: adjust the nameless infernalist trove.
Don't spawn monsters on the inside.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/dat/des/portals/trove.des | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/crawl-ref/source/dat/des/portals/trove.des b/crawl-ref/source/dat/des/portals/trove.des
index 017346ead8..25b36ade51 100644
--- a/crawl-ref/source/dat/des/portals/trove.des
+++ b/crawl-ref/source/dat/des/portals/trove.des
@@ -731,6 +731,7 @@ KFEAT: FL = l
KFEAT: y = x
: vault_metal_statue_setup(_G, "G", "fiery conduit")
NSUBST: l = 4:LLF / 4:LLFll / *:l
+KFEAT: ~ = l
TILE: c = wall_stone_scorched
TILE: m = dngn_transparent_wall_red
TILE: o = wall_permarock_clear_darkgray
@@ -756,12 +757,12 @@ xllllllloxm'....myolllllxlllllllllxllx
xlllllllommm.<.mmmolllllxllllllllxlllx
xllllllloym.....mxoooooolllllllllxlllx
xlllllllox...m...xxxxxxollllllllxllllx
-xllllllloxA.mmm..dxyllxolllllllxlllllx
-xllllllloxxxymxxd'W'Glxolllllllxlllllx
+xllllllloxA.mmm..dxy~~xolllllllxlllllx
+xllllllloxxxymxxd'W'G~xolllllllxlllllx
xllllllloooooooxxWdW'yxollllllxllllllx
xllllllxlllllloxy'WdWxxooooooolllllllx
-xlllllxllllllloxlG'W'dxxmyxxxolllllllx
-xlllllxllllllloxllyxd'.mmm.Axolllllllx
+xlllllxlllllllox~G'W'dxxmyxxxolllllllx
+xlllllxlllllllox~~yxd'.mmm.Axolllllllx
xllllxlllllllloxxxxxx...m...xolllllllx
xlllxlllllllllooooooxm.....myolllllllx
xlllxllllllllxlllllommm.<.mmmolllllllx
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 19:20:09
|
via 07e17c3bcb62a17a05bd36598782bf5395852c37 (commit)
via 5803638258d1efd1b2ca33dcd8a7d0f9305ad2d8 (commit)
from 47fa2142d4440ccc63a331912aedd7d94f095cce (commit)
-----------------------------------------------------------------------
commit 07e17c3bcb62a17a05bd36598782bf5395852c37
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 12:49:55 2025 -0600
Improve wizmode parchment handling.
Allow specifying a parchment spell in &o. Default to generating a parchment
rather than the first book containing a spell when providing a spell name.
commit 5803638258d1efd1b2ca33dcd8a7d0f9305ad2d8
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 00:54:18 2025 -0600
Fix: let spriggan druids boon while blind.
The type of monster_near_iterator used required the druid to actually be able
to see the monster, meaning that blinding them prevented it from working.
Appears to be unintended, so use the other monster_near_iterator instead.
Do the same for pharaoh ant bind souls, just in case.
Fixes #4308
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/items.cc | 32 ++++++++++++++++----------------
crawl-ref/source/mon-death.cc | 4 ++--
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index d1b209d190..5db21068a8 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -4570,22 +4570,12 @@ static bool _book_from_spell(const char* specs, item_def &item)
if (type == SPELL_NO_SPELL)
return false;
- for (int i = 0; i < NUM_BOOKS; ++i)
- {
- const auto bt = static_cast<book_type>(i);
- if (!book_exists(bt))
- continue;
- for (spell_type sp : spellbook_template(bt))
- {
- if (sp == type)
- {
- item.sub_type = i;
- return true;
- }
- }
- }
+ if (!is_player_book_spell(type))
+ return false;
- return false;
+ item.sub_type = BOOK_PARCHMENT;
+ item.plus = static_cast<int>(type);
+ return true;
}
bool get_item_by_name(item_def *item, const char* specs,
@@ -4650,7 +4640,7 @@ bool get_item_by_name(item_def *item, const char* specs,
switch (class_wanted)
{
case OBJ_BOOKS:
- // Try if we get a match against a spell.
+ // Make a parchment if we get a match against a spell.
if (_book_from_spell(specs, *item))
type_wanted = item->sub_type;
break;
@@ -4764,6 +4754,16 @@ bool get_item_by_name(item_def *item, const char* specs,
}
item->skill_points = random_range(2000, 3000);
}
+ else if (item->sub_type == BOOK_PARCHMENT)
+ {
+ char buf[80];
+ msgwin_get_line_autohist("What parchment spell? ", buf, sizeof(buf));
+ if (buf[0] != '\0')
+ {
+ if (!_book_from_spell(buf, *item))
+ mpr("That parchment doesn't seem to exist.");
+ }
+ }
else if (type_wanted == BOOK_RANDART_THEME)
build_themed_book(*item, capped_spell_filter(20));
else if (type_wanted == BOOK_RANDART_LEVEL)
diff --git a/crawl-ref/source/mon-death.cc b/crawl-ref/source/mon-death.cc
index 9efa81463e..a8a268e5c8 100644
--- a/crawl-ref/source/mon-death.cc
+++ b/crawl-ref/source/mon-death.cc
@@ -1326,7 +1326,7 @@ static void _infestation_create_scarab(monster* mons)
static void _pharaoh_ant_bind_souls(monster *mons)
{
bool bound = false;
- for (monster_near_iterator mi(mons, LOS_NO_TRANS); mi; ++mi)
+ for (monster_near_iterator mi(mons->pos(), LOS_NO_TRANS); mi; ++mi)
{
if (!mons_can_bind_soul(mons, *mi))
continue;
@@ -1601,7 +1601,7 @@ static void _make_derived_undead(monster* mons, bool quiet,
static void _druid_final_boon(const monster* mons)
{
vector<monster*> beasts;
- for (monster_near_iterator mi(mons); mi; ++mi)
+ for (monster_near_iterator mi(mons->pos()); mi; ++mi)
{
if (mons_is_beast(mons_base_type(**mi)) && mons_aligned(mons, *mi))
beasts.push_back(*mi);
--
Dungeon Crawl Stone Soup
|
|
From: <gi...@cr...> - 2025-12-01 19:10:09
|
via 47fa2142d4440ccc63a331912aedd7d94f095cce (commit)
from 632e635cf8060dcc5823838a19275d30b50f8c67 (commit)
-----------------------------------------------------------------------
commit 47fa2142d4440ccc63a331912aedd7d94f095cce
Author: hellmonk <nld...@gm...>
Date: Mon Dec 1 13:06:42 2025 -0600
Let draw out power cure mesm and fear.
Free your mind. Closes #4444.
-----------------------------------------------------------------------
Summary of changes:
crawl-ref/source/ability.cc | 2 ++
crawl-ref/source/god-abil.cc | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/crawl-ref/source/ability.cc b/crawl-ref/source/ability.cc
index a2b1db2a5c..d332ee5730 100644
--- a/crawl-ref/source/ability.cc
+++ b/crawl-ref/source/ability.cc
@@ -2064,6 +2064,8 @@ static bool _check_ability_possible(const ability_def& abil, bool quiet = false)
&& !you.duration[DUR_SLOW]
&& !you.attribute[ATTR_HELD]
&& !you.petrifying()
+ && !you.beheld()
+ && !you.afraid()
&& !you.is_constricted())
{
if (!quiet)
diff --git a/crawl-ref/source/god-abil.cc b/crawl-ref/source/god-abil.cc
index b565de96c3..1624b76170 100644
--- a/crawl-ref/source/god-abil.cc
+++ b/crawl-ref/source/god-abil.cc
@@ -5366,6 +5366,10 @@ void ru_draw_out_power()
you.duration[DUR_SLOW] = 0;
you.duration[DUR_PETRIFYING] = 0;
+ // remove fearmongers and mesmerizers
+ you.clear_beholders();
+ you.clear_fearmongers();
+
int hp_inc = div_rand_round(you.piety(), 16);
hp_inc += roll_dice(div_rand_round(you.piety(), 20), 6);
inc_hp(hp_inc);
--
Dungeon Crawl Stone Soup
|