Fixes for several broadcasting position related problems.

This commit is contained in:
MobiusDev 2018-05-09 17:53:53 +00:00
parent 74a1ffdf73
commit 8f144da03a
29 changed files with 351 additions and 341 deletions

View File

@ -2921,27 +2921,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
dy = m._yDestination - m._yAccurate;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0) // once a second to reduce possible cpu load
&& GeoEngine.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoEngine.getInstance().getHeight(xPrev, yPrev, zPrev);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if (isPlayer() && (Math.abs(getActingPlayer().getClientZ() - geoHeight) > 200) && (Math.abs(getActingPlayer().getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000)) // allow mob to climb up to pcinstance
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
double delta = (dx * dx) + (dy * dy);
if ((delta < 10000) && ((dz * dz) > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
@ -3515,8 +3498,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final MoveToLocation msg = new MoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new MoveToLocation(this));
return true;
}

View File

@ -502,6 +502,8 @@ public final class L2PcInstance extends L2Playable
private int _mountLevel;
/** Store object used to summon the strider you are mounting **/
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
private AdminTeleportType _teleportType = AdminTeleportType.NORMAL;
@ -762,9 +764,11 @@ public final class L2PcInstance extends L2Playable
private int _clientZ;
private int _clientHeading;
// during fall validations will be disabled for 10 ms.
private static final int FALLING_VALIDATION_DELAY = 10000;
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private volatile long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
private int _multiSocialTarget = 0;
private int _multiSociaAction = 0;
@ -6145,6 +6149,7 @@ public final class L2PcInstance extends L2Playable
clearPetData();
if (wasFlying)
{
_hasDismountedWyvern = true;
removeSkill(CommonSkill.WYVERN_BREATH.getSkill());
}
broadcastPacket(new Ride(this));
@ -6155,6 +6160,11 @@ public final class L2PcInstance extends L2Playable
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
public void setUptime(long time)
{
_uptime = time;
@ -12668,13 +12678,28 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(_fallingDamageSum);
sendPacket(sm);
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
setFalling();

View File

@ -182,7 +182,11 @@ public class ValidatePosition implements IClientIncomingPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;

View File

@ -2921,27 +2921,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
dy = m._yDestination - m._yAccurate;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0) // once a second to reduce possible cpu load
&& GeoEngine.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoEngine.getInstance().getHeight(xPrev, yPrev, zPrev);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if (isPlayer() && (Math.abs(getActingPlayer().getClientZ() - geoHeight) > 200) && (Math.abs(getActingPlayer().getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000)) // allow mob to climb up to pcinstance
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
double delta = (dx * dx) + (dy * dy);
if ((delta < 10000) && ((dz * dz) > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
@ -3515,8 +3498,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final MoveToLocation msg = new MoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new MoveToLocation(this));
return true;
}

View File

@ -504,6 +504,8 @@ public final class L2PcInstance extends L2Playable
private int _mountLevel;
/** Store object used to summon the strider you are mounting **/
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
private AdminTeleportType _teleportType = AdminTeleportType.NORMAL;
@ -764,9 +766,11 @@ public final class L2PcInstance extends L2Playable
private int _clientZ;
private int _clientHeading;
// during fall validations will be disabled for 10 ms.
private static final int FALLING_VALIDATION_DELAY = 10000;
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private volatile long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
private int _multiSocialTarget = 0;
private int _multiSociaAction = 0;
@ -6151,6 +6155,7 @@ public final class L2PcInstance extends L2Playable
clearPetData();
if (wasFlying)
{
_hasDismountedWyvern = true;
removeSkill(CommonSkill.WYVERN_BREATH.getSkill());
}
broadcastPacket(new Ride(this));
@ -6161,6 +6166,11 @@ public final class L2PcInstance extends L2Playable
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
public void setUptime(long time)
{
_uptime = time;
@ -12675,13 +12685,28 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(_fallingDamageSum);
sendPacket(sm);
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
setFalling();

View File

@ -182,7 +182,11 @@ public class ValidatePosition implements IClientIncomingPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;

View File

@ -2921,27 +2921,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
dy = m._yDestination - m._yAccurate;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0) // once a second to reduce possible cpu load
&& GeoEngine.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoEngine.getInstance().getHeight(xPrev, yPrev, zPrev);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if (isPlayer() && (Math.abs(getActingPlayer().getClientZ() - geoHeight) > 200) && (Math.abs(getActingPlayer().getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000)) // allow mob to climb up to pcinstance
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
double delta = (dx * dx) + (dy * dy);
if ((delta < 10000) && ((dz * dz) > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
@ -3515,8 +3498,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final MoveToLocation msg = new MoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new MoveToLocation(this));
return true;
}

View File

@ -506,6 +506,8 @@ public final class L2PcInstance extends L2Playable
private int _mountLevel;
/** Store object used to summon the strider you are mounting **/
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
private AdminTeleportType _teleportType = AdminTeleportType.NORMAL;
@ -766,9 +768,11 @@ public final class L2PcInstance extends L2Playable
private int _clientZ;
private int _clientHeading;
// during fall validations will be disabled for 10 ms.
private static final int FALLING_VALIDATION_DELAY = 10000;
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private volatile long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
private int _multiSocialTarget = 0;
private int _multiSociaAction = 0;
@ -6153,6 +6157,7 @@ public final class L2PcInstance extends L2Playable
clearPetData();
if (wasFlying)
{
_hasDismountedWyvern = true;
removeSkill(CommonSkill.WYVERN_BREATH.getSkill());
}
broadcastPacket(new Ride(this));
@ -6163,6 +6168,11 @@ public final class L2PcInstance extends L2Playable
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
public void setUptime(long time)
{
_uptime = time;
@ -12685,13 +12695,28 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(_fallingDamageSum);
sendPacket(sm);
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
setFalling();

View File

@ -182,7 +182,11 @@ public class ValidatePosition implements IClientIncomingPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;

View File

@ -2921,27 +2921,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
dy = m._yDestination - m._yAccurate;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0) // once a second to reduce possible cpu load
&& GeoEngine.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoEngine.getInstance().getHeight(xPrev, yPrev, zPrev);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if (isPlayer() && (Math.abs(getActingPlayer().getClientZ() - geoHeight) > 200) && (Math.abs(getActingPlayer().getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000)) // allow mob to climb up to pcinstance
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
double delta = (dx * dx) + (dy * dy);
if ((delta < 10000) && ((dz * dz) > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
@ -3515,8 +3498,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final MoveToLocation msg = new MoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new MoveToLocation(this));
return true;
}

View File

@ -511,6 +511,8 @@ public final class L2PcInstance extends L2Playable
private int _mountLevel;
/** Store object used to summon the strider you are mounting **/
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
private AdminTeleportType _teleportType = AdminTeleportType.NORMAL;
@ -773,9 +775,11 @@ public final class L2PcInstance extends L2Playable
private int _clientZ;
private int _clientHeading;
// during fall validations will be disabled for 10 ms.
private static final int FALLING_VALIDATION_DELAY = 10000;
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private volatile long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
private int _multiSocialTarget = 0;
private int _multiSociaAction = 0;
@ -6150,6 +6154,7 @@ public final class L2PcInstance extends L2Playable
clearPetData();
if (wasFlying)
{
_hasDismountedWyvern = true;
removeSkill(CommonSkill.WYVERN_BREATH.getSkill());
}
broadcastPacket(new Ride(this));
@ -6160,6 +6165,11 @@ public final class L2PcInstance extends L2Playable
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
public void setUptime(long time)
{
_uptime = time;
@ -12667,13 +12677,28 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(_fallingDamageSum);
sendPacket(sm);
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
setFalling();

View File

@ -182,7 +182,11 @@ public class ValidatePosition implements IClientIncomingPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;

View File

@ -87,18 +87,7 @@ public class AdminRideWyvern implements IAdminCommandHandler
}
else if (command.startsWith("admin_unride"))
{
if (activeChar.isFlying())
{
// Remove skill Wyvern Breath
activeChar.removeSkill(SkillTable.getInstance().getInfo(4289, 1));
activeChar.sendSkillList();
}
if (activeChar.setMountType(0))
{
Ride dismount = new Ride(activeChar.getObjectId(), Ride.ACTION_DISMOUNT, 0);
activeChar.broadcastPacket(dismount);
}
activeChar.dismount();
}
return true;
}

View File

@ -16,11 +16,8 @@
*/
package com.l2jmobius.gameserver.handler.usercommandhandlers;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.handler.IUserCommandHandler;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.serverpackets.Ride;
import com.l2jmobius.gameserver.util.Broadcast;
/**
* Support for /dismount command.
@ -51,17 +48,7 @@ public class DisMount implements IUserCommandHandler
}
else if (activeChar.isMounted())
{
if (activeChar.setMountType(0))
{
if (activeChar.isFlying())
{
activeChar.removeSkill(SkillTable.getInstance().getInfo(4289, 1));
}
Ride dismount = new Ride(activeChar.getObjectId(), Ride.ACTION_DISMOUNT, 0);
Broadcast.toSelfAndKnownPlayersInRadius(activeChar, dismount, 810000/* 900 */);
activeChar.setMountObjectID(0);
}
activeChar.dismount();
}
return true;

