diff --git a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/World.java b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/World.java index 8a1e71fcf0..db4e362d37 100644 --- a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/World.java +++ b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/World.java @@ -30,6 +30,16 @@ import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; public class World { + public static final int TILE_SIZE = 32768; + public static final int TILE_X_MIN = 11; + public static final int TILE_Y_MIN = 10; + // public static final int TILE_X_MAX = 26; + // public static final int TILE_Y_MAX = 26; + public static final int TILE_ZERO_COORD_X = 20; + public static final int TILE_ZERO_COORD_Y = 18; + public static final int MAP_MIN_X = (TILE_X_MIN - TILE_ZERO_COORD_X) * TILE_SIZE; + public static final int MAP_MIN_Y = (TILE_Y_MIN - TILE_ZERO_COORD_Y) * TILE_SIZE; + private final Map _allPlayers = new ConcurrentHashMap<>(); private final Map _allObjects = new ConcurrentHashMap<>(); private final Map _visibleObjects = new ConcurrentHashMap<>(); diff --git a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java index 0982a02e63..a7ae5327d5 100644 --- a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java +++ b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java @@ -135,6 +135,7 @@ public class PlayerInstance extends Creature private long _uptime; public byte updateKnownCounter = 0; private Creature _interactTarget; + private static Timer _waterTimer = null; public Skill addSkill(Skill newSkill) { @@ -871,6 +872,11 @@ public class PlayerInstance extends Creature @Override public void reduceCurrentHp(int amount, Creature attacker) + { + reduceCurrentHp(amount, attacker, true); + } + + public void reduceCurrentHp(int amount, Creature attacker, boolean sendMessage) { if (isInvul()) { @@ -889,24 +895,31 @@ public class PlayerInstance extends Creature } // Damage message. - final SystemMessage smsg = new SystemMessage(SystemMessage.S1_GAVE_YOU_S2_DMG); - if ((attacker instanceof MonsterInstance) || (attacker instanceof NpcInstance)) + if (sendMessage) { - final int mobId = ((NpcInstance) attacker).getNpcTemplate().getNpcId(); - smsg.addNpcName(mobId); + final SystemMessage msg = new SystemMessage(SystemMessage.S1_GAVE_YOU_S2_DMG); + if ((attacker instanceof MonsterInstance) || (attacker instanceof NpcInstance)) + { + final int mobId = ((NpcInstance) attacker).getNpcTemplate().getNpcId(); + msg.addNpcName(mobId); + } + else + { + msg.addString(attacker.getName()); + } + msg.addNumber(amount); + sendPacket(msg); } - else - { - smsg.addString(attacker.getName()); - } - smsg.addNumber(amount); - sendPacket(smsg); + // Dead check. if (!isDead()) { return; } + // Stop water task. + stopWaterTask(); + // Calculate Karma lost. if (getKarma() > 0) { @@ -921,12 +934,17 @@ public class PlayerInstance extends Creature getInventory().dropItem(item, 1); } } - decreaseKarma(); + + // Not self inflicted damage. + if (attacker != this) + { + decreaseKarma(); + } } // Died from player. final PlayerInstance killer = attacker.getActingPlayer(); - if (killer != null) + if ((killer != null) && (killer != this)) { if (_pvpFlag > 0) { @@ -936,7 +954,6 @@ public class PlayerInstance extends Creature else if (_karma == 0) { killer.increasePkKillsAndKarma(getLevel()); - killer.sendPacket(new UserInfo(killer)); } } } @@ -1806,6 +1823,95 @@ public class PlayerInstance extends Creature } } + public void checkWaterState() + { + // Water level. + if (getZ() < -3779) // TODO: Water zones. + { + // Banned "underwater" map regions. + final int regionX = ((getX() - World.MAP_MIN_X) >> 15) + World.TILE_X_MIN; + final int regionY = ((getY() - World.MAP_MIN_Y) >> 15) + World.TILE_Y_MIN; + // TODO: Check for more? + if (((regionX == 18) && (regionY == 19)) // School of Dark Arts + || ((regionX == 18) && (regionY == 23)) // Forgotten Temple + || ((regionX == 19) && (regionY == 23)) // Ant Nest + || ((regionX == 20) && (regionY == 18)) // Dark Elf Village + || ((regionX == 20) && (regionY == 21)) // Cruma Tower + || ((regionX == 21) && (regionY == 18)) // Sea of Spores + || ((regionX == 22) && (regionY == 18)) // Ivory Tower + || ((regionX == 24) && (regionY == 21)) // Lair of Antharas + || ((regionX == 25) && (regionY == 12)) // Mithril Mines + || ((regionX == 25) && (regionY == 19)) // Giant's Cave + || ((regionX == 25) && (regionY == 21)) // Antharas Nest + ) + { + return; + } + + startWaterTask(); + } + else + { + stopWaterTask(); + } + } + + public boolean isInWater() + { + return _waterTimer != null; + } + + private void startWaterTask() + { + if ((_waterTimer == null) && !isDead()) + { + _waterTimer = new Timer(); + _waterTimer.schedule(new waterTask(this), 86000, 1000); + sendPacket(new SetupGauge(SetupGauge.CYAN, 86000)); + } + } + + private void stopWaterTask() + { + if (_waterTimer != null) + { + _waterTimer.cancel(); + _waterTimer = null; + sendPacket(new SetupGauge(SetupGauge.CYAN, 0)); + } + } + + class waterTask extends TimerTask + { + private final PlayerInstance _player; + + public waterTask(PlayerInstance player) + { + _player = player; + } + + @Override + public void run() + { + try + { + int reduceHp = (int) (getMaxHp() / 100.0); + if (reduceHp < 1) + { + reduceHp = 1; + } + + reduceCurrentHp(reduceHp, _player, false); + final SystemMessage sm = new SystemMessage(SystemMessage.DROWN_DAMAGE_S1); + sm.addNumber(reduceHp); + sendPacket(sm); + } + catch (Throwable e) + { + } + } + } + @Override public PlayerInstance getActingPlayer() { diff --git a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java index 199830db73..552a63a99b 100644 --- a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java +++ b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/EnterWorld.java @@ -20,6 +20,7 @@ package org.l2jmobius.gameserver.network.clientpackets; import java.io.IOException; import org.l2jmobius.gameserver.Announcements; +import org.l2jmobius.gameserver.data.MapRegionTable; import org.l2jmobius.gameserver.managers.GmListManager; import org.l2jmobius.gameserver.model.Clan; import org.l2jmobius.gameserver.model.ShortCut; @@ -31,6 +32,7 @@ import org.l2jmobius.gameserver.network.serverpackets.Die; import org.l2jmobius.gameserver.network.serverpackets.ItemList; import org.l2jmobius.gameserver.network.serverpackets.ShortCutInit; import org.l2jmobius.gameserver.network.serverpackets.SystemMessage; +import org.l2jmobius.gameserver.network.serverpackets.TeleportToLocation; import org.l2jmobius.gameserver.network.serverpackets.UserInfo; public class EnterWorld extends ClientBasePacket @@ -91,6 +93,29 @@ public class EnterWorld extends ClientBasePacket } World.getInstance().addVisibleObject(activeChar); notifyClanMembers(activeChar); + + // Fallen in game graphics? + if (activeChar.getZ() < -16000) + { + final int[] townCords = MapRegionTable.getInstance().getClosestTownCords(activeChar); + activeChar.sendPacket(new TeleportToLocation(activeChar, townCords[0], townCords[1], townCords[2])); + World.getInstance().removeVisibleObject(activeChar); + activeChar.removeAllKnownObjects(); + activeChar.setX(townCords[0]); + activeChar.setY(townCords[1]); + activeChar.setZ(townCords[2]); + try + { + Thread.sleep(2000L); + } + catch (InterruptedException e) + { + } + World.getInstance().addVisibleObject(activeChar); + } + + // Water check. + activeChar.checkWaterState(); } private void notifyClanMembers(PlayerInstance activeChar) diff --git a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/Logout.java b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/Logout.java index 38e6c86a72..bee703197f 100644 --- a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/Logout.java +++ b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/Logout.java @@ -41,6 +41,13 @@ public class Logout extends ClientBasePacket player.sendPacket(new ActionFailed()); return; } + if (player.isInWater() && (player.getZ() > -16000)) + { + player.sendMessage("You cannot exit the game under water."); + player.sendPacket(new ActionFailed()); + return; + } + final LeaveWorld ql = new LeaveWorld(); client.getConnection().sendPacket(ql); player.deleteMe(); diff --git a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/MoveBackwardToLocation.java b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/MoveBackwardToLocation.java index 88f772c529..c0b928134e 100644 --- a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/MoveBackwardToLocation.java +++ b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/MoveBackwardToLocation.java @@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.network.clientpackets; import org.l2jmobius.gameserver.enums.CreatureState; +import org.l2jmobius.gameserver.model.World; import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance; import org.l2jmobius.gameserver.network.ClientThread; import org.l2jmobius.gameserver.network.serverpackets.ActionFailed; @@ -49,12 +50,20 @@ public class MoveBackwardToLocation extends ClientBasePacket activeChar.sendPacket(ac); activeChar.broadcastPacket(ac); } + activeChar.setInCombat(false); activeChar.setCurrentState(CreatureState.IDLE); activeChar.setX(originX); activeChar.setY(originY); activeChar.setZ(originZ); activeChar.moveTo(targetX, targetY, targetZ, 0); + + final int x = ((activeChar.getX() - World.MAP_MIN_X) >> 15) + World.TILE_X_MIN; + final int y = ((activeChar.getY() - World.MAP_MIN_Y) >> 15) + World.TILE_Y_MIN; + System.out.println(x + " " + y); + + // Water check. + activeChar.checkWaterState(); } } diff --git a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestart.java b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestart.java index 323b1a235e..2ec137a71c 100644 --- a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestart.java +++ b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/RequestRestart.java @@ -1,5 +1,5 @@ /* - * This file is part of the L2J Mobius project. +lo * This file is part of the L2J Mobius project. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +42,13 @@ public class RequestRestart extends ClientBasePacket player.sendPacket(new ActionFailed()); return; } + if (player.isInWater() && (player.getZ() > -16000)) + { + player.sendMessage("You cannot exit the game under water."); + player.sendPacket(new ActionFailed()); + return; + } + player.deleteMe(); final RestartResponse response = new RestartResponse(); client.getConnection().sendPacket(response); diff --git a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java index 17e45526b2..e008528da4 100644 --- a/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java +++ b/L2J_Mobius_C1_HarbingersOfWar/java/org/l2jmobius/gameserver/network/clientpackets/ValidatePosition.java @@ -92,6 +92,9 @@ public class ValidatePosition extends ClientBasePacket } activeChar.updateKnownCounter = 0; } + + // Water check. + activeChar.checkWaterState(); } }