Sync with L2jUnity (7db5b4f).

This commit is contained in:
MobiusDev
2016-12-04 21:28:20 +00:00
parent 9e1d3569f0
commit b9d3c99cf1
412 changed files with 13806 additions and 10065 deletions

View File

@@ -468,7 +468,6 @@ public class GeoData
if (WarpedSpaceManager.getInstance().checkForWarpedSpace(new Location(x, y, z), new Location(tx, ty, tz), instance))
{
System.out.println("there is a warp space in path !");
return new Location(x, y, getHeight(x, y, z));
}

View File

@@ -31,6 +31,7 @@ import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.interfaces.ILocational;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
@@ -510,6 +511,11 @@ public abstract class AbstractAI implements Ctrl
}
}
public void moveTo(ILocational loc)
{
moveTo(loc.getX(), loc.getY(), loc.getZ());
}
/**
* Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation <I>(broadcast)</I>.<br>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : Low level function, used by AI subclasses</B></FONT>

View File

@@ -34,7 +34,7 @@ import com.l2jmobius.gameserver.model.actor.L2Summon;
public class SummonSkillsTable
{
private static Logger LOGGER = Logger.getLogger(SummonSkillsTable.class.getName());
private final Map<Integer, Map<Integer, L2PetSkillLearn>> _skillTrees = new HashMap<>();
private final Map<Integer, Map<Long, L2PetSkillLearn>> _skillTrees = new HashMap<>();
protected SummonSkillsTable()
{
@@ -52,7 +52,7 @@ public class SummonSkillsTable
while (rs.next())
{
final int npcId = rs.getInt("templateId");
Map<Integer, L2PetSkillLearn> skillTree = _skillTrees.get(npcId);
Map<Long, L2PetSkillLearn> skillTree = _skillTrees.get(npcId);
if (skillTree == null)
{
skillTree = new HashMap<>();
@@ -110,9 +110,12 @@ public class SummonSkillsTable
}
break;
}
if ((temp.getMinLevel() <= cha.getLevel()) && (temp.getLevel() > lvl))
else if (temp.getMinLevel() <= cha.getLevel())
{
lvl = temp.getLevel();
if (temp.getLevel() > lvl)
{
lvl = temp.getLevel();
}
}
}
return lvl;

View File

@@ -37,7 +37,7 @@ public class AlchemyData implements IGameXmlReader
{
private static final Logger LOGGER = Logger.getLogger(AlchemyData.class.getName());
private final Map<Integer, AlchemyCraftData> _alchemy = new HashMap<>();
private final Map<Long, AlchemyCraftData> _alchemy = new HashMap<>();
protected AlchemyData()
{
@@ -112,8 +112,7 @@ public class AlchemyData implements IGameXmlReader
}
}
}
final int skillHashCode = SkillData.getSkillHashCode(set.getInt("id"), set.getInt("level"));
_alchemy.put(skillHashCode, alchemyCraft);
_alchemy.put(SkillData.getSkillHashCode(set.getInt("id"), set.getInt("level")), alchemyCraft);
}
}
}

View File

@@ -31,9 +31,10 @@ import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.templates.L2CubicTemplate;
import com.l2jmobius.gameserver.model.cubic.CubicSkill;
import com.l2jmobius.gameserver.model.cubic.ICubicConditionHolder;
import com.l2jmobius.gameserver.model.cubic.conditions.GeneralCondition;
import com.l2jmobius.gameserver.model.cubic.conditions.GeneralCondition.GeneralConditionType;
import com.l2jmobius.gameserver.model.cubic.conditions.HealthCondition;
import com.l2jmobius.gameserver.model.cubic.conditions.HpCondition;
import com.l2jmobius.gameserver.model.cubic.conditions.HpCondition.HpConditionType;
import com.l2jmobius.gameserver.model.cubic.conditions.RangeCondition;
/**
* @author UnAfraid
@@ -102,12 +103,17 @@ public class CubicData implements IGameXmlReader
{
switch (conditionNode.getNodeName())
{
case "general":
case "hp":
{
final GeneralConditionType type = parseEnum(conditionNode.getAttributes(), GeneralConditionType.class, "type");
final int hpPer = parseInteger(conditionNode.getAttributes(), "hpPercent");
final int hp = parseInteger(conditionNode.getAttributes(), "hp");
holder.addCondition(new GeneralCondition(type, hpPer, hp));
final HpConditionType type = parseEnum(conditionNode.getAttributes(), HpConditionType.class, "type");
final int hpPer = parseInteger(conditionNode.getAttributes(), "percent");
holder.addCondition(new HpCondition(type, hpPer));
break;
}
case "range":
{
final int range = parseInteger(conditionNode.getAttributes(), "value");
holder.addCondition(new RangeCondition(range));
break;
}
case "healthPercent":

View File

@@ -17,21 +17,22 @@
package com.l2jmobius.gameserver.data.xml.impl;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.IGameXmlReader;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.enums.SkillEnchantType;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.holders.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.skills.Skill;
/**
@@ -42,29 +43,10 @@ public class EnchantSkillGroupsData implements IGameXmlReader
{
private static final Logger LOGGER = Logger.getLogger(EnchantSkillGroupsData.class.getName());
public static final int NORMAL_ENCHANT_COST_MULTIPLIER = Config.NORMAL_ENCHANT_COST_MULTIPLIER;
public static final int SAFE_ENCHANT_COST_MULTIPLIER = Config.SAFE_ENCHANT_COST_MULTIPLIER;
private final Map<Integer, EnchantSkillHolder> _enchantSkillHolders = new LinkedHashMap<>();
private final Map<SkillHolder, Set<Integer>> _enchantSkillTrees = new HashMap<>();
public static final int NORMAL_ENCHANT_BOOK_OLD = 6622;
public static final int SAFE_ENCHANT_BOOK_OLD = 9627;
public static final int CHANGE_ENCHANT_BOOK_OLD = 9626;
public static final int UNTRAIN_ENCHANT_BOOK_OLD = 9625;
public static final int NORMAL_ENCHANT_BOOK = 30297;
public static final int SAFE_ENCHANT_BOOK = 30298;
public static final int CHANGE_ENCHANT_BOOK = 30299;
public static final int UNTRAIN_ENCHANT_BOOK = 30300;
public static final int IMMORTAL_SCROLL = 37044;
public static final int NORMAL_ENCHANT_BOOK_V2 = 46150;
public static final int SAFE_ENCHANT_BOOK_V2 = 46151;
public static final int CHANGE_ENCHANT_BOOK_V2 = 46152;
public static final int IMMORTAL_SCROLL_V2 = 46153;
public static final int NORMAL_ENCHANT_BOOK_V3 = 46154;
public static final int SAFE_ENCHANT_BOOK_V3 = 46155;
public static final int CHANGE_ENCHANT_BOOK_V3 = 46156;
public static final int IMMORTAL_SCROLL_V3 = 46157;
private final Map<Integer, L2EnchantSkillGroup> _enchantSkillGroups = new HashMap<>();
private final Map<Integer, L2EnchantSkillLearn> _enchantSkillTrees = new HashMap<>();
public static int MAX_ENCHANT_LEVEL;
/**
* Instantiates a new enchant groups table.
@@ -77,188 +59,78 @@ public class EnchantSkillGroupsData implements IGameXmlReader
@Override
public void load()
{
_enchantSkillGroups.clear();
_enchantSkillTrees.clear();
parseDatapackFile("data/EnchantSkillGroups.xml");
int routes = 0;
for (L2EnchantSkillGroup group : _enchantSkillGroups.values())
{
routes += group.getEnchantGroupDetails().size();
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _enchantSkillGroups.size() + " groups and " + routes + " routes.");
_enchantSkillHolders.clear();
parseDatapackFile("data/enchantSkillGroups.xml");
MAX_ENCHANT_LEVEL = _enchantSkillHolders.size();
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _enchantSkillHolders.size() + " enchant routes, max enchant set to " + MAX_ENCHANT_LEVEL + ".");
}
@Override
public void parseDocument(Document doc, File f)
{
NamedNodeMap attrs;
StatsSet set;
Node att;
int id = 0;
L2EnchantSkillGroup group;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
forEach(doc, "list", listNode -> forEach(listNode, "enchant", enchantNode ->
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("group".equalsIgnoreCase(d.getNodeName()))
{
attrs = d.getAttributes();
id = parseInteger(attrs, "id");
group = _enchantSkillGroups.get(id);
if (group == null)
{
group = new L2EnchantSkillGroup(id);
_enchantSkillGroups.put(id, group);
}
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("enchant".equalsIgnoreCase(b.getNodeName()))
{
attrs = b.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
group.addEnchantDetail(new EnchantSkillHolder(set));
}
}
}
}
}
}
}
/**
* Adds the new route for skill.
* @param skillId the skill id
* @param maxLvL the max lvl
* @param route the route
* @param group the group
* @return the int
*/
public int addNewRouteForSkill(int skillId, int maxLvL, int route, int group)
{
L2EnchantSkillLearn enchantableSkill = _enchantSkillTrees.get(skillId);
if (enchantableSkill == null)
{
enchantableSkill = new L2EnchantSkillLearn(skillId, maxLvL);
_enchantSkillTrees.put(skillId, enchantableSkill);
}
if (_enchantSkillGroups.containsKey(group))
{
enchantableSkill.addNewEnchantRoute(route, group);
final EnchantSkillHolder enchantSkillHolder = new EnchantSkillHolder(new StatsSet(parseAttributes(enchantNode)));
return _enchantSkillGroups.get(group).getEnchantGroupDetails().size();
}
LOGGER.severe(getClass().getSimpleName() + ": Error while loading generating enchant skill id: " + skillId + "; route: " + route + " missing group: " + group);
return 0;
}
/**
* Gets the skill enchantment for skill.
* @param skill the skill
* @return the skill enchantment for skill
*/
public L2EnchantSkillLearn getSkillEnchantmentForSkill(Skill skill)
{
// there is enchantment for this skill and we have the required level of it
final L2EnchantSkillLearn esl = getSkillEnchantmentBySkillId(skill.getId());
if ((esl != null) && (skill.getLevel() >= esl.getBaseLevel()))
{
return esl;
}
return null;
}
/**
* Gets the skill enchantment by skill id.
* @param skillId the skill id
* @return the skill enchantment by skill id
*/
public L2EnchantSkillLearn getSkillEnchantmentBySkillId(int skillId)
{
return _enchantSkillTrees.get(skillId);
}
/**
* Gets the enchant skill group by id.
* @param id the id
* @return the enchant skill group by id
*/
public L2EnchantSkillGroup getEnchantSkillGroupById(int id)
{
return _enchantSkillGroups.get(id);
}
/**
* Gets the enchant skill sp cost.
* @param skill the skill
* @return the enchant skill sp cost
*/
public int getEnchantSkillSpCost(Skill skill)
{
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
if (enchantSkillLearn != null)
{
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
if (esh != null)
forEach(enchantNode, "sps", spsNode -> forEach(spsNode, "sp", spNode ->
{
return esh.getSpCost();
}
}
return Integer.MAX_VALUE;
}
/**
* Gets the enchant skill Adena cost.
* @param skill the skill
* @return the enchant skill Adena cost
*/
public int getEnchantSkillAdenaCost(Skill skill)
{
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
if (enchantSkillLearn != null)
{
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
if (esh != null)
enchantSkillHolder.addSp(parseEnum(spNode.getAttributes(), SkillEnchantType.class, "type"), parseInteger(spNode.getAttributes(), "amount"));
}));
forEach(enchantNode, "chances", chancesNode -> forEach(chancesNode, "chance", chanceNode ->
{
return esh.getAdenaCost();
}
}
return Integer.MAX_VALUE;
}
/**
* Gets the enchant skill rate.
* @param player the player
* @param skill the skill
* @return the enchant skill rate
*/
public byte getEnchantSkillRate(L2PcInstance player, Skill skill)
{
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
if (enchantSkillLearn != null)
{
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
if (esh != null)
enchantSkillHolder.addChance(parseEnum(chanceNode.getAttributes(), SkillEnchantType.class, "type"), parseInteger(chanceNode.getAttributes(), "value"));
}));
forEach(enchantNode, "items", itemsNode -> forEach(itemsNode, "item", itemNode ->
{
return esh.getRate(player);
}
}
return 0;
enchantSkillHolder.addRequiredItem(parseEnum(itemNode.getAttributes(), SkillEnchantType.class, "type"), new ItemHolder(new StatsSet(parseAttributes(itemNode))));
}));
_enchantSkillHolders.put(parseInteger(enchantNode.getAttributes(), "level"), enchantSkillHolder);
}));
}
public void addRouteForSkill(int skillId, int level, int route)
{
addRouteForSkill(new SkillHolder(skillId, level), route);
}
public void addRouteForSkill(SkillHolder holder, int route)
{
_enchantSkillTrees.computeIfAbsent(holder, k -> new HashSet<>()).add(route);
}
public Set<Integer> getRouteForSkill(int skillId, int level)
{
return getRouteForSkill(skillId, level, 0);
}
public Set<Integer> getRouteForSkill(int skillId, int level, int subLevel)
{
return getRouteForSkill(new SkillHolder(skillId, level, subLevel));
}
public Set<Integer> getRouteForSkill(SkillHolder holder)
{
return _enchantSkillTrees.getOrDefault(holder, Collections.emptySet());
}
public boolean isEnchantable(Skill skill)
{
return isEnchantable(new SkillHolder(skill.getId(), skill.getLevel()));
}
public boolean isEnchantable(SkillHolder holder)
{
return _enchantSkillTrees.containsKey(holder);
}
public EnchantSkillHolder getEnchantSkillHolder(int level)
{
return _enchantSkillHolders.getOrDefault(level, null);
}
/**
* Gets the single instance of EnchantGroupsData.
* @return single instance of EnchantGroupsData
*/
public static EnchantSkillGroupsData getInstance()
{
return SingletonHolder._instance;

View File

@@ -225,7 +225,7 @@ public final class InitialShortcutData implements IGameXmlReader
final int shortcutId = parseInteger(attrs, "shortcutId");
final int shortcutLevel = parseInteger(attrs, "shortcutLevel", 0);
final int characterType = parseInteger(attrs, "characterType", 0);
return new Shortcut(slotId, pageId, shortcutType, shortcutId, shortcutLevel, characterType);
return new Shortcut(slotId, pageId, shortcutType, shortcutId, shortcutLevel, 0, characterType);
}
/**
@@ -305,7 +305,7 @@ public final class InitialShortcutData implements IGameXmlReader
}
// Register shortcut
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getCharacterType());
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getSubLevel(), shortcut.getCharacterType());
player.sendPacket(new ShortCutRegister(newShortcut));
player.registerShortCut(newShortcut);
}
@@ -348,7 +348,7 @@ public final class InitialShortcutData implements IGameXmlReader
}
}
// Register shortcut
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getCharacterType());
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getSubLevel(), shortcut.getCharacterType());
player.sendPacket(new ShortCutRegister(newShortcut));
player.registerShortCut(newShortcut);
}

View File

@@ -56,9 +56,8 @@ public class SkillData implements IGameXmlReader
{
private static final Logger LOGGER = Logger.getLogger(SkillData.class.getName());
private final Map<Integer, Skill> _skills = new HashMap<>();
private final Map<Long, Skill> _skills = new HashMap<>();
private final Map<Integer, Integer> _skillsMaxLevel = new HashMap<>();
private final Set<Integer> _enchantable = new HashSet<>();
private class NamedParamInfo
{
@@ -68,9 +67,8 @@ public class SkillData implements IGameXmlReader
private final Integer _fromSubLevel;
private final Integer _toSubLevel;
private final Map<Integer, Map<Integer, StatsSet>> _info;
private final StatsSet _generalInfo;
public NamedParamInfo(String name, Integer fromLevel, Integer toLevel, Integer fromSubLevel, Integer toSubLevel, Map<Integer, Map<Integer, StatsSet>> info, StatsSet generalInfo)
public NamedParamInfo(String name, Integer fromLevel, Integer toLevel, Integer fromSubLevel, Integer toSubLevel, Map<Integer, Map<Integer, StatsSet>> info)
{
_name = name;
_fromLevel = fromLevel;
@@ -78,7 +76,6 @@ public class SkillData implements IGameXmlReader
_fromSubLevel = fromSubLevel;
_toSubLevel = toSubLevel;
_info = info;
_generalInfo = generalInfo;
}
public String getName()
@@ -110,11 +107,6 @@ public class SkillData implements IGameXmlReader
{
return _info;
}
public StatsSet getGeneralInfo()
{
return _generalInfo;
}
}
protected SkillData()
@@ -127,9 +119,9 @@ public class SkillData implements IGameXmlReader
* @param skill The L2Skill to be hashed
* @return getSkillHashCode(skill.getId(), skill.getLevel())
*/
public static int getSkillHashCode(Skill skill)
public static long getSkillHashCode(Skill skill)
{
return getSkillHashCode(skill.getId(), skill.getLevel());
return getSkillHashCode(skill.getId(), skill.getLevel(), skill.getSubLevel());
}
/**
@@ -138,14 +130,31 @@ public class SkillData implements IGameXmlReader
* @param skillLevel The Skill Level
* @return The Skill hash number
*/
public static int getSkillHashCode(int skillId, int skillLevel)
public static long getSkillHashCode(int skillId, int skillLevel)
{
return (skillId * 1031) + skillLevel;
return getSkillHashCode(skillId, skillLevel, 0);
}
/**
* Centralized method for easier change of the hashing sys
* @param skillId The Skill Id
* @param skillLevel The Skill Level
* @param subSkillLevel The skill sub level
* @return The Skill hash number
*/
public static long getSkillHashCode(int skillId, int skillLevel, int subSkillLevel)
{
return subSkillLevel > 0 ? ((skillId * 4294967296L) + (subSkillLevel * 65536) + skillLevel) : (skillId * 65536) + skillLevel;
}
public Skill getSkill(int skillId, int level)
{
final Skill result = _skills.get(getSkillHashCode(skillId, level));
return getSkill(skillId, level, 0);
}
public Skill getSkill(int skillId, int level, int subLevel)
{
final Skill result = _skills.get(getSkillHashCode(skillId, level, subLevel));
if (result != null)
{
return result;
@@ -156,7 +165,7 @@ public class SkillData implements IGameXmlReader
// requested level too high
if ((maxLvl > 0) && (level > maxLvl))
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Call to unexisting skill level id: " + skillId + " requested level: " + level + " max level: " + maxLvl, new Throwable());
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Call to unexisting skill level id: " + skillId + " requested level: " + level + " max level: " + maxLvl + ".", new Throwable());
return _skills.get(getSkillHashCode(skillId, maxLvl));
}
@@ -170,16 +179,6 @@ public class SkillData implements IGameXmlReader
return maxLevel != null ? maxLevel : 0;
}
/**
* Verifies if the given skill ID correspond to an enchantable skill.
* @param skillId the skill ID
* @return {@code true} if the skill is enchantable, {@code false} otherwise
*/
public boolean isEnchantable(int skillId)
{
return _enchantable.contains(skillId);
}
/**
* @param addNoble
* @param hasCastle
@@ -217,7 +216,6 @@ public class SkillData implements IGameXmlReader
{
_skills.clear();
_skillsMaxLevel.clear();
_enchantable.clear();
parseDatapackDirectory("data/stats/skills/", true);
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _skills.size() + " Skills.");
}
@@ -243,12 +241,11 @@ public class SkillData implements IGameXmlReader
NamedNodeMap attributes = listNode.getAttributes();
final Map<Integer, Set<Integer>> levels = new HashMap<>();
final Map<Integer, Map<Integer, StatsSet>> skillInfo = new HashMap<>();
final StatsSet generalSkillInfo = new StatsSet();
final StatsSet generalSkillInfo = skillInfo.computeIfAbsent(-1, k -> new HashMap<>()).computeIfAbsent(-1, k -> new StatsSet());
parseAttributes(attributes, "", generalSkillInfo);
final Map<String, Map<Integer, Map<Integer, Object>>> variableValues = new HashMap<>();
final Map<String, Object> variableGeneralValues = new HashMap<>();
final Map<EffectScope, List<NamedParamInfo>> effectParamInfo = new HashMap<>();
final Map<SkillConditionScope, List<NamedParamInfo>> conditionParamInfo = new HashMap<>();
for (Node skillNode = listNode.getFirstChild(); skillNode != null; skillNode = skillNode.getNextSibling())
@@ -260,7 +257,7 @@ public class SkillData implements IGameXmlReader
{
attributes = skillNode.getAttributes();
final String name = "@" + parseString(attributes, "name");
variableGeneralValues.put(name, parseValues(skillNode, variableValues.computeIfAbsent(name, k -> new HashMap<>())));
variableValues.put(name, parseValues(skillNode));
break;
}
case "#text":
@@ -278,7 +275,7 @@ public class SkillData implements IGameXmlReader
{
case "effect":
{
effectParamInfo.computeIfAbsent(effectScope, k -> new LinkedList<>()).add(parseNamedParamInfo(effectsNode, variableValues, variableGeneralValues));
effectParamInfo.computeIfAbsent(effectScope, k -> new LinkedList<>()).add(parseNamedParamInfo(effectsNode, variableValues));
break;
}
}
@@ -294,7 +291,7 @@ public class SkillData implements IGameXmlReader
{
case "condition":
{
conditionParamInfo.computeIfAbsent(skillConditionScope, k -> new LinkedList<>()).add(parseNamedParamInfo(conditionNode, variableValues, variableGeneralValues));
conditionParamInfo.computeIfAbsent(skillConditionScope, k -> new LinkedList<>()).add(parseNamedParamInfo(conditionNode, variableValues));
break;
}
}
@@ -302,7 +299,7 @@ public class SkillData implements IGameXmlReader
}
else
{
parseInfo(skillNode, variableValues, variableGeneralValues, skillInfo, generalSkillInfo);
parseInfo(skillNode, variableValues, skillInfo);
}
break;
}
@@ -319,8 +316,16 @@ public class SkillData implements IGameXmlReader
skillInfo.forEach((level, subLevelMap) ->
{
if (level == -1)
{
return;
}
subLevelMap.forEach((subLevel, statsSet) ->
{
if (subLevel == -1)
{
return;
}
levels.computeIfAbsent(level, k -> new HashSet<>()).add(subLevel);
});
});
@@ -331,8 +336,16 @@ public class SkillData implements IGameXmlReader
{
namedParamInfo.getInfo().forEach((level, subLevelMap) ->
{
if (level == -1)
{
return;
}
subLevelMap.forEach((subLevel, statsSet) ->
{
if (subLevel == -1)
{
return;
}
levels.computeIfAbsent(level, k -> new HashSet<>()).add(subLevel);
});
});
@@ -362,8 +375,9 @@ public class SkillData implements IGameXmlReader
{
subLevels.forEach(subLevel ->
{
final StatsSet statsSet = Optional.ofNullable(skillInfo.getOrDefault(level, Collections.emptyMap()).get(subLevel)).orElseGet(() -> new StatsSet());
generalSkillInfo.getSet().forEach((k, v) -> statsSet.getSet().putIfAbsent(k, v));
final StatsSet statsSet = Optional.ofNullable(skillInfo.getOrDefault(level, Collections.emptyMap()).get(subLevel)).orElseGet(StatsSet::new);
skillInfo.getOrDefault(level, Collections.emptyMap()).getOrDefault(-1, StatsSet.EMPTY_STATSET).getSet().forEach(statsSet.getSet()::putIfAbsent);
skillInfo.getOrDefault(-1, Collections.emptyMap()).getOrDefault(-1, StatsSet.EMPTY_STATSET).getSet().forEach(statsSet.getSet()::putIfAbsent);
statsSet.set(".level", level);
statsSet.set(".subLevel", subLevel);
final Skill skill = new Skill(statsSet);
@@ -413,9 +427,9 @@ public class SkillData implements IGameXmlReader
_skills.put(getSkillHashCode(skill), skill);
_skillsMaxLevel.merge(skill.getId(), skill.getLevel(), Integer::max);
if ((skill.getLevel() > 99) && !_enchantable.contains(skill.getId()))
if ((skill.getSubLevel() % 1000) == 1)
{
_enchantable.add(skill.getId());
EnchantSkillGroupsData.getInstance().addRouteForSkill(skill.getId(), skill.getLevel(), skill.getSubLevel());
}
});
});
@@ -435,8 +449,9 @@ public class SkillData implements IGameXmlReader
{
if (((namedParamInfo.getFromSubLevel() == null) && (namedParamInfo.getToSubLevel() == null)) || ((namedParamInfo.getFromSubLevel() <= subLevel) && (namedParamInfo.getToSubLevel() >= subLevel)))
{
final StatsSet params = Optional.ofNullable(namedParamInfo.getInfo().getOrDefault(level, Collections.emptyMap()).get(subLevel)).orElseGet(() -> new StatsSet());
namedParamInfo.getGeneralInfo().getSet().forEach((k, v) -> params.getSet().putIfAbsent(k, v));
final StatsSet params = Optional.ofNullable(namedParamInfo.getInfo().getOrDefault(level, Collections.emptyMap()).get(subLevel)).orElseGet(StatsSet::new);
namedParamInfo.getInfo().getOrDefault(level, Collections.emptyMap()).getOrDefault(-1, StatsSet.EMPTY_STATSET).getSet().forEach(params.getSet()::putIfAbsent);
namedParamInfo.getInfo().getOrDefault(-1, Collections.emptyMap()).getOrDefault(-1, StatsSet.EMPTY_STATSET).getSet().forEach(params.getSet()::putIfAbsent);
params.set(".name", namedParamInfo.getName());
consumer.accept(scope, params);
}
@@ -445,58 +460,46 @@ public class SkillData implements IGameXmlReader
});
}
private NamedParamInfo parseNamedParamInfo(Node node, Map<String, Map<Integer, Map<Integer, Object>>> variableValues, Map<String, Object> variableGeneralValues)
private NamedParamInfo parseNamedParamInfo(Node node, Map<String, Map<Integer, Map<Integer, Object>>> variableValues)
{
final NamedNodeMap attributes = node.getAttributes();
final String name = parseString(attributes, "name");
final Integer level = parseInteger(attributes, "level");
final Integer fromLevel = parseInteger(attributes, "fromLevel", level);
final Integer toLevel = parseInteger(attributes, "toLevel", level);
final Integer subLevel = parseInteger(attributes, "subLevel", 0);
final Integer subLevel = parseInteger(attributes, "subLevel");
final Integer fromSubLevel = parseInteger(attributes, "fromSubLevel", subLevel);
final Integer toSubLevel = parseInteger(attributes, "toSubLevel", subLevel);
final Map<Integer, Map<Integer, StatsSet>> info = new HashMap<>();
final StatsSet generalInfo = new StatsSet();
for (node = node.getFirstChild(); node != null; node = node.getNextSibling())
{
if (!node.getNodeName().equals("#text"))
{
parseInfo(node, variableValues, variableGeneralValues, info, generalInfo);
parseInfo(node, variableValues, info);
}
}
return new NamedParamInfo(name, fromLevel, toLevel, fromSubLevel, toSubLevel, info, generalInfo);
return new NamedParamInfo(name, fromLevel, toLevel, fromSubLevel, toSubLevel, info);
}
private void parseInfo(Node node, Map<String, Map<Integer, Map<Integer, Object>>> variableValues, Map<String, Object> variableGeneralValues, Map<Integer, Map<Integer, StatsSet>> info, StatsSet generalInfo)
private void parseInfo(Node node, Map<String, Map<Integer, Map<Integer, Object>>> variableValues, Map<Integer, Map<Integer, StatsSet>> info)
{
Map<Integer, Map<Integer, Object>> values = new HashMap<>();
final Object generalValue = parseValues(node, values);
Map<Integer, Map<Integer, Object>> values = parseValues(node);
final Object generalValue = values.getOrDefault(-1, Collections.emptyMap()).get(-1);
if (generalValue != null)
{
final String stringGeneralValue = String.valueOf(generalValue);
if (stringGeneralValue.startsWith("@"))
{
final Map<Integer, Map<Integer, Object>> tableValue = variableValues.get(stringGeneralValue);
if (tableValue != null)
Map<Integer, Map<Integer, Object>> variableValue = variableValues.get(stringGeneralValue);
if (variableValue != null)
{
if (!tableValue.isEmpty())
{
values = tableValue;
}
else
{
generalInfo.set(node.getNodeName(), variableGeneralValues.get(stringGeneralValue));
}
values = variableValue;
}
else
{
throw new IllegalArgumentException("undefined variable " + stringGeneralValue);
}
}
else
{
generalInfo.set(node.getNodeName(), generalValue);
}
}
values.forEach((level, subLevelMap) ->
@@ -508,60 +511,62 @@ public class SkillData implements IGameXmlReader
});
}
private Object parseValues(Node node, Map<Integer, Map<Integer, Object>> values)
private Map<Integer, Map<Integer, Object>> parseValues(Node node)
{
final Map<Integer, Map<Integer, Object>> values = new HashMap<>();
Object parsedValue = parseValue(node, true, false, Collections.emptyMap());
if (parsedValue != null)
{
return parsedValue;
values.computeIfAbsent(-1, k -> new HashMap<>()).put(-1, parsedValue);
}
final List<Object> list = null;
for (node = node.getFirstChild(); node != null; node = node.getNextSibling())
else
{
if (node.getNodeName().equalsIgnoreCase("value"))
for (node = node.getFirstChild(); node != null; node = node.getNextSibling())
{
final NamedNodeMap attributes = node.getAttributes();
final Integer level = parseInteger(attributes, "level");
if (level != null)
if (node.getNodeName().equalsIgnoreCase("value"))
{
parsedValue = parseValue(node, false, false, Collections.emptyMap());
if (parsedValue != null)
final NamedNodeMap attributes = node.getAttributes();
final Integer level = parseInteger(attributes, "level");
if (level != null)
{
final Integer subLevel = parseInteger(attributes, "subLevel", 0);
values.computeIfAbsent(level, k -> new HashMap<>()).put(subLevel, parsedValue);
}
}
else
{
final int fromLevel = parseInteger(attributes, "fromLevel");
final int toLevel = parseInteger(attributes, "toLevel");
final int fromSubLevel = parseInteger(attributes, "fromSubLevel", 0);
final int toSubLevel = parseInteger(attributes, "toSubLevel", 0);
for (int i = fromLevel; i <= toLevel; i++)
{
for (int j = fromSubLevel; j <= toSubLevel; j++)
parsedValue = parseValue(node, false, false, Collections.emptyMap());
if (parsedValue != null)
{
final Map<Integer, Object> subValues = values.computeIfAbsent(i, k -> new HashMap<>());
final Map<String, Double> variables = new HashMap<>();
variables.put("index", (i - fromLevel) + 1d);
variables.put("subIndex", (j - fromSubLevel) + 1d);
final Object base = values.getOrDefault(i, Collections.emptyMap()).get(0);
if ((base != null) && !(base instanceof StatsSet))
final Integer subLevel = parseInteger(attributes, "subLevel", -1);
values.computeIfAbsent(level, k -> new HashMap<>()).put(subLevel, parsedValue);
}
}
else
{
final int fromLevel = parseInteger(attributes, "fromLevel");
final int toLevel = parseInteger(attributes, "toLevel");
final int fromSubLevel = parseInteger(attributes, "fromSubLevel", -1);
final int toSubLevel = parseInteger(attributes, "toSubLevel", -1);
for (int i = fromLevel; i <= toLevel; i++)
{
for (int j = fromSubLevel; j <= toSubLevel; j++)
{
variables.put("base", Double.parseDouble(String.valueOf(base)));
}
parsedValue = parseValue(node, false, false, variables);
if (parsedValue != null)
{
subValues.put(j, parsedValue);
Map<Integer, Object> subValues = values.computeIfAbsent(i, k -> new HashMap<>());
Map<String, Double> variables = new HashMap<>();
variables.put("index", (i - fromLevel) + 1d);
variables.put("subIndex", (j - fromSubLevel) + 1d);
Object base = values.getOrDefault(i, Collections.emptyMap()).get(-1);
if ((base != null) && !(base instanceof StatsSet))
{
variables.put("base", Double.parseDouble(String.valueOf(base)));
}
parsedValue = parseValue(node, false, false, variables);
if (parsedValue != null)
{
subValues.put(j, parsedValue);
}
}
}
}
}
}
}
return list;
return values;
}
Object parseValue(Node node, boolean blockValue, boolean parseAttributes, Map<String, Double> variables)

View File

@@ -80,39 +80,39 @@ public final class SkillTreesData implements IGameXmlReader
private static final Logger LOGGER = Logger.getLogger(SkillTreesData.class.getName());
// ClassId, Map of Skill Hash Code, L2SkillLearn
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<>();
private static final Map<ClassId, Map<Long, L2SkillLearn>> _classSkillTrees = new HashMap<>();
private static final Map<ClassId, Map<Long, L2SkillLearn>> _transferSkillTrees = new HashMap<>();
private static final Map<Race, Map<Long, L2SkillLearn>> _raceSkillTree = new HashMap<>();
private static final Map<SubclassType, Map<Long, L2SkillLearn>> _revelationSkillTree = new HashMap<>();
private static final Map<ClassId, Set<Integer>> _awakeningSaveSkillTree = new HashMap<>();
// Skill Hash Code, L2SkillLearn
private static final Map<Integer, L2SkillLearn> _collectSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _fishingSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _pledgeSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _subClassSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _subPledgeSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _transformSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _commonSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _subClassChangeSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _abilitySkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _alchemySkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _dualClassSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _collectSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _fishingSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _pledgeSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _subClassSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _subPledgeSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _transformSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _commonSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _subClassChangeSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _abilitySkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _alchemySkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _dualClassSkillTree = new HashMap<>();
// Other skill trees
private static final Map<Integer, L2SkillLearn> _nobleSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _heroSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _gameMasterSkillTree = new HashMap<>();
private static final Map<Integer, L2SkillLearn> _gameMasterAuraSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _nobleSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _heroSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _gameMasterSkillTree = new HashMap<>();
private static final Map<Long, L2SkillLearn> _gameMasterAuraSkillTree = new HashMap<>();
// Remove skill tree
private static final Map<ClassId, Set<Integer>> _removeSkillCache = new HashMap<>();
// Checker, sorted arrays of hash codes
private Map<Integer, int[]> _skillsByClassIdHashCodes; // Occupation skills
private Map<Integer, int[]> _skillsByRaceHashCodes; // Race-specific Transformations
private int[] _allSkillsHashCodes; // Fishing, Collection, Transformations, Common Skills.
private Map<Integer, long[]> _skillsByClassIdHashCodes; // Occupation skills
private Map<Integer, long[]> _skillsByRaceHashCodes; // Race-specific Transformations
private long[] _allSkillsHashCodes; // Fishing, Collection, Transformations, Common Skills.
private boolean _loading = true;
/** Parent class IDs are read from XML and stored in this map, to allow easy customization. */
/** Parent class Ids are read from XML and stored in this map, to allow easy customization. */
private static final Map<ClassId, ClassId> _parentClassMap = new HashMap<>();
/**
@@ -182,10 +182,10 @@ public final class SkillTreesData implements IGameXmlReader
{
if ("skillTree".equalsIgnoreCase(d.getNodeName()))
{
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<>();
final Map<Long, L2SkillLearn> classSkillTree = new HashMap<>();
final Map<Long, L2SkillLearn> transferSkillTree = new HashMap<>();
final Map<Long, L2SkillLearn> raceSkillTree = new HashMap<>();
final Map<Long, L2SkillLearn> revelationSkillTree = new HashMap<>();
type = d.getAttributes().getNamedItem("type").getNodeValue();
attr = d.getAttributes().getNamedItem("classId");
@@ -274,7 +274,7 @@ public final class SkillTreesData implements IGameXmlReader
}
}
final int skillHashCode = SkillData.getSkillHashCode(skillLearn.getSkillId(), skillLearn.getSkillLevel());
final long skillHashCode = SkillData.getSkillHashCode(skillLearn.getSkillId(), skillLearn.getSkillLevel());
switch (type)
{
case "classSkillTree":
@@ -393,35 +393,38 @@ public final class SkillTreesData implements IGameXmlReader
}
else if (type.equals("classSkillTree") && (cId > -1))
{
if (!_classSkillTrees.containsKey(classId))
final Map<Long, L2SkillLearn> classSkillTrees = _classSkillTrees.get(classId);
if (classSkillTrees == null)
{
_classSkillTrees.put(classId, classSkillTree);
}
else
{
_classSkillTrees.get(classId).putAll(classSkillTree);
classSkillTrees.putAll(classSkillTree);
}
}
else if (type.equals("raceSkillTree") && (race != null))
{
if (!_raceSkillTree.containsKey(race))
final Map<Long, L2SkillLearn> raceSkillTrees = _raceSkillTree.get(race);
if (raceSkillTrees == null)
{
_raceSkillTree.put(race, raceSkillTree);
}
else
{
_raceSkillTree.get(race).putAll(raceSkillTree);
raceSkillTrees.putAll(raceSkillTree);
}
}
else if (type.equals("revelationSkillTree") && (subType != null))
{
if (!_revelationSkillTree.containsKey(subType))
final Map<Long, L2SkillLearn> revelationSkillTrees = _revelationSkillTree.get(race);
if (revelationSkillTrees == null)
{
_revelationSkillTree.put(subType, revelationSkillTree);
}
else
{
_revelationSkillTree.get(subType).putAll(revelationSkillTree);
revelationSkillTrees.putAll(revelationSkillTree);
}
}
}
@@ -437,9 +440,9 @@ public final class SkillTreesData implements IGameXmlReader
* @param classId the class skill tree Id
* @return the complete Class Skill Tree including skill trees from parent class for a given {@code classId}
*/
public Map<Integer, L2SkillLearn> getCompleteClassSkillTree(ClassId classId)
public Map<Long, L2SkillLearn> getCompleteClassSkillTree(ClassId classId)
{
final Map<Integer, L2SkillLearn> skillTree = new HashMap<>();
final Map<Long, L2SkillLearn> skillTree = new HashMap<>();
// Add all skills that belong to all classes.
skillTree.putAll(_commonSkillTree);
while ((classId != null) && (_classSkillTrees.get(classId) != null))
@@ -456,7 +459,7 @@ public final class SkillTreesData implements IGameXmlReader
* @param classId the transfer skill tree Id
* @return the complete Transfer Skill Tree for a given {@code classId}
*/
public Map<Integer, L2SkillLearn> getTransferSkillTree(ClassId classId)
public Map<Long, L2SkillLearn> getTransferSkillTree(ClassId classId)
{
return _transferSkillTrees.get(classId);
}
@@ -475,7 +478,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the common skill tree.
* @return the complete Common Skill Tree
*/
public Map<Integer, L2SkillLearn> getCommonSkillTree()
public Map<Long, L2SkillLearn> getCommonSkillTree()
{
return _commonSkillTree;
}
@@ -484,7 +487,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the collect skill tree.
* @return the complete Collect Skill Tree
*/
public Map<Integer, L2SkillLearn> getCollectSkillTree()
public Map<Long, L2SkillLearn> getCollectSkillTree()
{
return _collectSkillTree;
}
@@ -493,7 +496,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the fishing skill tree.
* @return the complete Fishing Skill Tree
*/
public Map<Integer, L2SkillLearn> getFishingSkillTree()
public Map<Long, L2SkillLearn> getFishingSkillTree()
{
return _fishingSkillTree;
}
@@ -502,7 +505,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the pledge skill tree.
* @return the complete Pledge Skill Tree
*/
public Map<Integer, L2SkillLearn> getPledgeSkillTree()
public Map<Long, L2SkillLearn> getPledgeSkillTree()
{
return _pledgeSkillTree;
}
@@ -511,7 +514,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the sub class skill tree.
* @return the complete Sub-Class Skill Tree
*/
public Map<Integer, L2SkillLearn> getSubClassSkillTree()
public Map<Long, L2SkillLearn> getSubClassSkillTree()
{
return _subClassSkillTree;
}
@@ -520,7 +523,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the sub class change skill tree.
* @return the complete Common Skill Tree
*/
public Map<Integer, L2SkillLearn> getSubClassChangeSkillTree()
public Map<Long, L2SkillLearn> getSubClassChangeSkillTree()
{
return _subClassChangeSkillTree;
}
@@ -529,7 +532,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the sub pledge skill tree.
* @return the complete Sub-Pledge Skill Tree
*/
public Map<Integer, L2SkillLearn> getSubPledgeSkillTree()
public Map<Long, L2SkillLearn> getSubPledgeSkillTree()
{
return _subPledgeSkillTree;
}
@@ -538,7 +541,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the transform skill tree.
* @return the complete Transform Skill Tree
*/
public Map<Integer, L2SkillLearn> getTransformSkillTree()
public Map<Long, L2SkillLearn> getTransformSkillTree()
{
return _transformSkillTree;
}
@@ -547,7 +550,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the ability skill tree.
* @return the complete Ability Skill Tree
*/
public Map<Integer, L2SkillLearn> getAbilitySkillTree()
public Map<Long, L2SkillLearn> getAbilitySkillTree()
{
return _abilitySkillTree;
}
@@ -556,7 +559,7 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the ability skill tree.
* @return the complete Ability Skill Tree
*/
public Map<Integer, L2SkillLearn> getAlchemySkillTree()
public Map<Long, L2SkillLearn> getAlchemySkillTree()
{
return _alchemySkillTree;
}
@@ -565,11 +568,11 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the noble skill tree.
* @return the complete Noble Skill Tree
*/
public Map<Integer, Skill> getNobleSkillTree()
public Map<Long, Skill> getNobleSkillTree()
{
final Map<Integer, Skill> tree = new HashMap<>();
final Map<Long, Skill> tree = new HashMap<>();
final SkillData st = SkillData.getInstance();
for (Entry<Integer, L2SkillLearn> e : _nobleSkillTree.entrySet())
for (Entry<Long, L2SkillLearn> e : _nobleSkillTree.entrySet())
{
tree.put(e.getKey(), st.getSkill(e.getValue().getSkillId(), e.getValue().getSkillLevel()));
}
@@ -580,11 +583,11 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the hero skill tree.
* @return the complete Hero Skill Tree
*/
public Map<Integer, Skill> getHeroSkillTree()
public Map<Long, Skill> getHeroSkillTree()
{
final Map<Integer, Skill> tree = new HashMap<>();
final Map<Long, Skill> tree = new HashMap<>();
final SkillData st = SkillData.getInstance();
for (Entry<Integer, L2SkillLearn> e : _heroSkillTree.entrySet())
for (Entry<Long, L2SkillLearn> e : _heroSkillTree.entrySet())
{
tree.put(e.getKey(), st.getSkill(e.getValue().getSkillId(), e.getValue().getSkillLevel()));
}
@@ -595,11 +598,11 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the Game Master skill tree.
* @return the complete Game Master Skill Tree
*/
public Map<Integer, Skill> getGMSkillTree()
public Map<Long, Skill> getGMSkillTree()
{
final Map<Integer, Skill> tree = new HashMap<>();
final Map<Long, Skill> tree = new HashMap<>();
final SkillData st = SkillData.getInstance();
for (Entry<Integer, L2SkillLearn> e : _gameMasterSkillTree.entrySet())
for (Entry<Long, L2SkillLearn> e : _gameMasterSkillTree.entrySet())
{
tree.put(e.getKey(), st.getSkill(e.getValue().getSkillId(), e.getValue().getSkillLevel()));
}
@@ -610,11 +613,11 @@ public final class SkillTreesData implements IGameXmlReader
* Gets the Game Master Aura skill tree.
* @return the complete Game Master Aura Skill Tree
*/
public Map<Integer, Skill> getGMAuraSkillTree()
public Map<Long, Skill> getGMAuraSkillTree()
{
final Map<Integer, Skill> tree = new HashMap<>();
final Map<Long, Skill> tree = new HashMap<>();
final SkillData st = SkillData.getInstance();
for (Entry<Integer, L2SkillLearn> e : _gameMasterAuraSkillTree.entrySet())
for (Entry<Long, L2SkillLearn> e : _gameMasterAuraSkillTree.entrySet())
{
tree.put(e.getKey(), st.getSkill(e.getValue().getSkillId(), e.getValue().getSkillLevel()));
}
@@ -628,7 +631,7 @@ public final class SkillTreesData implements IGameXmlReader
*/
public boolean hasAvailableSkills(L2PcInstance player, ClassId classId)
{
final Map<Integer, L2SkillLearn> skills = getCompleteClassSkillTree(classId);
final Map<Long, L2SkillLearn> skills = getCompleteClassSkillTree(classId);
for (L2SkillLearn skill : skills.values())
{
if ((skill.getSkillId() == CommonSkill.DIVINE_INSPIRATION.getId()) || skill.isAutoGet() || skill.isLearnedByFS() || (skill.getGetLevel() > player.getLevel()))
@@ -673,7 +676,7 @@ public final class SkillTreesData implements IGameXmlReader
private List<L2SkillLearn> getAvailableSkills(L2PcInstance player, ClassId classId, boolean includeByFs, boolean includeAutoGet, ISkillsHolder holder)
{
final List<L2SkillLearn> result = new LinkedList<>();
final Map<Integer, L2SkillLearn> skills = getCompleteClassSkillTree(classId);
final Map<Long, L2SkillLearn> skills = getCompleteClassSkillTree(classId);
if (skills.isEmpty())
{
@@ -684,7 +687,7 @@ public final class SkillTreesData implements IGameXmlReader
final boolean isAwaken = player.isInCategory(CategoryType.AWAKEN_GROUP) && (player.getRace() != Race.ERTHEIA);
for (Entry<Integer, L2SkillLearn> entry : skills.entrySet())
for (Entry<Long, L2SkillLearn> entry : skills.entrySet())
{
final L2SkillLearn skill = entry.getValue();
@@ -787,7 +790,7 @@ public final class SkillTreesData implements IGameXmlReader
public List<L2SkillLearn> getAvailableAutoGetSkills(L2PcInstance player)
{
final List<L2SkillLearn> result = new ArrayList<>();
final Map<Integer, L2SkillLearn> skills = getCompleteClassSkillTree(player.getClassId());
final Map<Long, L2SkillLearn> skills = getCompleteClassSkillTree(player.getClassId());
if (skills.isEmpty())
{
// The Skill Tree for this class is undefined, so we return an empty list.
@@ -818,7 +821,7 @@ public final class SkillTreesData implements IGameXmlReader
}
final int maxLvl = SkillData.getInstance().getMaxLevel(skill.getSkillId());
final int hashCode = SkillData.getSkillHashCode(skill.getSkillId(), maxLvl);
final long hashCode = SkillData.getSkillHashCode(skill.getSkillId(), maxLvl);
if (skill.isAutoGet() && (player.getLevel() >= skill.getGetLevel()))
{
@@ -884,7 +887,7 @@ public final class SkillTreesData implements IGameXmlReader
public List<L2SkillLearn> getAvailableRevelationSkills(L2PcInstance player, SubclassType type)
{
final List<L2SkillLearn> result = new ArrayList<>();
final Map<Integer, L2SkillLearn> revelationSkills = _revelationSkillTree.get(type);
final Map<Long, L2SkillLearn> revelationSkills = _revelationSkillTree.get(type);
for (L2SkillLearn skill : revelationSkills.values())
{
@@ -1382,7 +1385,7 @@ public final class SkillTreesData implements IGameXmlReader
* @param skillTree the skill tree to search the minimum get level
* @return the minimum level for a new skill for a given {@code player} and {@code skillTree}
*/
public int getMinLevelForNewSkill(L2PcInstance player, Map<Integer, L2SkillLearn> skillTree)
public int getMinLevelForNewSkill(L2PcInstance player, Map<Long, L2SkillLearn> skillTree)
{
int minLevel = 0;
if (skillTree.isEmpty())
@@ -1407,7 +1410,7 @@ public final class SkillTreesData implements IGameXmlReader
public List<L2SkillLearn> getNextAvailableSkills(L2PcInstance player, ClassId classId, boolean includeByFs, boolean includeAutoGet)
{
final Map<Integer, L2SkillLearn> completeClassSkillTree = getCompleteClassSkillTree(classId);
final Map<Long, L2SkillLearn> completeClassSkillTree = getCompleteClassSkillTree(classId);
final List<L2SkillLearn> result = new LinkedList<>();
if (completeClassSkillTree.isEmpty())
{
@@ -1448,7 +1451,7 @@ public final class SkillTreesData implements IGameXmlReader
for (Skill skill : player.getAllSkills())
{
final int maxLvl = SkillData.getInstance().getMaxLevel(skill.getId());
final int hashCode = SkillData.getSkillHashCode(skill.getId(), maxLvl);
final long hashCode = SkillData.getSkillHashCode(skill.getId(), maxLvl);
if (!isCurrentClassSkillNoParent(player.getClassId(), hashCode) && !isRemoveSkill(player.getClassId(), skill.getId()) && !isAwakenSaveSkill(player.getClassId(), skill.getId()))
{
@@ -1481,7 +1484,7 @@ public final class SkillTreesData implements IGameXmlReader
*/
public boolean isGMSkill(int skillId, int skillLevel)
{
final int hashCode = SkillData.getSkillHashCode(skillId, skillLevel);
final long hashCode = SkillData.getSkillHashCode(skillId, skillLevel);
return _gameMasterSkillTree.containsKey(hashCode) || _gameMasterAuraSkillTree.containsKey(hashCode);
}
@@ -1493,7 +1496,7 @@ public final class SkillTreesData implements IGameXmlReader
*/
public boolean isClanSkill(int skillId, int skillLevel)
{
final int hashCode = SkillData.getSkillHashCode(skillId, skillLevel);
final long hashCode = SkillData.getSkillHashCode(skillId, skillLevel);
return _pledgeSkillTree.containsKey(hashCode) || _subPledgeSkillTree.containsKey(hashCode);
}
@@ -1513,7 +1516,7 @@ public final class SkillTreesData implements IGameXmlReader
return _removeSkillCache.getOrDefault(classId, Collections.emptySet()).contains(skillId);
}
public boolean isCurrentClassSkillNoParent(ClassId classId, Integer hashCode)
public boolean isCurrentClassSkillNoParent(ClassId classId, Long hashCode)
{
return _classSkillTrees.getOrDefault(classId, Collections.emptyMap()).containsKey(hashCode);
}
@@ -1544,18 +1547,18 @@ public final class SkillTreesData implements IGameXmlReader
private void generateCheckArrays()
{
int i;
int[] array;
long[] array;
// Class specific skills:
Map<Integer, L2SkillLearn> tempMap;
Map<Long, L2SkillLearn> tempMap;
final Set<ClassId> keySet = _classSkillTrees.keySet();
_skillsByClassIdHashCodes = new HashMap<>(keySet.size());
for (ClassId cls : keySet)
{
i = 0;
tempMap = getCompleteClassSkillTree(cls);
array = new int[tempMap.size()];
for (int h : tempMap.keySet())
array = new long[tempMap.size()];
for (long h : tempMap.keySet())
{
array[i++] = h;
}
@@ -1565,7 +1568,7 @@ public final class SkillTreesData implements IGameXmlReader
}
// Race specific skills from Fishing and Transformation skill trees.
final List<Integer> list = new ArrayList<>();
final List<Long> list = new ArrayList<>();
_skillsByRaceHashCodes = new HashMap<>(Race.values().length);
for (Race r : Race.values())
{
@@ -1586,8 +1589,8 @@ public final class SkillTreesData implements IGameXmlReader
}
i = 0;
array = new int[list.size()];
for (int s : list)
array = new long[list.size()];
for (long s : list)
{
array[i++] = s;
}
@@ -1636,9 +1639,9 @@ public final class SkillTreesData implements IGameXmlReader
list.add(SkillData.getSkillHashCode(s.getSkillId(), s.getSkillLevel()));
}
_allSkillsHashCodes = new int[list.size()];
_allSkillsHashCodes = new long[list.size()];
int j = 0;
for (int hashcode : list)
for (long hashcode : list)
{
_allSkillsHashCodes[j++] = hashcode;
}
@@ -1671,7 +1674,7 @@ public final class SkillTreesData implements IGameXmlReader
}
final int maxLvl = SkillData.getInstance().getMaxLevel(skill.getId());
final int hashCode = SkillData.getSkillHashCode(skill.getId(), Math.min(skill.getLevel(), maxLvl));
final long hashCode = SkillData.getSkillHashCode(skill.getId(), Math.min(skill.getLevel(), maxLvl));
if (Arrays.binarySearch(_skillsByClassIdHashCodes.get(player.getClassId().ordinal()), hashCode) >= 0)
{
@@ -1708,25 +1711,25 @@ public final class SkillTreesData implements IGameXmlReader
private void report()
{
int classSkillTreeCount = 0;
for (Map<Integer, L2SkillLearn> classSkillTree : _classSkillTrees.values())
for (Map<Long, L2SkillLearn> classSkillTree : _classSkillTrees.values())
{
classSkillTreeCount += classSkillTree.size();
}
int transferSkillTreeCount = 0;
for (Map<Integer, L2SkillLearn> trasferSkillTree : _transferSkillTrees.values())
for (Map<Long, L2SkillLearn> trasferSkillTree : _transferSkillTrees.values())
{
transferSkillTreeCount += trasferSkillTree.size();
}
int raceSkillTreeCount = 0;
for (Map<Integer, L2SkillLearn> raceSkillTree : _raceSkillTree.values())
for (Map<Long, L2SkillLearn> raceSkillTree : _raceSkillTree.values())
{
raceSkillTreeCount += raceSkillTree.size();
}
int revelationSkillTreeCount = 0;
for (Map<Integer, L2SkillLearn> revelationSkillTree : _revelationSkillTree.values())
for (Map<Long, L2SkillLearn> revelationSkillTree : _revelationSkillTree.values())
{
revelationSkillTreeCount += revelationSkillTree.size();
}

View File

@@ -117,7 +117,17 @@ public class SpawnsData implements IGameXmlReader
return _spawns;
}
public List<NpcSpawnTemplate> getSpawns(Predicate<NpcSpawnTemplate> condition)
public List<SpawnTemplate> getSpawns(Predicate<SpawnTemplate> condition)
{
return _spawns.stream().filter(condition).collect(Collectors.toList());
}
public List<SpawnGroup> getGroupsByName(String groupName)
{
return _spawns.stream().filter(template -> (template.getName() != null) && groupName.equalsIgnoreCase(template.getName())).flatMap(template -> template.getGroups().stream()).collect(Collectors.toList());
}
public List<NpcSpawnTemplate> getNpcSpawns(Predicate<NpcSpawnTemplate> condition)
{
return _spawns.stream().flatMap(template -> template.getGroups().stream()).flatMap(group -> group.getSpawns().stream()).filter(condition).collect(Collectors.toList());
}

View File

@@ -17,18 +17,14 @@
package com.l2jmobius.gameserver.engines;
import java.io.File;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.file.filter.XMLFilter;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.engines.items.DocumentItem;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.skills.Skill;
/**
* @author mkizub
@@ -38,7 +34,6 @@ public class DocumentEngine
private static final Logger LOGGER = Logger.getLogger(DocumentEngine.class.getName());
private final List<File> _itemFiles = new LinkedList<>();
private final List<File> _skillFiles = new LinkedList<>();
public static DocumentEngine getInstance()
{
@@ -52,11 +47,6 @@ public class DocumentEngine
{
hashFiles("data/stats/items/custom", _itemFiles);
}
hashFiles("data/stats/skills", _skillFiles);
if (Config.CUSTOM_SKILLS_LOAD)
{
hashFiles("data/stats/skills/custom", _skillFiles);
}
}
private void hashFiles(String dirname, List<File> hash)
@@ -74,35 +64,6 @@ public class DocumentEngine
}
}
public List<Skill> loadSkills(File file)
{
if (file == null)
{
LOGGER.warning("Skill file not found.");
return null;
}
return Collections.emptyList();
}
public void loadAllSkills(Map<Integer, Skill> allSkills)
{
int count = 0;
for (File file : _skillFiles)
{
final List<Skill> s = loadSkills(file);
if (s == null)
{
continue;
}
for (Skill skill : s)
{
allSkills.put(SkillData.getSkillHashCode(skill), skill);
count++;
}
}
LOGGER.info("Loaded " + count + " Skill templates from XML files.");
}
/**
* Return created items
* @return List of {@link L2Item}

View File

@@ -0,0 +1,27 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.enums;
/**
* @author Sdw
*/
public enum NextActionType
{
NONE,
ATTACK,
CAST
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.enums;
/**
* @author Sdw
*/
public enum SkillEnchantType
{
NORMAL,
BLESSED,
UNTRAIN,
CHANGE,
IMMORTAL
}

View File

@@ -60,8 +60,8 @@ public class ClanEntryManager
private static final String INSERT_WAITING_LIST = "INSERT INTO pledge_waiting_list VALUES (?, ?)";
private static final String DELETE_WAITING_LIST = "DELETE FROM pledge_waiting_list WHERE char_id = ?";
private static final String INSERT_CLAN_RECRUIT = "INSERT INTO pledge_recruit VALUES (?, ?, ?, ?)";
private static final String UPDATE_CLAN_RECRUIT = "UPDATE pledge_recruit SET karma = ?, information = ?, detailed_information = ? WHERE clan_id = ?";
private static final String INSERT_CLAN_RECRUIT = "INSERT INTO pledge_recruit VALUES (?, ?, ?, ?, ?, ?)";
private static final String UPDATE_CLAN_RECRUIT = "UPDATE pledge_recruit SET karma = ?, information = ?, detailed_information = ?, application_type = ?, recruit_type = ? WHERE clan_id = ?";
private static final String DELETE_CLAN_RECRUIT = "DELETE FROM pledge_recruit WHERE clan_id = ?";
//@formatter:off
@@ -97,7 +97,7 @@ public class ClanEntryManager
{
while (rs.next())
{
_clanList.put(rs.getInt("clan_id"), new PledgeRecruitInfo(rs.getInt("clan_id"), rs.getInt("karma"), rs.getString("information"), rs.getString("detailed_information")));
_clanList.put(rs.getInt("clan_id"), new PledgeRecruitInfo(rs.getInt("clan_id"), rs.getInt("karma"), rs.getString("information"), rs.getString("detailed_information"), rs.getInt("application_type"), rs.getInt("recruit_type")));
}
LOGGER.info(getClass().getSimpleName() + ": Loaded: " + _clanList.size() + " clan entry");
}
@@ -265,6 +265,8 @@ public class ClanEntryManager
statement.setInt(2, info.getKarma());
statement.setString(3, info.getInformation());
statement.setString(4, info.getDetailedInformation());
statement.setInt(5, info.getApplicationType());
statement.setInt(6, info.getRecruitType());
statement.executeUpdate();
}
catch (Exception e)
@@ -286,7 +288,9 @@ public class ClanEntryManager
statement.setInt(1, info.getKarma());
statement.setString(2, info.getInformation());
statement.setString(3, info.getDetailedInformation());
statement.setInt(4, info.getClanId());
statement.setInt(4, info.getApplicationType());
statement.setInt(5, info.getRecruitType());
statement.setInt(6, info.getClanId());
statement.executeUpdate();
}
catch (Exception e)

View File

@@ -101,7 +101,7 @@ public class DBSpawnManager
spawn.setAmount(1);
spawn.setHeading(rset.getInt("heading"));
final List<NpcSpawnTemplate> spawns = SpawnsData.getInstance().getSpawns(npc -> (npc.getId() == template.getId()) && npc.hasDBSave());
final List<NpcSpawnTemplate> spawns = SpawnsData.getInstance().getNpcSpawns(npc -> (npc.getId() == template.getId()) && npc.hasDBSave());
if (spawns.isEmpty())
{
LOGGER.warning(getClass().getSimpleName() + ": Couldn't find spawn declaration for npc: " + template.getId() + " - " + template.getName());
@@ -383,28 +383,15 @@ public class DBSpawnManager
}
final int npcId = spawn.getId();
if (!_spawns.containsKey(npcId))
{
return;
}
SpawnTable.getInstance().deleteSpawn(spawn, false);
_spawns.remove(npcId);
_npcs.remove(npcId);
_storedInfo.remove(npcId);
if (_npcs.containsKey(npcId))
final ScheduledFuture<?> task = _schedules.remove(npcId);
if (task != null)
{
_npcs.remove(npcId);
}
if (_schedules.containsKey(npcId))
{
final ScheduledFuture<?> f = _schedules.remove(npcId);
f.cancel(true);
}
if (_storedInfo.containsKey(npcId))
{
_storedInfo.remove(npcId);
task.cancel(true);
}
if (updateDb)
@@ -421,6 +408,8 @@ public class DBSpawnManager
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not remove npc #" + npcId + " from DB: ", e);
}
}
SpawnTable.getInstance().deleteSpawn(spawn, false);
}
/**

View File

@@ -432,7 +432,7 @@ public final class CharEffectList
}
else
{
_owner.sendPacket(new ShortBuffStatusUpdate(info.getSkill().getId(), info.getSkill().getLevel(), info.getTime()));
_owner.sendPacket(new ShortBuffStatusUpdate(info.getSkill().getId(), info.getSkill().getLevel(), info.getSkill().getSubLevel(), info.getTime()));
}
}
}

View File

@@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import com.l2jmobius.gameserver.enums.AttributeType;
import com.l2jmobius.gameserver.model.buylist.Product;
@@ -89,10 +90,7 @@ public class ItemInfo
*/
public ItemInfo(L2ItemInstance item)
{
if (item == null)
{
return;
}
Objects.requireNonNull(item);
// Get the Identifier of the L2ItemInstance
_objectId = item.getObjectId();

View File

@@ -1,105 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model;
import java.util.ArrayList;
import java.util.List;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
public final class L2EnchantSkillGroup
{
private final int _id;
private final List<EnchantSkillHolder> _enchantDetails = new ArrayList<>();
public L2EnchantSkillGroup(int id)
{
_id = id;
}
public void addEnchantDetail(EnchantSkillHolder detail)
{
_enchantDetails.add(detail);
}
public int getId()
{
return _id;
}
public List<EnchantSkillHolder> getEnchantGroupDetails()
{
return _enchantDetails;
}
public static class EnchantSkillHolder
{
private final int _level;
private final int _adenaCost;
private final int _expCost;
private final int _spCost;
private final byte[] _rate;
public EnchantSkillHolder(StatsSet set)
{
_level = set.getInt("level");
_adenaCost = set.getInt("adena", 0);
_expCost = set.getInt("exp", 0);
_spCost = set.getInt("sp", 0);
_rate = new byte[24];
for (int i = 0; i < 24; i++)
{
_rate[i] = set.getByte("chance" + (76 + i), (byte) 0);
}
}
/**
* @return Returns the level.
*/
public int getLevel()
{
return _level;
}
/**
* @return Returns the spCost.
*/
public int getSpCost()
{
return _spCost;
}
public int getExpCost()
{
return _expCost;
}
public int getAdenaCost()
{
return _adenaCost;
}
public byte getRate(L2PcInstance ply)
{
if (ply.getLevel() < 76)
{
return 0;
}
return _rate[ply.getLevel() - 76];
}
}
}

View File

@@ -1,128 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model;
import java.util.Set;
import java.util.TreeMap;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
public final class L2EnchantSkillLearn
{
private final int _id;
private final int _baseLvl;
private final TreeMap<Integer, Integer> _enchantRoutes = new TreeMap<>();
public L2EnchantSkillLearn(int id, int baseLvl)
{
_id = id;
_baseLvl = baseLvl;
}
public void addNewEnchantRoute(int route, int group)
{
_enchantRoutes.put(route, group);
}
/**
* @return Returns the id.
*/
public int getId()
{
return _id;
}
/**
* @return Returns the minLevel.
*/
public int getBaseLevel()
{
return _baseLvl;
}
public static int getEnchantRoute(int level)
{
return (int) Math.floor(level / 100);
}
public static int getEnchantIndex(int level)
{
return (level % 100) - 1;
}
public static int getEnchantType(int level)
{
return ((level - 1) / 100) - 1;
}
public L2EnchantSkillGroup getFirstRouteGroup()
{
return EnchantSkillGroupsData.getInstance().getEnchantSkillGroupById(_enchantRoutes.firstEntry().getValue());
}
public Set<Integer> getAllRoutes()
{
return _enchantRoutes.keySet();
}
public int getMinSkillLevel(int level)
{
if ((level % 100) == 1)
{
return _baseLvl;
}
return level - 1;
}
public boolean isMaxEnchant(int level)
{
final int enchantType = getEnchantRoute(level);
if ((enchantType < 1) || !_enchantRoutes.containsKey(enchantType))
{
return false;
}
final int index = getEnchantIndex(level);
if ((index + 1) >= EnchantSkillGroupsData.getInstance().getEnchantSkillGroupById(_enchantRoutes.get(enchantType)).getEnchantGroupDetails().size())
{
return true;
}
return false;
}
public EnchantSkillHolder getEnchantSkillHolder(int level)
{
final int enchantType = getEnchantRoute(level);
if ((enchantType < 1) || !_enchantRoutes.containsKey(enchantType))
{
return null;
}
final int index = getEnchantIndex(level);
final L2EnchantSkillGroup group = EnchantSkillGroupsData.getInstance().getEnchantSkillGroupById(_enchantRoutes.get(enchantType));
if (index < 0)
{
return group.getEnchantGroupDetails().get(0);
}
else if (index >= group.getEnchantGroupDetails().size())
{
return group.getEnchantGroupDetails().get(EnchantSkillGroupsData.getInstance().getEnchantSkillGroupById(_enchantRoutes.get(enchantType)).getEnchantGroupDetails().size() - 1);
}
return group.getEnchantGroupDetails().get(index);
}
}

View File

@@ -184,7 +184,7 @@ public class L2PetData
{
continue;
}
if (temp.getSkillLvl() == 0)
if (temp.getSkillLevel() == 0)
{
if (petLvl < 70)
{
@@ -209,9 +209,9 @@ public class L2PetData
}
else if (temp.getMinLevel() <= petLvl)
{
if (temp.getSkillLvl() > lvl)
if (temp.getSkillLevel() > lvl)
{
lvl = temp.getSkillLvl();
lvl = temp.getSkillLevel();
}
}
}

View File

@@ -90,7 +90,7 @@ public class ShortCuts implements IRestorable
}
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("REPLACE INTO character_shortcuts (charId,slot,page,type,shortcut_id,level,class_index) values(?,?,?,?,?,?,?)"))
PreparedStatement statement = con.prepareStatement("REPLACE INTO character_shortcuts (charId,slot,page,type,shortcut_id,level,sub_level,class_index) values(?,?,?,?,?,?,?,?)"))
{
statement.setInt(1, _owner.getObjectId());
statement.setInt(2, shortcut.getSlot());
@@ -98,7 +98,8 @@ public class ShortCuts implements IRestorable
statement.setInt(4, shortcut.getType().ordinal());
statement.setInt(5, shortcut.getId());
statement.setInt(6, shortcut.getLevel());
statement.setInt(7, _owner.getClassIndex());
statement.setInt(7, shortcut.getSubLevel());
statement.setInt(8, _owner.getClassIndex());
statement.execute();
}
catch (Exception e)
@@ -191,8 +192,8 @@ public class ShortCuts implements IRestorable
final int type = rset.getInt("type");
final int id = rset.getInt("shortcut_id");
final int level = rset.getInt("level");
_shortCuts.put(slot + (page * MAX_SHORTCUTS_PER_BAR), new Shortcut(slot, page, ShortcutType.values()[type], id, level, 1));
final int subLevel = rset.getInt("sub_level");
_shortCuts.put(slot + (page * MAX_SHORTCUTS_PER_BAR), new Shortcut(slot, page, ShortcutType.values()[type], id, level, subLevel, 1));
}
}
}
@@ -226,15 +227,16 @@ public class ShortCuts implements IRestorable
* Updates the shortcut bars with the new skill.
* @param skillId the skill Id to search and update.
* @param skillLevel the skill level to update.
* @param skillSubLevel the skill sub level to update.
*/
public synchronized void updateShortCuts(int skillId, int skillLevel)
public synchronized void updateShortCuts(int skillId, int skillLevel, int skillSubLevel)
{
// Update all the shortcuts for this skill
for (Shortcut sc : _shortCuts.values())
{
if ((sc.getId() == skillId) && (sc.getType() == ShortcutType.SKILL))
{
final Shortcut newsc = new Shortcut(sc.getSlot(), sc.getPage(), sc.getType(), sc.getId(), skillLevel, 1);
final Shortcut newsc = new Shortcut(sc.getSlot(), sc.getPage(), sc.getType(), sc.getId(), skillLevel, skillSubLevel, 1);
_owner.sendPacket(new ShortCutRegister(newsc));
_owner.registerShortCut(newsc);
}

View File

@@ -34,18 +34,21 @@ public class Shortcut
private final int _id;
/** Shortcut level (skills). */
private final int _level;
/** Shortcut level (skills). */
private final int _subLevel;
/** Character type: 1 player, 2 summon. */
private final int _characterType;
/** Shared reuse group. */
private int _sharedReuseGroup = -1;
public Shortcut(int slot, int page, ShortcutType type, int id, int level, int characterType)
public Shortcut(int slot, int page, ShortcutType type, int id, int level, int subLevel, int characterType)
{
_slot = slot;
_page = page;
_type = type;
_id = id;
_level = level;
_subLevel = subLevel;
_characterType = characterType;
}
@@ -67,6 +70,15 @@ public class Shortcut
return _level;
}
/**
* Gets the shortcut level.
* @return the level
*/
public int getSubLevel()
{
return _subLevel;
}
/**
* Gets the shortcut page.
* @return the page

View File

@@ -31,6 +31,8 @@ public class TimeStamp
private final int _id1;
/** Item object ID or skill level. */
private final int _id2;
/** Skill level. */
private final int _id3;
/** Item or skill reuse time. */
private final long _reuse;
/** Time stamp. */
@@ -48,6 +50,7 @@ public class TimeStamp
{
_id1 = skill.getId();
_id2 = skill.getLevel();
_id3 = skill.getSubLevel();
_reuse = reuse;
_stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
_group = -1;
@@ -63,6 +66,7 @@ public class TimeStamp
{
_id1 = item.getId();
_id2 = item.getObjectId();
_id3 = 0;
_reuse = reuse;
_stamp = systime > 0 ? systime : System.currentTimeMillis() + reuse;
_group = item.getSharedReuseGroup();
@@ -113,6 +117,15 @@ public class TimeStamp
return _id2;
}
/**
* Gets the skill sub level.
* @return the skill level
*/
public int getSkillSubLvl()
{
return _id3;
}
/**
* Gets the reuse.
* @return the reuse

View File

@@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import com.l2jmobius.gameserver.enums.AttributeType;
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
@@ -54,6 +55,7 @@ public class TradeItem
public TradeItem(L2ItemInstance item, long count, long price)
{
Objects.requireNonNull(item);
_objectId = item.getObjectId();
_item = item.getItem();
_location = item.getLocationSlot();
@@ -77,6 +79,7 @@ public class TradeItem
public TradeItem(L2Item item, long count, long price)
{
Objects.requireNonNull(item);
_objectId = 0;
_item = item;
_location = 0;
@@ -95,6 +98,7 @@ public class TradeItem
public TradeItem(TradeItem item, long count, long price)
{
Objects.requireNonNull(item);
_objectId = item.getObjectId();
_item = item.getItem();
_location = item.getLocationSlot();

View File

@@ -212,11 +212,11 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
/** Map containing all skills of this character. */
private final Map<Integer, Skill> _skills = new ConcurrentSkipListMap<>();
/** Map containing the skill reuse time stamps. */
private volatile Map<Integer, TimeStamp> _reuseTimeStampsSkills = null;
private volatile Map<Long, TimeStamp> _reuseTimeStampsSkills = null;
/** Map containing the item reuse time stamps. */
private volatile Map<Integer, TimeStamp> _reuseTimeStampsItems = null;
/** Map containing all the disabled skills. */
private volatile Map<Integer, Long> _disabledSkills = null;
private volatile Map<Long, Long> _disabledSkills = null;
private boolean _allSkillsDisabled;
private final byte[] _zones = new byte[ZoneId.getZoneCount()];
@@ -1665,7 +1665,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* Gets the skill reuse time stamps map.
* @return the skill reuse time stamps map
*/
public final Map<Integer, TimeStamp> getSkillReuseTimeStamps()
public final Map<Long, TimeStamp> getSkillReuseTimeStamps()
{
return _reuseTimeStampsSkills;
}
@@ -1730,7 +1730,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the remaining time, otherwise -1
*/
public synchronized final long getSkillRemainingReuseTime(int hashCode)
public synchronized final long getSkillRemainingReuseTime(long hashCode)
{
final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
return reuseStamp != null ? reuseStamp.getRemaining() : -1;
@@ -1741,7 +1741,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is under reuse time, {@code false} otherwise
*/
public synchronized final boolean hasSkillReuse(int hashCode)
public synchronized final boolean hasSkillReuse(long hashCode)
{
final TimeStamp reuseStamp = (_reuseTimeStampsSkills != null) ? _reuseTimeStampsSkills.get(hashCode) : null;
return (reuseStamp != null) && reuseStamp.hasNotPassed();
@@ -1752,7 +1752,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return if the skill has a reuse time stamp, the skill reuse time stamp, otherwise {@code null}
*/
public synchronized final TimeStamp getSkillReuseTimeStamp(int hashCode)
public synchronized final TimeStamp getSkillReuseTimeStamp(long hashCode)
{
return _reuseTimeStampsSkills != null ? _reuseTimeStampsSkills.get(hashCode) : null;
}
@@ -1761,7 +1761,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* Gets the disabled skills map.
* @return the disabled skills map
*/
public Map<Integer, Long> getDisabledSkills()
public Map<Long, Long> getDisabledSkills()
{
return _disabledSkills;
}
@@ -1847,7 +1847,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
* @param hashCode the skill hash code
* @return {@code true} if the skill is disabled, {@code false} otherwise
*/
public boolean isSkillDisabledByReuse(int hashCode)
public boolean isSkillDisabledByReuse(long hashCode)
{
if (_disabledSkills == null)
{
@@ -1900,12 +1900,6 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
*/
public boolean doDie(L2Character killer)
{
final TerminateReturn returnBack = EventDispatcher.getInstance().notifyEvent(new OnCreatureDeath(killer, this), this, TerminateReturn.class);
if ((returnBack != null) && returnBack.terminate())
{
return false;
}
// killing is only possible one time
synchronized (this)
{
@@ -1918,7 +1912,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
setCurrentHp(0);
setIsDead(true);
}
EventDispatcher.getInstance().notifyEvent(new OnCreatureDeath(killer, this), this);
EventDispatcher.getInstance().notifyEvent(new OnCreatureKilled(killer, this), killer);
abortAttack();
@@ -2400,7 +2394,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
public boolean isUndying()
{
return _isUndying || isInvul() || isAffected(EffectFlag.IGNORE_DEATH);
return _isUndying || isInvul() || isAffected(EffectFlag.IGNORE_DEATH) || isInsideZone(ZoneId.UNDYING);
}
public boolean isHpBlocked()
@@ -5423,7 +5417,7 @@ public abstract class L2Character extends L2Object implements ISkillsHolder, IDe
if (_ignoreSkillEffects != null)
{
final SkillHolder holder = getIgnoreSkillEffects().get(skillId);
return ((holder != null) && ((holder.getSkillLvl() < 1) || (holder.getSkillLvl() == skillLvl)));
return ((holder != null) && ((holder.getSkillLevel() < 1) || (holder.getSkillLevel() == skillLvl)));
}
return false;
}

View File

@@ -138,7 +138,7 @@ public class L2NpcInstance extends L2Npc
if (skills.isEmpty())
{
final Map<Integer, L2SkillLearn> skillTree = SkillTreesData.getInstance().getCompleteClassSkillTree(classId);
final Map<Long, L2SkillLearn> skillTree = SkillTreesData.getInstance().getCompleteClassSkillTree(classId);
final int minLevel = SkillTreesData.getInstance().getMinLevelForNewSkill(player, skillTree);
if (minLevel > 0)
{

View File

@@ -65,7 +65,6 @@ import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
import com.l2jmobius.gameserver.data.xml.impl.AdminData;
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.ExperienceData;
import com.l2jmobius.gameserver.data.xml.impl.HennaData;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
@@ -85,6 +84,7 @@ import com.l2jmobius.gameserver.enums.HtmlActionScope;
import com.l2jmobius.gameserver.enums.IllegalActionPunishmentType;
import com.l2jmobius.gameserver.enums.InstanceType;
import com.l2jmobius.gameserver.enums.MountType;
import com.l2jmobius.gameserver.enums.NextActionType;
import com.l2jmobius.gameserver.enums.PartyDistributionType;
import com.l2jmobius.gameserver.enums.PartySmallWindowUpdateType;
import com.l2jmobius.gameserver.enums.PlayerAction;
@@ -127,7 +127,6 @@ import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2ClanMember;
import com.l2jmobius.gameserver.model.L2CommandChannel;
import com.l2jmobius.gameserver.model.L2ContactList;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.model.L2ManufactureItem;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2Party;
@@ -262,6 +261,7 @@ import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.AbstractHtmlPacket;
import com.l2jmobius.gameserver.network.serverpackets.AcquireSkillList;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.ChangeWaitType;
import com.l2jmobius.gameserver.network.serverpackets.CharInfo;
@@ -346,15 +346,15 @@ import com.l2jmobius.gameserver.util.Util;
public final class L2PcInstance extends L2Playable
{
// Character Skill SQL String Definitions:
private static final String RESTORE_SKILLS_FOR_CHAR = "SELECT skill_id,skill_level FROM character_skills WHERE charId=? AND class_index=?";
private static final String UPDATE_CHARACTER_SKILL_LEVEL = "UPDATE character_skills SET skill_level=? WHERE skill_id=? AND charId=? AND class_index=?";
private static final String ADD_NEW_SKILLS = "REPLACE INTO character_skills (charId,skill_id,skill_level,class_index) VALUES (?,?,?,?)";
private static final String RESTORE_SKILLS_FOR_CHAR = "SELECT skill_id,skill_level,skill_sub_level FROM character_skills WHERE charId=? AND class_index=?";
private static final String UPDATE_CHARACTER_SKILL_LEVEL = "UPDATE character_skills SET skill_level=?, skill_sub_level=? WHERE skill_id=? AND charId=? AND class_index=?";
private static final String ADD_NEW_SKILLS = "REPLACE INTO character_skills (charId,skill_id,skill_level,skill_sub_level,class_index) VALUES (?,?,?,?,?)";
private static final String DELETE_SKILL_FROM_CHAR = "DELETE FROM character_skills WHERE skill_id=? AND charId=? AND class_index=?";
private static final String DELETE_CHAR_SKILLS = "DELETE FROM character_skills WHERE charId=? AND class_index=?";
// Character Skill Save SQL String Definitions:
private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (charId,skill_id,skill_level,remaining_time,reuse_delay,systime,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?)";
private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,remaining_time, reuse_delay, systime, restore_type FROM character_skills_save WHERE charId=? AND class_index=? ORDER BY buff_index ASC";
private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (charId,skill_id,skill_level,skill_sub_level,remaining_time,reuse_delay,systime,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?,?)";
private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,skill_sub_level,remaining_time, reuse_delay, systime, restore_type FROM character_skills_save WHERE charId=? AND class_index=? ORDER BY buff_index ASC";
private static final String DELETE_SKILL_SAVE = "DELETE FROM character_skills_save WHERE charId=? AND class_index=?";
// Character Item Reuse Time String Definition:
@@ -1546,10 +1546,11 @@ public final class L2PcInstance extends L2Playable
* Updates the shortcut bars with the new skill.
* @param skillId the skill Id to search and update.
* @param skillLevel the skill level to update.
* @param skillSubLevel the skill sub level to update.
*/
public void updateShortCuts(int skillId, int skillLevel)
public void updateShortCuts(int skillId, int skillLevel, int skillSubLevel)
{
_shortCuts.updateShortCuts(skillId, skillLevel);
_shortCuts.updateShortCuts(skillId, skillLevel, skillSubLevel);
}
/**
@@ -2047,7 +2048,7 @@ public final class L2PcInstance extends L2Playable
_curWeightPenalty = newWeightPenalty;
if ((newWeightPenalty > 0) && !_dietMode)
{
addSkill(SkillData.getInstance().getSkill(4270, newWeightPenalty));
addSkill(SkillData.getInstance().getSkill(CommonSkill.WEIGHT_PENALTY.getId(), newWeightPenalty));
setIsOverloaded(getCurrentLoad() > maxLoad);
}
else
@@ -3053,7 +3054,7 @@ public final class L2PcInstance extends L2Playable
if (count > 0)
{
final L2ItemInstance beautyTickets = _inventory.getAdenaInstance();
final L2ItemInstance beautyTickets = _inventory.getBeautyTicketsInstance();
if (!_inventory.reduceBeautyTickets(process, count, this, reference))
{
return false;
@@ -6699,6 +6700,12 @@ public final class L2PcInstance extends L2Playable
return null;
}
if (player.isGM())
{
final long masks = player.getVariables().getLong(COND_OVERRIDE_KEY, PcCondOverride.getAllExceptionsMask());
player.setOverrideCond(masks);
}
// Retrieve from the database all items of this L2PcInstance and add them to _inventory
player.getInventory().restore();
player.getFreight().restore();
@@ -6765,12 +6772,6 @@ public final class L2PcInstance extends L2Playable
player.restoreUISettings();
}
if (player.isGM())
{
final long masks = player.getVariables().getLong(COND_OVERRIDE_KEY, PcCondOverride.getAllExceptionsMask());
player.setOverrideCond(masks);
}
player.loadRecommendations();
player.startRecoGiveTask();
player.startOnlineTimeUpdateTask();
@@ -7204,7 +7205,7 @@ public final class L2PcInstance extends L2Playable
delete.execute();
int buff_index = 0;
final List<Integer> storedSkills = new ArrayList<>();
final List<Long> storedSkills = new ArrayList<>();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
@@ -7258,26 +7259,27 @@ public final class L2PcInstance extends L2Playable
statement.setInt(1, getObjectId());
statement.setInt(2, skill.getId());
statement.setInt(3, skill.getLevel());
statement.setInt(4, info.getTime());
statement.setInt(4, skill.getSubLevel());
statement.setInt(5, info.getTime());
final TimeStamp t = getSkillReuseTimeStamp(skill.getReuseHashCode());
statement.setLong(5, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
statement.setDouble(6, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
statement.setLong(6, (t != null) && t.hasNotPassed() ? t.getReuse() : 0);
statement.setDouble(7, (t != null) && t.hasNotPassed() ? t.getStamp() : 0);
statement.setInt(7, 0); // Store type 0, active buffs/debuffs.
statement.setInt(8, getClassIndex());
statement.setInt(9, ++buff_index);
statement.setInt(8, 0); // Store type 0, active buffs/debuffs.
statement.setInt(9, getClassIndex());
statement.setInt(10, ++buff_index);
statement.execute();
}
}
// Skills under reuse.
final Map<Integer, TimeStamp> reuseTimeStamps = getSkillReuseTimeStamps();
final Map<Long, TimeStamp> reuseTimeStamps = getSkillReuseTimeStamps();
if (reuseTimeStamps != null)
{
for (Entry<Integer, TimeStamp> ts : reuseTimeStamps.entrySet())
for (Entry<Long, TimeStamp> ts : reuseTimeStamps.entrySet())
{
final int hash = ts.getKey();
final long hash = ts.getKey();
if (storedSkills.contains(hash))
{
continue;
@@ -7291,12 +7293,13 @@ public final class L2PcInstance extends L2Playable
statement.setInt(1, getObjectId());
statement.setInt(2, t.getSkillId());
statement.setInt(3, t.getSkillLvl());
statement.setInt(4, -1);
statement.setLong(5, t.getReuse());
statement.setDouble(6, t.getStamp());
statement.setInt(7, 1); // Restore type 1, skill reuse.
statement.setInt(8, getClassIndex());
statement.setInt(9, ++buff_index);
statement.setInt(4, t.getSkillSubLvl());
statement.setInt(5, -1);
statement.setLong(6, t.getReuse());
statement.setDouble(7, t.getStamp());
statement.setInt(8, 1); // Restore type 1, skill reuse.
statement.setInt(9, getClassIndex());
statement.setInt(10, ++buff_index);
statement.execute();
}
}
@@ -7464,9 +7467,10 @@ public final class L2PcInstance extends L2Playable
try (PreparedStatement ps = con.prepareStatement(UPDATE_CHARACTER_SKILL_LEVEL))
{
ps.setInt(1, newSkill.getLevel());
ps.setInt(2, oldSkill.getId());
ps.setInt(3, getObjectId());
ps.setInt(4, classIndex);
ps.setInt(2, newSkill.getSubLevel());
ps.setInt(3, oldSkill.getId());
ps.setInt(4, getObjectId());
ps.setInt(5, classIndex);
ps.execute();
}
}
@@ -7477,7 +7481,8 @@ public final class L2PcInstance extends L2Playable
ps.setInt(1, getObjectId());
ps.setInt(2, newSkill.getId());
ps.setInt(3, newSkill.getLevel());
ps.setInt(4, classIndex);
ps.setInt(4, newSkill.getSubLevel());
ps.setInt(5, classIndex);
ps.execute();
}
}
@@ -7514,7 +7519,8 @@ public final class L2PcInstance extends L2Playable
ps.setInt(1, getObjectId());
ps.setInt(2, addSkill.getId());
ps.setInt(3, addSkill.getLevel());
ps.setInt(4, classIndex);
ps.setInt(4, addSkill.getSubLevel());
ps.setInt(5, classIndex);
ps.addBatch();
}
ps.executeBatch();
@@ -7543,9 +7549,10 @@ public final class L2PcInstance extends L2Playable
{
final int id = rset.getInt("skill_id");
final int level = rset.getInt("skill_level");
final int subLevel = rset.getInt("skill_sub_level");
// Create a L2Skill object for each record
final Skill skill = SkillData.getInstance().getSkill(id, level);
final Skill skill = SkillData.getInstance().getSkill(id, level, subLevel);
if (skill == null)
{
@@ -7596,7 +7603,7 @@ public final class L2PcInstance extends L2Playable
final long systime = rset.getLong("systime");
final int restoreType = rset.getInt("restore_type");
final Skill skill = SkillData.getInstance().getSkill(rset.getInt("skill_id"), rset.getInt("skill_level"));
final Skill skill = SkillData.getInstance().getSkill(rset.getInt("skill_id"), rset.getInt("skill_level"), rset.getInt("skill_sub_level"));
if (skill == null)
{
continue;
@@ -8305,11 +8312,18 @@ public final class L2PcInstance extends L2Playable
sendPacket(ActionFailed.STATIC_PACKET);
// Upon failed conditions, next action is called.
if ((skill.nextActionIsAttack()) && (target != this) && target.isAutoAttackable(this))
if ((skill.getNextAction() != NextActionType.NONE) && (target != this) && target.isAutoAttackable(this))
{
if ((getAI().getNextIntention() == null) || (getAI().getNextIntention().getCtrlIntention() != CtrlIntention.AI_INTENTION_MOVE_TO))
{
getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
if (skill.getNextAction() == NextActionType.ATTACK)
{
getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
}
else if (skill.getNextAction() == NextActionType.CAST)
{
getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target, item, false, false);
}
}
}
@@ -8453,8 +8467,6 @@ public final class L2PcInstance extends L2Playable
{
_cubics.values().forEach(CubicInstance::deactivate);
_cubics.clear();
sendPacket(new ExUserInfoCubic(this));
broadcastCharInfo();
}
}
@@ -9276,7 +9288,7 @@ public final class L2PcInstance extends L2Playable
public void sendSkillList(int lastLearnedSkillId)
{
boolean isDisabled = false;
final SkillList sl = new SkillList();
SkillList sl = new SkillList();
for (Skill s : getSkillList())
{
@@ -9285,32 +9297,15 @@ public final class L2PcInstance extends L2Playable
isDisabled = s.isClanSkill() && (getClan().getReputationScore() < 0);
}
boolean isEnchantable = SkillData.getInstance().isEnchantable(s.getId());
if (isEnchantable)
{
final L2EnchantSkillLearn esl = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(s.getId());
if (esl != null)
{
// if player dont have min level to enchant
if (s.getLevel() < esl.getBaseLevel())
{
isEnchantable = false;
}
}
// if no enchant data
else
{
isEnchantable = false;
}
}
sl.addSkill(s.getDisplayId(), s.getReuseDelayGroup(), s.getDisplayLevel(), s.isPassive(), isDisabled, isEnchantable);
sl.addSkill(s.getDisplayId(), s.getReuseDelayGroup(), s.getDisplayLevel(), s.getSubLevel(), s.isPassive(), isDisabled, s.isEnchantable());
}
if (lastLearnedSkillId > 0)
{
sl.setLastLearnedSkillId(lastLearnedSkillId);
}
sendPacket(sl);
sendPacket(new AcquireSkillList(this));
}
/**
@@ -9377,7 +9372,7 @@ public final class L2PcInstance extends L2Playable
getSubClasses().put(newClass.getClassIndex(), newClass);
final ClassId subTemplate = ClassId.getClassId(classId);
final Map<Integer, L2SkillLearn> skillTree = SkillTreesData.getInstance().getCompleteClassSkillTree(subTemplate);
final Map<Long, L2SkillLearn> skillTree = SkillTreesData.getInstance().getCompleteClassSkillTree(subTemplate);
final Map<Integer, Skill> prevSkillList = new HashMap<>();
for (L2SkillLearn skillInfo : skillTree.values())
{
@@ -9457,6 +9452,18 @@ public final class L2PcInstance extends L2Playable
{
getVariables().remove(PlayerVariables.ABILITY_POINTS_DUAL_CLASS);
getVariables().remove(PlayerVariables.ABILITY_POINTS_USED_DUAL_CLASS);
int revelationSkill = getVariables().getInt(PlayerVariables.REVELATION_SKILL_1_DUAL_CLASS, 0);
if (revelationSkill != 0)
{
removeSkill(revelationSkill);
}
revelationSkill = getVariables().getInt(PlayerVariables.REVELATION_SKILL_2_DUAL_CLASS, 0);
if (revelationSkill != 0)
{
removeSkill(revelationSkill);
}
getVariables().remove(PlayerVariables.REVELATION_SKILL_1_DUAL_CLASS);
getVariables().remove(PlayerVariables.REVELATION_SKILL_2_DUAL_CLASS);
}
}
catch (Exception e)
@@ -10611,7 +10618,7 @@ public final class L2PcInstance extends L2Playable
{
if (isFlying())
{
removeSkill(SkillData.getInstance().getSkill(4289, 1));
removeSkill(SkillData.getInstance().getSkill(CommonSkill.WYVERN_BREATH.getId(), 1));
}
}
catch (Exception e)
@@ -10807,6 +10814,15 @@ public final class L2PcInstance extends L2Playable
}
}
try
{
stopCubics();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "deleteMe()", e);
}
// Update database with items in its inventory and remove them from the world
try
{
@@ -12404,7 +12420,7 @@ public final class L2PcInstance extends L2Playable
final int damage = (int) Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), null, null, false, true, false, false);
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), this, null, false, true, false, false);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_RECEIVED_S1_FALLING_DAMAGE);
sm.addInt(damage);
sendPacket(sm);
@@ -12566,7 +12582,7 @@ public final class L2PcInstance extends L2Playable
private void deacreaseSkillLevel(Skill skill, int lvlDiff)
{
int nextLevel = -1;
final Map<Integer, L2SkillLearn> skillTree = SkillTreesData.getInstance().getCompleteClassSkillTree(getClassId());
final Map<Long, L2SkillLearn> skillTree = SkillTreesData.getInstance().getCompleteClassSkillTree(getClassId());
for (L2SkillLearn sl : skillTree.values())
{
if ((sl.getSkillId() == skill.getId()) && (nextLevel < sl.getSkillLevel()) && (getLevel() >= (sl.getGetLevel() - lvlDiff)))

View File

@@ -78,8 +78,8 @@ public class L2PetInstance extends L2Summon
{
protected static final Logger _logPet = Logger.getLogger(L2PetInstance.class.getName());
private static final String ADD_SKILL_SAVE = "INSERT INTO character_pet_skills_save (petObjItemId,skill_id,skill_level,remaining_time,buff_index) VALUES (?,?,?,?,?)";
private static final String RESTORE_SKILL_SAVE = "SELECT petObjItemId,skill_id,skill_level,remaining_time,buff_index FROM character_pet_skills_save WHERE petObjItemId=? ORDER BY buff_index ASC";
private static final String ADD_SKILL_SAVE = "INSERT INTO character_pet_skills_save (petObjItemId,skill_id,skill_level,skill_sub_level,remaining_time,buff_index) VALUES (?,?,?,?,?,?)";
private static final String RESTORE_SKILL_SAVE = "SELECT petObjItemId,skill_id,skill_level,skill_sub_level,remaining_time,buff_index FROM character_pet_skills_save WHERE petObjItemId=? ORDER BY buff_index ASC";
private static final String DELETE_SKILL_SAVE = "DELETE FROM character_pet_skills_save WHERE petObjItemId=?";
private int _curFed;
@@ -998,7 +998,7 @@ public class L2PetInstance extends L2Summon
int buff_index = 0;
final Set<Integer> storedSkills = new HashSet<>();
final Set<Long> storedSkills = new HashSet<>();
// Store all effect data along with calculated remaining
if (storeEffects)
@@ -1044,8 +1044,9 @@ public class L2PetInstance extends L2Summon
ps2.setInt(1, getControlObjectId());
ps2.setInt(2, skill.getId());
ps2.setInt(3, skill.getLevel());
ps2.setInt(4, info.getTime());
ps2.setInt(5, ++buff_index);
ps2.setInt(4, skill.getSubLevel());
ps2.setInt(5, info.getTime());
ps2.setInt(6, ++buff_index);
ps2.execute();
SummonEffectsTable.getInstance().getPetEffects().computeIfAbsent(getControlObjectId(), k -> new CopyOnWriteArrayList<>()).add(new SummonEffect(skill, info.getTime()));

View File

@@ -299,7 +299,7 @@ public class L2ServitorInstance extends L2Summon implements Runnable
int buff_index = 0;
final List<Integer> storedSkills = new CopyOnWriteArrayList<>();
final List<Long> storedSkills = new CopyOnWriteArrayList<>();
// Store all effect data along with calculated remaining
if (storeEffects)

View File

@@ -401,7 +401,7 @@ public class CharStat
*/
public final int getShldDef()
{
return (int) getValue(Stats.SHIELD_DEFENCE, 0);
return (int) getValue(Stats.SHIELD_DEFENCE);
}
public long getSp()

View File

@@ -45,7 +45,7 @@ public class WaterTask implements Runnable
reduceHp = 1;
}
_player.reduceCurrentHp(reduceHp, null, null, false, true, false, false);
_player.reduceCurrentHp(reduceHp, _player, null, false, true, false, false);
// reduced hp, becouse not rest
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_TAKEN_S1_DAMAGE_BECAUSE_YOU_WERE_UNABLE_TO_BREATHE);
sm.addInt((int) reduceHp);

View File

@@ -429,7 +429,7 @@ public final class Transform implements IIdentifiable
{
if (player.getLevel() >= holder.getMinLevel())
{
if (player.getSkillLevel(holder.getSkillId()) < holder.getSkillLvl())
if (player.getSkillLevel(holder.getSkillId()) < holder.getSkillLevel())
{
player.addTransformSkill(holder.getSkill());
}

View File

@@ -18,6 +18,7 @@ package com.l2jmobius.gameserver.model.buylist;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
@@ -45,6 +46,7 @@ public final class Product
public Product(int buyListId, L2Item item, long price, long restockDelay, long maxCount)
{
Objects.requireNonNull(item);
_buyListId = buyListId;
_item = item;
_price = price;

View File

@@ -29,14 +29,18 @@ public class PledgeRecruitInfo
private String _information;
private String _detailedInformation;
private final L2Clan _clan;
private final int _applicationType;
private final int _recruitType;
public PledgeRecruitInfo(int clanId, int karma, String information, String detailedInformation)
public PledgeRecruitInfo(int clanId, int karma, String information, String detailedInformation, int applicationType, int recruitType)
{
_clanId = clanId;
_karma = karma;
_information = information;
_detailedInformation = detailedInformation;
_clan = ClanTable.getInstance().getClan(clanId);
_applicationType = applicationType;
_recruitType = recruitType;
}
public int getClanId()
@@ -94,6 +98,16 @@ public class PledgeRecruitInfo
_detailedInformation = detailedInformation;
}
public int getApplicationType()
{
return _applicationType;
}
public int getRecruitType()
{
return _recruitType;
}
public L2Clan getClan()
{
return _clan;

View File

@@ -87,6 +87,6 @@ public class CubicSkill extends SkillHolder implements ICubicConditionHolder
@Override
public String toString()
{
return "Cubic skill id: " + getSkillId() + " level: " + getSkillLvl() + " triggerRate: " + _triggerRate + " successRate: " + _successRate + " canUseOnStaticObjects: " + _canUseOnStaticObjects + " targetType: " + _targetType + " isTargetingDebuff: " + _targetDebuff + Config.EOL;
return "Cubic skill id: " + getSkillId() + " level: " + getSkillLevel() + " triggerRate: " + _triggerRate + " successRate: " + _successRate + " canUseOnStaticObjects: " + _canUseOnStaticObjects + " targetType: " + _targetType + " isTargetingDebuff: " + _targetDebuff + Config.EOL;
}
}

View File

@@ -22,17 +22,15 @@ import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/**
* @author UnAfraid
*/
public class GeneralCondition implements ICubicCondition
public class HpCondition implements ICubicCondition
{
private final GeneralConditionType _type;
private final HpConditionType _type;
private final int _hpPer;
private final int _hp;
public GeneralCondition(GeneralConditionType type, int hpPer, int hp)
public HpCondition(HpConditionType type, int hpPer)
{
_type = type;
_hpPer = hpPer;
_hp = hp;
}
@Override
@@ -43,27 +41,11 @@ public class GeneralCondition implements ICubicCondition
{
case GREATER:
{
if (hpPer < _hpPer)
{
return false;
}
if (target.getCurrentHp() < _hp)
{
return false;
}
break;
return hpPer > _hpPer;
}
case LESSER:
{
if (hpPer > _hpPer)
{
return false;
}
if (target.getCurrentHp() > _hp)
{
return false;
}
break;
return hpPer < _hpPer;
}
}
return true;
@@ -72,10 +54,10 @@ public class GeneralCondition implements ICubicCondition
@Override
public String toString()
{
return getClass().getSimpleName() + " chance: " + _hpPer + " range: " + _hp;
return getClass().getSimpleName() + " chance: " + _hpPer;
}
public static enum GeneralConditionType
public static enum HpConditionType
{
GREATER,
LESSER;

View File

@@ -0,0 +1,39 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.cubic.conditions;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.cubic.CubicInstance;
/**
* @author Sdw
*/
public class RangeCondition implements ICubicCondition
{
private final int _range;
public RangeCondition(int range)
{
_range = range;
}
@Override
public boolean test(CubicInstance cubic, L2Character owner, L2Character target)
{
return owner.distFromMe(target) <= _range;
}
}

View File

@@ -160,7 +160,7 @@ public enum EventType
ON_CREATURE_DAMAGE_RECEIVED(OnCreatureDamageReceived.class, void.class, DamageReturn.class),
ON_CREATURE_DAMAGE_DEALT(OnCreatureDamageDealt.class, void.class),
ON_CREATURE_HP_CHANGE(OnCreatureHpChange.class, void.class),
ON_CREATURE_DEATH(OnCreatureDeath.class, void.class, TerminateReturn.class),
ON_CREATURE_DEATH(OnCreatureDeath.class, void.class),
ON_CREATURE_KILLED(OnCreatureKilled.class, void.class, TerminateReturn.class),
ON_CREATURE_SEE(OnCreatureSee.class, void.class),
ON_CREATURE_SKILL_USE(OnCreatureSkillUse.class, void.class, TerminateReturn.class),

View File

@@ -75,7 +75,7 @@ public class ArmorsetSkillHolder extends SkillHolder
}
// Player already knows that skill
if (player.getSkillLevel(getSkillId()) == getSkillLvl())
if (player.getSkillLevel(getSkillId()) == getSkillLevel())
{
return false;
}

View File

@@ -0,0 +1,84 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.holders;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.l2jmobius.gameserver.enums.SkillEnchantType;
import com.l2jmobius.gameserver.model.StatsSet;
/**
* @author Sdw
*/
public class EnchantSkillHolder
{
private final int _level;
private final int _enchantFailLevel;
private final Map<SkillEnchantType, Long> _sp = new EnumMap<>(SkillEnchantType.class);
private final Map<SkillEnchantType, Integer> _chance = new EnumMap<>(SkillEnchantType.class);
private final Map<SkillEnchantType, Set<ItemHolder>> _requiredItems = new EnumMap<>(SkillEnchantType.class);
public EnchantSkillHolder(StatsSet set)
{
_level = set.getInt("level");
_enchantFailLevel = set.getInt("enchantFailLevel");
}
public int getLevel()
{
return _level;
}
public int getEnchantFailLevel()
{
return _enchantFailLevel;
}
public void addSp(SkillEnchantType type, long sp)
{
_sp.put(type, sp);
}
public long getSp(SkillEnchantType type)
{
return _sp.getOrDefault(type, 0L);
}
public void addChance(SkillEnchantType type, int chance)
{
_chance.put(type, chance);
}
public int getChance(SkillEnchantType type)
{
return _chance.getOrDefault(type, 100);
}
public void addRequiredItem(SkillEnchantType type, ItemHolder item)
{
_requiredItems.computeIfAbsent(type, k -> new HashSet<>()).add(item);
}
public Set<ItemHolder> getRequiredItems(SkillEnchantType type)
{
return _requiredItems.getOrDefault(type, Collections.emptySet());
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.l2jmobius.gameserver.model.holders;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.interfaces.IIdentifiable;
/**
@@ -28,6 +29,12 @@ public class ItemHolder implements IIdentifiable
private final int _id;
private final long _count;
public ItemHolder(StatsSet set)
{
_id = set.getInt("id");
_count = set.getLong("count");
}
public ItemHolder(int id, long count)
{
_id = id;

View File

@@ -26,18 +26,28 @@ import com.l2jmobius.gameserver.model.skills.Skill;
public class SkillHolder
{
private final int _skillId;
private final int _skillLvl;
private final int _skillLevel;
private final int _skillSubLevel;
public SkillHolder(int skillId, int skillLvl)
public SkillHolder(int skillId, int skillLevel)
{
_skillId = skillId;
_skillLvl = skillLvl;
_skillLevel = skillLevel;
_skillSubLevel = 0;
}
public SkillHolder(int skillId, int skillLevel, int skillSubLevel)
{
_skillId = skillId;
_skillLevel = skillLevel;
_skillSubLevel = skillSubLevel;
}
public SkillHolder(Skill skill)
{
_skillId = skill.getId();
_skillLvl = skill.getLevel();
_skillLevel = skill.getLevel();
_skillSubLevel = skill.getSubLevel();
}
public final int getSkillId()
@@ -45,19 +55,52 @@ public class SkillHolder
return _skillId;
}
public final int getSkillLvl()
public final int getSkillLevel()
{
return _skillLvl;
return _skillLevel;
}
public final int getSkillSubLevel()
{
return _skillSubLevel;
}
public final Skill getSkill()
{
return SkillData.getInstance().getSkill(_skillId, Math.max(_skillLvl, 1));
return SkillData.getInstance().getSkill(_skillId, Math.max(_skillLevel, 1), _skillSubLevel);
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof SkillHolder))
{
return false;
}
final SkillHolder holder = (SkillHolder) obj;
return (holder.getSkillId() == _skillId) && (holder.getSkillLevel() == _skillLevel) && (holder.getSkillSubLevel() == _skillSubLevel);
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + _skillId;
result = (prime * result) + _skillLevel;
result = (prime * result) + _skillSubLevel;
return result;
}
@Override
public String toString()
{
return "[SkillId: " + _skillId + " Level: " + _skillLvl + "]";
return "[SkillId: " + _skillId + " Level: " + _skillLevel + "]";
}
}

View File

@@ -30,9 +30,11 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
@@ -432,6 +434,56 @@ public final class Instance implements IIdentifiable, INamable
return spawns;
}
/**
* @param name
* @return {@code List} of NPCs that are part of specified group
*/
public List<L2Npc> getNpcsOfGroup(String name)
{
return getNpcsOfGroup(name, null);
}
/**
* @param groupName
* @param filter
* @return {@code List} of NPCs that are part of specified group and matches filter specified
*/
public List<L2Npc> getNpcsOfGroup(String groupName, Predicate<L2Npc> filter)
{
return getStreamOfGroup(groupName, filter).collect(Collectors.toList());
}
/**
* @param groupName
* @param filter
* @return {@code Npc} instance of an NPC that is part of a group and matches filter specified
*/
public L2Npc getNpcOfGroup(String groupName, Predicate<L2Npc> filter)
{
return getStreamOfGroup(groupName, filter).findFirst().orElse(null);
}
/**
* @param groupName
* @param filter
* @return {@code Stream<Npc>} of NPCs that is part of a group and matches filter specified
*/
public Stream<L2Npc> getStreamOfGroup(String groupName, Predicate<L2Npc> filter)
{
if (filter == null)
{
filter = Objects::nonNull;
}
//@formatter:off
return _spawns.stream()
.flatMap(spawnTemplate -> spawnTemplate.getGroupsByName(groupName).stream())
.flatMap(group -> group.getSpawns().stream())
.flatMap(npcTemplate -> npcTemplate.getSpawnedNpcs().stream())
.filter(filter);
//@formatter:on
}
/**
* Spawn NPCs from group (defined in XML template) into instance world.
* @param name name of group which should be spawned

View File

@@ -23,6 +23,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -277,6 +278,7 @@ public class PcInventory extends Inventory
return _items.values().stream()
.filter(i -> i.isAvailable(getOwner(), false, false))
.map(tradeList::adjustAvailableItem)
.filter(Objects::nonNull)
.collect(Collectors.toCollection(LinkedList::new));
//@formatter:on
}

View File

@@ -17,6 +17,7 @@
package com.l2jmobius.gameserver.model.items;
import java.util.Collection;
import java.util.Objects;
import com.l2jmobius.gameserver.enums.AttributeType;
import com.l2jmobius.gameserver.model.ensoul.EnsoulOption;
@@ -70,6 +71,7 @@ public class L2WarehouseItem
public L2WarehouseItem(L2ItemInstance item)
{
Objects.requireNonNull(item);
_item = item.getItem();
_object = item.getObjectId();
_count = item.getCount();

View File

@@ -2132,6 +2132,11 @@ public final class L2ItemInstance extends L2Object
public void applySpecialAbilities()
{
if (!isEquipped())
{
return;
}
_ensoulOptions.values().forEach(this::applySpecialAbility);
_ensoulSpecialOptions.values().forEach(this::applySpecialAbility);
}

View File

@@ -220,6 +220,8 @@ public enum AbnormalType
CLAN_TEAMWORK(-1),
SONG_OF_ARCHERY(-1),
DANCE_OF_SAGE(-1),
SONG_WEAPON(-1), // TODO: need find proper name
HEAL_RESISTANCE(-1), // TODO: need find proper name
AB_HAWK_EYE(0),
ALL_ATTACK_DOWN(1),
ALL_ATTACK_UP(2),

View File

@@ -24,7 +24,6 @@ import com.l2jmobius.gameserver.model.holders.SkillHolder;
*/
public enum CommonSkill
{
SWEEPER(42, 1),
RAID_CURSE(4215, 1),
RAID_CURSE2(4515, 1),
SEAL_OF_RULER(246, 1),
@@ -58,7 +57,8 @@ public enum CommonSkill
HAIR_ACCESSORY_SET(17192, 1),
ALCHEMY_CUBE(17943, 1),
ALCHEMY_CUBE_RANDOM_SUCCESS(17966, 1),
PET_SWITCH_STANCE(6054, 1);
PET_SWITCH_STANCE(6054, 1),
WEIGHT_PENALTY(4270, 1);
private final SkillHolder _holder;
@@ -74,7 +74,7 @@ public enum CommonSkill
public int getLevel()
{
return _holder.getSkillLvl();
return _holder.getSkillLevel();
}
public Skill getSkill()

View File

@@ -32,11 +32,13 @@ import java.util.stream.Collectors;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
import com.l2jmobius.gameserver.enums.AttributeType;
import com.l2jmobius.gameserver.enums.BasicProperty;
import com.l2jmobius.gameserver.enums.MountType;
import com.l2jmobius.gameserver.enums.NextActionType;
import com.l2jmobius.gameserver.enums.ShotType;
import com.l2jmobius.gameserver.handler.AffectScopeHandler;
import com.l2jmobius.gameserver.handler.IAffectScopeHandler;
@@ -62,7 +64,6 @@ import com.l2jmobius.gameserver.model.stats.BasicPropertyResist;
import com.l2jmobius.gameserver.model.stats.Formulas;
import com.l2jmobius.gameserver.model.stats.TraitType;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation.FlyType;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
public final class Skill implements IIdentifiable
@@ -73,6 +74,8 @@ public final class Skill implements IIdentifiable
private final int _id;
/** Skill level. */
private final int _level;
/** Skill sub level. */
private final int _subLevel;
/** Custom skill ID displayed by the client. */
private final int _displayId;
/** Custom skill level displayed by the client. */
@@ -120,7 +123,7 @@ public final class Skill implements IIdentifiable
private final int _hitTime;
// private final int _skillInterruptTime;
private final int _coolTime;
private final int _reuseHashCode;
private final long _reuseHashCode;
private final int _reuseDelay;
private final int _reuseDelayGroup;
@@ -141,7 +144,7 @@ public final class Skill implements IIdentifiable
private final int[] _affectLimit = new int[3]; // TODO: Third value is unknown... find it out!
private final int[] _affectHeight = new int[2];
private final boolean _nextActionIsAttack;
private final NextActionType _nextAction;
private final boolean _removedOnAnyActionExceptMove;
private final boolean _removedOnDamage;
@@ -163,10 +166,6 @@ public final class Skill implements IIdentifiable
private final Map<SkillConditionScope, List<ISkillCondition>> _conditionLists = new EnumMap<>(SkillConditionScope.class);
private final Map<EffectScope, List<AbstractEffect>> _effectLists = new EnumMap<>(EffectScope.class);
// Flying support
private final FlyType _flyType;
private final int _flyRadius;
private final boolean _isDebuff;
private final boolean _isSuicideAttack;
@@ -210,6 +209,7 @@ public final class Skill implements IIdentifiable
{
_id = set.getInt(".id");
_level = set.getInt(".level");
_subLevel = set.getInt(".subLevel", 0);
_refId = set.getInt(".referenceId", 0);
_displayId = set.getInt(".displayId", _id);
_displayLevel = set.getInt(".displayLevel", _level);
@@ -268,7 +268,7 @@ public final class Skill implements IIdentifiable
}
_reuseDelayGroup = set.getInt("reuseDelayGroup", -1);
_reuseHashCode = SkillData.getSkillHashCode(_reuseDelayGroup > 0 ? _reuseDelayGroup : _id, _level);
_reuseHashCode = SkillData.getSkillHashCode(_reuseDelayGroup > 0 ? _reuseDelayGroup : _id, _level, _subLevel);
_targetType = set.getEnum("targetType", TargetType.class, TargetType.SELF);
_affectScope = set.getEnum("affectScope", AffectScope.class, AffectScope.SINGLE);
@@ -357,7 +357,7 @@ public final class Skill implements IIdentifiable
_minChance = set.getInt("minChance", Config.MIN_ABNORMAL_STATE_SUCCESS_RATE);
_maxChance = set.getInt("maxChance", Config.MAX_ABNORMAL_STATE_SUCCESS_RATE);
_nextActionIsAttack = set.getBoolean("nextActionAttack", false);
_nextAction = set.getEnum("nextAction", NextActionType.class, NextActionType.NONE);
_removedOnAnyActionExceptMove = set.getBoolean("removedOnAnyActionExceptMove", false);
_removedOnDamage = set.getBoolean("removedOnDamage", false);
@@ -378,9 +378,6 @@ public final class Skill implements IIdentifiable
_isTriggeredSkill = set.getBoolean("isTriggeredSkill", false);
_effectPoint = set.getInt("effectPoint", 0);
_flyType = set.getEnum("flyType", FlyType.class, null);
_flyRadius = set.getInt("flyRadius", 0);
_canBeDispelled = set.getBoolean("canBeDispelled", true);
_excludedFromCheck = set.getBoolean("excludedFromCheck", false);
@@ -618,12 +615,12 @@ public final class Skill implements IIdentifiable
}
/**
* Return true if character should attack target after skill
* Return character action after cast
* @return
*/
public boolean nextActionIsAttack()
public NextActionType getNextAction()
{
return _nextActionIsAttack;
return _nextAction;
}
/**
@@ -721,6 +718,14 @@ public final class Skill implements IIdentifiable
return _level;
}
/**
* @return Returns the sub level.
*/
public int getSubLevel()
{
return _subLevel;
}
/**
* @return isMagic integer value from the XML.
*/
@@ -817,7 +822,7 @@ public final class Skill implements IIdentifiable
return _reuseDelayGroup;
}
public int getReuseHashCode()
public long getReuseHashCode()
{
return _reuseHashCode;
}
@@ -933,6 +938,11 @@ public final class Skill implements IIdentifiable
return _operateType.isContinuous() || isSelfContinuous();
}
public boolean isFlyType()
{
return _operateType.isFlyType();
}
public boolean isSelfContinuous()
{
return _operateType.isSelfContinuous();
@@ -953,6 +963,11 @@ public final class Skill implements IIdentifiable
return _operateType.isSynergy();
}
public SkillOperateType getOperateType()
{
return _operateType;
}
/**
* Verify if the skill is a transformation skill.
* @return {@code true} if the skill is a transformation, {@code false} otherwise
@@ -1016,16 +1031,6 @@ public final class Skill implements IIdentifiable
return _soulMaxConsume;
}
public FlyType getFlyType()
{
return _flyType;
}
public int getFlyRadius()
{
return _flyRadius;
}
public boolean isStayAfterDeath()
{
return _stayAfterDeath || isIrreplacableBuff() || isNecessaryToggle();
@@ -1051,7 +1056,7 @@ public final class Skill implements IIdentifiable
return false;
}
return checkConditions(SkillConditionScope.GENERAL, activeChar, object);
return checkConditions(SkillConditionScope.GENERAL, activeChar, object) && checkConditions(SkillConditionScope.TARGET, activeChar, object);
}
/**
@@ -1482,7 +1487,7 @@ public final class Skill implements IIdentifiable
@Override
public String toString()
{
return "Skill " + _name + "(" + _id + "," + _level + ")";
return "Skill " + _name + "(" + _id + "," + _level + "," + _subLevel + ")";
}
/**
@@ -1669,7 +1674,7 @@ public final class Skill implements IIdentifiable
// If character is double casting, return double cast skill.
if ((getDoubleCastSkill() > 0) && activeChar.isAffected(EffectFlag.DOUBLE_CAST))
{
return SkillData.getInstance().getSkill(getDoubleCastSkill(), getLevel());
return SkillData.getInstance().getSkill(getDoubleCastSkill(), getLevel(), getSubLevel());
}
// Default toggle group ID, assume nothing attached.
@@ -1699,7 +1704,7 @@ public final class Skill implements IIdentifiable
return null;
}
return SkillData.getInstance().getSkill(attachedSkill.getSkillId(), getLevel());
return SkillData.getInstance().getSkill(attachedSkill.getSkillId(), getLevel(), getSubLevel());
}
public boolean canDoubleCast()
@@ -1774,4 +1779,9 @@ public final class Skill implements IIdentifiable
{
return _magicCriticalRate;
}
public boolean isEnchantable()
{
return EnchantSkillGroupsData.getInstance().isEnchantable(this);
}
}

View File

@@ -29,15 +29,18 @@ import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.GeoData;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.ai.CtrlEvent;
import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.data.xml.impl.ActionData;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.ItemSkillType;
import com.l2jmobius.gameserver.enums.NextActionType;
import com.l2jmobius.gameserver.enums.StatusUpdateType;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.L2Attackable;
import com.l2jmobius.gameserver.model.actor.L2Character;
@@ -65,6 +68,7 @@ import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
import com.l2jmobius.gameserver.network.serverpackets.ExRotation;
import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation;
import com.l2jmobius.gameserver.network.serverpackets.FlyToLocation.FlyType;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillCanceld;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched;
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
@@ -352,10 +356,9 @@ public class SkillCaster implements Runnable
_targets = _skill.getTargetsAffected(caster, target);
// Finish flying by setting the target location after picking targets. Packet is sent before MagicSkillLaunched.
if (_skill.getFlyType() != null)
if (_skill.isFlyType())
{
caster.broadcastPacket(new FlyToLocation(caster, target, _skill.getFlyType()));
caster.setXYZ(target.getX(), target.getY(), target.getZ());
handleSkillFly(caster, target);
}
// Display animation of launching skill upon targets.
@@ -546,7 +549,7 @@ public class SkillCaster implements Runnable
((L2Character) obj).getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, caster);
}
}
else if (obj.isMonster() || (obj.isPlayable() && ((obj.getActingPlayer().getPvpFlag() > 0) || (obj.getActingPlayer().getReputation() < 0))))
else if (((skill.getEffectPoint() > 0) && obj.isMonster()) || (obj.isPlayable() && ((obj.getActingPlayer().getPvpFlag() > 0) || (obj.getActingPlayer().getReputation() < 0))))
{
// Supporting players or monsters result in pvpflag.
player.updatePvPStatus();
@@ -645,11 +648,18 @@ public class SkillCaster implements Runnable
// Attack target after skill use
// TODO: This shouldnt be here. If skill condition fail, you still go autoattack. This doesn't happen if skill is in cooldown though.
if ((_skill.nextActionIsAttack()) && (target != null) && (target != caster) && target.canBeAttacked())
if ((_skill.getNextAction() != NextActionType.NONE) && (target != null) && (target != caster) && target.canBeAttacked())
{
if ((caster.getAI().getNextIntention() == null) || (caster.getAI().getNextIntention().getCtrlIntention() != CtrlIntention.AI_INTENTION_MOVE_TO))
if ((caster.getAI().getIntention() == null) || (caster.getAI().getIntention() != CtrlIntention.AI_INTENTION_MOVE_TO))
{
caster.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
if (_skill.getNextAction() == NextActionType.ATTACK)
{
caster.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
}
else if (_skill.getNextAction() == NextActionType.CAST)
{
caster.getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, _skill, target, _item, false, false);
}
}
}
}
@@ -800,7 +810,7 @@ public class SkillCaster implements Runnable
return false;
}
if ((skill == null) || caster.isSkillDisabled(skill) || (((skill.getFlyRadius() > 0) || (skill.getFlyType() != null)) && caster.isMovementDisabled()))
if ((skill == null) || caster.isSkillDisabled(skill) || ((skill.isFlyType() && caster.isMovementDisabled())))
{
caster.sendPacket(ActionFailed.STATIC_PACKET);
return false;
@@ -923,4 +933,73 @@ public class SkillCaster implements Runnable
return true;
}
private void handleSkillFly(L2Character creature, L2Object target)
{
int x = 0;
int y = 0;
int z = 0;
FlyType flyType = FlyType.CHARGE;
switch (_skill.getOperateType())
{
case DA4:
case DA5:
{
final double course = _skill.getOperateType() == SkillOperateType.DA4 ? Math.toRadians(270) : Math.toRadians(90);
final double radian = Math.toRadians(Util.convertHeadingToDegree(target.getHeading()));
double nRadius = creature.getCollisionRadius();
if (target.isCharacter())
{
nRadius += ((L2Character) target).getCollisionRadius();
}
x = target.getX() + (int) (Math.cos(Math.PI + radian + course) * nRadius);
y = target.getY() + (int) (Math.sin(Math.PI + radian + course) * nRadius);
z = target.getZ();
break;
}
case DA3:
{
flyType = FlyType.WARP_BACK;
final double radian = Math.toRadians(Util.convertHeadingToDegree(creature.getHeading()));
x = creature.getX() + (int) (Math.cos(Math.PI + radian) * _skill.getCastRange());
y = creature.getY() + (int) (Math.sin(Math.PI + radian) * _skill.getCastRange());
z = creature.getZ();
break;
}
case DA2:
case DA1:
{
if (creature == target)
{
final double course = Math.toRadians(180);
final double radian = Math.toRadians(Util.convertHeadingToDegree(creature.getHeading()));
x = creature.getX() + (int) (Math.cos(Math.PI + radian + course) * _skill.getCastRange());
y = creature.getY() + (int) (Math.sin(Math.PI + radian + course) * _skill.getCastRange());
z = creature.getZ();
}
else
{
final int dx = target.getX() - creature.getX();
final int dy = target.getY() - creature.getY();
final double distance = Math.sqrt((dx * dx) + (dy * dy));
double nRadius = creature.getCollisionRadius();
if (target.isCharacter())
{
nRadius += ((L2Character) target).getCollisionRadius();
}
x = (int) (target.getX() - (nRadius * (dx / distance)));
y = (int) (target.getY() - (nRadius * (dy / distance)));
z = target.getZ();
}
break;
}
}
final Location destination = GeoData.getInstance().moveCheck(creature.getX(), creature.getY(), creature.getZ(), x, y, z, creature.getInstanceWorld());
creature.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
creature.broadcastPacket(new FlyToLocation(creature, destination, flyType, 0, 0, 333));
creature.setXYZ(destination);
creature.revalidateZone(true);
}
}

View File

@@ -45,7 +45,7 @@ public enum SkillOperateType
A2,
/**
* Active Skill with "Instant effect + Continuous effect"
* Active Skill with "Instant effect for target + Continuous effect for self"
*/
A3,
@@ -94,6 +94,16 @@ public enum SkillOperateType
*/
DA3,
/**
* Directional Active Skill with "Left Continuous effect".
*/
DA4,
/**
* Directional Active Skill with "Right Continuous effect".
*/
DA5,
/**
* Passive Skill.
*/
@@ -132,6 +142,8 @@ public enum SkillOperateType
case CA5:
case DA1:
case DA2:
case DA4:
case DA5:
return true;
default:
return false;
@@ -151,6 +163,8 @@ public enum SkillOperateType
case A5:
case A6:
case DA2:
case DA4:
case DA5:
return true;
default:
return false;
@@ -234,4 +248,19 @@ public enum SkillOperateType
{
return (this == A6);
}
public boolean isFlyType()
{
switch (this)
{
case DA1:
case DA2:
case DA3:
case DA4:
case DA5:
return true;
default:
return false;
}
}
}

View File

@@ -274,6 +274,11 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
return null;
}
public void spawn()
{
spawn(null);
}
public void spawn(Instance instance)
{
try

View File

@@ -106,6 +106,11 @@ public class SpawnGroup implements Cloneable, ITerritorized
return _spawns.stream().filter(spawn -> spawn.getId() == id).collect(Collectors.toList());
}
public void spawnAll()
{
spawnAll(null);
}
public void spawnAll(Instance instance)
{
_spawns.forEach(template -> template.spawn(instance));

View File

@@ -156,6 +156,11 @@ public class SpawnTemplate implements Cloneable, ITerritorized, IParameterized<S
_groups.stream().filter(groupFilter).forEach(group -> group.spawnAll(instance));
}
public void spawnAll()
{
spawnAll(null);
}
public void spawnAll(Instance instance)
{
spawn(SpawnGroup::isSpawningByDefault, instance);

View File

@@ -112,7 +112,7 @@ public final class Formulas
final double pvpPveMod = calculatePvpPveBonus(attacker, target, skill, true);
// Initial damage
final double ssmod = ss ? attacker.getStat().getValue(Stats.SHOTS_BONUS, 2) : 1; // 2.04 for dual weapon?
final double ssmod = ss ? (2 * attacker.getStat().getValue(Stats.SHOTS_BONUS)) : 1; // 2.04 for dual weapon?
final double cdMult = criticalMod * (((criticalPositionMod - 1) / 2) + 1) * (((criticalVulnMod - 1) / 2) + 1);
final double cdPatk = criticalAddMod + criticalAddVuln;
final Position position = Position.getPosition(attacker, target);
@@ -156,7 +156,7 @@ public final class Formulas
}
// Bonus Spirit shot
final double shotsBonus = (sps || bss) ? attacker.getStat().getValue(Stats.SHOTS_BONUS, bss ? 4 : 2) : 1;
final double shotsBonus = bss ? (4 * attacker.getStat().getValue(Stats.SHOTS_BONUS)) : sps ? (2 * attacker.getStat().getValue(Stats.SHOTS_BONUS)) : 1;
final double critMod = mcrit ? (2 * calcCritDamage(attacker, target, skill)) : 1; // TODO not really a proper way... find how it works then implement. // damage += attacker.getStat().getValue(Stats.MAGIC_CRIT_DMG_ADD, 0);
// Trait, elements

View File

@@ -46,6 +46,8 @@ import com.l2jmobius.gameserver.model.stats.finalizers.RandomDamageFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.RegenCPFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.RegenHPFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.RegenMPFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.ShieldDefenceFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.ShieldDefenceRateFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.ShotsBonusFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.SpeedFinalizer;
import com.l2jmobius.gameserver.model.stats.finalizers.VampiricChanceFinalizer;
@@ -77,7 +79,7 @@ public enum Stats
PHYSICAL_ATTACK_SPEED("pAtkSpd", new PAttackSpeedFinalizer()),
MAGIC_ATTACK_SPEED("mAtkSpd", new MAttackSpeedFinalizer()), // Magic Skill Casting Time Rate
ATK_REUSE("atkReuse"), // Bows Hits Reuse Rate
SHIELD_DEFENCE("sDef"),
SHIELD_DEFENCE("sDef", new ShieldDefenceFinalizer()),
CRITICAL_DAMAGE("cAtk"),
CRITICAL_DAMAGE_ADD("cAtkAdd"), // this is another type for special critical damage mods - vicious stance, critical power and critical damage SA
HATE_ATTACK("attackHate"),
@@ -108,7 +110,7 @@ public enum Stats
CRITICAL_DAMAGE_SKILL("cAtkSkill"),
CRITICAL_DAMAGE_SKILL_ADD("cAtkSkillAdd"),
MAGIC_CRITICAL_DAMAGE_ADD("mCritPowerAdd"),
SHIELD_DEFENCE_RATE("rShld"),
SHIELD_DEFENCE_RATE("rShld", new ShieldDefenceRateFinalizer()),
CRITICAL_RATE("rCrit", new PCriticalRateFinalizer(), MathUtil::add, MathUtil::add, null, 1d),
CRITICAL_RATE_SKILL("rCritSkill", Stats::defaultValue, MathUtil::add, MathUtil::add, null, 1d),
MAGIC_CRITICAL_RATE("mCritRate", new MCritRateFinalizer()),

View File

@@ -20,9 +20,7 @@ import java.util.Optional;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.stats.IStatsFunction;
import com.l2jmobius.gameserver.model.stats.Stats;
@@ -37,14 +35,6 @@ public class PEvasionRateFinalizer implements IStatsFunction
throwIfPresent(base);
double baseValue = calcWeaponPlusBaseValue(creature, stat);
final Inventory inv = creature.getInventory();
if (inv != null)
{
for (L2ItemInstance item : inv.getPaperdollItems(L2ItemInstance::isEquipped))
{
baseValue += item.getItem().getStats(stat, 0);
}
}
final int level = creature.getLevel();
if (creature.isPlayer())

View File

@@ -0,0 +1,38 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.stats.finalizers;
import java.util.Optional;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.stats.IStatsFunction;
import com.l2jmobius.gameserver.model.stats.Stats;
/**
* @author Sdw
*/
public class ShieldDefenceFinalizer implements IStatsFunction
{
@Override
public double calc(L2Character creature, Optional<Double> base, Stats stat)
{
throwIfPresent(base);
double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
}
}

View File

@@ -0,0 +1,38 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.stats.finalizers;
import java.util.Optional;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.stats.IStatsFunction;
import com.l2jmobius.gameserver.model.stats.Stats;
/**
* @author Sdw
*/
public class ShieldDefenceRateFinalizer implements IStatsFunction
{
@Override
public double calc(L2Character creature, Optional<Double> base, Stats stat)
{
throwIfPresent(base);
double baseValue = calcWeaponPlusBaseValue(creature, stat);
return Stats.defaultValue(creature, stat, baseValue);
}
}

View File

@@ -54,6 +54,8 @@ public class PlayerVariables extends AbstractVariables
public static final String ABILITY_POINTS_DUAL_CLASS = "ABILITY_POINTS_DUAL_CLASS";
public static final String ABILITY_POINTS_USED_MAIN_CLASS = "ABILITY_POINTS_USED";
public static final String ABILITY_POINTS_USED_DUAL_CLASS = "ABILITY_POINTS_DUAL_CLASS_USED";
public static final String REVELATION_SKILL_1_DUAL_CLASS = "DualclassRevelationSkill1";
public static final String REVELATION_SKILL_2_DUAL_CLASS = "DualclassRevelationSkill2";
public static final String EXTEND_DROP = "EXTEND_DROP";
private final int _objectId;

View File

@@ -46,7 +46,8 @@ public enum ZoneId
NO_ITEM_DROP,
NO_RESTART,
SAYUNE,
FISHING;
FISHING,
UNDYING;
public static int getZoneCount()
{

View File

@@ -0,0 +1,45 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.model.zone.type;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.gameserver.model.zone.L2ZoneType;
import com.l2jmobius.gameserver.model.zone.ZoneId;
/**
* An Undying Zone
* @author UnAfraid
*/
public class L2UndyingZone extends L2ZoneType
{
public L2UndyingZone(int id)
{
super(id);
}
@Override
protected void onEnter(L2Character character)
{
character.setInsideZone(ZoneId.UNDYING, true);
}
@Override
protected void onExit(L2Character character)
{
character.setInsideZone(ZoneId.UNDYING, false);
}
}

View File

@@ -325,6 +325,7 @@ public enum ExIncomingPackets implements IIncomingPackets<L2GameClient>
REQUEST_ABILITY_WND_OPEN(0xEE, RequestAbilityWndOpen::new, ConnectionState.IN_GAME),
REQUEST_ABILITY_WND_CLOSE(0xEF, RequestAbilityWndClose::new, ConnectionState.IN_GAME),
EX_PC_CAFE_REQUEST_OPEN_WINDOW_WITHOUT_NPC(0xF0, ExPCCafeRequestOpenWindowWithoutNPC::new, ConnectionState.IN_GAME),
REQUEST_LUCKY_GAME_START_INFO(0xF1, null, ConnectionState.IN_GAME),
REQUEST_LUCKY_GAME_PLAY(0xF2, null, ConnectionState.IN_GAME),
NOTIFY_TRAINING_ROOM_END(0xF3, null, ConnectionState.IN_GAME),
REQUEST_NEW_ENCHANT_PUSH_ONE(0xF4, RequestNewEnchantPushOne::new, ConnectionState.IN_GAME),

View File

@@ -341,11 +341,6 @@ public final class CharacterCreate implements IClientIncomingPacket
}
}
for (L2SkillLearn skill : SkillTreesData.getInstance().getRaceSkillTree(newChar.getRace()))
{
newChar.addSkill(SkillData.getInstance().getSkill(skill.getSkillId(), skill.getSkillLevel()), true);
}
for (L2SkillLearn skill : SkillTreesData.getInstance().getAvailableSkills(newChar, newChar.getClassId(), false, true))
{
if (Config.DEBUG)

View File

@@ -59,7 +59,6 @@ import com.l2jmobius.gameserver.model.variables.PlayerVariables;
import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.AcquireSkillList;
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
import com.l2jmobius.gameserver.network.serverpackets.Die;
import com.l2jmobius.gameserver.network.serverpackets.EtcStatusUpdate;
@@ -336,9 +335,6 @@ public class EnterWorld implements IClientIncomingPacket
// Send Skill list
activeChar.sendSkillList();
// Send acquirable skill list
activeChar.sendPacket(new AcquireSkillList(activeChar));
// Send EtcStatusUpdate
activeChar.sendPacket(new EtcStatusUpdate(activeChar));

View File

@@ -47,7 +47,6 @@ import com.l2jmobius.gameserver.model.variables.PlayerVariables;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.AcquireSkillDone;
import com.l2jmobius.gameserver.network.serverpackets.AcquireSkillList;
import com.l2jmobius.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
import com.l2jmobius.gameserver.network.serverpackets.ExAlchemySkillList;
import com.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
@@ -72,8 +71,8 @@ public final class RequestAcquireSkill implements IClientIncomingPacket
private static final String[] DUALCLASS_REVELATION_VAR_NAMES =
{
"DualclassRevelationSkill1",
"DualclassRevelationSkill2"
PlayerVariables.REVELATION_SKILL_1_DUAL_CLASS,
PlayerVariables.REVELATION_SKILL_2_DUAL_CLASS
};
private int _id;
@@ -594,7 +593,7 @@ public final class RequestAcquireSkill implements IClientIncomingPacket
{
for (SkillHolder skill : skillLearn.getPreReqSkills())
{
if (player.getSkillLevel(skill.getSkillId()) != skill.getSkillLvl())
if (player.getSkillLevel(skill.getSkillId()) != skill.getSkillLevel())
{
if (skill.getSkillId() == CommonSkill.ONYX_BEAST_TRANSFORMATION.getId())
{
@@ -697,7 +696,7 @@ public final class RequestAcquireSkill implements IClientIncomingPacket
player.sendPacket(new ExBasicActionList(ExBasicActionList.DEFAULT_ACTION_LIST));
player.sendSkillList(skill.getId());
player.updateShortCuts(_id, _level);
player.updateShortCuts(_id, _level, 0);
showSkillList(trainer, player);
// If skill is expand type then sends packet:
@@ -724,12 +723,6 @@ public final class RequestAcquireSkill implements IClientIncomingPacket
*/
private void showSkillList(L2Npc trainer, L2PcInstance player)
{
if ((_skillType == AcquireSkillType.TRANSFORM) || (_skillType == AcquireSkillType.TRANSFER))
{
// Managed in Datapack.
return;
}
if (_skillType == AcquireSkillType.SUBCLASS)
{
showSubSkillList(player);
@@ -742,10 +735,6 @@ public final class RequestAcquireSkill implements IClientIncomingPacket
{
L2FishermanInstance.showFishSkillList(player);
}
else
{
player.sendPacket(new AcquireSkillList(player));
}
}
/**

View File

@@ -33,13 +33,15 @@ public class RequestDispel implements IClientIncomingPacket
private int _objectId;
private int _skillId;
private int _skillLevel;
private int _skillSubLevel;
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
_objectId = packet.readD();
_skillId = packet.readD();
_skillLevel = packet.readD();
_skillLevel = packet.readH();
_skillSubLevel = packet.readH();
return true;
}
@@ -55,7 +57,7 @@ public class RequestDispel implements IClientIncomingPacket
{
return;
}
final Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLevel);
final Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLevel, _skillSubLevel);
if (skill == null)
{
return;
@@ -84,9 +86,10 @@ public class RequestDispel implements IClientIncomingPacket
pet.stopSkillEffects(true, _skillId);
}
if (activeChar.hasServitor(_objectId))
final L2Summon servitor = activeChar.getServitor(_objectId);
if (servitor != null)
{
activeChar.removeServitor(_objectId);
servitor.stopSkillEffects(true, _skillId);
}
}
}

View File

@@ -17,7 +17,6 @@
package com.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import com.l2jmobius.Config;
@@ -25,11 +24,12 @@ import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.enums.PrivateStoreType;
import com.l2jmobius.gameserver.enums.SkillEnchantType;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.holders.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
@@ -37,43 +37,41 @@ import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfo;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfoDetail;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillResult;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
/**
* Format (ch) dd c: (id) 0xD0 h: (subid) 0x06 d: skill id d: skill lvl
* @author -Wooden-
*/
public final class RequestExEnchantSkill implements IClientIncomingPacket
{
private static final Logger _logEnchant = Logger.getLogger("enchant.skills");
private int _type; // enchant type: 0 - normal, 1 - safe, 2 - untrain, 3 - change route, 4 - 100%
private static final Logger LOGGER = Logger.getLogger(RequestExEnchantSkill.class.getName());
private static final Logger LOGGER_ENCHANT = Logger.getLogger("enchant.skills");
private SkillEnchantType _type;
private int _skillId;
private int _skillLvl;
private int _fullLvl;
private int _skillSubLvl;
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
_type = packet.readD();
final int type = packet.readD();
if ((type < 0) || (type >= SkillEnchantType.values().length))
{
LOGGER.log(Level.WARNING, "Client: " + client + " send incorrect type " + type + " on packet: " + getClass().getSimpleName());
return false;
}
_type = SkillEnchantType.values()[type];
_skillId = packet.readD();
_fullLvl = packet.readD();
if (_fullLvl < 100)
{
_skillLvl = _fullLvl;
}
else
{
_skillLvl = _fullLvl >> 16;
}
_skillLvl = packet.readH();
_skillSubLvl = packet.readH();
return true;
}
@Override
public void run(L2GameClient client)
{
if ((_skillId <= 0) || (_skillLvl <= 0))
if ((_skillId <= 0) || (_skillLvl <= 0) || (_skillSubLvl < 0))
{
return;
}
@@ -84,487 +82,177 @@ public final class RequestExEnchantSkill implements IClientIncomingPacket
return;
}
if (player.getClassId().level() < 3) // requires to have 3rd class quest completed
if (!player.isInCategory(CategoryType.AWAKEN_GROUP))
{
player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_CLASS_YOU_CAN_USE_CORRESPONDING_FUNCTION_WHEN_COMPLETING_THE_THIRD_CLASS_CHANGE);
return;
}
if (player.getLevel() < 76)
{
player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_ON_THIS_LEVEL_YOU_CAN_USE_THE_CORRESPONDING_FUNCTION_ON_LEVELS_HIGHER_THAN_LV_76);
return;
}
if (!player.isAllowedToEnchantSkills())
{
player.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_STATE_YOU_CAN_ENHANCE_SKILLS_WHEN_NOT_IN_BATTLE_AND_CANNOT_USE_THE_FUNCTION_WHILE_TRANSFORMED_IN_BATTLE_ON_A_MOUNT_OR_WHILE_THE_SKILL_IS_ON_COOLDOWN);
return;
}
if (player.isSellingBuffs())
{
player.sendMessage("You cannot use the skill enhancing function while you selling buffs.");
return;
}
final Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLvl);
if (player.isInOlympiadMode())
{
return;
}
if (player.getPrivateStoreType() != PrivateStoreType.NONE)
{
return;
}
Skill skill = player.getKnownSkill(_skillId);
if (skill == null)
{
return;
}
final L2EnchantSkillLearn s = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_skillId);
if (s == null)
if (!skill.isEnchantable())
{
return;
}
final int _elvl = ((_skillLvl % 100) - 1) / 10;
if (_type == 0) // enchant
{
final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl);
final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId);
if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl))
{
return;
}
final int costMultiplier = EnchantSkillGroupsData.NORMAL_ENCHANT_COST_MULTIPLIER;
final int requiredSp = esd.getSpCost() * costMultiplier;
if (player.getSp() >= requiredSp)
{
final boolean usesBook = true;
final int reqItemId;
if (player.getClassId().level() == 3)
{
reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_OLD;
}
else if (_elvl == 0)
{
reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK;
}
else if (_elvl == 1)
{
reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V2;
}
else
{
reqItemId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V3;
}
final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId);
if (Config.ES_SP_BOOK_NEEDED && usesBook && (spb == null))
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
final int requiredAdena = esd.getAdenaCost() * costMultiplier;
if (player.getInventory().getAdena() < requiredAdena)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
boolean check = player.getStat().removeExpAndSp(0, requiredSp, false);
if (Config.ES_SP_BOOK_NEEDED && usesBook)
{
check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true);
}
check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requiredAdena, player, true);
if (!check)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
// ok. Destroy ONE copy of the book
final int rate = esd.getRate(player);
if (Rnd.get(100) <= rate)
{
if (Config.LOG_SKILL_ENCHANTS)
{
final LogRecord record = new LogRecord(Level.INFO, "Success");
record.setParameters(new Object[]
{
player,
skill,
spb,
rate
});
record.setLoggerName("skill");
_logEnchant.log(record);
}
player.addSkill(skill, true);
player.sendPacket(ExEnchantSkillResult.valueOf(true));
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED);
sm.addSkillName(_skillId);
player.sendPacket(sm);
if (Config.DEBUG)
{
_log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requiredAdena + " Adena.");
}
}
else
{
if (player.getClassId().level() == 3)
{
player.addSkill(SkillData.getInstance().getSkill(_skillId, s.getBaseLevel()), true);
}
else
{
final int _clvl = ((((_skillLvl % 100) - 1) / 10) * 10) + ((_skillLvl / 1000) * 1000);
player.addSkill(SkillData.getInstance().getSkill(_skillId, _clvl), true);
}
player.sendPacket(SystemMessageId.SKILL_ENCHANT_FAILED_THE_SKILL_WILL_BE_INITIALIZED);
player.sendPacket(ExEnchantSkillResult.valueOf(false));
if (Config.LOG_SKILL_ENCHANTS)
{
final LogRecord record = new LogRecord(Level.INFO, "Fail");
record.setParameters(new Object[]
{
player,
skill,
spb,
rate
});
record.setLoggerName("skill");
_logEnchant.log(record);
}
}
player.sendPacket(new UserInfo(player));
player.sendSkillList();
final int afterEnchantSkillLevel = player.getSkillLevel(_skillId);
player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel));
player.sendPacket(new ExEnchantSkillInfoDetail(0, _skillId, afterEnchantSkillLevel + 1, player));
player.updateShortCuts(_skillId, afterEnchantSkillLevel);
}
else
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL);
}
}
else if (_type == 1) // safe enchant
{
final int costMultiplier = EnchantSkillGroupsData.SAFE_ENCHANT_COST_MULTIPLIER;
final int reqItemId;
if (player.getClassId().level() == 3)
{
reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_OLD;
}
else if (_elvl == 0)
{
reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK;
}
else if (_elvl == 1)
{
reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V2;
}
else
{
reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V3;
}
final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl);
final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId);
if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl))
{
return;
}
final int requiredSp = esd.getSpCost() * costMultiplier;
final int requireditems = esd.getAdenaCost() * costMultiplier;
final int rate = esd.getRate(player);
if (player.getSp() >= requiredSp)
{
final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId);
if (spb == null)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
if (player.getInventory().getAdena() < requireditems)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
boolean check = player.getStat().removeExpAndSp(0, requiredSp, false);
check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true);
check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requireditems, player, true);
if (!check)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
if (Rnd.get(100) <= rate)
{
if (Config.LOG_SKILL_ENCHANTS)
{
final LogRecord record = new LogRecord(Level.INFO, "Safe Success");
record.setParameters(new Object[]
{
player,
skill,
spb,
rate
});
record.setLoggerName("skill");
_logEnchant.log(record);
}
player.addSkill(skill, true);
if (Config.DEBUG)
{
_log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requireditems + " Adena.");
}
player.sendPacket(ExEnchantSkillResult.valueOf(true));
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED);
sm.addSkillName(_skillId);
player.sendPacket(sm);
}
else
{
if (Config.LOG_SKILL_ENCHANTS)
{
final LogRecord record = new LogRecord(Level.INFO, "Safe Fail");
record.setParameters(new Object[]
{
player,
skill,
spb,
rate
});
record.setLoggerName("skill");
_logEnchant.log(record);
}
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_FAILED_THE_SKILL_WILL_BE_INITIALIZED);
player.sendPacket(sm);
player.sendPacket(ExEnchantSkillResult.valueOf(false));
}
player.sendPacket(new UserInfo(player));
player.sendSkillList();
final int afterEnchantSkillLevel = player.getSkillLevel(_skillId);
player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel));
player.sendPacket(new ExEnchantSkillInfoDetail(1, _skillId, afterEnchantSkillLevel + 1, player));
player.updateShortCuts(_skillId, afterEnchantSkillLevel);
}
else
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL));
}
}
else if (_type == 2) // untrain
if (skill.getLevel() != _skillLvl)
{
return;
}
else if (_type == 3) // change route
if (skill.getSubLevel() > 0)
{
final int reqItemId;
if (player.getClassId().level() == 3)
if (_type == SkillEnchantType.CHANGE)
{
reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_OLD;
final int group1 = (_skillSubLvl % 1000);
final int group2 = (skill.getSubLevel() % 1000);
if (group1 != group2)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Client: " + client + " send incorrect sub level group: " + group1 + " expected: " + group2);
return;
}
}
else if (_elvl == 0)
{
reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK;
}
else if (_elvl == 1)
{
reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V2;
}
else
{
reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V3;
}
final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId);
if (beforeEnchantSkillLevel <= 1000)
else if ((skill.getSubLevel() + 1) != _skillSubLvl)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Client: " + client + " send incorrect sub level: " + _skillSubLvl + " expected: " + skill.getSubLevel() + 1);
return;
}
final int currentEnchantLevel = beforeEnchantSkillLevel % 1000;
if (currentEnchantLevel != (_skillLvl % 1000))
{
return;
}
final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl);
final int requiredSp = esd.getSpCost();
final int requireditems = esd.getAdenaCost();
if (player.getSp() >= requiredSp)
{
final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId);
if (Config.ES_SP_BOOK_NEEDED && (spb == null))
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_SKILL_ROUTE_CHANGE);
return;
}
if (player.getInventory().getAdena() < requireditems)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
boolean check = player.getStat().removeExpAndSp(0, requiredSp, false);
if (Config.ES_SP_BOOK_NEEDED)
{
check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true);
}
check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requireditems, player, true);
if (!check)
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
final int levelPenalty = Rnd.get(Math.min(4, currentEnchantLevel));
_skillLvl -= levelPenalty;
if ((_skillLvl % 1000) == 0)
{
_skillLvl = s.getBaseLevel();
}
if (Config.LOG_SKILL_ENCHANTS)
{
final LogRecord record = new LogRecord(Level.INFO, "Route Change");
record.setParameters(new Object[]
{
player,
skill,
spb
});
record.setLoggerName("skill");
_logEnchant.log(record);
}
player.addSkill(SkillData.getInstance().getSkill(_skillId, _skillLvl), true);
player.sendPacket(ExEnchantSkillResult.valueOf(true));
if (Config.DEBUG)
{
_log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requireditems + " Adena.");
}
player.sendPacket(new UserInfo(player));
final SystemMessage sm;
if (levelPenalty == 0)
{
sm = SystemMessage.getSystemMessage(SystemMessageId.ENCHANT_SKILL_ROUTE_CHANGE_WAS_SUCCESSFUL_LV_OF_ENCHANT_SKILL_S1_WILL_REMAIN);
sm.addSkillName(_skillId);
}
else
{
sm = SystemMessage.getSystemMessage(SystemMessageId.ENCHANT_SKILL_ROUTE_CHANGE_WAS_SUCCESSFUL_LV_OF_ENCHANT_SKILL_S1_HAS_BEEN_DECREASED_BY_S2);
sm.addSkillName(_skillId);
if (_skillLvl > 1000)
{
sm.addInt(_skillLvl % 1000);
}
else
{
sm.addInt(0);
}
}
player.sendPacket(sm);
player.sendSkillList();
final int afterEnchantSkillLevel = player.getSkillLevel(_skillId);
player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel));
player.sendPacket(new ExEnchantSkillInfoDetail(3, _skillId, afterEnchantSkillLevel, player));
player.updateShortCuts(_skillId, afterEnchantSkillLevel);
}
else
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL));
}
}
else if (_type == 4) // 100% enchant
final EnchantSkillHolder enchantSkillHolder = EnchantSkillGroupsData.getInstance().getEnchantSkillHolder(_skillSubLvl % 1000);
// Verify if player has all the ingredients
for (ItemHolder holder : enchantSkillHolder.getRequiredItems(_type))
{
final int reqItemId;
if (player.getClassId().level() == 3)
{
reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL;
}
else if (_elvl == 0)
{
reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL;
}
else if (_elvl == 1)
{
reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V2;
}
else
{
reqItemId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V3;
}
final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId);
if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl))
{
return;
}
final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId);
if (spb == null)
if (player.getInventory().getInventoryItemCount(holder.getId(), 0) < holder.getCount())
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
player.destroyItem("Consume", spb.getObjectId(), 1, player, true);
if (Config.LOG_SKILL_ENCHANTS)
{
final LogRecord record = new LogRecord(Level.INFO, "100% Success");
record.setParameters(new Object[]
{
player,
skill,
spb,
100
});
record.setLoggerName("skill");
_logEnchant.log(record);
}
player.addSkill(skill, true);
if (Config.DEBUG)
{
_log.fine("Learned skill ID: " + _skillId + " Level: " + _skillLvl + ".");
}
player.sendPacket(ExEnchantSkillResult.valueOf(true));
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED);
sm.addSkillName(_skillId);
player.sendPacket(sm);
player.sendPacket(new UserInfo(player));
player.sendSkillList();
final int afterEnchantSkillLevel = player.getSkillLevel(_skillId);
player.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel));
player.sendPacket(new ExEnchantSkillInfoDetail(1, _skillId, afterEnchantSkillLevel + 1, player));
player.updateShortCuts(_skillId, afterEnchantSkillLevel);
}
// Consume all ingredients
for (ItemHolder holder : enchantSkillHolder.getRequiredItems(_type))
{
if (!player.destroyItemByItemId("Skill enchanting", holder.getId(), holder.getCount(), player, true))
{
return;
}
}
if (player.getSp() < enchantSkillHolder.getSp(_type))
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL);
return;
}
player.getStat().removeExpAndSp(0, enchantSkillHolder.getSp(_type), false);
switch (_type)
{
case BLESSED:
case NORMAL:
case IMMORTAL:
{
if (Rnd.get(100) <= enchantSkillHolder.getChance(_type))
{
final Skill enchantedSkill = SkillData.getInstance().getSkill(_skillId, _skillLvl, _skillSubLvl);
if (Config.LOG_SKILL_ENCHANTS)
{
LOGGER_ENCHANT.log(Level.INFO, "Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + enchantedSkill.getLevel() + " " + enchantedSkill.getSubLevel() + " - " + enchantedSkill.getName() + " (" + enchantedSkill.getId() + "), " + enchantSkillHolder.getChance(_type));
}
player.addSkill(enchantedSkill, true);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED);
sm.addSkillName(_skillId);
player.sendPacket(sm);
player.sendPacket(ExEnchantSkillResult.STATIC_PACKET_TRUE);
}
else
{
final int newSubLevel = skill.getSubLevel() > 0 ? ((skill.getSubLevel() - (skill.getSubLevel() % 1000)) + enchantSkillHolder.getEnchantFailLevel()) : 0;
final Skill enchantedSkill = SkillData.getInstance().getSkill(_skillId, _skillLvl, _type == SkillEnchantType.NORMAL ? newSubLevel : skill.getSubLevel());
if (_type == SkillEnchantType.NORMAL)
{
player.addSkill(enchantedSkill, true);
player.sendPacket(SystemMessageId.SKILL_ENCHANT_FAILED_THE_SKILL_WILL_BE_INITIALIZED);
}
else if (_type == SkillEnchantType.BLESSED)
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_FAILED_CURRENT_LEVEL_OF_ENCHANT_SKILL_S1_WILL_REMAIN_UNCHANGED).addSkillName(skill));
}
player.sendPacket(ExEnchantSkillResult.STATIC_PACKET_FALSE);
if (Config.LOG_SKILL_ENCHANTS)
{
LOGGER_ENCHANT.log(Level.INFO, "Failed, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + enchantedSkill.getLevel() + " " + enchantedSkill.getSubLevel() + " - " + enchantedSkill.getName() + " (" + enchantedSkill.getId() + "), " + enchantSkillHolder.getChance(_type));
}
}
break;
}
case CHANGE:
{
if (Rnd.get(100) <= enchantSkillHolder.getChance(_type))
{
final Skill enchantedSkill = SkillData.getInstance().getSkill(_skillId, _skillLvl, _skillSubLvl);
if (Config.LOG_SKILL_ENCHANTS)
{
LOGGER_ENCHANT.info("Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + enchantedSkill.getLevel() + " " + enchantedSkill.getSubLevel() + " - " + enchantedSkill.getName() + " (" + enchantedSkill.getId() + "), " + enchantSkillHolder.getChance(_type));
}
player.addSkill(enchantedSkill, true);
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.ENCHANT_SKILL_ROUTE_CHANGE_WAS_SUCCESSFUL_LV_OF_ENCHANT_SKILL_S1_WILL_REMAIN);
sm.addSkillName(_skillId);
player.sendPacket(sm);
player.sendPacket(ExEnchantSkillResult.STATIC_PACKET_TRUE);
}
else
{
final Skill enchantedSkill = SkillData.getInstance().getSkill(_skillId, _skillLvl, enchantSkillHolder.getEnchantFailLevel());
player.addSkill(enchantedSkill, true);
player.sendPacket(SystemMessageId.SKILL_ENCHANT_FAILED_THE_SKILL_WILL_BE_INITIALIZED);
player.sendPacket(ExEnchantSkillResult.STATIC_PACKET_FALSE);
if (Config.LOG_SKILL_ENCHANTS)
{
LOGGER_ENCHANT.log(Level.INFO, "Failed, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + enchantedSkill.getLevel() + " " + enchantedSkill.getSubLevel() + " - " + enchantedSkill.getName() + " (" + enchantedSkill.getId() + "), " + enchantSkillHolder.getChance(_type));
}
}
break;
}
}
player.broadcastUserInfo();
player.sendSkillList();
skill = player.getKnownSkill(_skillId);
player.sendPacket(new ExEnchantSkillInfo(skill.getId(), skill.getLevel(), skill.getSubLevel(), skill.getSubLevel()));
player.sendPacket(new ExEnchantSkillInfoDetail(_type, skill.getId(), skill.getLevel(), Math.min(skill.getSubLevel() + 1, EnchantSkillGroupsData.MAX_ENCHANT_LEVEL), player));
player.updateShortCuts(skill.getLevel(), skill.getSubLevel(), skill.getSubLevel());
}
}

