Sync with L2jUnity (7db5b4f).
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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":
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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());
|
||||
}
|
||||
|
@@ -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}
|
||||
|
@@ -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
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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)
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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)))
|
||||
|
@@ -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()));
|
||||
|
@@ -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)
|
||||
|
@@ -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()
|
||||
|
@@ -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);
|
||||
|
@@ -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());
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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),
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
@@ -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 + "]";
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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),
|
||||
|
@@ -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()
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -274,6 +274,11 @@ public class NpcSpawnTemplate implements Cloneable, IParameterized<StatsSet>
|
||||
return null;
|
||||
}
|
||||
|
||||
public void spawn()
|
||||
{
|
||||
spawn(null);
|
||||
}
|
||||
|
||||
public void spawn(Instance instance)
|
||||
{
|
||||
try
|
||||
|
@@ -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));
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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()),
|
||||
|
@@ -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())
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
@@ -46,7 +46,8 @@ public enum ZoneId
|
||||
NO_ITEM_DROP,
|
||||
NO_RESTART,
|
||||
SAYUNE,
|
||||
FISHING;
|
||||
FISHING,
|
||||
UNDYING;
|
||||
|
||||
public static int getZoneCount()
|
||||
{
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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),
|
||||
|
@@ -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)
|
||||
|
@@ -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));
|
||||
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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)
|
||||
{
|
||||
|
@@ -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));
|
||||
}
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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());
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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());
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user