From 85872327316914451f3a11ef2a0a66bf588b3788 Mon Sep 17 00:00:00 2001 From: stribog Date: Thu, 27 Aug 2026 14:45:29 +0200 Subject: [PATCH] fix(dg): let a sleeping player use commands near a "*" command trigger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Спящий игрок не запускает command-триггеры -- но раньше команда при этом ещё и съедалась: триггер отвечал "Сделать это в ваших снах?" и возвращал 1, то есть "команду обработали". А compare_cmd для арглиста "*" совпадает с любой командой, и такие триггеры не редкость. Рядом с любым из них спящий не мог выполнить вообще ничего -- в том числе "проснуться": на каждую команду приходил один и тот же ответ, и выбраться можно было только реконнектом. Так это и поймал Мородей. Проверка позиции теперь просто пропускает триггер, а команду разбирает интерпретатор, у которого своя проверка минимальной позиции: "проснуться" исполняется, а всё, что спящему не положено, он и отсечёт сам. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH --- src/engine/scripting/dg_triggers.cpp | 30 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/engine/scripting/dg_triggers.cpp b/src/engine/scripting/dg_triggers.cpp index 88cfb6cc3..f9dbb6b9a 100644 --- a/src/engine/scripting/dg_triggers.cpp +++ b/src/engine/scripting/dg_triggers.cpp @@ -488,11 +488,13 @@ int command_mtrigger(CharData *actor, char *cmd, const char *argument) { } if (compare_cmd(GET_TRIG_NARG(t), t->arglist.c_str(), cmd)) { - if (!actor->IsNpc() - && (actor->GetPosition() == EPosition::kSleep)) // command триггер не будет срабатывать если игрок спит - { - SendMsgToChar("Сделать это в ваших снах?\r\n", actor); - return 1; + // Спящий игрок command-триггеры не запускает. Раньше здесь команда ещё и + // съедалась с ответом "Сделать это в ваших снах?", и рядом с триггером на "*" + // (он совпадает с любой командой) спящий не мог выполнить вообще ничего -- в том + // числе "проснуться", то есть выбирался только реконнектом. Теперь триггер просто + // пропускаем, а команду разбирает интерпретатор со своей проверкой позиции. + if (!actor->IsNpc() && actor->GetPosition() == EPosition::kSleep) { + continue; } ADD_UID_CHAR_VAR(buf, t, actor, "actor", 0); @@ -1014,11 +1016,10 @@ int cmd_otrig(ObjData *obj, CharData *actor, char *cmd, const char *argument, in if (IS_SET(GET_TRIG_NARG(t), type) && (t->arglist[0] == '*' || 0 == strn_cmp(t->arglist.c_str(), cmd, t->arglist.size()))) { - if (!actor->IsNpc() - && (actor->GetPosition() == EPosition::kSleep)) // command триггер не будет срабатывать если игрок спит - { - SendMsgToChar("Сделать это в ваших снах?\r\n", actor); - return 1; + // Спящий игрок command-триггеры не запускает, но и команду у него не отбираем: + // см. комментарий в command_mtrigger. + if (!actor->IsNpc() && actor->GetPosition() == EPosition::kSleep) { + continue; } ADD_UID_CHAR_VAR(buf, t, actor, "actor", 0); skip_spaces(&argument); @@ -1397,11 +1398,10 @@ int command_wtrigger(CharData *actor, char *cmd, const char *argument) { } if (compare_cmd(GET_TRIG_NARG(t), t->arglist.c_str(), cmd)) { - if (!actor->IsNpc() - && (actor->GetPosition() == EPosition::kSleep)) // command триггер не будет срабатывать если игрок спит - { - SendMsgToChar("Сделать это в ваших снах?\r\n", actor); - return 1; + // Спящий игрок command-триггеры не запускает, но и команду у него не отбираем: + // см. комментарий в command_mtrigger. + if (!actor->IsNpc() && actor->GetPosition() == EPosition::kSleep) { + continue; } // в идеале бы в триггере бой проверять а не хардкодом, ленивые скотины.... if (actor->GetPosition() == EPosition::kFight && t->arglist[0] != '*') {