View File

@@ -16,9 +16,12 @@
*/
package com.l2jmobius.gameserver.network.clientpackets;
import java.util.Set;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.client.L2GameClient;
@@ -32,28 +35,21 @@ public final class RequestExEnchantSkillInfo implements IClientIncomingPacket
{
private int _skillId;
private int _skillLvl;
private int _fullLvl;
private int _skillSubLvl;
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
_skillId = packet.readD();
_fullLvl = packet.readD();
if (_fullLvl < 100)
{
_skillLvl = _fullLvl;
}
else
{
_skillLvl = _fullLvl >> 16;
}
_skillLvl = packet.readH();
_skillSubLvl = packet.readH();
return true;
}
@Override
public void run(L2GameClient client)
{
if ((_skillId <= 0) || (_skillLvl <= 0))
if ((_skillId <= 0) || (_skillLvl <= 0) || (_skillSubLvl < 0))
{
return;
}
@@ -65,28 +61,30 @@ public final class RequestExEnchantSkillInfo implements IClientIncomingPacket
return;
}
if (activeChar.getLevel() < 76)
if (!activeChar.isInCategory(CategoryType.AWAKEN_GROUP))
{
return;
}
final Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLvl);
final Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLvl, _skillSubLvl);
if ((skill == null) || (skill.getId() != _skillId))
{
return;
}
if (EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_skillId) == null)
final Set<Integer> route = EnchantSkillGroupsData.getInstance().getRouteForSkill(_skillId, _skillLvl);
if (route.isEmpty())
{
return;
}
final int playerSkillLvl = activeChar.getSkillLevel(_skillId);
if ((playerSkillLvl == -1) || (playerSkillLvl != _skillLvl))
final Skill playerSkill = activeChar.getKnownSkill(_skillId);
if ((playerSkill.getLevel() != _skillLvl) || (playerSkill.getSubLevel() != _skillSubLvl))
{
return;
}
activeChar.sendPacket(new ExEnchantSkillInfo(_skillId, _skillLvl));
client.sendPacket(new ExEnchantSkillInfo(_skillId, _skillLvl, _skillSubLvl, playerSkill.getSubLevel()));
// ExEnchantSkillInfoDetail - not really necessary I think
// client.sendPacket(new ExEnchantSkillInfoDetail(SkillEnchantType.NORMAL, _skillId, _skillLvl, _skillSubLvl, activeChar));
}
}

