Skip to content

fix(dg): shake-off never cleared mob lag, set_wait(0) is a no-op (#3658) - #3673

Merged
bylins merged 1 commit into
masterfrom
fix/hitprcnt-shakeoff-wait-3658
Aug 2, 2026
Merged

fix(dg): shake-off never cleared mob lag, set_wait(0) is a no-op (#3658)#3673
bylins merged 1 commit into
masterfrom
fix/hitprcnt-shakeoff-wait-3658

Conversation

@bylins

@bylins bylins commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Продолжение #3658.

Что осталось после прошлого фикса

Гард от перезапуска (93b901d, PR #3668) убрал лишние экземпляры HitPercent-триггера. Но внутри одного экземпляра спам никуда не делся: на каждую команду триггера в комнату летело «Множество быстрых теней метнулись вокруг ...», и в лог падала строка «моб отжил из лага/стана в HitPercent».

Причина

Shake-off снимал лаг вызовом ch->set_wait(0), а CharData::set_wait() ноль игнорирует — в теле стоит guard (src/engine/entities/char_data.cpp:1205):

void CharData::set_wait(const unsigned _) {
	if (_ > 0) {
		chardata_wait_list.insert(this);
		m_wait = _;
	}
}

Аффекты (kHold, kStopFight, kMagicStopFight, kSleep) снимались честно, а m_wait оставался прежним. Поэтому следующая команда триггера снова проходила условие блока и снова всё это печатала.

Заменено на ch->zero_wait() — штатный метод обнуления (char_data.h:517), которым уже пользуются bash, slay, firstaid, fight_stuff, char_handler, comm и world_characters. Из chardata_wait_list персонаж при этом не удаляется, и это правильно: обход в db.cpp:3706 сам выкидывает оттуда тех, у кого лаг кончился.

Как подтверждено

Лог боя с мобом «Электра» (триггер 97132, зона 971). Номера строк в логе смещены на 4 относительно тела скрипта:

В логе В скрипте Команда
10 14 load mob 97115
13 17 load mob 97116
22 26 load mob 97119
26 30 echo __Неожиданно...

Последовательность 13→26, 13→26, 10→26, 13→26, 22→26 — это один проход while на пять итераций, по две команды в каждой, и каждая логировалась. Всё уложилось в одну миллисекунду, то есть игрового пульса между командами не было и лаг взяться заново не мог — он просто не снимался.

Прочее

Единственный оставшийся в проекте вызов set_wait(0) — в fight_hit.cpp:1127, он внутри закомментированного блока.

Патч VERSION 0.1.24 → 0.1.25. Сборка чистая, тесты проходят (604).

🤖 Generated with Claude Code

Продолжение #3658. Гард от перезапуска (93b901d) убрал лишние экземпляры
HitPercent-триггера, но внутри одного экземпляра спам остался: на каждую
команду триггера в комнату летели "Множество быстрых теней..." и строка
в лог "моб отжил из лага/стана в HitPercent".

Причина: shake-off снимал лаг вызовом ch->set_wait(0), а CharData::set_wait()
игнорирует ноль -- в теле стоит guard "if (_ > 0)" (char_data.cpp:1205).
Аффекты (kHold, kStopFight, kMagicStopFight, kSleep) снимались честно, а
m_wait оставался прежним, поэтому следующая команда снова проходила условие
блока и снова всё это печатала.

Заменено на ch->zero_wait() -- штатный метод обнуления (char_data.h:517),
которым уже пользуются bash, slay, firstaid, fight_stuff, char_handler,
comm и world_characters. Из chardata_wait_list персонаж при этом не
удаляется, и это правильно: обход в db.cpp:3706 сам выкидывает оттуда тех,
у кого лаг кончился.

Проверено на логе боя с мобом "Электра" (триггер 97132, зона 971): пять
итераций while за одну миллисекунду, по две записи на итерацию -- игрового
пульса между командами не было, лаг взяться заново не мог, он просто не
снимался.

Единственный оставшийся в проекте вызов set_wait(0) -- в fight_hit.cpp:1127,
он внутри закомментированного блока.

Патч VERSION 0.1.24 -> 0.1.25. Сборка чистая, тесты проходят (604).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bylins
bylins merged commit bd2e6b0 into master Aug 2, 2026
20 checks passed
@bylins
bylins deleted the fix/hitprcnt-shakeoff-wait-3658 branch August 2, 2026 11:55
bylins added a commit that referenced this pull request Aug 2, 2026
По просьбе игрока (Хендела, воззвание к богам): заклинания добавили, а
справки по ним нет -- непонятно, что они делают и кому доступны.

Обе статьи собраны по конфигам, а не на глаз:

- kUnweave ("расплести чары"), spells.xml: магия света, kTarCharRoom|kTarSelf,
  <unaffect affect_flags="kAfDispellable" debuff_only="Y"> -- снимает с цели
  только враждебные чары и только те, что помечены снимаемыми. Волшебник и
  купец, 12 уровень, 4 круг.
- kCleanseArea ("очищение"), spells.xml: магия света, kTarRoomThis + kMagRoom,
  <unaffect affect_flags="kAfDispellable"> без debuff_only -- снимает с комнаты
  все снимаемые чары, и чужие, и свои. Волшебник и паладин, 15 уровень, 5 круг.

Формат повторяет соседние статьи: рамка 80 байт видимой ширины, пары
$COLORx/$COLORn добавляют по 14 байт, пары &X/&n -- по 4. Ключевые слова
даны без пробелов, как у "контроль погоды" -> КОНТРОЛЬПОГОДЫ; для
"расплести чары" добавлено короткое РАСПЛЕСТИ. Пересечений с ключами в
других .hlp нет.

Из той же партии световых заклинаний справки по-прежнему нет у "подавление",
"разъедание", "разлом" и "силки" -- отдельным решением.

Патч VERSION 0.1.24 -> 0.1.26: 0.1.25 занят веткой fix/hitprcnt-shakeoff-wait-3658
(PR #3673), обе отведены от одного мастера.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant