Sync with L2jUnity (7db5b4f).

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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