View File

@@ -17,107 +17,44 @@
package com.l2jmobius.gameserver.network.clientpackets;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.enums.SkillEnchantType;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfoDetail;
/**
* Format (ch) ddd c: (id) 0xD0 h: (subid) 0x31 d: type d: skill id d: skill lvl
* @author -Wooden-
*/
public final class RequestExEnchantSkillInfoDetail implements IClientIncomingPacket
{
private int _type;
private SkillEnchantType _type;
private int _skillId;
private int _skillLvl;
private int _fullLvl;
private int _skillSubLvl;
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
_type = packet.readD();
_type = SkillEnchantType.values()[packet.readD()];
_skillId = packet.readD();
_fullLvl = packet.readD();
if (_fullLvl < 100)
{
_skillLvl = _fullLvl;
}
else
{
_skillLvl = _fullLvl >> 16;
}
_skillLvl = packet.readH();
_skillSubLvl = packet.readH();
return true;
}
@Override
public void run(L2GameClient client)
{
if ((_skillId <= 0) || (_skillLvl <= 0))
if ((_skillId <= 0) || (_skillLvl <= 0) || (_skillSubLvl < 0))
{
return;
}
final L2PcInstance activeChar = client.getActiveChar();
if (activeChar == null)
{
return;
}
int reqSkillLvl = -2;
if ((_type == 0) || (_type == 1))
{
reqSkillLvl = _skillLvl - 1; // enchant
}
else if (_type == 2)
{
return;
}
else if (_type == 3)
{
reqSkillLvl = _skillLvl; // change route
}
final int playerSkillLvl = activeChar.getSkillLevel(_skillId);
// dont have such skill
if (playerSkillLvl == -1)
{
return;
}
// if reqlvl is 100,200,.. check base skill lvl enchant
if ((reqSkillLvl % 1000) == 0)
{
final L2EnchantSkillLearn esl = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_skillId);
if (esl != null)
{
// if player dont have min level to enchant
if (playerSkillLvl != esl.getBaseLevel())
{
return;
}
}
// enchant data dont exist?
else
{
return;
}
}
else if (playerSkillLvl != reqSkillLvl)
{
// change route is different skill lvl but same enchant
if ((_type == 3) && ((playerSkillLvl % 1000) != (_skillLvl % 1000)))
{
return;
}
}
// send skill enchantment detail
final ExEnchantSkillInfoDetail esd = new ExEnchantSkillInfoDetail(_type, _skillId, _skillLvl, activeChar);
activeChar.sendPacket(esd);
activeChar.sendPacket(new ExEnchantSkillInfoDetail(_type, _skillId, _skillLvl, _skillSubLvl, activeChar));
}
}

