Dropped SQL teleport table.

Adapted from: L2jUnity free files.
This commit is contained in:
MobiusDev
2017-11-17 03:46:03 +00:00
parent 7adad0d806
commit 8a82470da0
1100 changed files with 14721 additions and 12839 deletions

View File

@@ -511,6 +511,18 @@ public final class CommonUtil
}
}
public static int parseInt(String value, int defaultValue)
{
try
{
return Integer.parseInt(value);
}
catch (Exception e)
{
return defaultValue;
}
}
/**
* @param str - the string whose first letter to capitalize
* @return a string with the first letter of the {@code str} capitalized

View File

@@ -38,7 +38,6 @@ import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.sql.impl.CrestTable;
import com.l2jmobius.gameserver.data.sql.impl.OfflineTradersTable;
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jmobius.gameserver.data.xml.impl.AbilityPointsData;
import com.l2jmobius.gameserver.data.xml.impl.ActionData;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
@@ -304,7 +303,6 @@ public class GameServer
printSection("Cache");
HtmCache.getInstance();
CrestTable.getInstance();
TeleportLocationTable.getInstance();
TeleportersData.getInstance();
MatchingRoomManager.getInstance();
PetitionManager.getInstance();

View File

@@ -1,123 +0,0 @@
/*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.model.L2TeleportLocation;
public class TeleportLocationTable
{
private static Logger LOGGER = Logger.getLogger(TeleportLocationTable.class.getName());
private final Map<Integer, L2TeleportLocation> _teleports = new HashMap<>();
protected TeleportLocationTable()
{
reloadAll();
}
public void reloadAll()
{
_teleports.clear();
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT id, loc_x, loc_y, loc_z, price, fornoble, itemId FROM teleport"))
{
L2TeleportLocation teleport;
while (rs.next())
{
teleport = new L2TeleportLocation();
teleport.setTeleId(rs.getInt("id"));
teleport.setLocX(rs.getInt("loc_x"));
teleport.setLocY(rs.getInt("loc_y"));
teleport.setLocZ(rs.getInt("loc_z"));
teleport.setPrice(rs.getInt("price"));
teleport.setIsForNoble(rs.getInt("fornoble") == 1);
teleport.setItemId(rs.getInt("itemId"));
_teleports.put(teleport.getTeleId(), teleport);
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _teleports.size() + " Teleport Location Templates.");
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error loading Teleport Table.", e);
}
if (Config.CUSTOM_TELEPORT_TABLE)
{
int cTeleCount = _teleports.size();
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT id, loc_x, loc_y, loc_z, price, fornoble, itemId FROM custom_teleport"))
{
L2TeleportLocation teleport;
while (rs.next())
{
teleport = new L2TeleportLocation();
teleport.setTeleId(rs.getInt("id"));
teleport.setLocX(rs.getInt("loc_x"));
teleport.setLocY(rs.getInt("loc_y"));
teleport.setLocZ(rs.getInt("loc_z"));
teleport.setPrice(rs.getInt("price"));
teleport.setIsForNoble(rs.getInt("fornoble") == 1);
teleport.setItemId(rs.getInt("itemId"));
_teleports.put(teleport.getTeleId(), teleport);
}
cTeleCount = _teleports.size() - cTeleCount;
if (cTeleCount > 0)
{
LOGGER.info(getClass().getSimpleName() + ": Loaded " + cTeleCount + " Custom Teleport Location Templates.");
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while creating custom teleport table " + e.getMessage(), e);
}
}
}
/**
* @param id
* @return
*/
public L2TeleportLocation getTemplate(int id)
{
return _teleports.get(id);
}
public static TeleportLocationTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final TeleportLocationTable _instance = new TeleportLocationTable();
}
}

View File

