Просмотр полной версии : Телепорт
Народ посоветуйте как разрешить такую проблемку.
Грубый пример (правда нето):
скажем началась драка, поток проги видя потерю сп начинаеть хавать банки. Тут я понимаю что невывоз и жму бсое и лечу 2 мин в лаге (тоеть тут меня уже нет но в городе тоже) прога все эти 2 мин спамит бестолку реквестюзеитем.
как можно отслеживать окончание провала после события телепортлокейшн?
врод как appearing шлет клиент как все переварит. А отвечает ли на него сервер чемто?
supernewbie
26.01.2012, 15:05
по идее ничем кроме данных после телепорта, т.е. нпсинфо, чаринфо, хз что будет если слать appearing самому сразу после телепорта, по логике вещей клиент может прикуеть, так что самое норм - хукать сенд пакет и ждать пока клиент сам отправит apprearing
Хукнут не проблема, но решение мне кажетса уж совсем неизящным. Ловить чаринфо это тоже как "наощупь".
проблема особенно острая в случае:
делает тп кудато свм, затем основа,сд остаетса на месте. В это время падают денс сонг.
Если я в момент тп сразу меняю в бд свою локацию начинает истерично денсить свм считая что я уже рядом. Если жду аперинга то пляшет сд. А посути меня нет не там не тут. Гдежеблять я в это время и как им "сказать" что меня нет.
Добавлять какойнеть флаг char.inaccess если ток чтоб при установлено getdist возвращала скажем 9999.
supernewbie
26.01.2012, 16:21
ну да, на сервере так и делают, там есть переменная isTeleporting
TechnoWiz@rd
04.02.2012, 02:16
mira, можно сделать проще. Перед бафом отсылать пакет Action c ObjectID основы, если основа уже телепортировалась, то получим пакет MyTargetSelected от сервера, если нет то пакет ActionFail.
с таргетными скилами итак сначало выбирают цель (если выбралась то бафают).
но вопервых брать в таргет перед любыми скилами это лишняя потеря времени, скажем пвп.
во вторых сопартиец выделитса в пати даже если он на другом конце карты (чтоб работал суммон френд канечноже)
TechnoWiz@rd
04.02.2012, 14:18
mira, а если попробовать отслеживать пакеты ObjectDelete и CharInfo. Если ловим на сапе ObjectDelete с ID основы, запрещаем баф. Когда ловим CharInfo, опять-же с ID основы, то значит основа появилась в зоне видимости сапа и баф разрешаем. Точное расстояние между чарами можно получить через уравнение длинны вектора:
Sqrt( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 );
Я так и щитаю) но там иногда получаетса отрицательное число которое под корнем вызывает исключение ариф. Процессора если считать "в лоб".
supernewbie
06.02.2012, 21:48
mira, как у тебя после возведения в квадрат получается отрицательное число?)
mira, как у тебя после возведения в квадрат получается отрицательное число?)
я хотел спросить то же самое, но все-таки воздержался))))
mira, как у тебя после возведения в квадрат получается отрицательное число?)
function L2VectorDist(const v1,v2: TL2Vector):single;
var
fx,fy,fz:double;
summ : double;
begin
fx:=(v1.x-v2.x)*(v1.x-v2.x);
fy:=(v1.y-v2.y)*(v1.y-v2.y);
fz:=(v1.z-v2.z)*(v1.z-v2.z);
summ:=abs(fx+fy+fz);
result:=sqrt(summ);
end;
у меня дистанция считаетса вот так. без abs иногда получаетса непонятная уета с summ<0
Добавлено через 4 минуты
если ктото мне объяснит в чем тут чудо я буду тока рад)
пока поставил абс как костыль вроде норм...
supernewbie
07.02.2012, 04:31
mira, точно уверен что < 0 получается?
пробывал проверять что приходит в функцию вообще?
а само значение, пусть даже меньше нуля - правильное? если правильное, то можно помножить на (-1)
иф q < 0 то
q*(-1)
mira, точно уверен что < 0 получается?
пробывал проверять что приходит в функцию вообще?
проверял. Норм все в функцию приходит.
Я функцию выносил в тестовый апликейшн и при больших цифрах возникала ошибка ариф.процессора типа отрицательное число под корнем. Проверил степ-степ отладкой так и оказалось. Хз в чем дело, мб какоето переполнение.
supernewbie
07.02.2012, 10:01
Норм все в функцию приходит.
а как именно ты это узнал?
fx:=(v1.x-v2.x)*(v1.x-v2.x);
вот если делфи видит это как
fx:=integer((v1.x-v2.x)*(v1.x-v2.x));
тогда в принципе все обьяснимо
вот если делфи видит это как
fx:=integer((v1.x-v2.x)*(v1.x-v2.x));
тогда в принципе все обьяснимо
очень сомневаюсь...
и кстати замени double на int64 (мб и на LongInt, хотя туда вряд ли влезет квадрат слишком отдаленных координат), один хрен координаты не имеют десятичных точек.
а как именно ты это узнал?
да просто.
Как тока у меня вышла наепка я сразуже запомнил координаты персов м/у которыми считалось.
Потом засунул их в тестовую прогу с копией функции - баг повторилса.
да. Растояние был довольно большое
Выложи сюда эти координаты ради интереса.
x1=3434232
y1=23000
z1=2000
x2=65788
y2=455
z2=2000
например это
Добавлено через 1 минуту
координаты взяты из головы а нее из реальных игровых условий
факт что эти цифры уже приводят к ошибке
Добавлено через 10 минут
кстате ошибка возникает при использовании структуры
TL2Vector = packed record
x,y,z:integer;
end;
если сделать
TL2Vector = packed record
x,y,z:DWORD;
end;
ошибки нет, впрочем расчет всеравно получаетса ошибочный
что еще раз подтверждает теорию о переполнении занкового и беззнакового числа
видимо ясно почему в клиенте юзают тип DOUBLE внутри клиента а integer-ы тока в пакетном уровне
не понимаю зачем корейцам DOUBLE.
DOUBLE - число с десятичной точкой (нафига, если координаты все равно целые числа????), 64 бита
int, DWORD - целые, 32 бита
Int64 - целое, 64 бита.
Учитывая размеры карты, то сейчас для хранения любой координаты стандартного int'а более чем достаточно, там еще разрядов 10 в запасе относительно самой максимально координаты.
А вот для вычисления квадрата расстояния, если один персонаж находится в деревне хуманов, а другой где-нить возле деревни гномов, то явно для результата потребуется больше 32 бит.
fx:=integer((v1.x-v2.x)*(v1.x-v2.x)); - вот это все таки оказалось правдой. Причем видит так не только делфи))))
fx:=double((v1.x-v2.x)*(v1.x-v2.x)); - вот так скорее всего заработает верно. По крайней мере на плюсах аналогичный пример стал считать правильно
угу проверил это подтвердилось. а так не сильно заморачивалса этой багой.
у меня растояния больше 3к боты считали что цель слишком далеко чтоб уделять ей внимание поэтому хватало кастыля. щас разобрались исправил)
за тем и нужны DOUBLE чтоб производить подобные расчеты, плюс любой графический движок работает только с floating point числами
TechnoWiz@rd
08.02.2012, 12:07
Я так и щитаю) но там иногда получаетса отрицательное число которое под корнем вызывает исключение ариф. Процессора если считать "в лоб".
По модулю возьми вектор, тогда не будет выскакивать исключений.
Так и было в виде костыля.
Щас разбил выражение все стало верно.
f : double;
fx,fy,fz : double;
begin
f:= v1.x - v2.x:
fx:=f*f;
.........
Result:=sqrt(fx+fy+fz)
supernewbie
08.02.2012, 17:17
mira, в л2вектор x также инт остался?
а то у меня
i1,i2:integer;
i3:double;
i1:=high(integer);
i2:=high(integer);
i3:=i1+i2;
WriteLn(FloatToStr(i3)); //-2
i1,i2:integer;
i3:double;
i1:=high(integer);
i2:=high(integer);
i3:=int64(i1)+int64(i2);
WriteLn(FloatToStr(i3)); //4294967294
что в 7, что в xe2
да там инты.
с двордом ваще бред получилса ибо отрицательная координата z часто принимающая в игре минусовые значения как дворд оказывалась 234334345 типа того)
ну вот как я щас написал считает все без нареканий и глюков
Добавлено через 6 минут
mira, в л2вектор x также инт остался?
а то у меня
i1,i2:integer;
i3:double;
i1:=high(integer);
i2:=high(integer);
i3:=i1+i2;
WriteLn(FloatToStr(i3)); //-2
i1,i2:integer;
i3:double;
i1:=high(integer);
i2:=high(integer);
i3:=int64(i1)+int64(i2);
WriteLn(FloatToStr(i3)); //4294967294
что в 7, что в xe2
первый вариант это то что получал я.
второй вариант посути верен, опятьже если не переполнить int64
сделал вывод что считать разумнее сразу приводя исходные данные к double. пусть незначительно страдает точность расчета, зато отпадают возможные косяки с переполнениями
да там инты.
с двордом ваще бред получилса ибо отрицательная координата z часто принимающая в игре минусовые значения как дворд оказывалась 234334345 типа того)
ну вот как я щас написал считает все без нареканий и глюков
Добавлено через 6 минут
первый вариант это то что получал я.
второй вариант посути верен, опятьже если не переполнить int64
сделал вывод что считать разумнее сразу приводя исходные данные к double. пусть незначительно страдает точность расчета, зато отпадают возможные косяки с переполнениями
переполнить double больше шансов, чем переполнить int64)))
переполнить double больше шансов, чем переполнить int64)))
удачи всунуть в int64 значение MAXDOUBLE = 10^307
как определоно в делфи
MaxDouble = 1.7e+308;
точно, точно) чушь сморозил)
vBulletin® v3.6.11, Copyright ©2000-2025, Jelsoft Enterprises Ltd. Перевод: zCarot