View File

@@ -1,229 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfo;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfoDetail;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillResult;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
/**
* Format (ch) dd c: (id) 0xD0 h: (subid) 0x34 d: skill id d: skill lvl
* @author -Wooden-
*/
public final class RequestExEnchantSkillRouteChange implements IClientIncomingPacket
{
private static final Logger _logEnchant = Logger.getLogger("enchant.skills");
private int _skillId;
private int _skillLvl;
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
_skillId = packet.readD();
_skillLvl = packet.readD();
return true;
}
@Override
public void run(L2GameClient client)
{
if ((_skillId <= 0) || (_skillLvl <= 0))
{
return;
}
final L2PcInstance player = client.getActiveChar();
if (player == null)
{
return;
}
if (player.getClassId().level() < 3) // requires to have 3rd class quest completed
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_CLASS_YOU_CAN_USE_CORRESPONDING_FUNCTION_WHEN_COMPLETING_THE_THIRD_CLASS_CHANGE);
return;
}
if (player.getLevel() < 76)
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_ON_THIS_LEVEL_YOU_CAN_USE_THE_CORRESPONDING_FUNCTION_ON_LEVELS_HIGHER_THAN_LV_76);
return;
}
if (!player.isAllowedToEnchantSkills())
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_STATE_YOU_CAN_ENHANCE_SKILLS_WHEN_NOT_IN_BATTLE_AND_CANNOT_USE_THE_FUNCTION_WHILE_TRANSFORMED_IN_BATTLE_ON_A_MOUNT_OR_WHILE_THE_SKILL_IS_ON_COOLDOWN);
return;
}
Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLvl);
if (skill == null)
{
return;
}
final int reqItemId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK;
final L2EnchantSkillLearn s = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_skillId);
if (s == null)
{
return;
}
final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId);
// do u have this skill enchanted?
if (beforeEnchantSkillLevel <= 100)
{
return;
}
final int currentEnchantLevel = beforeEnchantSkillLevel % 100;
// is the requested level valid?
if (currentEnchantLevel != (_skillLvl % 100))
{
return;
}
final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl);
final int requiredSp = esd.getSpCost();
final int requireditems = esd.getAdenaCost();
if (player.getSp() >= requiredSp)
{
// only first lvl requires book
final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId);
if (Config.ES_SP_BOOK_NEEDED)
{
if (spb == null)// Haven't spellbook
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_SKILL_ROUTE_CHANGE);
return;
}
}
if (player.getInventory().getAdena() < requireditems)
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
boolean check;
check = player.getStat().removeExpAndSp(0, requiredSp, false);
if (Config.ES_SP_BOOK_NEEDED)
{
check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true);
}
check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requireditems, player, true);
if (!check)
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
final int levelPenalty = Rnd.get(Math.min(4, currentEnchantLevel));
_skillLvl -= levelPenalty;
if ((_skillLvl % 100) == 0)
{
_skillLvl = s.getBaseLevel();
}
skill = SkillData.getInstance().getSkill(_skillId, _skillLvl);
if (skill != null)
{
if (Config.LOG_SKILL_ENCHANTS)
{
if (skill.getLevel() > 100)
{
if (spb != null)
{
_logEnchant.info("Route Change, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "]");
}
else
{
_logEnchant.info("Route Change, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + ")");
}
}
else
{
if (spb != null)
{
_logEnchant.info("Route Change, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "]");
}
else
{
_logEnchant.info("Route Change, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + ")");
}
}
}
player.addSkill(skill, true);
client.sendPacket(ExEnchantSkillResult.valueOf(true));
}
if (Config.DEBUG)
{
_log.finer("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requireditems + " Adena.");
}
client.sendPacket(new UserInfo(player));
if (levelPenalty == 0)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.ENCHANT_SKILL_ROUTE_CHANGE_WAS_SUCCESSFUL_LV_OF_ENCHANT_SKILL_S1_WILL_REMAIN);
sm.addSkillName(_skillId);
client.sendPacket(sm);
}
else
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.ENCHANT_SKILL_ROUTE_CHANGE_WAS_SUCCESSFUL_LV_OF_ENCHANT_SKILL_S1_HAS_BEEN_DECREASED_BY_S2);
sm.addSkillName(_skillId);
sm.addInt(levelPenalty);
client.sendPacket(sm);
}
player.sendSkillList();
final int afterEnchantSkillLevel = player.getSkillLevel(_skillId);
client.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel));
client.sendPacket(new ExEnchantSkillInfoDetail(3, _skillId, afterEnchantSkillLevel, player));
player.updateShortCuts(_skillId, afterEnchantSkillLevel);
}
else
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL);
client.sendPacket(sm);
}
}
}