@@ -17,28 +17,28 @@
package com.l2jmobius.gameserver.data.xml.impl;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.enums.TeleportType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.teleporter.TeleportHolder;
import com.l2jmobius.gameserver.model.teleporter.TeleportLocation;
import com.l2jmobius.gameserver.model.teleporter.TeleportType;
/**
* @author UnAfraid
*/
public class TeleportersData implements IGameXmlReader
{
// Logger instance
private static final Logger LOGGER = Logger.getLogger(TeleportersData.class.getName());
private final Map<Integer, TeleportHolder> _teleporters = new HashMap<>();
// Teleporter data
private final Map<Integer, Map<String, TeleportHolder>> _teleporters = new HashMap<>();
protected TeleportersData()
{
@@ -56,66 +56,73 @@ public class TeleportersData implements IGameXmlReader
@Override
public void parseDocument(Document doc, File f)
{
for (Node listNode = doc.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
forEach(doc, "list", (list) ->
{
if ("list".equals(listNode.getNodeName()))
forEach(list, "npc", (npc) ->
{
for (Node npcNode = listNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
final Map<String, TeleportHolder> teleList = new HashMap<>();
// Parse npc node child
final int npcId = parseInteger(npc.getAttributes(), "id");
forEach(npc, (node) ->
{
if ("npc".equals(npcNode.getNodeName()))
switch (node.getNodeName())
{
final int id = parseInteger(npcNode.getAttributes(), "id");
final TeleportHolder holder = new TeleportHolder(id);
for (Node tpNode = npcNode.getFirstChild(); tpNode != null; tpNode = tpNode.getNextSibling())
case "teleport":
{
if ("teleport".equals(tpNode.getNodeName()))
final NamedNodeMap nodeAttrs = node.getAttributes();
// Parse attributes
final TeleportType type = parseEnum(nodeAttrs, TeleportType.class, "type");
final String name = parseString(nodeAttrs, "name", type.name());
// Parse locations
final TeleportHolder holder = new TeleportHolder(name, type);
forEach(node, "location", (location) -> holder.registerLocation(new StatsSet(parseAttributes(location))));
// Register holder
if (teleList.putIfAbsent(name, holder) != null)
{
final TeleportType type = parseEnum(tpNode.getAttributes(), TeleportType.class, "type", TeleportType.NORMAL);
for (Node locNode = tpNode.getFirstChild(); locNode != null; locNode = locNode.getNextSibling())
{
if ("location".equals(locNode.getNodeName()))
{
final NamedNodeMap attrs = locNode.getAttributes();
final int nextId = holder.getLocations(type).size() + 1;
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node locationNode = attrs.item(i);
set.set(locationNode.getNodeName(), locationNode.getNodeValue());
}
holder.addLocation(type, new TeleportLocation(nextId, set));
}
}
}
else if ("npcs".equals(tpNode.getNodeName()))
{
for (Node locNode = tpNode.getFirstChild(); locNode != null; locNode = locNode.getNextSibling())
{
if ("npc".equals(locNode.getNodeName()))
{
final int npcId = parseInteger(locNode.getAttributes(), "id");
if (_teleporters.putIfAbsent(npcId, holder) != null)
{
LOGGER.warning(getClass().getSimpleName() + ": Duplicate location entires for npc: " + npcId);
}
}
}
LOGGER.warning("Duplicate teleport list (" + name + ") has been found for NPC: " + npcId);
}
break;
}
if (_teleporters.putIfAbsent(id, holder) != null)
case "npcs":
{
LOGGER.warning(getClass().getSimpleName() + ": Duplicate location entires for npc: " + id);
forEach(node, "npc", (npcNode) ->
{
final int id = parseInteger(npcNode.getAttributes(), "id");
registerTeleportList(id, teleList);
});
break;
}
}
}
}
}
});
registerTeleportList(npcId, teleList);
});
});
}
public TeleportHolder getHolder(int npcId)
public int getTeleporterCount()
{
return _teleporters.get(npcId);
return _teleporters.size();
}
/**
* Register teleport data to global teleport list holder. Also show warning when any duplicate occurs.
* @param npcId template id of teleporter
* @param teleList teleport data to register
*/
private void registerTeleportList(int npcId, Map<String, TeleportHolder> teleList)
{
_teleporters.put(npcId, teleList);
}
/**
* Gets teleport data for specified NPC and list name
* @param npcId template id of teleporter
* @param listName name of teleport list
* @return {@link TeleportHolder} if found otherwise {@code null}
*/
public TeleportHolder getHolder(int npcId, String listName)
{
return _teleporters.getOrDefault(npcId, Collections.emptyMap()).get(listName);
}
/**

View File

@@ -0,0 +1,54 @@
/*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.enums;
/**
* @author Nik
*/
public enum SpecialItemType
{
PC_CAFE_POINTS(-100),
CLAN_REPUTATION(-200),
FAME(-300),
FIELD_CYCLE_POINTS(-400),
RAIDBOSS_POINTS(-500);
private int _clientId;
private SpecialItemType(int clientId)
{
_clientId = clientId;
}
public int getClientId()
{
return _clientId;
}
public static SpecialItemType getByClientId(int clientId)
{
for (SpecialItemType type : values())
{
if (type.getClientId() == clientId)
{
return type;
}
}
return null;
}
}

View File

@@ -1,28 +1,28 @@
/*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.teleporter;
/**
* @author UnAfraid
*/
public enum TeleportType
{
NORMAL,
NOBLES_TOKEN,
NOBLES_ADENA,
OTHER
}
/*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.enums;
/**
* @author UnAfraid
*/
public enum TeleportType
{
NORMAL,
NOBLES_TOKEN,
NOBLES_ADENA,
OTHER;
}

View File

