From 8f144da03a9021e1b52704a7a7e05d20eaa847b7 Mon Sep 17 00:00:00 2001 From: MobiusDev <8391001+MobiusDevelopment@users.noreply.github.com> Date: Wed, 9 May 2018 17:53:53 +0000 Subject: [PATCH] Fixes for several broadcasting position related problems. --- .../gameserver/model/actor/L2Character.java | 26 ++----- .../model/actor/instance/L2PcInstance.java | 41 +++++++++--- .../clientpackets/ValidatePosition.java | 6 +- .../gameserver/model/actor/L2Character.java | 26 ++----- .../model/actor/instance/L2PcInstance.java | 41 +++++++++--- .../clientpackets/ValidatePosition.java | 6 +- .../gameserver/model/actor/L2Character.java | 26 ++----- .../model/actor/instance/L2PcInstance.java | 41 +++++++++--- .../clientpackets/ValidatePosition.java | 6 +- .../gameserver/model/actor/L2Character.java | 26 ++----- .../model/actor/instance/L2PcInstance.java | 41 +++++++++--- .../clientpackets/ValidatePosition.java | 6 +- .../admincommandhandlers/AdminRideWyvern.java | 13 +--- .../handler/usercommandhandlers/DisMount.java | 15 +---- .../handler/usercommandhandlers/Mount.java | 26 +------ .../gameserver/model/actor/L2Character.java | 27 +------- .../model/actor/instance/L2PcInstance.java | 67 ++++++++++++------- .../clientpackets/RequestActionUse.java | 16 +---- .../clientpackets/ValidatePosition.java | 6 +- .../dist/game/config/General.ini | 2 +- .../gameserver/model/actor/L2Character.java | 28 ++------ .../model/actor/instance/L2PcInstance.java | 44 +++++++++--- .../clientpackets/ValidatePosition.java | 10 ++- .../gameserver/model/actor/L2Character.java | 26 ++----- .../model/actor/instance/L2PcInstance.java | 41 +++++++++--- .../clientpackets/ValidatePosition.java | 6 +- .../gameserver/model/actor/L2Character.java | 26 ++----- .../model/actor/instance/L2PcInstance.java | 41 +++++++++--- .../clientpackets/ValidatePosition.java | 6 +- 29 files changed, 351 insertions(+), 341 deletions(-) diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 5fbd1415da..6e08eb8525 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index e173b6255a..bf8657f2d9 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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(); diff --git a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 622d6d2d7f..59ef5de5ea 100644 --- a/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_1.0_Ertheia/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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; diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 5fbd1415da..6e08eb8525 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 396d399daa..cb20a0a732 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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(); diff --git a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 622d6d2d7f..59ef5de5ea 100644 --- a/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_2.5_Underground/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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; diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 5fbd1415da..6e08eb8525 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 22241985b4..35ece6ed34 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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(); diff --git a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 622d6d2d7f..59ef5de5ea 100644 --- a/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_3.0_Helios/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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; diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 5fbd1415da..6e08eb8525 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 7dbb262b44..f33d62db17 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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(); diff --git a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 622d6d2d7f..59ef5de5ea 100644 --- a/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_4.0_GrandCrusade/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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; diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/admincommandhandlers/AdminRideWyvern.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/admincommandhandlers/AdminRideWyvern.java index 64afe980e5..d074b8df73 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/admincommandhandlers/AdminRideWyvern.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/admincommandhandlers/AdminRideWyvern.java @@ -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; } diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/DisMount.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/DisMount.java index b98de9e1a6..110556e9f5 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/DisMount.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/DisMount.java @@ -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; diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/Mount.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/Mount.java index 8b95bf5ab6..f3ac12aad7 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/Mount.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/handler/usercommandhandlers/Mount.java @@ -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; diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 60d09097ee..fdb1b36b34 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 8ca5160eb4..eb9a4c5874 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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; diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/RequestActionUse.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/RequestActionUse.java index 8152126bdc..76529c5278 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/RequestActionUse.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/RequestActionUse.java @@ -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; } diff --git a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 1f9b1c0620..247b9608d7 100644 --- a/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_C6_Interlude/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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; diff --git a/L2J_Mobius_CT_2.6_HighFive/dist/game/config/General.ini b/L2J_Mobius_CT_2.6_HighFive/dist/game/config/General.ini index 098ddc1213..1aa3308bfd 100644 --- a/L2J_Mobius_CT_2.6_HighFive/dist/game/config/General.ini +++ b/L2J_Mobius_CT_2.6_HighFive/dist/game/config/General.ini @@ -287,7 +287,7 @@ GridNeighborTurnOffTime = 90 # Allow characters to receive damage from falling. # CoordSynchronize = 2 is recommended. # Default: True -EnableFallingDamage = False +EnableFallingDamage = True # --------------------------------------------------------------------------- diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java index efe7e81904..c973becf8a 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index 74be58efa0..875dedd4bc 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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(); diff --git a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index a147723d90..43c3b66f4a 100644 --- a/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_CT_2.6_HighFive/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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; diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 5fbd1415da..6e08eb8525 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index ce0b6805a1..44e74aa60f 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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(); diff --git a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 622d6d2d7f..59ef5de5ea 100644 --- a/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_Classic_2.0_Saviors/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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; diff --git a/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java b/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java index 5fbd1415da..6e08eb8525 100644 --- a/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java +++ b/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/L2Character.java @@ -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; } diff --git a/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java b/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java index b80a6567c4..382af44204 100644 --- a/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java +++ b/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/model/actor/instance/L2PcInstance.java @@ -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(); diff --git a/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 622d6d2d7f..59ef5de5ea 100644 --- a/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_Classic_2.0_Zaken/java/com/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -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;