View File

@ -16,7 +16,6 @@
*/
package com.l2jmobius.gameserver.handler.usercommandhandlers;
import com.l2jmobius.gameserver.datatables.SkillTable;
import com.l2jmobius.gameserver.geodata.GeoData;
import com.l2jmobius.gameserver.handler.IUserCommandHandler;
import com.l2jmobius.gameserver.model.Inventory;
@ -110,17 +109,7 @@ public class Mount implements IUserCommandHandler
if ((activeChar.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND) != null) || (activeChar.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LRHAND) != null))
{
if (activeChar.setMountType(0))
{
if (activeChar.isFlying())
{
activeChar.removeSkill(SkillTable.getInstance().getInfo(4289, 1));
}
Ride dismount = new Ride(activeChar.getObjectId(), Ride.ACTION_DISMOUNT, 0);
Broadcast.toSelfAndKnownPlayers(activeChar, dismount);
activeChar.setMountObjectID(0);
}
activeChar.dismount();
}
}
}
@ -130,18 +119,7 @@ public class Mount implements IUserCommandHandler
}
else if (activeChar.isMounted())
{
// Dismount
if (activeChar.setMountType(0))
{
if (activeChar.isFlying())
{
activeChar.removeSkill(SkillTable.getInstance().getInfo(4289, 1));
}
Ride dismount = new Ride(activeChar.getObjectId(), Ride.ACTION_DISMOUNT, 0);
Broadcast.toSelfAndKnownPlayers(activeChar, dismount);
activeChar.setMountObjectID(0);
}
activeChar.dismount();
}
return true;