View File

@@ -1,204 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.commons.util.Rnd;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfo;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfoDetail;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillResult;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
/**
* Format (ch) dd c: (id) 0xD0 h: (subid) 0x32 d: skill id d: skill lvl
* @author -Wooden-
*/
public final class RequestExEnchantSkillSafe implements IClientIncomingPacket
{
private static final Logger _logEnchant = Logger.getLogger("enchant.skills");
private int _skillId;
private int _skillLvl;
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
_skillId = packet.readD();
_skillLvl = packet.readD();
return true;
}
@Override
public void run(L2GameClient client)
{
if ((_skillId <= 0) || (_skillLvl <= 0))
{
return;
}
final L2PcInstance player = client.getActiveChar();
if (player == null)
{
return;
}
if (player.getClassId().level() < 3) // requires to have 3rd class quest completed
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_CLASS_YOU_CAN_USE_CORRESPONDING_FUNCTION_WHEN_COMPLETING_THE_THIRD_CLASS_CHANGE);
return;
}
if (player.getLevel() < 76)
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_ON_THIS_LEVEL_YOU_CAN_USE_THE_CORRESPONDING_FUNCTION_ON_LEVELS_HIGHER_THAN_LV_76);
return;
}
if (!player.isAllowedToEnchantSkills())
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_STATE_YOU_CAN_ENHANCE_SKILLS_WHEN_NOT_IN_BATTLE_AND_CANNOT_USE_THE_FUNCTION_WHILE_TRANSFORMED_IN_BATTLE_ON_A_MOUNT_OR_WHILE_THE_SKILL_IS_ON_COOLDOWN);
return;
}
if (player.isSellingBuffs())
{
player.sendMessage("You cannot use the skill enchanting function while you selling buffs.");
return;
}
final Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLvl);
if (skill == null)
{
return;
}
final int costMultiplier = Config.SAFE_ENCHANT_COST_MULTIPLIER;
final int reqItemId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK;
final L2EnchantSkillLearn s = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_skillId);
if (s == null)
{
return;
}
final EnchantSkillHolder esd = s.getEnchantSkillHolder(_skillLvl);
final int beforeEnchantSkillLevel = player.getSkillLevel(_skillId);
if (beforeEnchantSkillLevel != s.getMinSkillLevel(_skillLvl))
{
return;
}
final int requiredSp = esd.getSpCost() * costMultiplier;
final int requireditems = esd.getAdenaCost() * costMultiplier;
final int rate = esd.getRate(player);
if (player.getSp() >= requiredSp)
{
// No config option for safe enchant book consume
final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId);
if (spb == null) // Haven't spellbook
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
if (player.getInventory().getAdena() < requireditems)
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
boolean check = player.getStat().removeExpAndSp(0, requiredSp, false);
check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true);
check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requireditems, player, true);
if (!check)
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
// ok. Destroy ONE copy of the book
if (Rnd.get(100) <= rate)
{
if (Config.LOG_SKILL_ENCHANTS)
{
if (skill.getLevel() > 100)
{
_logEnchant.info("Safe Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate);
}
else
{
_logEnchant.info("Safe Success, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate);
}
}
player.addSkill(skill, true);
client.sendPacket(ExEnchantSkillResult.valueOf(true));
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_WAS_SUCCESSFUL_S1_HAS_BEEN_ENCHANTED);
sm.addSkillName(_skillId);
client.sendPacket(sm);
}
else
{
if (Config.LOG_SKILL_ENCHANTS)
{
if (skill.getLevel() > 100)
{
_logEnchant.info("Safe Fail, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate);
}
else
{
_logEnchant.info("Safe Fail, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "], " + rate);
}
}
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.SKILL_ENCHANT_FAILED_CURRENT_LEVEL_OF_ENCHANT_SKILL_S1_WILL_REMAIN_UNCHANGED);
sm.addSkillName(_skillId);
client.sendPacket(sm);
client.sendPacket(ExEnchantSkillResult.valueOf(false));
}
client.sendPacket(new UserInfo(player));
player.sendSkillList();
final int afterEnchantSkillLevel = player.getSkillLevel(_skillId);
client.sendPacket(new ExEnchantSkillInfo(_skillId, afterEnchantSkillLevel));
client.sendPacket(new ExEnchantSkillInfoDetail(1, _skillId, afterEnchantSkillLevel + 1, player));
player.updateShortCuts(_skillId, afterEnchantSkillLevel);
}
else
{
client.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_SP_TO_ENCHANT_THAT_SKILL));
}
}
}

