[spoiler]
Любое нарушение этих правил приводит к тому, что визуально руны могут ложиться на КД и тому подобное - но с их восстановлением твориться жуткая дичь.
Я то и имел в виду визуально. Еще я заметил в официальном коде Тринити, что состояние рун на момент каста записывается в момент каста. Насколько я помню - в заклинаниях есть две основных фазы - каст и прилет. Если заклинание мгновенное (без анимации снаряда), то все равно расчет урона идет только на фазе прилета , потому что пока снаряд долетит - может быть иммун или еще что. Поэтому в фазе каста сохраняется состояние рун, бафы. А в состоянии прилета - берутся по факту бафы и дебафы на цели заклинания и уже происходит полный расчет.
Так вот, между этими фазами есть промежуток (потому что момент каста и урона могут занимать секунды и больше), в котором цикл сервера продолжается. И в этот момент в этом промежутке руны могут обновится через ResyncRunes, от чего текущее и прошлое состояние (до и после) меняется. Но заклинание хранит другую версию того что было до, потому что состояние рун записывается в момент каста. В этом и наверное кроется ошибка.
Нужно предыдущее состояние рун хранить в отдельной переменной и обновлять ее всегда когда обновляются руны любым из двух способов (через каст заклинания или через ResyncRunes). И тогда если в промежутке между кастом и прилетом прокнет обновление КД через ResyncRunes - последовательность не нарушиться.
Вот как на мой взгляд происходит баг:
1) Допустим у нас две руны на КД, и скоро КД одной из них спадет. Игрок нажимает каст заклинания, сохраняется состояние рун (к примеру 11-01-01)
2) В промежутке между кастом и прилетом одна руна восстанавливается в Player::RegenerateAll() и посылается пакет:
До (11-01-01)
После (11-11-01)
3) В фазе прилета заклинание попадает в цель (или промах) выбирается время кулдауна 10с или 1,5с, вешается КД на руну, новое состояние теперь такое: 01-11-01
В итоге сервер получает два пакета почти одновременно:
1й) пакет от Player::RegenerateAll() с данными:
До (11-01-01)
После (11-11-01)
2й) пакет с кастом заклинания с данными:
До (11-01-01))
После (01-11-01)
Цепочка состояний нарушена, но что у голове у клиента в голове непонятно, возможно он просчитает своей логикой и восстановит последовательность путем каких-то допущений. Но что будет, если данным заклинанием окажется Кровоотвод, или например комбинация этой ситуации с последующим или предшествующим Кровоотводом?
Ведь смотрите, зачем вообще отправлять информацию что было до и что было после? Если можно просто оправить маску тех рун, которые изменились без всяких до и после и плюс информацию о кд. Да даже просто инфу о текущих КД? Как он это делает с обновлением маны, например.
Я думаю это сделано по той причине, что когда пакеты приходят не по порядку, он по цепочке состояний может вернуться и пересчитать состояние рун на текущее время. Типа если потерялся пакет - цепочка нарушена - и он ищет то место в цепочке куда бы пакет подошел, а затем учитывая этот пакет - переосмысливает текущее состояние. Или просто игнорит его, я не знаю.
Теперь когда по вышеописаному сценарию у нас нарушена цепочка - он думает что пакет потерялся или либо игнорит второй пакет, либо пытается его вписать между предыдущими чтобы пересчитать текущее состояние.
Но нужно также учитывать что у пакетов есть айдишники и он еще может следить за их последовательностью. Поэтому точно сказать нельзя что будет, но можно сказать точно, что в общем случае ему по айдишникам и пересланным КД удается понять, что в цепочке состояний была ошибка, а не потеря пакетов, и косвенно он может правильно восстановить цепочку и забить на это. Что якобы происходит в обычном случае.
Но когда эта ошибка происходит в паре с кровоотводом, который инвертирует обычный процесс восстановления рун - клиент может ошибиться при косвенном расчете и неправильно восстановить цепочку, либо предполагая что заклинание может только вешать кд на руны, а не восстанавливать, либо еще что-то.
В общем я у себя в 3.4.3 реализовал так, что заклинание не сохраняет состояние рун при касте. Состояние рун у меня сохраняется только после факта синхронизации любым их методов (каст или ResyncRunes в Player::RegenerateAll() ). Таким образом плевать на последовательность синхронизации и обсчета каста - прилета - цепочка состояний сохраняется всегда правильная. У меня даже можно повешать КД несколько раз подряд, на каждую руну отдельно, либо сразу на несколько, не важно, предыдущее состояние перезапишется только в момент отсылки пакета. Что и гарантирует последовательность
Сообщение отредактировал riomcboo: 07 февраля 2025 - 20:27