Sync with L2JServer Jan 9th 2015.

This commit is contained in:
mobius
2015-01-09 19:55:02 +00:00
parent 9c9b0aaff7
commit 4c2db62a63
618 changed files with 19803 additions and 7853 deletions
+106 -82
View File
@@ -18,8 +18,6 @@
*/
package com.l2jserver;
import info.tak11.subnet.Subnet;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
@@ -38,7 +36,9 @@ import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
@@ -52,6 +52,7 @@ import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
@@ -59,6 +60,7 @@ import org.w3c.dom.Node;
import com.l2jserver.gameserver.engines.DocumentParser;
import com.l2jserver.gameserver.enums.IllegalActionPunishmentType;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.holders.ItemHolder;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.util.FloodProtectorConfig;
@@ -107,6 +109,7 @@ public final class Config
public static final String CHAT_FILTER_FILE = "./config/chatfilter.txt";
public static final String EMAIL_CONFIG_FILE = "./config/Email.properties";
public static final String CH_SIEGE_FILE = "./config/ConquerableHallSiege.properties";
public static final String GEODATA_FILE = "./config/GeoData.properties";
// --------------------------------------------------
// L2J Variable Definitions
// --------------------------------------------------
@@ -338,6 +341,9 @@ public final class Config
public static int CS_SUPPORT1_FEE;
public static int CS_SUPPORT2_FEE;
public static List<Integer> SIEGE_HOUR_LIST;
public static int CASTLE_TAX_NEUTRAL;
public static int CASTLE_TAX_LIGHT;
public static int CASTLE_TAX_DARK;
public static int OUTER_DOOR_UPGRADE_PRICE2;
public static int OUTER_DOOR_UPGRADE_PRICE3;
public static int OUTER_DOOR_UPGRADE_PRICE5;
@@ -512,24 +518,10 @@ public final class Config
public static int MAX_NPC_ANIMATION;
public static int MIN_MONSTER_ANIMATION;
public static int MAX_MONSTER_ANIMATION;
public static int COORD_SYNCHRONIZE;
public static boolean ENABLE_FALLING_DAMAGE;
public static boolean GRIDS_ALWAYS_ON;
public static int GRID_NEIGHBOR_TURNON_TIME;
public static int GRID_NEIGHBOR_TURNOFF_TIME;
public static int GEODATA;
public static String GEODATA_DRIVER;
public static File PATHNODE_DIR;
public static boolean GEODATA_CELLFINDING;
public static String PATHFIND_BUFFERS;
public static float LOW_WEIGHT;
public static float MEDIUM_WEIGHT;
public static float HIGH_WEIGHT;
public static boolean ADVANCED_DIAGONAL_STRATEGY;
public static float DIAGONAL_WEIGHT;
public static int MAX_POSTFILTER_PASSES;
public static boolean DEBUG_PATH;
public static boolean FORCE_GEODATA;
public static boolean MOVE_BASED_KNOWNLIST;
public static long KNOWNLIST_UPDATE_INTERVAL;
public static int PEACE_ZONE_MODE;
@@ -560,6 +552,10 @@ public final class Config
public static boolean USE_SAY_FILTER;
public static String CHAT_FILTER_CHARS;
public static int[] BAN_CHAT_CHANNELS;
public static int WORLD_CHAT_MIN_LEVEL;
public static int WORLD_CHAT_POINTS_PER_DAY;
public static Duration WORLD_CHAT_INTERVAL;
public static String WORLD_CHAT_RESET_TIME;
public static int ALT_OLY_START_TIME;
public static int ALT_OLY_MIN;
public static int ALT_OLY_MAX_BUFFS;
@@ -1001,18 +997,15 @@ public final class Config
// Vitality Settings
// --------------------------------------------------
public static boolean ENABLE_VITALITY;
public static boolean RECOVER_VITALITY_ON_RECONNECT;
public static boolean ENABLE_DROP_VITALITY_HERBS;
public static float RATE_VITALITY_LEVEL_1;
public static float RATE_VITALITY_LEVEL_2;
public static float RATE_VITALITY_LEVEL_3;
public static float RATE_VITALITY_LEVEL_4;
public static int STARTING_VITALITY_POINTS;
public static int ALT_VITALITY_DATE_RESET;
public static String ALT_VITALITY_HOUR_RESET;
public static float RATE_VITALITY_EXP_MULTIPLIER;
public static float RATE_DROP_VITALITY_HERBS;
public static float RATE_RECOVERY_VITALITY_PEACE_ZONE;
public static float RATE_VITALITY_LOST;
public static float RATE_VITALITY_GAIN;
public static float RATE_RECOVERY_ON_RECONNECT;
public static int STARTING_VITALITY_POINTS;
// --------------------------------------------------
// No classification assigned to the following yet
@@ -1137,6 +1130,24 @@ public final class Config
public static int CHS_FAME_AMOUNT;
public static int CHS_FAME_FREQUENCY;
// GeoData Settings
public static int GEODATA;
public static File PATHNODE_DIR;
public static boolean GEODATA_CELLFINDING;
public static String PATHFIND_BUFFERS;
public static float LOW_WEIGHT;
public static float MEDIUM_WEIGHT;
public static float HIGH_WEIGHT;
public static boolean ADVANCED_DIAGONAL_STRATEGY;
public static float DIAGONAL_WEIGHT;
public static int MAX_POSTFILTER_PASSES;
public static boolean DEBUG_PATH;
public static boolean FORCE_GEODATA;
public static int COORD_SYNCHRONIZE;
public static Path GEODATA_PATH;
public static boolean TRY_LOAD_UNSPECIFIED_REGIONS;
public static Map<String, Boolean> GEODATA_REGIONS;
/**
* This class initializes all global variables for configuration.<br>
* If the key doesn't appear in properties file, a default value is set by this class. {@link #CONFIGURATION_FILE} (properties file) for configuring your server.
@@ -1292,6 +1303,9 @@ public final class Config
SIEGE_HOUR_LIST.add(Integer.parseInt(hour));
}
}
CASTLE_TAX_NEUTRAL = Feature.getInt("TaxForNeutralSide", 15);
CASTLE_TAX_LIGHT = Feature.getInt("TaxForLightSide", 0);
CASTLE_TAX_DARK = Feature.getInt("TaxForDarkSide", 30);
CS_TELE_FEE_RATIO = Feature.getLong("CastleTeleportFunctionFeeRatio", 604800000);
CS_TELE1_FEE = Feature.getInt("CastleTeleportFunctionFeeLvl1", 1000);
CS_TELE2_FEE = Feature.getInt("CastleTeleportFunctionFeeLvl2", 10000);
@@ -1528,8 +1542,14 @@ public final class Config
FEE_DELETE_TRANSFER_SKILLS = Character.getInt("FeeDeleteTransferSkills", 10000000);
FEE_DELETE_SUBCLASS_SKILLS = Character.getInt("FeeDeleteSubClassSkills", 10000000);
ENABLE_VITALITY = Character.getBoolean("EnableVitality", true);
RECOVER_VITALITY_ON_RECONNECT = Character.getBoolean("RecoverVitalityOnReconnect", true);
STARTING_VITALITY_POINTS = Character.getInt("StartingVitalityPoints", 20000);
STARTING_VITALITY_POINTS = Character.getInt("StartingVitalityPoints", 140000);
ALT_VITALITY_DATE_RESET = Character.getInt("AltVitalityDateReset", 4);
if ((ALT_VITALITY_DATE_RESET < 1) || (ALT_VITALITY_DATE_RESET > 7))
{
_log.log(Level.WARNING, "Wrong value specified for AltVitalityDateReset: " + ALT_VITALITY_DATE_RESET);
ALT_VITALITY_DATE_RESET = 3;
}
ALT_VITALITY_HOUR_RESET = Character.getString("AltVitalityHourReset", "06:30:00");
MAX_BONUS_EXP = Character.getDouble("MaxExpBonus", 3.5);
MAX_BONUS_SP = Character.getDouble("MaxSpBonus", 3.5);
MAX_RUN_SPEED = Character.getInt("MaxRunSpeed", 250);
@@ -1867,32 +1887,6 @@ public final class Config
GRIDS_ALWAYS_ON = General.getBoolean("GridsAlwaysOn", false);
GRID_NEIGHBOR_TURNON_TIME = General.getInt("GridNeighborTurnOnTime", 1);
GRID_NEIGHBOR_TURNOFF_TIME = General.getInt("GridNeighborTurnOffTime", 90);
GEODATA = General.getInt("GeoData", 0);
GEODATA_DRIVER = General.getString("GeoDataDriver", "com.l2jserver.gameserver.geoengine.NullDriver");
try
{
PATHNODE_DIR = new File(General.getString("PathnodeDirectory", "data/pathnode").replaceAll("\\\\", "/")).getCanonicalFile();
}
catch (IOException e)
{
_log.log(Level.WARNING, "Error setting pathnode directory!", e);
PATHNODE_DIR = new File("data/pathnode");
}
GEODATA_CELLFINDING = General.getBoolean("CellPathFinding", false);
PATHFIND_BUFFERS = General.getString("PathFindBuffers", "100x6;128x6;192x6;256x4;320x4;384x4;500x2");
LOW_WEIGHT = General.getFloat("LowWeight", 0.5f);
MEDIUM_WEIGHT = General.getFloat("MediumWeight", 2);
HIGH_WEIGHT = General.getFloat("HighWeight", 3);
ADVANCED_DIAGONAL_STRATEGY = General.getBoolean("AdvancedDiagonalStrategy", true);
DIAGONAL_WEIGHT = General.getFloat("DiagonalWeight", 0.707f);
MAX_POSTFILTER_PASSES = General.getInt("MaxPostfilterPasses", 3);
DEBUG_PATH = General.getBoolean("DebugPath", false);
FORCE_GEODATA = General.getBoolean("ForceGeodata", true);
COORD_SYNCHRONIZE = General.getInt("CoordSynchronize", -1);
String str = General.getString("EnableFallingDamage", "auto");
ENABLE_FALLING_DAMAGE = "auto".equalsIgnoreCase(str) ? GEODATA > 0 : Boolean.parseBoolean(str);
PEACE_ZONE_MODE = General.getInt("PeaceZoneMode", 0);
DEFAULT_GLOBAL_CHAT = General.getString("GlobalChat", "ON");
DEFAULT_TRADE_CHAT = General.getString("TradeChat", "ON");
@@ -1934,6 +1928,10 @@ public final class Config
{
_log.log(Level.WARNING, nfe.getMessage(), nfe);
}
WORLD_CHAT_MIN_LEVEL = General.getInt("WorldChatMinLevel", 95);
WORLD_CHAT_POINTS_PER_DAY = General.getInt("WorldChatPointsPerDay", 10);
WORLD_CHAT_INTERVAL = General.getDuration("WorldChatInterval", "20secs", Duration.ofSeconds(20));
WORLD_CHAT_RESET_TIME = General.getString("WorldChatResetTime", "06:30:00");
ALT_MANOR_REFRESH_TIME = General.getInt("AltManorRefreshTime", 20);
ALT_MANOR_REFRESH_MIN = General.getInt("AltManorRefreshMin", 0);
ALT_MANOR_APPROVE_TIME = General.getInt("AltManorApproveTime", 4);
@@ -2137,14 +2135,9 @@ public final class Config
RATE_HB_TRUST_INCREASE = RatesSettings.getFloat("RateHellboundTrustIncrease", 1);
RATE_HB_TRUST_DECREASE = RatesSettings.getFloat("RateHellboundTrustDecrease", 1);
RATE_VITALITY_LEVEL_1 = RatesSettings.getFloat("RateVitalityLevel1", 1.5f);
RATE_VITALITY_LEVEL_2 = RatesSettings.getFloat("RateVitalityLevel2", 2);
RATE_VITALITY_LEVEL_3 = RatesSettings.getFloat("RateVitalityLevel3", 2.5f);
RATE_VITALITY_LEVEL_4 = RatesSettings.getFloat("RateVitalityLevel4", 3);
RATE_RECOVERY_VITALITY_PEACE_ZONE = RatesSettings.getFloat("RateRecoveryPeaceZone", 1);
RATE_VITALITY_EXP_MULTIPLIER = RatesSettings.getFloat("RateVitalityExpMultiplier", 2);
RATE_VITALITY_LOST = RatesSettings.getFloat("RateVitalityLost", 1);
RATE_VITALITY_GAIN = RatesSettings.getFloat("RateVitalityGain", 1);
RATE_RECOVERY_ON_RECONNECT = RatesSettings.getFloat("RateRecoveryOnReconnect", 4);
RATE_KARMA_LOST = RatesSettings.getFloat("RateKarmaLost", -1);
if (RATE_KARMA_LOST == -1)
{
@@ -2778,6 +2771,49 @@ public final class Config
CHS_ENABLE_FAME = ClanHallSiege.getBoolean("EnableFame", false);
CHS_FAME_AMOUNT = ClanHallSiege.getInt("FameAmount", 0);
CHS_FAME_FREQUENCY = ClanHallSiege.getInt("FameFrequency", 0);
final PropertiesParser geoData = new PropertiesParser(GEODATA_FILE);
GEODATA = geoData.getInt("GeoData", 0);
try
{
PATHNODE_DIR = new File(geoData.getString("PathnodeDirectory", "data/pathnode").replaceAll("\\\\", "/")).getCanonicalFile();
}
catch (IOException e)
{
_log.log(Level.WARNING, "Error setting pathnode directory!", e);
PATHNODE_DIR = new File("data/pathnode");
}
GEODATA_CELLFINDING = geoData.getBoolean("CellPathFinding", false);
PATHFIND_BUFFERS = geoData.getString("PathFindBuffers", "100x6;128x6;192x6;256x4;320x4;384x4;500x2");
LOW_WEIGHT = geoData.getFloat("LowWeight", 0.5f);
MEDIUM_WEIGHT = geoData.getFloat("MediumWeight", 2);
HIGH_WEIGHT = geoData.getFloat("HighWeight", 3);
ADVANCED_DIAGONAL_STRATEGY = geoData.getBoolean("AdvancedDiagonalStrategy", true);
DIAGONAL_WEIGHT = geoData.getFloat("DiagonalWeight", 0.707f);
MAX_POSTFILTER_PASSES = geoData.getInt("MaxPostfilterPasses", 3);
DEBUG_PATH = geoData.getBoolean("DebugPath", false);
FORCE_GEODATA = geoData.getBoolean("ForceGeoData", true);
COORD_SYNCHRONIZE = geoData.getInt("CoordSynchronize", -1);
GEODATA_PATH = Paths.get(geoData.getString("GeoDataPath", "./data/geodata"));
TRY_LOAD_UNSPECIFIED_REGIONS = geoData.getBoolean("TryLoadUnspecifiedRegions", true);
GEODATA_REGIONS = new HashMap<>();
for (int regionX = L2World.TILE_X_MIN; regionX <= L2World.TILE_X_MAX; regionX++)
{
for (int regionY = L2World.TILE_Y_MIN; regionY <= L2World.TILE_Y_MAX; regionY++)
{
String key = regionX + "_" + regionY;
if (geoData.containskey(regionX + "_" + regionY))
{
GEODATA_REGIONS.put(key, geoData.getBoolean(key, false));
}
}
}
String str = General.getString("EnableFallingDamage", "auto");
ENABLE_FALLING_DAMAGE = "auto".equalsIgnoreCase(str) ? GEODATA > 0 : Boolean.parseBoolean(str);
}
else if (Server.serverMode == Server.MODE_LOGINSERVER)
{
@@ -2931,20 +2967,8 @@ public final class Config
case "ratehellboundtrustdecrease":
RATE_HB_TRUST_DECREASE = Float.parseFloat(pValue);
break;
case "ratevitalitylevel1":
RATE_VITALITY_LEVEL_1 = Float.parseFloat(pValue);
break;
case "ratevitalitylevel2":
RATE_VITALITY_LEVEL_2 = Float.parseFloat(pValue);
break;
case "ratevitalitylevel3":
RATE_VITALITY_LEVEL_3 = Float.parseFloat(pValue);
break;
case "ratevitalitylevel4":
RATE_VITALITY_LEVEL_4 = Float.parseFloat(pValue);
break;
case "raterecoverypeacezone":
RATE_RECOVERY_VITALITY_PEACE_ZONE = Float.parseFloat(pValue);
case "ratevitalityexpmultiplier":
RATE_VITALITY_EXP_MULTIPLIER = Float.parseFloat(pValue);
break;
case "ratevitalitylost":
RATE_VITALITY_LOST = Float.parseFloat(pValue);
@@ -2952,9 +2976,6 @@ public final class Config
case "ratevitalitygain":
RATE_VITALITY_GAIN = Float.parseFloat(pValue);
break;
case "raterecoveryonreconnect":
RATE_RECOVERY_ON_RECONNECT = Float.parseFloat(pValue);
break;
case "ratekarmaexplost":
RATE_KARMA_EXP_LOST = Float.parseFloat(pValue);
break;
@@ -4041,7 +4062,6 @@ public final class Config
{
Enumeration<NetworkInterface> niList = NetworkInterface.getNetworkInterfaces();
Subnet sub = new Subnet();
while (niList.hasMoreElements())
{
NetworkInterface ni = niList.nextElement();
@@ -4063,14 +4083,18 @@ public final class Config
continue;
}
sub.setIPAddress(ia.getAddress().getHostAddress());
sub.setMaskedBits(ia.getNetworkPrefixLength());
String subnet = sub.getSubnetAddress() + '/' + sub.getMaskedBits();
final String hostAddress = ia.getAddress().getHostAddress();
final int subnetPrefixLength = ia.getNetworkPrefixLength();
final int subnetMaskInt = IntStream.rangeClosed(1, subnetPrefixLength).reduce((r, e) -> (r << 1) + 1).orElse(0) << (32 - subnetPrefixLength);
final int hostAddressInt = Arrays.stream(hostAddress.split("\\.")).mapToInt(Integer::parseInt).reduce((r, e) -> (r << 8) + e).orElse(0);
final int subnetAddressInt = hostAddressInt & subnetMaskInt;
final String subnetAddress = ((subnetAddressInt >> 24) & 0xFF) + "." + ((subnetAddressInt >> 16) & 0xFF) + "." + ((subnetAddressInt >> 8) & 0xFF) + "." + (subnetAddressInt & 0xFF);
final String subnet = subnetAddress + '/' + subnetPrefixLength;
if (!_subnets.contains(subnet) && !subnet.equals("0.0.0.0/0"))
{
_subnets.add(subnet);
_hosts.add(sub.getIPAddress());
LOGGER.log(Level.INFO, "Network Config: Adding new subnet: " + subnet + " address: " + sub.getIPAddress());
_hosts.add(hostAddress);
LOGGER.log(Level.INFO, "Network Config: Adding new subnet: " + subnet + " address: " + hostAddress);
}
}
}
@@ -19,14 +19,11 @@
package com.l2jserver.gameserver;
import java.util.Calendar;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javolution.util.FastMap;
import com.l2jserver.Config;
import com.l2jserver.gameserver.ai.CtrlEvent;
import com.l2jserver.gameserver.ai.L2CharacterAI;
import com.l2jserver.gameserver.instancemanager.DayNightSpawnManager;
import com.l2jserver.gameserver.model.actor.L2Character;
@@ -49,7 +46,7 @@ public final class GameTimeController extends Thread
private static GameTimeController _instance;
private final FastMap<Integer, L2Character> _movingObjects = new FastMap<Integer, L2Character>().shared();
private final Set<L2Character> _movingObjects = ConcurrentHashMap.newKeySet();
private final long _referenceTime;
private GameTimeController()
@@ -113,7 +110,7 @@ public final class GameTimeController extends Thread
return;
}
_movingObjects.putIfAbsent(cha.getObjectId(), cha);
_movingObjects.add(cha);
}
/**
@@ -129,43 +126,7 @@ public final class GameTimeController extends Thread
*/
private final void moveObjects()
{
for (FastMap.Entry<Integer, L2Character> e = _movingObjects.head(), tail = _movingObjects.tail(); (e = e.getNext()) != tail;)
{
final L2Character character = e.getValue();
if (character.updatePosition(getGameTicks()))
{
// Destination reached. Remove from map and execute arrive event.
_movingObjects.remove(e.getKey());
fireCharacterArrived(character);
}
}
}
private final void fireCharacterArrived(final L2Character character)
{
final L2CharacterAI ai = character.getAI();
if (ai == null)
{
return;
}
ThreadPoolManager.getInstance().executeAi(() ->
{
try
{
if (Config.MOVE_BASED_KNOWNLIST)
{
character.getKnownList().findObjects();
}
ai.notifyEvent(CtrlEvent.EVT_ARRIVED);
}
catch (final Throwable e)
{
_log.log(Level.WARNING, "", e);
}
});
_movingObjects.removeIf(L2Character::updatePosition);
}
public final void stopTimer()
+207 -196
View File
@@ -18,137 +18,218 @@
*/
package com.l2jserver.gameserver;
import java.io.FileInputStream;
import java.lang.reflect.Constructor;
import java.nio.file.Paths;
import java.util.Properties;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.DoorTable;
import com.l2jserver.gameserver.geoengine.Direction;
import com.l2jserver.gameserver.geoengine.NullDriver;
import com.l2jserver.gameserver.geoengine.abstraction.IGeoDriver;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.Location;
import com.l2jserver.gameserver.model.interfaces.ILocational;
import com.l2jserver.gameserver.util.GeoUtils;
import com.l2jserver.gameserver.util.LinePointIterator;
import com.l2jserver.gameserver.util.LinePointIterator3D;
import com.l2jserver.geodriver.Cell;
import com.l2jserver.geodriver.GeoDriver;
/**
* @author -Nemesiss-, HorridoJoho
*/
public class GeoData implements IGeoDriver
public class GeoData
{
private static final Logger LOGGER = Logger.getLogger(GeoData.class.getName());
private static final String FILE_NAME_FORMAT = "%d_%d.l2j";
private static final int ELEVATED_SEE_OVER_DISTANCE = 2;
private static final int MAX_SEE_OVER_HEIGHT = 48;
private static final int Z_DELTA_LIMIT = 100;
private final IGeoDriver _driver;
private final GeoDriver _driver = new GeoDriver();
protected GeoData()
{
if (Config.GEODATA > 0)
if (Config.GEODATA == 0)
{
IGeoDriver driver = null;
try
{
Class<?> cls = Class.forName(Config.GEODATA_DRIVER);
if (!IGeoDriver.class.isAssignableFrom(cls))
{
throw new ClassCastException("Geodata driver class needs to implement IGeoDriver!");
}
Constructor<?> ctor = cls.getConstructor(Properties.class);
Properties props = new Properties();
try (FileInputStream fis = new FileInputStream(Paths.get("config", "GeoDriver.properties").toString()))
{
props.load(fis);
}
driver = (IGeoDriver) ctor.newInstance(props);
}
catch (Exception ex)
{
LOGGER.log(Level.SEVERE, "Failed to load geodata driver!", ex);
System.exit(1);
}
// we do it this way so it's predictable for the compiler
_driver = driver;
LOGGER.info(getClass().getSimpleName() + ": Disabled.");
return;
}
else
int loadedRegions = 0;
try
{
_driver = new NullDriver(null);
for (int regionX = L2World.TILE_X_MIN; regionX <= L2World.TILE_X_MAX; regionX++)
{
for (int regionY = L2World.TILE_Y_MIN; regionY <= L2World.TILE_Y_MAX; regionY++)
{
final Path geoFilePath = Config.GEODATA_PATH.resolve(String.format(FILE_NAME_FORMAT, regionX, regionY));
final Boolean loadFile = Config.GEODATA_REGIONS.get(regionX + "_" + regionY);
if (loadFile != null)
{
if (loadFile)
{
LOGGER.info(getClass().getSimpleName() + ": Loading " + geoFilePath.getFileName() + "...");
_driver.loadRegion(geoFilePath, regionX, regionY);
loadedRegions++;
}
}
else if (Config.TRY_LOAD_UNSPECIFIED_REGIONS)
{
try
{
LOGGER.info(getClass().getSimpleName() + ": Loading " + geoFilePath.getFileName() + "...");
_driver.loadRegion(geoFilePath, regionX, regionY);
loadedRegions++;
}
catch (Exception e)
{
// ignore file not found errors
if (!(e instanceof FileNotFoundException))
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Failed to load " + geoFilePath.getFileName() + "!", e);
}
}
}
}
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Failed to load geodata!", e);
System.exit(1);
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + loadedRegions + " regions.");
}
@Override
public int getGeoX(int worldX)
{
return _driver.getGeoX(worldX);
}
@Override
public int getGeoY(int worldY)
{
return _driver.getGeoY(worldY);
}
@Override
public int getWorldX(int geoX)
{
return _driver.getWorldX(geoX);
}
@Override
public int getWorldY(int geoY)
{
return _driver.getWorldY(geoY);
}
@Override
public boolean hasGeoPos(int geoX, int geoY)
{
return _driver.hasGeoPos(geoX, geoY);
}
@Override
public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe)
{
return _driver.checkNearestNswe(geoX, geoY, worldZ, nswe);
}
public boolean checkNearestNswe(int geoX, int geoY, int worldZ, int nswe, int zDeltaLimit)
{
return _driver.checkNearestNswe(geoX, geoY, worldZ, nswe, zDeltaLimit);
}
public boolean checkNearestNsweAntiCornerCut(int geoX, int geoY, int worldZ, int nswe)
{
boolean can = true;
if ((nswe & Cell.NSWE_NORTH_EAST) != 0)
{
// can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.NORTH);
can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_EAST) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_NORTH);
}
if (can && ((nswe & Cell.NSWE_NORTH_WEST) != 0))
{
// can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.NORTH);
can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_WEST) && checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_NORTH);
}
if (can && ((nswe & Cell.NSWE_SOUTH_EAST) != 0))
{
// can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.SOUTH);
can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_EAST) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_SOUTH);
}
if (can && ((nswe & Cell.NSWE_SOUTH_WEST) != 0))
{
// can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.SOUTH);
can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_WEST) && checkNearestNswe(geoX - 1, geoY, worldZ, Cell.NSWE_SOUTH);
}
return can && checkNearestNswe(geoX, geoY, worldZ, nswe);
}
public boolean checkNearestNsweAntiCornerCut(int geoX, int geoY, int worldZ, int nswe, int zDeltaLimit)
{
boolean can = true;
if ((nswe & Cell.NSWE_NORTH_EAST) != 0)
{
// can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.NORTH);
can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_EAST, zDeltaLimit) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_NORTH, zDeltaLimit);
}
if (can && ((nswe & Cell.NSWE_NORTH_WEST) != 0))
{
// can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.NORTH);
can = checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_WEST, zDeltaLimit) && checkNearestNswe(geoX, geoY - 1, worldZ, Cell.NSWE_NORTH, zDeltaLimit);
}
if (can && ((nswe & Cell.NSWE_SOUTH_EAST) != 0))
{
// can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.SOUTH);
can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_EAST, zDeltaLimit) && checkNearestNswe(geoX + 1, geoY, worldZ, Cell.NSWE_SOUTH, zDeltaLimit);
}
if (can && ((nswe & Cell.NSWE_SOUTH_WEST) != 0))
{
// can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.SOUTH);
can = checkNearestNswe(geoX, geoY + 1, worldZ, Cell.NSWE_WEST, zDeltaLimit) && checkNearestNswe(geoX - 1, geoY, worldZ, Cell.NSWE_SOUTH, zDeltaLimit);
}
return can && checkNearestNswe(geoX, geoY, worldZ, nswe, zDeltaLimit);
}
public int getNearestZ(int geoX, int geoY, int worldZ)
{
return _driver.getNearestZ(geoX, geoY, worldZ);
}
@Override
public int getNearestZ(int geoX, int geoY, int worldZ, int zDeltaLimit)
{
return _driver.getNearestZ(geoX, geoY, worldZ, zDeltaLimit);
}
public int getNextLowerZ(int geoX, int geoY, int worldZ)
{
return _driver.getNextLowerZ(geoX, geoY, worldZ);
}
@Override
public int getNextLowerZ(int geoX, int geoY, int worldZ, int zDeltaLimit)
{
return _driver.getNextLowerZ(geoX, geoY, worldZ, zDeltaLimit);
}
public int getNextHigherZ(int geoX, int geoY, int worldZ)
{
return _driver.getNextHigherZ(geoX, geoY, worldZ);
}
@Override
public boolean canEnterNeighbors(int geoX, int geoY, int worldZ, Direction first, Direction... more)
public int getNextHigherZ(int geoX, int geoY, int worldZ, int zDeltaLimit)
{
return _driver.canEnterNeighbors(geoX, geoY, worldZ, first, more);
return _driver.getNextHigherZ(geoX, geoY, worldZ, zDeltaLimit);
}
@Override
public boolean canEnterAllNeighbors(int geoX, int geoY, int worldZ)
public int getGeoX(int worldX)
{
return _driver.canEnterAllNeighbors(geoX, geoY, worldZ);
return _driver.getGeoX(worldX);
}
public int getGeoY(int worldY)
{
return _driver.getGeoY(worldY);
}
public int getWorldX(int geoX)
{
return _driver.getWorldX(geoX);
}
public int getWorldY(int geoY)
{
return _driver.getWorldY(geoY);
}
// ///////////////////
// L2J METHODS
public boolean isNullDriver()
{
return _driver instanceof NullDriver;
}
/**
* Gets the height.
* @param x the x coordinate
@@ -170,8 +251,7 @@ public class GeoData implements IGeoDriver
*/
public int getSpawnHeight(int x, int y, int z)
{
// + 30, defend against defective geodata and invalid spawn z :(
return getNextLowerZ(getGeoX(x), getGeoY(y), z + 30);
return getNearestZ(getGeoX(x), getGeoY(y), z, Z_DELTA_LIMIT);
}
/**
@@ -253,31 +333,17 @@ public class GeoData implements IGeoDriver
return canSeeTarget(x, y, z, tx, ty, tz);
}
private int getLosGeoZ(int prevX, int prevY, int prevGeoZ, int curX, int curY, Direction dir)
private int getLosGeoZ(int prevX, int prevY, int prevGeoZ, int curX, int curY, int nswe)
{
boolean can = true;
switch (dir)
if ((((nswe & Cell.NSWE_NORTH) != 0) && ((nswe & Cell.NSWE_SOUTH) != 0)) || (((nswe & Cell.NSWE_WEST) != 0) && ((nswe & Cell.NSWE_EAST) != 0)))
{
case NORTH_EAST:
can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.NORTH);
break;
case NORTH_WEST:
can = canEnterNeighbors(prevX, prevY - 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.NORTH);
break;
case SOUTH_EAST:
can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevGeoZ, Direction.SOUTH);
break;
case SOUTH_WEST:
can = canEnterNeighbors(prevX, prevY + 1, prevGeoZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevGeoZ, Direction.SOUTH);
break;
}
if (can && canEnterNeighbors(prevX, prevY, prevGeoZ, dir))
{
return getNearestZ(curX, curY, prevGeoZ);
throw new RuntimeException("Multiple directions!");
}
if (checkNearestNsweAntiCornerCut(prevX, prevY, prevGeoZ, nswe, Z_DELTA_LIMIT))
{
return getNearestZ(curX, curY, prevGeoZ, Z_DELTA_LIMIT);
}
return getNextHigherZ(curX, curY, prevGeoZ);
}
@@ -298,9 +364,10 @@ public class GeoData implements IGeoDriver
int tGeoX = getGeoX(tx);
int tGeoY = getGeoY(ty);
z = getNearestZ(geoX, geoY, z);
tz = getNearestZ(tGeoX, tGeoY, tz);
z = getNearestZ(geoX, geoY, z, Z_DELTA_LIMIT);
tz = getNearestZ(tGeoX, tGeoY, tz, Z_DELTA_LIMIT);
// fastpath
if ((geoX == tGeoX) && (geoY == tGeoY))
{
if (hasGeoPos(tGeoX, tGeoY))
@@ -356,12 +423,12 @@ public class GeoData implements IGeoDriver
int beeCurZ = pointIter.z();
int curGeoZ = prevGeoZ;
// the current position has geodata
// check if the position has geodata
if (hasGeoPos(curX, curY))
{
int beeCurGeoZ = getNearestZ(curX, curY, beeCurZ);
Direction dir = GeoUtils.computeDirection(prevX, prevY, curX, curY);
curGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, curX, curY, dir);
int nswe = GeoUtils.computeNswe(prevX, prevY, curX, curY);// .computeDirection(prevX, prevY, curX, curY);
curGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, curX, curY, nswe);
int maxHeight;
if (ptIndex < ELEVATED_SEE_OVER_DISTANCE)
{
@@ -375,41 +442,33 @@ public class GeoData implements IGeoDriver
boolean canSeeThrough = false;
if ((curGeoZ <= maxHeight) && (curGeoZ <= beeCurGeoZ))
{
switch (dir)
if ((nswe & Cell.NSWE_NORTH_EAST) != 0)
{
case NORTH_EAST:
{
int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Direction.EAST);
int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Direction.NORTH);
canSeeThrough = (northGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
break;
}
case NORTH_WEST:
{
int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Direction.WEST);
int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Direction.NORTH);
canSeeThrough = (northGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
break;
}
case SOUTH_EAST:
{
int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Direction.EAST);
int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Direction.SOUTH);
canSeeThrough = (southGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
break;
}
case SOUTH_WEST:
{
int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Direction.WEST);
int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Direction.SOUTH);
canSeeThrough = (southGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
break;
}
default:
{
canSeeThrough = true;
break;
}
int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Cell.NSWE_EAST);
int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Cell.NSWE_NORTH);
canSeeThrough = (northGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
}
else if ((nswe & Cell.NSWE_NORTH_WEST) != 0)
{
int northGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY - 1, Cell.NSWE_WEST);
int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Cell.NSWE_NORTH);
canSeeThrough = (northGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (northGeoZ <= getNearestZ(prevX, prevY - 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
}
else if ((nswe & Cell.NSWE_SOUTH_EAST) != 0)
{
int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Cell.NSWE_EAST);
int eastGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX + 1, prevY, Cell.NSWE_SOUTH);
canSeeThrough = (southGeoZ <= maxHeight) && (eastGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (eastGeoZ <= getNearestZ(prevX + 1, prevY, beeCurZ));
}
else if ((nswe & Cell.NSWE_SOUTH_WEST) != 0)
{
int southGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX, prevY + 1, Cell.NSWE_WEST);
int westGeoZ = getLosGeoZ(prevX, prevY, prevGeoZ, prevX - 1, prevY, Cell.NSWE_SOUTH);
canSeeThrough = (southGeoZ <= maxHeight) && (westGeoZ <= maxHeight) && (southGeoZ <= getNearestZ(prevX, prevY + 1, beeCurZ)) && (westGeoZ <= getNearestZ(prevX - 1, prevY, beeCurZ));
}
else
{
canSeeThrough = true;
}
}
@@ -443,10 +502,10 @@ public class GeoData implements IGeoDriver
{
int geoX = getGeoX(x);
int geoY = getGeoY(y);
z = getNearestZ(geoX, geoY, z);
z = getNearestZ(geoX, geoY, z, Z_DELTA_LIMIT);
int tGeoX = getGeoX(tx);
int tGeoY = getGeoY(ty);
tz = getNearestZ(tGeoX, tGeoY, tz);
tz = getNearestZ(tGeoX, tGeoY, tz, Z_DELTA_LIMIT);
if (DoorTable.getInstance().checkIfDoorsBetween(x, y, z, tx, ty, tz, instanceId, false))
{
@@ -464,36 +523,12 @@ public class GeoData implements IGeoDriver
{
int curX = pointIter.x();
int curY = pointIter.y();
int curZ = getNearestZ(curX, curY, prevZ);
int curZ = getNearestZ(curX, curY, prevZ, Z_DELTA_LIMIT);
if (hasGeoPos(prevX, prevY))
{
Direction dir = GeoUtils.computeDirection(prevX, prevY, curX, curY);
boolean canEnter = false;
if (canEnterNeighbors(prevX, prevY, prevZ, dir))
{
// check diagonal movement
switch (dir)
{
case NORTH_EAST:
canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.NORTH);
break;
case NORTH_WEST:
canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.NORTH);
break;
case SOUTH_EAST:
canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.SOUTH);
break;
case SOUTH_WEST:
canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.SOUTH);
break;
default:
canEnter = true;
break;
}
}
if (!canEnter)
int nswe = GeoUtils.computeNswe(prevX, prevY, curX, curY);
if (!checkNearestNsweAntiCornerCut(prevX, prevY, prevZ, nswe, Z_DELTA_LIMIT))
{
// can't move, return previous location
return new Location(getWorldX(prevX), getWorldY(prevY), prevZ);
@@ -529,10 +564,10 @@ public class GeoData implements IGeoDriver
{
int geoX = getGeoX(fromX);
int geoY = getGeoY(fromY);
fromZ = getNearestZ(geoX, geoY, fromZ);
fromZ = getNearestZ(geoX, geoY, fromZ, Z_DELTA_LIMIT);
int tGeoX = getGeoX(toX);
int tGeoY = getGeoY(toY);
toZ = getNearestZ(tGeoX, tGeoY, toZ);
toZ = getNearestZ(tGeoX, tGeoY, toZ, Z_DELTA_LIMIT);
if (DoorTable.getInstance().checkIfDoorsBetween(fromX, fromY, fromZ, toX, toY, toZ, instanceId, false))
{
@@ -550,36 +585,12 @@ public class GeoData implements IGeoDriver
{
int curX = pointIter.x();
int curY = pointIter.y();
int curZ = getNearestZ(curX, curY, prevZ);
int curZ = getNearestZ(curX, curY, prevZ, Z_DELTA_LIMIT);
if (hasGeoPos(prevX, prevY))
{
Direction dir = GeoUtils.computeDirection(prevX, prevY, curX, curY);
boolean canEnter = false;
if (canEnterNeighbors(prevX, prevY, prevZ, dir))
{
// check diagonal movement
switch (dir)
{
case NORTH_EAST:
canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.NORTH);
break;
case NORTH_WEST:
canEnter = canEnterNeighbors(prevX, prevY - 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.NORTH);
break;
case SOUTH_EAST:
canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.EAST) && canEnterNeighbors(prevX + 1, prevY, prevZ, Direction.SOUTH);
break;
case SOUTH_WEST:
canEnter = canEnterNeighbors(prevX, prevY + 1, prevZ, Direction.WEST) && canEnterNeighbors(prevX - 1, prevY, prevZ, Direction.SOUTH);
break;
default:
canEnter = true;
break;
}
}
if (!canEnter)
int nswe = GeoUtils.computeNswe(prevX, prevY, curX, curY);
if (!checkNearestNsweAntiCornerCut(prevX, prevY, prevZ, nswe, Z_DELTA_LIMIT))
{
return false;
}
@@ -603,7 +614,7 @@ public class GeoData implements IGeoDriver
{
int geoX = getGeoX(x);
int geoY = getGeoY(y);
z = getNearestZ(geoX, geoY, z);
z = getNearestZ(geoX, geoY, z, Z_DELTA_LIMIT);
int tGeoX = getGeoX(tx);
int tGeoY = getGeoY(ty);
@@ -616,7 +627,7 @@ public class GeoData implements IGeoDriver
{
int curX = pointIter.x();
int curY = pointIter.y();
int curZ = getNearestZ(curX, curY, prevZ);
int curZ = getNearestZ(curX, curY, prevZ, Z_DELTA_LIMIT);
prevZ = curZ;
}
@@ -0,0 +1,115 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.datatables;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jserver.gameserver.engines.DocumentParser;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.model.holders.CastleSpawnHolder;
/**
* @author St3eT
*/
public final class CastleData implements DocumentParser
{
private final Map<Integer, List<CastleSpawnHolder>> _castles = new HashMap<>();
protected CastleData()
{
load();
}
@Override
public void load()
{
_castles.clear();
parseDatapackDirectory("data/castles", true);
}
@Override
public void parseDocument(Document doc)
{
for (Node listNode = doc.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
{
if ("list".equals(listNode.getNodeName()))
{
for (Node castleNode = listNode.getFirstChild(); castleNode != null; castleNode = castleNode.getNextSibling())
{
if ("castle".equals(castleNode.getNodeName()))
{
final int castleId = parseInteger(castleNode.getAttributes(), "id");
final List<CastleSpawnHolder> spawns = new ArrayList<>();
for (Node tpNode = castleNode.getFirstChild(); tpNode != null; tpNode = tpNode.getNextSibling())
{
if ("spawn".equals(tpNode.getNodeName()))
{
final CastleSide side = parseEnum(tpNode.getAttributes(), CastleSide.class, "castleSide", CastleSide.NEUTRAL);
for (Node npcNode = tpNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
{
if ("npc".equals(npcNode.getNodeName()))
{
final NamedNodeMap np = npcNode.getAttributes();
final int npcId = parseInteger(np, "id");
final int x = parseInteger(np, "x");
final int y = parseInteger(np, "y");
final int z = parseInteger(np, "z");
final int heading = parseInteger(np, "heading");
spawns.add(new CastleSpawnHolder(npcId, side, x, y, z, heading));
}
}
}
}
_castles.put(castleId, spawns);
}
}
}
}
}
public final List<CastleSpawnHolder> getSpawnsForSide(int castleId, CastleSide side)
{
return _castles.getOrDefault(castleId, Collections.emptyList()).stream().filter(s -> s.getSide() == side).collect(Collectors.toList());
}
/**
* Gets the single instance of TeleportersData.
* @return single instance of TeleportersData
*/
public static CastleData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final CastleData _instance = new CastleData();
}
}
@@ -401,12 +401,14 @@ public class ClanTable
_log.log(Level.SEVERE, getClass().getSimpleName() + ": Error storing clan wars data.", e);
}
// SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.A_CLAN_WAR_WITH_CLAN_S1_HAS_STARTED_THE_CLAN_THAT_CANCELS_THE_WAR_FIRST_WILL_LOSE_5_000_CLAN_REPUTATION_ANY_CLAN_THAT_CANCELS_THE_WAR_WILL_BE_UNABLE_TO_DECLARE_A_WAR_FOR_1_WEEK_IF_YOUR_CLAN_MEMBER_GETS_KILLED_BY_THE_OTHER_CLAN_XP_DECREASES_BY_1_4_OF_THE_AMOUNT_THAT_DECREASES_IN_THE_HUNTING_GROUND);
// SystemMessage msg =
// SystemMessage.getSystemMessage(SystemMessageId.A_CLAN_WAR_WITH_CLAN_S1_HAS_STARTED_THE_CLAN_THAT_CANCELS_THE_WAR_FIRST_WILL_LOSE_5_000_CLAN_REPUTATION_ANY_CLAN_THAT_CANCELS_THE_WAR_WILL_BE_UNABLE_TO_DECLARE_A_WAR_FOR_1_WEEK_IF_YOUR_CLAN_MEMBER_GETS_KILLED_BY_THE_OTHER_CLAN_XP_DECREASES_BY_1_4_OF_THE_AMOUNT_THAT_DECREASES_IN_THE_HUNTING_GROUND);
//
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_DECLARED_A_CLAN_WAR_WITH_S1);
msg.addString(clan2.getName());
clan1.broadcastToOnlineMembers(msg);
// msg = SystemMessage.getSystemMessage(SystemMessageId.A_CLAN_WAR_WITH_CLAN_S1_HAS_STARTED_THE_CLAN_THAT_CANCELS_THE_WAR_FIRST_WILL_LOSE_5_000_CLAN_REPUTATION_ANY_CLAN_THAT_CANCELS_THE_WAR_WILL_BE_UNABLE_TO_DECLARE_A_WAR_FOR_1_WEEK_IF_YOUR_CLAN_MEMBER_GETS_KILLED_BY_THE_OTHER_CLAN_XP_DECREASES_BY_1_4_OF_THE_AMOUNT_THAT_DECREASES_IN_THE_HUNTING_GROUND);
// msg =
// SystemMessage.getSystemMessage(SystemMessageId.A_CLAN_WAR_WITH_CLAN_S1_HAS_STARTED_THE_CLAN_THAT_CANCELS_THE_WAR_FIRST_WILL_LOSE_5_000_CLAN_REPUTATION_ANY_CLAN_THAT_CANCELS_THE_WAR_WILL_BE_UNABLE_TO_DECLARE_A_WAR_FOR_1_WEEK_IF_YOUR_CLAN_MEMBER_GETS_KILLED_BY_THE_OTHER_CLAN_XP_DECREASES_BY_1_4_OF_THE_AMOUNT_THAT_DECREASES_IN_THE_HUNTING_GROUND);
// msg.addString(clan1.getName());
// clan2.broadcastToOnlineMembers(msg);
// clan1 declared clan war.
@@ -458,7 +460,7 @@ public class ClanTable
count++;
}
}
if (count == (clan1.getMembers().length - 1))
if (count == (clan1.getMembers().size() - 1))
{
clan1.deleteEnemyClan(clan2);
clan2.deleteEnemyClan(clan1);
@@ -20,6 +20,8 @@ package com.l2jserver.gameserver.datatables;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
@@ -27,6 +29,7 @@ import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.gameserver.engines.DocumentEngine;
import com.l2jserver.gameserver.model.skills.CommonSkill;
import com.l2jserver.gameserver.model.skills.Skill;
/**
@@ -150,21 +153,23 @@ public final class SkillData
* @param hasCastle
* @return an array with siege skills. If addNoble == true, will add also Advanced headquarters.
*/
public Skill[] getSiegeSkills(boolean addNoble, boolean hasCastle)
public List<Skill> getSiegeSkills(boolean addNoble, boolean hasCastle)
{
Skill[] temp = new Skill[2 + (addNoble ? 1 : 0) + (hasCastle ? 2 : 0)];
int i = 0;
temp[i++] = _skills.get(SkillData.getSkillHashCode(246, 1));
temp[i++] = _skills.get(SkillData.getSkillHashCode(247, 1));
final List<Skill> temp = new LinkedList<>();
temp.add(_skills.get(SkillData.getSkillHashCode(CommonSkill.IMPRIT_OF_LIGHT.getId(), 1)));
temp.add(_skills.get(SkillData.getSkillHashCode(CommonSkill.IMPRIT_OF_DARKNESS.getId(), 1)));
temp.add(_skills.get(SkillData.getSkillHashCode(247, 1))); // Build Headquarters
if (addNoble)
{
temp[i++] = _skills.get(SkillData.getSkillHashCode(326, 1));
temp.add(_skills.get(SkillData.getSkillHashCode(326, 1))); // Build Advanced Headquarters
}
if (hasCastle)
{
temp[i++] = _skills.get(SkillData.getSkillHashCode(844, 1));
temp[i++] = _skills.get(SkillData.getSkillHashCode(845, 1));
temp.add(_skills.get(SkillData.getSkillHashCode(844, 1))); // Outpost Construction
temp.add(_skills.get(SkillData.getSkillHashCode(845, 1))); // Outpost Demolition
}
return temp;
}
@@ -23,6 +23,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -35,6 +36,7 @@ import org.w3c.dom.Node;
import com.l2jserver.Config;
import com.l2jserver.gameserver.engines.DocumentParser;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.enums.SubclassType;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2SkillLearn;
import com.l2jserver.gameserver.model.L2SkillLearn.SubClassData;
@@ -78,6 +80,7 @@ public final class SkillTreesData implements DocumentParser
private static final Map<ClassId, Map<Integer, L2SkillLearn>> _classSkillTrees = new HashMap<>();
private static final Map<ClassId, Map<Integer, L2SkillLearn>> _transferSkillTrees = new HashMap<>();
private static final Map<Race, Map<Integer, L2SkillLearn>> _raceSkillTree = new HashMap<>();
private static final Map<SubclassType, Map<Integer, L2SkillLearn>> _revelationSkillTree = new HashMap<>();
// Skill Hash Code, L2SkillLearn
private static final Map<Integer, L2SkillLearn> _collectSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _fishingSkillTree = new HashMap<>();
@@ -133,6 +136,7 @@ public final class SkillTreesData implements DocumentParser
_gameMasterSkillTree.clear();
_gameMasterAuraSkillTree.clear();
_raceSkillTree.clear();
_revelationSkillTree.clear();
// Load files.
parseDatapackDirectory("data/skillTrees/", false);
@@ -156,6 +160,7 @@ public final class SkillTreesData implements DocumentParser
Node attr;
String type = null;
Race race = null;
SubclassType subType = null;
int cId = -1;
int parentClassId = -1;
ClassId classId = null;
@@ -170,6 +175,7 @@ public final class SkillTreesData implements DocumentParser
final Map<Integer, L2SkillLearn> classSkillTree = new HashMap<>();
final Map<Integer, L2SkillLearn> transferSkillTree = new HashMap<>();
final Map<Integer, L2SkillLearn> raceSkillTree = new HashMap<>();
final Map<Integer, L2SkillLearn> revelationSkillTree = new HashMap<>();
type = d.getAttributes().getNamedItem("type").getNodeValue();
attr = d.getAttributes().getNamedItem("classId");
@@ -189,6 +195,12 @@ public final class SkillTreesData implements DocumentParser
race = parseEnum(attr, Race.class);
}
attr = d.getAttributes().getNamedItem("subType");
if (attr != null)
{
subType = parseEnum(attr, SubclassType.class);
}
attr = d.getAttributes().getNamedItem("parentClassId");
if (attr != null)
{
@@ -271,6 +283,11 @@ public final class SkillTreesData implements DocumentParser
raceSkillTree.put(skillHashCode, skillLearn);
break;
}
case "revelationSkillTree":
{
revelationSkillTree.put(skillHashCode, skillLearn);
break;
}
case "fishingSkillTree":
{
_fishingSkillTree.put(skillHashCode, skillLearn);
@@ -365,6 +382,17 @@ public final class SkillTreesData implements DocumentParser
_raceSkillTree.get(race).putAll(raceSkillTree);
}
}
else if (type.equals("revelationSkillTree") && (subType != null))
{
if (!_revelationSkillTree.containsKey(subType))
{
_revelationSkillTree.put(subType, revelationSkillTree);
}
else
{
_revelationSkillTree.get(subType).putAll(revelationSkillTree);
}
}
}
}
}
@@ -576,7 +604,7 @@ public final class SkillTreesData implements DocumentParser
final Map<Integer, L2SkillLearn> skills = getCompleteClassSkillTree(classId);
for (L2SkillLearn skill : skills.values())
{
if ((skill.getSkillId() == CommonSkill.DIVINE_INSPIRATION.getId()) || skill.isAutoGet() || skill.isLearnedByFS())
if ((skill.getSkillId() == CommonSkill.DIVINE_INSPIRATION.getId()) || skill.isAutoGet() || skill.isLearnedByFS() || (skill.getGetLevel() > player.getLevel()))
{
continue;
}
@@ -585,7 +613,7 @@ public final class SkillTreesData implements DocumentParser
{
return true;
}
else if (skill.getSkillLevel() == 1)
else if ((oldSkill == null) && (skill.getSkillLevel() == 1))
{
return true;
}
@@ -617,7 +645,7 @@ public final class SkillTreesData implements DocumentParser
*/
private List<L2SkillLearn> getAvailableSkills(L2PcInstance player, ClassId classId, boolean includeByFs, boolean includeAutoGet, ISkillsHolder holder)
{
final List<L2SkillLearn> result = new ArrayList<>();
final List<L2SkillLearn> result = new LinkedList<>();
final Map<Integer, L2SkillLearn> skills = getCompleteClassSkillTree(classId);
if (skills.isEmpty())
@@ -761,6 +789,29 @@ public final class SkillTreesData implements DocumentParser
return result;
}
/**
* Gets the available revelation skills
* @param player the player requesting the revelation skills
* @param type the player current subclass type
* @return all the available revelation skills for a given {@code player}
*/
public List<L2SkillLearn> getAvailableRevelationSkills(L2PcInstance player, SubclassType type)
{
final List<L2SkillLearn> result = new ArrayList<>();
Map<Integer, L2SkillLearn> revelationSkills = _revelationSkillTree.get(type);
for (L2SkillLearn skill : revelationSkills.values())
{
final Skill oldSkill = player.getSkills().get(skill.getSkillId());
if (oldSkill == null)
{
result.add(skill);
}
}
return result;
}
/**
* Gets the available alchemy skills, restricted to Ertheia
* @param player the player requesting the alchemy skills
@@ -1057,6 +1108,12 @@ public final class SkillTreesData implements DocumentParser
case COLLECT:
sl = getCollectSkill(id, lvl);
break;
case REVELATION:
sl = getRevelationSkill(SubclassType.BASECLASS, id, lvl);
break;
case REVELATION_DUALCLASS:
sl = getRevelationSkill(SubclassType.DUALCLASS, id, lvl);
break;
case ALCHEMY:
sl = getAlchemySkill(id, lvl);
break;
@@ -1214,6 +1271,18 @@ public final class SkillTreesData implements DocumentParser
return _collectSkillTree.get(SkillData.getSkillHashCode(id, lvl));
}
/**
* Gets the revelation skill.
* @param type the subclass type
* @param id the revelation skill Id
* @param lvl the revelation skill level
* @return the revelation skill from the Revelation Skill Tree for a given {@code id} and {@code lvl}
*/
public L2SkillLearn getRevelationSkill(SubclassType type, int id, int lvl)
{
return _revelationSkillTree.get(type).get(SkillData.getSkillHashCode(id, lvl));
}
/**
* Gets the minimum level for new skill.
* @param player the player that requires the minimum level
@@ -1243,6 +1312,40 @@ public final class SkillTreesData implements DocumentParser
return minLevel;
}
public List<L2SkillLearn> getNextAvailableSkills(L2PcInstance player, ClassId classId, boolean includeByFs, boolean includeAutoGet)
{
final Map<Integer, L2SkillLearn> completeClassSkillTree = getCompleteClassSkillTree(classId);
final List<L2SkillLearn> result = new LinkedList<>();
if (completeClassSkillTree.isEmpty())
{
return result;
}
final int minLevelForNewSkill = getMinLevelForNewSkill(player, completeClassSkillTree);
if (minLevelForNewSkill > 0)
{
for (L2SkillLearn skill : completeClassSkillTree.values())
{
if (((includeAutoGet && skill.isAutoGet()) || skill.isLearnedByNpc() || (includeByFs && skill.isLearnedByFS())) && (minLevelForNewSkill == skill.getGetLevel()))
{
final Skill oldSkill = player.getKnownSkill(skill.getSkillId());
if (oldSkill != null)
{
if (oldSkill.getLevel() == (skill.getSkillLevel() - 1))
{
result.add(skill);
}
}
else if (skill.getSkillLevel() == 1)
{
result.add(skill);
}
}
}
}
return result;
}
/**
* Checks if is hero skill.
* @param skillId the Id of the skill to check
@@ -1517,6 +1620,12 @@ public final class SkillTreesData implements DocumentParser
raceSkillTreeCount += raceSkillTree.size();
}
int revelationSkillTreeCount = 0;
for (Map<Integer, L2SkillLearn> revelationSkillTree : _revelationSkillTree.values())
{
revelationSkillTreeCount += revelationSkillTree.size();
}
int dwarvenOnlyFishingSkillCount = 0;
for (L2SkillLearn fishSkill : _fishingSkillTree.values())
{
@@ -1551,6 +1660,7 @@ public final class SkillTreesData implements DocumentParser
LOGGER.info(className + ": Loaded " + _gameMasterAuraSkillTree.size() + " Game Master Aura Skills.");
LOGGER.info(className + ": Loaded " + _abilitySkillTree.size() + " Ability Skills.");
LOGGER.info(className + ": Loaded " + _alchemySkillTree.size() + " Alchemy Skills.");
LOGGER.info(className + ": Loaded " + revelationSkillTreeCount + " Revelation Skills.");
final int commonSkills = _commonSkillTree.size();
if (commonSkills > 0)
@@ -37,6 +37,7 @@ import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.InstanceType;
import com.l2jserver.gameserver.enums.Race;
@@ -87,6 +88,7 @@ import com.l2jserver.gameserver.model.conditions.ConditionPlayerInvSize;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerIsClanLeader;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerIsHero;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerIsInCombat;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerIsOnSide;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerLandingZone;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerLevel;
import com.l2jserver.gameserver.model.conditions.ConditionPlayerLevelRange;
@@ -927,6 +929,11 @@ public abstract class DocumentBase
cond = joinAnd(cond, new ConditionPlayerIsInCombat(Boolean.parseBoolean(a.getNodeValue())));
break;
}
case "isonside":
{
cond = joinAnd(cond, new ConditionPlayerIsOnSide(Enum.valueOf(CastleSide.class, a.getNodeValue())));
break;
}
}
}
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.enums;
/**
* @author St3eT
*/
public enum CastleSide
{
NEUTRAL,
LIGHT,
DARK;
}
@@ -149,7 +149,23 @@ public enum CategoryType
BEASTFARM_INVADER,
ICEQUEEN_NPC,
AWAKEN_GROUP,
SHILENS_FOLLOWERS;
SHILENS_FOLLOWERS,
SIGEL_CANDIDATE,
TYRR_CANDIDATE,
OTHELL_CANDIDATE,
YUL_CANDIDATE,
FEOH_CANDIDATE,
ISS_CANDIDATE,
WYNN_CANDIDATE,
AEORE_CANDIDATE,
SIGEL_GROUP,
TYRR_GROUP,
OTHELL_GROUP,
YUL_GROUP,
FEOH_GROUP,
ISS_GROUP,
WYNN_GROUP,
AEORE_GROUP;
/**
* Finds category by it's name
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.enums;
/**
* @author St3eT
*/
public enum SiegeClanType
{
OWNER,
DEFENDER_PENDING,
DEFENDER,
ATTACKER;
}
@@ -289,7 +289,7 @@ public abstract class IdFactory
stmt.executeUpdate("UPDATE clan_data SET auction_bid_at = 0 WHERE auction_bid_at NOT IN (SELECT auctionId FROM auction_bid);");
stmt.executeUpdate("UPDATE clan_data SET new_leader_id = 0 WHERE new_leader_id <> 0 AND new_leader_id NOT IN (SELECT charId FROM characters);");
stmt.executeUpdate("UPDATE clan_subpledges SET leader_id=0 WHERE clan_subpledges.leader_id NOT IN (SELECT charId FROM characters) AND leader_id > 0;");
stmt.executeUpdate("UPDATE castle SET taxpercent=0 WHERE castle.id NOT IN (SELECT hasCastle FROM clan_data);");
stmt.executeUpdate("UPDATE castle SET side='NEUTRAL' WHERE castle.id NOT IN (SELECT hasCastle FROM clan_data);");
stmt.executeUpdate("UPDATE characters SET clanid=0, clan_privs=0, wantspeace=0, subpledge=0, lvl_joined_academy=0, apprentice=0, sponsor=0, clan_join_expiry_time=0, clan_create_expiry_time=0 WHERE characters.clanid > 0 AND characters.clanid NOT IN (SELECT clan_id FROM clan_data);");
stmt.executeUpdate("UPDATE clanhall SET ownerId=0, paidUntil=0, paid=0 WHERE clanhall.ownerId NOT IN (SELECT clan_id FROM clan_data);");
stmt.executeUpdate("UPDATE fort SET owner=0 WHERE owner NOT IN (SELECT clan_id FROM clan_data);");
@@ -200,18 +200,6 @@ public final class CastleManager implements InstanceListManager
return hasOwnedCastle;
}
public final void validateTaxes(int sealStrifeOwner)
{
final int maxTax = 15;
for (Castle castle : _castles)
{
if (castle.getTaxPercent() > maxTax)
{
castle.setTaxPercent(maxTax);
}
}
}
public int getCirclet()
{
return getCircletByCastleId(1);
@@ -343,4 +331,4 @@ public final class CastleManager implements InstanceListManager
{
protected static final CastleManager _instance = new CastleManager();
}
}
}
@@ -197,7 +197,8 @@ public final class CursedWeaponsManager
private final void controlPlayers()
{
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT owner_id FROM items WHERE item_id=?"))
{
// TODO: See comments below...
// This entire for loop should NOT be necessary, since it is already handled by
@@ -205,55 +206,49 @@ public final class CursedWeaponsManager
// then we'd better make sure that it FULLY cleans up inactive cursed weapons!
// Undesired effects result otherwise, such as player with no zariche but with karma
// or a lost-child entry in the cursed weapons table, without a corresponding one in items...
// Retrieve the L2PcInstance from the characters table of the database
try (PreparedStatement ps = con.prepareStatement("SELECT owner_id FROM items WHERE item_id=?"))
for (CursedWeapon cw : _cursedWeapons.values())
{
for (CursedWeapon cw : _cursedWeapons.values())
if (cw.isActivated())
{
if (cw.isActivated())
continue;
}
// Do an item check to be sure that the cursed weapon isn't hold by someone
final int itemId = cw.getItemId();
ps.setInt(1, itemId);
try (ResultSet rset = ps.executeQuery())
{
if (rset.next())
{
continue;
}
// Do an item check to be sure that the cursed weapon isn't hold by someone
int itemId = cw.getItemId();
ps.setInt(1, itemId);
try (ResultSet rset = ps.executeQuery())
{
if (rset.next())
// A player has the cursed weapon in his inventory ...
final int playerId = rset.getInt("owner_id");
_log.info("PROBLEM : Player " + playerId + " owns the cursed weapon " + itemId + " but he shouldn't.");
// Delete the item
try (PreparedStatement delete = con.prepareStatement("DELETE FROM items WHERE owner_id=? AND item_id=?"))
{
// A player has the cursed weapon in his inventory ...
int playerId = rset.getInt("owner_id");
_log.info("PROBLEM : Player " + playerId + " owns the cursed weapon " + itemId + " but he shouldn't.");
// Delete the item
try (PreparedStatement delete = con.prepareStatement("DELETE FROM items WHERE owner_id=? AND item_id=?"))
delete.setInt(1, playerId);
delete.setInt(2, itemId);
if (delete.executeUpdate() != 1)
{
delete.setInt(1, playerId);
delete.setInt(2, itemId);
if (delete.executeUpdate() != 1)
{
_log.warning("Error while deleting cursed weapon " + itemId + " from userId " + playerId);
}
_log.warning("Error while deleting cursed weapon " + itemId + " from userId " + playerId);
}
// Restore the player's old karma and pk count
try (PreparedStatement update = con.prepareStatement("UPDATE characters SET karma=?, pkkills=? WHERE charId=?"))
{
update.setInt(1, cw.getPlayerKarma());
update.setInt(2, cw.getPlayerPkKills());
update.setInt(3, playerId);
if (update.executeUpdate() != 1)
{
_log.warning("Error while updating karma & pkkills for userId " + cw.getPlayerId());
}
}
// clean up the cursed weapons table.
removeFromDb(itemId);
}
// Restore the player's old karma and pk count
try (PreparedStatement update = con.prepareStatement("UPDATE characters SET karma=?, pkkills=? WHERE charId=?"))
{
update.setInt(1, cw.getPlayerKarma());
update.setInt(2, cw.getPlayerPkKills());
update.setInt(3, playerId);
if (update.executeUpdate() != 1)
{
_log.warning("Error while updating karma & pkkills for userId " + cw.getPlayerId());
}
}
// clean up the cursed weapons table.
removeFromDb(itemId);
}
ps.clearParameters();
}
}
}
@@ -143,7 +143,7 @@ public class BlockList
return _blockList.contains(targetId);
}
private boolean isBlockAll()
public boolean isBlockAll()
{
return _owner.getMessageRefusal();
}
@@ -516,9 +516,9 @@ public class L2Clan implements IIdentifiable, INamable
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanLeft(exMember, this));
}
public L2ClanMember[] getMembers()
public Collection<L2ClanMember> getMembers()
{
return _members.values().toArray(new L2ClanMember[_members.size()]);
return _members.values();
}
public int getMembersCount()
@@ -22,7 +22,7 @@ import com.l2jserver.Config;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
import com.l2jserver.gameserver.network.serverpackets.AllyCrest;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeCrestLarge;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeEmblem;
import com.l2jserver.gameserver.network.serverpackets.PledgeCrest;
/**
@@ -106,7 +106,25 @@ public final class L2Crest implements IIdentifiable
}
case PLEDGE_LARGE:
{
activeChar.sendPacket(new ExPledgeCrestLarge(getId(), getData()));
final byte[] data = getData();
if (data != null)
{
for (int i = 0; i <= 4; i++)
{
if (i < 4)
{
final byte[] fullChunk = new byte[14336];
System.arraycopy(data, (14336 * i), fullChunk, 0, 14336);
activeChar.sendPacket(new ExPledgeEmblem(getId(), fullChunk, 0, i, 14336));
}
else
{
final byte[] lastChunk = new byte[8320];
System.arraycopy(data, (14336 * i), lastChunk, 0, 8320);
activeChar.sendPacket(new ExPledgeEmblem(getId(), lastChunk, 0, i, 8320));
}
}
}
path = "Crest.crest_" + Config.SERVER_ID + "_" + getId() + "_l";
break;
}
@@ -813,7 +813,7 @@ public class L2Party extends AbstractPlayerGroup
sqLevelSum += (member.getLevel() * member.getLevel());
}
final float vitalityPoints = (target.getVitalityPoints(partyDmg) * Config.RATE_PARTY_XP) / validMembers.size();
final int vitalityPoints = (int) ((target.getVitalityPoints(partyDmg) * Config.RATE_PARTY_XP) / validMembers.size());
final boolean useVitalityRate = target.useVitalityRate();
for (L2PcInstance member : rewardedMembers)
@@ -22,6 +22,7 @@ import java.util.List;
import javolution.util.FastList;
import com.l2jserver.gameserver.enums.SiegeClanType;
import com.l2jserver.gameserver.model.actor.L2Npc;
public class L2SiegeClan
@@ -31,14 +32,6 @@ public class L2SiegeClan
private int _numFlagsAdded = 0;
private SiegeClanType _type;
public enum SiegeClanType
{
OWNER,
DEFENDER,
ATTACKER,
DEFENDER_PENDING
}
public L2SiegeClan(int clanId, SiegeClanType type)
{
_clanId = clanId;
@@ -1640,7 +1640,7 @@ public class L2Attackable extends L2Npc
/*
* Return vitality points decrease (if positive) or increase (if negative) based on damage. Maximum for damage = maxHp.
*/
public float getVitalityPoints(int damage)
public int getVitalityPoints(int damage)
{
// sanity check
if (damage <= 0)
@@ -1655,7 +1655,7 @@ public class L2Attackable extends L2Npc
}
// negative value - vitality will be consumed
return -Math.min(damage, getMaxHp()) / divider;
return (int) (-Math.min(damage, getMaxHp()) / divider);
}
/*
@@ -4201,10 +4201,9 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* the L2Character position is automatically set to the destination position even if the movement is not finished.<br>
* <FONT COLOR=#FF0000><B><U>Caution</U>: The current Z position is obtained FROM THE CLIENT by the Client->Server ValidatePosition Packet.<br>
* But x and y positions must be calculated to avoid that players try to modify their movement speed.</B></FONT>
* @param gameTicks Nb of ticks since the server start
* @return True if the movement is finished
*/
public boolean updatePosition(int gameTicks)
public boolean updatePosition()
{
// Get movement data
MoveData m = _move;
@@ -4228,6 +4227,8 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
m._yAccurate = getY();
}
int gameTicks = GameTimeController.getInstance().getGameTicks();
// Check if the position has already been calculated
if (m._moveTimestamp == gameTicks)
{
@@ -4317,7 +4318,29 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
// Set the timer of last position update to now
m._moveTimestamp = gameTicks;
return (distFraction > 1);
if (distFraction > 1)
{
ThreadPoolManager.getInstance().executeAi(() ->
{
try
{
if (Config.MOVE_BASED_KNOWNLIST)
{
getKnownList().findObjects();
}
getAI().notifyEvent(CtrlEvent.EVT_ARRIVED);
}
catch (final Throwable e)
{
_log.log(Level.WARNING, "", e);
}
});
return true;
}
return false;
}
public void revalidateZone(boolean force)
@@ -342,9 +342,9 @@ public abstract class L2Vehicle extends L2Character
}
@Override
public boolean updatePosition(int gameTicks)
public boolean updatePosition()
{
final boolean result = super.updatePosition(gameTicks);
final boolean result = super.updatePosition();
for (L2PcInstance player : _passengers)
{
@@ -108,7 +108,7 @@ public final class L2GrandBossInstance extends L2MonsterInstance
}
@Override
public float getVitalityPoints(int damage)
public int getVitalityPoints(int damage)
{
return -super.getVitalityPoints(damage) / 100;
}
@@ -40,7 +40,6 @@ import java.util.Set;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
@@ -81,6 +80,7 @@ import com.l2jserver.gameserver.datatables.PlayerXpPercentLostData;
import com.l2jserver.gameserver.datatables.RecipeData;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.HtmlActionScope;
import com.l2jserver.gameserver.enums.IllegalActionPunishmentType;
@@ -168,7 +168,6 @@ import com.l2jserver.gameserver.model.actor.tasks.player.InventoryEnableTask;
import com.l2jserver.gameserver.model.actor.tasks.player.LookingForFishTask;
import com.l2jserver.gameserver.model.actor.tasks.player.PetFeedTask;
import com.l2jserver.gameserver.model.actor.tasks.player.PvPFlagTask;
import com.l2jserver.gameserver.model.actor.tasks.player.RecoBonusTaskEnd;
import com.l2jserver.gameserver.model.actor.tasks.player.RecoGiveTask;
import com.l2jserver.gameserver.model.actor.tasks.player.RentPetTask;
import com.l2jserver.gameserver.model.actor.tasks.player.ResetChargesTask;
@@ -176,7 +175,6 @@ import com.l2jserver.gameserver.model.actor.tasks.player.ResetSoulsTask;
import com.l2jserver.gameserver.model.actor.tasks.player.SitDownTask;
import com.l2jserver.gameserver.model.actor.tasks.player.StandUpTask;
import com.l2jserver.gameserver.model.actor.tasks.player.TeleportWatchdogTask;
import com.l2jserver.gameserver.model.actor.tasks.player.VitalityTask;
import com.l2jserver.gameserver.model.actor.tasks.player.WarnUserTakeBreakTask;
import com.l2jserver.gameserver.model.actor.tasks.player.WaterTask;
import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
@@ -262,6 +260,7 @@ import com.l2jserver.gameserver.network.serverpackets.CharInfo;
import com.l2jserver.gameserver.network.serverpackets.ConfirmDlg;
import com.l2jserver.gameserver.network.serverpackets.EtcStatusUpdate;
import com.l2jserver.gameserver.network.serverpackets.ExAbnormalStatusUpdateFromTarget;
import com.l2jserver.gameserver.network.serverpackets.ExAcquireAPSkillList;
import com.l2jserver.gameserver.network.serverpackets.ExAdenaInvenCount;
import com.l2jserver.gameserver.network.serverpackets.ExAutoSoulShot;
import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
@@ -272,6 +271,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExGetBookMarkInfoPacket;
import com.l2jserver.gameserver.network.serverpackets.ExGetOnAirShip;
import com.l2jserver.gameserver.network.serverpackets.ExMagicAttackInfo;
import com.l2jserver.gameserver.network.serverpackets.ExOlympiadMode;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeCount;
import com.l2jserver.gameserver.network.serverpackets.ExPrivateStoreSetWholeMsg;
import com.l2jserver.gameserver.network.serverpackets.ExSetCompassZoneCode;
import com.l2jserver.gameserver.network.serverpackets.ExStartScenePlayer;
@@ -370,9 +370,9 @@ public final class L2PcInstance extends L2Playable
private static final String DELETE_TP_BOOKMARK = "DELETE FROM character_tpbookmark WHERE charId=? AND Id=?";
// Character Subclass SQL String Definitions:
private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE charId=? ORDER BY class_index ASC";
private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (charId,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)";
private static final String UPDATE_CHAR_SUBCLASS = "UPDATE character_subclasses SET exp=?,sp=?,level=?,class_id=? WHERE charId=? AND class_index =?";
private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index,dual_class FROM character_subclasses WHERE charId=? ORDER BY class_index ASC";
private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (charId,class_id,exp,sp,level,class_index,dual_class) VALUES (?,?,?,?,?,?,?)";
private static final String UPDATE_CHAR_SUBCLASS = "UPDATE character_subclasses SET exp=?,sp=?,level=?,class_id=?,dual_class=? WHERE charId=? AND class_index =?";
private static final String DELETE_CHAR_SUBCLASS = "DELETE FROM character_subclasses WHERE charId=? AND class_index=?";
// Character Henna SQL String Definitions:
@@ -397,6 +397,8 @@ public final class L2PcInstance extends L2Playable
public static final int REQUEST_TIMEOUT = 15;
public static final String WORLD_CHAT_VARIABLE_NAME = "WORLD_CHAT_POINTS";
private final List<IEventListener> _eventListeners = new FastList<IEventListener>().shared();
public class AIAccessor extends L2Character.AIAccessor
@@ -488,9 +490,6 @@ public final class L2PcInstance extends L2Playable
private int _fame;
private ScheduledFuture<?> _fameTask;
/** Vitality recovery task */
private ScheduledFuture<?> _vitalityTask;
private volatile ScheduledFuture<?> _teleportWatchdog;
/** The Siege state of the L2PcInstance */
@@ -568,8 +567,6 @@ public final class L2PcInstance extends L2Playable
private int _recomHave; // how much I was recommended by others
/** The number of recommendation that the L2PcInstance can give */
private int _recomLeft; // how many recommendations I can give to others
/** Recommendation Bonus task **/
private ScheduledFuture<?> _recoBonusTask;
/** Recommendation task **/
private ScheduledFuture<?> _recoGiveTask;
/** Recommendation Two Hours bonus **/
@@ -1119,8 +1116,6 @@ public final class L2PcInstance extends L2Playable
// Create a L2Radar object
_radar = new L2Radar(this);
startVitalityTask();
}
@Override
@@ -5556,6 +5551,10 @@ public final class L2PcInstance extends L2Playable
increasePvpKills(target);
}
}
else if (targetPlayer.isOnDarkSide()) // Member's of Dark side can be killed without any penalty
{
increasePvpKills(target);
}
else if (targetPlayer.getPvpFlag() == 0) // Target player doesn't have karma
{
increasePkKillsAndKarma(target);
@@ -5768,8 +5767,6 @@ public final class L2PcInstance extends L2Playable
stopSoulTask();
stopChargeTask();
stopFameTask();
stopVitalityTask();
stopRecoBonusTask();
stopRecoGiveTask();
}
@@ -6173,7 +6170,7 @@ public final class L2PcInstance extends L2Playable
@Override
protected void reduceArrowCount(boolean bolts)
{
L2ItemInstance arrows = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
final L2ItemInstance arrows = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
if (arrows == null)
{
@@ -6190,6 +6187,12 @@ public final class L2PcInstance extends L2Playable
return;
}
// Infinite quiver doesn't decreases arrows upon use
if (arrows.isEtcItem() && arrows.getEtcItem().isInfinite())
{
return;
}
// Adjust item quantity
if (arrows.getCount() > 1)
{
@@ -7017,8 +7020,6 @@ public final class L2PcInstance extends L2Playable
CursedWeaponsManager.getInstance().checkPlayer(player);
player.setVitalityPoints(rset.getInt("vitality_points"), true);
// Set the x,y,z position of the L2PcInstance and make it invisible
player.setXYZInvisible(rset.getInt("x"), rset.getInt("y"), rset.getInt("z"));
@@ -7113,6 +7114,9 @@ public final class L2PcInstance extends L2Playable
final long masks = player.getVariables().getLong(COND_OVERRIDE_KEY, PcCondOverride.getAllExceptionsMask());
player.setOverrideCond(masks);
}
player.loadRecommendations();
player.startRecoGiveTask();
}
catch (Exception e)
{
@@ -7194,8 +7198,9 @@ public final class L2PcInstance extends L2Playable
subClass.setClassId(rset.getInt("class_id"));
subClass.setLevel(rset.getByte("level"));
subClass.setExp(rset.getLong("exp"));
subClass.setSp(rset.getInt("sp"));
subClass.setSp(rset.getLong("sp"));
subClass.setClassIndex(rset.getInt("class_index"));
subClass.setIsDualClass(rset.getBoolean("dual_class"));
// Enforce the correct indexing of _subClasses against their class indexes.
player.getSubClasses().put(subClass.getClassIndex(), subClass);
@@ -7470,7 +7475,7 @@ public final class L2PcInstance extends L2Playable
statement.setString(45, getName());
statement.setLong(46, 0); // unset
statement.setInt(47, getBookMarkSlot());
statement.setInt(48, getVitalityPoints());
statement.setInt(48, 0); // unset
statement.setString(49, getLang());
statement.setInt(50, getObjectId());
@@ -7500,7 +7505,7 @@ public final class L2PcInstance extends L2Playable
statement.setInt(4, subClass.getClassId());
statement.setInt(5, getObjectId());
statement.setInt(6, subClass.getClassIndex());
statement.setBoolean(7, subClass.isDualClass());
statement.execute();
statement.clearParameters();
}
@@ -9772,6 +9777,42 @@ public final class L2PcInstance extends L2Playable
return _blockList;
}
/**
* @param player
* @return returns {@code true} if player is current player cannot accepting messages from the target player, {@code false} otherwise
*/
public boolean isBlocking(L2PcInstance player)
{
return _blockList.isBlockAll() || _blockList.isInBlockList(player);
}
/**
* @param player
* @return returns {@code true} if player is current player can accepting messages from the target player, {@code false} otherwise
*/
public boolean isNotBlocking(L2PcInstance player)
{
return !_blockList.isBlockAll() && !_blockList.isInBlockList(player);
}
/**
* @param player
* @return returns {@code true} if player is target player cannot accepting messages from the current player, {@code false} otherwise
*/
public boolean isBlocked(L2PcInstance player)
{
return player.getBlockList().isBlockAll() || player.getBlockList().isInBlockList(this);
}
/**
* @param player
* @return returns {@code true} if player is target player can accepting messages from the current player, {@code false} otherwise
*/
public boolean isNotBlocked(L2PcInstance player)
{
return !player.getBlockList().isBlockAll() && !player.getBlockList().isInBlockList(this);
}
public void setHero(boolean hero)
{
if (hero && (_baseClass == _activeClass))
@@ -9956,6 +9997,10 @@ public final class L2PcInstance extends L2Playable
_noble = val;
sendSkillList();
if (val && (getLevel() == 99))
{
sendPacket(new ExAcquireAPSkillList(this));
}
}
public void setLvlJoinedAcademy(int lvl)
@@ -10092,7 +10137,8 @@ public final class L2PcInstance extends L2Playable
statement.setLong(3, newClass.getExp());
statement.setLong(4, newClass.getSp());
statement.setInt(5, newClass.getLevel());
statement.setInt(6, newClass.getClassIndex()); // <-- Added
statement.setInt(6, newClass.getClassIndex());
statement.setBoolean(7, newClass.isDualClass());
statement.execute();
}
catch (Exception e)
@@ -10203,6 +10249,24 @@ public final class L2PcInstance extends L2Playable
return _classIndex > 0;
}
public void setDualClass(int classIndex)
{
if (isSubClassActive())
{
getSubClasses().get(_classIndex).setIsDualClass(true);
}
}
public boolean isDualClassActive()
{
return isSubClassActive() && getSubClasses().get(_classIndex).isDualClass();
}
public boolean hasDualClass()
{
return getSubClasses().values().stream().anyMatch(SubClass::isDualClass);
}
public Map<Integer, SubClass> getSubClasses()
{
if (_subClasses == null)
@@ -11567,6 +11631,7 @@ public final class L2PcInstance extends L2Playable
if (getClanId() > 0)
{
getClan().broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(this), this);
getClan().broadcastToOnlineMembers(new ExPledgeCount(getClan()));
// ClanTable.getInstance().getClan(getClanId()).broadcastToOnlineMembers(new PledgeShowMemberListAdd(this));
}
@@ -12240,23 +12305,6 @@ public final class L2PcInstance extends L2Playable
}
}
public void startVitalityTask()
{
if (Config.ENABLE_VITALITY && (_vitalityTask == null))
{
_vitalityTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new VitalityTask(this), 1000, 60000);
}
}
public void stopVitalityTask()
{
if (_vitalityTask != null)
{
_vitalityTask.cancel(false);
_vitalityTask = null;
}
}
public int getPowerGrade()
{
return _powerGrade;
@@ -12541,20 +12589,12 @@ public final class L2PcInstance extends L2Playable
return getStat().getVitalityPoints();
}
/**
* @return Vitality Level
*/
public int getVitalityLevel()
{
return getStat().getVitalityLevel();
}
public void setVitalityPoints(int points, boolean quiet)
{
getStat().setVitalityPoints(points, quiet);
}
public void updateVitalityPoints(float points, boolean useRates, boolean quiet)
public void updateVitalityPoints(int points, boolean useRates, boolean quiet)
{
getStat().updateVitalityPoints(points, useRates, quiet);
}
@@ -13889,11 +13929,9 @@ public final class L2PcInstance extends L2Playable
/**
* Load L2PcInstance Recommendations data.
* @return
*/
private long loadRecommendations()
private void loadRecommendations()
{
long _time_left = 0;
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("SELECT rec_have,rec_left,time_left FROM character_reco_bonus WHERE charId=? LIMIT 1"))
{
@@ -13904,11 +13942,6 @@ public final class L2PcInstance extends L2Playable
{
setRecomHave(rset.getInt("rec_have"));
setRecomLeft(rset.getInt("rec_left"));
_time_left = rset.getLong("time_left");
}
else
{
_time_left = 3600000;
}
}
}
@@ -13916,7 +13949,6 @@ public final class L2PcInstance extends L2Playable
{
_log.log(Level.SEVERE, "Could not restore Recommendations for player: " + getObjectId(), e);
}
return _time_left;
}
/**
@@ -13924,23 +13956,17 @@ public final class L2PcInstance extends L2Playable
*/
public void storeRecommendations()
{
long recoTaskEnd = 0;
if (_recoBonusTask != null)
{
recoTaskEnd = Math.max(0, _recoBonusTask.getDelay(TimeUnit.MILLISECONDS));
}
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("INSERT INTO character_reco_bonus (charId,rec_have,rec_left,time_left) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE rec_have=?, rec_left=?, time_left=?"))
{
statement.setInt(1, getObjectId());
statement.setInt(2, getRecomHave());
statement.setInt(3, getRecomLeft());
statement.setLong(4, recoTaskEnd);
statement.setLong(4, 0);
// Update part
statement.setInt(5, getRecomHave());
statement.setInt(6, getRecomLeft());
statement.setLong(7, recoTaskEnd);
statement.setLong(7, 0);
statement.execute();
}
catch (Exception e)
@@ -13949,23 +13975,8 @@ public final class L2PcInstance extends L2Playable
}
}
public void checkRecoBonusTask()
public void startRecoGiveTask()
{
// Load data
long taskTime = loadRecommendations();
if (taskTime > 0)
{
// Add 20 recos on first login
if (taskTime == 3600000)
{
setRecomLeft(getRecomLeft() + 20);
}
// If player have some timeleft, start bonus task
_recoBonusTask = ThreadPoolManager.getInstance().scheduleGeneral(new RecoBonusTaskEnd(this), taskTime);
}
// Create task to give new recommendations
_recoGiveTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RecoGiveTask(this), 7200000, 3600000);
@@ -13973,15 +13984,6 @@ public final class L2PcInstance extends L2Playable
storeRecommendations();
}
public void stopRecoBonusTask()
{
if (_recoBonusTask != null)
{
_recoBonusTask.cancel(false);
_recoBonusTask = null;
}
}
public void stopRecoGiveTask()
{
if (_recoGiveTask != null)
@@ -14001,22 +14003,6 @@ public final class L2PcInstance extends L2Playable
_recoTwoHoursGiven = val;
}
public int getRecomBonusTime()
{
if (_recoBonusTask != null)
{
return (int) Math.max(0, _recoBonusTask.getDelay(TimeUnit.SECONDS));
}
return 0;
}
public int getRecomBonusType()
{
// Maintain = 1
return 0;
}
public void setLastPetitionGmName(String gmName)
{
_lastPetitionGmName = gmName;
@@ -14342,6 +14328,25 @@ public final class L2PcInstance extends L2Playable
}
public boolean isAwaken()
{
if (((getActiveClass() >= 139) && (getActiveClass() <= 181)) || (getActiveClass() >= 188))
{
return true;
}
return false;
}
public int getJumpTrackId()
{
return _jumpTrackId;
}
public void setJumpTrackId(int jumpTrackId)
{
_jumpTrackId = jumpTrackId;
}
/**
* @param target the target
* @return {@code true} if this player got war with the target, {@code false} otherwise.
@@ -14362,82 +14367,149 @@ public final class L2PcInstance extends L2Playable
return false;
}
/**
* Sets the beauty shop hair
* @param hairId
*/
public void setVisualHair(int hairId)
{
getVariables().set("visualHairId", hairId);
}
/**
* Sets the beauty shop hair color
* @param colorId
*/
public void setVisualHairColor(int colorId)
{
getVariables().set("visualHairColorId", colorId);
}
/**
* Sets the beauty shop modified face
* @param faceId
*/
public void setVisualFace(int faceId)
{
getVariables().set("visualFaceId", faceId);
}
/**
* @return the beauty shop hair, or his normal if not changed.
*/
public int getVisualHair()
{
return getVariables().getInt("visualHairId", getAppearance().getHairStyle());
}
/**
* @return the beauty shop hair color, or his normal if not changed.
*/
public int getVisualHairColor()
{
return getVariables().getInt("visualHairColorId", getAppearance().getHairColor());
}
/**
* @return the beauty shop modified face, or his normal if not changed.
*/
public int getVisualFace()
{
return getVariables().getInt("visualFaceId", getAppearance().getFace());
}
/**
* @return {@code true} if player has mentees, {@code false} otherwise
*/
public boolean isMentor()
{
return MentorManager.getInstance().isMentor(getObjectId());
}
/**
* @return {@code true} if player has mentor, {@code false} otherwise
*/
public boolean isMentee()
{
return MentorManager.getInstance().isMentee(getObjectId());
}
/**
* @return the amount of ability points player can spend on learning skills.
*/
public int getAbilityPoints()
{
return getVariables().getInt("ABILITY_POINTS", 0);
}
/**
* Sets the amount of ability points player can spend on learning skills.
* @param points
*/
public void setAbilityPoints(int points)
{
getVariables().set("ABILITY_POINTS", points);
}
/**
* @return how much ability points player has spend on learning skills.
*/
public int getAbilityPointsUsed()
{
return getVariables().getInt("ABILITY_POINTS_USED", 0);
}
/**
* Sets how much ability points player has spend on learning skills.
* @param points
*/
public void setAbilityPointsUsed(int points)
{
getVariables().set("ABILITY_POINTS_USED", points);
}
public boolean isAwaken()
/**
* @return The amount of times player can use world chat
*/
public int getWorldChatPoints()
{
if (((getActiveClass() >= 139) && (getActiveClass() <= 181)) || (getActiveClass() >= 188))
return getVariables().getInt(WORLD_CHAT_VARIABLE_NAME, 1);
}
/**
* Sets the amount of times player can use world chat
* @param points
*/
public void setWorldChatPoints(int points)
{
getVariables().set(WORLD_CHAT_VARIABLE_NAME, points);
}
/**
* @return Side of the player.
*/
public CastleSide getPlayerSide()
{
if ((getClan() == null) || (getClan().getCastleId() == 0))
{
return true;
return CastleSide.NEUTRAL;
}
return false;
return CastleManager.getInstance().getCastleById(getClan().getCastleId()).getSide();
}
public int getJumpTrackId()
/**
* @return {@code true} if player is on Dark side, {@code false} otherwise.
*/
public boolean isOnDarkSide()
{
return _jumpTrackId;
return getPlayerSide() == CastleSide.DARK;
}
public void setJumpTrackId(int jumpTrackId)
/**
* @return {@code true} if player is on Light side, {@code false} otherwise.
*/
public boolean isOnLightSide()
{
_jumpTrackId = jumpTrackId;
return getPlayerSide() == CastleSide.LIGHT;
}
}
@@ -157,7 +157,7 @@ public class L2RaidBossInstance extends L2MonsterInstance
}
@Override
public float getVitalityPoints(int damage)
public int getVitalityPoints(int damage)
{
return -super.getVitalityPoints(damage) / 100;
}
@@ -129,7 +129,7 @@ public final class L2TeleporterInstance extends L2Npc
finalName = "<fstring>" + loc.getNpcStringId().getId() + "</fstring>";
confirmDesc = "F;" + loc.getNpcStringId().getId();
}
if (shouldPayFee(player, loc))
if (shouldPayFee(player, type, loc))
{
finalName += " - " + calculateFee(player, type, loc) + " " + getItemName(loc.getFeeId(), true);
}
@@ -192,7 +192,7 @@ public final class L2TeleporterInstance extends L2Npc
{
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
}
else if (shouldPayFee(player, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), calculateFee(player, type, loc), this, true))
else if (shouldPayFee(player, type, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), calculateFee(player, type, loc), this, true))
{
if (loc.getFeeId() == Inventory.ADENA_ID)
{
@@ -227,13 +227,13 @@ public final class L2TeleporterInstance extends L2Npc
*/
private long calculateFee(L2PcInstance player, TeleportType type, TeleportLocation loc)
{
if (player.getLevel() < 77)
{
return 0;
}
if (type == TeleportType.NORMAL)
{
if (!player.isSubClassActive() && (player.getLevel() < 77))
{
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);
@@ -242,13 +242,12 @@ public final class L2TeleporterInstance extends L2Npc
return loc.getFeeCount() / 2;
}
}
return loc.getFeeCount();
}
protected boolean shouldPayFee(L2PcInstance player, TeleportLocation loc)
protected boolean shouldPayFee(L2PcInstance player, TeleportType type, TeleportLocation loc)
{
return Config.ALT_GAME_FREE_TELEPORT || ((player.getLevel() >= 76) && ((loc.getFeeId() != 0) && (loc.getFeeCount() > 0)));
return (type != TeleportType.NORMAL) || (!Config.ALT_GAME_FREE_TELEPORT && ((player.getLevel() > 76) || player.isSubClassActive()) && ((loc.getFeeId() != 0) && (loc.getFeeCount() > 0)));
}
protected int parseNextInt(StringTokenizer st, int defaultVal)
@@ -31,7 +31,6 @@ import com.l2jserver.gameserver.model.actor.instance.L2ClassMasterInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
import com.l2jserver.gameserver.model.entity.RecoBonus;
import com.l2jserver.gameserver.model.events.EventDispatcher;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLevelChanged;
import com.l2jserver.gameserver.model.stats.Formulas;
@@ -40,6 +39,7 @@ import com.l2jserver.gameserver.model.stats.Stats;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.AcquireSkillList;
import com.l2jserver.gameserver.network.serverpackets.ExAcquireAPSkillList;
import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
import com.l2jserver.gameserver.network.serverpackets.ExVitalityPointInfo;
import com.l2jserver.gameserver.network.serverpackets.ExVoteSystemInfo;
@@ -57,8 +57,6 @@ public class PcStat extends PlayableStat
private int _oldMaxHp; // stats watch
private int _oldMaxMp; // stats watch
private int _oldMaxCp; // stats watch
private float _vitalityPoints = 1;
private byte _vitalityLevel = 0;
private long _startingXp;
/** Player's maximum cubic count. */
private int _maxCubicCount = 1;
@@ -66,17 +64,9 @@ public class PcStat extends PlayableStat
private final AtomicInteger _talismanSlots = new AtomicInteger();
private boolean _cloakSlot = false;
public static final int VITALITY_LEVELS[] =
{
240,
2000,
13000,
17000,
20000
};
public static final int MAX_VITALITY_POINTS = VITALITY_LEVELS[4];
public static final int MAX_VITALITY_POINTS = 140000;
public static final int MIN_VITALITY_POINTS = 1;
public static String VITALITY_VARIABLE = "vitality_points";
public PcStat(L2PcInstance activeChar)
{
@@ -316,7 +306,6 @@ public class PcStat extends PlayableStat
getActiveChar().sendPacket(new UserInfo(getActiveChar()));
// Send acquirable skill list
getActiveChar().sendPacket(new AcquireSkillList(getActiveChar()));
getActiveChar().sendPacket(new ExBrExtraUserInfo(getActiveChar()));
getActiveChar().sendPacket(new ExVoteSystemInfo(getActiveChar()));
if (getActiveChar().isInParty())
{
@@ -324,6 +313,10 @@ public class PcStat extends PlayableStat
partyWindow.addUpdateType(PartySmallWindowUpdateType.LEVEL);
getActiveChar().getParty().broadcastToPartyMembers(getActiveChar(), partyWindow);
}
if ((getLevel() == 99) && getActiveChar().isNoble())
{
getActiveChar().sendPacket(new ExAcquireAPSkillList(getActiveChar()));
}
return levelIncreased;
}
@@ -655,60 +648,17 @@ public class PcStat extends PlayableStat
return val;
}
private void updateVitalityLevel(boolean quiet)
{
final byte level;
if (_vitalityPoints <= VITALITY_LEVELS[0])
{
level = 0;
}
else if (_vitalityPoints <= VITALITY_LEVELS[1])
{
level = 1;
}
else if (_vitalityPoints <= VITALITY_LEVELS[2])
{
level = 2;
}
else if (_vitalityPoints <= VITALITY_LEVELS[3])
{
level = 3;
}
else
{
level = 4;
}
if (!quiet && (level != _vitalityLevel))
{
if (level < _vitalityLevel)
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_HAS_DECREASED);
}
else
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_HAS_INCREASED);
}
if (level == 0)
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_IS_FULLY_EXHAUSTED);
}
else if (level == 4)
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_IS_AT_MAXIMUM);
}
}
_vitalityLevel = level;
}
/*
* Return current vitality points in integer format
*/
public int getVitalityPoints()
{
return (int) _vitalityPoints;
return getActiveChar().getAccountVariables().getInt(VITALITY_VARIABLE, Config.STARTING_VITALITY_POINTS);
}
public void setVitalityPoints(int points)
{
getActiveChar().getAccountVariables().set(VITALITY_VARIABLE, points);
}
/*
@@ -717,13 +667,31 @@ public class PcStat extends PlayableStat
public void setVitalityPoints(int points, boolean quiet)
{
points = Math.min(Math.max(points, MIN_VITALITY_POINTS), MAX_VITALITY_POINTS);
if (points == _vitalityPoints)
if (points == getVitalityPoints())
{
return;
}
_vitalityPoints = points;
updateVitalityLevel(quiet);
if (points < getVitalityPoints())
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_HAS_DECREASED);
}
else
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_HAS_INCREASED);
}
setVitalityPoints(points);
if (points == 0)
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_IS_FULLY_EXHAUSTED);
}
else if (points == MAX_VITALITY_POINTS)
{
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_IS_AT_MAXIMUM);
}
final L2PcInstance player = getActiveChar();
player.sendPacket(new ExVitalityPointInfo(getVitalityPoints()));
if (player.isInParty())
@@ -734,7 +702,7 @@ public class PcStat extends PlayableStat
}
}
public synchronized void updateVitalityPoints(float points, boolean useRates, boolean quiet)
public synchronized void updateVitalityPoints(int points, boolean useRates, boolean quiet)
{
if ((points == 0) || !Config.ENABLE_VITALITY)
{
@@ -776,73 +744,35 @@ public class PcStat extends PlayableStat
if (points > 0)
{
points = Math.min(_vitalityPoints + points, MAX_VITALITY_POINTS);
points = Math.min(getVitalityPoints() + points, MAX_VITALITY_POINTS);
}
else
{
points = Math.max(_vitalityPoints + points, MIN_VITALITY_POINTS);
points = Math.max(getVitalityPoints() + points, MIN_VITALITY_POINTS);
}
if (Math.abs(points - _vitalityPoints) <= 1e-6)
if (Math.abs(points - getVitalityPoints()) <= 1e-6)
{
return;
}
_vitalityPoints = points;
updateVitalityLevel(quiet);
setVitalityPoints(points);
}
public double getVitalityMultiplier()
{
double vitality = 1.0;
if (Config.ENABLE_VITALITY)
{
switch (getVitalityLevel())
{
case 1:
vitality = Config.RATE_VITALITY_LEVEL_1;
break;
case 2:
vitality = Config.RATE_VITALITY_LEVEL_2;
break;
case 3:
vitality = Config.RATE_VITALITY_LEVEL_3;
break;
case 4:
vitality = Config.RATE_VITALITY_LEVEL_4;
break;
}
}
return vitality;
}
/**
* @return the _vitalityLevel
*/
public byte getVitalityLevel()
{
return _vitalityLevel;
return Config.ENABLE_VITALITY ? Config.RATE_VITALITY_EXP_MULTIPLIER : 1;
}
public double getExpBonusMultiplier()
{
double bonus = 1.0;
double vitality = 1.0;
double nevits = 1.0;
double hunting = 1.0;
double bonusExp = 1.0;
// Bonus from Vitality System
vitality = getVitalityMultiplier();
// Bonus from Nevit's Blessing
nevits = RecoBonus.getRecoMultiplier(getActiveChar());
// Bonus from Nevit's Hunting
// TODO: Nevit's hunting bonus
// Bonus exp from skills
bonusExp = 1 + (calcStat(Stats.BONUS_EXP, 0, null, null) / 100);
@@ -850,14 +780,7 @@ public class PcStat extends PlayableStat
{
bonus += (vitality - 1);
}
if (nevits > 1.0)
{
bonus += (nevits - 1);
}
if (hunting > 1.0)
{
bonus += (hunting - 1);
}
if (bonusExp > 1)
{
bonus += (bonusExp - 1);
@@ -874,19 +797,11 @@ public class PcStat extends PlayableStat
{
double bonus = 1.0;
double vitality = 1.0;
double nevits = 1.0;
double hunting = 1.0;
double bonusSp = 1.0;
// Bonus from Vitality System
vitality = getVitalityMultiplier();
// Bonus from Nevit's Blessing
nevits = RecoBonus.getRecoMultiplier(getActiveChar());
// Bonus from Nevit's Hunting
// TODO: Nevit's hunting bonus
// Bonus sp from skills
bonusSp = 1 + (calcStat(Stats.BONUS_SP, 0, null, null) / 100);
@@ -894,14 +809,7 @@ public class PcStat extends PlayableStat
{
bonus += (vitality - 1);
}
if (nevits > 1.0)
{
bonus += (nevits - 1);
}
if (hunting > 1.0)
{
bonus += (hunting - 1);
}
if (bonusSp > 1)
{
bonus += (bonusSp - 1);
@@ -18,6 +18,9 @@
*/
package com.l2jserver.gameserver.model.base;
import java.util.HashSet;
import java.util.Set;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
@@ -265,6 +268,9 @@ public enum ClassId implements IIdentifiable
/** The parent ClassId or null if this class is a root */
private final ClassId _parent;
/** List of available Class for next transfer **/
private final Set<ClassId> _nextClassIds = new HashSet<>(1);
/**
* Class constructor.
* @param pId the class Id.
@@ -279,6 +285,11 @@ public enum ClassId implements IIdentifiable
_isSummoner = false;
_race = race;
_parent = pParent;
if (_parent != null)
{
_parent.addNextClassId(this);
}
}
/**
@@ -296,6 +307,11 @@ public enum ClassId implements IIdentifiable
_isSummoner = pIsSummoner;
_race = race;
_parent = pParent;
if (_parent != null)
{
_parent.addNextClassId(this);
}
}
/**
@@ -382,6 +398,14 @@ public enum ClassId implements IIdentifiable
return _parent;
}
/**
* @return list of possible class transfer for this class
*/
public Set<ClassId> getNextClassIds()
{
return _nextClassIds;
}
public static ClassId getClassId(int cId)
{
try
@@ -393,4 +417,9 @@ public enum ClassId implements IIdentifiable
return null;
}
}
private final void addNextClassId(ClassId cId)
{
_nextClassIds.add(cId);
}
}
@@ -35,22 +35,7 @@ public final class SubClass
private long _sp = 0;
private byte _level = Config.BASE_SUBCLASS_LEVEL;
private int _classIndex = 1;
public SubClass(int classId, long exp, int sp, byte level, int classIndex)
{
_class = PlayerClass.values()[classId];
_exp = exp;
_sp = sp;
_level = level;
_classIndex = classIndex;
}
public SubClass(int classId, int classIndex)
{
// Used for defining a sub class using default values for XP, SP and player level.
_class = PlayerClass.values()[classId];
_classIndex = classIndex;
}
private boolean _dualClass = false;
public SubClass()
{
@@ -117,9 +102,19 @@ public final class SubClass
_classIndex = classIndex;
}
public boolean isDualClass()
{
return _dualClass;
}
public void setIsDualClass(boolean dualClass)
{
_dualClass = dualClass;
}
public void setLevel(byte levelValue)
{
if (levelValue > _maxLevel)
if (!_dualClass && (levelValue > _maxLevel))
{
levelValue = _maxLevel;
}
@@ -133,7 +128,7 @@ public final class SubClass
public void incLevel()
{
if (getLevel() == _maxLevel)
if (!_dualClass && (getLevel() == _maxLevel))
{
return;
}
@@ -152,4 +147,4 @@ public final class SubClass
_level--;
setExp(ExperienceTable.getInstance().getExpForLevel(getLevel()));
}
}
}
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.model.conditions;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.model.actor.L2Character;
import com.l2jserver.gameserver.model.items.L2Item;
import com.l2jserver.gameserver.model.skills.Skill;
/**
* The Class ConditionPlayerIsOnSide.
* @author St3eT
*/
public class ConditionPlayerIsOnSide extends Condition
{
private final CastleSide _side;
/**
* Instantiates a new condition player race.
* @param side the allowed Castle side.
*/
public ConditionPlayerIsOnSide(CastleSide side)
{
_side = side;
}
@Override
public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item)
{
if ((effector == null) || !effector.isPlayer())
{
return false;
}
return effector.getActingPlayer().getPlayerSide() == _side;
}
}
@@ -25,6 +25,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -33,8 +34,11 @@ import javolution.util.FastMap;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.CastleData;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.datatables.DoorTable;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.enums.MountType;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.instancemanager.CastleManorManager;
@@ -43,31 +47,40 @@ import com.l2jserver.gameserver.instancemanager.SiegeManager;
import com.l2jserver.gameserver.instancemanager.ZoneManager;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.TowerSpawn;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2ArtefactInstance;
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jserver.gameserver.model.holders.CastleSpawnHolder;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
import com.l2jserver.gameserver.model.skills.CommonSkill;
import com.l2jserver.gameserver.model.skills.Skill;
import com.l2jserver.gameserver.model.zone.type.L2CastleZone;
import com.l2jserver.gameserver.model.zone.type.L2ResidenceTeleportZone;
import com.l2jserver.gameserver.model.zone.type.L2SiegeZone;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExCastleState;
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
import com.l2jserver.gameserver.network.serverpackets.PledgeShowInfoUpdate;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.util.Broadcast;
public final class Castle extends AbstractResidence
{
protected static final Logger _log = Logger.getLogger(Castle.class.getName());
private final List<L2DoorInstance> _doors = new ArrayList<>();
private final List<L2Npc> _sideNpcs = new ArrayList<>();
private int _ownerId = 0;
private Siege _siege = null;
private Calendar _siegeDate;
private boolean _isTimeRegistrationOver = true; // true if Castle Lords set the time, or 24h is elapsed after the siege
private Calendar _siegeTimeRegistrationEndDate; // last siege end date + 1 day
private int _taxPercent = 0;
private double _taxRate = 0;
private CastleSide _castleSide = null;
private double _taxRate;
private long _treasury = 0;
private boolean _showNpcCrest = false;
private L2SiegeZone _zone = null;
@@ -231,11 +244,9 @@ public final class Castle extends AbstractResidence
{
super(castleId);
load();
/*
* if (getResidenceId() == 7 || castleId == 9) // Goddard and Schuttgart _nbArtifact = 2;
*/
_function = new FastMap<>();
initResidenceZone();
spawnSideNpcs();
if (getOwnerId() != 0)
{
loadFunctions();
@@ -257,15 +268,17 @@ public final class Castle extends AbstractResidence
return null;
}
public synchronized void engrave(L2Clan clan, L2Object target)
public synchronized void engrave(L2Clan clan, L2Object target, CastleSide side)
{
if (!_artefacts.contains(target))
{
return;
}
setSide(side);
setOwner(clan);
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.CLAN_S1_HAS_SUCCEEDED_IN_S2);
msg.addString(clan.getName());
msg.addString(getName());
getSiege().announceToPlayer(msg, true);
}
@@ -282,34 +295,42 @@ public final class Castle extends AbstractResidence
return;
}
if (getName().equalsIgnoreCase("Schuttgart") || getName().equalsIgnoreCase("Goddard"))
switch (getName().toLowerCase())
{
Castle rune = CastleManager.getInstance().getCastle("rune");
if (rune != null)
case "schuttgart":
case "goddard":
{
long runeTax = (long) (amount * rune.getTaxRate());
if (rune.getOwnerId() > 0)
final Castle rune = CastleManager.getInstance().getCastle("rune");
if (rune != null)
{
rune.addToTreasury(runeTax);
final long runeTax = (long) (amount * rune.getTaxRate());
if (rune.getOwnerId() > 0)
{
rune.addToTreasury(runeTax);
}
amount -= runeTax;
}
amount -= runeTax;
break;
}
case "dion":
case "giran":
case "gludio":
case "innadril":
case "oren":
{
final Castle aden = CastleManager.getInstance().getCastle("aden");
if (aden != null)
{
final long adenTax = (long) (amount * aden.getTaxRate()); // Find out what Aden gets from the current castle instance's income
if (aden.getOwnerId() > 0)
{
aden.addToTreasury(adenTax); // Only bother to really add the tax to the treasury if not npc owned
}
amount -= adenTax; // Subtract Aden's income from current castle instance's income
}
break;
}
}
if (!getName().equalsIgnoreCase("aden") && !getName().equalsIgnoreCase("Rune") && !getName().equalsIgnoreCase("Schuttgart") && !getName().equalsIgnoreCase("Goddard")) // If current castle instance is not Aden, Rune, Goddard or Schuttgart.
{
Castle aden = CastleManager.getInstance().getCastle("aden");
if (aden != null)
{
long adenTax = (long) (amount * aden.getTaxRate()); // Find out what Aden gets from the current castle instance's income
if (aden.getOwnerId() > 0)
{
aden.addToTreasury(adenTax); // Only bother to really add the tax to the treasury if not npc owned
}
amount -= adenTax; // Subtract Aden's income from current castle instance's income
}
}
addToTreasuryNoTax(amount);
}
@@ -513,6 +534,7 @@ public final class Castle extends AbstractResidence
{
removeResidentialSkills(member);
member.sendSkillList();
member.broadcastUserInfo();
}
}
}
@@ -559,6 +581,7 @@ public final class Castle extends AbstractResidence
clan.broadcastToOnlineMembers(new PledgeShowInfoUpdate(clan));
}
setSide(CastleSide.NEUTRAL);
updateOwnerInDB(null);
if (getSiege().isInProgress())
{
@@ -572,24 +595,6 @@ public final class Castle extends AbstractResidence
_function.clear();
}
public void setTaxPercent(int taxPercent)
{
_taxPercent = taxPercent;
_taxRate = _taxPercent / 100.0;
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE castle SET taxPercent = ? WHERE id = ?"))
{
ps.setInt(1, taxPercent);
ps.setInt(2, getResidenceId());
ps.execute();
}
catch (Exception e)
{
_log.log(Level.WARNING, e.getMessage(), e);
}
}
/**
* Respawn all doors on castle grounds.
*/
@@ -642,7 +647,8 @@ public final class Castle extends AbstractResidence
_siegeTimeRegistrationEndDate.setTimeInMillis(rs.getLong("regTimeEnd"));
_isTimeRegistrationOver = rs.getBoolean("regTimeOver");
_taxPercent = rs.getInt("taxPercent");
_castleSide = Enum.valueOf(CastleSide.class, rs.getString("side"));
_treasury = rs.getLong("treasury");
_showNpcCrest = rs.getBoolean("showNpcCrest");
@@ -650,8 +656,8 @@ public final class Castle extends AbstractResidence
_ticketBuyCount = rs.getInt("ticketBuyCount");
}
}
_taxRate = _taxPercent / 100.0;
setTaxRate(getTaxPercent() / 100);
ps2.setInt(1, getResidenceId());
try (ResultSet rs = ps2.executeQuery())
{
@@ -945,7 +951,25 @@ public final class Castle extends AbstractResidence
public final int getTaxPercent()
{
return _taxPercent;
final int taxPercent;
switch (getSide())
{
case LIGHT:
taxPercent = Config.CASTLE_TAX_LIGHT;
break;
case DARK:
taxPercent = Config.CASTLE_TAX_DARK;
break;
default:
taxPercent = Config.CASTLE_TAX_NEUTRAL;
break;
}
return taxPercent;
}
public void setTaxRate(double taxRate)
{
_taxRate = taxRate;
}
public final double getTaxRate()
@@ -1122,9 +1146,90 @@ public final class Castle extends AbstractResidence
}
}
// TODO: Implement me
public int getState()
@Override
public void giveResidentialSkills(L2PcInstance player)
{
return 1;
super.giveResidentialSkills(player);
final Skill skill = getSide() == CastleSide.DARK ? CommonSkill.ABILITY_OF_DARKNESS.getSkill() : CommonSkill.ABILITY_OF_LIGHT.getSkill();
player.addSkill(skill);
}
@Override
public void removeResidentialSkills(L2PcInstance player)
{
super.removeResidentialSkills(player);
player.removeSkill(CommonSkill.ABILITY_OF_DARKNESS.getId());
player.removeSkill(CommonSkill.ABILITY_OF_LIGHT.getId());
}
public void spawnSideNpcs()
{
_sideNpcs.stream().filter(Objects::nonNull).forEach(L2Npc::deleteMe);
_sideNpcs.clear();
for (CastleSpawnHolder holder : getSideSpawns())
{
if (holder != null)
{
final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(holder.getNpcId());
if (npcTemplate == null)
{
_log.warning(Castle.class.getSimpleName() + ": Spawn of the nonexisting NPC ID: " + holder.getNpcId());
return;
}
L2Spawn spawn;
try
{
spawn = new L2Spawn(npcTemplate);
}
catch (Exception e)
{
_log.warning(Castle.class.getSimpleName() + ": " + e.getMessage());
return;
}
spawn.setX(holder.getX());
spawn.setY(holder.getY());
spawn.setZ(holder.getZ());
spawn.setHeading(holder.getHeading());
final L2Npc npc = spawn.doSpawn(false);
npc.broadcastInfo();
_sideNpcs.add(npc);
}
}
}
public List<CastleSpawnHolder> getSideSpawns()
{
return CastleData.getInstance().getSpawnsForSide(getResidenceId(), getSide());
}
public void setSide(CastleSide side)
{
if (_castleSide == side)
{
return;
}
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE castle SET side = ? WHERE id = ?"))
{
ps.setString(1, side.toString());
ps.setInt(2, getResidenceId());
ps.execute();
}
catch (Exception e)
{
_log.log(Level.WARNING, e.getMessage(), e);
}
_castleSide = side;
setTaxRate(getTaxPercent() / 100);
Broadcast.toAllOnlinePlayers(new ExCastleState(this));
spawnSideNpcs();
}
public CastleSide getSide()
{
return _castleSide;
}
}
@@ -35,6 +35,7 @@ import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.enums.FortTeleportWhoType;
import com.l2jserver.gameserver.enums.SiegeClanType;
import com.l2jserver.gameserver.instancemanager.FortManager;
import com.l2jserver.gameserver.instancemanager.FortSiegeGuardManager;
import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
@@ -43,7 +44,6 @@ import com.l2jserver.gameserver.model.FortSiegeSpawn;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.L2SiegeClan;
import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.TeleportWhereType;
@@ -86,10 +86,14 @@ public class Message
_returned = rset.getBoolean("isReturned");
_itemId = rset.getInt("itemId");
_enchantLvl = rset.getInt("enchantLvl");
final String[] elemDef = rset.getString("elementals").split(";");
for (int i = 0; i < 6; i++)
final String elemental = rset.getString("elementals");
if (elemental != null)
{
_elementals[i] = Integer.parseInt(elemDef[i]);
final String[] elemDef = elemental.split(";");
for (int i = 0; i < 6; i++)
{
_elementals[i] = Integer.parseInt(elemDef[i]);
}
}
}
@@ -1,162 +0,0 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.model.entity;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
/**
* @author Gnacik
*/
public final class RecoBonus
{
private static final int[][] _recoBonus =
{
{
25,
50,
50,
50,
50,
50,
50,
50,
50,
50
},
{
16,
33,
50,
50,
50,
50,
50,
50,
50,
50
},
{
12,
25,
37,
50,
50,
50,
50,
50,
50,
50
},
{
10,
20,
30,
40,
50,
50,
50,
50,
50,
50
},
{
8,
16,
25,
33,
41,
50,
50,
50,
50,
50
},
{
7,
14,
21,
28,
35,
42,
50,
50,
50,
50
},
{
6,
12,
18,
25,
31,
37,
43,
50,
50,
50
},
{
5,
11,
16,
22,
27,
33,
38,
44,
50,
50
},
{
5,
10,
15,
20,
25,
30,
35,
40,
45,
50
}
};
public static int getRecoBonus(L2PcInstance activeChar)
{
if ((activeChar != null) && activeChar.isOnline() && (activeChar.getRecomHave() != 0))
{
final int lvl = activeChar.getLevel() / 10;
final int exp = (Math.min(100, activeChar.getRecomHave()) - 1) / 10;
return _recoBonus[lvl][exp];
}
return 0;
}
public static double getRecoMultiplier(L2PcInstance activeChar)
{
double multiplier = 1.0;
final double bonus = getRecoBonus(activeChar);
if (bonus > 0)
{
multiplier += (bonus / 100);
}
return multiplier;
}
}
@@ -38,6 +38,7 @@ import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.datatables.SiegeScheduleData;
import com.l2jserver.gameserver.enums.SiegeClanType;
import com.l2jserver.gameserver.enums.SiegeTeleportWhoType;
import com.l2jserver.gameserver.instancemanager.CastleManager;
import com.l2jserver.gameserver.instancemanager.MercTicketManager;
@@ -47,7 +48,6 @@ import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2ClanMember;
import com.l2jserver.gameserver.model.L2Object;
import com.l2jserver.gameserver.model.L2SiegeClan;
import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.PcCondOverride;
import com.l2jserver.gameserver.model.SiegeScheduleDate;
@@ -299,6 +299,11 @@ public class Siege implements Siegable
continue;
}
for (L2PcInstance member : clan.getOnlineMembers(0))
{
member.checkItemRestriction();
}
clan.clearSiegeKills();
clan.clearSiegeDeaths();
}
@@ -311,6 +316,11 @@ public class Siege implements Siegable
continue;
}
for (L2PcInstance member : clan.getOnlineMembers(0))
{
member.checkItemRestriction();
}
clan.clearSiegeKills();
clan.clearSiegeDeaths();
}
@@ -35,11 +35,11 @@ import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.datatables.NpcData;
import com.l2jserver.gameserver.enums.SiegeClanType;
import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
import com.l2jserver.gameserver.instancemanager.MapRegionManager;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2SiegeClan;
import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.Location;
@@ -24,9 +24,9 @@ import java.util.Calendar;
import java.util.logging.Level;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.enums.SiegeClanType;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2SiegeClan;
import com.l2jserver.gameserver.model.L2SiegeClan.SiegeClanType;
import com.l2jserver.gameserver.model.StatsSet;
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
@@ -125,6 +125,7 @@ import com.l2jserver.gameserver.model.stats.Stats;
import com.l2jserver.gameserver.model.zone.L2ZoneType;
import com.l2jserver.gameserver.network.NpcStringId;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExAdenaInvenCount;
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoInvenWeight;
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
@@ -2106,6 +2107,7 @@ public abstract class AbstractScript extends ManagedScript
}
// send packets
player.sendPacket(new ExUserInfoInvenWeight(player));
player.sendPacket(new ExAdenaInvenCount(player));
}
/**
@@ -49,6 +49,7 @@ import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAtt
import com.l2jserver.gameserver.model.events.impl.character.playable.OnPlayableExpChanged;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerAugment;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerBypass;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerChangeToAwakenedClass;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerChat;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerCreate;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerDelete;
@@ -216,6 +217,7 @@ public enum EventType
ON_PLAYER_LOGOUT(OnPlayerLogout.class, void.class),
ON_PLAYER_PK_CHANGED(OnPlayerPKChanged.class, void.class),
ON_PLAYER_PROFESSION_CHANGE(OnPlayerProfessionChange.class, void.class),
ON_PLAYER_CHANGE_TO_AWAKENED_CLASS(OnPlayerChangeToAwakenedClass.class, void.class),
ON_PLAYER_PVP_CHANGED(OnPlayerPvPChanged.class, void.class),
ON_PLAYER_PVP_KILL(OnPlayerPvPKill.class, void.class),
ON_PLAYER_RESTORE(OnPlayerRestore.class, void.class),
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.model.events.impl.character.player;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.events.EventType;
import com.l2jserver.gameserver.model.events.impl.IBaseEvent;
/**
* @author Sdw
*/
public final class OnPlayerChangeToAwakenedClass implements IBaseEvent
{
private final L2PcInstance _activeChar;
public OnPlayerChangeToAwakenedClass(L2PcInstance activeChar)
{
_activeChar = activeChar;
}
public L2PcInstance getActiveChar()
{
return _activeChar;
}
@Override
public EventType getType()
{
return EventType.ON_PLAYER_CHANGE_TO_AWAKENED_CLASS;
}
}
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.model.holders;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.model.Location;
/**
* @author St3eT
*/
public class CastleSpawnHolder extends Location
{
private final int _npcId;
private final CastleSide _side;
public CastleSpawnHolder(int npcId, CastleSide side, int x, int y, int z, int heading)
{
super(x, y, z, heading);
_npcId = npcId;
_side = side;
}
public final int getNpcId()
{
return _npcId;
}
public final CastleSide getSide()
{
return _side;
}
}
@@ -36,6 +36,7 @@ public final class L2EtcItem extends L2Item
private EtcItemType _type;
private final boolean _isBlessed;
private final List<L2ExtractableProduct> _extractableItems;
private final boolean _isInfinite;
/**
* Constructor for EtcItem.
@@ -117,6 +118,8 @@ public final class L2EtcItem extends L2Item
{
_extractableItems = null;
}
_isInfinite = set.getBoolean("is_infinite", false);
}
/**
@@ -160,4 +163,12 @@ public final class L2EtcItem extends L2Item
{
return _extractableItems;
}
/**
* @return true if item is infinite
*/
public boolean isInfinite()
{
return _isInfinite;
}
}
@@ -51,7 +51,11 @@ public enum CommonSkill
DIVINE_INSPIRATION(1405, 1),
SERVITOR_SHARE(1557, 1),
CARAVANS_SECRET_MEDICINE(2341, 1),
SHILENS_BREATH(14571, 1);
SHILENS_BREATH(14571, 1),
IMPRIT_OF_LIGHT(19034, 1),
IMPRIT_OF_DARKNESS(19035, 1),
ABILITY_OF_LIGHT(19032, 1),
ABILITY_OF_DARKNESS(19033, 1);
private final SkillHolder _holder;
@@ -74,4 +78,4 @@ public enum CommonSkill
{
return _holder.getSkill();
}
}
}
File diff suppressed because it is too large Load Diff
@@ -9508,7 +9508,7 @@ public final class SystemMessageId
@ClientString(id = 3306, message = "You are declaring Clan War against $s1. If you withdraw from the war, your clan will lose 5,000 Reputation points. Proceed?")
public static SystemMessageId YOU_ARE_DECLARING_CLAN_WAR_AGAINST_S1_IF_YOU_WITHDRAW_FROM_THE_WAR_YOUR_CLAN_WILL_LOSE_5_000_REPUTATION_POINTS_PROCEED;
@ClientString(id = 3307, message = "$s1 will be deleted from Friend List.nDo you want to continue?")
@ClientString(id = 3307, message = "$s1 will be deleted from Friend List.nDo you want to continue?")
public static SystemMessageId S1_WILL_BE_DELETED_FROM_FRIEND_LIST_NDO_YOU_WANT_TO_CONTINUE;
@ClientString(id = 3308, message = "No character is selected to add to the list. Please select a character.")
@@ -14167,4 +14167,4 @@ public final class SystemMessageId
return _builder.toString(params);
}
}
}
}
@@ -71,6 +71,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExNewSkillToLearnByLevelUp
import com.l2jserver.gameserver.network.serverpackets.ExNoticePostArrived;
import com.l2jserver.gameserver.network.serverpackets.ExNotifyPremiumItem;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeCount;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeWaitingListAlarm;
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
import com.l2jserver.gameserver.network.serverpackets.ExShowUsm;
import com.l2jserver.gameserver.network.serverpackets.ExStorageMaxCount;
@@ -80,6 +81,7 @@ import com.l2jserver.gameserver.network.serverpackets.ExUserInfoEquipSlot;
import com.l2jserver.gameserver.network.serverpackets.ExUserInfoInvenWeight;
import com.l2jserver.gameserver.network.serverpackets.ExVitalityEffectInfo;
import com.l2jserver.gameserver.network.serverpackets.ExVoteSystemInfo;
import com.l2jserver.gameserver.network.serverpackets.ExWorldChatCnt;
import com.l2jserver.gameserver.network.serverpackets.HennaInfo;
import com.l2jserver.gameserver.network.serverpackets.ItemList;
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
@@ -358,9 +360,13 @@ public class EnterWorld extends L2GameClientPacket
final L2Clan clan = activeChar.getClan();
clan.broadcastToOnlineMembers(new PledgeShowMemberListUpdate(activeChar));
sendPacket(new PledgeShowMemberListAll(clan));
activeChar.sendPacket(new ExPledgeCount(clan));
clan.broadcastToOnlineMembers(new ExPledgeCount(clan));
activeChar.sendPacket(new PledgeSkillList(clan));
}
else
{
activeChar.sendPacket(ExPledgeWaitingListAlarm.STATIC_PACKET);
}
activeChar.broadcastUserInfo();
@@ -594,6 +600,7 @@ public class EnterWorld extends L2GameClientPacket
}
activeChar.sendPacket(new ExAcquireAPSkillList(activeChar));
activeChar.sendPacket(new ExWorldChatCnt(activeChar));
}
/**
@@ -23,6 +23,7 @@ import java.util.List;
import com.l2jserver.Config;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.IllegalActionPunishmentType;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.enums.UserInfoType;
@@ -74,6 +75,18 @@ public final class RequestAcquireSkill extends L2GameClientPacket
"ClassAbility80-"
};
private static final String[] REVELATION_VAR_NAMES =
{
"RevelationSkill1",
"RevelationSkill2"
};
private static final String[] DUALCLASS_REVELATION_VAR_NAMES =
{
"DualclassRevelationSkill1",
"DualclassRevelationSkill2"
};
private int _id;
private int _level;
private AcquireSkillType _skillType;
@@ -414,6 +427,91 @@ public final class RequestAcquireSkill extends L2GameClientPacket
break;
}
case REVELATION:
{
if (activeChar.isSubClassActive())
{
activeChar.sendPacket(SystemMessageId.THIS_SKILL_CANNOT_BE_LEARNED_WHILE_IN_THE_SUBCLASS_STATE_PLEASE_TRY_AGAIN_AFTER_CHANGING_TO_THE_MAIN_CLASS);
Util.handleIllegalPlayerAction(activeChar, "Player " + activeChar.getName() + " is requesting skill Id: " + _id + " level " + _level + " while Sub-Class is active!", IllegalActionPunishmentType.NONE);
return;
}
if ((activeChar.getLevel() < 85) || !activeChar.isInCategory(CategoryType.AWAKEN_GROUP))
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_THE_NECESSARY_MATERIALS_OR_PREREQUISITES_TO_LEARN_THIS_SKILL);
Util.handleIllegalPlayerAction(activeChar, "Player " + activeChar.getName() + " is requesting skill Id: " + _id + " level " + _level + " while not being level 85 or awaken!", IllegalActionPunishmentType.NONE);
return;
}
int count = 0;
for (String varName : REVELATION_VAR_NAMES)
{
if (activeChar.getVariables().getInt(varName, 0) > 0)
{
count++;
}
}
if (count >= 2)
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_THE_NECESSARY_MATERIALS_OR_PREREQUISITES_TO_LEARN_THIS_SKILL);
Util.handleIllegalPlayerAction(activeChar, "Player " + activeChar.getName() + " is requesting skill Id: " + _id + " level " + _level + " while having already learned 2 skills!", IllegalActionPunishmentType.NONE);
return;
}
if (checkPlayerSkill(activeChar, trainer, s))
{
final String varName = count == 0 ? REVELATION_VAR_NAMES[0] : REVELATION_VAR_NAMES[1];
activeChar.getVariables().set(varName, skill.getId());
giveSkill(activeChar, trainer, skill);
}
break;
}
case REVELATION_DUALCLASS:
{
if (activeChar.isSubClassActive() && !activeChar.isDualClassActive())
{
activeChar.sendPacket(SystemMessageId.THIS_SKILL_CANNOT_BE_LEARNED_WHILE_IN_THE_SUBCLASS_STATE_PLEASE_TRY_AGAIN_AFTER_CHANGING_TO_THE_MAIN_CLASS);
Util.handleIllegalPlayerAction(activeChar, "Player " + activeChar.getName() + " is requesting skill Id: " + _id + " level " + _level + " while Sub-Class is active!", IllegalActionPunishmentType.NONE);
return;
}
if ((activeChar.getLevel() < 85) || !activeChar.isInCategory(CategoryType.AWAKEN_GROUP))
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_THE_NECESSARY_MATERIALS_OR_PREREQUISITES_TO_LEARN_THIS_SKILL);
Util.handleIllegalPlayerAction(activeChar, "Player " + activeChar.getName() + " is requesting skill Id: " + _id + " level " + _level + " while not being level 85 or awaken!", IllegalActionPunishmentType.NONE);
return;
}
int count = 0;
for (String varName : DUALCLASS_REVELATION_VAR_NAMES)
{
if (activeChar.getVariables().getInt(varName, 0) > 0)
{
count++;
}
}
if (count >= 2)
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_THE_NECESSARY_MATERIALS_OR_PREREQUISITES_TO_LEARN_THIS_SKILL);
Util.handleIllegalPlayerAction(activeChar, "Player " + activeChar.getName() + " is requesting skill Id: " + _id + " level " + _level + " while having already learned 2 skills!", IllegalActionPunishmentType.NONE);
return;
}
if (checkPlayerSkill(activeChar, trainer, s))
{
final String varName = count == 0 ? DUALCLASS_REVELATION_VAR_NAMES[0] : DUALCLASS_REVELATION_VAR_NAMES[1];
activeChar.getVariables().set(varName, skill.getId());
giveSkill(activeChar, trainer, skill);
}
break;
}
default:
{
_log.warning("Recived Wrong Packet Data in Aquired Skill, unknown skill type:" + _skillType);
@@ -20,6 +20,7 @@ package com.l2jserver.gameserver.network.clientpackets;
import com.l2jserver.gameserver.datatables.SkillData;
import com.l2jserver.gameserver.datatables.SkillTreesData;
import com.l2jserver.gameserver.enums.CategoryType;
import com.l2jserver.gameserver.enums.Race;
import com.l2jserver.gameserver.model.ClanPrivilege;
import com.l2jserver.gameserver.model.L2SkillLearn;
@@ -148,6 +149,24 @@ public final class RequestAcquireSkillInfo extends L2GameClientPacket
sendPacket(new AcquireSkillInfo(_skillType, s));
break;
}
case REVELATION:
{
if ((activeChar.getLevel() < 85) || !activeChar.isInCategory(CategoryType.AWAKEN_GROUP))
{
return;
}
sendPacket(new AcquireSkillInfo(_skillType, s));
break;
}
case REVELATION_DUALCLASS:
{
if (!activeChar.isSubClassActive() || !activeChar.isDualClassActive())
{
return;
}
sendPacket(new AcquireSkillInfo(_skillType, s));
break;
}
}
}
@@ -23,6 +23,7 @@ import com.l2jserver.gameserver.instancemanager.FortManager;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeCount;
import com.l2jserver.gameserver.network.serverpackets.JoinPledge;
import com.l2jserver.gameserver.network.serverpackets.PledgeShowInfoUpdate;
import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListAdd;
@@ -77,7 +78,7 @@ public final class RequestAnswerJoinPledge extends L2GameClientPacket
}
RequestJoinPledge requestPacket = (RequestJoinPledge) requestor.getRequest().getRequestPacket();
L2Clan clan = requestor.getClan();
final L2Clan clan = requestor.getClan();
// we must double check this cause during response time conditions can be changed, i.e. another player could join clan
if (clan.checkClanJoinCondition(requestor, activeChar, requestPacket.getPledgeType()))
{
@@ -102,18 +103,19 @@ public final class RequestAnswerJoinPledge extends L2GameClientPacket
sm.addString(activeChar.getName());
clan.broadcastToOnlineMembers(sm);
if (activeChar.getClan().getCastleId() > 0)
if (clan.getCastleId() > 0)
{
CastleManager.getInstance().getCastleByOwner(activeChar.getClan()).giveResidentialSkills(activeChar);
CastleManager.getInstance().getCastleByOwner(clan).giveResidentialSkills(activeChar);
}
if (activeChar.getClan().getFortId() > 0)
if (clan.getFortId() > 0)
{
FortManager.getInstance().getFortByOwner(activeChar.getClan()).giveResidentialSkills(activeChar);
FortManager.getInstance().getFortByOwner(clan).giveResidentialSkills(activeChar);
}
activeChar.sendSkillList();
clan.broadcastToOtherOnlineMembers(new PledgeShowMemberListAdd(activeChar), activeChar);
clan.broadcastToOnlineMembers(new PledgeShowInfoUpdate(clan));
clan.broadcastToOnlineMembers(new ExPledgeCount(clan));
// this activates the clan tab on the new member
activeChar.sendPacket(new PledgeShowMemberListAll(clan));
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.network.clientpackets;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.events.EventDispatcher;
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerChangeToAwakenedClass;
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
/**
* @author Sdw
*/
public class RequestChangeToAwakenedClass extends L2GameClientPacket
{
private static final String _C__D0_A1_REQUESTCHANGETOAWAKENEDCLASS = "[C] D0;A2 RequestChangeToAwakenedClass";
private boolean _change;
@Override
protected void readImpl()
{
_change = readD() == 1;
}
@Override
protected void runImpl()
{
final L2PcInstance player = getClient().getActiveChar();
if (player == null)
{
return;
}
if (_change)
{
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerChangeToAwakenedClass(player), player);
}
else
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
@Override
public String getType()
{
return _C__D0_A1_REQUESTCHANGETOAWAKENEDCLASS;
}
}
@@ -18,28 +18,50 @@
*/
package com.l2jserver.gameserver.network.clientpackets;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeCrestLarge;
import com.l2jserver.gameserver.datatables.CrestTable;
import com.l2jserver.gameserver.model.L2Crest;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeEmblem;
/**
* Fomat : chd c: (id) 0xD0 h: (subid) 0x10 d: the crest id This is a trigger
* @author -Wooden-
* @author -Wooden-, Sdw
*/
public final class RequestExPledgeCrestLarge extends L2GameClientPacket
{
private static final String _C__D0_10_REQUESTEXPLEDGECRESTLARGE = "[C] D0:10 RequestExPledgeCrestLarge";
private int _crestId;
private int _clanId;
@Override
protected void readImpl()
{
_crestId = readD();
_clanId = readD();
}
@Override
protected void runImpl()
{
sendPacket(new ExPledgeCrestLarge(_crestId));
final L2Crest crest = CrestTable.getInstance().getCrest(_crestId);
final byte[] data = crest != null ? crest.getData() : null;
if (data != null)
{
for (int i = 0; i <= 4; i++)
{
if (i < 4)
{
final byte[] fullChunk = new byte[14336];
System.arraycopy(data, (14336 * i), fullChunk, 0, 14336);
sendPacket(new ExPledgeEmblem(_crestId, fullChunk, _clanId, i, 14336));
}
else
{
final byte[] lastChunk = new byte[8320];
System.arraycopy(data, (14336 * i), lastChunk, 0, 8320);
sendPacket(new ExPledgeEmblem(_crestId, lastChunk, _clanId, i, 8320));
}
}
}
}
@Override
@@ -24,6 +24,7 @@ import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2ClanMember;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeCount;
import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListDelete;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
@@ -46,7 +47,7 @@ public final class RequestOustPledgeMember extends L2GameClientPacket
@Override
protected void runImpl()
{
L2PcInstance activeChar = getClient().getActiveChar();
final L2PcInstance activeChar = getClient().getActiveChar();
if (activeChar == null)
{
return;
@@ -94,6 +95,7 @@ public final class RequestOustPledgeMember extends L2GameClientPacket
// Remove the Player From the Member list
clan.broadcastToOnlineMembers(new PledgeShowMemberListDelete(_target));
clan.broadcastToOnlineMembers(new ExPledgeCount(clan));
if (member.isOnline())
{
@@ -76,7 +76,7 @@ public class RequestPledgeWaitingApply extends L2GameClientPacket
if (clanLeader != null)
{
clanLeader.sendPacket(new ExPledgeWaitingListAlarm());
clanLeader.sendPacket(ExPledgeWaitingListAlarm.STATIC_PACKET);
}
}
else
@@ -22,6 +22,7 @@ import com.l2jserver.Config;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.ExPledgeCount;
import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListDelete;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
@@ -73,6 +74,7 @@ public final class RequestWithdrawalPledge extends L2GameClientPacket
// Remove the Player From the Member list
clan.broadcastToOnlineMembers(new PledgeShowMemberListDelete(activeChar.getName()));
clan.broadcastToOnlineMembers(new ExPledgeCount(clan));
activeChar.sendPacket(SystemMessageId.YOU_HAVE_WITHDRAWN_FROM_THE_CLAN);
activeChar.sendPacket(SystemMessageId.AFTER_LEAVING_OR_HAVING_BEEN_DISMISSED_FROM_A_CLAN_YOU_MUST_WAIT_AT_LEAST_A_DAY_BEFORE_JOINING_ANOTHER_CLAN);
@@ -70,6 +70,8 @@ public final class Say2 extends L2GameClientPacket
public static final int MPCC_ROOM = 21;
public static final int NPC_ALL = 22;
public static final int NPC_SHOUT = 23;
public static final int NPC_TELL = 24;
public static final int GLOBAL = 25;
private static final String[] CHAT_NAMES =
{
@@ -94,7 +96,11 @@ public final class Say2 extends L2GameClientPacket
"CRITICAL_ANNOUNCE",
"SCREEN_ANNOUNCE",
"BATTLEFIELD",
"MPCC_ROOM"
"MPCC_ROOM",
"NPC_ALL",
"NPC_SHOUT",
"NEW_TELL",
"GLOBAL"
};
private static final String[] WALKER_COMMAND_LIST =
@@ -308,6 +308,16 @@ public final class UseItem extends L2GameClientPacket
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
return;
}
break;
}
case L2Item.SLOT_BROOCH_JEWEL:
{
if (!item.isEquipped() && (activeChar.getInventory().getBroochJewelSlots() == 0))
{
activeChar.sendPacket(SystemMessageId.YOU_CANNOT_EQUIP_S1_WITHOUT_EQUIPPING_A_BROOCH);
return;
}
break;
}
}
@@ -36,6 +36,7 @@ public class AcquireSkillList extends L2GameServerPacket
public AcquireSkillList(L2PcInstance activeChar)
{
_learnable = SkillTreesData.getInstance().getAvailableSkills(activeChar, activeChar.getClassId(), false, false);
_learnable.addAll(SkillTreesData.getInstance().getNextAvailableSkills(activeChar, activeChar.getClassId(), false, false));
}
@Override
@@ -49,7 +50,7 @@ public class AcquireSkillList extends L2GameServerPacket
writeH(skill.getSkillLevel());
writeQ(skill.getLevelUpSp());
writeC(skill.getGetLevel());
writeC(skill.getGetLevel()); // Dual Class Level Required
writeC(0x00); // Dual Class Level Required
writeC(skill.getRequiredItems().size());
for (ItemHolder item : skill.getRequiredItems())
{
@@ -90,6 +90,14 @@ public final class CreatureSay extends L2GameServerPacket
_text = text;
}
public CreatureSay(L2PcInstance player, int messageType, String text)
{
_objectId = player.getObjectId();
_textType = messageType;
_charName = player.getAppearance().getVisibleName();
_text = text;
}
public CreatureSay(int objectId, int messageType, int charId, NpcStringId npcString)
{
_objectId = objectId;
@@ -18,6 +18,7 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.enums.CastleSide;
import com.l2jserver.gameserver.model.entity.Castle;
/**
@@ -26,12 +27,12 @@ import com.l2jserver.gameserver.model.entity.Castle;
public class ExCastleState extends L2GameServerPacket
{
private final int _castleId;
private final int _state;
private final CastleSide _castleSide;
public ExCastleState(Castle castle)
{
_castleId = castle.getResidenceId();
_state = castle.getState();
_castleSide = castle.getSide();
}
@Override
@@ -40,6 +41,6 @@ public class ExCastleState extends L2GameServerPacket
writeC(0xFE);
writeH(0x12D);
writeD(_castleId);
writeD(_state);
writeD(_castleSide.ordinal());
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.network.serverpackets;
/**
* @author Sdw
*/
public class ExChangeToAwakenedClass extends L2GameServerPacket
{
private final int _classId;
public ExChangeToAwakenedClass(int classId)
{
_classId = classId;
}
@Override
protected void writeImpl()
{
writeC(0xFE);
writeH(0xFF);
writeD(_classId);
}
}
@@ -18,28 +18,27 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.datatables.CrestTable;
import com.l2jserver.gameserver.model.L2Crest;
import com.l2jserver.Config;
/**
* @author -Wooden-
* @author -Wooden-, Sdw
*/
public class ExPledgeCrestLarge extends L2GameServerPacket
public class ExPledgeEmblem extends L2GameServerPacket
{
private final int _crestId;
private final int _clanId;
private final byte[] _data;
private final int _chunkId;
private final int _chunkSize;
private static final int TOTAL_SIZE = 65664;
public ExPledgeCrestLarge(int crestId)
public ExPledgeEmblem(int crestId, byte[] chunkedData, int clanId, int chunkId, int chunkSize)
{
_crestId = crestId;
final L2Crest crest = CrestTable.getInstance().getCrest(crestId);
_data = crest != null ? crest.getData() : null;
}
public ExPledgeCrestLarge(int crestId, byte[] data)
{
_crestId = crestId;
_data = data;
_data = chunkedData;
_clanId = clanId;
_chunkId = chunkId;
_chunkSize = chunkSize;
}
@Override
@@ -47,8 +46,12 @@ public class ExPledgeCrestLarge extends L2GameServerPacket
{
writeC(0xFE);
writeH(0x1B);
writeD(0x00);
writeD(Config.SERVER_ID);
writeD(_clanId);
writeD(_crestId);
writeD(_chunkId);
writeD(TOTAL_SIZE);
writeD(_chunkSize);
if (_data != null)
{
writeD(_data.length);
@@ -23,6 +23,8 @@ package com.l2jserver.gameserver.network.serverpackets;
*/
public class ExPledgeWaitingListAlarm extends L2GameServerPacket
{
public static final ExPledgeWaitingListAlarm STATIC_PACKET = new ExPledgeWaitingListAlarm();
@Override
protected void writeImpl()
{
@@ -63,7 +63,7 @@ public class ExSubjobInfo extends L2GameServerPacket
_index = sub.getClassIndex();
_classId = sub.getClassId();
_level = sub.getLevel();
_type = SubclassType.SUBCLASS.ordinal();
_type = sub.isDualClass() ? SubclassType.DUALCLASS.ordinal() : SubclassType.SUBCLASS.ordinal();
}
public SubInfo(L2PcInstance player)
@@ -18,7 +18,11 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.Config;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.stat.PcStat;
import com.l2jserver.gameserver.model.variables.AccountVariables;
import com.l2jserver.gameserver.network.L2GameClient;
/**
* @author Sdw
@@ -32,6 +36,12 @@ public class ExVitalityEffectInfo extends L2GameServerPacket
_points = cha.getVitalityPoints();
}
public ExVitalityEffectInfo(L2GameClient client)
{
final AccountVariables vars = new AccountVariables(client.getAccountName());
_points = vars.getInt(PcStat.VITALITY_VARIABLE, Config.STARTING_VITALITY_POINTS);
}
@Override
protected final void writeImpl()
{
@@ -39,7 +49,7 @@ public class ExVitalityEffectInfo extends L2GameServerPacket
writeH(0x118);
writeD(_points);
writeD(0x00); // Vitality Bonus
writeD((int) (Config.RATE_VITALITY_EXP_MULTIPLIER * 100)); // Vitality Bonus
writeH(0x05); // How much vitality items remaining for use
writeH(0x05); // Max number of items for use
}
@@ -19,7 +19,6 @@
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.entity.RecoBonus;
/**
* ExVoteSystemInfo packet implementation.
@@ -37,9 +36,9 @@ public class ExVoteSystemInfo extends L2GameServerPacket
{
_recomLeft = player.getRecomLeft();
_recomHave = player.getRecomHave();
_bonusTime = player.getRecomBonusTime();
_bonusVal = RecoBonus.getRecoBonus(player);
_bonusType = player.getRecomBonusType();
_bonusTime = 0;
_bonusVal = 0;
_bonusType = 0;
}
@Override
@@ -16,41 +16,28 @@
* 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.l2jserver.gameserver.model.actor.tasks.player;
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.Config;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.stat.PcStat;
import com.l2jserver.gameserver.model.zone.ZoneId;
import com.l2jserver.gameserver.network.serverpackets.ExVitalityPointInfo;
/**
* Task dedicated to reward player with vitality.
* @author UnAfraid
*/
public class VitalityTask implements Runnable
public class ExWorldChatCnt extends L2GameServerPacket
{
private final L2PcInstance _player;
private final int _points;
public VitalityTask(L2PcInstance player)
public ExWorldChatCnt(L2PcInstance activeChar)
{
_player = player;
_points = activeChar.getLevel() < Config.WORLD_CHAT_MIN_LEVEL ? 0 : activeChar.getWorldChatPoints();
}
@Override
public void run()
protected void writeImpl()
{
if (!_player.isInsideZone(ZoneId.PEACE))
{
return;
}
if (_player.getVitalityPoints() >= PcStat.MAX_VITALITY_POINTS)
{
return;
}
_player.updateVitalityPoints(Config.RATE_RECOVERY_VITALITY_PEACE_ZONE, false, false);
_player.sendPacket(new ExVitalityPointInfo(_player.getVitalityPoints()));
writeC(0xFE);
writeH(0x173);
writeD(_points);
}
}
@@ -55,6 +55,8 @@ public final class GMHennaInfo extends L2GameServerPacket
writeC(_activeChar.getHennaStatMEN()); // equip MEN
writeC(_activeChar.getHennaStatDEX()); // equip DEX
writeC(_activeChar.getHennaStatWIT()); // equip WIT
writeC(0x00); // equip LUC
writeC(0x00); // equip CHA
writeD(3); // Slots
writeD(_hennas.size()); // Size
for (L2Henna henna : _hennas)
@@ -62,5 +64,8 @@ public final class GMHennaInfo extends L2GameServerPacket
writeD(henna.getDyeId());
writeD(0x01);
}
writeD(0x00);
writeD(0x00);
writeD(0x00);
}
}
@@ -109,8 +109,8 @@ public class GMViewCharacterInfo extends L2GameServerPacket
writeD(_activeChar.getPAtkSpd());
writeD(_activeChar.getMDef(null, null));
writeD(0x00); // magic evasion
writeD(0x00); // magic accuracy
writeD(_activeChar.getMagicEvasionRate(null));
writeD(_activeChar.getMagicAccuracy());
writeD(_activeChar.getMCriticalHit(null, null));
writeD(_activeChar.getPvpFlag()); // 0-non-pvp 1-pvp = violett name
@@ -37,11 +37,13 @@ public class GMViewPledgeInfo extends L2GameServerPacket
protected final void writeImpl()
{
writeC(0x96);
writeD(0x00);
writeS(_activeChar.getName());
writeD(_clan.getId());
writeD(0x00);
writeS(_clan.getName());
writeS(_clan.getLeaderName());
writeD(_clan.getCrestId()); // -> no, it's no longer used (nuocnam) fix by game
writeD(_clan.getLevel());
writeD(_clan.getCastleId());
@@ -51,14 +53,14 @@ public class GMViewPledgeInfo extends L2GameServerPacket
writeD(_clan.getReputationScore());
writeD(0x00);
writeD(0x00);
writeD(0x00);
writeD(_clan.getAllyId()); // c2
writeS(_clan.getAllyName()); // c2
writeD(_clan.getAllyCrestId()); // c2
writeD(_clan.isAtWar() ? 1 : 0); // c3
writeD(0x00); // T3 Unknown
writeD(_clan.getMembers().length);
writeD(_clan.getMembers().size());
for (L2ClanMember member : _clan.getMembers())
{
if (member != null)
@@ -50,6 +50,7 @@ public class GMViewSkillInfo extends L2GameServerPacket
writeD(skill.isPassive() ? 1 : 0);
writeD(skill.getDisplayLevel());
writeD(skill.getDisplayId());
writeD(0x00);
writeC(isDisabled && skill.isClanSkill() ? 1 : 0);
writeC(SkillData.getInstance().isEnchantable(skill.getDisplayId()) ? 1 : 0);
}
@@ -43,29 +43,16 @@ public class GmViewQuestInfo extends L2GameServerPacket
Quest[] questList = _activeChar.getAllActiveQuests();
if (questList.length == 0)
{
writeC(0);
writeH(0);
writeH(0);
return;
}
writeH(questList.length); // quest count
for (Quest q : questList)
{
final QuestState qs = _activeChar.getQuestState(q.getName());
writeD(q.getId());
QuestState qs = _activeChar.getQuestState(q.getName());
if (qs == null)
{
writeD(0);
continue;
}
writeD(qs.getInt("cond")); // stage of quest progress
writeD(qs == null ? 0 : qs.getInt("cond"));
}
writeH(0x00); // some size
// for size; ddQQ
}
}
@@ -23,6 +23,7 @@ import java.util.logging.Logger;
import org.mmocore.network.SendablePacket;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.interfaces.IPositionable;
import com.l2jserver.gameserver.model.interfaces.IUpdateTypeComponent;
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
@@ -178,8 +179,23 @@ public abstract class L2GameServerPacket extends SendablePacket<L2GameClient>
protected abstract void writeImpl();
/**
* @param masks
* @param type
* @return {@code true} if the mask contains the current update component type
*/
protected static boolean containsMask(int masks, IUpdateTypeComponent type)
{
return (masks & type.getMask()) == type.getMask();
}
/**
* Sends this packet to the target player, useful for lambda operations like <br>
* {@code L2World.getInstance().getPlayers().forEach(packet::sendTo)}
* @param player
*/
public void sendTo(L2PcInstance player)
{
player.sendPacket(this);
}
}
@@ -18,6 +18,8 @@
*/
package com.l2jserver.gameserver.network.serverpackets;
import java.util.Collection;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2Clan.SubPledge;
import com.l2jserver.gameserver.model.L2ClanMember;
@@ -27,7 +29,7 @@ import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
public class PledgeShowMemberListAll extends L2GameServerPacket
{
private final L2Clan _clan;
private final L2ClanMember[] _members;
private final Collection<L2ClanMember> _members;
private int _pledgeType;
public PledgeShowMemberListAll(L2Clan clan)
@@ -19,6 +19,7 @@
package com.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.datatables.ClanTable;
import com.l2jserver.gameserver.enums.SiegeClanType;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2SiegeClan;
import com.l2jserver.gameserver.model.entity.Castle;
@@ -60,69 +61,71 @@ public final class SiegeDefenderList extends L2GameServerPacket
{
writeC(0xcb);
writeD(_castle.getResidenceId());
writeD(0x00); // 0
writeD(0x01); // 1
writeD(0x00); // 0
int size = _castle.getSiege().getDefenderClans().size() + _castle.getSiege().getDefenderWaitingClans().size();
if (size > 0)
writeD(0x00); // Unknown
writeD(0x01); // Unknown
writeD(0x00); // Unknown
final int size = _castle.getSiege().getDefenderWaitingClans().size() + _castle.getSiege().getDefenderClans().size() + (_castle.getOwner() != null ? 1 : 0);
writeD(size);
writeD(size);
// Add owners
final L2Clan ownerClan = _castle.getOwner();
if (ownerClan != null)
{
L2Clan clan;
writeD(size);
writeD(size);
// Listing the Lord and the approved clans
for (L2SiegeClan siegeclan : _castle.getSiege().getDefenderClans())
{
clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
if (clan == null)
{
continue;
}
writeD(clan.getId());
writeS(clan.getName());
writeS(clan.getLeaderName());
writeD(clan.getCrestId());
writeD(0x00); // signed time (seconds) (not storated by L2J)
switch (siegeclan.getType())
{
case OWNER:
writeD(0x01); // owner
break;
case DEFENDER_PENDING:
writeD(0x02); // approved
break;
case DEFENDER:
writeD(0x03); // waiting approved
break;
default:
writeD(0x00);
break;
}
writeD(clan.getAllyId());
writeS(clan.getAllyName());
writeS(""); // AllyLeaderName
writeD(clan.getAllyCrestId());
}
for (L2SiegeClan siegeclan : _castle.getSiege().getDefenderWaitingClans())
{
clan = ClanTable.getInstance().getClan(siegeclan.getClanId());
writeD(clan.getId());
writeS(clan.getName());
writeS(clan.getLeaderName());
writeD(clan.getCrestId());
writeD(0x00); // signed time (seconds) (not storated by L2J)
writeD(0x02); // waiting approval
writeD(clan.getAllyId());
writeS(clan.getAllyName());
writeS(""); // AllyLeaderName
writeD(clan.getAllyCrestId());
}
writeD(ownerClan.getId());
writeS(ownerClan.getName());
writeS(ownerClan.getLeaderName());
writeD(ownerClan.getCrestId());
writeD(0x00); // signed time (seconds) (not storated by L2J)
writeD(SiegeClanType.OWNER.ordinal());
writeD(ownerClan.getAllyId());
writeS(ownerClan.getAllyName());
writeS(""); // AllyLeaderName
writeD(ownerClan.getAllyCrestId());
}
else
// List of confirmed defenders
for (L2SiegeClan siegeClan : _castle.getSiege().getDefenderClans())
{
writeD(0x00);
writeD(0x00);
final L2Clan defendingClan = ClanTable.getInstance().getClan(siegeClan.getClanId());
if ((defendingClan == null) || (defendingClan == _castle.getOwner()))
{
continue;
}
writeD(defendingClan.getId());
writeS(defendingClan.getName());
writeS(defendingClan.getLeaderName());
writeD(defendingClan.getCrestId());
writeD(0x00); // signed time (seconds) (not storated by L2J)
writeD(SiegeClanType.DEFENDER.ordinal());
writeD(defendingClan.getAllyId());
writeS(defendingClan.getAllyName());
writeS(""); // AllyLeaderName
writeD(defendingClan.getAllyCrestId());
}
// List of not confirmed defenders
for (L2SiegeClan siegeClan : _castle.getSiege().getDefenderWaitingClans())
{
final L2Clan defendingClan = ClanTable.getInstance().getClan(siegeClan.getClanId());
if (defendingClan == null)
{
continue;
}
writeD(defendingClan.getId());
writeS(defendingClan.getName());
writeS(defendingClan.getLeaderName());
writeD(defendingClan.getCrestId());
writeD(0x00); // signed time (seconds) (not storated by L2J)
writeD(SiegeClanType.DEFENDER_PENDING.ordinal());
writeD(defendingClan.getAllyId());
writeS(defendingClan.getAllyName());
writeS(""); // AllyLeaderName
writeD(defendingClan.getAllyCrestId());
}
}
}
@@ -1,389 +1,389 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.enums.UserInfoType;
import com.l2jserver.gameserver.instancemanager.RaidBossPointsManager;
import com.l2jserver.gameserver.model.Elementals;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.zone.ZoneId;
/**
* @author Sdw, UnAfraid
*/
public class UserInfo extends AbstractMaskPacket<UserInfoType>
{
private final L2PcInstance _activeChar;
private final int _relation;
private final int _runSpd;
private final int _walkSpd;
private final int _swimRunSpd;
private final int _swimWalkSpd;
private final int _flRunSpd = 0;
private final int _flWalkSpd = 0;
private final int _flyRunSpd;
private final int _flyWalkSpd;
private final double _moveMultiplier;
private int _enchantLevel = 0;
private int _armorEnchant = 0;
private final byte[] _masks = new byte[]
{
(byte) 0x00,
(byte) 0x00,
(byte) 0x00
};
private int _initSize = 5;
public UserInfo(L2PcInstance cha)
{
this(cha, true);
}
public UserInfo(L2PcInstance cha, boolean addAll)
{
_activeChar = cha;
_relation = calculateRelation(cha);
_moveMultiplier = cha.getMovementSpeedMultiplier();
_runSpd = (int) Math.round(cha.getRunSpeed() / _moveMultiplier);
_walkSpd = (int) Math.round(cha.getWalkSpeed() / _moveMultiplier);
_swimRunSpd = (int) Math.round(cha.getSwimRunSpeed() / _moveMultiplier);
_swimWalkSpd = (int) Math.round(cha.getSwimWalkSpeed() / _moveMultiplier);
_flyRunSpd = cha.isFlying() ? _runSpd : 0;
_flyWalkSpd = cha.isFlying() ? _walkSpd : 0;
_enchantLevel = cha.getInventory().getWeaponEnchant();
_armorEnchant = cha.getInventory().getArmorMinEnchant();
if (addAll)
{
addComponentType(UserInfoType.values());
}
}
@Override
protected byte[] getMasks()
{
return _masks;
}
@Override
protected void onNewMaskAdded(UserInfoType component)
{
calcBlockSize(component);
}
private void calcBlockSize(UserInfoType type)
{
switch (type)
{
case BASIC_INFO:
{
_initSize += type.getBlockLength() + (_activeChar.getName().length() * 2);
break;
}
case CLAN:
{
_initSize += type.getBlockLength() + (_activeChar.getTitle().length() * 2);
break;
}
default:
{
_initSize += type.getBlockLength();
break;
}
}
}
@Override
protected void writeImpl()
{
writeC(0x32);
writeD(_activeChar.getObjectId());
writeD(_initSize);
writeH(23);
writeB(_masks);
if (containsMask(UserInfoType.RELATION))
{
writeD(_relation);
}
if (containsMask(UserInfoType.BASIC_INFO))
{
writeH(16 + (_activeChar.getName().length() * 2));
writeString(_activeChar.getName());
writeC(_activeChar.isGM() ? 0x01 : 0x00);
writeC(_activeChar.getRace().ordinal());
writeC(_activeChar.getAppearance().getSex() ? 0x01 : 0x00);
writeD(_activeChar.getBaseClass());
writeD(_activeChar.getClassId().getId());
writeC(_activeChar.getLevel());
}
if (containsMask(UserInfoType.BASE_STATS))
{
writeH(18);
writeH(_activeChar.getSTR());
writeH(_activeChar.getDEX());
writeH(_activeChar.getCON());
writeH(_activeChar.getINT());
writeH(_activeChar.getWIT());
writeH(_activeChar.getMEN());
writeH(_activeChar.getLUC());
writeH(_activeChar.getCHA());
}
if (containsMask(UserInfoType.MAX_HPCPMP))
{
writeH(14);
writeD(_activeChar.getMaxHp());
writeD(_activeChar.getMaxMp());
writeD(_activeChar.getMaxCp());
}
if (containsMask(UserInfoType.CURRENT_HPMPCP_EXP_SP))
{
writeH(38);
writeD((int) Math.round(_activeChar.getCurrentHp()));
writeD((int) Math.round(_activeChar.getCurrentMp()));
writeD((int) Math.round(_activeChar.getCurrentCp()));
writeQ(_activeChar.getSp());
writeQ(_activeChar.getExp());
writeF((float) (_activeChar.getExp() - ExperienceTable.getInstance().getExpForLevel(_activeChar.getLevel())) / (ExperienceTable.getInstance().getExpForLevel(_activeChar.getLevel() + 1) - ExperienceTable.getInstance().getExpForLevel(_activeChar.getLevel())));
}
if (containsMask(UserInfoType.ENCHANTLEVEL))
{
writeH(4);
writeC(_enchantLevel);
writeC(_armorEnchant);
}
if (containsMask(UserInfoType.APPAREANCE))
{
writeH(15);
writeD(_activeChar.getVisualHair());
writeD(_activeChar.getVisualHairColor());
writeD(_activeChar.getVisualFace());
writeC(_activeChar.isHairAccessoryEnabled() ? 0x01 : 0x00);
}
if (containsMask(UserInfoType.STATUS))
{
writeH(6);
writeC(_activeChar.getMountType().ordinal());
writeC(_activeChar.getPrivateStoreType().getId());
writeC(_activeChar.hasDwarvenCraft() ? 1 : 0);
writeC(0x00);
}
if (containsMask(UserInfoType.STATS))
{
writeH(56);
writeH(_activeChar.getActiveWeaponItem() != null ? 40 : 20);
writeD(_activeChar.getPAtk(null));
writeD(_activeChar.getPAtkSpd());
writeD(_activeChar.getPDef(null));
writeD(_activeChar.getEvasionRate(null));
writeD(_activeChar.getAccuracy());
writeD(_activeChar.getCriticalHit(null, null));
writeD(_activeChar.getMAtk(null, null));
writeD(_activeChar.getMAtkSpd());
writeD(_activeChar.getPAtkSpd()); // Seems like atk speed - 1
writeD(_activeChar.getMagicEvasionRate(null));
writeD(_activeChar.getMDef(null, null));
writeD(_activeChar.getMagicAccuracy());
writeD(_activeChar.getMCriticalHit(null, null));
}
if (containsMask(UserInfoType.ELEMENTALS))
{
writeH(14);
writeH(_activeChar.getDefenseElementValue(Elementals.FIRE));
writeH(_activeChar.getDefenseElementValue(Elementals.WATER));
writeH(_activeChar.getDefenseElementValue(Elementals.WIND));
writeH(_activeChar.getDefenseElementValue(Elementals.EARTH));
writeH(_activeChar.getDefenseElementValue(Elementals.HOLY));
writeH(_activeChar.getDefenseElementValue(Elementals.DARK));
}
if (containsMask(UserInfoType.POSITION))
{
writeH(18);
writeD(_activeChar.getX());
writeD(_activeChar.getY());
writeD(_activeChar.getZ());
writeD(_activeChar.getHeading());
}
if (containsMask(UserInfoType.SPEED))
{
writeH(18);
writeH(_runSpd);
writeH(_walkSpd);
writeH(_swimRunSpd);
writeH(_swimWalkSpd);
writeH(_flRunSpd);
writeH(_flWalkSpd);
writeH(_flyRunSpd);
writeH(_flyWalkSpd);
}
if (containsMask(UserInfoType.MULTIPLIER))
{
writeH(18);
writeF(_moveMultiplier);
writeF(_activeChar.getAttackSpeedMultiplier());
}
if (containsMask(UserInfoType.COL_RADIUS_HEIGHT))
{
writeH(18);
writeF(_activeChar.getCollisionRadius());
writeF(_activeChar.getCollisionHeight());
}
if (containsMask(UserInfoType.ATK_ELEMENTAL))
{
writeH(5);
byte attackAttribute = _activeChar.getAttackElement();
writeC(attackAttribute);
writeH(_activeChar.getAttackElementValue(attackAttribute));
}
if (containsMask(UserInfoType.CLAN))
{
writeH(32 + (_activeChar.getTitle().length() * 2));
writeString(_activeChar.getTitle());
writeH(_activeChar.getPledgeType());
writeD(_activeChar.getClanId());
writeD(_activeChar.getClanCrestLargeId());
writeD(_activeChar.getClanCrestId());
writeC(_activeChar.isClanLeader() ? -1 : 0x00);
writeD(_activeChar.getClanPrivileges().getBitmask());
writeD(_activeChar.getAllyId());
writeD(_activeChar.getAllyCrestId());
writeC(_activeChar.isInPartyMatchRoom() ? 0x01 : 0x00);
}
if (containsMask(UserInfoType.SOCIAL))
{
writeH(22);
writeC(_activeChar.getPvpFlag());
writeD(_activeChar.getKarma()); // Reputation
writeC(_activeChar.isNoble() ? 0x01 : 0x00);
writeC(_activeChar.isHero() ? 0x01 : 0x00);
writeC(_activeChar.getPledgeClass());
writeD(_activeChar.getPkKills());
writeD(_activeChar.getPvpKills());
writeD(_activeChar.getRecomLeft());
}
if (containsMask(UserInfoType.VITA_FAME))
{
writeH(15);
writeD(_activeChar.getVitalityPoints());
writeC(0x00); // Vita Bonus
writeD(_activeChar.getFame());
writeD(RaidBossPointsManager.getInstance().getPointsByOwnerId(_activeChar.getObjectId()));
}
if (containsMask(UserInfoType.SLOTS))
{
writeH(9);
writeC(_activeChar.getInventory().getTalismanSlots()); // Confirmed
writeC(_activeChar.getInventory().getBroochJewelSlots()); // Confirmed
writeC(_activeChar.getTeam().getId()); // Confirmed
writeC(0x00); // Red dotted ring on the floor
writeC(0x00);
writeC(0x00);
writeC(0x00);
}
if (containsMask(UserInfoType.MOVEMENTS))
{
writeH(4);
writeC(_activeChar.isInsideZone(ZoneId.WATER) ? 1 : _activeChar.isFlyingMounted() ? 2 : 0);
writeC(_activeChar.isRunning() ? 0x01 : 0x00);
}
if (containsMask(UserInfoType.COLOR))
{
writeH(10);
writeD(_activeChar.getAppearance().getNameColor());
writeD(_activeChar.getAppearance().getTitleColor());
}
if (containsMask(UserInfoType.INVENTORY_LIMIT))
{
writeH(9);
writeH(0x00);
writeH(0x00);
writeH(_activeChar.getInventoryLimit());
writeC(0x00); // if greater than 1 show the attack cursor when interacting
}
if (containsMask(UserInfoType.UNK_3))
{
writeH(9);
writeC(0x00);
writeH(0x00);
writeD(0x00);
}
}
private int calculateRelation(L2PcInstance activeChar)
{
int relation = 0;
final L2Party party = activeChar.getParty();
final L2Clan clan = activeChar.getClan();
if (party != null)
{
relation |= 0x08; // Party member
if (party.getLeader() == _activeChar)
{
relation |= 0x10; // Party leader
}
}
if (clan != null)
{
relation |= 0x20; // Clan member
if (clan.getLeaderId() == activeChar.getObjectId())
{
relation |= 0x40; // Clan leader
}
}
if (activeChar.isInSiege())
{
relation |= 0x80; // In siege
}
return relation;
}
}
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.network.serverpackets;
import com.l2jserver.gameserver.datatables.ExperienceTable;
import com.l2jserver.gameserver.enums.UserInfoType;
import com.l2jserver.gameserver.instancemanager.RaidBossPointsManager;
import com.l2jserver.gameserver.model.Elementals;
import com.l2jserver.gameserver.model.L2Clan;
import com.l2jserver.gameserver.model.L2Party;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.zone.ZoneId;
/**
* @author Sdw, UnAfraid
*/
public class UserInfo extends AbstractMaskPacket<UserInfoType>
{
private final L2PcInstance _activeChar;
private final int _relation;
private final int _runSpd;
private final int _walkSpd;
private final int _swimRunSpd;
private final int _swimWalkSpd;
private final int _flRunSpd = 0;
private final int _flWalkSpd = 0;
private final int _flyRunSpd;
private final int _flyWalkSpd;
private final double _moveMultiplier;
private int _enchantLevel = 0;
private int _armorEnchant = 0;
private final byte[] _masks = new byte[]
{
(byte) 0x00,
(byte) 0x00,
(byte) 0x00
};
private int _initSize = 5;
public UserInfo(L2PcInstance cha)
{
this(cha, true);
}
public UserInfo(L2PcInstance cha, boolean addAll)
{
_activeChar = cha;
_relation = calculateRelation(cha);
_moveMultiplier = cha.getMovementSpeedMultiplier();
_runSpd = (int) Math.round(cha.getRunSpeed() / _moveMultiplier);
_walkSpd = (int) Math.round(cha.getWalkSpeed() / _moveMultiplier);
_swimRunSpd = (int) Math.round(cha.getSwimRunSpeed() / _moveMultiplier);
_swimWalkSpd = (int) Math.round(cha.getSwimWalkSpeed() / _moveMultiplier);
_flyRunSpd = cha.isFlying() ? _runSpd : 0;
_flyWalkSpd = cha.isFlying() ? _walkSpd : 0;
_enchantLevel = cha.getInventory().getWeaponEnchant();
_armorEnchant = cha.getInventory().getArmorMinEnchant();
if (addAll)
{
addComponentType(UserInfoType.values());
}
}
@Override
protected byte[] getMasks()
{
return _masks;
}
@Override
protected void onNewMaskAdded(UserInfoType component)
{
calcBlockSize(component);
}
private void calcBlockSize(UserInfoType type)
{
switch (type)
{
case BASIC_INFO:
{
_initSize += type.getBlockLength() + (_activeChar.getName().length() * 2);
break;
}
case CLAN:
{
_initSize += type.getBlockLength() + (_activeChar.getTitle().length() * 2);
break;
}
default:
{
_initSize += type.getBlockLength();
break;
}
}
}
@Override
protected void writeImpl()
{
writeC(0x32);
writeD(_activeChar.getObjectId());
writeD(_initSize);
writeH(23);
writeB(_masks);
if (containsMask(UserInfoType.RELATION))
{
writeD(_relation);
}
if (containsMask(UserInfoType.BASIC_INFO))
{
writeH(16 + (_activeChar.getName().length() * 2));
writeString(_activeChar.getName());
writeC(_activeChar.isGM() ? 0x01 : 0x00);
writeC(_activeChar.getRace().ordinal());
writeC(_activeChar.getAppearance().getSex() ? 0x01 : 0x00);
writeD(_activeChar.getBaseClass());
writeD(_activeChar.getClassId().getId());
writeC(_activeChar.getLevel());
}
if (containsMask(UserInfoType.BASE_STATS))
{
writeH(18);
writeH(_activeChar.getSTR());
writeH(_activeChar.getDEX());
writeH(_activeChar.getCON());
writeH(_activeChar.getINT());
writeH(_activeChar.getWIT());
writeH(_activeChar.getMEN());
writeH(_activeChar.getLUC());
writeH(_activeChar.getCHA());
}
if (containsMask(UserInfoType.MAX_HPCPMP))
{
writeH(14);
writeD(_activeChar.getMaxHp());
writeD(_activeChar.getMaxMp());
writeD(_activeChar.getMaxCp());
}
if (containsMask(UserInfoType.CURRENT_HPMPCP_EXP_SP))
{
writeH(38);
writeD((int) Math.round(_activeChar.getCurrentHp()));
writeD((int) Math.round(_activeChar.getCurrentMp()));
writeD((int) Math.round(_activeChar.getCurrentCp()));
writeQ(_activeChar.getSp());
writeQ(_activeChar.getExp());
writeF((float) (_activeChar.getExp() - ExperienceTable.getInstance().getExpForLevel(_activeChar.getLevel())) / (ExperienceTable.getInstance().getExpForLevel(_activeChar.getLevel() + 1) - ExperienceTable.getInstance().getExpForLevel(_activeChar.getLevel())));
}
if (containsMask(UserInfoType.ENCHANTLEVEL))
{
writeH(4);
writeC(_enchantLevel);
writeC(_armorEnchant);
}
if (containsMask(UserInfoType.APPAREANCE))
{
writeH(15);
writeD(_activeChar.getVisualHair());
writeD(_activeChar.getVisualHairColor());
writeD(_activeChar.getVisualFace());
writeC(_activeChar.isHairAccessoryEnabled() ? 0x01 : 0x00);
}
if (containsMask(UserInfoType.STATUS))
{
writeH(6);
writeC(_activeChar.getMountType().ordinal());
writeC(_activeChar.getPrivateStoreType().getId());
writeC(_activeChar.hasDwarvenCraft() ? 1 : 0);
writeC(_activeChar.getAbilityPointsUsed());
}
if (containsMask(UserInfoType.STATS))
{
writeH(56);
writeH(_activeChar.getActiveWeaponItem() != null ? 40 : 20);
writeD(_activeChar.getPAtk(null));
writeD(_activeChar.getPAtkSpd());
writeD(_activeChar.getPDef(null));
writeD(_activeChar.getEvasionRate(null));
writeD(_activeChar.getAccuracy());
writeD(_activeChar.getCriticalHit(null, null));
writeD(_activeChar.getMAtk(null, null));
writeD(_activeChar.getMAtkSpd());
writeD(_activeChar.getPAtkSpd()); // Seems like atk speed - 1
writeD(_activeChar.getMagicEvasionRate(null));
writeD(_activeChar.getMDef(null, null));
writeD(_activeChar.getMagicAccuracy());
writeD(_activeChar.getMCriticalHit(null, null));
}
if (containsMask(UserInfoType.ELEMENTALS))
{
writeH(14);
writeH(_activeChar.getDefenseElementValue(Elementals.FIRE));
writeH(_activeChar.getDefenseElementValue(Elementals.WATER));
writeH(_activeChar.getDefenseElementValue(Elementals.WIND));
writeH(_activeChar.getDefenseElementValue(Elementals.EARTH));
writeH(_activeChar.getDefenseElementValue(Elementals.HOLY));
writeH(_activeChar.getDefenseElementValue(Elementals.DARK));
}
if (containsMask(UserInfoType.POSITION))
{
writeH(18);
writeD(_activeChar.getX());
writeD(_activeChar.getY());
writeD(_activeChar.getZ());
writeD(_activeChar.getHeading());
}
if (containsMask(UserInfoType.SPEED))
{
writeH(18);
writeH(_runSpd);
writeH(_walkSpd);
writeH(_swimRunSpd);
writeH(_swimWalkSpd);
writeH(_flRunSpd);
writeH(_flWalkSpd);
writeH(_flyRunSpd);
writeH(_flyWalkSpd);
}
if (containsMask(UserInfoType.MULTIPLIER))
{
writeH(18);
writeF(_moveMultiplier);
writeF(_activeChar.getAttackSpeedMultiplier());
}
if (containsMask(UserInfoType.COL_RADIUS_HEIGHT))
{
writeH(18);
writeF(_activeChar.getCollisionRadius());
writeF(_activeChar.getCollisionHeight());
}
if (containsMask(UserInfoType.ATK_ELEMENTAL))
{
writeH(5);
byte attackAttribute = _activeChar.getAttackElement();
writeC(attackAttribute);
writeH(_activeChar.getAttackElementValue(attackAttribute));
}
if (containsMask(UserInfoType.CLAN))
{
writeH(32 + (_activeChar.getTitle().length() * 2));
writeString(_activeChar.getTitle());
writeH(_activeChar.getPledgeType());
writeD(_activeChar.getClanId());
writeD(_activeChar.getClanCrestLargeId());
writeD(_activeChar.getClanCrestId());
writeC(_activeChar.isClanLeader() ? -1 : 0x00);
writeD(_activeChar.getClanPrivileges().getBitmask());
writeD(_activeChar.getAllyId());
writeD(_activeChar.getAllyCrestId());
writeC(_activeChar.isInPartyMatchRoom() ? 0x01 : 0x00);
}
if (containsMask(UserInfoType.SOCIAL))
{
writeH(22);
writeC(_activeChar.getPvpFlag());
writeD(_activeChar.getKarma()); // Reputation
writeC(_activeChar.isNoble() ? 0x01 : 0x00);
writeC(_activeChar.isHero() ? 0x01 : 0x00);
writeC(_activeChar.getPledgeClass());
writeD(_activeChar.getPkKills());
writeD(_activeChar.getPvpKills());
writeD(_activeChar.getRecomLeft());
}
if (containsMask(UserInfoType.VITA_FAME))
{
writeH(15);
writeD(_activeChar.getVitalityPoints());
writeC(0x00); // Vita Bonus
writeD(_activeChar.getFame());
writeD(RaidBossPointsManager.getInstance().getPointsByOwnerId(_activeChar.getObjectId()));
}
if (containsMask(UserInfoType.SLOTS))
{
writeH(9);
writeC(_activeChar.getInventory().getTalismanSlots()); // Confirmed
writeC(_activeChar.getInventory().getBroochJewelSlots()); // Confirmed
writeC(_activeChar.getTeam().getId()); // Confirmed
writeC(0x00); // Red dotted ring on the floor
writeC(0x00);
writeC(0x00);
writeC(0x00);
}
if (containsMask(UserInfoType.MOVEMENTS))
{
writeH(4);
writeC(_activeChar.isInsideZone(ZoneId.WATER) ? 1 : _activeChar.isFlyingMounted() ? 2 : 0);
writeC(_activeChar.isRunning() ? 0x01 : 0x00);
}
if (containsMask(UserInfoType.COLOR))
{
writeH(10);
writeD(_activeChar.getAppearance().getNameColor());
writeD(_activeChar.getAppearance().getTitleColor());
}
if (containsMask(UserInfoType.INVENTORY_LIMIT))
{
writeH(9);
writeH(0x00);
writeH(0x00);
writeH(_activeChar.getInventoryLimit());
writeC(0x00); // if greater than 1 show the attack cursor when interacting
}
if (containsMask(UserInfoType.UNK_3))
{
writeH(9);
writeC(0x00);
writeH(0x00);
writeD(0x00);
}
}
private int calculateRelation(L2PcInstance activeChar)
{
int relation = 0;
final L2Party party = activeChar.getParty();
final L2Clan clan = activeChar.getClan();
if (party != null)
{
relation |= 0x08; // Party member
if (party.getLeader() == _activeChar)
{
relation |= 0x10; // Party leader
}
}
if (clan != null)
{
relation |= 0x20; // Clan member
if (clan.getLeaderId() == activeChar.getObjectId())
{
relation |= 0x40; // Clan leader
}
}
if (activeChar.isInSiege())
{
relation |= 0x80; // In siege
}
return relation;
}
}
@@ -19,8 +19,8 @@
package com.l2jserver.gameserver.pathfinding.cellnodes;
import com.l2jserver.gameserver.GeoData;
import com.l2jserver.gameserver.geoengine.Direction;
import com.l2jserver.gameserver.pathfinding.AbstractNodeLoc;
import com.l2jserver.geodriver.Cell;
/**
* @author -Nemesiss-, HorridoJoho
@@ -44,10 +44,10 @@ public class NodeLoc extends AbstractNodeLoc
{
_x = x;
_y = y;
_goNorth = GeoData.getInstance().canEnterNeighbors(x, y, z, Direction.NORTH);
_goEast = GeoData.getInstance().canEnterNeighbors(x, y, z, Direction.EAST);
_goSouth = GeoData.getInstance().canEnterNeighbors(x, y, z, Direction.SOUTH);
_goWest = GeoData.getInstance().canEnterNeighbors(x, y, z, Direction.WEST);
_goNorth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_NORTH);
_goEast = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_EAST);
_goSouth = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_SOUTH);
_goWest = GeoData.getInstance().checkNearestNswe(x, y, z, Cell.NSWE_WEST);
_geoHeight = GeoData.getInstance().getNearestZ(x, y, z);
}
@@ -120,28 +120,27 @@ public class NodeLoc extends AbstractNodeLoc
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + _x;
result = (prime * result) + _y;
byte nswe = 0;
int nswe = 0;
if (canGoNorth())
{
nswe |= 1;
nswe |= Cell.NSWE_NORTH;
}
if (canGoEast())
{
nswe |= 1 << 1;
nswe |= Cell.NSWE_EAST;
}
if (canGoSouth())
{
nswe |= 1 << 2;
nswe |= Cell.NSWE_SOUTH;
}
if (canGoEast())
{
nswe |= 1 << 3;
nswe |= Cell.NSWE_EAST;
}
result = (prime * result) + (((_geoHeight & 0xFFFF) << 1) | nswe);
@@ -44,6 +44,7 @@ import com.l2jserver.gameserver.taskmanager.tasks.TaskBirthday;
import com.l2jserver.gameserver.taskmanager.tasks.TaskClanLeaderApply;
import com.l2jserver.gameserver.taskmanager.tasks.TaskCleanUp;
import com.l2jserver.gameserver.taskmanager.tasks.TaskDailySkillReuseClean;
import com.l2jserver.gameserver.taskmanager.tasks.TaskDailyWorldChatPointReset;
import com.l2jserver.gameserver.taskmanager.tasks.TaskGlobalVariablesSave;
import com.l2jserver.gameserver.taskmanager.tasks.TaskOlympiadSave;
import com.l2jserver.gameserver.taskmanager.tasks.TaskRaidPointsReset;
@@ -51,6 +52,7 @@ import com.l2jserver.gameserver.taskmanager.tasks.TaskRecom;
import com.l2jserver.gameserver.taskmanager.tasks.TaskRestart;
import com.l2jserver.gameserver.taskmanager.tasks.TaskScript;
import com.l2jserver.gameserver.taskmanager.tasks.TaskShutdown;
import com.l2jserver.gameserver.taskmanager.tasks.TaskVitalityReset;
/**
* @author Layane
@@ -188,6 +190,7 @@ public final class TaskManager
registerTask(new TaskClanLeaderApply());
registerTask(new TaskCleanUp());
registerTask(new TaskDailySkillReuseClean());
registerTask(new TaskDailyWorldChatPointReset());
registerTask(new TaskGlobalVariablesSave());
registerTask(new TaskOlympiadSave());
registerTask(new TaskRaidPointsReset());
@@ -195,6 +198,7 @@ public final class TaskManager
registerTask(new TaskRestart());
registerTask(new TaskScript());
registerTask(new TaskShutdown());
registerTask(new TaskVitalityReset());
}
public void registerTask(Task task)
@@ -0,0 +1,76 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.taskmanager.tasks;
import java.sql.Connection;
import java.sql.PreparedStatement;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.ExWorldChatCnt;
import com.l2jserver.gameserver.taskmanager.Task;
import com.l2jserver.gameserver.taskmanager.TaskManager;
import com.l2jserver.gameserver.taskmanager.TaskManager.ExecutedTask;
import com.l2jserver.gameserver.taskmanager.TaskTypes;
public class TaskDailyWorldChatPointReset extends Task
{
private static final String NAME = "daily_world_chat_reset";
@Override
public String getName()
{
return NAME;
}
@Override
public void onTimeElapsed(ExecutedTask task)
{
// Update data for offline players.
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE character_variables SET val = ? WHERE var = ?"))
{
ps.setInt(1, Config.WORLD_CHAT_POINTS_PER_DAY);
ps.setString(1, L2PcInstance.WORLD_CHAT_VARIABLE_NAME);
ps.executeUpdate();
}
catch (Exception e)
{
_log.severe(getClass().getSimpleName() + ": Could not reset daily world chat points: " + e);
}
// Update data for online players.
L2World.getInstance().getPlayers().stream().forEach(player ->
{
player.setWorldChatPoints(Config.WORLD_CHAT_POINTS_PER_DAY);
player.sendPacket(new ExWorldChatCnt(player));
player.getVariables().storeMe();
});
_log.info("Daily world chat points has been resetted.");
}
@Override
public void initializate()
{
TaskManager.addUniqueTask(getName(), TaskTypes.TYPE_GLOBAL_TASK, "1", Config.WORLD_CHAT_RESET_TIME, "");
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) 2004-2014 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.gameserver.taskmanager.tasks;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Calendar;
import java.util.logging.Level;
import com.l2jserver.Config;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.model.actor.stat.PcStat;
import com.l2jserver.gameserver.taskmanager.Task;
import com.l2jserver.gameserver.taskmanager.TaskManager;
import com.l2jserver.gameserver.taskmanager.TaskManager.ExecutedTask;
import com.l2jserver.gameserver.taskmanager.TaskTypes;
/**
* @author UnAfraid
*/
public class TaskVitalityReset extends Task
{
private static final String NAME = "vitalityreset";
@Override
public String getName()
{
return NAME;
}
@Override
public void onTimeElapsed(ExecutedTask task)
{
Calendar cal = Calendar.getInstance();
if (cal.get(Calendar.DAY_OF_WEEK) == Config.ALT_VITALITY_DATE_RESET)
{
for (L2PcInstance player : L2World.getInstance().getPlayers())
{
player.setVitalityPoints(PcStat.MAX_VITALITY_POINTS, false);
}
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement st = con.prepareStatement("DELETE FROM account_gsdata WHERE var = ?"))
{
st.setString(1, PcStat.VITALITY_VARIABLE);
st.execute();
}
catch (Exception e)
{
_log.log(Level.WARNING, "", e);
}
_log.info(getClass().getSimpleName() + ": launched.");
}
}
@Override
public void initializate()
{
TaskManager.addUniqueTask(NAME, TaskTypes.TYPE_GLOBAL_TASK, "1", Config.ALT_VITALITY_HOUR_RESET, "");
}
}
@@ -21,9 +21,9 @@ package com.l2jserver.gameserver.util;
import java.awt.Color;
import com.l2jserver.gameserver.GeoData;
import com.l2jserver.gameserver.geoengine.Direction;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.ExServerPrimitive;
import com.l2jserver.geodriver.Cell;
/**
* @author HorridoJoho
@@ -93,9 +93,9 @@ public final class GeoUtils
player.sendPacket(prim);
}
private static Color getDirectionColor(int x, int y, int z, Direction dir)
private static Color getDirectionColor(int x, int y, int z, int nswe)
{
if (GeoData.getInstance().canEnterNeighbors(x, y, z, dir))
if (GeoData.getInstance().checkNearestNswe(x, y, z, nswe, 100))
{
return Color.GREEN;
}
@@ -146,27 +146,27 @@ public final class GeoUtils
int z = gd.getNearestZ(gx, gy, player.getZ());
// north arrow
Color col = getDirectionColor(gx, gy, z, Direction.NORTH);
Color col = getDirectionColor(gx, gy, z, Cell.NSWE_NORTH);
exsp.addLine(col, x - 1, y - 7, z, x + 1, y - 7, z);
exsp.addLine(col, x - 2, y - 6, z, x + 2, y - 6, z);
exsp.addLine(col, x - 3, y - 5, z, x + 3, y - 5, z);
exsp.addLine(col, x - 4, y - 4, z, x + 4, y - 4, z);
// east arrow
col = getDirectionColor(gx, gy, z, Direction.EAST);
col = getDirectionColor(gx, gy, z, Cell.NSWE_EAST);
exsp.addLine(col, x + 7, y - 1, z, x + 7, y + 1, z);
exsp.addLine(col, x + 6, y - 2, z, x + 6, y + 2, z);
exsp.addLine(col, x + 5, y - 3, z, x + 5, y + 3, z);
exsp.addLine(col, x + 4, y - 4, z, x + 4, y + 4, z);
// south arrow
col = getDirectionColor(gx, gy, z, Direction.SOUTH);
col = getDirectionColor(gx, gy, z, Cell.NSWE_SOUTH);
exsp.addLine(col, x - 1, y + 7, z, x + 1, y + 7, z);
exsp.addLine(col, x - 2, y + 6, z, x + 2, y + 6, z);
exsp.addLine(col, x - 3, y + 5, z, x + 3, y + 5, z);
exsp.addLine(col, x - 4, y + 4, z, x + 4, y + 4, z);
col = getDirectionColor(gx, gy, z, Direction.WEST);
col = getDirectionColor(gx, gy, z, Cell.NSWE_WEST);
exsp.addLine(col, x - 7, y - 1, z, x - 7, y + 1, z);
exsp.addLine(col, x - 6, y - 2, z, x - 6, y + 2, z);
exsp.addLine(col, x - 5, y - 3, z, x - 5, y + 3, z);
@@ -180,7 +180,7 @@ public final class GeoUtils
}
/**
* difference between x values: never abover 1<br>
* difference between x values: never above 1<br>
* difference between y values: never above 1
* @param lastX
* @param lastY
@@ -188,36 +188,36 @@ public final class GeoUtils
* @param y
* @return
*/
public static Direction computeDirection(int lastX, int lastY, int x, int y)
public static int computeNswe(int lastX, int lastY, int x, int y)
{
if (x > lastX) // east
{
if (y > lastY)
{
return Direction.SOUTH_EAST;
return Cell.NSWE_SOUTH_EAST;// Direction.SOUTH_EAST;
}
else if (y < lastY)
{
return Direction.NORTH_EAST;
return Cell.NSWE_NORTH_EAST;// Direction.NORTH_EAST;
}
else
{
return Direction.EAST;
return Cell.NSWE_EAST;// Direction.EAST;
}
}
else if (x < lastX) // west
{
if (y > lastY)
{
return Direction.SOUTH_WEST;
return Cell.NSWE_SOUTH_WEST;// Direction.SOUTH_WEST;
}
else if (y < lastY)
{
return Direction.NORTH_WEST;
return Cell.NSWE_NORTH_WEST;// Direction.NORTH_WEST;
}
else
{
return Direction.WEST;
return Cell.NSWE_WEST;// Direction.WEST;
}
}
else
@@ -225,15 +225,15 @@ public final class GeoUtils
{
if (y > lastY)
{
return Direction.SOUTH;
return Cell.NSWE_SOUTH;// Direction.SOUTH;
}
else if (y < lastY)
{
return Direction.NORTH;
return Cell.NSWE_NORTH;// Direction.NORTH;
}
else
{
return null;// error, should never happen, TODO: Logging
throw new RuntimeException();
}
}
}
@@ -34,7 +34,6 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import javolution.io.UTF8StreamReader;
@@ -185,17 +184,17 @@ public final class GameServerTable
* @param gsi the game server information DTO
* @return true, if successful
*/
public boolean registerWithFirstAvaliableId(GameServerInfo gsi)
public boolean registerWithFirstAvailableId(GameServerInfo gsi)
{
// avoid two servers registering with the same "free" id
synchronized (_gameServerTable)
{
for (Entry<Integer, String> entry : _serverNames.entrySet())
for (Integer serverId : _serverNames.keySet())
{
if (!_gameServerTable.containsKey(entry.getKey()))
if (!_gameServerTable.containsKey(serverId))
{
_gameServerTable.put(entry.getKey(), gsi);
gsi.setId(entry.getKey());
_gameServerTable.put(serverId, gsi);
gsi.setId(serverId);
return true;
}
}
@@ -217,7 +216,6 @@ public final class GameServerTable
if (!_gameServerTable.containsKey(id))
{
_gameServerTable.put(id, gsi);
gsi.setId(id);
return true;
}
}
@@ -381,6 +379,12 @@ public final class GameServerTable
return _hexId;
}
public String getName()
{
// this value can't be stored in a private variable because the ID can be changed by setId()
return GameServerTable.getInstance().getServerNameById(_id);
}
/**
* Sets the authed.
* @param isAuthed the new authed
@@ -435,6 +439,20 @@ public final class GameServerTable
return _status;
}
public String getStatusName()
{
switch (_status)
{
case 0: return "Auto";
case 1: return "Good";
case 2: return "Normal";
case 3: return "Full";
case 4: return "Down";
case 5: return "GM Only";
default: return "Unknown";
}
}
/**
* Gets the current player count.
* @return the current player count
@@ -129,7 +129,7 @@ public class GameServerAuth extends BaseRecievePacket
if (Config.ACCEPT_NEW_GAMESERVER && _acceptAlternativeId)
{
gsi = new GameServerInfo(id, hexId, _server);
if (gameServerTable.registerWithFirstAvaliableId(gsi))
if (gameServerTable.registerWithFirstAvailableId(gsi))
{
_server.attachGameServerInfo(gsi, _port, _hosts, _maxPlayers);
gameServerTable.registerServerOnDB(gsi);
@@ -32,16 +32,6 @@ public class ServerStatus extends BaseRecievePacket
{
protected static Logger _log = Logger.getLogger(ServerStatus.class.getName());
public static final String[] STATUS_STRING =
{
"Auto",
"Good",
"Normal",
"Full",
"Down",
"Gm Only"
};
public static final int SERVER_LIST_STATUS = 0x01;
public static final int SERVER_TYPE = 0x02;
public static final int SERVER_LIST_SQUARE_BRACKET = 0x03;
@@ -27,11 +27,13 @@ import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import com.l2jserver.Config;
import com.l2jserver.loginserver.GameServerTable;
import com.l2jserver.loginserver.GameServerTable.GameServerInfo;
import com.l2jserver.loginserver.L2LoginServer;
import com.l2jserver.loginserver.LoginController;
@@ -209,8 +211,29 @@ public class LoginStatusThread extends Thread
}
else if (_usrCommand.equals("status"))
{
// TODO enhance the output
_print.println("Registered Server Count: " + GameServerTable.getInstance().getRegisteredGameServers().size());
final Map<Integer, GameServerInfo> gslist = GameServerTable.getInstance().getRegisteredGameServers();
if (gslist.isEmpty())
{
_print.println("Registered Servers: 0");
}
else
{
_print.println("=== Registered Servers ===");
_print.println("ID\tName\tStatus\tPlayers online");
gslist.forEach((id, gsinfo) ->
{
_print.print(id);
_print.print("\t");
_print.print(gsinfo.getName());
_print.print("\t");
_print.print(gsinfo.getStatusName());
_print.print("\t");
_print.print(gsinfo.getCurrentPlayerCount());
_print.println();
});
}
}
else if (_usrCommand.startsWith("unblock"))
{
@@ -1,58 +0,0 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.tools.dbinstaller;
import java.awt.HeadlessException;
import javax.swing.UIManager;
import com.l2jserver.tools.dbinstaller.console.DBInstallerConsole;
import com.l2jserver.tools.dbinstaller.gui.DBConfigGUI;
/**
* Contains main class for Database Installer If system doesn't support the graphical UI, start the installer in console mode.
* @author mrTJO
*/
public class LauncherCS
{
public static void main(String[] args)
{
String mode = "l2jcs";
String dir = "../sql/community/";
String cleanUp = "cs_cleanup.sql";
try
{
// Set OS Look And Feel
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
}
try
{
new DBConfigGUI(mode, dir, cleanUp);
}
catch (HeadlessException e)
{
new DBInstallerConsole(mode, dir, cleanUp);
}
}
}
@@ -24,8 +24,8 @@ import java.util.prefs.Preferences;
import com.l2jserver.tools.dbinstaller.DBOutputInterface;
import com.l2jserver.tools.dbinstaller.RunTasks;
import com.l2jserver.tools.dbinstaller.util.CloseShieldedInputStream;
import com.l2jserver.tools.dbinstaller.util.mysql.MySqlConnect;
import com.l2jserver.util.CloseShieldedInputStream;
/**
* @author mrTJO
@@ -16,7 +16,7 @@
* 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.l2jserver.util;
package com.l2jserver.tools.dbinstaller.util;
import java.io.IOException;
import java.io.InputStream;
@@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.time.Duration;
import java.util.Properties;
import java.util.logging.Logger;
@@ -242,4 +243,34 @@ public final class PropertiesParser
return defaultValue;
}
}
/**
* @param durationPattern
* @param defaultValue
* @return {@link Duration} object by the durationPattern specified, {@code null} in case of malformed pattern.
*/
public Duration getDuration(String durationPattern, String defaultValue)
{
return getDuration(durationPattern, defaultValue, null);
}
/**
* @param durationPattern
* @param defaultValue
* @param defaultDuration
* @return {@link Duration} object by the durationPattern specified, the defaultDuration in case of malformed pattern.
*/
public Duration getDuration(String durationPattern, String defaultValue, Duration defaultDuration)
{
final String value = getString(durationPattern, defaultValue);
try
{
return TimeUtil.parseDuration(value);
}
catch (IllegalStateException e)
{
_log.warning("[" + _file.getName() + "] Invalid value specified for key: " + durationPattern + " specified value: " + value + " should be time patttern using default value: " + defaultValue);
}
return defaultDuration;
}
}
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright (C) 2004-2015 L2J Server
*
* This file is part of L2J Server.
*
* L2J Server 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.
*
* L2J Server 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.l2jserver.util;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
/**
* @author UnAfraid
*/
public class TimeUtil
{
public static int findIndexOfNonDigit(CharSequence text)
{
for (int i = 0; i < text.length(); i++)
{
if (Character.isDigit(text.charAt(i)))
{
continue;
}
return i;
}
return -1;
}
/**
* Parses patterns like:
* <ul>
* <li>1min or 10mins</li>
* <li>1day or 10days</li>
* <li>1week or 4weeks</li>
* <li>1month or 12months</li>
* <li>1year or 5years</li>
* </ul>
* @param datePattern
* @return {@link Duration} object converted by the date pattern specified.
* @throws IllegalStateException when malformed pattern specified.
*/
public static Duration parseDuration(String datePattern)
{
final int index = findIndexOfNonDigit(datePattern);
if (index == -1)
{
throw new IllegalStateException("Incorrect time format given: " + datePattern);
}
try
{
int val = Integer.parseInt(datePattern.substring(0, index));
final String type = datePattern.substring(index);
final ChronoUnit unit;
switch (type.toLowerCase())
{
case "sec":
case "secs":
{
unit = ChronoUnit.SECONDS;
break;
}
case "min":
case "mins":
{
unit = ChronoUnit.MINUTES;
break;
}
case "hour":
case "hours":
{
unit = ChronoUnit.HOURS;
break;
}
case "day":
case "days":
{
unit = ChronoUnit.DAYS;
break;
}
case "week":
case "weeks":
{
unit = ChronoUnit.WEEKS;
break;
}
case "month":
case "months":
{
unit = ChronoUnit.MONTHS;
break;
}
case "year":
case "years":
{
unit = ChronoUnit.YEARS;
break;
}
default:
{
unit = ChronoUnit.valueOf(type);
if (unit == null)
{
throw new IllegalStateException("Incorrect format: " + type + " !!");
}
}
}
return Duration.of(val, unit);
}
catch (Exception e)
{
throw new IllegalStateException("Incorrect time format given: " + datePattern + " val: " + datePattern.substring(0, index));
}
}
}