Вход

Просмотр полной версии : Телепорт


mira
26.01.2012, 14:16
Народ посоветуйте как разрешить такую проблемку.
Грубый пример (правда нето):
скажем началась драка, поток проги видя потерю сп начинаеть хавать банки. Тут я понимаю что невывоз и жму бсое и лечу 2 мин в лаге (тоеть тут меня уже нет но в городе тоже) прога все эти 2 мин спамит бестолку реквестюзеитем.

как можно отслеживать окончание провала после события телепортлокейшн?

врод как appearing шлет клиент как все переварит. А отвечает ли на него сервер чемто?

supernewbie
26.01.2012, 15:05
по идее ничем кроме данных после телепорта, т.е. нпсинфо, чаринфо, хз что будет если слать appearing самому сразу после телепорта, по логике вещей клиент может прикуеть, так что самое норм - хукать сенд пакет и ждать пока клиент сам отправит apprearing

mira
26.01.2012, 15:44
Хукнут не проблема, но решение мне кажетса уж совсем неизящным. Ловить чаринфо это тоже как "наощупь".

проблема особенно острая в случае:
делает тп кудато свм, затем основа,сд остаетса на месте. В это время падают денс сонг.
Если я в момент тп сразу меняю в бд свою локацию начинает истерично денсить свм считая что я уже рядом. Если жду аперинга то пляшет сд. А посути меня нет не там не тут. Гдежеблять я в это время и как им "сказать" что меня нет.
Добавлять какойнеть флаг char.inaccess если ток чтоб при установлено getdist возвращала скажем 9999.

supernewbie
26.01.2012, 16:21
ну да, на сервере так и делают, там есть переменная isTeleporting

TechnoWiz@rd
04.02.2012, 02:16
mira, можно сделать проще. Перед бафом отсылать пакет Action c ObjectID основы, если основа уже телепортировалась, то получим пакет MyTargetSelected от сервера, если нет то пакет ActionFail.

mira
04.02.2012, 11:58
с таргетными скилами итак сначало выбирают цель (если выбралась то бафают).

но вопервых брать в таргет перед любыми скилами это лишняя потеря времени, скажем пвп.

во вторых сопартиец выделитса в пати даже если он на другом конце карты (чтоб работал суммон френд канечноже)

TechnoWiz@rd
04.02.2012, 14:18
mira, а если попробовать отслеживать пакеты ObjectDelete и CharInfo. Если ловим на сапе ObjectDelete с ID основы, запрещаем баф. Когда ловим CharInfo, опять-же с ID основы, то значит основа появилась в зоне видимости сапа и баф разрешаем. Точное расстояние между чарами можно получить через уравнение длинны вектора:

Sqrt( (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 );

mira
06.02.2012, 10:00
Я так и щитаю) но там иногда получаетса отрицательное число которое под корнем вызывает исключение ариф. Процессора если считать "в лоб".

supernewbie
06.02.2012, 21:48
mira, как у тебя после возведения в квадрат получается отрицательное число?)

Aries
06.02.2012, 23:58
mira, как у тебя после возведения в квадрат получается отрицательное число?)

я хотел спросить то же самое, но все-таки воздержался))))

mira
07.02.2012, 02:18
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 получается?
пробывал проверять что приходит в функцию вообще?

SeregaZ
07.02.2012, 07:33
а само значение, пусть даже меньше нуля - правильное? если правильное, то можно помножить на (-1)
иф q < 0 то
q*(-1)

mira
07.02.2012, 09:57
mira, точно уверен что < 0 получается?
пробывал проверять что приходит в функцию вообще?

проверял. Норм все в функцию приходит.
Я функцию выносил в тестовый апликейшн и при больших цифрах возникала ошибка ариф.процессора типа отрицательное число под корнем. Проверил степ-степ отладкой так и оказалось. Хз в чем дело, мб какоето переполнение.

supernewbie
07.02.2012, 10:01
Норм все в функцию приходит.
а как именно ты это узнал?

mira
07.02.2012, 10:02
fx:=(v1.x-v2.x)*(v1.x-v2.x);



вот если делфи видит это как

fx:=integer((v1.x-v2.x)*(v1.x-v2.x));

тогда в принципе все обьяснимо

Aries
07.02.2012, 13:25
вот если делфи видит это как

fx:=integer((v1.x-v2.x)*(v1.x-v2.x));

тогда в принципе все обьяснимо

очень сомневаюсь...
и кстати замени double на int64 (мб и на LongInt, хотя туда вряд ли влезет квадрат слишком отдаленных координат), один хрен координаты не имеют десятичных точек.

mira
07.02.2012, 13:39
а как именно ты это узнал?

да просто.
Как тока у меня вышла наепка я сразуже запомнил координаты персов м/у которыми считалось.
Потом засунул их в тестовую прогу с копией функции - баг повторилса.
да. Растояние был довольно большое

Aries
07.02.2012, 18:16
Выложи сюда эти координаты ради интереса.

mira
07.02.2012, 19:01
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-ы тока в пакетном уровне

Aries
07.02.2012, 19:55
не понимаю зачем корейцам 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)); - вот так скорее всего заработает верно. По крайней мере на плюсах аналогичный пример стал считать правильно

mira
07.02.2012, 21:19
угу проверил это подтвердилось. а так не сильно заморачивалса этой багой.
у меня растояния больше 3к боты считали что цель слишком далеко чтоб уделять ей внимание поэтому хватало кастыля. щас разобрались исправил)

за тем и нужны DOUBLE чтоб производить подобные расчеты, плюс любой графический движок работает только с floating point числами

TechnoWiz@rd
08.02.2012, 12:07
Я так и щитаю) но там иногда получаетса отрицательное число которое под корнем вызывает исключение ариф. Процессора если считать "в лоб".

По модулю возьми вектор, тогда не будет выскакивать исключений.

mira
08.02.2012, 15:00
Так и было в виде костыля.
Щас разбил выражение все стало верно.

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

mira
08.02.2012, 17:52
да там инты.
с двордом ваще бред получилса ибо отрицательная координата 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. пусть незначительно страдает точность расчета, зато отпадают возможные косяки с переполнениями

Aries
08.02.2012, 18:39
да там инты.
с двордом ваще бред получилса ибо отрицательная координата z часто принимающая в игре минусовые значения как дворд оказывалась 234334345 типа того)

ну вот как я щас написал считает все без нареканий и глюков

Добавлено через 6 минут


первый вариант это то что получал я.
второй вариант посути верен, опятьже если не переполнить int64

сделал вывод что считать разумнее сразу приводя исходные данные к double. пусть незначительно страдает точность расчета, зато отпадают возможные косяки с переполнениями

переполнить double больше шансов, чем переполнить int64)))

mira
08.02.2012, 18:45
переполнить double больше шансов, чем переполнить int64)))
удачи всунуть в int64 значение MAXDOUBLE = 10^307

как определоно в делфи

MaxDouble = 1.7e+308;

Aries
08.02.2012, 20:13
точно, точно) чушь сморозил)