Free version update 14-12-2023.
This commit is contained in:
@@ -611,6 +611,7 @@ public class Config
|
||||
public static boolean ENABLE_AUTO_SKILL;
|
||||
public static boolean ENABLE_AUTO_ITEM;
|
||||
public static boolean RESUME_AUTO_PLAY;
|
||||
public static boolean ENABLE_AUTO_ASSIST;
|
||||
public static AbnormalVisualEffect BLUE_TEAM_ABNORMAL_EFFECT;
|
||||
public static AbnormalVisualEffect RED_TEAM_ABNORMAL_EFFECT;
|
||||
|
||||
@@ -841,6 +842,9 @@ public class Config
|
||||
public static boolean HARDIN_ENABLE_ERTHEIAS;
|
||||
public static Map<Integer, List<Integer>> HARDIN_REMOVED_SKILLS;
|
||||
|
||||
// Eraton
|
||||
public static Set<Integer> ERATON_RETAINED_SKILLS = new HashSet<>();
|
||||
|
||||
// --------------------------------------------------
|
||||
// Vitality Settings
|
||||
// --------------------------------------------------
|
||||
@@ -848,6 +852,7 @@ public class Config
|
||||
public static int STARTING_VITALITY_POINTS;
|
||||
public static boolean RAIDBOSS_USE_VITALITY;
|
||||
public static float RATE_VITALITY_EXP_MULTIPLIER;
|
||||
public static float RATE_VITALITY_EXP_PREMIUM_MULTIPLIER;
|
||||
public static int VITALITY_MAX_ITEMS_ALLOWED;
|
||||
public static float RATE_VITALITY_LOST;
|
||||
public static float RATE_VITALITY_GAIN;
|
||||
@@ -1153,6 +1158,7 @@ public class Config
|
||||
public static int CONQUEST_RATE_SERVER_POINTS;
|
||||
public static int CONQUEST_RATE_SERVER_SOUL_ORBS;
|
||||
public static int CONQUEST_RATE_ZONE_POINTS;
|
||||
public static int CONQUEST_RATE_BLOODY_COINS;
|
||||
public static int CONQUEST_ATTACK_POINTS;
|
||||
public static int CONQUEST_LIFE_POINTS;
|
||||
public static boolean CONQUEST_PVP_ZONE;
|
||||
@@ -1425,6 +1431,7 @@ public class Config
|
||||
public static boolean FAKE_PLAYER_USE_SHOTS;
|
||||
public static boolean FAKE_PLAYER_KILL_PVP;
|
||||
public static boolean FAKE_PLAYER_KILL_KARMA;
|
||||
public static boolean FAKE_PLAYER_AUTO_ATTACKABLE;
|
||||
public static boolean FAKE_PLAYER_AGGRO_MONSTERS;
|
||||
public static boolean FAKE_PLAYER_AGGRO_PLAYERS;
|
||||
public static boolean FAKE_PLAYER_AGGRO_FPC;
|
||||
@@ -1912,6 +1919,15 @@ public class Config
|
||||
HARDIN_REMOVED_SKILLS.get(classId).add(Integer.parseInt(classInfo[i]));
|
||||
}
|
||||
}
|
||||
ERATON_RETAINED_SKILLS.clear();
|
||||
final String eratonRetainedSkills = characterConfig.getString("EratonRetainedSkills", "").trim();
|
||||
if (!eratonRetainedSkills.isEmpty())
|
||||
{
|
||||
for (String id : eratonRetainedSkills.split(","))
|
||||
{
|
||||
ERATON_RETAINED_SKILLS.add(Integer.parseInt(id));
|
||||
}
|
||||
}
|
||||
ENABLE_VITALITY = characterConfig.getBoolean("EnableVitality", true);
|
||||
STARTING_VITALITY_POINTS = characterConfig.getInt("StartingVitalityPoints", 140000);
|
||||
RAIDBOSS_USE_VITALITY = characterConfig.getBoolean("RaidbossUseVitality", true);
|
||||
@@ -2134,6 +2150,7 @@ public class Config
|
||||
CONQUEST_RATE_SERVER_POINTS = conquestConfig.getInt("ConquestRateServerPoints", 1);
|
||||
CONQUEST_RATE_SERVER_SOUL_ORBS = conquestConfig.getInt("ConquestRateServerSoulOrbs", 100);
|
||||
CONQUEST_RATE_ZONE_POINTS = conquestConfig.getInt("ConquestRateZonePoints", 1);
|
||||
CONQUEST_RATE_BLOODY_COINS = conquestConfig.getInt("ConquestRateBloodyCoins", 1);
|
||||
CONQUEST_ATTACK_POINTS = conquestConfig.getInt("ConquestCharacterAttackPoints", 100);
|
||||
CONQUEST_LIFE_POINTS = conquestConfig.getInt("ConquestCharacterLifePoints", 20);
|
||||
CONQUEST_PVP_ZONE = conquestConfig.getBoolean("ConquestIsPvpZone", false);
|
||||
@@ -2452,6 +2469,7 @@ public class Config
|
||||
ENABLE_AUTO_SKILL = generalConfig.getBoolean("EnableAutoSkill", true);
|
||||
ENABLE_AUTO_ITEM = generalConfig.getBoolean("EnableAutoItem", true);
|
||||
RESUME_AUTO_PLAY = generalConfig.getBoolean("ResumeAutoPlay", false);
|
||||
ENABLE_AUTO_ASSIST = generalConfig.getBoolean("AssistLeader", false);
|
||||
BLUE_TEAM_ABNORMAL_EFFECT = null;
|
||||
final String blueTeamAve = generalConfig.getString("BlueTeamAbnormalEffect", "").trim();
|
||||
if (!blueTeamAve.isEmpty())
|
||||
@@ -2580,6 +2598,7 @@ public class Config
|
||||
MONSTER_EXP_MAX_LEVEL_DIFFERENCE = ratesConfig.getInt("MonsterExpMaxLevelDifference", 11);
|
||||
RATE_RAIDBOSS_POINTS = ratesConfig.getFloat("RateRaidbossPointsReward", 1);
|
||||
RATE_VITALITY_EXP_MULTIPLIER = ratesConfig.getFloat("RateVitalityExpMultiplier", 2);
|
||||
RATE_VITALITY_EXP_PREMIUM_MULTIPLIER = ratesConfig.getFloat("RateVitalityExpPremiumMultiplier", 3);
|
||||
VITALITY_MAX_ITEMS_ALLOWED = ratesConfig.getInt("VitalityMaxItemsAllowed", 999);
|
||||
RATE_VITALITY_LOST = ratesConfig.getFloat("RateVitalityLost", 1);
|
||||
RATE_VITALITY_GAIN = ratesConfig.getFloat("RateVitalityGain", 1);
|
||||
@@ -3647,6 +3666,7 @@ public class Config
|
||||
FAKE_PLAYER_USE_SHOTS = fakePlayerConfig.getBoolean("FakePlayerUseShots", false);
|
||||
FAKE_PLAYER_KILL_PVP = fakePlayerConfig.getBoolean("FakePlayerKillsRewardPvP", false);
|
||||
FAKE_PLAYER_KILL_KARMA = fakePlayerConfig.getBoolean("FakePlayerUnflaggedKillsKarma", false);
|
||||
FAKE_PLAYER_AUTO_ATTACKABLE = fakePlayerConfig.getBoolean("FakePlayerAutoAttackable", false);
|
||||
FAKE_PLAYER_AGGRO_MONSTERS = fakePlayerConfig.getBoolean("FakePlayerAggroMonsters", false);
|
||||
FAKE_PLAYER_AGGRO_PLAYERS = fakePlayerConfig.getBoolean("FakePlayerAggroPlayers", false);
|
||||
FAKE_PLAYER_AGGRO_FPC = fakePlayerConfig.getBoolean("FakePlayerAggroFPC", false);
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.l2jmobius.commons.util.Rnd;
|
||||
import org.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import org.l2jmobius.gameserver.model.WorldObject;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.actor.Summon;
|
||||
import org.l2jmobius.gameserver.model.item.instance.Item;
|
||||
import org.l2jmobius.gameserver.model.skill.Skill;
|
||||
@@ -327,9 +328,17 @@ public class SummonAI extends PlayableAI implements Runnable
|
||||
}
|
||||
|
||||
final Summon summon = getActor();
|
||||
if ((summon.getOwner() != null) && (summon.getOwner() != attacker) && !summon.isMoving() && summon.canAttack(attacker, false))
|
||||
final Player owner = summon.getOwner();
|
||||
if (owner != null)
|
||||
{
|
||||
summon.doAttack(attacker);
|
||||
if (summon.calculateDistance3D(owner) > 3000)
|
||||
{
|
||||
summon.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, owner);
|
||||
}
|
||||
else if ((owner != attacker) && !summon.isMoving() && summon.canAttack(attacker, false))
|
||||
{
|
||||
summon.doAttack(attacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -420,7 +420,6 @@ public class ClanTable
|
||||
|
||||
private void restoreClanWars()
|
||||
{
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
try (Connection con = DatabaseFactory.getConnection();
|
||||
Statement statement = con.createStatement();
|
||||
ResultSet rset = statement.executeQuery("SELECT clan1, clan2, clan1Kill, clan2Kill, winnerClan, startTime, endTime, state FROM clan_wars"))
|
||||
@@ -431,14 +430,8 @@ public class ClanTable
|
||||
final Clan attacked = getClan(rset.getInt("clan2"));
|
||||
if ((attacker != null) && (attacked != null))
|
||||
{
|
||||
final long endTime = rset.getLong("endTime");
|
||||
if (endTime < currentTime)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final ClanWarState state = ClanWarState.values()[rset.getInt("state")];
|
||||
final ClanWar clanWar = new ClanWar(attacker, attacked, rset.getInt("clan1Kill"), rset.getInt("clan2Kill"), rset.getInt("winnerClan"), rset.getLong("startTime"), endTime, state);
|
||||
final ClanWar clanWar = new ClanWar(attacker, attacked, rset.getInt("clan1Kill"), rset.getInt("clan2Kill"), rset.getInt("winnerClan"), rset.getLong("startTime"), rset.getLong("endTime"), state);
|
||||
attacker.addWar(attacked.getId(), clanWar);
|
||||
attacked.addWar(attacker.getId(), clanWar);
|
||||
}
|
||||
|
||||
@@ -88,6 +88,11 @@ public class ActionData implements IXmlReader
|
||||
return _actionSkillsData.getOrDefault(skillId, -1);
|
||||
}
|
||||
|
||||
public int[] getActionIdList()
|
||||
{
|
||||
return _actionData.keySet().stream().mapToInt(Number::intValue).toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of ActionData.
|
||||
* @return single instance of ActionData
|
||||
|
||||
+2
-2
@@ -307,7 +307,7 @@ public class InitialShortcutData implements IXmlReader
|
||||
|
||||
// Register shortcut
|
||||
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getSubLevel(), shortcut.getCharacterType());
|
||||
player.sendPacket(new ShortCutRegister(newShortcut));
|
||||
player.sendPacket(new ShortCutRegister(newShortcut, player));
|
||||
player.registerShortCut(newShortcut);
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ public class InitialShortcutData implements IXmlReader
|
||||
}
|
||||
// Register shortcut
|
||||
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getSubLevel(), shortcut.getCharacterType());
|
||||
player.sendPacket(new ShortCutRegister(newShortcut));
|
||||
player.sendPacket(new ShortCutRegister(newShortcut, player));
|
||||
player.registerShortCut(newShortcut);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -126,7 +126,9 @@ public class LimitShopCraftData implements IXmlReader
|
||||
boolean announce3 = false;
|
||||
boolean announce4 = false;
|
||||
boolean announce5 = false;
|
||||
int enchant = 0;
|
||||
int accountDailyLimit = 0;
|
||||
int accountMontlyLimit = 0;
|
||||
int accountBuyLimit = 0;
|
||||
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
@@ -217,6 +219,7 @@ public class LimitShopCraftData implements IXmlReader
|
||||
count = parseLong(attrs, "count", 1L);
|
||||
chance = parseFloat(attrs, "chance", 100f);
|
||||
announce = parseBoolean(attrs, "announce", false);
|
||||
enchant = parseInteger(attrs, "enchant", 0);
|
||||
productionId2 = parseInteger(attrs, "id2", 0);
|
||||
count2 = parseLong(attrs, "count2", 1L);
|
||||
chance2 = parseFloat(attrs, "chance2", 100f);
|
||||
@@ -233,6 +236,7 @@ public class LimitShopCraftData implements IXmlReader
|
||||
count5 = parseLong(attrs, "count5", 1L);
|
||||
announce5 = parseBoolean(attrs, "announce5", false);
|
||||
accountDailyLimit = parseInteger(attrs, "accountDailyLimit", 0);
|
||||
accountMontlyLimit = parseInteger(attrs, "accountMontlyLimit", 0);
|
||||
accountBuyLimit = parseInteger(attrs, "accountBuyLimit", 0);
|
||||
|
||||
final ItemTemplate item = ItemTable.getInstance().getTemplate(productionId);
|
||||
@@ -244,7 +248,7 @@ public class LimitShopCraftData implements IXmlReader
|
||||
}
|
||||
}
|
||||
|
||||
_products.add(new LimitShopProductHolder(id, category, minLevel, maxLevel, ingredientIds, ingredientQuantities, ingredientEnchants, productionId, count, chance, announce, productionId2, count2, chance2, announce2, productionId3, count3, chance3, announce3, productionId4, count4, chance4, announce4, productionId5, count5, announce5, accountDailyLimit, accountBuyLimit));
|
||||
_products.add(new LimitShopProductHolder(id, category, minLevel, maxLevel, ingredientIds, ingredientQuantities, ingredientEnchants, productionId, count, chance, announce, enchant, productionId2, count2, chance2, announce2, productionId3, count3, chance3, announce3, productionId4, count4, chance4, announce4, productionId5, count5, announce5, accountDailyLimit, accountMontlyLimit, accountBuyLimit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -109,6 +109,7 @@ public class LimitShopData implements IXmlReader
|
||||
ingredientEnchants[4] = 0;
|
||||
int productionId = 0;
|
||||
int accountDailyLimit = 0;
|
||||
int accountMontlyLimit = 0;
|
||||
int accountBuyLimit = 0;
|
||||
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
@@ -197,6 +198,7 @@ public class LimitShopData implements IXmlReader
|
||||
{
|
||||
productionId = parseInteger(attrs, "id");
|
||||
accountDailyLimit = parseInteger(attrs, "accountDailyLimit", 0);
|
||||
accountMontlyLimit = parseInteger(attrs, "accountMontlyLimit", 0);
|
||||
accountBuyLimit = parseInteger(attrs, "accountBuyLimit", 0);
|
||||
|
||||
final ItemTemplate item = ItemTable.getInstance().getTemplate(productionId);
|
||||
@@ -208,7 +210,7 @@ public class LimitShopData implements IXmlReader
|
||||
}
|
||||
}
|
||||
|
||||
_products.add(new LimitShopProductHolder(id, category, minLevel, maxLevel, ingredientIds, ingredientQuantities, ingredientEnchants, productionId, 1, 100, false, 0, 0, 0, false, 0, 0, 0, false, 0, 0, 0, false, 0, 0, false, accountDailyLimit, accountBuyLimit));
|
||||
_products.add(new LimitShopProductHolder(id, category, minLevel, maxLevel, ingredientIds, ingredientQuantities, ingredientEnchants, productionId, 1, 100, false, 0, 0, 0, 0, false, 0, 0, 0, false, 0, 0, 0, false, 0, 0, false, accountDailyLimit, accountMontlyLimit, accountBuyLimit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,9 +546,10 @@ public class SkillData implements IXmlReader
|
||||
variables.put("index", (i - fromLevel) + 1d);
|
||||
variables.put("subIndex", (j - fromSubLevel) + 1d);
|
||||
final Object base = values.getOrDefault(i, Collections.emptyMap()).get(-1);
|
||||
if ((base != null) && !(base instanceof StatSet))
|
||||
final String baseText = String.valueOf(base);
|
||||
if ((base != null) && !(base instanceof StatSet) && (!baseText.equalsIgnoreCase("true") && !baseText.equalsIgnoreCase("false")))
|
||||
{
|
||||
variables.put("base", Double.parseDouble(String.valueOf(base)));
|
||||
variables.put("base", Double.parseDouble(baseText));
|
||||
}
|
||||
parsedValue = parseValue(n, false, false, variables);
|
||||
if (parsedValue != null)
|
||||
|
||||
+1
-2
@@ -33,7 +33,6 @@ import org.l2jmobius.gameserver.model.actor.transform.TransformTemplate;
|
||||
import org.l2jmobius.gameserver.model.holders.AdditionalItemHolder;
|
||||
import org.l2jmobius.gameserver.model.holders.AdditionalSkillHolder;
|
||||
import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
|
||||
|
||||
/**
|
||||
* Transformation data.
|
||||
@@ -142,7 +141,7 @@ public class TransformData implements IXmlReader
|
||||
}
|
||||
set.set("actions", z.getTextContent());
|
||||
final int[] actions = set.getIntArray("actions", " ");
|
||||
templateData.setBasicActionList(new ExBasicActionList(actions));
|
||||
templateData.setBasicActionList(actions);
|
||||
break;
|
||||
}
|
||||
case "additionalSkills":
|
||||
|
||||
@@ -30,14 +30,14 @@ public enum NpcInfoType implements IUpdateTypeComponent
|
||||
NAME(0x03, 2),
|
||||
POSITION(0x04, (3 * 4)),
|
||||
HEADING(0x05, 4),
|
||||
UNKNOWN2(0x06, 4),
|
||||
VEHICLE_ID(0x06, 4),
|
||||
ATK_CAST_SPEED(0x07, (2 * 4)),
|
||||
|
||||
// 1
|
||||
SPEED_MULTIPLIER(0x08, (2 * 4)),
|
||||
EQUIPPED(0x09, (3 * 4)),
|
||||
ALIVE(0x0A, 1),
|
||||
RUNNING(0x0B, 1),
|
||||
STOP_MODE(0x0A, 1),
|
||||
MOVE_MODE(0x0B, 1),
|
||||
SWIM_OR_FLY(0x0E, 1),
|
||||
TEAM(0x0F, 1),
|
||||
|
||||
@@ -45,7 +45,7 @@ public enum NpcInfoType implements IUpdateTypeComponent
|
||||
ENCHANT(0x10, 4),
|
||||
FLYING(0x11, 4),
|
||||
CLONE(0x12, 4),
|
||||
COLOR_EFFECT(0x13, 4),
|
||||
PET_EVOLUTION_ID(0x13, 4),
|
||||
DISPLAY_EFFECT(0x16, 4),
|
||||
TRANSFORMATION(0x17, 4),
|
||||
|
||||
@@ -55,7 +55,7 @@ public enum NpcInfoType implements IUpdateTypeComponent
|
||||
MAX_HP(0x1A, 4),
|
||||
MAX_MP(0x1B, 4),
|
||||
SUMMONED(0x1C, 1),
|
||||
UNKNOWN12(0x1D, (2 * 4)),
|
||||
FOLLOW_INFO(0x1D, (2 * 4)),
|
||||
TITLE(0x1E, 2),
|
||||
NAME_NPCSTRINGID(0x1F, 4),
|
||||
|
||||
|
||||
+5
@@ -25,4 +25,9 @@ import org.l2jmobius.gameserver.model.actor.Player;
|
||||
public interface IPlayerActionHandler
|
||||
{
|
||||
void useAction(Player player, ActionDataHolder data, boolean ctrlPressed, boolean shiftPressed);
|
||||
|
||||
default boolean isPetAction()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+30
@@ -139,6 +139,11 @@ public class DailyTaskManager
|
||||
resetHuntPass();
|
||||
}
|
||||
|
||||
if (calendar.get(Calendar.DAY_OF_MONTH) == 1)
|
||||
{
|
||||
resetMontlyLimitShopData();
|
||||
}
|
||||
|
||||
// Daily tasks.
|
||||
resetAttendanceRewards();
|
||||
resetDailySkills();
|
||||
@@ -779,6 +784,31 @@ public class DailyTaskManager
|
||||
LOGGER.info("LimitShopData has been reset.");
|
||||
}
|
||||
|
||||
private void resetMontlyLimitShopData()
|
||||
{
|
||||
for (LimitShopProductHolder holder : LimitShopData.getInstance().getProducts())
|
||||
{
|
||||
// Update data for offline players.
|
||||
try (Connection con = DatabaseFactory.getConnection();
|
||||
PreparedStatement ps = con.prepareStatement("DELETE FROM account_gsdata WHERE var=?"))
|
||||
{
|
||||
ps.setString(1, AccountVariables.LCOIN_SHOP_PRODUCT_MONTLY_COUNT + holder.getProductionId());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Could not reset LimitShopData: " + e);
|
||||
}
|
||||
// Update data for online players.
|
||||
for (Player player : World.getInstance().getPlayers())
|
||||
{
|
||||
player.getAccountVariables().remove(AccountVariables.LCOIN_SHOP_PRODUCT_MONTLY_COUNT + holder.getProductionId());
|
||||
player.getAccountVariables().storeMe();
|
||||
}
|
||||
}
|
||||
LOGGER.info("LimitShopData has been resetted.");
|
||||
}
|
||||
|
||||
private void resetHuntPass()
|
||||
{
|
||||
// Update data for offline players.
|
||||
|
||||
+5
-1
@@ -364,7 +364,11 @@ public class WalkingManager implements IXmlReader
|
||||
final WalkInfo walk = _activeRoutes.remove(npc.getObjectId());
|
||||
if (walk != null)
|
||||
{
|
||||
walk.getWalkCheckTask().cancel(true);
|
||||
final ScheduledFuture<?> task = walk.getWalkCheckTask();
|
||||
if (task != null)
|
||||
{
|
||||
task.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ public class ShortCuts implements IRestorable
|
||||
{
|
||||
final Shortcut newsc = new Shortcut(sc.getSlot(), sc.getPage(), sc.getType(), sc.getId(), skillLevel, skillSubLevel, 1);
|
||||
newsc.setAutoUse(sc.isAutoUse());
|
||||
_owner.sendPacket(new ShortCutRegister(newsc));
|
||||
_owner.sendPacket(new ShortCutRegister(newsc, _owner));
|
||||
_owner.registerShortCut(newsc);
|
||||
}
|
||||
}
|
||||
|
||||
+118
-156
@@ -1298,7 +1298,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
player.updatePvPStatus(target);
|
||||
}
|
||||
|
||||
if (isFakePlayer() && (target.isPlayable() || target.isFakePlayer()))
|
||||
if (isFakePlayer() && !Config.FAKE_PLAYER_AUTO_ATTACKABLE && (target.isPlayable() || target.isFakePlayer()))
|
||||
{
|
||||
final Npc npc = ((Npc) this);
|
||||
if (!npc.isScriptValue(1))
|
||||
@@ -2826,7 +2826,7 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
}
|
||||
|
||||
// If this creature was previously moving, but now due to stat change can no longer move, broadcast StopMove packet.
|
||||
if (isMoving() && (_stat.getMoveSpeed() <= 0))
|
||||
if (isMoving() && (getMoveSpeed() <= 0))
|
||||
{
|
||||
stopMove(null);
|
||||
}
|
||||
@@ -2839,177 +2839,139 @@ public abstract class Creature extends WorldObject implements ISkillsHolder, IDe
|
||||
summon.updateAndBroadcastStatus(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (isPlayer())
|
||||
{
|
||||
final boolean broadcastFull = true;
|
||||
final StatusUpdate su = new StatusUpdate(this);
|
||||
UserInfo info = null;
|
||||
if (isPlayer())
|
||||
final UserInfo info = new UserInfo(getActingPlayer(), false);
|
||||
info.addComponentType(UserInfoType.SLOTS, UserInfoType.ENCHANTLEVEL);
|
||||
|
||||
boolean updateWeight = false;
|
||||
for (Stat stat : currentChanges)
|
||||
{
|
||||
info = new UserInfo(getActingPlayer(), false);
|
||||
info.addComponentType(UserInfoType.SLOTS, UserInfoType.ENCHANTLEVEL);
|
||||
}
|
||||
if (info != null)
|
||||
{
|
||||
for (Stat stat : currentChanges)
|
||||
switch (stat)
|
||||
{
|
||||
switch (stat)
|
||||
case MOVE_SPEED:
|
||||
case RUN_SPEED:
|
||||
case WALK_SPEED:
|
||||
case SWIM_RUN_SPEED:
|
||||
case SWIM_WALK_SPEED:
|
||||
case FLY_RUN_SPEED:
|
||||
case FLY_WALK_SPEED:
|
||||
{
|
||||
case MOVE_SPEED:
|
||||
case RUN_SPEED:
|
||||
case WALK_SPEED:
|
||||
case SWIM_RUN_SPEED:
|
||||
case SWIM_WALK_SPEED:
|
||||
case FLY_RUN_SPEED:
|
||||
case FLY_WALK_SPEED:
|
||||
{
|
||||
info.addComponentType(UserInfoType.MULTIPLIER);
|
||||
break;
|
||||
}
|
||||
case PHYSICAL_ATTACK_SPEED:
|
||||
{
|
||||
info.addComponentType(UserInfoType.MULTIPLIER, UserInfoType.STATS);
|
||||
break;
|
||||
}
|
||||
case PHYSICAL_ATTACK:
|
||||
case PHYSICAL_DEFENCE:
|
||||
case EVASION_RATE:
|
||||
case ACCURACY_COMBAT:
|
||||
case CRITICAL_RATE:
|
||||
case MAGIC_CRITICAL_RATE:
|
||||
case MAGIC_EVASION_RATE:
|
||||
case ACCURACY_MAGIC:
|
||||
case MAGIC_ATTACK:
|
||||
case MAGIC_ATTACK_SPEED:
|
||||
case MAGICAL_DEFENCE:
|
||||
{
|
||||
info.addComponentType(UserInfoType.STATS);
|
||||
break;
|
||||
}
|
||||
case MAX_CP:
|
||||
{
|
||||
if (isPlayer())
|
||||
{
|
||||
info.addComponentType(UserInfoType.MAX_HPCPMP);
|
||||
}
|
||||
else
|
||||
{
|
||||
su.addUpdate(StatusUpdateType.MAX_CP, _stat.getMaxCp());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MAX_HP:
|
||||
{
|
||||
if (isPlayer())
|
||||
{
|
||||
info.addComponentType(UserInfoType.MAX_HPCPMP);
|
||||
}
|
||||
else
|
||||
{
|
||||
su.addUpdate(StatusUpdateType.MAX_HP, _stat.getMaxHp());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MAX_MP:
|
||||
{
|
||||
if (isPlayer())
|
||||
{
|
||||
info.addComponentType(UserInfoType.MAX_HPCPMP);
|
||||
}
|
||||
else
|
||||
{
|
||||
su.addUpdate(StatusUpdateType.MAX_CP, _stat.getMaxMp());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STAT_STR:
|
||||
case STAT_CON:
|
||||
case STAT_DEX:
|
||||
case STAT_INT:
|
||||
case STAT_WIT:
|
||||
case STAT_MEN:
|
||||
{
|
||||
info.addComponentType(UserInfoType.BASE_STATS);
|
||||
break;
|
||||
}
|
||||
case FIRE_RES:
|
||||
case WATER_RES:
|
||||
case WIND_RES:
|
||||
case EARTH_RES:
|
||||
case HOLY_RES:
|
||||
case DARK_RES:
|
||||
{
|
||||
info.addComponentType(UserInfoType.ELEMENTALS);
|
||||
break;
|
||||
}
|
||||
case FIRE_POWER:
|
||||
case WATER_POWER:
|
||||
case WIND_POWER:
|
||||
case EARTH_POWER:
|
||||
case HOLY_POWER:
|
||||
case DARK_POWER:
|
||||
{
|
||||
info.addComponentType(UserInfoType.ATK_ELEMENTAL);
|
||||
break;
|
||||
}
|
||||
info.addComponentType(UserInfoType.MULTIPLIER);
|
||||
break;
|
||||
}
|
||||
case PHYSICAL_ATTACK_SPEED:
|
||||
{
|
||||
info.addComponentType(UserInfoType.MULTIPLIER, UserInfoType.STATS);
|
||||
break;
|
||||
}
|
||||
case PHYSICAL_ATTACK:
|
||||
case PHYSICAL_DEFENCE:
|
||||
case EVASION_RATE:
|
||||
case ACCURACY_COMBAT:
|
||||
case CRITICAL_RATE:
|
||||
case MAGIC_CRITICAL_RATE:
|
||||
case MAGIC_EVASION_RATE:
|
||||
case ACCURACY_MAGIC:
|
||||
case MAGIC_ATTACK:
|
||||
case MAGIC_ATTACK_SPEED:
|
||||
case MAGICAL_DEFENCE:
|
||||
{
|
||||
info.addComponentType(UserInfoType.STATS);
|
||||
break;
|
||||
}
|
||||
case MAX_CP:
|
||||
{
|
||||
info.addComponentType(UserInfoType.MAX_HPCPMP);
|
||||
break;
|
||||
}
|
||||
case MAX_HP:
|
||||
{
|
||||
info.addComponentType(UserInfoType.MAX_HPCPMP);
|
||||
break;
|
||||
}
|
||||
case MAX_MP:
|
||||
{
|
||||
info.addComponentType(UserInfoType.MAX_HPCPMP);
|
||||
break;
|
||||
}
|
||||
case STAT_STR:
|
||||
case STAT_CON:
|
||||
case STAT_DEX:
|
||||
case STAT_INT:
|
||||
case STAT_WIT:
|
||||
case STAT_MEN:
|
||||
{
|
||||
info.addComponentType(UserInfoType.BASE_STATS);
|
||||
updateWeight = true;
|
||||
break;
|
||||
}
|
||||
case FIRE_RES:
|
||||
case WATER_RES:
|
||||
case WIND_RES:
|
||||
case EARTH_RES:
|
||||
case HOLY_RES:
|
||||
case DARK_RES:
|
||||
{
|
||||
info.addComponentType(UserInfoType.ELEMENTALS);
|
||||
break;
|
||||
}
|
||||
case FIRE_POWER:
|
||||
case WATER_POWER:
|
||||
case WIND_POWER:
|
||||
case EARTH_POWER:
|
||||
case HOLY_POWER:
|
||||
case DARK_POWER:
|
||||
{
|
||||
info.addComponentType(UserInfoType.ATK_ELEMENTAL);
|
||||
break;
|
||||
}
|
||||
case WEIGHT_LIMIT:
|
||||
case WEIGHT_PENALTY:
|
||||
{
|
||||
updateWeight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// currentChanges.clear();
|
||||
}
|
||||
|
||||
if (isPlayer())
|
||||
final Player player = getActingPlayer();
|
||||
if (updateWeight)
|
||||
{
|
||||
final Player player = getActingPlayer();
|
||||
player.refreshOverloaded(true);
|
||||
sendPacket(info);
|
||||
}
|
||||
|
||||
sendPacket(info);
|
||||
|
||||
player.broadcastCharInfo();
|
||||
|
||||
if (hasServitors() && hasAbnormalType(AbnormalType.ABILITY_CHANGE))
|
||||
{
|
||||
getServitors().values().forEach(Summon::broadcastStatusUpdate);
|
||||
}
|
||||
}
|
||||
else if (isNpc())
|
||||
{
|
||||
World.getInstance().forEachVisibleObject(this, Player.class, player ->
|
||||
{
|
||||
if (!isVisibleFor(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (broadcastFull)
|
||||
if (isFakePlayer())
|
||||
{
|
||||
player.broadcastCharInfo();
|
||||
player.sendPacket(new FakePlayerInfo((Npc) this));
|
||||
}
|
||||
else if (su.hasUpdates())
|
||||
else if (getRunSpeed() == 0)
|
||||
{
|
||||
broadcastPacket(su);
|
||||
player.sendPacket(new ServerObjectInfo((Npc) this, player));
|
||||
}
|
||||
if (hasServitors() && hasAbnormalType(AbnormalType.ABILITY_CHANGE))
|
||||
else
|
||||
{
|
||||
getServitors().values().forEach(Summon::broadcastStatusUpdate);
|
||||
player.sendPacket(new NpcInfo((Npc) this));
|
||||
}
|
||||
}
|
||||
else if (isNpc())
|
||||
{
|
||||
if (broadcastFull)
|
||||
{
|
||||
World.getInstance().forEachVisibleObject(this, Player.class, player ->
|
||||
{
|
||||
if (!isVisibleFor(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFakePlayer())
|
||||
{
|
||||
player.sendPacket(new FakePlayerInfo((Npc) this));
|
||||
}
|
||||
else if (_stat.getRunSpeed() == 0)
|
||||
{
|
||||
player.sendPacket(new ServerObjectInfo((Npc) this, player));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new NpcInfo((Npc) this));
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (su.hasUpdates())
|
||||
{
|
||||
broadcastPacket(su);
|
||||
}
|
||||
}
|
||||
else if (su.hasUpdates())
|
||||
{
|
||||
broadcastPacket(su);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_broadcastModifiedStatTask = null;
|
||||
|
||||
@@ -331,6 +331,7 @@ import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoAbnormalVisualEf
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoCubic;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoEquipSlot;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExVitalityEffectInfo;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.GetOnVehicle;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.HennaInfo;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
@@ -4690,7 +4691,7 @@ public class Player extends Playable
|
||||
{
|
||||
super.doAutoAttack(target);
|
||||
setRecentFakeDeath(false);
|
||||
if (target.isFakePlayer())
|
||||
if (target.isFakePlayer() && !Config.FAKE_PLAYER_AUTO_ATTACKABLE)
|
||||
{
|
||||
updatePvPStatus();
|
||||
}
|
||||
@@ -8706,9 +8707,13 @@ public class Player extends Playable
|
||||
if ((getWantsPeace() == 0) && (attackerPlayer.getWantsPeace() == 0) && !isAcademyMember())
|
||||
{
|
||||
final ClanWar war = attackerClan.getWarWith(getClanId());
|
||||
if ((war != null) && ((war.getState() == ClanWarState.MUTUAL) || (((war.getState() == ClanWarState.BLOOD_DECLARATION) || (war.getState() == ClanWarState.DECLARATION)) && (war.getAttackerClanId() == attackerClan.getId()))))
|
||||
if (war != null)
|
||||
{
|
||||
return true;
|
||||
final ClanWarState warState = war.getState();
|
||||
if ((warState == ClanWarState.MUTUAL) || (((warState == ClanWarState.BLOOD_DECLARATION) || (warState == ClanWarState.DECLARATION)) && (war.getAttackerClanId() == clan.getId())))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10048,6 +10053,7 @@ public class Player extends Playable
|
||||
sendPacket(new ExUserBoostStat(this, BonusExpType.VITALITY));
|
||||
sendPacket(new ExUserBoostStat(this, BonusExpType.BUFFS));
|
||||
sendPacket(new ExUserBoostStat(this, BonusExpType.PASSIVE));
|
||||
sendPacket(new ExVitalityEffectInfo(this));
|
||||
_userBoostStatTask = null;
|
||||
}, 300);
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ import org.l2jmobius.gameserver.network.serverpackets.ExPartyPetWindowUpdate;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExPetInfo;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.PetDelete;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.PetInfo;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.PetItemList;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.PetStatusUpdate;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.PetSummonInfo;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.RelationChanged;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ServerPacket;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.SummonInfo;
|
||||
@@ -211,7 +211,7 @@ public abstract class Summon extends Playable
|
||||
{
|
||||
if (player == _owner)
|
||||
{
|
||||
player.sendPacket(new PetInfo(this, 1));
|
||||
player.sendPacket(new PetSummonInfo(this, 1));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -375,10 +375,7 @@ public abstract class Summon extends Playable
|
||||
@Override
|
||||
public void onDecay()
|
||||
{
|
||||
if (!isPet())
|
||||
{
|
||||
super.onDecay();
|
||||
}
|
||||
unSummon(_owner);
|
||||
deleteMe(_owner);
|
||||
}
|
||||
|
||||
@@ -412,14 +409,18 @@ public abstract class Summon extends Playable
|
||||
}
|
||||
}
|
||||
|
||||
// pet will be deleted along with all his items
|
||||
// Pet will be deleted along with all his items.
|
||||
if (getInventory() != null)
|
||||
{
|
||||
getInventory().destroyAllItems("pet deleted", _owner, this);
|
||||
}
|
||||
|
||||
decayMe();
|
||||
|
||||
CharSummonTable.getInstance().removeServitor(_owner, getObjectId());
|
||||
if (!isPet())
|
||||
{
|
||||
CharSummonTable.getInstance().removeServitor(_owner, getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
public void unSummon(Player owner)
|
||||
@@ -854,7 +855,7 @@ public abstract class Summon extends Playable
|
||||
|
||||
if (isSpawned())
|
||||
{
|
||||
sendPacket(new PetInfo(this, value));
|
||||
sendPacket(new PetSummonInfo(this, value));
|
||||
sendPacket(new PetStatusUpdate(this));
|
||||
broadcastNpcInfo(value);
|
||||
|
||||
@@ -875,7 +876,14 @@ public abstract class Summon extends Playable
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendPacket(new ExPetInfo(this, player, value));
|
||||
if (isPet())
|
||||
{
|
||||
player.sendPacket(new ExPetInfo(this, player, value));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new SummonInfo(this, player, value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -900,7 +908,7 @@ public abstract class Summon extends Playable
|
||||
// Check if the Player is the owner of the Pet
|
||||
if (player == _owner)
|
||||
{
|
||||
player.sendPacket(new PetInfo(this, isDead() ? 0 : 1));
|
||||
player.sendPacket(new PetSummonInfo(this, isDead() ? 0 : 1));
|
||||
if (isPet())
|
||||
{
|
||||
player.sendPacket(new PetItemList(getInventory().getItems()));
|
||||
@@ -908,7 +916,14 @@ public abstract class Summon extends Playable
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new ExPetInfo(this, player, 0));
|
||||
if (isPet())
|
||||
{
|
||||
player.sendPacket(new ExPetInfo(this, player, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new SummonInfo(this, player, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,7 +969,7 @@ public abstract class Summon extends Playable
|
||||
{
|
||||
setTarget(target);
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
if (target.isFakePlayer())
|
||||
if (target.isFakePlayer() && !Config.FAKE_PLAYER_AUTO_ATTACKABLE)
|
||||
{
|
||||
_owner.updatePvPStatus();
|
||||
}
|
||||
|
||||
+2
-1
@@ -596,6 +596,8 @@ public class Door extends Creature
|
||||
{
|
||||
if (isVisibleFor(player))
|
||||
{
|
||||
player.sendPacket(new StaticObjectInfo(this, player.isGM()));
|
||||
player.sendPacket(new DoorStatusUpdate(this));
|
||||
if (getEmitter() > 0)
|
||||
{
|
||||
if (_isInverted)
|
||||
@@ -607,7 +609,6 @@ public class Door extends Creature
|
||||
player.sendPacket(new OnEventTrigger(getEmitter(), _open));
|
||||
}
|
||||
}
|
||||
player.sendPacket(new StaticObjectInfo(this, player.isGM()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ public class Monster extends Attackable
|
||||
{
|
||||
if (isFakePlayer())
|
||||
{
|
||||
return isInCombat() || attacker.isMonster() || (getScriptValue() > 0);
|
||||
return Config.FAKE_PLAYER_AUTO_ATTACKABLE || isInCombat() || attacker.isMonster() || (getScriptValue() > 0);
|
||||
}
|
||||
|
||||
// Check if the Monster target is aggressive
|
||||
|
||||
+22
-40
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.model.actor.stat;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
@@ -61,8 +62,6 @@ public class CreatureStat
|
||||
|
||||
private final Map<Stat, Double> _statsAdd = new EnumMap<>(Stat.class);
|
||||
private final Map<Stat, Double> _statsMul = new EnumMap<>(Stat.class);
|
||||
private final Map<Stat, Double> _addValueCache = new EnumMap<>(Stat.class);
|
||||
private final Map<Stat, Double> _mulValueCache = new EnumMap<>(Stat.class);
|
||||
private final Map<Stat, Map<MoveType, Double>> _moveTypeStats = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, Double> _reuseStat = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, Double> _mpConsumeStat = new ConcurrentHashMap<>();
|
||||
@@ -883,15 +882,13 @@ public class CreatureStat
|
||||
// Initialize default values
|
||||
for (Stat stat : Stat.values())
|
||||
{
|
||||
final Double resetAddValue = stat.getResetAddValue();
|
||||
if (resetAddValue.doubleValue() != 0)
|
||||
if (stat.getResetAddValue() != 0)
|
||||
{
|
||||
_statsAdd.put(stat, resetAddValue);
|
||||
_statsAdd.put(stat, stat.getResetAddValue());
|
||||
}
|
||||
final Double resetMulValue = stat.getResetMulValue();
|
||||
if (resetMulValue.doubleValue() != 0)
|
||||
if (stat.getResetMulValue() != 0)
|
||||
{
|
||||
_statsMul.put(stat, resetMulValue);
|
||||
_statsMul.put(stat, stat.getResetMulValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -902,8 +899,12 @@ public class CreatureStat
|
||||
*/
|
||||
public void recalculateStats(boolean broadcast)
|
||||
{
|
||||
Set<Stat> changed = null;
|
||||
// Copy old data before wiping it out.
|
||||
final Map<Stat, Double> adds = !broadcast ? Collections.emptyMap() : new EnumMap<>(_statsAdd);
|
||||
final Map<Stat, Double> muls = !broadcast ? Collections.emptyMap() : new EnumMap<>(_statsMul);
|
||||
|
||||
_lock.writeLock().lock();
|
||||
|
||||
try
|
||||
{
|
||||
// Wipe all the data.
|
||||
@@ -912,7 +913,7 @@ public class CreatureStat
|
||||
// Call pump to each effect.
|
||||
for (BuffInfo info : _creature.getEffectList().getPassives())
|
||||
{
|
||||
if (info.isInUse() && info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _creature, _creature))
|
||||
if (info.isInUse() && info.getSkill().checkConditions(SkillConditionScope.PASSIVE, _creature, _creature.getTarget()))
|
||||
{
|
||||
for (AbstractEffect effect : info.getEffects())
|
||||
{
|
||||
@@ -985,45 +986,26 @@ public class CreatureStat
|
||||
}
|
||||
_attackSpeedMultiplier = Formulas.calcAtkSpdMultiplier(_creature);
|
||||
_mAttackSpeedMultiplier = Formulas.calcMAtkSpdMultiplier(_creature);
|
||||
|
||||
if (broadcast)
|
||||
{
|
||||
// Calculate the difference between old and new stats.
|
||||
changed = EnumSet.noneOf(Stat.class);
|
||||
for (Stat stat : Stat.values())
|
||||
{
|
||||
// Check if add value changed for this stat.
|
||||
final Double resetAddValue = stat.getResetAddValue();
|
||||
final Double addValue = _statsAdd.getOrDefault(stat, resetAddValue);
|
||||
if (addValue.doubleValue() != _addValueCache.getOrDefault(stat, resetAddValue).doubleValue())
|
||||
{
|
||||
_addValueCache.put(stat, addValue);
|
||||
changed.add(stat);
|
||||
}
|
||||
else // Check if mul value changed for this stat.
|
||||
{
|
||||
final Double resetMulValue = stat.getResetMulValue();
|
||||
final Double mulValue = _statsMul.getOrDefault(stat, resetMulValue);
|
||||
if (mulValue.doubleValue() != _mulValueCache.getOrDefault(stat, resetMulValue).doubleValue())
|
||||
{
|
||||
_mulValueCache.put(stat, mulValue);
|
||||
changed.add(stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lock.writeLock().unlock();
|
||||
}
|
||||
|
||||
// Notify recalculation to child classes.
|
||||
// Notify recalculation to child classes
|
||||
onRecalculateStats(broadcast);
|
||||
|
||||
// Broadcast changes.
|
||||
if ((changed != null) && !changed.isEmpty())
|
||||
if (broadcast)
|
||||
{
|
||||
// Calculate the difference between old and new stats
|
||||
final Set<Stat> changed = EnumSet.noneOf(Stat.class);
|
||||
for (Stat stat : Stat.values())
|
||||
{
|
||||
if (_statsAdd.getOrDefault(stat, stat.getResetAddValue()).equals(adds.getOrDefault(stat, stat.getResetAddValue())) || _statsMul.getOrDefault(stat, stat.getResetMulValue()).equals(muls.getOrDefault(stat, stat.getResetMulValue())))
|
||||
{
|
||||
changed.add(stat);
|
||||
}
|
||||
}
|
||||
_creature.broadcastModifiedStats(changed);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -482,7 +482,11 @@ public class PlayerStat extends PlayableStat
|
||||
|
||||
public double getVitalityExpBonus()
|
||||
{
|
||||
return (getVitalityPoints() > 0) ? getMul(Stat.VITALITY_EXP_RATE, Config.RATE_VITALITY_EXP_MULTIPLIER) : 1.0;
|
||||
if (getVitalityPoints() > 0)
|
||||
{
|
||||
return getMul(Stat.VITALITY_EXP_RATE, 1) * (getActiveChar().hasPremiumStatus() ? Config.RATE_VITALITY_EXP_PREMIUM_MULTIPLIER : Config.RATE_VITALITY_EXP_MULTIPLIER);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setVitalityPoints(int value)
|
||||
|
||||
+2
-2
@@ -122,7 +122,7 @@ public class Transform implements IIdentifiable
|
||||
return _title;
|
||||
}
|
||||
|
||||
private TransformTemplate getTemplate(Creature creature)
|
||||
public TransformTemplate getTemplate(Creature creature)
|
||||
{
|
||||
if (creature.isPlayer())
|
||||
{
|
||||
@@ -318,7 +318,7 @@ public class Transform implements IIdentifiable
|
||||
// Send basic action list.
|
||||
if (template.hasBasicActionList())
|
||||
{
|
||||
player.sendPacket(template.getBasicActionList());
|
||||
player.sendPacket(new ExBasicActionList(template.getBasicActionList()));
|
||||
}
|
||||
|
||||
player.getEffectList().stopAllToggles();
|
||||
|
||||
+6
-8
@@ -30,7 +30,6 @@ import org.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import org.l2jmobius.gameserver.model.item.type.WeaponType;
|
||||
import org.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
import org.l2jmobius.gameserver.model.stats.Stat;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
@@ -45,8 +44,7 @@ public class TransformTemplate
|
||||
private List<AdditionalItemHolder> _additionalItems;
|
||||
private Map<Integer, Integer> _baseDefense;
|
||||
private Map<Integer, Double> _baseStats;
|
||||
|
||||
private ExBasicActionList _list;
|
||||
private int[] _actions;
|
||||
private final Map<Integer, TransformLevelData> _data = new LinkedHashMap<>(100);
|
||||
|
||||
public TransformTemplate(StatSet set)
|
||||
@@ -282,19 +280,19 @@ public class TransformTemplate
|
||||
return _additionalItems != null ? _additionalItems : Collections.emptyList();
|
||||
}
|
||||
|
||||
public void setBasicActionList(ExBasicActionList list)
|
||||
public void setBasicActionList(int[] actions)
|
||||
{
|
||||
_list = list;
|
||||
_actions = actions;
|
||||
}
|
||||
|
||||
public ExBasicActionList getBasicActionList()
|
||||
public int[] getBasicActionList()
|
||||
{
|
||||
return _list;
|
||||
return _actions;
|
||||
}
|
||||
|
||||
public boolean hasBasicActionList()
|
||||
{
|
||||
return _list != null;
|
||||
return _actions != null;
|
||||
}
|
||||
|
||||
public void addLevelData(TransformLevelData data)
|
||||
|
||||
@@ -184,7 +184,7 @@ public class ClanWar
|
||||
|
||||
_winnerClanId = winnerClan.getId();
|
||||
_endTime = System.currentTimeMillis();
|
||||
ThreadPool.schedule(() -> ClanTable.getInstance().deleteClanWars(cancelor.getId(), winnerClan.getId()), (_endTime + TIME_TO_DELETION_AFTER_DEFEAT) - System.currentTimeMillis());
|
||||
ThreadPool.schedule(() -> ClanTable.getInstance().deleteClanWars(cancelor.getId(), winnerClan.getId()), 5000 /* (_endTime + TIME_TO_DELETION_AFTER_DEFEAT) - System.currentTimeMillis() */);
|
||||
}
|
||||
|
||||
public void clanWarTimeout()
|
||||
@@ -203,7 +203,7 @@ public class ClanWar
|
||||
|
||||
_state = ClanWarState.TIE;
|
||||
_endTime = System.currentTimeMillis();
|
||||
ThreadPool.schedule(() -> ClanTable.getInstance().deleteClanWars(attackerClan.getId(), attackedClan.getId()), (_endTime + TIME_TO_DELETION_AFTER_CANCELLATION) - System.currentTimeMillis());
|
||||
ThreadPool.schedule(() -> ClanTable.getInstance().deleteClanWars(attackerClan.getId(), attackedClan.getId()), 5000 /* (_endTime + TIME_TO_DELETION_AFTER_CANCELLATION) - System.currentTimeMillis() */);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -57,7 +57,10 @@ public enum CommissionItemType
|
||||
NECKLACE(31),
|
||||
BELT(32),
|
||||
BRACELET(33),
|
||||
AGATHION(62),
|
||||
HAIR_ACCESSORY(34),
|
||||
BROOCH_JEWEL(63),
|
||||
ARTIFACT(64),
|
||||
// Supplies
|
||||
POTION(35),
|
||||
SCROLL_ENCHANT_WEAPON(36),
|
||||
@@ -65,6 +68,7 @@ public enum CommissionItemType
|
||||
SCROLL_OTHER(38),
|
||||
SOULSHOT(39),
|
||||
SPIRITSHOT(40),
|
||||
OTHER_SUPPLIES(41),
|
||||
// Pet Goods
|
||||
PET_EQUIPMENT(42),
|
||||
PET_SUPPLIES(43),
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ public enum CommissionTreeType
|
||||
CommissionItemType.SPEAR,
|
||||
CommissionItemType.OTHER_WEAPON),
|
||||
ARMOR(1, CommissionItemType.HELMET, CommissionItemType.ARMOR_TOP, CommissionItemType.ARMOR_PANTS, CommissionItemType.FULL_BODY, CommissionItemType.GLOVES, CommissionItemType.FEET, CommissionItemType.SHIELD, CommissionItemType.SIGIL, CommissionItemType.UNDERWEAR, CommissionItemType.CLOAK),
|
||||
ACCESSORY(2, CommissionItemType.RING, CommissionItemType.EARRING, CommissionItemType.NECKLACE, CommissionItemType.BELT, CommissionItemType.BRACELET, CommissionItemType.HAIR_ACCESSORY),
|
||||
SUPPLIES(3, CommissionItemType.POTION, CommissionItemType.SCROLL_ENCHANT_WEAPON, CommissionItemType.SCROLL_ENCHANT_ARMOR, CommissionItemType.SCROLL_OTHER, CommissionItemType.SOULSHOT, CommissionItemType.SPIRITSHOT),
|
||||
ACCESSORY(2, CommissionItemType.RING, CommissionItemType.EARRING, CommissionItemType.NECKLACE, CommissionItemType.BELT, CommissionItemType.BRACELET, CommissionItemType.AGATHION, CommissionItemType.HAIR_ACCESSORY, CommissionItemType.BROOCH_JEWEL, CommissionItemType.ARTIFACT),
|
||||
SUPPLIES(3, CommissionItemType.POTION, CommissionItemType.SCROLL_ENCHANT_WEAPON, CommissionItemType.SCROLL_ENCHANT_ARMOR, CommissionItemType.SCROLL_OTHER, CommissionItemType.SOULSHOT, CommissionItemType.SPIRITSHOT, CommissionItemType.OTHER_SUPPLIES),
|
||||
PET_GOODS(4, CommissionItemType.PET_EQUIPMENT, CommissionItemType.PET_SUPPLIES),
|
||||
MISC(
|
||||
5,
|
||||
|
||||
+1
@@ -64,5 +64,6 @@ public enum EffectType
|
||||
TELEPORT_TO_TARGET,
|
||||
ABNORMAL_SHIELD,
|
||||
DUAL_RANGE,
|
||||
RESTORE_SYMBOL_SEAL,
|
||||
VITALITY_POINT_UP
|
||||
}
|
||||
+11
@@ -2242,6 +2242,17 @@ public abstract class AbstractScript extends ManagedScript implements IEventTime
|
||||
summoner.addSummonedNpc(npc);
|
||||
}
|
||||
|
||||
// Retain monster original position if ENABLE_RANDOM_MONSTER_SPAWNS is enabled.
|
||||
if (Config.ENABLE_RANDOM_MONSTER_SPAWNS && !randomOffset && npc.isMonster())
|
||||
{
|
||||
spawn.setXYZ(x, y, zValue);
|
||||
npc.setXYZ(x, y, zValue);
|
||||
if (heading > -1)
|
||||
{
|
||||
npc.setHeading(heading);
|
||||
}
|
||||
}
|
||||
|
||||
// Fixes invisible NPCs spawned by script.
|
||||
npc.broadcastInfo();
|
||||
|
||||
|
||||
+15
-1
@@ -32,6 +32,7 @@ public class LimitShopProductHolder
|
||||
private final long _count;
|
||||
private final float _chance;
|
||||
private final boolean _announce;
|
||||
private final int _enchant;
|
||||
private final int _productionId2;
|
||||
private final long _count2;
|
||||
private final float _chance2;
|
||||
@@ -48,9 +49,10 @@ public class LimitShopProductHolder
|
||||
private final long _count5;
|
||||
private final boolean _announce5;
|
||||
private final int _accountDailyLimit;
|
||||
private final int _accountMontlyLimit;
|
||||
private final int _accountBuyLimit;
|
||||
|
||||
public LimitShopProductHolder(int id, int category, int minLevel, int maxLevel, int[] ingredientIds, long[] ingredientQuantities, int[] ingredientEnchants, int productionId, long count, float chance, boolean announce, int productionId2, long count2, float chance2, boolean announce2, int productionId3, long count3, float chance3, boolean announce3, int productionId4, long count4, float chance4, boolean announce4, int productionId5, long count5, boolean announce5, int accountDailyLimit, int accountBuyLimit)
|
||||
public LimitShopProductHolder(int id, int category, int minLevel, int maxLevel, int[] ingredientIds, long[] ingredientQuantities, int[] ingredientEnchants, int productionId, long count, float chance, boolean announce, int enchant, int productionId2, long count2, float chance2, boolean announce2, int productionId3, long count3, float chance3, boolean announce3, int productionId4, long count4, float chance4, boolean announce4, int productionId5, long count5, boolean announce5, int accountDailyLimit, int accountMontlyLimit, int accountBuyLimit)
|
||||
{
|
||||
_id = id;
|
||||
_category = category;
|
||||
@@ -63,6 +65,7 @@ public class LimitShopProductHolder
|
||||
_count = count;
|
||||
_chance = chance;
|
||||
_announce = announce;
|
||||
_enchant = enchant;
|
||||
_productionId2 = productionId2;
|
||||
_count2 = count2;
|
||||
_chance2 = chance2;
|
||||
@@ -79,6 +82,7 @@ public class LimitShopProductHolder
|
||||
_count5 = count5;
|
||||
_announce5 = announce5;
|
||||
_accountDailyLimit = accountDailyLimit;
|
||||
_accountMontlyLimit = accountMontlyLimit;
|
||||
_accountBuyLimit = accountBuyLimit;
|
||||
}
|
||||
|
||||
@@ -137,6 +141,11 @@ public class LimitShopProductHolder
|
||||
return _announce;
|
||||
}
|
||||
|
||||
public int getEnchant()
|
||||
{
|
||||
return _enchant;
|
||||
}
|
||||
|
||||
public int getProductionId2()
|
||||
{
|
||||
return _productionId2;
|
||||
@@ -217,6 +226,11 @@ public class LimitShopProductHolder
|
||||
return _accountDailyLimit;
|
||||
}
|
||||
|
||||
public int getAccountMontlyLimit()
|
||||
{
|
||||
return _accountMontlyLimit;
|
||||
}
|
||||
|
||||
public int getAccountBuyLimit()
|
||||
{
|
||||
return _accountBuyLimit;
|
||||
|
||||
+133
-1
@@ -39,6 +39,7 @@ import org.l2jmobius.commons.util.StringUtil;
|
||||
import org.l2jmobius.gameserver.data.ItemTable;
|
||||
import org.l2jmobius.gameserver.data.xml.AgathionData;
|
||||
import org.l2jmobius.gameserver.data.xml.AppearanceItemData;
|
||||
import org.l2jmobius.gameserver.data.xml.ArmorSetData;
|
||||
import org.l2jmobius.gameserver.data.xml.EnchantItemOptionsData;
|
||||
import org.l2jmobius.gameserver.data.xml.EnsoulData;
|
||||
import org.l2jmobius.gameserver.data.xml.OptionData;
|
||||
@@ -52,6 +53,7 @@ import org.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import org.l2jmobius.gameserver.instancemanager.IdManager;
|
||||
import org.l2jmobius.gameserver.instancemanager.ItemsOnGroundManager;
|
||||
import org.l2jmobius.gameserver.instancemanager.SiegeGuardManager;
|
||||
import org.l2jmobius.gameserver.model.ArmorSet;
|
||||
import org.l2jmobius.gameserver.model.DropProtection;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.VariationInstance;
|
||||
@@ -74,12 +76,14 @@ import org.l2jmobius.gameserver.model.events.impl.item.OnItemBypassEvent;
|
||||
import org.l2jmobius.gameserver.model.events.impl.item.OnItemEnchantAdd;
|
||||
import org.l2jmobius.gameserver.model.events.impl.item.OnItemTalk;
|
||||
import org.l2jmobius.gameserver.model.holders.AgathionSkillHolder;
|
||||
import org.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
|
||||
import org.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import org.l2jmobius.gameserver.model.item.Armor;
|
||||
import org.l2jmobius.gameserver.model.item.EtcItem;
|
||||
import org.l2jmobius.gameserver.model.item.ItemTemplate;
|
||||
import org.l2jmobius.gameserver.model.item.Weapon;
|
||||
import org.l2jmobius.gameserver.model.item.appearance.AppearanceStone;
|
||||
import org.l2jmobius.gameserver.model.item.appearance.AppearanceType;
|
||||
import org.l2jmobius.gameserver.model.item.enchant.attribute.AttributeHolder;
|
||||
import org.l2jmobius.gameserver.model.item.type.EtcItemType;
|
||||
import org.l2jmobius.gameserver.model.item.type.ItemType;
|
||||
@@ -94,6 +98,7 @@ import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.DropItem;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.GetItem;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.SkillCoolTime;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.SpawnItem;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import org.l2jmobius.gameserver.taskmanager.ItemAppearanceTaskManager;
|
||||
@@ -1652,7 +1657,9 @@ public class Item extends WorldObject
|
||||
setDropperObjectId(dropper != null ? dropper.getObjectId() : 0); // Set the dropper Id for the knownlist packets in sendInfo
|
||||
|
||||
// Add the Item dropped in the world as a visible object
|
||||
World.getInstance().addVisibleObject(this, getWorldRegion());
|
||||
final WorldRegion region = getWorldRegion();
|
||||
region.addVisibleObject(this);
|
||||
World.getInstance().addVisibleObject(this, region);
|
||||
if (Config.SAVE_DROPPED_ITEM)
|
||||
{
|
||||
ItemsOnGroundManager.getInstance().save(this);
|
||||
@@ -2581,6 +2588,11 @@ public class Item extends WorldObject
|
||||
}
|
||||
}
|
||||
|
||||
public int getAppearanceStoneId()
|
||||
{
|
||||
return getVariables().getInt(ItemVariables.VISUAL_APPEARANCE_STONE_ID, 0);
|
||||
}
|
||||
|
||||
public long getVisualLifeTime()
|
||||
{
|
||||
return getVariables().getLong(ItemVariables.VISUAL_APPEARANCE_LIFE_TIME, 0);
|
||||
@@ -2605,6 +2617,8 @@ public class Item extends WorldObject
|
||||
|
||||
public void onVisualLifeTimeEnd()
|
||||
{
|
||||
removeVisualSetSkills();
|
||||
|
||||
final ItemVariables vars = getVariables();
|
||||
vars.remove(ItemVariables.VISUAL_ID);
|
||||
vars.remove(ItemVariables.VISUAL_APPEARANCE_STONE_ID);
|
||||
@@ -2630,6 +2644,124 @@ public class Item extends WorldObject
|
||||
}
|
||||
}
|
||||
|
||||
public void removeVisualSetSkills()
|
||||
{
|
||||
if (!isEquipped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int appearanceStoneId = getAppearanceStoneId();
|
||||
if (appearanceStoneId > 0)
|
||||
{
|
||||
final AppearanceStone stone = AppearanceItemData.getInstance().getStone(appearanceStoneId);
|
||||
if ((stone != null) && (stone.getType() == AppearanceType.FIXED))
|
||||
{
|
||||
final Player player = getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
boolean update = false;
|
||||
for (ArmorSet armorSet : ArmorSetData.getInstance().getSets(stone.getVisualId()))
|
||||
{
|
||||
if ((armorSet.getPiecesCount(player, Item::getVisualId) - 1 /* not removed yet */) < armorSet.getMinimumPieces())
|
||||
{
|
||||
for (ArmorsetSkillHolder holder : armorSet.getSkills())
|
||||
{
|
||||
final Skill skill = holder.getSkill();
|
||||
if (skill != null)
|
||||
{
|
||||
player.removeSkill(skill, false, skill.isPassive());
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
player.sendSkillList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void applyVisualSetSkills()
|
||||
{
|
||||
if (!isEquipped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int appearanceStoneId = getAppearanceStoneId();
|
||||
if (appearanceStoneId > 0)
|
||||
{
|
||||
final AppearanceStone stone = AppearanceItemData.getInstance().getStone(appearanceStoneId);
|
||||
if ((stone != null) && (stone.getType() == AppearanceType.FIXED))
|
||||
{
|
||||
final Player player = getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
boolean update = false;
|
||||
boolean updateTimeStamp = false;
|
||||
for (ArmorSet armorSet : ArmorSetData.getInstance().getSets(stone.getVisualId()))
|
||||
{
|
||||
if (armorSet.getPiecesCount(player, Item::getVisualId) >= armorSet.getMinimumPieces())
|
||||
{
|
||||
for (ArmorsetSkillHolder holder : armorSet.getSkills())
|
||||
{
|
||||
if (player.getSkillLevel(holder.getSkillId()) >= holder.getSkillLevel())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Skill skill = holder.getSkill();
|
||||
if ((skill == null) || (skill.isPassive() && !skill.checkConditions(SkillConditionScope.PASSIVE, player, player)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player.addSkill(skill, false);
|
||||
update = true;
|
||||
|
||||
if (skill.isActive())
|
||||
{
|
||||
if (!player.hasSkillReuse(skill.getReuseHashCode()))
|
||||
{
|
||||
final int equipDelay = getEquipReuseDelay();
|
||||
if (equipDelay > 0)
|
||||
{
|
||||
player.addTimeStamp(skill, equipDelay);
|
||||
player.disableSkill(skill, equipDelay);
|
||||
}
|
||||
}
|
||||
|
||||
// Active, non offensive, skills start with reuse on equip.
|
||||
if (!skill.isBad() && !skill.isTransformation() && (Config.ARMOR_SET_EQUIP_ACTIVE_SKILL_REUSE > 0) && player.hasEnteredWorld())
|
||||
{
|
||||
player.addTimeStamp(skill, skill.getReuseDelay() > 0 ? skill.getReuseDelay() : Config.ARMOR_SET_EQUIP_ACTIVE_SKILL_REUSE);
|
||||
}
|
||||
|
||||
updateTimeStamp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (updateTimeStamp)
|
||||
{
|
||||
player.sendPacket(new SkillCoolTime(player));
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
player.sendSkillList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item in String format
|
||||
* @return String
|
||||
|
||||
+4
-2
@@ -755,7 +755,8 @@ public abstract class Inventory extends ItemContainer
|
||||
final int itemVisualId = item.getVisualId();
|
||||
if (itemVisualId > 0)
|
||||
{
|
||||
final AppearanceStone stone = AppearanceItemData.getInstance().getStone(itemVisualId);
|
||||
final int appearanceStoneId = item.getAppearanceStoneId();
|
||||
final AppearanceStone stone = AppearanceItemData.getInstance().getStone(appearanceStoneId > 0 ? appearanceStoneId : itemVisualId);
|
||||
if ((stone != null) && (stone.getType() == AppearanceType.FIXED) && verifyAndApply(player, item, Item::getVisualId))
|
||||
{
|
||||
update = true;
|
||||
@@ -907,7 +908,8 @@ public abstract class Inventory extends ItemContainer
|
||||
final int itemVisualId = item.getVisualId();
|
||||
if (itemVisualId > 0)
|
||||
{
|
||||
final AppearanceStone stone = AppearanceItemData.getInstance().getStone(itemVisualId);
|
||||
final int appearanceStoneId = item.getAppearanceStoneId();
|
||||
final AppearanceStone stone = AppearanceItemData.getInstance().getStone(appearanceStoneId > 0 ? appearanceStoneId : itemVisualId);
|
||||
if ((stone != null) && (stone.getType() == AppearanceType.FIXED) && verifyAndRemove(player, item, Item::getVisualId))
|
||||
{
|
||||
remove = true;
|
||||
|
||||
+3
-3
@@ -686,7 +686,7 @@ public class SkillCaster implements Runnable
|
||||
((Creature) obj).addAttackerToAttackByList(caster);
|
||||
|
||||
// Summoning a servitor should not renew your own PvP flag time.
|
||||
if (obj.isFakePlayer() && (!obj.isServitor() || (obj.getObjectId() != player.getFirstServitor().getObjectId())))
|
||||
if (obj.isFakePlayer() && !Config.FAKE_PLAYER_AUTO_ATTACKABLE && (!obj.isServitor() || (obj.getObjectId() != player.getFirstServitor().getObjectId())))
|
||||
{
|
||||
player.updatePvPStatus();
|
||||
}
|
||||
@@ -709,7 +709,7 @@ public class SkillCaster implements Runnable
|
||||
{
|
||||
// Consider fake player PvP status.
|
||||
if (!obj.isFakePlayer() //
|
||||
|| (obj.isFakePlayer() && (!((Npc) obj).isScriptValue(0) || (((Npc) obj).getReputation() < 0))))
|
||||
|| (obj.isFakePlayer() && !Config.FAKE_PLAYER_AUTO_ATTACKABLE && (!((Npc) obj).isScriptValue(0) || (((Npc) obj).getReputation() < 0))))
|
||||
{
|
||||
player.updatePvPStatus();
|
||||
}
|
||||
@@ -744,7 +744,7 @@ public class SkillCaster implements Runnable
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (caster.isFakePlayer()) // fake player attacks player
|
||||
else if (caster.isFakePlayer() && !Config.FAKE_PLAYER_AUTO_ATTACKABLE) // fake player attacks player
|
||||
{
|
||||
if (target.isPlayable() || target.isFakePlayer())
|
||||
{
|
||||
|
||||
@@ -97,6 +97,7 @@ public enum Stat
|
||||
REAR_DAMAGE_RATE("rearDamage"),
|
||||
DRAGON_WEAPON_DEFENCE("dragonWeaponDefence"),
|
||||
AUTO_ATTACK_DAMAGE_BONUS("autoAttackDamageBonus"),
|
||||
IGNORE_REDUCE_DAMAGE("ignoreReduceDamage"),
|
||||
|
||||
// PVP BONUS
|
||||
PVP_PHYSICAL_ATTACK_DAMAGE("pvpPhysDmg"),
|
||||
@@ -137,7 +138,8 @@ public enum Stat
|
||||
SHIELD_DEFENCE_RATE("rShld", new ShieldDefenceRateFinalizer()),
|
||||
CRITICAL_RATE("rCrit", new PCriticalRateFinalizer(), MathUtil::add, MathUtil::add, 0, 1),
|
||||
CRITICAL_RATE_SKILL("physicalSkillCriticalRate"),
|
||||
MAX_MAGIC_CRITICAL_RATE("maxMagicCritRate"),
|
||||
ADD_MAX_MAGIC_CRITICAL_RATE("addMaxMagicCritRate"),
|
||||
ADD_MAX_PHYSICAL_CRITICAL_RATE("addMaxPhysicalCritRate"),
|
||||
MAGIC_CRITICAL_RATE("mCritRate", new MCritRateFinalizer()),
|
||||
DEFENCE_CRITICAL_RATE("defCritRate"),
|
||||
DEFENCE_CRITICAL_RATE_ADD("defCritRateAdd"),
|
||||
|
||||
+12
-1
@@ -43,7 +43,18 @@ public class MCritRateFinalizer implements IStatFunction
|
||||
}
|
||||
|
||||
final double witBonus = creature.getWIT() > 0 ? BaseStat.WIT.calcBonus(creature) : 1;
|
||||
return validateValue(creature, Stat.defaultValue(creature, stat, baseValue * witBonus * 10), 0, creature.isPlayable() ? creature.getStat().getValue(Stat.MAX_MAGIC_CRITICAL_RATE, Config.MAX_MCRIT_RATE) : Double.MAX_VALUE);
|
||||
|
||||
final double maxMagicalCritRate;
|
||||
if (creature.isPlayable())
|
||||
{
|
||||
maxMagicalCritRate = Config.MAX_MCRIT_RATE + creature.getStat().getValue(Stat.ADD_MAX_MAGIC_CRITICAL_RATE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxMagicalCritRate = Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
return validateValue(creature, Stat.defaultValue(creature, stat, baseValue * witBonus * 10), 0, maxMagicalCritRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -95,6 +95,6 @@ public class MDefenseFinalizer implements IStatFunction
|
||||
{
|
||||
final double mul = Math.max(creature.getStat().getMul(stat), 0.5);
|
||||
final double add = creature.getStat().getAdd(stat);
|
||||
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
|
||||
return Math.max((baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType()), creature.getTemplate().getBaseValue(stat, 0) * 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -42,7 +42,18 @@ public class PCriticalRateFinalizer implements IStatFunction
|
||||
baseValue += calcEnchantBodyPart(creature, ItemTemplate.SLOT_LEGS);
|
||||
}
|
||||
final double dexBonus = creature.getDEX() > 0 ? BaseStat.DEX.calcBonus(creature) : 1;
|
||||
return validateValue(creature, Stat.defaultValue(creature, stat, baseValue * dexBonus * 10), 0, creature.isPlayable() ? Config.MAX_PCRIT_RATE : Double.MAX_VALUE);
|
||||
|
||||
final double maxPhysicalCritRate;
|
||||
if (creature.isPlayable())
|
||||
{
|
||||
maxPhysicalCritRate = Config.MAX_PCRIT_RATE + creature.getStat().getValue(Stat.ADD_MAX_PHYSICAL_CRITICAL_RATE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxPhysicalCritRate = Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
return validateValue(creature, Stat.defaultValue(creature, stat, baseValue * dexBonus * 10), 0, maxPhysicalCritRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -97,6 +97,6 @@ public class PDefenseFinalizer implements IStatFunction
|
||||
{
|
||||
final double mul = Math.max(creature.getStat().getMul(stat), 0.5);
|
||||
final double add = creature.getStat().getAdd(stat);
|
||||
return (baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType());
|
||||
return Math.max((baseValue * mul) + add + creature.getStat().getMoveTypeValue(stat, creature.getMoveType()), creature.getTemplate().getBaseValue(stat, 0) * 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -45,6 +45,7 @@ public class AccountVariables extends AbstractVariables
|
||||
public static final String PRIME_SHOP_PRODUCT_DAILY_COUNT = "PSPDailyCount";
|
||||
public static final String LCOIN_SHOP_PRODUCT_COUNT = "LCSCount";
|
||||
public static final String LCOIN_SHOP_PRODUCT_DAILY_COUNT = "LCSDailyCount";
|
||||
public static final String LCOIN_SHOP_PRODUCT_MONTLY_COUNT = "LCSMontlyCount";
|
||||
|
||||
private final String _accountName;
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@ import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureZoneEnter;
|
||||
import org.l2jmobius.gameserver.model.events.impl.creature.OnCreatureZoneExit;
|
||||
import org.l2jmobius.gameserver.model.instancezone.Instance;
|
||||
import org.l2jmobius.gameserver.model.interfaces.ILocational;
|
||||
import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ServerPacket;
|
||||
|
||||
/**
|
||||
@@ -215,6 +217,10 @@ public abstract class ZoneType extends ListenersContainer
|
||||
// Check level
|
||||
if ((creature.getLevel() < _minLevel) || (creature.getLevel() > _maxLevel))
|
||||
{
|
||||
if (creature.isPlayer())
|
||||
{
|
||||
creature.getActingPlayer().sendPacket(new ExShowScreenMessage(SystemMessageId.YOU_CANNOT_ENTER_AS_YOUR_LEVEL_DOESN_T_MEED_THE_REQUIREMENTS, ExShowScreenMessage.TOP_CENTER, 10000));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.model.zone.type;
|
||||
|
||||
import org.l2jmobius.gameserver.enums.InstanceType;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
import org.l2jmobius.gameserver.model.zone.ZoneType;
|
||||
@@ -32,6 +33,7 @@ public class TeleportZone extends ZoneType
|
||||
public TeleportZone(int id)
|
||||
{
|
||||
super(id);
|
||||
setTargetType(InstanceType.Player); // Default only player.
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-1
@@ -117,6 +117,11 @@ public class RequestAcquireSkill implements ClientPacket
|
||||
|
||||
final int skillId = player.getReplacementSkill(_id);
|
||||
final Skill existingSkill = player.getKnownSkill(skillId); // Mobius: Keep existing sublevel.
|
||||
if ((_level > 65536000) && (existingSkill != null) && (existingSkill.getSubLevel() > 1000))
|
||||
{
|
||||
_level -= existingSkill.getSubLevel() * 65536;
|
||||
}
|
||||
|
||||
final Skill skill = SkillData.getInstance().getSkill(skillId, _level, existingSkill == null ? 0 : existingSkill.getSubLevel());
|
||||
if (skill == null)
|
||||
{
|
||||
@@ -681,7 +686,7 @@ public class RequestAcquireSkill implements ClientPacket
|
||||
player.sendItemList();
|
||||
player.updateShortCuts(_id, skill.getLevel(), skill.getSubLevel());
|
||||
player.sendPacket(new ShortCutInit(player));
|
||||
player.sendPacket(new ExBasicActionList(ExBasicActionList.DEFAULT_ACTION_LIST));
|
||||
player.sendPacket(ExBasicActionList.STATIC_PACKET);
|
||||
player.sendSkillList(skill.getId());
|
||||
showSkillList(trainer, player);
|
||||
|
||||
|
||||
+4
-3
@@ -25,6 +25,7 @@ import org.l2jmobius.gameserver.handler.IPlayerActionHandler;
|
||||
import org.l2jmobius.gameserver.handler.PlayerActionHandler;
|
||||
import org.l2jmobius.gameserver.model.ActionDataHolder;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.actor.transform.TransformTemplate;
|
||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import org.l2jmobius.gameserver.model.skill.AbnormalType;
|
||||
import org.l2jmobius.gameserver.model.skill.BuffInfo;
|
||||
@@ -32,7 +33,6 @@ import org.l2jmobius.gameserver.network.GameClient;
|
||||
import org.l2jmobius.gameserver.network.PacketLogger;
|
||||
import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.RecipeShopManageList;
|
||||
|
||||
/**
|
||||
@@ -86,8 +86,9 @@ public class RequestActionUse implements ClientPacket
|
||||
// Don't allow to do some action if player is transformed
|
||||
if (player.isTransformed())
|
||||
{
|
||||
final int[] allowedActions = player.isTransformed() ? ExBasicActionList.ACTIONS_ON_TRANSFORM : ExBasicActionList.DEFAULT_ACTION_LIST;
|
||||
if (Arrays.binarySearch(allowedActions, _actionId) < 0)
|
||||
final TransformTemplate transformTemplate = player.getTransformation().get().getTemplate(player);
|
||||
final int[] allowedActions = transformTemplate.getBasicActionList();
|
||||
if ((allowedActions == null) || (Arrays.binarySearch(allowedActions, _actionId) < 0))
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
PacketLogger.warning(player + " used action which he does not have! Id = " + _actionId + " transform: " + player.getTransformation().get().getId());
|
||||
|
||||
+2
-2
@@ -87,7 +87,7 @@ public class RequestShortCutReg implements ClientPacket
|
||||
else if (_page == 23)
|
||||
{
|
||||
final Item item = player.getInventory().getItemByObjectId(_id);
|
||||
if ((item != null) && !item.isPotion())
|
||||
if (((item != null) && !item.isPotion()) || (_type == ShortcutType.ACTION))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -148,7 +148,7 @@ public class RequestShortCutReg implements ClientPacket
|
||||
final Shortcut sc = new Shortcut(_slot, _page, _type, _id, _level, _subLevel, _characterType);
|
||||
sc.setAutoUse(_active);
|
||||
player.registerShortCut(sc);
|
||||
player.sendPacket(new ShortCutRegister(sc));
|
||||
player.sendPacket(new ShortCutRegister(sc, player));
|
||||
player.sendPacket(new ExActivateAutoShortcut(sc, _active));
|
||||
|
||||
// When id is not auto used, deactivate auto shortcuts.
|
||||
|
||||
+4
-4
@@ -225,21 +225,21 @@ public class UseItem implements ClientPacket
|
||||
|
||||
if (CategoryData.getInstance().isInCategory(CategoryType.DEATH_KNIGHT_ALL_CLASS, player.getClassId().getId()))
|
||||
{
|
||||
// Death Knight class unequip shields.
|
||||
// Unequip shields.
|
||||
if ((player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND) != null) && (player.getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND).getItemType() == ArmorType.SHIELD))
|
||||
{
|
||||
player.disarmShield();
|
||||
}
|
||||
|
||||
// Prevent Death Knight class to equip shields.
|
||||
// Prevent equipping shields.
|
||||
if (item.getItemType() == ArmorType.SHIELD)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent Death Knight class to equip other weapons.
|
||||
if (item.isWeapon() && ((item.getWeaponItem().getItemType() != WeaponType.SWORD) || ((item.getTemplate().getBodyPart() == ItemTemplate.SLOT_LR_HAND))))
|
||||
// Prevent equipping other weapons.
|
||||
if (item.isWeapon() && (item.getWeaponItem().getItemType() != WeaponType.FISHINGROD) && ((item.getWeaponItem().getItemType() != WeaponType.SWORD) || (item.getTemplate().getBodyPart() == ItemTemplate.SLOT_LR_HAND)))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIRED_CONDITION_TO_EQUIP_THAT_ITEM);
|
||||
return;
|
||||
|
||||
+4
@@ -229,6 +229,8 @@ public class RequestShapeShiftingItem implements ClientPacket
|
||||
}
|
||||
case FIXED:
|
||||
{
|
||||
targetItem.removeVisualSetSkills();
|
||||
|
||||
if (appearanceStone.getVisualIds().isEmpty())
|
||||
{
|
||||
extracItemId = appearanceStone.getVisualId();
|
||||
@@ -245,6 +247,8 @@ public class RequestShapeShiftingItem implements ClientPacket
|
||||
targetItem.getVariables().set(ItemVariables.VISUAL_APPEARANCE_STONE_ID, appearanceStone.getId());
|
||||
}
|
||||
}
|
||||
|
||||
targetItem.applyVisualSetSkills();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -99,10 +99,6 @@ public class RequestEnchantItem implements ClientPacket
|
||||
player.removeRequest(request.getClass());
|
||||
return;
|
||||
}
|
||||
if (item.getEnchantLevel() != request.getEnchantLevel())
|
||||
{
|
||||
item.setEnchantLevel(request.getEnchantLevel());
|
||||
}
|
||||
|
||||
// Template for scroll.
|
||||
final EnchantScroll scrollTemplate = EnchantItemData.getInstance().getEnchantScroll(scroll);
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class RequestHeroBookEnchant implements ClientPacket
|
||||
@Override
|
||||
public void run(GameClient client)
|
||||
{
|
||||
Player player = client.getPlayer();
|
||||
final Player player = client.getPlayer();
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
|
||||
+38
-20
@@ -112,26 +112,9 @@ public class RequestHuntPassReward implements ClientPacket
|
||||
return;
|
||||
}
|
||||
|
||||
// Normal reward.
|
||||
if (!huntPass.isPremium() && (rewardIndex <= HuntPassData.getInstance().getRewardsCount()))
|
||||
{
|
||||
rewardItem(player, HuntPassData.getInstance().getRewards().get(rewardIndex));
|
||||
huntPass.setRewardStep(rewardIndex + 1);
|
||||
}
|
||||
// Premium reward.
|
||||
else if (huntPass.isPremium())
|
||||
{
|
||||
if ((rewardIndex < HuntPassData.getInstance().getRewardsCount()) && (rewardIndex <= premiumRewardIndex))
|
||||
{
|
||||
rewardItem(player, HuntPassData.getInstance().getRewards().get(rewardIndex));
|
||||
huntPass.setRewardStep(rewardIndex + 1);
|
||||
}
|
||||
else if ((premiumRewardIndex < rewardIndex) && (premiumRewardIndex <= HuntPassData.getInstance().getPremiumRewardsCount()))
|
||||
{
|
||||
rewardItem(player, HuntPassData.getInstance().getPremiumRewards().get(premiumRewardIndex));
|
||||
huntPass.setPremiumRewardStep(premiumRewardIndex + 1);
|
||||
}
|
||||
}
|
||||
normalReward(player);
|
||||
premiumReward(player);
|
||||
huntPass.setRewardStep(rewardIndex + 1);
|
||||
huntPass.setRewardAlert(false);
|
||||
|
||||
player.sendPacket(new HuntPassInfo(player, _huntPassType));
|
||||
@@ -157,4 +140,39 @@ public class RequestHuntPassReward implements ClientPacket
|
||||
player.addItem("HuntPassReward", reward, player, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void premiumReward(Player player)
|
||||
{
|
||||
final HuntPass huntPass = player.getHuntPass();
|
||||
final int premiumRewardIndex = huntPass.getPremiumRewardStep();
|
||||
if (premiumRewardIndex >= HuntPassData.getInstance().getPremiumRewardsCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!huntPass.isPremium())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rewardItem(player, HuntPassData.getInstance().getPremiumRewards().get(premiumRewardIndex));
|
||||
huntPass.setPremiumRewardStep(premiumRewardIndex + 1);
|
||||
}
|
||||
|
||||
private void normalReward(Player player)
|
||||
{
|
||||
final HuntPass huntPass = player.getHuntPass();
|
||||
final int rewardIndex = huntPass.getRewardStep();
|
||||
if (rewardIndex >= HuntPassData.getInstance().getRewardsCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (huntPass.isPremium() && ((huntPass.getPremiumRewardStep() < rewardIndex) || (huntPass.getPremiumRewardStep() >= HuntPassData.getInstance().getPremiumRewardsCount())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rewardItem(player, HuntPassData.getInstance().getRewards().get(rewardIndex));
|
||||
}
|
||||
}
|
||||
|
||||
+38
-20
@@ -115,26 +115,9 @@ public class RequestHuntPassRewardAll implements ClientPacket
|
||||
break REWARD_LOOP;
|
||||
}
|
||||
|
||||
// Normal reward.
|
||||
if (!huntPass.isPremium() && (rewardIndex <= HuntPassData.getInstance().getRewardsCount()))
|
||||
{
|
||||
rewardItem(player, HuntPassData.getInstance().getRewards().get(rewardIndex));
|
||||
huntPass.setRewardStep(rewardIndex + 1);
|
||||
}
|
||||
// Premium reward.
|
||||
else if (huntPass.isPremium())
|
||||
{
|
||||
if ((rewardIndex < HuntPassData.getInstance().getRewardsCount()) && (rewardIndex <= premiumRewardIndex))
|
||||
{
|
||||
rewardItem(player, HuntPassData.getInstance().getRewards().get(rewardIndex));
|
||||
huntPass.setRewardStep(rewardIndex + 1);
|
||||
}
|
||||
else if ((premiumRewardIndex < rewardIndex) && (premiumRewardIndex <= HuntPassData.getInstance().getPremiumRewardsCount()))
|
||||
{
|
||||
rewardItem(player, HuntPassData.getInstance().getPremiumRewards().get(premiumRewardIndex));
|
||||
huntPass.setPremiumRewardStep(premiumRewardIndex + 1);
|
||||
}
|
||||
}
|
||||
normalReward(player);
|
||||
premiumReward(player);
|
||||
huntPass.setRewardStep(rewardIndex + 1);
|
||||
}
|
||||
|
||||
if (!inventoryLimitReached)
|
||||
@@ -165,4 +148,39 @@ public class RequestHuntPassRewardAll implements ClientPacket
|
||||
player.addItem("HuntPassReward", reward, player, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void premiumReward(Player player)
|
||||
{
|
||||
final HuntPass huntPass = player.getHuntPass();
|
||||
final int premiumRewardIndex = huntPass.getPremiumRewardStep();
|
||||
if (premiumRewardIndex >= HuntPassData.getInstance().getPremiumRewardsCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!huntPass.isPremium())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rewardItem(player, HuntPassData.getInstance().getPremiumRewards().get(premiumRewardIndex));
|
||||
huntPass.setPremiumRewardStep(premiumRewardIndex + 1);
|
||||
}
|
||||
|
||||
private void normalReward(Player player)
|
||||
{
|
||||
final HuntPass huntPass = player.getHuntPass();
|
||||
final int rewardIndex = huntPass.getRewardStep();
|
||||
if (rewardIndex >= HuntPassData.getInstance().getRewardsCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (huntPass.isPremium() && ((huntPass.getPremiumRewardStep() < rewardIndex) || (huntPass.getPremiumRewardStep() >= HuntPassData.getInstance().getPremiumRewardsCount())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rewardItem(player, HuntPassData.getInstance().getRewards().get(rewardIndex));
|
||||
}
|
||||
}
|
||||
|
||||
+26
-3
@@ -147,6 +147,25 @@ public class RequestPurchaseLimitShopItemBuy implements ClientPacket
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (_product.getAccountMontlyLimit() > 0)
|
||||
{
|
||||
final long amount = _product.getAccountMontlyLimit() * _amount;
|
||||
if (amount < 1)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.INCORRECT_ITEM_COUNT_2);
|
||||
player.removeRequest(PrimeShopRequest.class);
|
||||
player.sendPacket(new ExPurchaseLimitShopItemResult(false, _shopIndex, _productId, 0, Collections.emptyList()));
|
||||
return;
|
||||
}
|
||||
if (player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_MONTLY_COUNT + _product.getProductionId(), 0) >= amount)
|
||||
{
|
||||
player.sendMessage("You have reached your montly limit.");
|
||||
player.removeRequest(PrimeShopRequest.class);
|
||||
player.sendPacket(new ExPurchaseLimitShopItemResult(false, _shopIndex, _productId, 0, Collections.emptyList()));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
else if (_product.getAccountBuyLimit() > 0) // Count limit.
|
||||
{
|
||||
final long amount = _product.getAccountBuyLimit() * _amount;
|
||||
@@ -168,7 +187,7 @@ public class RequestPurchaseLimitShopItemBuy implements ClientPacket
|
||||
}
|
||||
|
||||
// Check existing items.
|
||||
final int remainingInfo = Math.max(0, Math.max(_product.getAccountBuyLimit(), _product.getAccountDailyLimit()));
|
||||
final int remainingInfo = Math.max(0, Math.max(_product.getAccountBuyLimit(), Math.max(_product.getAccountDailyLimit(), _product.getAccountMontlyLimit())));
|
||||
for (int i = 0; i < _product.getIngredientIds().length; i++)
|
||||
{
|
||||
if (_product.getIngredientIds()[i] == 0)
|
||||
@@ -315,7 +334,7 @@ public class RequestPurchaseLimitShopItemBuy implements ClientPacket
|
||||
if (Rnd.get(100) < _product.getChance())
|
||||
{
|
||||
rewards.computeIfAbsent(0, k -> new LimitShopRandomCraftReward(_product.getProductionId(), 0, 0)).getCount().addAndGet((int) _product.getCount());
|
||||
final Item item = player.addItem("LCoinShop", _product.getProductionId(), _product.getCount(), player, true);
|
||||
final Item item = player.addItem("LCoinShop", _product.getProductionId(), _product.getCount(), _product.getEnchant(), player, true);
|
||||
if (_product.isAnnounce())
|
||||
{
|
||||
Broadcast.toAllOnlinePlayers(new ExItemAnnounce(player, item, ExItemAnnounce.SPECIAL_CREATION));
|
||||
@@ -362,7 +381,7 @@ public class RequestPurchaseLimitShopItemBuy implements ClientPacket
|
||||
else if (Rnd.get(100) < _product.getChance())
|
||||
{
|
||||
rewards.put(0, new LimitShopRandomCraftReward(_product.getProductionId(), (int) (_product.getCount() * _amount), 0));
|
||||
final Item item = player.addItem("LCoinShop", _product.getProductionId(), _product.getCount() * _amount, player, true);
|
||||
final Item item = player.addItem("LCoinShop", _product.getProductionId(), _product.getCount() * _amount, _product.getEnchant(), player, true);
|
||||
if (_product.isAnnounce())
|
||||
{
|
||||
Broadcast.toAllOnlinePlayers(new ExItemAnnounce(player, item, ExItemAnnounce.SPECIAL_CREATION));
|
||||
@@ -374,6 +393,10 @@ public class RequestPurchaseLimitShopItemBuy implements ClientPacket
|
||||
{
|
||||
player.getAccountVariables().set(AccountVariables.LCOIN_SHOP_PRODUCT_DAILY_COUNT + _product.getProductionId(), player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_DAILY_COUNT + _product.getProductionId(), 0) + _amount);
|
||||
}
|
||||
if (_product.getAccountMontlyLimit() > 0)
|
||||
{
|
||||
player.getAccountVariables().set(AccountVariables.LCOIN_SHOP_PRODUCT_MONTLY_COUNT + _product.getProductionId(), player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_MONTLY_COUNT + _product.getProductionId(), 0) + _amount);
|
||||
}
|
||||
else if (_product.getAccountBuyLimit() > 0)
|
||||
{
|
||||
player.getAccountVariables().set(AccountVariables.LCOIN_SHOP_PRODUCT_COUNT + _product.getProductionId(), player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_COUNT + _product.getProductionId(), 0) + _amount);
|
||||
|
||||
+2
-123
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import org.l2jmobius.gameserver.data.xml.ActionData;
|
||||
import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
|
||||
/**
|
||||
@@ -23,129 +24,7 @@ import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
*/
|
||||
public class ExBasicActionList extends ServerPacket
|
||||
{
|
||||
//@formatter:off
|
||||
public static final int[] ACTIONS_ON_TRANSFORM =
|
||||
{
|
||||
1, 3, 4, 5,
|
||||
6, 7, 8, 9,
|
||||
11, 15, 16, 17,
|
||||
18, 19, 21, 22,
|
||||
23, 32, 36, 39,
|
||||
40, 41, 42, 43,
|
||||
44, 45, 46, 47,
|
||||
48, 50, 52, 53,
|
||||
54, 55, 56, 57,
|
||||
63, 64, 65, 70,
|
||||
86, 1000, 1001, 1003,
|
||||
1004, 1005, 1006, 1007,
|
||||
1008, 1009, 1010, 1011,
|
||||
1012, 1013, 1014, 1015,
|
||||
1016, 1017, 1018, 1019,
|
||||
1020, 1021, 1022, 1023,
|
||||
1024, 1025, 1026, 1027,
|
||||
1028, 1029, 1030, 1031,
|
||||
1032, 1033, 1034, 1035,
|
||||
1036, 1037, 1038, 1039,
|
||||
1040, 1041, 1042, 1043,
|
||||
1044, 1045, 1046, 1047,
|
||||
1048, 1049, 1050, 1051,
|
||||
1052, 1053, 1054, 1055,
|
||||
1056, 1057, 1058, 1059,
|
||||
1060, 1061, 1062, 1063,
|
||||
1064, 1065, 1066, 1067,
|
||||
1068, 1069, 1070, 1071,
|
||||
1072, 1073, 1074, 1075,
|
||||
1076, 1077, 1078, 1079,
|
||||
1080, 1081, 1082, 1083,
|
||||
1084, 1089, 1090, 1091,
|
||||
1092, 1093, 1094, 1095,
|
||||
1096, 1097, 1098, 1099,
|
||||
1100, 1101, 1102, 1103,
|
||||
1104, 1106, 1107, 1108,
|
||||
1109, 1110, 1111, 1113,
|
||||
1114, 1115, 1116, 1117,
|
||||
1118, 1120, 1121, 1124,
|
||||
1125, 1126, 1127, 1128,
|
||||
1129, 1130, 1131, 1132,
|
||||
1133, 1134, 1135, 1136,
|
||||
1137, 1138, 1139, 1140,
|
||||
1141, 1142, 1143, 1144,
|
||||
1145, 1146, 1147, 1148,
|
||||
1149, 1150, 1151, 1152,
|
||||
1153, 1154, 1155
|
||||
};
|
||||
public static final int[] DEFAULT_ACTION_LIST =
|
||||
{
|
||||
0, 1, 2, 3,
|
||||
4, 5, 6, 7,
|
||||
8, 9, 10, 11,
|
||||
12, 13, 14, 15,
|
||||
16, 17, 18, 19,
|
||||
20, 21, 22, 23,
|
||||
24, 25, 26, 27,
|
||||
28, 29, 30, 31,
|
||||
32, 33, 34, 35,
|
||||
36, 37, 38, 39,
|
||||
40, 41, 42, 43,
|
||||
44, 45, 46, 47,
|
||||
48, 49, 50, 51,
|
||||
52, 53, 54, 55,
|
||||
56, 57, 58, 59,
|
||||
60, 61, 62, 63,
|
||||
64, 65, 66, 67,
|
||||
68, 69, 70, 71,
|
||||
72, 73, 74, 76,
|
||||
77, 78, 79, 80,
|
||||
81, 82, 83, 84,
|
||||
85, 86, 87, 88,
|
||||
89, 90, 92, 93,
|
||||
94, 95, 96, 97,
|
||||
1000, 1001,
|
||||
1002, 1003, 1004, 1005,
|
||||
1006, 1007, 1008, 1009,
|
||||
1010, 1011, 1012, 1013,
|
||||
1014, 1015, 1016, 1017,
|
||||
1018, 1019, 1020, 1021,
|
||||
1022, 1023, 1024, 1025,
|
||||
1026, 1027, 1028, 1029,
|
||||
1030, 1031, 1032, 1033,
|
||||
1034, 1035, 1036, 1037,
|
||||
1038, 1039, 1040, 1041,
|
||||
1042, 1043, 1044, 1045,
|
||||
1046, 1047, 1048, 1049,
|
||||
1050, 1051, 1052, 1053,
|
||||
1054, 1055, 1056, 1057,
|
||||
1058, 1059, 1060, 1061,
|
||||
1062, 1063, 1064, 1065,
|
||||
1066, 1067, 1068, 1069,
|
||||
1070, 1071, 1072, 1073,
|
||||
1074, 1075, 1076, 1077,
|
||||
1078, 1079, 1080, 1081,
|
||||
1082, 1083, 1084, 1086,
|
||||
1087, 1088, 1089, 1090,
|
||||
1091, 1092, 1093, 1094,
|
||||
1095, 1096, 1097, 1098,
|
||||
1099, 1100, 1101, 1102,
|
||||
1103, 1104, 1106, 1107,
|
||||
1108, 1109, 1110, 1111,
|
||||
1112, 1113, 1114, 1115,
|
||||
1116, 1117, 1118, 1119,
|
||||
1120, 1121, 1122, 1123,
|
||||
1124, 1125, 1126, 1127,
|
||||
1128, 1129, 1130, 1131,
|
||||
1132, 1133, 1134, 1135,
|
||||
1136, 1137, 1138, 1139,
|
||||
1140, 1141, 1142, 1143,
|
||||
1144, 1145, 1146, 1147,
|
||||
1148, 1149, 1150, 1151,
|
||||
1152, 1153, 1154, 1155,
|
||||
5000, 5001, 5002, 5003,
|
||||
5004, 5005, 5006, 5007,
|
||||
5008, 5009, 5010, 5011,
|
||||
5012, 5013, 5014, 5015
|
||||
};
|
||||
//@formatter:on
|
||||
public static final ExBasicActionList STATIC_PACKET = new ExBasicActionList(DEFAULT_ACTION_LIST);
|
||||
public static final ExBasicActionList STATIC_PACKET = new ExBasicActionList(ActionData.getInstance().getActionIdList());
|
||||
|
||||
private final int[] _actionIds;
|
||||
|
||||
|
||||
+8
-9
@@ -67,7 +67,7 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
_masks[2] |= 0x10;
|
||||
addComponentType(NpcInfoType.NAME);
|
||||
}
|
||||
addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.RELATIONS, NpcInfoType.TITLE, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.ALIVE, NpcInfoType.RUNNING, NpcInfoType.PVP_FLAG);
|
||||
addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.RELATIONS, NpcInfoType.TITLE, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.STOP_MODE, NpcInfoType.MOVE_MODE, NpcInfoType.PVP_FLAG);
|
||||
if (summon.getHeading() > 0)
|
||||
{
|
||||
addComponentType(NpcInfoType.HEADING);
|
||||
@@ -141,7 +141,7 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
_allyId = summon.getOwner().getAppearance().getVisibleAllyCrestId();
|
||||
addComponentType(NpcInfoType.CLAN);
|
||||
}
|
||||
addComponentType(NpcInfoType.COLOR_EFFECT);
|
||||
addComponentType(NpcInfoType.PET_EVOLUTION_ID);
|
||||
// TODO: Confirm me
|
||||
if (summon.isInCombat())
|
||||
{
|
||||
@@ -240,9 +240,9 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeInt(_summon.getHeading());
|
||||
}
|
||||
if (containsMask(NpcInfoType.UNKNOWN2))
|
||||
if (containsMask(NpcInfoType.VEHICLE_ID))
|
||||
{
|
||||
writeInt(0); // Unknown
|
||||
writeInt(0); // Vehicle object id.
|
||||
}
|
||||
if (containsMask(NpcInfoType.ATK_CAST_SPEED))
|
||||
{
|
||||
@@ -260,11 +260,11 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
writeInt(_summon.getArmor()); // Armor id?
|
||||
writeInt(0);
|
||||
}
|
||||
if (containsMask(NpcInfoType.ALIVE))
|
||||
if (containsMask(NpcInfoType.STOP_MODE))
|
||||
{
|
||||
writeByte(!_summon.isDead());
|
||||
}
|
||||
if (containsMask(NpcInfoType.RUNNING))
|
||||
if (containsMask(NpcInfoType.MOVE_MODE))
|
||||
{
|
||||
writeByte(_summon.isRunning());
|
||||
}
|
||||
@@ -288,9 +288,8 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeInt(0); // Player ObjectId with Decoy
|
||||
}
|
||||
if (containsMask(NpcInfoType.COLOR_EFFECT))
|
||||
if (containsMask(NpcInfoType.PET_EVOLUTION_ID))
|
||||
{
|
||||
// No visual effect
|
||||
writeInt(0); // Unknown
|
||||
}
|
||||
if (containsMask(NpcInfoType.DISPLAY_EFFECT))
|
||||
@@ -321,7 +320,7 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeByte(_summon.isShowSummonAnimation() ? 2 : 0); // 2 - do some animation on spawn
|
||||
}
|
||||
if (containsMask(NpcInfoType.UNKNOWN12))
|
||||
if (containsMask(NpcInfoType.FOLLOW_INFO))
|
||||
{
|
||||
writeInt(0);
|
||||
writeInt(0);
|
||||
|
||||
+4
-24
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.enums.BonusExpType;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.stats.Stat;
|
||||
@@ -45,31 +46,10 @@ public class ExUserBoostStat extends ServerPacket
|
||||
{
|
||||
case VITALITY:
|
||||
{
|
||||
final int currentVitalityPoints = _player.getStat().getVitalityPoints();
|
||||
if (currentVitalityPoints > 105000)
|
||||
if (_player.getStat().getVitalityPoints() > 0)
|
||||
{
|
||||
count = 1;
|
||||
bonus = 300;
|
||||
}
|
||||
else if (currentVitalityPoints > 70000)
|
||||
{
|
||||
count = 1;
|
||||
bonus = 250;
|
||||
}
|
||||
else if (currentVitalityPoints > 35000)
|
||||
{
|
||||
count = 1;
|
||||
bonus = 200;
|
||||
}
|
||||
else if (currentVitalityPoints > 0)
|
||||
{
|
||||
count = 1;
|
||||
bonus = 100;
|
||||
}
|
||||
if (bonus > 0)
|
||||
{
|
||||
count += (int) _player.getStat().getValue(Stat.VITALITY_SKILLS, 0);
|
||||
bonus += (int) ((_player.getStat().getMul(Stat.VITALITY_EXP_RATE, 1) - 1) * 100);
|
||||
count = (int) (_player.getStat().getValue(Stat.VITALITY_SKILLS, 0) + 1);
|
||||
bonus = (int) (((_player.getStat().getMul(Stat.VITALITY_EXP_RATE, 1) - 1) + (_player.hasPremiumStatus() ? Config.RATE_VITALITY_EXP_PREMIUM_MULTIPLIER : Config.RATE_VITALITY_EXP_MULTIPLIER)) * 100d);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+5
-2
@@ -18,6 +18,7 @@ package org.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.stats.Stat;
|
||||
import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
|
||||
/**
|
||||
@@ -26,13 +27,15 @@ import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
public class ExVitalityEffectInfo extends ServerPacket
|
||||
{
|
||||
private final int _vitalityBonus;
|
||||
private final int _vitalityAddBonus;
|
||||
private final int _vitalityItemsRemaining;
|
||||
private final int _points;
|
||||
|
||||
public ExVitalityEffectInfo(Player player)
|
||||
{
|
||||
_points = player.getVitalityPoints();
|
||||
_vitalityBonus = (int) player.getStat().getVitalityExpBonus() * 100;
|
||||
_vitalityBonus = (int) ((player.getStat().getMul(Stat.VITALITY_EXP_RATE, 1) - 1) + (player.hasPremiumStatus() ? Config.RATE_VITALITY_EXP_PREMIUM_MULTIPLIER : Config.RATE_VITALITY_EXP_MULTIPLIER)) * 100;
|
||||
_vitalityAddBonus = (int) ((player.getStat().getMul(Stat.VITALITY_EXP_RATE, 1) - 1) * 100);
|
||||
_vitalityItemsRemaining = Config.VITALITY_MAX_ITEMS_ALLOWED - player.getVitalityItemsUsed();
|
||||
}
|
||||
|
||||
@@ -42,7 +45,7 @@ public class ExVitalityEffectInfo extends ServerPacket
|
||||
ServerPackets.EX_VITALITY_EFFECT_INFO.writeId(this);
|
||||
writeInt(_points);
|
||||
writeInt(_vitalityBonus); // Vitality Bonus
|
||||
writeShort(0); // Vitality additional bonus in %
|
||||
writeShort(_vitalityAddBonus); // Vitality additional bonus in %
|
||||
writeShort(_vitalityItemsRemaining); // How much vitality items remaining for use
|
||||
writeShort(Config.VITALITY_MAX_ITEMS_ALLOWED); // Max number of items for use
|
||||
}
|
||||
|
||||
+1
-1
@@ -167,7 +167,7 @@ public class FakePlayerInfo extends ServerPacket
|
||||
writeByte(_npc.getTeam().getId());
|
||||
writeInt(_clan != null ? _clan.getCrestLargeId() : 0);
|
||||
writeByte(_fpcHolder.getNobleLevel());
|
||||
writeByte(_fpcHolder.isHero());
|
||||
writeByte(_fpcHolder.isHero() ? 2 : 0); // 152 - Value for enabled changed to 2
|
||||
writeByte(_fpcHolder.isFishing());
|
||||
writeInt(_fpcHolder.getBaitLocationX());
|
||||
writeInt(_fpcHolder.getBaitLocationY());
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ public class MultiSellList extends AbstractItemPacket
|
||||
}
|
||||
writeLong(_list.getProductCount(product));
|
||||
writeShort(product.getEnchantmentLevel() > 0 ? product.getEnchantmentLevel() : displayItemEnchantment != null ? displayItemEnchantment.getEnchantLevel() : 0); // enchant level
|
||||
writeInt((int) product.getChance() * 1000000); // chance
|
||||
writeInt((int) (product.getChance() * 1000000)); // chance
|
||||
writeItemAugment(displayItemEnchantment);
|
||||
writeItemElemental(displayItemEnchantment);
|
||||
writeItemEnsoulOptions(displayItemEnchantment);
|
||||
|
||||
+9
-9
@@ -61,7 +61,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
_npc = npc;
|
||||
_abnormalVisualEffects = npc.getEffectList().getCurrentAbnormalVisualEffects();
|
||||
addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.RELATIONS, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.ALIVE, NpcInfoType.RUNNING);
|
||||
addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.RELATIONS, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.STOP_MODE, NpcInfoType.MOVE_MODE);
|
||||
if (npc.getHeading() > 0)
|
||||
{
|
||||
addComponentType(NpcInfoType.HEADING);
|
||||
@@ -170,7 +170,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
addComponentType(NpcInfoType.CLAN);
|
||||
}
|
||||
}
|
||||
addComponentType(NpcInfoType.COLOR_EFFECT);
|
||||
addComponentType(NpcInfoType.PET_EVOLUTION_ID);
|
||||
if (npc.getPvpFlag() > 0)
|
||||
{
|
||||
addComponentType(NpcInfoType.PVP_FLAG);
|
||||
@@ -330,9 +330,9 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeInt(_npc.getHeading());
|
||||
}
|
||||
if (containsMask(NpcInfoType.UNKNOWN2))
|
||||
if (containsMask(NpcInfoType.VEHICLE_ID))
|
||||
{
|
||||
writeInt(0); // Unknown
|
||||
writeInt(0); // Vehicle object id.
|
||||
}
|
||||
if (containsMask(NpcInfoType.ATK_CAST_SPEED))
|
||||
{
|
||||
@@ -350,11 +350,11 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
writeInt(0); // Armor id?
|
||||
writeInt(_npc.getLeftHandItem());
|
||||
}
|
||||
if (containsMask(NpcInfoType.ALIVE))
|
||||
if (containsMask(NpcInfoType.STOP_MODE))
|
||||
{
|
||||
writeByte(!_npc.isDead());
|
||||
}
|
||||
if (containsMask(NpcInfoType.RUNNING))
|
||||
if (containsMask(NpcInfoType.MOVE_MODE))
|
||||
{
|
||||
writeByte(_npc.isRunning());
|
||||
}
|
||||
@@ -378,9 +378,9 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeInt(_npc.getCloneObjId()); // Player ObjectId with Decoy
|
||||
}
|
||||
if (containsMask(NpcInfoType.COLOR_EFFECT))
|
||||
if (containsMask(NpcInfoType.PET_EVOLUTION_ID))
|
||||
{
|
||||
writeInt(_npc.getColorEffect()); // Color effect
|
||||
writeInt(0); // Unknown
|
||||
}
|
||||
if (containsMask(NpcInfoType.DISPLAY_EFFECT))
|
||||
{
|
||||
@@ -410,7 +410,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeByte(0); // 2 - do some animation on spawn
|
||||
}
|
||||
if (containsMask(NpcInfoType.UNKNOWN12))
|
||||
if (containsMask(NpcInfoType.FOLLOW_INFO))
|
||||
{
|
||||
writeInt(0);
|
||||
writeInt(0);
|
||||
|
||||
+200
-201
@@ -1,201 +1,200 @@
|
||||
/*
|
||||
* 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 org.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.enums.Team;
|
||||
import org.l2jmobius.gameserver.model.actor.Summon;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.Pet;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.Servitor;
|
||||
import org.l2jmobius.gameserver.model.skill.AbnormalVisualEffect;
|
||||
import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
import org.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
|
||||
public class PetInfo extends ServerPacket
|
||||
{
|
||||
private final Summon _summon;
|
||||
private final int _value;
|
||||
private final int _runSpd;
|
||||
private final int _walkSpd;
|
||||
private final int _swimRunSpd;
|
||||
private final int _swimWalkSpd;
|
||||
private final int _flRunSpd = 0;
|
||||
private final int _flWalkSpd = 0;
|
||||
private final int _flyRunSpd;
|
||||
private final int _flyWalkSpd;
|
||||
private final double _moveMultiplier;
|
||||
private int _maxFed;
|
||||
private int _curFed;
|
||||
private int _statusMask = 0;
|
||||
|
||||
public PetInfo(Summon summon, int value)
|
||||
{
|
||||
_summon = summon;
|
||||
_moveMultiplier = summon.getMovementSpeedMultiplier();
|
||||
_runSpd = (int) Math.round(summon.getRunSpeed() / _moveMultiplier);
|
||||
_walkSpd = (int) Math.round(summon.getWalkSpeed() / _moveMultiplier);
|
||||
_swimRunSpd = (int) Math.round(summon.getSwimRunSpeed() / _moveMultiplier);
|
||||
_swimWalkSpd = (int) Math.round(summon.getSwimWalkSpeed() / _moveMultiplier);
|
||||
_flyRunSpd = summon.isFlying() ? _runSpd : 0;
|
||||
_flyWalkSpd = summon.isFlying() ? _walkSpd : 0;
|
||||
_value = value;
|
||||
if (summon.isPet())
|
||||
{
|
||||
final Pet pet = (Pet) _summon;
|
||||
_curFed = pet.getCurrentFed(); // how fed it is
|
||||
_maxFed = pet.getMaxFed(); // max fed it can be
|
||||
}
|
||||
else if (summon.isServitor())
|
||||
{
|
||||
final Servitor sum = (Servitor) _summon;
|
||||
_curFed = sum.getLifeTimeRemaining();
|
||||
_maxFed = sum.getLifeTime();
|
||||
}
|
||||
if (summon.isBetrayed())
|
||||
{
|
||||
_statusMask |= 0x01; // Auto attackable status
|
||||
}
|
||||
_statusMask |= 0x02; // can be chatted with
|
||||
if (summon.isRunning())
|
||||
{
|
||||
_statusMask |= 0x04;
|
||||
}
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(summon))
|
||||
{
|
||||
_statusMask |= 0x08;
|
||||
}
|
||||
if (summon.isDead())
|
||||
{
|
||||
_statusMask |= 0x10;
|
||||
}
|
||||
if (summon.isMountable())
|
||||
{
|
||||
_statusMask |= 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write()
|
||||
{
|
||||
ServerPackets.PET_INFO.writeId(this);
|
||||
writeByte(_summon.getSummonType());
|
||||
writeInt(_summon.getObjectId());
|
||||
writeInt(_summon.getTemplate().getDisplayId() + 1000000);
|
||||
writeInt(_summon.getX());
|
||||
writeInt(_summon.getY());
|
||||
writeInt(_summon.getZ());
|
||||
writeInt(_summon.getHeading());
|
||||
writeInt(_summon.getStat().getMAtkSpd());
|
||||
writeInt(_summon.getStat().getPAtkSpd());
|
||||
writeShort(_runSpd);
|
||||
writeShort(_walkSpd);
|
||||
writeShort(_swimRunSpd);
|
||||
writeShort(_swimWalkSpd);
|
||||
writeShort(_flRunSpd);
|
||||
writeShort(_flWalkSpd);
|
||||
writeShort(_flyRunSpd);
|
||||
writeShort(_flyWalkSpd);
|
||||
writeDouble(_moveMultiplier);
|
||||
writeDouble(_summon.getAttackSpeedMultiplier()); // attack speed multiplier
|
||||
writeDouble(_summon.getTemplate().getFCollisionRadius());
|
||||
writeDouble(_summon.getTemplate().getFCollisionHeight());
|
||||
writeInt(_summon.getWeapon()); // right hand weapon
|
||||
writeInt(_summon.getArmor()); // body armor
|
||||
writeInt(0); // left hand weapon
|
||||
writeByte(_summon.isShowSummonAnimation() ? 2 : _value); // 0=teleported 1=default 2=summoned
|
||||
writeInt(-1); // High Five NPCString ID
|
||||
if (_summon.isPet())
|
||||
{
|
||||
writeString(_summon.getName()); // Pet name.
|
||||
}
|
||||
else
|
||||
{
|
||||
writeString(_summon.getTemplate().isUsingServerSideName() ? _summon.getName() : ""); // Summon name.
|
||||
}
|
||||
writeInt(-1); // High Five NPCString ID
|
||||
writeString(_summon.getTitle()); // owner name
|
||||
writeByte(_summon.getPvpFlag()); // confirmed
|
||||
writeInt(_summon.getReputation()); // confirmed
|
||||
writeInt(_curFed); // how fed it is
|
||||
writeInt(_maxFed); // max fed it can be
|
||||
writeInt((int) _summon.getCurrentHp()); // current hp
|
||||
writeInt(_summon.getMaxHp()); // max hp
|
||||
writeInt((int) _summon.getCurrentMp()); // current mp
|
||||
writeInt(_summon.getMaxMp()); // max mp
|
||||
writeLong(_summon.getStat().getSp()); // sp
|
||||
writeByte(_summon.getLevel()); // level
|
||||
writeLong(_summon.getStat().getExp());
|
||||
if (_summon.getExpForThisLevel() > _summon.getStat().getExp())
|
||||
{
|
||||
writeLong(_summon.getStat().getExp()); // 0% absolute value
|
||||
}
|
||||
else
|
||||
{
|
||||
writeLong(_summon.getExpForThisLevel()); // 0% absolute value
|
||||
}
|
||||
writeLong(_summon.getExpForNextLevel()); // 100% absoulte value
|
||||
writeByte(0); // 286
|
||||
writeInt(_summon.isPet() ? _summon.getInventory().getTotalWeight() : 0); // weight
|
||||
writeInt(_summon.getMaxLoad()); // max weight it can carry
|
||||
writeInt(_summon.getPAtk()); // patk
|
||||
writeInt(_summon.getPDef()); // pdef
|
||||
writeInt(_summon.getAccuracy()); // accuracy
|
||||
writeInt(_summon.getEvasionRate()); // evasion
|
||||
writeInt(_summon.getCriticalHit()); // critical
|
||||
writeInt(_summon.getMAtk()); // matk
|
||||
writeInt(_summon.getMDef()); // mdef
|
||||
writeInt(_summon.getMagicAccuracy()); // magic accuracy
|
||||
writeInt(_summon.getMagicEvasionRate()); // magic evasion
|
||||
writeInt(_summon.getMCriticalHit()); // mcritical
|
||||
writeInt((int) _summon.getStat().getMoveSpeed()); // speed
|
||||
writeInt(_summon.getPAtkSpd()); // atkspeed
|
||||
writeInt(_summon.getMAtkSpd()); // casting speed
|
||||
writeByte(0); // TODO: Check me, might be ride status
|
||||
writeByte(_summon.getTeam().getId()); // Confirmed
|
||||
writeByte(_summon.getSoulShotsPerHit()); // How many soulshots this servitor uses per hit - Confirmed
|
||||
writeByte(_summon.getSpiritShotsPerHit()); // How many spiritshots this servitor uses per hit - - Confirmed
|
||||
writeInt(0); // TODO: Find me
|
||||
writeInt(0); // "Transformation ID - Confirmed" - Used to bug Fenrir after 64 level.
|
||||
writeByte(_summon.getOwner().getSummonPoints()); // Used Summon Points
|
||||
writeByte(_summon.getOwner().getMaxSummonPoints()); // Maximum Summon Points
|
||||
final Set<AbnormalVisualEffect> aves = _summon.getEffectList().getCurrentAbnormalVisualEffects();
|
||||
final Team team = (Config.BLUE_TEAM_ABNORMAL_EFFECT != null) && (Config.RED_TEAM_ABNORMAL_EFFECT != null) ? _summon.getTeam() : Team.NONE;
|
||||
writeShort(aves.size() + (_summon.isInvisible() ? 1 : 0) + (team != Team.NONE ? 1 : 0)); // Confirmed
|
||||
for (AbnormalVisualEffect ave : aves)
|
||||
{
|
||||
writeShort(ave.getClientId()); // Confirmed
|
||||
}
|
||||
if (_summon.isInvisible())
|
||||
{
|
||||
writeShort(AbnormalVisualEffect.STEALTH.getClientId());
|
||||
}
|
||||
if (team == Team.BLUE)
|
||||
{
|
||||
if (Config.BLUE_TEAM_ABNORMAL_EFFECT != null)
|
||||
{
|
||||
writeShort(Config.BLUE_TEAM_ABNORMAL_EFFECT.getClientId());
|
||||
}
|
||||
}
|
||||
else if ((team == Team.RED) && (Config.RED_TEAM_ABNORMAL_EFFECT != null))
|
||||
{
|
||||
writeShort(Config.RED_TEAM_ABNORMAL_EFFECT.getClientId());
|
||||
}
|
||||
writeByte(_statusMask);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 org.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.l2jmobius.Config;
|
||||
import org.l2jmobius.gameserver.enums.Team;
|
||||
import org.l2jmobius.gameserver.model.actor.Summon;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.Pet;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.Servitor;
|
||||
import org.l2jmobius.gameserver.model.skill.AbnormalVisualEffect;
|
||||
import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
import org.l2jmobius.gameserver.taskmanager.AttackStanceTaskManager;
|
||||
|
||||
public class PetSummonInfo extends ServerPacket
|
||||
{
|
||||
private final Summon _summon;
|
||||
private final int _value;
|
||||
private final int _runSpd;
|
||||
private final int _walkSpd;
|
||||
private final int _swimRunSpd;
|
||||
private final int _swimWalkSpd;
|
||||
private final int _flRunSpd = 0;
|
||||
private final int _flWalkSpd = 0;
|
||||
private final int _flyRunSpd;
|
||||
private final int _flyWalkSpd;
|
||||
private final double _moveMultiplier;
|
||||
private int _maxFed;
|
||||
private int _curFed;
|
||||
private int _statusMask = 0;
|
||||
|
||||
public PetSummonInfo(Summon summon, int value)
|
||||
{
|
||||
_summon = summon;
|
||||
_moveMultiplier = summon.getMovementSpeedMultiplier();
|
||||
_runSpd = (int) Math.round(summon.getRunSpeed() / _moveMultiplier);
|
||||
_walkSpd = (int) Math.round(summon.getWalkSpeed() / _moveMultiplier);
|
||||
_swimRunSpd = (int) Math.round(summon.getSwimRunSpeed() / _moveMultiplier);
|
||||
_swimWalkSpd = (int) Math.round(summon.getSwimWalkSpeed() / _moveMultiplier);
|
||||
_flyRunSpd = summon.isFlying() ? _runSpd : 0;
|
||||
_flyWalkSpd = summon.isFlying() ? _walkSpd : 0;
|
||||
_value = value;
|
||||
if (summon.isPet())
|
||||
{
|
||||
final Pet pet = (Pet) _summon;
|
||||
_curFed = pet.getCurrentFed(); // how fed it is
|
||||
_maxFed = pet.getMaxFed(); // max fed it can be
|
||||
}
|
||||
else if (summon.isServitor())
|
||||
{
|
||||
final Servitor sum = (Servitor) _summon;
|
||||
_curFed = sum.getLifeTimeRemaining();
|
||||
_maxFed = sum.getLifeTime();
|
||||
}
|
||||
if (summon.isBetrayed())
|
||||
{
|
||||
_statusMask |= 0x01; // Auto attackable status
|
||||
}
|
||||
_statusMask |= 0x02; // can be chatted with
|
||||
if (summon.isRunning())
|
||||
{
|
||||
_statusMask |= 0x04;
|
||||
}
|
||||
if (AttackStanceTaskManager.getInstance().hasAttackStanceTask(summon))
|
||||
{
|
||||
_statusMask |= 0x08;
|
||||
}
|
||||
if (summon.isDead())
|
||||
{
|
||||
_statusMask |= 0x10;
|
||||
}
|
||||
if (summon.isMountable())
|
||||
{
|
||||
_statusMask |= 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write()
|
||||
{
|
||||
ServerPackets.PET_INFO.writeId(this);
|
||||
writeByte(_summon.getSummonType());
|
||||
writeInt(_summon.getObjectId());
|
||||
writeInt(_summon.getTemplate().getDisplayId() + 1000000);
|
||||
writeInt(_summon.getX());
|
||||
writeInt(_summon.getY());
|
||||
writeInt(_summon.getZ());
|
||||
writeInt(_summon.getHeading());
|
||||
writeInt(_summon.getStat().getMAtkSpd());
|
||||
writeInt(_summon.getStat().getPAtkSpd());
|
||||
writeShort(_runSpd);
|
||||
writeShort(_walkSpd);
|
||||
writeShort(_swimRunSpd);
|
||||
writeShort(_swimWalkSpd);
|
||||
writeShort(_flRunSpd);
|
||||
writeShort(_flWalkSpd);
|
||||
writeShort(_flyRunSpd);
|
||||
writeShort(_flyWalkSpd);
|
||||
writeDouble(_moveMultiplier);
|
||||
writeDouble(_summon.getAttackSpeedMultiplier()); // attack speed multiplier
|
||||
writeDouble(_summon.getTemplate().getFCollisionRadius());
|
||||
writeDouble(_summon.getTemplate().getFCollisionHeight());
|
||||
writeInt(_summon.getWeapon()); // right hand weapon
|
||||
writeInt(_summon.getArmor()); // body armor
|
||||
writeInt(0); // left hand weapon
|
||||
writeByte(_summon.isShowSummonAnimation() ? 2 : _value); // 0=teleported 1=default 2=summoned
|
||||
writeInt(-1); // High Five NPCString ID
|
||||
if (_summon.isPet())
|
||||
{
|
||||
writeString(_summon.getName()); // Pet name.
|
||||
}
|
||||
else
|
||||
{
|
||||
writeString(_summon.getTemplate().isUsingServerSideName() ? _summon.getName() : ""); // Summon name.
|
||||
}
|
||||
writeInt(-1); // High Five NPCString ID
|
||||
writeString(_summon.getTitle()); // owner name
|
||||
writeByte(_summon.getPvpFlag()); // confirmed
|
||||
writeInt(_summon.getReputation()); // confirmed
|
||||
writeInt(_curFed); // how fed it is
|
||||
writeInt(_maxFed); // max fed it can be
|
||||
writeInt((int) _summon.getCurrentHp()); // current hp
|
||||
writeInt(_summon.getMaxHp()); // max hp
|
||||
writeInt((int) _summon.getCurrentMp()); // current mp
|
||||
writeInt(_summon.getMaxMp()); // max mp
|
||||
writeLong(_summon.getStat().getSp()); // sp
|
||||
writeShort(_summon.getLevel()); // level
|
||||
writeLong(_summon.getStat().getExp());
|
||||
if (_summon.getExpForThisLevel() > _summon.getStat().getExp())
|
||||
{
|
||||
writeLong(_summon.getStat().getExp()); // 0% absolute value
|
||||
}
|
||||
else
|
||||
{
|
||||
writeLong(_summon.getExpForThisLevel()); // 0% absolute value
|
||||
}
|
||||
writeLong(_summon.getExpForNextLevel()); // 100% absoulte value
|
||||
writeInt(_summon.isPet() ? _summon.getInventory().getTotalWeight() : 0); // weight
|
||||
writeInt(_summon.getMaxLoad()); // max weight it can carry
|
||||
writeInt(_summon.getPAtk()); // patk
|
||||
writeInt(_summon.getPDef()); // pdef
|
||||
writeInt(_summon.getAccuracy()); // accuracy
|
||||
writeInt(_summon.getEvasionRate()); // evasion
|
||||
writeInt(_summon.getCriticalHit()); // critical
|
||||
writeInt(_summon.getMAtk()); // matk
|
||||
writeInt(_summon.getMDef()); // mdef
|
||||
writeInt(_summon.getMagicAccuracy()); // magic accuracy
|
||||
writeInt(_summon.getMagicEvasionRate()); // magic evasion
|
||||
writeInt(_summon.getMCriticalHit()); // mcritical
|
||||
writeInt((int) _summon.getStat().getMoveSpeed()); // speed
|
||||
writeInt(_summon.getPAtkSpd()); // atkspeed
|
||||
writeInt(_summon.getMAtkSpd()); // casting speed
|
||||
writeByte(0); // TODO: Check me, might be ride status
|
||||
writeByte(_summon.getTeam().getId()); // Confirmed
|
||||
writeByte(_summon.getSoulShotsPerHit()); // How many soulshots this servitor uses per hit - Confirmed
|
||||
writeByte(_summon.getSpiritShotsPerHit()); // How many spiritshots this servitor uses per hit - - Confirmed
|
||||
writeInt(0); // TODO: Find me
|
||||
writeInt(0); // "Transformation ID - Confirmed" - Used to bug Fenrir after 64 level.
|
||||
writeByte(_summon.getOwner().getSummonPoints()); // Used Summon Points
|
||||
writeByte(_summon.getOwner().getMaxSummonPoints()); // Maximum Summon Points
|
||||
final Set<AbnormalVisualEffect> aves = _summon.getEffectList().getCurrentAbnormalVisualEffects();
|
||||
final Team team = (Config.BLUE_TEAM_ABNORMAL_EFFECT != null) && (Config.RED_TEAM_ABNORMAL_EFFECT != null) ? _summon.getTeam() : Team.NONE;
|
||||
writeShort(aves.size() + (_summon.isInvisible() ? 1 : 0) + (team != Team.NONE ? 1 : 0)); // Confirmed
|
||||
for (AbnormalVisualEffect ave : aves)
|
||||
{
|
||||
writeShort(ave.getClientId()); // Confirmed
|
||||
}
|
||||
if (_summon.isInvisible())
|
||||
{
|
||||
writeShort(AbnormalVisualEffect.STEALTH.getClientId());
|
||||
}
|
||||
if (team == Team.BLUE)
|
||||
{
|
||||
if (Config.BLUE_TEAM_ABNORMAL_EFFECT != null)
|
||||
{
|
||||
writeShort(Config.BLUE_TEAM_ABNORMAL_EFFECT.getClientId());
|
||||
}
|
||||
}
|
||||
else if ((team == Team.RED) && (Config.RED_TEAM_ABNORMAL_EFFECT != null))
|
||||
{
|
||||
writeShort(Config.RED_TEAM_ABNORMAL_EFFECT.getClientId());
|
||||
}
|
||||
writeByte(_statusMask);
|
||||
}
|
||||
}
|
||||
+21
-7
@@ -19,20 +19,21 @@ package org.l2jmobius.gameserver.network.serverpackets;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.l2jmobius.gameserver.model.Shortcut;
|
||||
import org.l2jmobius.gameserver.model.VariationInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.item.instance.Item;
|
||||
import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
|
||||
public class ShortCutInit extends ServerPacket
|
||||
{
|
||||
private Collection<Shortcut> _shortCuts;
|
||||
private final Player _player;
|
||||
private final Collection<Shortcut> _shortCuts;
|
||||
|
||||
public ShortCutInit(Player player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_player = player;
|
||||
_shortCuts = player.getAllShortCuts();
|
||||
player.restoreAutoShortcutVisual();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,8 +55,21 @@ public class ShortCutInit extends ServerPacket
|
||||
writeInt(sc.getSharedReuseGroup());
|
||||
writeInt(0);
|
||||
writeInt(0);
|
||||
writeLong(0); // Augment id
|
||||
writeInt(0); // Visual id
|
||||
|
||||
final Item item = _player.getInventory().getItemByObjectId(sc.getId());
|
||||
if (item != null)
|
||||
{
|
||||
final VariationInstance augment = item.getAugmentation();
|
||||
writeInt(augment != null ? augment.getOption1Id() : 0); // item augment id
|
||||
writeInt(augment != null ? augment.getOption2Id() : 0); // item augment id
|
||||
writeInt(item.getVisualId()); // visual id
|
||||
}
|
||||
else
|
||||
{
|
||||
writeInt(0);
|
||||
writeInt(0);
|
||||
writeInt(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SKILL:
|
||||
|
||||
+12
-4
@@ -17,18 +17,24 @@
|
||||
package org.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import org.l2jmobius.gameserver.model.Shortcut;
|
||||
import org.l2jmobius.gameserver.model.VariationInstance;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.item.instance.Item;
|
||||
import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
|
||||
public class ShortCutRegister extends ServerPacket
|
||||
{
|
||||
private final Player _player;
|
||||
private final Shortcut _shortcut;
|
||||
|
||||
/**
|
||||
* Register new skill shortcut
|
||||
* @param shortcut
|
||||
* @param player
|
||||
*/
|
||||
public ShortCutRegister(Shortcut shortcut)
|
||||
public ShortCutRegister(Shortcut shortcut, Player player)
|
||||
{
|
||||
_player = player;
|
||||
_shortcut = shortcut;
|
||||
}
|
||||
|
||||
@@ -43,14 +49,16 @@ public class ShortCutRegister extends ServerPacket
|
||||
{
|
||||
case ITEM:
|
||||
{
|
||||
final Item item = _player.getInventory().getItemByObjectId(_shortcut.getId());
|
||||
final VariationInstance augment = item.getAugmentation();
|
||||
writeInt(_shortcut.getId());
|
||||
writeInt(_shortcut.getCharacterType());
|
||||
writeInt(_shortcut.getSharedReuseGroup());
|
||||
writeInt(0); // unknown
|
||||
writeInt(0); // unknown
|
||||
writeInt(0); // item augment id
|
||||
writeInt(0); // item augment id
|
||||
writeInt(0); // visual id
|
||||
writeInt(augment != null ? augment.getOption1Id() : 0); // item augment id
|
||||
writeInt(augment != null ? augment.getOption2Id() : 0); // item augment id
|
||||
writeInt(item.getVisualId()); // visual id
|
||||
break;
|
||||
}
|
||||
case SKILL:
|
||||
|
||||
+63
-48
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.network.serverpackets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.l2jmobius.gameserver.data.sql.ClanTable;
|
||||
import org.l2jmobius.gameserver.enums.SiegeClanType;
|
||||
import org.l2jmobius.gameserver.model.SiegeClan;
|
||||
@@ -44,7 +47,7 @@ import org.l2jmobius.gameserver.network.ServerPackets;
|
||||
* S = AllyName<br>
|
||||
* S = AllyLeaderName<br>
|
||||
* d = AllyCrestID<br>
|
||||
* @author KenM
|
||||
* @author Atronic
|
||||
*/
|
||||
public class SiegeDefenderList extends ServerPacket
|
||||
{
|
||||
@@ -60,64 +63,76 @@ public class SiegeDefenderList extends ServerPacket
|
||||
{
|
||||
ServerPackets.CASTLE_SIEGE_DEFENDER_LIST.writeId(this);
|
||||
writeInt(_castle.getResidenceId());
|
||||
writeInt(0); // Unknown
|
||||
writeInt(1); // Unknown
|
||||
writeInt(0); // Unknown
|
||||
final int size = _castle.getSiege().getDefenderWaitingClans().size() + _castle.getSiege().getDefenderClans().size() + (_castle.getOwner() != null ? 1 : 0);
|
||||
writeInt(size);
|
||||
writeInt(size);
|
||||
// Add owners
|
||||
final Clan ownerClan = _castle.getOwner();
|
||||
if (ownerClan != null)
|
||||
writeInt(0); // Unknown.
|
||||
|
||||
final Clan owner = _castle.getOwner();
|
||||
writeInt((owner != null) && _castle.isTimeRegistrationOver()); // Valid registration.
|
||||
writeInt(0); // Unknown.
|
||||
|
||||
// Add owners.
|
||||
final List<Clan> defenders = new ArrayList<>();
|
||||
if (owner != null)
|
||||
{
|
||||
writeInt(ownerClan.getId());
|
||||
writeString(ownerClan.getName());
|
||||
writeString(ownerClan.getLeaderName());
|
||||
writeInt(ownerClan.getCrestId());
|
||||
writeInt(0); // signed time (seconds) (not storated by L2J)
|
||||
writeInt(SiegeClanType.OWNER.ordinal());
|
||||
writeInt(ownerClan.getAllyId());
|
||||
writeString(ownerClan.getAllyName());
|
||||
writeString(""); // AllyLeaderName
|
||||
writeInt(ownerClan.getAllyCrestId());
|
||||
defenders.add(owner);
|
||||
}
|
||||
// List of confirmed defenders
|
||||
|
||||
// List of confirmed defenders.
|
||||
for (SiegeClan siegeClan : _castle.getSiege().getDefenderClans())
|
||||
{
|
||||
final Clan defendingClan = ClanTable.getInstance().getClan(siegeClan.getClanId());
|
||||
if ((defendingClan == null) || (defendingClan == _castle.getOwner()))
|
||||
final Clan clan = ClanTable.getInstance().getClan(siegeClan.getClanId());
|
||||
if ((clan != null) && (clan != owner))
|
||||
{
|
||||
continue;
|
||||
defenders.add(clan);
|
||||
}
|
||||
writeInt(defendingClan.getId());
|
||||
writeString(defendingClan.getName());
|
||||
writeString(defendingClan.getLeaderName());
|
||||
writeInt(defendingClan.getCrestId());
|
||||
writeInt(0); // signed time (seconds) (not storated by L2J)
|
||||
writeInt(SiegeClanType.DEFENDER.ordinal());
|
||||
writeInt(defendingClan.getAllyId());
|
||||
writeString(defendingClan.getAllyName());
|
||||
writeString(""); // AllyLeaderName
|
||||
writeInt(defendingClan.getAllyCrestId());
|
||||
}
|
||||
// List of not confirmed defenders
|
||||
|
||||
// List of not confirmed defenders.
|
||||
for (SiegeClan siegeClan : _castle.getSiege().getDefenderWaitingClans())
|
||||
{
|
||||
final Clan defendingClan = ClanTable.getInstance().getClan(siegeClan.getClanId());
|
||||
if (defendingClan == null)
|
||||
final Clan clan = ClanTable.getInstance().getClan(siegeClan.getClanId());
|
||||
if (clan != null)
|
||||
{
|
||||
continue;
|
||||
defenders.add(clan);
|
||||
}
|
||||
}
|
||||
|
||||
final int size = defenders.size();
|
||||
writeInt(size);
|
||||
writeInt(size);
|
||||
|
||||
for (Clan clan : defenders)
|
||||
{
|
||||
writeInt(clan.getId());
|
||||
writeString(clan.getName());
|
||||
writeString(clan.getLeaderName());
|
||||
writeInt(clan.getCrestId());
|
||||
writeInt(0); // Signed time in seconds.
|
||||
if (clan == owner)
|
||||
{
|
||||
writeInt(SiegeClanType.OWNER.ordinal() + 1);
|
||||
}
|
||||
else if (_castle.getSiege().getDefenderClans().stream().anyMatch(defender -> defender.getClanId() == clan.getId()))
|
||||
{
|
||||
writeInt(SiegeClanType.DEFENDER.ordinal() + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeInt(SiegeClanType.DEFENDER_PENDING.ordinal() + 1);
|
||||
}
|
||||
writeInt(clan.getAllyId());
|
||||
if (clan.getAllyId() != 0)
|
||||
{
|
||||
final AllianceInfo info = new AllianceInfo(clan.getAllyId());
|
||||
writeString(info.getName());
|
||||
writeString(info.getLeaderP()); // Ally leader name.
|
||||
writeInt(clan.getAllyCrestId());
|
||||
}
|
||||
else
|
||||
{
|
||||
writeString("");
|
||||
writeString(""); // Ally leader name.
|
||||
writeInt(0);
|
||||
}
|
||||
writeInt(defendingClan.getId());
|
||||
writeString(defendingClan.getName());
|
||||
writeString(defendingClan.getLeaderName());
|
||||
writeInt(defendingClan.getCrestId());
|
||||
writeInt(0); // signed time (seconds) (not storated by L2J)
|
||||
writeInt(SiegeClanType.DEFENDER_PENDING.ordinal());
|
||||
writeInt(defendingClan.getAllyId());
|
||||
writeString(defendingClan.getAllyName());
|
||||
writeString(""); // AllyLeaderName
|
||||
writeInt(defendingClan.getAllyCrestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-9
@@ -68,7 +68,7 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
_masks[2] |= 0x10;
|
||||
addComponentType(NpcInfoType.NAME);
|
||||
}
|
||||
addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.RELATIONS, NpcInfoType.TITLE, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.ALIVE, NpcInfoType.RUNNING, NpcInfoType.PVP_FLAG);
|
||||
addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.RELATIONS, NpcInfoType.TITLE, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.STOP_MODE, NpcInfoType.MOVE_MODE, NpcInfoType.PVP_FLAG);
|
||||
if (summon.getHeading() > 0)
|
||||
{
|
||||
addComponentType(NpcInfoType.HEADING);
|
||||
@@ -149,7 +149,7 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
_allyId = summon.getOwner().getAppearance().getVisibleAllyCrestId();
|
||||
addComponentType(NpcInfoType.CLAN);
|
||||
}
|
||||
addComponentType(NpcInfoType.COLOR_EFFECT);
|
||||
addComponentType(NpcInfoType.PET_EVOLUTION_ID);
|
||||
// TODO: Confirm me
|
||||
if (summon.isInCombat())
|
||||
{
|
||||
@@ -249,9 +249,9 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeInt(_summon.getHeading());
|
||||
}
|
||||
if (containsMask(NpcInfoType.UNKNOWN2))
|
||||
if (containsMask(NpcInfoType.VEHICLE_ID))
|
||||
{
|
||||
writeInt(0); // Unknown
|
||||
writeInt(0); // Vehicle object id.
|
||||
}
|
||||
if (containsMask(NpcInfoType.ATK_CAST_SPEED))
|
||||
{
|
||||
@@ -269,11 +269,11 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
writeInt(_summon.getArmor()); // Armor id?
|
||||
writeInt(0);
|
||||
}
|
||||
if (containsMask(NpcInfoType.ALIVE))
|
||||
if (containsMask(NpcInfoType.STOP_MODE))
|
||||
{
|
||||
writeByte(!_summon.isDead());
|
||||
}
|
||||
if (containsMask(NpcInfoType.RUNNING))
|
||||
if (containsMask(NpcInfoType.MOVE_MODE))
|
||||
{
|
||||
writeByte(_summon.isRunning());
|
||||
}
|
||||
@@ -297,9 +297,8 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeInt(0); // Player ObjectId with Decoy
|
||||
}
|
||||
if (containsMask(NpcInfoType.COLOR_EFFECT))
|
||||
if (containsMask(NpcInfoType.PET_EVOLUTION_ID))
|
||||
{
|
||||
// No visual effect
|
||||
writeInt(0); // Unknown
|
||||
}
|
||||
if (containsMask(NpcInfoType.DISPLAY_EFFECT))
|
||||
@@ -330,7 +329,7 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
|
||||
{
|
||||
writeByte(_summon.isShowSummonAnimation() ? 2 : 0); // 2 - do some animation on spawn
|
||||
}
|
||||
if (containsMask(NpcInfoType.UNKNOWN12))
|
||||
if (containsMask(NpcInfoType.FOLLOW_INFO))
|
||||
{
|
||||
writeInt(0);
|
||||
writeInt(0);
|
||||
|
||||
+11
@@ -83,6 +83,17 @@ public class ExPurchaseLimitShopItemListNew extends ServerPacket
|
||||
writeInt(product.getAccountDailyLimit() - _player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_DAILY_COUNT + product.getProductionId(), 0));
|
||||
}
|
||||
}
|
||||
else if (product.getAccountMontlyLimit() > 0)
|
||||
{
|
||||
if (_player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_MONTLY_COUNT + product.getProductionId(), 0) >= product.getAccountMontlyLimit())
|
||||
{
|
||||
writeInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeInt(product.getAccountMontlyLimit() - _player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_MONTLY_COUNT + product.getProductionId(), 0));
|
||||
}
|
||||
}
|
||||
else if (product.getAccountBuyLimit() > 0) // Count limit.
|
||||
{
|
||||
if (_player.getAccountVariables().getInt(AccountVariables.LCOIN_SHOP_PRODUCT_COUNT + product.getProductionId(), 0) >= product.getAccountBuyLimit())
|
||||
|
||||
+85
-35
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package org.l2jmobius.gameserver.taskmanager;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -25,6 +26,7 @@ import org.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import org.l2jmobius.gameserver.enums.Race;
|
||||
import org.l2jmobius.gameserver.geoengine.GeoEngine;
|
||||
import org.l2jmobius.gameserver.model.Location;
|
||||
import org.l2jmobius.gameserver.model.Party;
|
||||
import org.l2jmobius.gameserver.model.World;
|
||||
import org.l2jmobius.gameserver.model.WorldObject;
|
||||
import org.l2jmobius.gameserver.model.actor.Creature;
|
||||
@@ -42,6 +44,7 @@ import org.l2jmobius.gameserver.util.Util;
|
||||
public class AutoPlayTaskManager
|
||||
{
|
||||
private static final Set<Set<Player>> POOLS = ConcurrentHashMap.newKeySet();
|
||||
private static final Map<Player, Integer> IDLE_COUNT = new ConcurrentHashMap<>();
|
||||
private static final int POOL_SIZE = 300;
|
||||
private static final int TASK_DELAY = 300;
|
||||
|
||||
@@ -96,6 +99,17 @@ public class AutoPlayTaskManager
|
||||
// We take granted that mage classes do not auto hit.
|
||||
if (isMageCaster(player))
|
||||
{
|
||||
// Logic adjustment for summons not attacking when in offline play.
|
||||
if (player.isOfflinePlay() && player.hasSummon())
|
||||
{
|
||||
for (Summon summon : player.getServitors().values())
|
||||
{
|
||||
if (summon.hasAI() && !summon.isMoving() && !summon.isDisabled() && (summon.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && (summon.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST) && creature.isAutoAttackable(player) && GeoEngine.getInstance().canSeeTarget(player, creature))
|
||||
{
|
||||
summon.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, creature);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue PLAY;
|
||||
}
|
||||
|
||||
@@ -121,23 +135,32 @@ public class AutoPlayTaskManager
|
||||
final Weapon weapon = player.getActiveWeaponItem();
|
||||
if (weapon != null)
|
||||
{
|
||||
final boolean ranged = weapon.getItemType().isRanged();
|
||||
final double angle = Util.calculateHeadingFrom(player, creature);
|
||||
final double radian = Math.toRadians(angle);
|
||||
final double course = Math.toRadians(180);
|
||||
final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + creature.getCollisionRadius()) * 2;
|
||||
final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance);
|
||||
final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance);
|
||||
final Location location;
|
||||
if (ranged)
|
||||
final int idleCount = IDLE_COUNT.getOrDefault(player, 0);
|
||||
if (idleCount > 10)
|
||||
{
|
||||
location = new Location(player.getX() + x1, player.getY() + y1, player.getZ());
|
||||
final boolean ranged = weapon.getItemType().isRanged();
|
||||
final double angle = Util.calculateHeadingFrom(player, creature);
|
||||
final double radian = Math.toRadians(angle);
|
||||
final double course = Math.toRadians(180);
|
||||
final double distance = (ranged ? player.getCollisionRadius() : player.getCollisionRadius() + creature.getCollisionRadius()) * 2;
|
||||
final int x1 = (int) (Math.cos(Math.PI + radian + course) * distance);
|
||||
final int y1 = (int) (Math.sin(Math.PI + radian + course) * distance);
|
||||
final Location location;
|
||||
if (ranged)
|
||||
{
|
||||
location = new Location(player.getX() + x1, player.getY() + y1, player.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
location = new Location(creature.getX() + x1, creature.getY() + y1, player.getZ());
|
||||
}
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location);
|
||||
IDLE_COUNT.remove(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
location = new Location(creature.getX() + x1, creature.getY() + y1, player.getZ());
|
||||
IDLE_COUNT.put(player, idleCount + 1);
|
||||
}
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,6 +168,9 @@ public class AutoPlayTaskManager
|
||||
}
|
||||
}
|
||||
|
||||
// Reset idle count.
|
||||
IDLE_COUNT.remove(player);
|
||||
|
||||
// Pickup.
|
||||
if (player.getAutoPlaySettings().doPickup())
|
||||
{
|
||||
@@ -179,32 +205,55 @@ public class AutoPlayTaskManager
|
||||
|
||||
// Find target.
|
||||
Creature creature = null;
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
TARGET: for (Creature nearby : World.getInstance().getVisibleObjectsInRange(player, Creature.class, player.getAutoPlaySettings().isShortRange() && (targetMode != 2 /* Characters */) ? 600 : 1400))
|
||||
final Party party = player.getParty();
|
||||
final Player leader = party == null ? null : party.getLeader();
|
||||
if (Config.ENABLE_AUTO_ASSIST && (party != null) && (leader != null) && (leader != player) && !leader.isDead())
|
||||
{
|
||||
// Skip unavailable creatures.
|
||||
if ((nearby == null) || nearby.isAlikeDead())
|
||||
if (leader.calculateDistance3D(player) < (Config.ALT_PARTY_RANGE * 2 /* 2? */))
|
||||
{
|
||||
continue TARGET;
|
||||
}
|
||||
// Check creature target.
|
||||
if (player.getAutoPlaySettings().isRespectfulHunting() && !nearby.isPlayable() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId()))
|
||||
{
|
||||
continue TARGET;
|
||||
}
|
||||
// Check next target mode.
|
||||
if (!isTargetModeValid(targetMode, player, nearby))
|
||||
{
|
||||
continue TARGET;
|
||||
}
|
||||
// Check if creature is reachable.
|
||||
if ((Math.abs(player.getZ() - nearby.getZ()) < 180) && GeoEngine.getInstance().canSeeTarget(player, nearby) && GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
|
||||
{
|
||||
final double creatureDistance = player.calculateDistance2D(nearby);
|
||||
if (creatureDistance < closestDistance)
|
||||
final WorldObject leaderTarget = leader.getTarget();
|
||||
if ((leaderTarget != null) && (leaderTarget.isAttackable() || (leaderTarget.isPlayable() && !party.containsPlayer(leaderTarget.getActingPlayer()))))
|
||||
{
|
||||
creature = nearby;
|
||||
closestDistance = creatureDistance;
|
||||
creature = (Creature) leaderTarget;
|
||||
}
|
||||
else if ((player.getAI().getIntention() != CtrlIntention.AI_INTENTION_FOLLOW) && !player.isDisabled())
|
||||
{
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, leader);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
TARGET: for (Creature nearby : World.getInstance().getVisibleObjectsInRange(player, Creature.class, player.getAutoPlaySettings().isShortRange() && (targetMode != 2 /* Characters */) ? 600 : 1400))
|
||||
{
|
||||
// Skip unavailable creatures.
|
||||
if ((nearby == null) || nearby.isAlikeDead())
|
||||
{
|
||||
continue TARGET;
|
||||
}
|
||||
|
||||
// Check creature target.
|
||||
if (player.getAutoPlaySettings().isRespectfulHunting() && !nearby.isPlayable() && (nearby.getTarget() != null) && (nearby.getTarget() != player) && !player.getServitors().containsKey(nearby.getTarget().getObjectId()))
|
||||
{
|
||||
continue TARGET;
|
||||
}
|
||||
|
||||
// Check next target mode.
|
||||
if (!isTargetModeValid(targetMode, player, nearby))
|
||||
{
|
||||
continue TARGET;
|
||||
}
|
||||
|
||||
// Check if creature is reachable.
|
||||
if ((Math.abs(player.getZ() - nearby.getZ()) < 180) && GeoEngine.getInstance().canSeeTarget(player, nearby) && GeoEngine.getInstance().canMoveToTarget(player.getX(), player.getY(), player.getZ(), nearby.getX(), nearby.getY(), nearby.getZ(), player.getInstanceWorld()))
|
||||
{
|
||||
final double creatureDistance = player.calculateDistance2D(nearby);
|
||||
if (creatureDistance < closestDistance)
|
||||
{
|
||||
creature = nearby;
|
||||
closestDistance = creatureDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,6 +359,7 @@ public class AutoPlayTaskManager
|
||||
{
|
||||
player.getPet().followOwner();
|
||||
}
|
||||
IDLE_COUNT.remove(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+77
-4
@@ -35,7 +35,9 @@ import org.l2jmobius.gameserver.model.actor.Playable;
|
||||
import org.l2jmobius.gameserver.model.actor.Player;
|
||||
import org.l2jmobius.gameserver.model.actor.Summon;
|
||||
import org.l2jmobius.gameserver.model.actor.instance.Guard;
|
||||
import org.l2jmobius.gameserver.model.actor.transform.TransformTemplate;
|
||||
import org.l2jmobius.gameserver.model.effects.AbstractEffect;
|
||||
import org.l2jmobius.gameserver.model.effects.EffectType;
|
||||
import org.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import org.l2jmobius.gameserver.model.events.EventType;
|
||||
import org.l2jmobius.gameserver.model.events.impl.item.OnItemUse;
|
||||
@@ -46,12 +48,12 @@ import org.l2jmobius.gameserver.model.item.ItemTemplate;
|
||||
import org.l2jmobius.gameserver.model.item.instance.Item;
|
||||
import org.l2jmobius.gameserver.model.skill.AbnormalType;
|
||||
import org.l2jmobius.gameserver.model.skill.BuffInfo;
|
||||
import org.l2jmobius.gameserver.model.skill.EffectScope;
|
||||
import org.l2jmobius.gameserver.model.skill.Skill;
|
||||
import org.l2jmobius.gameserver.model.skill.targets.AffectScope;
|
||||
import org.l2jmobius.gameserver.model.skill.targets.TargetType;
|
||||
import org.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import org.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import org.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
|
||||
|
||||
/**
|
||||
* @author Mobius
|
||||
@@ -381,8 +383,9 @@ public class AutoUseTaskManager
|
||||
// Do not allow to do some action if player is transformed.
|
||||
if (player.isTransformed())
|
||||
{
|
||||
final int[] allowedActions = player.isTransformed() ? ExBasicActionList.ACTIONS_ON_TRANSFORM : ExBasicActionList.DEFAULT_ACTION_LIST;
|
||||
if (Arrays.binarySearch(allowedActions, actionId) < 0)
|
||||
final TransformTemplate transformTemplate = player.getTransformation().get().getTemplate(player);
|
||||
final int[] allowedActions = transformTemplate.getBasicActionList();
|
||||
if ((allowedActions == null) || (Arrays.binarySearch(allowedActions, actionId) < 0))
|
||||
{
|
||||
continue ACTIONS;
|
||||
}
|
||||
@@ -394,7 +397,24 @@ public class AutoUseTaskManager
|
||||
final IPlayerActionHandler actionHandler = PlayerActionHandler.getInstance().getHandler(actionHolder.getHandler());
|
||||
if (actionHandler != null)
|
||||
{
|
||||
actionHandler.useAction(player, actionHolder, false, false);
|
||||
if (!actionHandler.isPetAction())
|
||||
{
|
||||
actionHandler.useAction(player, actionHolder, false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Summon summon = player.getAnyServitor();
|
||||
if ((summon != null) && !summon.isAlikeDead())
|
||||
{
|
||||
final Skill skill = summon.getKnownSkill(actionHolder.getOptionId());
|
||||
if ((skill != null) && !canSummonCastSkill(player, summon, skill))
|
||||
{
|
||||
continue ACTIONS;
|
||||
}
|
||||
|
||||
actionHandler.useAction(player, actionHolder, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,6 +497,59 @@ public class AutoUseTaskManager
|
||||
|
||||
return !player.isSkillDisabled(skill) && skill.checkCondition(player, target, false);
|
||||
}
|
||||
|
||||
private boolean canSummonCastSkill(Player player, Summon summon, Skill skill)
|
||||
{
|
||||
if (skill.isBad() && (player.getTarget() == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final int mpConsume = skill.getMpConsume() + skill.getMpInitialConsume();
|
||||
if ((((mpConsume != 0) && (mpConsume > (int) Math.floor(summon.getCurrentMp()))) || ((skill.getHpConsume() != 0) && (skill.getHpConsume() > (int) Math.floor(summon.getCurrentHp())))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (summon.isSkillDisabled(skill))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((player.getTarget() != null) && !skill.checkCondition(summon, player.getTarget(), false)) || ((player.getTarget() == null) && !skill.checkCondition(summon, player, false)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((skill.getItemConsumeCount() > 0) && (summon.getInventory().getInventoryItemCount(skill.getItemConsumeId(), -1) < skill.getItemConsumeCount()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (skill.getTargetType().equals(TargetType.SELF) || skill.getTargetType().equals(TargetType.SUMMON))
|
||||
{
|
||||
final BuffInfo summonInfo = summon.getEffectList().getBuffInfoBySkillId(skill.getId());
|
||||
return (summonInfo != null) && (summonInfo.getTime() >= REUSE_MARGIN_TIME);
|
||||
}
|
||||
|
||||
if ((skill.getEffects(EffectScope.GENERAL) != null) && skill.getEffects(EffectScope.GENERAL).stream().anyMatch(a -> a.getEffectType().equals(EffectType.MANAHEAL_BY_LEVEL)) && (player.getCurrentMpPercent() > 80))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final BuffInfo buffInfo = player.getEffectList().getBuffInfoBySkillId(skill.getId());
|
||||
final BuffInfo abnormalBuffInfo = player.getEffectList().getFirstBuffInfoByAbnormalType(skill.getAbnormalType());
|
||||
if (abnormalBuffInfo != null)
|
||||
{
|
||||
if (buffInfo != null)
|
||||
{
|
||||
return (abnormalBuffInfo.getSkill().getId() == buffInfo.getSkill().getId()) && ((buffInfo.getTime() <= REUSE_MARGIN_TIME) || (buffInfo.getSkill().getLevel() < skill.getLevel()));
|
||||
}
|
||||
return (abnormalBuffInfo.getSkill().getAbnormalLevel() < skill.getAbnormalLevel()) || abnormalBuffInfo.isAbnormalType(AbnormalType.NONE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void startAutoUseTask(Player player)
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -721,13 +722,13 @@ public class Util
|
||||
{
|
||||
if (descending)
|
||||
{
|
||||
return map.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
return map.entrySet().stream().sorted(Entry.comparingByValue(Collections.reverseOrder())).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
}
|
||||
return map.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
return map.entrySet().stream().sorted(Entry.comparingByValue()).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
}
|
||||
|
||||
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map)
|
||||
{
|
||||
return map.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
return map.entrySet().stream().sorted(Entry.comparingByValue()).collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user