@@ -18,12 +18,13 @@ package com.l2jmobius.gameserver.model.actor.instance;
import java.util.StringTokenizer;
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
import com.l2jmobius.gameserver.data.xml.impl.TeleportersData;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.model.L2TeleportLocation;
import com.l2jmobius.gameserver.enums.TeleportType;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.teleporter.TeleportHolder;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
@@ -92,7 +93,12 @@ public class L2DoormenInstance extends L2NpcInstance
{
if (isOwnerClan(player))
{
doTeleport(player, command);
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId(), TeleportType.OTHER.name());
if (holder != null)
{
final int locId = Integer.parseInt(command.substring(5).trim());
holder.doTeleport(player, this, locId);
}
}
return;
}
@@ -150,25 +156,6 @@ public class L2DoormenInstance extends L2NpcInstance
player.sendPacket(html);
}
protected void doTeleport(L2PcInstance player, String command)
{
final int whereTo = Integer.parseInt(command.substring(5).trim());
final L2TeleportLocation list = TeleportLocationTable.getInstance().getTemplate(whereTo);
if (list != null)
{
if (!player.isAlikeDead())
{
player.teleToLocation(list.getLocX(), list.getLocY(), list.getLocZ());
}
}
else
{
_log.warning("No teleport destination with id:" + whereTo);
}
player.sendPacket(ActionFailed.STATIC_PACKET);
}
protected boolean isOwnerClan(L2PcInstance player)
{
return true;

View File

@@ -20,15 +20,17 @@ import java.text.SimpleDateFormat;
import java.util.StringTokenizer;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jmobius.commons.util.CommonUtil;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.data.xml.impl.TeleportersData;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.model.ClanPrivilege;
import com.l2jmobius.gameserver.model.L2TeleportLocation;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.effects.L2EffectType;
import com.l2jmobius.gameserver.model.entity.Fort;
import com.l2jmobius.gameserver.model.entity.Fort.FortFunction;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.model.teleporter.TeleportHolder;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.network.serverpackets.WareHouseDepositList;
@@ -938,10 +940,23 @@ public class L2FortManagerInstance extends L2MerchantInstance
sendHtmlMessage(player, html);
return;
}
else if (actualCommand.equalsIgnoreCase("goto"))
else if (actualCommand.equalsIgnoreCase("goto")) // goto listId locId
{
final int whereTo = Integer.parseInt(val);
doTeleport(player, whereTo);
final FortFunction func = getFort().getFortFunction(Fort.FUNC_TELEPORT);
if ((func == null) || !st.hasMoreTokens())
{
return;
}
final int funcLvl = (val.length() >= 4) ? CommonUtil.parseInt(val.substring(3), -1) : -1;
if (func.getLvl() == funcLvl)
{
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId(), val);
if (holder != null)
{
holder.doTeleport(player, this, CommonUtil.parseNextInt(st, -1));
}
}
return;
}
super.onBypassFeedback(player, command);
@@ -974,31 +989,6 @@ public class L2FortManagerInstance extends L2MerchantInstance
player.sendPacket(html);
}
private void doTeleport(L2PcInstance player, int val)
{
if (Config.DEBUG)
{
_log.warning("doTeleport(L2PcInstance player, int val) is called");
}
final L2TeleportLocation list = TeleportLocationTable.getInstance().getTemplate(val);
if (list != null)
{
if (player.destroyItemByItemId("Teleport", list.getItemId(), list.getPrice(), this, true))
{
if (Config.DEBUG)
{
_log.warning("Teleporting player " + player.getName() + " for Fortress to new location: " + list.getLocX() + ":" + list.getLocY() + ":" + list.getLocZ());
}
player.teleToLocation(list.getLocX(), list.getLocY(), list.getLocZ());
}
}
else
{
_log.warning("No teleport destination with id:" + val);
}
player.sendPacket(ActionFailed.STATIC_PACKET);
}
protected int validateCondition(L2PcInstance player)
{
if ((getFort() != null) && (getFort().getResidenceId() > 0))

View File

@@ -16,30 +16,18 @@
*/
package com.l2jmobius.gameserver.model.actor.instance;
import java.util.Calendar;
import java.util.StringTokenizer;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
import com.l2jmobius.gameserver.data.xml.impl.MultisellData;
import com.l2jmobius.gameserver.data.xml.impl.TeleportersData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.enums.TeleportType;
import com.l2jmobius.gameserver.instancemanager.CastleManager;
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
import com.l2jmobius.gameserver.instancemanager.TownManager;
import com.l2jmobius.gameserver.model.L2TeleportLocation;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.skills.CommonSkill;
import com.l2jmobius.gameserver.model.teleporter.TeleportHolder;
import com.l2jmobius.gameserver.model.teleporter.TeleportLocation;
import com.l2jmobius.gameserver.model.teleporter.TeleportType;
import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jmobius.gameserver.util.Util;
@@ -48,10 +36,14 @@ import com.l2jmobius.gameserver.util.Util;
*/
public final class L2TeleporterInstance extends L2Npc
{
private static final int COND_ALL_FALSE = 0;
private static final int COND_BUSY_BECAUSE_OF_SIEGE = 1;
private static final int COND_OWNER = 2;
private static final int COND_REGULAR = 3;
private static final Logger LOGGER = Logger.getLogger(L2TeleporterInstance.class.getName());
private static final CommonSkill[] FORBIDDEN_TRANSFORM =
{
CommonSkill.FROG_TRANSFORM,
CommonSkill.CHILD_TRANSFORM,
CommonSkill.NATIVE_TRANSFORM
};
public L2TeleporterInstance(L2NpcTemplate template)
{
@@ -62,194 +54,83 @@ public final class L2TeleporterInstance extends L2Npc
@Override
public boolean isAutoAttackable(L2Character attacker)
{
if (attacker.isMonster())
{
return true;
}
return super.isAutoAttackable(attacker);
return attacker.isMonster() || super.isAutoAttackable(attacker);
}
@Override
public void onBypassFeedback(L2PcInstance player, String command)
{
// Check if transformed
for (CommonSkill skill : FORBIDDEN_TRANSFORM)
{
if (player.isAffectedBySkill(skill.getId()))
{
sendHtmlMessage(player, "data/html/teleporter/epictransformed.htm");
return;
}
}
// Process bypass
final StringTokenizer st = new StringTokenizer(command, " ");
final String cmd = st.nextToken();
switch (cmd)
switch (st.nextToken())
{
case "showNoblesSelect":
{
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/" + (player.isNoble() ? "nobles_select" : "not_nobles") + ".htm");
msg.replace("%objectId%", getObjectId());
player.sendPacket(msg);
sendHtmlMessage(player, "data/html/teleporter/" + (player.isNoble() ? "nobles_select" : "not_nobles") + ".htm");
break;
}
case "showTeleports":
{
final TeleportType type = parseTeleportType(st);
if (((type == TeleportType.NOBLES_TOKEN) || (type == TeleportType.NOBLES_ADENA)) && !player.isNoble())
{
_log.warning(player + " attempted to use nobles teleport without being nobles!");
break;
}
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId());
final String listName = (st.hasMoreTokens()) ? st.nextToken() : TeleportType.NORMAL.name();
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId(), listName);
if (holder == null)
{
_log.warning(player + " requested show teleports for npc with no teleport data " + toString());
break;
LOGGER.warning("Player " + player.getObjectId() + " requested show teleports for list with name " + listName + " at NPC " + getId() + "!");
return;
}
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/teleports.htm");
final StringBuilder sb = new StringBuilder();
final StringBuilder sb_f = new StringBuilder();
final int questZoneId = player.getQuestZoneId();
for (TeleportLocation loc : holder.getLocations(type))
{
final int id = loc.getId();
final boolean isQuestTeleport = (questZoneId >= 0) && (loc.getQuestZoneId() == questZoneId);
String finalName = loc.getName();
String confirmDesc = loc.getName();
if (loc.getNpcStringId() != null)
{
finalName = "<fstring>" + loc.getNpcStringId().getId() + "</fstring>";
confirmDesc = "F;" + loc.getNpcStringId().getId();
}
if (shouldPayFee(player, type, loc))
{
finalName += " - " + calculateFee(player, type, loc) + " " + getItemName(loc.getFeeId(), true);
}
if (isQuestTeleport)
{
sb_f.append("<button align=left icon=\"quest\" action=\"bypass -h npc_" + getObjectId() + "_teleport " + type.ordinal() + " " + id + "\" msg=\"811;" + confirmDesc + "\">" + finalName + "</button>");
}
else
{
sb.append("<button align=left icon=\"teleport\" action=\"bypass -h npc_" + getObjectId() + "_teleport " + type.ordinal() + " " + id + "\" msg=\"811;" + confirmDesc + "\">" + finalName + "</button>");
}
}
sb_f.append(sb.toString());
msg.replace("%locations%", sb_f.toString());
player.sendPacket(msg);
holder.showTeleportList(player, this);
break;
}
case "teleport":
{
final int typeId = parseNextInt(st, -1);
if ((typeId < 0) || (typeId > TeleportType.values().length))
// Check for required count of params.
if (st.countTokens() != 2)
{
_log.warning(player + " attempted to use incorrect teleport type: " + typeId);
LOGGER.warning("Player " + player.getObjectId() + " send unhandled teleport command: " + command);
return;
}
final TeleportType type = TeleportType.values()[typeId];
if (((type == TeleportType.NOBLES_TOKEN) || (type == TeleportType.NOBLES_ADENA)) && !player.isNoble())
{
_log.warning(player + " attempted to use nobles teleport without being nobles!");
break;
}
final int locId = parseNextInt(st, -1);
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId());
final String listName = st.nextToken();
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId(), listName);
if (holder == null)
{
_log.warning(player + " requested show teleports for npc with no teleport data " + toString());
break;
}
final TeleportLocation loc = holder.getLocation(type, locId);
if (loc == null)
{
_log.warning(player + " attempted to use not existing teleport location id: " + locId);
LOGGER.warning("Player " + player.getObjectId() + " requested unknown teleport list: " + listName + " for npc: " + getId() + "!");
return;
}
// you cannot teleport to village that is in siege
if (SiegeManager.getInstance().getSiege(loc.getX(), loc.getY(), loc.getZ()) != null)
holder.doTeleport(player, this, parseNextInt(st, -1));
break;
}
case "chat":
{
int val = 0;
try
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
val = Integer.parseInt(command.substring(5));
}
else if (TownManager.townHasCastleInSiege(loc.getX(), loc.getY()) && isInsideZone(ZoneId.TOWN))
catch (IndexOutOfBoundsException | NumberFormatException ignored)
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
}
else if (getCastle().getSiege().isInProgress())
{
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/castleteleporter-busy.htm");
player.sendPacket(msg);
}
else if (!Config.ALT_GAME_KARMA_PLAYER_CAN_USE_GK && (player.getReputation() < 0))
{
player.sendMessage("Go away, you're not welcome here.");
}
else if (player.isCombatFlagEquipped())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
}
else if (shouldPayFee(player, type, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), calculateFee(player, type, loc), this, true))
{
if (loc.getFeeId() == Inventory.ADENA_ID)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
}
else
{
player.sendMessage("You do not have enough " + getItemName(loc.getFeeId(), false));
}
}
else if (!player.isAlikeDead())
{
player.teleToLocation(loc);
}
showChatWindow(player, val);
break;
}
default:
{
processLegacyBypass(player, command);
break;
super.onBypassFeedback(player, command);
}
}
}
/**
* For characters below level 77 teleport service is free.<br>
* From 8.00 pm to 00.00 from Monday till Tuesday for all characters there's a 50% discount on teleportation services
* @param player
* @param type
* @param loc
* @return
*/
private long calculateFee(L2PcInstance player, TeleportType type, TeleportLocation loc)
{
if (type == TeleportType.NORMAL)
{
if (!player.isSubClassActive() && (player.getLevel() <= Config.MAX_FREE_TELEPORT_LEVEL))
{
return 0;
}
final Calendar cal = Calendar.getInstance();
final int hour = cal.get(Calendar.HOUR_OF_DAY);
final int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
if ((hour >= 20) && ((dayOfWeek >= Calendar.MONDAY) && (dayOfWeek <= Calendar.TUESDAY)))
{
return loc.getFeeCount() / 2;
}
}
return loc.getFeeCount();
}
protected boolean shouldPayFee(L2PcInstance player, TeleportType type, TeleportLocation loc)
{
return (!Config.ALT_GAME_FREE_TELEPORT && ((player.getLevel() > Config.MAX_FREE_TELEPORT_LEVEL) || player.isSubClassActive()) && ((loc.getFeeId() != 0) && (loc.getFeeCount() > 0)));
}
protected int parseNextInt(StringTokenizer st, int defaultVal)
private int parseNextInt(StringTokenizer st, int defaultVal)
{
if (st.hasMoreTokens())
{
@@ -262,294 +143,42 @@ public final class L2TeleporterInstance extends L2Npc
return defaultVal;
}
protected TeleportType parseTeleportType(StringTokenizer st)
{
TeleportType type = TeleportType.NORMAL;
if (st.hasMoreTokens())
{
final String typeToken = st.nextToken();
for (TeleportType teleportType : TeleportType.values())
{
if (teleportType.name().equalsIgnoreCase(typeToken))
{
type = teleportType;
break;
}
}
}
return type;
}
protected String getItemName(int itemId, boolean fstring)
{
if (fstring)
{
if (itemId == Inventory.ADENA_ID)
{
return "<fstring>1000308</fstring>";
}
else if (itemId == Inventory.ANCIENT_ADENA_ID)
{
return "<fstring>1000309</fstring>";
}
}
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
if (item != null)
{
return item.getName();
}
switch (itemId)
{
case MultisellData.PC_CAFE_POINTS:
{
return "Player Commendation Points";
}
case MultisellData.CLAN_REPUTATION:
{
return "Clan Reputation Points";
}
case MultisellData.FAME:
{
return "Fame";
}
case MultisellData.RAIDBOSS_POINTS:
{
return "Raid Points";
}
}
return "Unknown item: " + itemId;
}
private void processLegacyBypass(L2PcInstance player, String command)
{
player.sendPacket(ActionFailed.STATIC_PACKET);
final int condition = validateCondition(player);
final StringTokenizer st = new StringTokenizer(command, " ");
final String actualCommand = st.nextToken(); // Get actual command
if (player.isAffectedBySkill(6201) || player.isAffectedBySkill(6202) || player.isAffectedBySkill(6203))
{
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
final String filename = "data/html/teleporter/epictransformed.htm";
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
return;
}
else if (actualCommand.equalsIgnoreCase("goto"))
{
final int npcId = getId();
switch (npcId)
{
case 32534: // Seed of Infinity
case 32539:
{
if (player.isFlyingMounted())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_ENTER_A_SEED_WHILE_IN_A_FLYING_TRANSFORMATION_STATE);
return;
}
break;
}
}
if (st.countTokens() <= 0)
{
return;
}
final int whereTo = Integer.parseInt(st.nextToken());
if (condition == COND_REGULAR)
{
doTeleport(player, whereTo);
return;
}
else if (condition == COND_OWNER)
{
// TODO: Replace 0 with highest level when privilege level is implemented
int minPrivilegeLevel = 0;
if (st.countTokens() >= 1)
{
minPrivilegeLevel = Integer.parseInt(st.nextToken());
}
// TODO: Replace 10 with privilege level of player
if (10 >= minPrivilegeLevel)
{
doTeleport(player, whereTo);
}
else
{
player.sendMessage("You don't have the sufficient access level to teleport there.");
}
return;
}
}
else if (command.startsWith("Chat"))
{
int val = 0;
try
{
val = Integer.parseInt(command.substring(5));
}
catch (IndexOutOfBoundsException ioobe)
{
}
catch (NumberFormatException nfe)
{
}
showChatWindow(player, val);
}
super.onBypassFeedback(player, command);
}
@Override
public String getHtmlPath(int npcId, int val)
{
String pom = "";
if (val == 0)
{
pom = "" + npcId;
}
else
{
pom = npcId + "-" + val;
}
final String pom = (val == 0) ? String.valueOf(npcId) : (npcId + "-" + val);
return "data/html/teleporter/" + pom + ".htm";
}
@Override
public void showChatWindow(L2PcInstance player)
{
String filename = "data/html/teleporter/castleteleporter-no.htm";
final int condition = validateCondition(player);
if (condition == COND_REGULAR)
// Teleporter isn't on castle ground
if (CastleManager.getInstance().getCastle(this) == null)
{
super.showChatWindow(player);
return;
}
else if (condition > COND_ALL_FALSE)
{
if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
{
filename = "data/html/teleporter/castleteleporter-busy.htm"; // Busy because of siege
}
else if (condition == COND_OWNER) // Clan owns castle
{
filename = getHtmlPath(getId(), 0); // Owner message window
}
}
// Teleporter is on castle ground
String filename = "data/html/teleporter/castleteleporter-no.htm";
if ((player.getClan() != null) && (getCastle().getOwnerId() == player.getClanId())) // Clan owns castle
{
filename = getHtmlPath(getId(), 0); // Owner message window
}
else if (getCastle().getSiege().isInProgress()) // Teleporter is busy due siege
{
filename = "data/html/teleporter/castleteleporter-busy.htm"; // Busy because of siege
}
sendHtmlMessage(player, filename);
}
private void sendHtmlMessage(L2PcInstance player, String filename)
{
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
}
private void doTeleport(L2PcInstance player, int val)
{
final L2TeleportLocation list = TeleportLocationTable.getInstance().getTemplate(val);
if (list != null)
{
// you cannot teleport to village that is in siege
if (SiegeManager.getInstance().getSiege(list.getLocX(), list.getLocY(), list.getLocZ()) != null)
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
return;
}
else if (TownManager.townHasCastleInSiege(list.getLocX(), list.getLocY()) && isInsideZone(ZoneId.TOWN))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
return;
}
else if (!Config.ALT_GAME_KARMA_PLAYER_CAN_USE_GK && (player.getReputation() < 0)) // karma
{
player.sendMessage("Go away, you're not welcome here.");
return;
}
else if (player.isCombatFlagEquipped())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
return;
}
else if (list.getIsForNoble() && !player.isNoble())
{
final String filename = "data/html/teleporter/nobleteleporter-no.htm";
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
html.setFile(player.getHtmlPrefix(), filename);
html.replace("%objectId%", String.valueOf(getObjectId()));
html.replace("%npcname%", getName());
player.sendPacket(html);
return;
}
else if (player.isAlikeDead())
{
return;
}
final Calendar cal = Calendar.getInstance();
int price = list.getPrice();
if (player.getLevel() <= Config.MAX_FREE_TELEPORT_LEVEL)
{
price = 0;
}
else if (!list.getIsForNoble())
{
if ((cal.get(Calendar.HOUR_OF_DAY) >= 20) && (cal.get(Calendar.HOUR_OF_DAY) <= 23) && ((cal.get(Calendar.DAY_OF_WEEK) == 1) || (cal.get(Calendar.DAY_OF_WEEK) == 7)))
{
price /= 2;
}
}
if (Config.ALT_GAME_FREE_TELEPORT || player.destroyItemByItemId("Teleport " + (list.getIsForNoble() ? " nobless" : ""), list.getItemId(), price, this, true))
{
if (Config.DEBUG)
{
_log.info("Teleporting player " + player.getName() + " to new location: " + list.getLocX() + ":" + list.getLocY() + ":" + list.getLocZ());
}
player.teleToLocation(list.getLocX(), list.getLocY(), list.getLocZ());
}
}
else
{
_log.warning("No teleport destination with id:" + val);
}
player.sendPacket(ActionFailed.STATIC_PACKET);
}
private int validateCondition(L2PcInstance player)
{
// Teleporter isn't on castle ground
if (CastleManager.getInstance().getCastle(this) == null)
{
return COND_REGULAR; // Regular access
}
// Teleporter is on castle ground and siege is in progress
else if (getCastle().getSiege().isInProgress())
{
return COND_BUSY_BECAUSE_OF_SIEGE; // Busy because of siege
}
// Teleporter is on castle ground and player is in a clan
else if (player.getClan() != null)
{
if (getCastle().getOwnerId() == player.getClanId())
{
return COND_OWNER; // Owner
}
}
return COND_ALL_FALSE;
}
}