View File

@ -5999,28 +5999,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
dy = m._yDestination - m._yAccurate;
}
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.PATHFINDING > 0) && (Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && !(this instanceof L2BoatInstance) && ((GameTimeController.getGameTicks() % 10) == 0 // once a second to reduce possible cpu load
) && GeoData.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoData.getInstance().getSpawnHeight(xPrev, yPrev, zPrev - 30);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if ((this instanceof L2PcInstance) && (Math.abs(((L2PcInstance) this).getClientZ() - geoHeight) > 200) && (Math.abs(((L2PcInstance) this).getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000))
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
float speed;
if (this instanceof L2BoatInstance)
@ -6682,8 +6662,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final CharMoveToLocation msg = new CharMoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new CharMoveToLocation(this));
return true;
}

View File

@ -541,6 +541,9 @@ public final class L2PcInstance extends L2Playable
/** Store object used to summon the strider you are mounting *. */
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
/** The _telemode. */
public int _telemode = 0;
@ -1050,12 +1053,11 @@ public final class L2PcInstance extends L2Playable
/** The isintwtown. */
private boolean isintwtown = false;
// during fall validations will be disabled for 10 ms.
/** The Constant FALLING_VALIDATION_DELAY. */
private static final int FALLING_VALIDATION_DELAY = 10000;
/** The _falling timestamp. */
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
/** Previous coordinate sent to party in ValidatePosition *. */
private final Point3D _lastPartyPosition = new Point3D(0, 0, 0);
@ -17729,22 +17731,23 @@ public final class L2PcInstance extends L2Playable
*/
public boolean dismount()
{
if (setMountType(0))
final boolean wasFlying = isFlying();
setMountType(0);
if (wasFlying)
{
if (isFlying())
{
removeSkill(SkillTable.getInstance().getInfo(4289, 1));
}
Ride dismount = new Ride(getObjectId(), Ride.ACTION_DISMOUNT, 0);
broadcastPacket(dismount);
setMountObjectID(0);
// Notify self and others about speed change
broadcastUserInfo();
return true;
_hasDismountedWyvern = true;
removeSkill(SkillTable.getInstance().getInfo(4289, 1));
}
return false;
Ride dismount = new Ride(getObjectId(), Ride.ACTION_DISMOUNT, 0);
broadcastPacket(dismount);
setMountObjectID(0);
broadcastUserInfo();
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
/**
@ -18454,15 +18457,27 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if ((damage > 0) && !isInvul())
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), null, false);
sendPacket(new SystemMessage(SystemMessageId.FALL_DAMAGE_S1).addNumber(damage));
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), null, false);
sendPacket(new SystemMessage(SystemMessageId.FALL_DAMAGE_S1).addNumber(_fallingDamageSum));
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
// Mobius: Prevent falling in game graphics.
sendPacket(new ValidateLocation(this));
_fallingTimestamp = System.currentTimeMillis() + FALLING_VALIDATION_DELAY;

View File

@ -365,21 +365,7 @@ public final class RequestActionUse extends L2GameClientPacket
}
else if (activeChar.isMounted())
{
if (activeChar.isFlying())
{
// Remove skill Wyvern Breath
activeChar.removeSkill(SkillTable.getInstance().getInfo(4289, 1));
activeChar.sendSkillList();
}
if (activeChar.setMountType(0))
{
final Ride dismount = new Ride(activeChar.getObjectId(), Ride.ACTION_DISMOUNT, 0);
activeChar.broadcastPacket(dismount);
activeChar.setMountObjectID(0);
// Update status after unmount to avoid visual bug
activeChar.broadcastStatusUpdate();
activeChar.broadcastUserInfo();
}
activeChar.dismount();
}
break;
}

View File

@ -147,7 +147,11 @@ public final class ValidatePosition extends L2GameClientPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;

View File

@ -287,7 +287,7 @@ GridNeighborTurnOffTime = 90
# Allow characters to receive damage from falling.
# CoordSynchronize = 2 is recommended.
# Default: True
EnableFallingDamage = False
EnableFallingDamage = True
# ---------------------------------------------------------------------------

View File

@ -3942,29 +3942,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
dy = m._yDestination - m._yAccurate;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0 // once a second to reduce possible cpu load
) && GeoEngine.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoEngine.getInstance().getHeight(xPrev, yPrev, zPrev);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if (isPlayer() && (Math.abs(getActingPlayer().getClientZ() - geoHeight) > 200) && (Math.abs(getActingPlayer().getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000)) // allow mob to climb up to pcinstance
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
double delta = (dx * dx) + (dy * dy);
if ((delta < 10000) && ((dz * dz) > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
&& !isFloating)
@ -4534,8 +4515,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final MoveToLocation msg = new MoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new MoveToLocation(this));
return true;
}

View File

@ -507,6 +507,8 @@ public final class L2PcInstance extends L2Playable
private int _mountLevel;
/** Store object used to summon the strider you are mounting **/
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
public int _telemode = 0;
@ -791,9 +793,11 @@ public final class L2PcInstance extends L2Playable
private int _clientZ;
private int _clientHeading;
// during fall validations will be disabled for 10 ms.
private static final int FALLING_VALIDATION_DELAY = 10000;
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private volatile long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
private int _multiSocialTarget = 0;
private int _multiSociaAction = 0;
@ -6377,6 +6381,7 @@ public final class L2PcInstance extends L2Playable
stopFeed();
if (wasFlying)
{
_hasDismountedWyvern = true;
removeSkill(CommonSkill.WYVERN_BREATH.getSkill());
}
broadcastPacket(new Ride(this));
@ -6387,6 +6392,11 @@ public final class L2PcInstance extends L2Playable
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
public void setUptime(long time)
{
_uptime = time;
@ -13510,17 +13520,29 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), null, false, true, null);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), null, false, true, null);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(_fallingDamageSum);
sendPacket(sm);
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
// FIXME: Prevent falling in game graphics.
sendPacket(new ValidateLocation(this));
setFalling();