View File

@@ -1,206 +0,0 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.network.clientpackets;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.network.PacketReader;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfo;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillInfoDetail;
import com.l2jmobius.gameserver.network.serverpackets.ExEnchantSkillResult;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
/**
* Format (ch) dd c: (id) 0xD0 h: (subid) 0x33 d: skill id d: skill lvl
* @author -Wooden-
*/
public final class RequestExEnchantSkillUntrain implements IClientIncomingPacket
{
private static final Logger _logEnchant = Logger.getLogger("enchant.skills");
private int _skillId;
private int _skillLvl;
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
_skillId = packet.readD();
_skillLvl = packet.readD();
return true;
}
@Override
public void run(L2GameClient client)
{
if ((_skillId <= 0) || (_skillLvl <= 0))
{
return;
}
final L2PcInstance player = client.getActiveChar();
if (player == null)
{
return;
}
if (player.getClassId().level() < 3) // requires to have 3rd class quest completed
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_CLASS_YOU_CAN_USE_CORRESPONDING_FUNCTION_WHEN_COMPLETING_THE_THIRD_CLASS_CHANGE);
return;
}
if (player.getLevel() < 76)
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_ON_THIS_LEVEL_YOU_CAN_USE_THE_CORRESPONDING_FUNCTION_ON_LEVELS_HIGHER_THAN_LV_76);
return;
}
if (!player.isAllowedToEnchantSkills())
{
client.sendPacket(SystemMessageId.YOU_CANNOT_USE_THE_SKILL_ENHANCING_FUNCTION_IN_THIS_STATE_YOU_CAN_ENHANCE_SKILLS_WHEN_NOT_IN_BATTLE_AND_CANNOT_USE_THE_FUNCTION_WHILE_TRANSFORMED_IN_BATTLE_ON_A_MOUNT_OR_WHILE_THE_SKILL_IS_ON_COOLDOWN);
return;
}
final L2EnchantSkillLearn s = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_skillId);
if (s == null)
{
return;
}
if ((_skillLvl % 100) == 0)
{
_skillLvl = s.getBaseLevel();
}
final Skill skill = SkillData.getInstance().getSkill(_skillId, _skillLvl);
if (skill == null)
{
return;
}
final int reqItemId = EnchantSkillGroupsData.UNTRAIN_ENCHANT_BOOK;
final int beforeUntrainSkillLevel = player.getSkillLevel(_skillId);
if (((beforeUntrainSkillLevel - 1) != _skillLvl) && (((beforeUntrainSkillLevel % 100) != 1) || (_skillLvl != s.getBaseLevel())))
{
return;
}
final EnchantSkillHolder esd = s.getEnchantSkillHolder(beforeUntrainSkillLevel);
final int requiredSp = esd.getSpCost();
final int requireditems = esd.getAdenaCost();
final L2ItemInstance spb = player.getInventory().getItemByItemId(reqItemId);
if (Config.ES_SP_BOOK_NEEDED)
{
if (spb == null) // Haven't spellbook
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
}
if (player.getInventory().getAdena() < requireditems)
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
boolean check = true;
if (Config.ES_SP_BOOK_NEEDED)
{
check &= player.destroyItem("Consume", spb.getObjectId(), 1, player, true);
}
check &= player.destroyItemByItemId("Consume", Inventory.ADENA_ID, requireditems, player, true);
if (!check)
{
client.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ALL_OF_THE_ITEMS_NEEDED_TO_ENCHANT_THAT_SKILL);
return;
}
player.getStat().addSp((int) (requiredSp * 0.8));
if (Config.LOG_SKILL_ENCHANTS)
{
if (skill.getLevel() > 100)
{
if (spb != null)
{
_logEnchant.info("Untrain, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "]");
}
else
{
_logEnchant.info("Untrain, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", +" + (skill.getLevel() % 100) + " " + skill.getName() + "(" + skill.getId() + ")");
}
}
else
{
if (spb != null)
{
_logEnchant.info("Untrain, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + "), " + spb.getName() + "(" + spb.getCount() + ") [" + spb.getObjectId() + "]");
}
else
{
_logEnchant.info("Untrain, Character:" + player.getName() + " [" + player.getObjectId() + "] Account:" + player.getAccountName() + " IP:" + player.getIPAddress() + ", " + skill.getName() + "(" + skill.getId() + ")");
}
}
}
player.addSkill(skill, true);
client.sendPacket(ExEnchantSkillResult.valueOf(true));
if (Config.DEBUG)
{
_log.finer("Learned skill ID: " + _skillId + " Level: " + _skillLvl + " for " + requiredSp + " SP, " + requireditems + " Adena.");
}
client.sendPacket(new UserInfo(player));
if (_skillLvl > 100)
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.UNTRAIN_OF_ENCHANT_SKILL_WAS_SUCCESSFUL_CURRENT_LEVEL_OF_ENCHANT_SKILL_S1_HAS_BEEN_DECREASED_BY_1);
sm.addSkillName(_skillId);
client.sendPacket(sm);
}
else
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.UNTRAIN_OF_ENCHANT_SKILL_WAS_SUCCESSFUL_CURRENT_LEVEL_OF_ENCHANT_SKILL_S1_BECAME_0_AND_ENCHANT_SKILL_WILL_BE_INITIALIZED);
sm.addSkillName(_skillId);
client.sendPacket(sm);
}
player.sendSkillList();
final int afterUntrainSkillLevel = player.getSkillLevel(_skillId);
client.sendPacket(new ExEnchantSkillInfo(_skillId, afterUntrainSkillLevel));
client.sendPacket(new ExEnchantSkillInfoDetail(2, _skillId, afterUntrainSkillLevel - 1, player));
player.updateShortCuts(_skillId, afterUntrainSkillLevel);
}
}