View File

@@ -54,6 +54,7 @@ import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcSkillFinish
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcSkillSee;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcSpawn;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcTeleport;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcTeleportRequest;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayableExpChanged;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerAbilityPointsChanged;
import com.l2jmobius.gameserver.model.events.impl.character.player.OnPlayerAugment;
@@ -197,6 +198,7 @@ public enum EventType
ON_NPC_MANOR_BYPASS(OnNpcManorBypass.class, void.class),
ON_NPC_MENU_SELECT(OnNpcMenuSelect.class, void.class),
ON_NPC_DESPAWN(OnNpcDespawn.class, void.class),
ON_NPC_TELEPORT_REQUEST(OnNpcTeleportRequest.class, void.class, TerminateReturn.class),
// Olympiad events
ON_OLYMPIAD_MATCH_RESULT(OnOlympiadMatchResult.class, void.class),

View File

@@ -0,0 +1,63 @@
/*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.events.impl.character.npc;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.events.EventType;
import com.l2jmobius.gameserver.model.events.impl.IBaseEvent;
import com.l2jmobius.gameserver.model.teleporter.TeleportHolder;
import com.l2jmobius.gameserver.model.teleporter.TeleportLocation;
/**
* Player teleport request listner - called from {@link TeleportHolder#doTeleport(L2PcInstance, L2Npc, int)}
* @author malyelfik
*/
public final class OnNpcTeleportRequest implements IBaseEvent
{
private final L2PcInstance _player;
private final L2Npc _npc;
private final TeleportLocation _loc;
public OnNpcTeleportRequest(L2PcInstance player, L2Npc npc, TeleportLocation loc)
{
_player = player;
_npc = npc;
_loc = loc;
}
public L2PcInstance getPlayer()
{
return _player;
}
public L2Npc getNpc()
{
return _npc;
}
public TeleportLocation getLocation()
{
return _loc;
}
@Override
public EventType getType()
{
return EventType.ON_NPC_TELEPORT_REQUEST;
}
}