View File

@ -64,8 +64,8 @@ public class ValidatePosition implements IClientIncomingPacket
if (Config.DEVELOPER)
{
LOGGER.fine("client pos: " + _x + " " + _y + " " + _z + " head " + _heading);
LOGGER.fine("server pos: " + realX + " " + realY + " " + realZ + " head " + activeChar.getHeading());
LOGGER.finer("client pos: " + _x + " " + _y + " " + _z + " head " + _heading);
LOGGER.finer("server pos: " + realX + " " + realY + " " + realZ + " head " + activeChar.getHeading());
}
if ((_x == 0) && (_y == 0))
@ -182,7 +182,11 @@ public class ValidatePosition implements IClientIncomingPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;

View File

@ -2921,27 +2921,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
dy = m._yDestination - m._yAccurate;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0) // once a second to reduce possible cpu load
&& GeoEngine.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoEngine.getInstance().getHeight(xPrev, yPrev, zPrev);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if (isPlayer() && (Math.abs(getActingPlayer().getClientZ() - geoHeight) > 200) && (Math.abs(getActingPlayer().getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000)) // allow mob to climb up to pcinstance
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
double delta = (dx * dx) + (dy * dy);
if ((delta < 10000) && ((dz * dz) > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
@ -3515,8 +3498,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final MoveToLocation msg = new MoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new MoveToLocation(this));
return true;
}

View File

@ -501,6 +501,8 @@ public final class L2PcInstance extends L2Playable
private int _mountLevel;
/** Store object used to summon the strider you are mounting **/
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
private AdminTeleportType _teleportType = AdminTeleportType.NORMAL;
@ -760,9 +762,11 @@ public final class L2PcInstance extends L2Playable
private int _clientZ;
private int _clientHeading;
// during fall validations will be disabled for 10 ms.
private static final int FALLING_VALIDATION_DELAY = 10000;
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private volatile long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
private int _multiSocialTarget = 0;
private int _multiSociaAction = 0;
@ -6117,6 +6121,7 @@ public final class L2PcInstance extends L2Playable
clearPetData();
if (wasFlying)
{
_hasDismountedWyvern = true;
removeSkill(CommonSkill.WYVERN_BREATH.getSkill());
}
broadcastPacket(new Ride(this));
@ -6127,6 +6132,11 @@ public final class L2PcInstance extends L2Playable
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
public void setUptime(long time)
{
_uptime = time;
@ -12516,13 +12526,28 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(_fallingDamageSum);
sendPacket(sm);
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
setFalling();

View File

@ -182,7 +182,11 @@ public class ValidatePosition implements IClientIncomingPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;

View File

@ -2921,27 +2921,10 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
dy = m._yDestination - m._yAccurate;
}
// Z coordinate will follow client values
dz = m._zDestination - zPrev;
final boolean isFloating = isFlying() || isInsideZone(ZoneId.WATER);
// Z coordinate will follow geodata or client values
if ((Config.COORD_SYNCHRONIZE == 2) && !isFloating && !m.disregardingGeodata && ((GameTimeController.getInstance().getGameTicks() % 10) == 0) // once a second to reduce possible cpu load
&& GeoEngine.getInstance().hasGeo(xPrev, yPrev))
{
final int geoHeight = GeoEngine.getInstance().getHeight(xPrev, yPrev, zPrev);
dz = m._zDestination - geoHeight;
// quite a big difference, compare to validatePosition packet
if (isPlayer() && (Math.abs(getActingPlayer().getClientZ() - geoHeight) > 200) && (Math.abs(getActingPlayer().getClientZ() - geoHeight) < 1500))
{
dz = m._zDestination - zPrev; // allow diff
}
else if (isInCombat() && (Math.abs(dz) > 200) && (((dx * dx) + (dy * dy)) < 40000)) // allow mob to climb up to pcinstance
{
dz = m._zDestination - zPrev; // climbing
}
}
else
{
dz = m._zDestination - zPrev;
}
double delta = (dx * dx) + (dy * dy);
if ((delta < 10000) && ((dz * dz) > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
@ -3515,8 +3498,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// to destination by GameTimeController
// Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
final MoveToLocation msg = new MoveToLocation(this);
broadcastPacket(msg);
broadcastPacket(new MoveToLocation(this));
return true;
}

View File

@ -501,6 +501,8 @@ public final class L2PcInstance extends L2Playable
private int _mountLevel;
/** Store object used to summon the strider you are mounting **/
private int _mountObjectID = 0;
/** Remember if dismounted from Wyvern **/
private boolean _hasDismountedWyvern = false;
private AdminTeleportType _teleportType = AdminTeleportType.NORMAL;
@ -760,9 +762,11 @@ public final class L2PcInstance extends L2Playable
private int _clientZ;
private int _clientHeading;
// during fall validations will be disabled for 10 ms.
private static final int FALLING_VALIDATION_DELAY = 10000;
// during fall validations will be disabled for 1000 ms.
private static final int FALLING_VALIDATION_DELAY = 1000;
private volatile long _fallingTimestamp = 0;
private volatile int _fallingDamageSum = 0;
private Future<?> _fallingDamageTask = null;
private int _multiSocialTarget = 0;
private int _multiSociaAction = 0;
@ -6117,6 +6121,7 @@ public final class L2PcInstance extends L2Playable
clearPetData();
if (wasFlying)
{
_hasDismountedWyvern = true;
removeSkill(CommonSkill.WYVERN_BREATH.getSkill());
}
broadcastPacket(new Ride(this));
@ -6127,6 +6132,11 @@ public final class L2PcInstance extends L2Playable
return true;
}
public boolean hasDismountedWyvern()
{
return _hasDismountedWyvern;
}
public void setUptime(long time)
{
_uptime = time;
@ -12516,13 +12526,28 @@ public final class L2PcInstance extends L2Playable
return false;
}
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
// TODO: Test on retail. Add or set damage?
_fallingDamageSum += (int) Formulas.calcFallDam(this, deltaZ);
if (_fallingDamageTask != null)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
_fallingDamageTask.cancel(true);
}
_fallingDamageTask = ThreadPool.schedule(() ->
{
if ((_fallingDamageSum > 0) && !isInvul())
{
reduceCurrentHp(Math.min(_fallingDamageSum, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(_fallingDamageSum);
sendPacket(sm);
}
_hasDismountedWyvern = false;
_fallingDamageSum = 0;
_fallingDamageTask = null;
}, 1500);
if (!_hasDismountedWyvern)
{
sendPacket(new ValidateLocation(this));
}
setFalling();

View File

@ -182,7 +182,11 @@ public class ValidatePosition implements IClientIncomingPacket
{
// if ((_z - activeChar.getClientZ()) < 200 && Math.abs(activeChar.getLastServerPosition().getZ()-realZ) > 70)
if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
if (activeChar.hasDismountedWyvern())
{
activeChar.setXYZ(_x, _y, _z);
}
else if ((Math.abs(dz) > 200) && (Math.abs(dz) < 1500) && (Math.abs(_z - activeChar.getClientZ()) < 800))
{
activeChar.setXYZ(realX, realY, _z);
realZ = _z;