View File

@@ -35,6 +35,8 @@ public class RequestPledgeRecruitBoardAccess implements IClientIncomingPacket
private int _karma;
private String _information;
private String _datailedInformation;
private int _applicationType;
private int _recruitingType;
@Override
public boolean read(L2GameClient client, PacketReader packet)
@@ -43,6 +45,8 @@ public class RequestPledgeRecruitBoardAccess implements IClientIncomingPacket
_karma = packet.readD();
_information = packet.readS();
_datailedInformation = packet.readS();
_applicationType = packet.readD(); // 0 - Allow, 1 - Public
_recruitingType = packet.readD(); // 0 - Main clan
return true;
}
@@ -70,7 +74,7 @@ public class RequestPledgeRecruitBoardAccess implements IClientIncomingPacket
return;
}
final PledgeRecruitInfo pledgeRecruitInfo = new PledgeRecruitInfo(clan.getId(), _karma, _information, _datailedInformation);
final PledgeRecruitInfo pledgeRecruitInfo = new PledgeRecruitInfo(clan.getId(), _karma, _information, _datailedInformation, _applicationType, _recruitingType);
switch (_applyType)
{

View File

@@ -29,6 +29,7 @@ public final class RequestShortCutReg implements IClientIncomingPacket
private int _slot;
private int _page;
private int _lvl;
private int _subLvl;
private int _characterType; // 1 - player, 2 - pet
@Override
@@ -41,7 +42,7 @@ public final class RequestShortCutReg implements IClientIncomingPacket
_page = slot / 12;
_id = packet.readD();
_lvl = packet.readH();
packet.readH(); // Sublevel
_subLvl = packet.readH(); // Sublevel
_characterType = packet.readD();
return true;
}
@@ -54,7 +55,7 @@ public final class RequestShortCutReg implements IClientIncomingPacket
return;
}
final Shortcut sc = new Shortcut(_slot, _page, _type, _id, _lvl, _characterType);
final Shortcut sc = new Shortcut(_slot, _page, _type, _id, _lvl, _subLvl, _characterType);
client.getActiveChar().registerShortCut(sc);
client.sendPacket(new ShortCutRegister(sc));
}

View File