View File

@@ -58,6 +58,9 @@ public enum CommonSkill
ALCHEMY_CUBE_RANDOM_SUCCESS(17966, 1),
PET_SWITCH_STANCE(6054, 1),
WEIGHT_PENALTY(4270, 1),
FROG_TRANSFORM(6201, 1),
CHILD_TRANSFORM(6202, 1),
NATIVE_TRANSFORM(6203, 1),
LUCKY_CLOVER(18103, 1);
private final SkillHolder _holder;

View File

@@ -16,42 +16,343 @@
*/
package com.l2jmobius.gameserver.model.teleporter;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.SpecialItemType;
import com.l2jmobius.gameserver.enums.TeleportType;
import com.l2jmobius.gameserver.instancemanager.CastleManager;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcTeleportRequest;
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
/**
* Teleport holder
* @author UnAfraid
*/
public class TeleportHolder
public final class TeleportHolder
{
private final int _npcId;
private final Map<TeleportType, Map<Integer, TeleportLocation>> _teleportLocations = new EnumMap<>(TeleportType.class);
private static final Logger LOGGER = Logger.getLogger(TeleportHolder.class.getName());
public TeleportHolder(int id)
private final String _name;
private final TeleportType _type;
private final List<TeleportLocation> _teleportData = new ArrayList<>();
/**
* Constructor
* @param name name of teleport list
* @param type type of teleport list
*/
public TeleportHolder(String name, TeleportType type)
{
_npcId = id;
_name = name;
_type = type;
}
public int getNpcId()
/**
* Gets list identification (name).
* @return list name
*/
public String getName()
{
return _npcId;
return _name;
}
public void addLocation(TeleportType type, TeleportLocation loc)
/**
* Check if teleport list is for noblesse or not.
* @return {@code true} if is for noblesse otherwise {@code false}
*/
public boolean isNoblesse()
{
_teleportLocations.computeIfAbsent(type, val -> new TreeMap<>()).put(loc.getId(), loc);
return _type.equals(TeleportType.NOBLES_ADENA) || _type.equals(TeleportType.NOBLES_TOKEN);
}
public TeleportLocation getLocation(TeleportType type, int index)
/**
* Gets type of teleport list.
* @return type of list
*/
public TeleportType getType()
{
return _teleportLocations.getOrDefault(type, Collections.emptyMap()).get(index);
return _type;
}
public Collection<TeleportLocation> getLocations(TeleportType type)
/**
* Create new teleport location in this holder.
* @param locData information about teleport location
*/
public void registerLocation(StatsSet locData)
{
return _teleportLocations.getOrDefault(type, Collections.emptyMap()).values();
_teleportData.add(new TeleportLocation(_teleportData.size(), locData));
}
}
/**
* Gets teleport location with specific index.
* @param locationId index of location (begins with {@code 0})
* @return instance of {@link TeleportLocation} if found otherwise {@code null}
*/
public TeleportLocation getLocation(int locationId)
{
return _teleportData.get(locationId);
}
/**
* Gets all teleport locations registered in current holder.
* @return collection of {@link TeleportLocation}
*/
public List<TeleportLocation> getLocations()
{
return _teleportData;
}
/**
* Build HTML message from teleport list and send it to player.
* @param player receiver of HTML message
* @param npc teleporter
*/
public void showTeleportList(L2PcInstance player, L2Npc npc)
{
showTeleportList(player, npc, "npc_" + npc.getObjectId() + "_teleport");
}
/**
* Build HTML message from teleport list and send it to player.
* @param player receiver of HTML message
* @param npc teleporter
* @param bypass bypass used while building message
*/
public void showTeleportList(L2PcInstance player, L2Npc npc, String bypass)
{
if (isNoblesse() && !player.isNoble())
{
LOGGER.warning("Player " + player.getObjectId() + " requested noblesse teleport without being noble!");
return;
}
// Load variables
final int questZoneId = (_type == TeleportType.NORMAL) ? player.getQuestZoneId() : -1;
// Build html
final StringBuilder sb = new StringBuilder();
final StringBuilder sb_f = new StringBuilder();
for (TeleportLocation loc : getLocations())
{
String finalName = loc.getName();
String confirmDesc = loc.getName();
if (loc.getNpcStringId() != null)
{
final int stringId = loc.getNpcStringId().getId();
finalName = "<fstring>" + stringId + "</fstring>";
confirmDesc = "F;" + stringId;
}
if (shouldPayFee(player, loc))
{
final long fee = calculateFee(player, loc);
if (fee != 0)
{
finalName += " - " + fee + " " + getItemName(loc.getFeeId(), true);
}
}
final boolean isQuestTeleport = (questZoneId >= 0) && (loc.getQuestZoneId() == questZoneId);
if (isQuestTeleport)
{
sb_f.append("<button align=left icon=\"quest\" action=\"bypass -h " + bypass + " " + _name + " " + loc.getId() + "\" msg=\"811;" + confirmDesc + "\">" + finalName + "</button>");
}
else
{
sb.append("<button align=left icon=\"teleport\" action=\"bypass -h " + bypass + " " + _name + " " + loc.getId() + "\" msg=\"811;" + confirmDesc + "\">" + finalName + "</button>");
}
}
sb_f.append(sb.toString());
// Send html message
final NpcHtmlMessage msg = new NpcHtmlMessage(npc.getObjectId());
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/teleports.htm");
msg.replace("%locations%", sb_f.toString());
player.sendPacket(msg);
}
/**
* Teleports player to final location
* @param player player being teleported
* @param npc teleporter
* @param locId destination
*/
public void doTeleport(L2PcInstance player, L2Npc npc, int locId)
{
if (isNoblesse() && !player.isNoble())
{
LOGGER.warning("Player " + player.getObjectId() + " requested noblesse teleport without being noble!");
return;
}
final TeleportLocation loc = getLocation(locId);
if (loc == null)
{
LOGGER.warning("Player " + player.getObjectId() + " requested unknown teleport location " + locId + " within list " + _name + "!");
return;
}
// Check if castle is in siege
for (int castleId : loc.getCastleId())
{
if (CastleManager.getInstance().getCastleById(castleId).getSiege().isInProgress())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
return;
}
}
// Validate conditions for NORMAL teleport
if (_type == TeleportType.NORMAL)
{
if (npc.getCastle().getSiege().isInProgress())
{
final NpcHtmlMessage msg = new NpcHtmlMessage(npc.getObjectId());
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/castleteleporter-busy.htm");
player.sendPacket(msg);
return;
}
else if (!Config.ALT_GAME_KARMA_PLAYER_CAN_USE_GK && (player.getReputation() < 0))
{
player.sendMessage("Go away, you're not welcome here.");
return;
}
else if (player.isCombatFlagEquipped())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
return;
}
}
// Notify listeners
final TerminateReturn term = EventDispatcher.getInstance().notifyEvent(new OnNpcTeleportRequest(player, npc, loc), npc, TerminateReturn.class);
if ((term != null) && term.terminate())
{
return;
}
// Check rest of conditions
if (shouldPayFee(player, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), calculateFee(player, loc), npc, true))
{
if (loc.getFeeId() == Inventory.ADENA_ID)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
}
else
{
player.sendMessage("You do not have enough " + getItemName(loc.getFeeId(), false));
}
}
else if (!player.isAlikeDead())
{
player.teleToLocation(loc);
}
}
/**
* Check if player have to play fee or not.
* @param player player which request teleport
* @param loc location where player should be teleported
* @return {@code true} when all requirements are met otherwise {@code false}
*/
private boolean shouldPayFee(L2PcInstance player, TeleportLocation loc)
{
return (_type != TeleportType.NORMAL) || (!Config.ALT_GAME_FREE_TELEPORT && ((player.getLevel() > Config.MAX_FREE_TELEPORT_LEVEL) || player.isSubClassActive()) && ((loc.getFeeId() != 0) && (loc.getFeeCount() > 0)));
}
/**
* Calculate fee amount for requested teleport.<br>
* For characters below level 77 teleport service is free.<br>
* From 8.00 pm to 00.00 from Monday till Tuesday for all characters there's a 50% discount on teleportation services
* @param player player which request teleport
* @param loc location where player should be teleported
* @return fee amount
*/
private long calculateFee(L2PcInstance player, TeleportLocation loc)
{
if (_type == TeleportType.NORMAL)
{
if (!player.isSubClassActive() && (player.getLevel() <= Config.MAX_FREE_TELEPORT_LEVEL))
{
return 0;
}
final Calendar cal = Calendar.getInstance();
final int hour = cal.get(Calendar.HOUR_OF_DAY);
final int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
if ((hour >= 20) && ((dayOfWeek >= Calendar.MONDAY) && (dayOfWeek <= Calendar.TUESDAY)))
{
return loc.getFeeCount() / 2;
}
}
return loc.getFeeCount();
}
/**
* Gets name of specified item.
* @param itemId template id of item
* @param fstring prefer using client strings
* @return item name
*/
private String getItemName(int itemId, boolean fstring)
{
if (fstring)
{
if (itemId == Inventory.ADENA_ID)
{
return "<fstring>1000308</fstring>";
}
else if (itemId == Inventory.ANCIENT_ADENA_ID)
{
return "<fstring>1000309</fstring>";
}
}
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
if (item != null)
{
return item.getName();
}
final SpecialItemType specialItem = SpecialItemType.getByClientId(itemId);
if (specialItem != null)
{
switch (specialItem)
{
case PC_CAFE_POINTS:
{
return "Player Commendation Points";
}
case CLAN_REPUTATION:
{
return "Clan Reputation Points";
}
case FAME:
{
return "Fame";
}
case FIELD_CYCLE_POINTS:
{
return "Field Cycle Points";
}
case RAIDBOSS_POINTS:
{
return "Raid Points";
}
}
}
return "Unknown item: " + itemId;
}
}

View File

@@ -16,6 +16,10 @@
*/
package com.l2jmobius.gameserver.model.teleporter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
@@ -32,6 +36,7 @@ public class TeleportLocation extends Location
private final int _questZoneId;
private final int _feeId;
private final long _feeCount;
private final List<Integer> _castleId;
public TeleportLocation(int id, StatsSet set)
{
@@ -42,6 +47,24 @@ public class TeleportLocation extends Location
_questZoneId = set.getInt("questZoneId", 0);
_feeId = set.getInt("feeId", Inventory.ADENA_ID);
_feeCount = set.getLong("feeCount", 0);
final String castleIds = set.getString("castleId", "");
if (castleIds.isEmpty())
{
_castleId = Collections.emptyList();
}
else if (!castleIds.contains(";"))
{
_castleId = Collections.singletonList(Integer.parseInt(castleIds));
}
else
{
_castleId = new ArrayList<>();
for (String castleId : castleIds.split(";"))
{
_castleId.add(Integer.parseInt(castleId));
}
}
}
public int getId()
@@ -73,4 +96,9 @@ public class TeleportLocation extends Location
{
return _feeCount;
}
public List<Integer> getCastleId()
{
return _castleId;
}
}