/**
* <b>Описание:</b><br>
* Этот класс содержит в себе пакет данных, предназначенный для отправки клиенту, который содержит данные об измененном
* статусе ожидания персонажа.
*/
public class ChangeWaitType extends Send {
private final int id; // Уникальный идентификатор персонажа.
private final WaitType waitType; // Тип ожидания персонажа.
private final int x, y, z; // Координаты местоположения персонажа.
/**
* <b>Описание:</b><br>
* Конструктор для создания нового экземпляра класса.
* @param character Объект персонажа.
* @param waitType Тип ожидания персонажа.
*/
public ChangeWaitType(Character character, WaitType waitType) {
this.id = character.getId();
this.waitType = waitType;
final LocationObject locationObject = character.getLocationObject();
this.x = locationObject.getX();
this.y = locationObject.getY();
this.z = locationObject.getZ();
write(); // Выполняет расчет размера пакета данных.
}
/**
* <b>Описание:</b><br>
* Оболочка, в которой формируется пакет данных для отправки клиенту.
*/
@Override
public void write() {
writeByte(0x29); // Префикс пакета данных.
writeInt(id); // Уникальный идентификатор персонажа.
writeInt(waitType.ordinal()); // Тип ожидания персонажа.
writeInt(x); // Координата по оси X местоположения персонажа.
writeInt(y); // Координата по оси Y местоположения персонажа.
writeInt(z); // Координата по оси Z местоположения персонажа.
}
}
// Координаты текущие, правильные.
-79788
248343
-3629
// После того, как жму сесть: (То есть присылает пакет левый, как я и писал и как меняет координату Y и Z)
-> [Система] Код - 219.
-79788
218352151
-3724
// Потом жму встать:
-79788
251906583
-3724
// Потом снова сесть:
-> [Система] Код - 243.
-79788
-1073493481
-3783
Ну и потом персонаж вообще перестает реагировать.
/**
* <b>Описание:</b><br>
* Оболочка в которой формируется пакет данных для отправки.
*/
@Override
public void write() {
writeByte(0x32); // Префикс пакета данных.
writeInt(location[0]); // Координата X персонажа.
writeInt(location[1]); // Координата Y персонажа.
writeInt(location[2]); // Координата Z персонажа.
writeInt(0x00); // Идентификатор корабля (не используем).
writeInt(objectId); // Уникальный идентификатор объекта в мире.
writeString(name); // Имя персонажа.
writeInt(raceId); // Идентификатор расы персонажа.
writeInt(sexId); // Идентификатор пола персонажа.
writeInt(classId); // Идентификатор класса персонажа.
writeInt(level); // Уровень персонажа.
writeLong(exp); // Количество очков опыта персонажа.
writeInt(cStr); // Сила персонажа.
writeInt(cDex); // Ловкость персонажа.
writeInt(cCon); // Выносливость персонажа.
writeInt(cInt); // Интеллект персонажа.
writeInt(cWit); // Мудрость персонажа.
writeInt(cMen); // Дух персонажа.
writeInt(maxHp); // Максимальное количество жизненных сил.
writeInt(curHp); // Текущее количество жизненных сил.
writeInt(maxMp); // Максимальное количество магических сил.
writeInt(curMp); // Текущее количество магических сил.
writeInt(sp); // Количество очков навыков.
writeInt(curWeight); // Текущий вес всех предметов в инвентаре.
writeInt(maxWeight); // Максимальная грузоподъемность.
writeInt(activeWeapon); // Идентификатор активного оружия.
// Экипировка персонажа - Идентификатор предмета в мире.
for (final int[] equip : equip) {
writeInt(equip[0]);
}
// Экипировка персонажа - Идентификатор предмета в клиенте.
for (final int[] equip : equip) {
writeInt(equip[1]);
}
// Экипировка персонажа - Идентификатор аргументации предмета (Не используем).
for (final int[] _ : equip) {
writeInt(0x00);
}
writeInt(maxTalismans); // Максимальное количество талисманов.
writeInt(slotCloak); // Слот для плаща (открыт/закрыт).
writeInt(pAtk); // Физическая атака.
writeInt(pAtkSpd); // Скорость физической атаки.
writeInt(pDef); // Физическая защита.
writeInt(evasion); // Шанс уклонения.
writeInt(accuracy); // Точность.
writeInt(rCrit); // Шанс критической атаки.
writeInt(mAtk); // Магическая атака.
writeInt(mAtkSpd); // Скорость магической атаки.
writeInt(pAtkSpd); // Скорость физической атаки.
writeInt(mDef); // Магическая защита.
writeInt(0x00); // PVP флаг (Не используем).
writeInt(0x00); // Карма (Не используем).
writeInt(speedRun); // Скорость бега.
writeInt(speedWalk); // Скорость ходьбы.
writeInt(speedSwim); // Скорость плавания (бег).
writeInt(speedSwim); // Скорость плавания (ходьба).
writeInt(speedRunRide); // Скорость бега верхом.
writeInt(speedWalkRide); // Скорость ходьбы верхом.
writeInt(speedRunFly); // Скорость полета.
writeInt(speedWalkFly); // Скорость полета при ходьбе.
writeDouble(speedMultiplier); // Множитель скорости передвижения.
writeDouble(speedAtkMultiplier); // Множитель скорости атаки.
writeDouble(radius); // Радиус персонажа.
writeDouble(height); // Высота персонажа.
writeInt(hairStyleId); // Идентификатор прически.
writeInt(hairColorId); // Идентификатор цвета волос.
writeInt(faceId); // Идентификатор лица.
writeInt(gm); // Статус администратора.
writeString(title); // Титул персонажа.
writeInt(clanId); // Идентификатор клана.
writeInt(clanCrestId); // Идентификатор герба клана.
writeInt(allyId); // Идентификатор альянса.
writeInt(allyCrestId); // Идентификатор герба альянса.
writeInt(relation); // Отношения персонажа.
writeByte(mountType); // Тип животного, которое использует персонаж.
writeByte(privateStoreType); // Тип приватного магазина.
writeByte(canCrystallize); // Возможность кристаллизации предметов.
writeInt(0x00); // Количество PK (Не используем).
writeInt(kills); // Количество убийств.
writeShort(cubics.size()); // Количество активных кубиков у персонажа.
// Список активных кубиков у персонажа.
for (final Cubic cubic : cubics.values()) {
writeShort(cubic.getId());
}
writeByte(0x00); // PartyRoom (Не используем).
writeInt(abnormalMainEffects); // Основные абнормальные эффекты.
writeByte(moveType); // Тип перемещения.
writeInt(clanPrivileges); // Привилегии в клане.
writeShort(0x00); // Рекомендации (Не используем).
writeShort(0x00); // Рекомендации (Не используем).
writeInt(mountId); // Идентификатор призванного животного.
writeShort(inventorySlot); // Максимальное количество слотов инвентаря.
writeInt(classId); // Идентификатор класса.
writeInt(0x00); // Не используемый параметр.
writeInt(maxCp); // Максимальные боевые силы.
writeInt(curCp); // Текущие боевые силы.
writeByte(enchantEffect); // Эффект зачарования надетого оружия.
writeByte(0x00); // Свечение команды (Синее и красное) (Не используем).
writeInt(clanCrestLargeId); // Идентификатор большого герба клана.
writeByte(noble); // Статус дворянина.
writeByte(clanLeaderAura); // Аура лидера клана.
writeByte(fishing); // Статус рыбалки.
writeInt(fishingLoc[0]); // Координата X места рыбалки.
writeInt(fishingLoc[1]); // Координата Y места рыбалки.
writeInt(fishingLoc[2]); // Координата Z места рыбалки.
writeInt(nameColor); // Цвет имени.
writeByte(run); // Флаг бега.
writeInt(clanRank); // Ранг в клане.
writeInt(clanSubunit); // Подразделение в клане.
writeInt(titleColor); // Цвет титула.
writeInt(0x00); // CursedWeapons (Не используем).
writeInt(0x00); // Идентификатор трансформации (Не используем).
writeShort(element[0]); // Идентификатор типа элемента как основного.
writeShort(element[1]); // Сила атаки основного элемента.
writeShort(element[2]); // Защита от элемента огня.
writeShort(element[3]); // Защита от элемента воды.
writeShort(element[4]); // Защита от элемента ветра.
writeShort(element[5]); // Защита от элемента земли.
writeShort(element[6]); // Защита от элемента святости.
writeShort(element[7]); // Защита от элемента тьмы.
writeInt(agathionId); // Идентификатор агатиона.
writeInt(glory); // Очки славы.
writeInt(0x01); // Разрешение мини карты на HellBound.
writeInt(0x00); // Система Vitality (Не используем).
writeInt(abnormalSpecialEffects); // Специальные абнормальные эффекты.
writeInt(0x00); // Идентификатор территории, где происходит осада, в которой участвует персонаж.
writeInt(0x00); // Статус нахождения персонажа на территории, где происходит осада.
writeInt(0x00); // Идентификатор территории, где происходит осада, в которой участвует персонаж, если персонаж находится на территории.
}
x
[тут один лишний байт]
y
z
Да у меня так рассчитывается размер пакета, там все правильно, все остальные пакеты работают без проблем.нужно ли в конструкторе вызвать метод write ?
Поверхность в клиенте ниже реальной поверхности по геодате. Разница от 8 до 32(зависит от типа сектора). Т.е если вы условно кликаете в точку XYZ, то реальная позиция на сервере в этом месте будет выше. При этом, любое движение, проверки видимости, ступеньки и прочее рассчитываются строго по геокоординатам. Геодвиг должен корректно отрабатывать эту разницу, при получении пакета C_MOVE_BACKWARD_TO_LOCATIONСистема такая, есть движок передвижение персонажа, координаты местоположения во время передвижения вычисляются на каждый такт - 50мс. Сразу скажу движок отлаженный и работает в связке с геодатой, координаты возвращает настоящие, без погрешностей. Пакет ValidatePosition использую для хранения координат клиента на сервере как последнюю валидную точку, что-бы корректировать резкие скачки координат при перемещении, баги ловит, провалы мб в текстурах и т.д. Пакет ValidatePosition всегда приходит после отправке клиенту пакета ChangeWaitType, ну так и должно быть, это норма. Только координаты по Y и Z он присылает левые. пример можешь посмотреть в логах я скидывал. Заметил, что координату по Z он кидает ниже точки текстур земли самой игры. Я что и подумал, я кидаю координаты местоположения персонажа по земле, по слою геодаты, а клиент ее уменьшает и присылает мне уменьшенную координату, ну то есть ниже моей точки. Может он присылая мне те координаты персонажа перемещает в те же координаты, он застревает в текстурах и шлет мне все что угодно. Но пробовал играть с координатой Z и выше ставил и ниже, не чего не помогает. Еще заметил такое, когда я жму бежать, персонаж в точку бежит, если в момент бега я нажму сесть, он сядет, потом жму встать и все отлично, дальше жму бежать или другие действия все отлично. Вот только в момент, когда персонаж стоит, и жму сесть такая проблема. В userInfo все хорошо отправляет, Не тут 100% дело в координатах, которые я отправляю в пакете ChangeWaitType и скорее всего теми координатами, которые уже есть в клиенте на момент отправки пакета ChangeWaitType. Вот у вас в сборках при перемещении координата персонажа сохраняется по низу слоя? или + высота модели персонажа или как? Думаю в этом не точность.
Движение не валидирует позицию, а лишь задает направление и длину вектора. Точки, которые вы передаете в клиенте не играют никакой роли. Вы можете слать вообще произвольные цифры, просто задавая вектор и персонаж будет бегать без каких-то проблем. Для решения вопросов с рассинхронизацией(когда координаты в клиенте не совпадают с координатами на сервере), клиент при любом изменении позиции актора, шлет пакет с клиентскими координатами. Исходя из данных, полученных в этом пакете, скрвер принимает решение о необходимости синхронизации. Когда вы садитесь в игре, вы шлете в клиент информацию о том, где вы сели на сервере, а клиент аналогично присылает свои координаты в ответ, чтобы сервер проверил, не нужно ли синхронизироваться.Ну как я знаю, от 8 до 48. Дело в том, что ари передвижении, я то отправляю местоположение персонажа в пакете клиенту и все хорошо, персонаж перемещается без проблем, тогда в чем можеи быть проблема, при действии сесть/встать?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?