@@ -26,21 +26,17 @@ import com.l2jmobius.gameserver.ai.CtrlIntention;
import com.l2jmobius.gameserver.ai.NextAction;
import com.l2jmobius.gameserver.enums.ItemSkillType;
import com.l2jmobius.gameserver.enums.PrivateStoreType;
import com.l2jmobius.gameserver.enums.Race;
import com.l2jmobius.gameserver.handler.IItemHandler;
import com.l2jmobius.gameserver.handler.ItemHandler;
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
import com.l2jmobius.gameserver.model.L2Object;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.PcCondOverride;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.effects.L2EffectType;
import com.l2jmobius.gameserver.model.holders.ItemSkillHolder;
import com.l2jmobius.gameserver.model.items.L2EtcItem;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.L2Weapon;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.items.type.ArmorType;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.client.L2GameClient;
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
@@ -53,32 +49,6 @@ public final class UseItem implements IClientIncomingPacket
private boolean _ctrlPressed;
private int _itemId;
/** Weapon Equip Task */
private static class WeaponEquipTask implements Runnable
{
L2ItemInstance item;
L2PcInstance activeChar;
protected WeaponEquipTask(L2ItemInstance it, L2PcInstance character)
{
item = it;
activeChar = character;
}
@Override
public void run()
{
// If character is still engaged in strike we should not change weapon
if (activeChar.isAttackingNow())
{
return;
}
// Equip or unEquip
activeChar.useEquippableItem(item, false);
}
}
@Override
public boolean read(L2GameClient client, PacketReader packet)
{
@@ -233,12 +203,7 @@ public final class UseItem implements IClientIncomingPacket
return;
}
if (activeChar.isMounted())
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
return;
}
if (activeChar.isDisarmed())
if (activeChar.isMounted() || activeChar.isDisarmed())
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
return;
@@ -249,82 +214,6 @@ public final class UseItem implements IClientIncomingPacket
{
return;
}
// Don't allow other Race to Wear Kamael exclusive Weapons.
if (!item.isEquipped() && item.isWeapon() && !activeChar.canOverrideCond(PcCondOverride.ITEM_CONDITIONS))
{
final L2Weapon wpn = (L2Weapon) item.getItem();
switch (activeChar.getRace())
{
case KAMAEL:
{
switch (wpn.getItemType())
{
case NONE:
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
return;
}
}
break;
}
case HUMAN:
case DWARF:
case ELF:
case DARK_ELF:
case ORC:
{
switch (wpn.getItemType())
{
case RAPIER:
case CROSSBOW:
case ANCIENTSWORD:
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
return;
}
}
break;
}
case ERTHEIA:
{
switch (wpn.getItemType())
{
case SWORD:
case DAGGER:
case BOW:
case POLE:
case NONE:
case DUAL:
case RAPIER:
case ANCIENTSWORD:
case CROSSBOW:
case DUALDAGGER:
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
return;
}
}
break;
}
}
}
break;
}
case L2Item.SLOT_CHEST:
case L2Item.SLOT_FULL_ARMOR:
case L2Item.SLOT_BACK:
case L2Item.SLOT_GLOVES:
case L2Item.SLOT_FEET:
case L2Item.SLOT_HEAD:
case L2Item.SLOT_LEGS:
{
if ((activeChar.getRace() == Race.ERTHEIA) && activeChar.isMageClass() && ((item.getItem().getItemType() == ArmorType.SHIELD) || (item.getItem().getItemType() == ArmorType.SIGIL)))
{
activeChar.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
return;
}
break;
}
case L2Item.SLOT_DECO:
@@ -356,7 +245,17 @@ public final class UseItem implements IClientIncomingPacket
}
else if (activeChar.isAttackingNow())
{
ThreadPoolManager.getInstance().scheduleGeneral(new WeaponEquipTask(item, activeChar), activeChar.getAttackEndTime() - System.currentTimeMillis());
ThreadPoolManager.getInstance().scheduleGeneral(() ->
{
// If character is still engaged in strike we should not change weapon
if (activeChar.isAttackingNow())
{
return;
}
// Equip or unEquip
activeChar.useEquippableItem(item, false);
}, activeChar.getAttackEndTime() - System.currentTimeMillis());
}
else
{

View File

@@ -101,10 +101,10 @@ public class RequestAcquireAbilityList implements IClientIncomingPacket
final List<L2SkillLearn> skillsToLearn = new ArrayList<>(_skills.size());
for (SkillHolder holder : _skills.values())
{
final L2SkillLearn learn = SkillTreesData.getInstance().getAbilitySkill(holder.getSkillId(), holder.getSkillLvl());
final L2SkillLearn learn = SkillTreesData.getInstance().getAbilitySkill(holder.getSkillId(), holder.getSkillLevel());
if (learn == null)
{
_log.warning("SkillLearn " + holder.getSkillId() + " (" + holder.getSkillLvl() + ") not found!");
_log.warning("SkillLearn " + holder.getSkillId() + " (" + holder.getSkillLevel() + ") not found!");
client.sendPacket(ActionFailed.STATIC_PACKET);
break;
}
@@ -112,7 +112,7 @@ public class RequestAcquireAbilityList implements IClientIncomingPacket
final Skill skill = holder.getSkill();
if (skill == null)
{
_log.warning("Skill " + holder.getSkillId() + " (" + holder.getSkillLvl() + ") not found!");
_log.warning("Skill " + holder.getSkillId() + " (" + holder.getSkillLevel() + ") not found!");
client.sendPacket(ActionFailed.STATIC_PACKET);
break;
}
@@ -153,7 +153,7 @@ public class RequestAcquireAbilityList implements IClientIncomingPacket
// Case 2: Learning skill without having its parent
for (SkillHolder required : learn.getPreReqSkills())
{
if (activeChar.getSkillLevel(required.getSkillId()) < required.getSkillLvl())
if (activeChar.getSkillLevel(required.getSkillId()) < required.getSkillLevel())
{
_log.warning("Player " + activeChar + " is trying to learn " + skill + " without having prerequsite skill: " + required.getSkill() + "!");
client.sendPacket(ActionFailed.STATIC_PACKET);

View File

@@ -57,7 +57,7 @@ public class AbnormalStatusUpdate implements IClientOutgoingPacket
{
packet.writeD(info.getSkill().getDisplayId());
packet.writeH(info.getSkill().getDisplayLevel());
packet.writeH(0x00); // Sub level
packet.writeH(info.getSkill().getSubLevel());
packet.writeD(info.getSkill().getAbnormalType().getClientId());
writeOptionalD(packet, info.getSkill().isAura() ? -1 : info.getTime());
}

View File

@@ -51,6 +51,7 @@ public class ExAbnormalStatusUpdateFromTarget implements IClientOutgoingPacket
_skillId = skill.getDisplayId();
_level = skill.getDisplayLevel();
_subLevel = skill.getSubLevel();
_abnormalType = skill.getAbnormalType().getClientId();
_duration = skill.isAura() ? -1 : info.getTime();
_caster = casterId;

View File

@@ -16,95 +16,48 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.network.client.OutgoingPackets;
public final class ExEnchantSkillInfo implements IClientOutgoingPacket
{
private final List<Integer> _routes = new LinkedList<>(); // skill lvls for each route
private final Set<Integer> _routes;
private final int _id;
private final int _lvl;
private final int _maxlvl;
private boolean _maxEnchanted = false;
private final int _skillId;
private final int _skillLevel;
private final int _skillSubLevel;
private final int _currentSubLevel;
public ExEnchantSkillInfo(int id, int lvl)
public ExEnchantSkillInfo(int skillId, int skillLevel, int skillSubLevel, int currentSubLevel)
{
_id = id;
_lvl = lvl;
_maxlvl = SkillData.getInstance().getMaxLevel(_id);
final L2EnchantSkillLearn enchantLearn = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(_id);
// do we have this skill?
if (enchantLearn != null)
{
// skill already enchanted?
if (_lvl > 1000)
{
_maxEnchanted = enchantLearn.isMaxEnchant(_lvl);
// get detail for next level
final EnchantSkillHolder esd = enchantLearn.getEnchantSkillHolder(_lvl);
// if it exists add it
if ((esd != null) && !_maxEnchanted)
{
_routes.add(_lvl + 1); // current enchant add firts
}
for (int route : enchantLearn.getAllRoutes())
{
if (((route * 1000) + (_lvl % 1000)) == _lvl)
{
continue;
}
_routes.add((route * 1000) + (_lvl % 1000));
}
}
else
// not already enchanted
{
for (int route : enchantLearn.getAllRoutes())
{
// add first level (+1) of all routes
_routes.add((route * 1000) + 1);
}
}
}
_skillId = skillId;
_skillLevel = skillLevel;
_skillSubLevel = skillSubLevel;
_currentSubLevel = currentSubLevel;
_routes = EnchantSkillGroupsData.getInstance().getRouteForSkill(_skillId, _skillLevel);
}
@Override
public boolean write(PacketWriter packet)
{
OutgoingPackets.EX_ENCHANT_SKILL_INFO.writeId(packet);
packet.writeD(_id);
if (_lvl < 100)
{
packet.writeD(_lvl);
}
else
{
packet.writeH(_maxlvl);
packet.writeH(_lvl);
}
packet.writeD(_maxEnchanted ? 0 : 1);
packet.writeD(_lvl > 1000 ? 1 : 0); // enchanted?
packet.writeD(_skillId);
packet.writeH(_skillLevel);
packet.writeH(_skillSubLevel);
packet.writeD((_skillSubLevel % 1000) == EnchantSkillGroupsData.MAX_ENCHANT_LEVEL ? 0 : 1);
packet.writeD(_skillSubLevel > 1000 ? 1 : 0);
packet.writeD(_routes.size());
for (int level : _routes)
_routes.forEach(route ->
{
packet.writeH(_maxlvl);
packet.writeH(level);
}
final int routeId = route / 1000;
final int currentRouteId = _skillSubLevel / 1000;
final int subLevel = _currentSubLevel > 0 ? (route + (_currentSubLevel % 1000)) - 1 : route;
packet.writeH(_skillLevel);
packet.writeH(currentRouteId != routeId ? subLevel : subLevel + 1);
});
return true;
}
}

View File

@@ -16,14 +16,14 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import com.l2jmobius.Config;
import java.util.Set;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.data.xml.impl.EnchantSkillGroupsData;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.enums.SkillEnchantType;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
import com.l2jmobius.gameserver.model.holders.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.network.client.OutgoingPackets;
/**
@@ -31,172 +31,20 @@ import com.l2jmobius.gameserver.network.client.OutgoingPackets;
*/
public class ExEnchantSkillInfoDetail implements IClientOutgoingPacket
{
private static final int TYPE_NORMAL_ENCHANT = 0;
private static final int TYPE_SAFE_ENCHANT = 1;
private static final int TYPE_UNTRAIN_ENCHANT = 2;
private static final int TYPE_CHANGE_ENCHANT = 3;
private static final int TYPE_IMMORTAL_ENCHANT = 4;
private final SkillEnchantType _type;
private final int _skillId;
private final int _skillLvl;
private final int _skillSubLvl;
private final EnchantSkillHolder _enchantSkillHolder;
private int bookId = 0;
private int reqCount = 0;
private int multi = 1;
private final int _type;
private final int _skillid;
private final int _skilllvl;
private final int _maxlvl;
private final int _chance;
private int _sp;
private final int _adenacount;
public ExEnchantSkillInfoDetail(int type, int skillid, int skilllvl, L2PcInstance ply)
public ExEnchantSkillInfoDetail(SkillEnchantType type, int skillId, int skillLvl, int skillSubLvl, L2PcInstance player)
{
_type = type;
_skillid = skillid;
_skilllvl = skilllvl;
_maxlvl = SkillData.getInstance().getMaxLevel(_skillid);
_skillId = skillId;
_skillLvl = skillLvl;
_skillSubLvl = skillSubLvl;
final L2EnchantSkillLearn enchantLearn = EnchantSkillGroupsData.getInstance().getSkillEnchantmentBySkillId(skillid);
EnchantSkillHolder esd = null;
// do we have this skill?
if (enchantLearn != null)
{
if (_skilllvl > 1000)
{
esd = enchantLearn.getEnchantSkillHolder(_skilllvl);
}
else
{
esd = enchantLearn.getFirstRouteGroup().getEnchantGroupDetails().get(0);
}
}
if (esd == null)
{
throw new IllegalArgumentException("Skill " + skillid + " dont have enchant data for level " + _skilllvl);
}
if (type == 0)
{
multi = EnchantSkillGroupsData.NORMAL_ENCHANT_COST_MULTIPLIER;
}
else if (type == 1)
{
multi = EnchantSkillGroupsData.SAFE_ENCHANT_COST_MULTIPLIER;
}
if (type != TYPE_IMMORTAL_ENCHANT)
{
_chance = esd.getRate(ply);
_sp = esd.getSpCost();
if (type == TYPE_UNTRAIN_ENCHANT)
{
_sp = (int) (0.8 * _sp);
}
_adenacount = esd.getAdenaCost() * multi;
}
else
{
_chance = 100;
_sp = 0;
_adenacount = 0;
}
final int _elvl = ((_skilllvl % 100) - 1) / 10;
switch (type)
{
case TYPE_NORMAL_ENCHANT:
{
if (ply.getClassId().level() < 4)
{
bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_OLD;
}
else if (_elvl == 0)
{
bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK;
}
else if (_elvl == 1)
{
bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V2;
}
else
{
bookId = EnchantSkillGroupsData.NORMAL_ENCHANT_BOOK_V3;
}
reqCount = 1;
break;
}
case TYPE_SAFE_ENCHANT:
{
if (ply.getClassId().level() < 4)
{
bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_OLD;
}
else if (_elvl == 0)
{
bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK;
}
else if (_elvl == 1)
{
bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V2;
}
else
{
bookId = EnchantSkillGroupsData.SAFE_ENCHANT_BOOK_V3;
}
reqCount = 1;
break;
}
case TYPE_CHANGE_ENCHANT:
{
if (ply.getClassId().level() < 4)
{
bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_OLD;
}
else if (_elvl == 0)
{
bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK;
}
else if (_elvl == 1)
{
bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V2;
}
else
{
bookId = EnchantSkillGroupsData.CHANGE_ENCHANT_BOOK_V3;
}
reqCount = 1;
break;
}
case TYPE_IMMORTAL_ENCHANT:
{
if (ply.getClassId().level() < 4)
{
bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL;
}
else if (_elvl == 0)
{
bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL;
}
else if (_elvl == 1)
{
bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V2;
}
else
{
bookId = EnchantSkillGroupsData.IMMORTAL_SCROLL_V3;
}
reqCount = 1;
break;
}
default:
{
return;
}
}
if ((type != TYPE_SAFE_ENCHANT) && !Config.ES_SP_BOOK_NEEDED)
{
reqCount = 0;
}
_enchantSkillHolder = EnchantSkillGroupsData.getInstance().getEnchantSkillHolder(skillSubLvl % 1000);
}
@Override
@@ -204,17 +52,22 @@ public class ExEnchantSkillInfoDetail implements IClientOutgoingPacket
{
OutgoingPackets.EX_ENCHANT_SKILL_INFO_DETAIL.writeId(packet);
packet.writeD(_type);
packet.writeD(_skillid);
packet.writeH(_maxlvl);
packet.writeH(_skilllvl);
packet.writeQ(_sp * multi); // sp
packet.writeD(_chance); // exp
packet.writeD(0x02); // items count?
packet.writeD(Inventory.ADENA_ID); // Adena
packet.writeD(_adenacount); // Adena count
packet.writeD(bookId); // ItemId Required
packet.writeD(reqCount);
return true;
packet.writeD(_type.ordinal());
packet.writeD(_skillId);
packet.writeH(_skillLvl);
packet.writeH(_skillSubLvl);
if (_enchantSkillHolder != null)
{
packet.writeQ(_enchantSkillHolder.getSp(_type));
packet.writeD(_enchantSkillHolder.getChance(_type));
final Set<ItemHolder> holders = _enchantSkillHolder.getRequiredItems(_type);
packet.writeD(holders.size());
holders.forEach(holder ->
{
packet.writeD(holder.getId());
packet.writeD((int) holder.getCount());
});
}
return _enchantSkillHolder != null;
}
}

View File

@@ -16,46 +16,27 @@
*/
package com.l2jmobius.gameserver.network.serverpackets;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.enums.SkillEnchantType;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.client.OutgoingPackets;
public class ExEnchantSkillList implements IClientOutgoingPacket
{
public enum EnchantSkillType
{
NORMAL,
SAFE,
UNTRAIN,
CHANGE_ROUTE,
}
private final SkillEnchantType _type;
private final List<Skill> _skills = new LinkedList<>();
private final EnchantSkillType _type;
private final List<Skill> _skills;
static class Skill
{
public int id;
public int nextLevel;
Skill(int pId, int pNextLevel)
{
id = pId;
nextLevel = pNextLevel;
}
}
public void addSkill(int id, int level)
{
_skills.add(new Skill(id, level));
}
public ExEnchantSkillList(EnchantSkillType type)
public ExEnchantSkillList(SkillEnchantType type)
{
_type = type;
_skills = new ArrayList<>();
}
public void addSkill(Skill skill)
{
_skills.add(skill);
}
@Override
@@ -65,10 +46,11 @@ public class ExEnchantSkillList implements IClientOutgoingPacket
packet.writeD(_type.ordinal());
packet.writeD(_skills.size());
for (Skill sk : _skills)
for (Skill skill : _skills)
{
packet.writeD(sk.id);
packet.writeD(sk.nextLevel);
packet.writeD(skill.getId());
packet.writeH(skill.getLevel());
packet.writeH(skill.getSubLevel());
}
return true;
}

View File

@@ -24,13 +24,8 @@ import com.l2jmobius.gameserver.network.client.OutgoingPackets;
*/
public class ExEnchantSkillResult implements IClientOutgoingPacket
{
private static final ExEnchantSkillResult STATIC_PACKET_TRUE = new ExEnchantSkillResult(true);
private static final ExEnchantSkillResult STATIC_PACKET_FALSE = new ExEnchantSkillResult(false);
public static ExEnchantSkillResult valueOf(boolean result)
{
return result ? STATIC_PACKET_TRUE : STATIC_PACKET_FALSE;
}
public static final ExEnchantSkillResult STATIC_PACKET_TRUE = new ExEnchantSkillResult(true);
public static final ExEnchantSkillResult STATIC_PACKET_FALSE = new ExEnchantSkillResult(false);
private final boolean _enchanted;

View File

@@ -41,6 +41,8 @@ public class ExPledgeRecruitBoardDetail implements IClientOutgoingPacket
packet.writeD(_pledgeRecruitInfo.getKarma());
packet.writeS(_pledgeRecruitInfo.getInformation());
packet.writeS(_pledgeRecruitInfo.getDetailedInformation());
packet.writeD(_pledgeRecruitInfo.getApplicationType());
packet.writeD(_pledgeRecruitInfo.getRecruitType());
return true;
}
}

View File

@@ -72,6 +72,8 @@ public class ExPledgeRecruitBoardSearch implements IClientOutgoingPacket
packet.writeD(clan.getMembersCount());
packet.writeD(_clanList.get(i).getKarma());
packet.writeS(_clanList.get(i).getInformation());
packet.writeD(_clanList.get(i).getApplicationType());
packet.writeD(_clanList.get(i).getRecruitType());
}
return true;
}

View File

@@ -19,7 +19,6 @@ package com.l2jmobius.gameserver.network.serverpackets;
import java.util.Collection;
import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.data.xml.impl.SkillData;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.client.OutgoingPackets;
@@ -53,7 +52,7 @@ public class GMViewSkillInfo implements IClientOutgoingPacket
packet.writeD(skill.getDisplayId());
packet.writeD(0x00);
packet.writeC(isDisabled && skill.isClanSkill() ? 1 : 0);
packet.writeC(SkillData.getInstance().isEnchantable(skill.getDisplayId()) ? 1 : 0);
packet.writeC(skill.isEnchantable() ? 1 : 0);
}
return true;
}

View File

@@ -21,16 +21,18 @@ import com.l2jmobius.gameserver.network.client.OutgoingPackets;
public class ShortBuffStatusUpdate implements IClientOutgoingPacket
{
public static final ShortBuffStatusUpdate RESET_SHORT_BUFF = new ShortBuffStatusUpdate(0, 0, 0);
public static final ShortBuffStatusUpdate RESET_SHORT_BUFF = new ShortBuffStatusUpdate(0, 0, 0, 0);
private final int _skillId;
private final int _skillLvl;
private final int _skillSubLvl;
private final int _duration;
public ShortBuffStatusUpdate(int skillId, int skillLvl, int duration)
public ShortBuffStatusUpdate(int skillId, int skillLvl, int skillSubLvl, int duration)
{
_skillId = skillId;
_skillLvl = skillLvl;
_skillSubLvl = skillSubLvl;
_duration = duration;
}
@@ -40,7 +42,8 @@ public class ShortBuffStatusUpdate implements IClientOutgoingPacket
OutgoingPackets.SHORT_BUFF_STATUS_UPDATE.writeId(packet);
packet.writeD(_skillId);
packet.writeD(_skillLvl);
packet.writeH(_skillLvl);
packet.writeH(_skillSubLvl);
packet.writeD(_duration);
return true;
}

View File

@@ -62,7 +62,8 @@ public final class ShortCutInit implements IClientOutgoingPacket
case SKILL:
{
packet.writeD(sc.getId());
packet.writeD(sc.getLevel());
packet.writeH(sc.getLevel());
packet.writeH(sc.getSubLevel());
packet.writeD(sc.getSharedReuseGroup());
packet.writeC(0x00); // C5
packet.writeD(0x01); // C6

View File

@@ -57,7 +57,7 @@ public final class ShortCutRegister implements IClientOutgoingPacket
{
packet.writeD(_shortcut.getId());
packet.writeH(_shortcut.getLevel());
packet.writeH(0x00); // Sub level
packet.writeH(_shortcut.getSubLevel());
packet.writeD(_shortcut.getSharedReuseGroup());
packet.writeC(0x00); // C5
packet.writeD(_shortcut.getCharacterType());

View File

@@ -37,12 +37,12 @@ public class SkillCoolTime implements IClientOutgoingPacket
public SkillCoolTime(L2PcInstance player)
{
final Map<Integer, TimeStamp> skillReuseTimeStamps = player.getSkillReuseTimeStamps();
final Map<Long, TimeStamp> skillReuseTimeStamps = player.getSkillReuseTimeStamps();
if (skillReuseTimeStamps != null)
{
for (TimeStamp ts : skillReuseTimeStamps.values())
{
final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl());
final Skill skill = SkillData.getInstance().getSkill(ts.getSkillId(), ts.getSkillLvl(), ts.getSkillSubLvl());
if (ts.hasNotPassed() && !skill.isNotBroadcastable())
{
_skillReuseTimeStamps.add(ts);

View File

@@ -34,24 +34,26 @@ public final class SkillList implements IClientOutgoingPacket
public int id;
public int reuseDelayGroup;
public int level;
public int subLevel;
public boolean passive;
public boolean disabled;
public boolean enchanted;
Skill(int pId, int pReuseDelayGroup, int pLevel, boolean pPassive, boolean pDisabled, boolean pEnchanted)
Skill(int pId, int pReuseDelayGroup, int pLevel, int pSubLevel, boolean pPassive, boolean pDisabled, boolean pEnchanted)
{
id = pId;
reuseDelayGroup = pReuseDelayGroup;
level = pLevel;
subLevel = pSubLevel;
passive = pPassive;
disabled = pDisabled;
enchanted = pEnchanted;
}
}
public void addSkill(int id, int reuseDelayGroup, int level, boolean passive, boolean disabled, boolean enchanted)
public void addSkill(int id, int reuseDelayGroup, int level, int subLevel, boolean passive, boolean disabled, boolean enchanted)
{
_skills.add(new Skill(id, reuseDelayGroup, level, passive, disabled, enchanted));
_skills.add(new Skill(id, reuseDelayGroup, level, subLevel, passive, disabled, enchanted));
}
public void setLastLearnedSkillId(int lastLearnedSkillId)
@@ -63,12 +65,13 @@ public final class SkillList implements IClientOutgoingPacket
public boolean write(PacketWriter packet)
{
OutgoingPackets.SKILL_LIST.writeId(packet);
_skills.sort(Comparator.comparing(s -> SkillData.getInstance().getSkill(s.id, s.level).isToggle() ? 1 : 0));
_skills.sort(Comparator.comparing(s -> SkillData.getInstance().getSkill(s.id, s.level, s.subLevel).isToggle() ? 1 : 0));
packet.writeD(_skills.size());
for (Skill temp : _skills)
{
packet.writeD(temp.passive ? 1 : 0);
packet.writeD(temp.level);
packet.writeH(temp.level);
packet.writeH(temp.subLevel);
packet.writeD(temp.id);
packet.writeD(temp.reuseDelayGroup); // GOD ReuseDelayShareGroupID
packet.writeC(temp.disabled ? 1 : 0); // iSkillDisabled

View File

@@ -46,7 +46,7 @@ public class ExResponseCommissionBuyInfo extends AbstractItemPacket
packet.writeQ(_commissionItem.getPricePerUnit());
packet.writeQ(_commissionItem.getCommissionId());
packet.writeD(0); // CommissionItemType seems client does not really need it.
writeCommissionItem(packet, _commissionItem.getItemInfo());
writeItem(packet, _commissionItem.getItemInfo());
}
return true;
}

View File

@@ -90,7 +90,7 @@ public class ExResponseCommissionList extends AbstractItemPacket
packet.writeD((commissionItem.getDurationInDays() - 1) / 2);
packet.writeD((int) commissionItem.getEndTime().getEpochSecond());
packet.writeS(null); // Seller Name its not displayed somewhere so i am not sending it to decrease traffic.
writeCommissionItem(packet, commissionItem.getItemInfo());
writeItem(packet, commissionItem.getItemInfo());
}
break;
}

View File

@@ -54,17 +54,6 @@ public class AttackStanceTaskManager
{
if (actor != null)
{
// if (actor.isPlayable())
// {
// final PlayerInstance player = actor.getActingPlayer();
// for (L2CubicInstance cubic : player.getCubics().values())
// {
// if (cubic.getId() != L2CubicInstance.LIFE_CUBIC)
// {
// cubic.doAction();
// }
// }
// }
_attackStanceTasks.put(actor, System.currentTimeMillis());
}
}