Explorar el Código

Added support for Agathions with Energy

Added Condition player has agathion.
Added condition player agathion energy.
Added packet ExBR_AgathionEnergyInfo to display agathion energy on
inventory.
Added database support for agathion energy.
Added Agathion energy data, must be unhardcoded.
Fixed several typos in the code.

Require database update.
Zoey76 hace 4 años
padre
commit
8a8dda9ed3
Se han modificado 20 ficheros con 480 adiciones y 195 borrados
  1. 0 6
      .settings/org.eclipse.jdt.core.prefs
  2. 58 0
      src/main/java/com/l2jserver/gameserver/agathion/Agathion.java
  3. 80 0
      src/main/java/com/l2jserver/gameserver/agathion/repository/AgathionRepository.java
  4. 3 3
      src/main/java/com/l2jserver/gameserver/datatables/ItemTable.java
  5. 20 11
      src/main/java/com/l2jserver/gameserver/engines/DocumentBase.java
  6. 9 10
      src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
  7. 1 1
      src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PetInstance.java
  8. 59 0
      src/main/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerAgathionEnergy.java
  9. 5 6
      src/main/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerAgathionId.java
  10. 42 0
      src/main/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerHasAgathion.java
  11. 7 9
      src/main/java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java
  12. 1 1
      src/main/java/com/l2jserver/gameserver/model/itemcontainer/ItemContainer.java
  13. 1 1
      src/main/java/com/l2jserver/gameserver/model/itemcontainer/Mail.java
  14. 1 1
      src/main/java/com/l2jserver/gameserver/model/itemcontainer/PcInventory.java
  15. 1 9
      src/main/java/com/l2jserver/gameserver/model/items/L2Armor.java
  16. 6 0
      src/main/java/com/l2jserver/gameserver/model/items/L2Item.java
  17. 70 76
      src/main/java/com/l2jserver/gameserver/model/items/instance/L2ItemInstance.java
  18. 32 46
      src/main/java/com/l2jserver/gameserver/model/skills/Skill.java
  19. 52 0
      src/main/java/com/l2jserver/gameserver/network/serverpackets/ExBR_AgathionEnergyInfo.java
  20. 32 15
      src/main/java/com/l2jserver/gameserver/network/serverpackets/ItemList.java

+ 0 - 6
.settings/org.eclipse.jdt.core.prefs

@@ -1,11 +1,5 @@
 eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=14
-org.eclipse.jdt.core.compiler.compliance=14
-org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
-org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=14
 org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
 org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false

+ 58 - 0
src/main/java/com/l2jserver/gameserver/agathion/Agathion.java

@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2004-2020 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * L2J Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.agathion;
+
+/**
+ * Agathion.
+ * @author Zoey76
+ * @version 2.6.2.0
+ */
+public class Agathion {
+	
+	private final int npcId;
+	
+	private final int itemId;
+	
+	private final int energy;
+	
+	private final int maxEnergy;
+	
+	public Agathion(int npcId, int id, int itemId, int energy, int maxEnergy) {
+		this.npcId = npcId;
+		this.itemId = itemId;
+		this.energy = energy;
+		this.maxEnergy = maxEnergy;
+	}
+	
+	public int getNpcId() {
+		return npcId;
+	}
+	
+	public int getItemId() {
+		return itemId;
+	}
+	
+	public int getEnergy() {
+		return energy;
+	}
+	
+	public int getMaxEnergy() {
+		return maxEnergy;
+	}
+}

+ 80 - 0
src/main/java/com/l2jserver/gameserver/agathion/repository/AgathionRepository.java

@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2004-2020 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * L2J Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.agathion.repository;
+
+import static java.util.stream.Collectors.toMap;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.l2jserver.gameserver.agathion.Agathion;
+
+/**
+ * Agathion repository.
+ * @author Zoey76
+ * @version 2.6.2.0
+ */
+public class AgathionRepository {
+	
+	// TODO(Zoey76): Unhardcode this map.
+	private final Map<Integer, Agathion> agathions = new HashMap<>() {
+		private static final long serialVersionUID = 1L;
+		{
+			put(1539, new Agathion(1539, 539, 20818, 100000, 100000));
+			put(1540, new Agathion(1540, 540, 20820, 100000, 100000));
+			put(1541, new Agathion(1541, 541, 20822, 100000, 100000));
+			put(1542, new Agathion(1542, 542, 20824, 100000, 100000));
+			put(1543, new Agathion(1543, 543, 20826, 100000, 100000));
+			put(1544, new Agathion(1544, 544, 20828, 100000, 100000));
+			put(1545, new Agathion(1545, 545, 20830, 100000, 100000));
+			put(1546, new Agathion(1546, 546, 20832, 100000, 100000));
+			put(1547, new Agathion(1547, 547, 20834, 100000, 100000));
+			put(1548, new Agathion(1548, 548, 20836, 100000, 100000));
+			put(1549, new Agathion(1549, 549, 20838, 100000, 100000));
+			put(1550, new Agathion(1550, 550, 20840, 100000, 100000));
+			put(1576, new Agathion(1576, 576, 20983, 1000, 1000));
+			put(1577, new Agathion(1577, 577, 20984, 1000, 1000));
+			put(1578, new Agathion(1578, 578, 20985, 1000, 1000));
+			put(1579, new Agathion(1579, 579, 20986, 1000, 1000));
+			put(1580, new Agathion(1580, 580, 20987, 1000, 1000));
+			put(1581, new Agathion(1581, 581, 20988, 1000, 1000));
+			put(1582, new Agathion(1582, 582, 20989, 1000, 1000));
+			put(1583, new Agathion(1583, 583, 20990, 1000, 1000));
+			put(1584, new Agathion(1584, 584, 20991, 1000, 1000));
+		}
+	};
+	
+	private final Map<Integer, Agathion> agathionItems = agathions.entrySet().stream().collect(toMap(e -> e.getValue().getItemId(), Map.Entry::getValue));
+	
+	public Agathion getByNpcId(int npcId) {
+		return agathions.get(npcId);
+	}
+	
+	public Agathion getByItemId(int itemId) {
+		return agathionItems.get(itemId);
+	}
+	
+	public static AgathionRepository getInstance() {
+		return SingletonHolder.INSTANCE;
+	}
+	
+	private static class SingletonHolder {
+		static final AgathionRepository INSTANCE = new AgathionRepository();
+	}
+}

+ 3 - 3
src/main/java/com/l2jserver/gameserver/datatables/ItemTable.java

@@ -207,12 +207,12 @@ public class ItemTable {
 				if ((raid.getFirstCommandChannelAttacked() != null) && !character().autoLootRaids()) {
 					item.setOwnerId(raid.getFirstCommandChannelAttacked().getLeaderObjectId());
 					itemLootShedule = ThreadPoolManager.getInstance().scheduleGeneral(new ResetOwner(item), character().getRaidLootRightsInterval());
-					item.setItemLootShedule(itemLootShedule);
+					item.setItemLootSchedule(itemLootShedule);
 				}
 			} else if (!character().autoLoot() || ((reference instanceof L2EventMonsterInstance) && ((L2EventMonsterInstance) reference).eventDropOnGround())) {
 				item.setOwnerId(actor.getObjectId());
 				itemLootShedule = ThreadPoolManager.getInstance().scheduleGeneral(new ResetOwner(item), 15000);
-				item.setItemLootShedule(itemLootShedule);
+				item.setItemLootSchedule(itemLootShedule);
 			}
 		}
 		
@@ -335,7 +335,7 @@ public class ItemTable {
 		@Override
 		public void run() {
 			_item.setOwnerId(0);
-			_item.setItemLootShedule(null);
+			_item.setItemLootSchedule(null);
 		}
 	}
 	

+ 20 - 11
src/main/java/com/l2jserver/gameserver/engines/DocumentBase.java

@@ -53,6 +53,7 @@ import com.l2jserver.gameserver.model.conditions.ConditionLogicOr;
 import com.l2jserver.gameserver.model.conditions.ConditionMinDistance;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerActiveEffectId;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerActiveSkillId;
+import com.l2jserver.gameserver.model.conditions.ConditionPlayerAgathionEnergy;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerAgathionId;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerCallPc;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerCanCreateBase;
@@ -89,6 +90,7 @@ import com.l2jserver.gameserver.model.conditions.ConditionPlayerLandingZone;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerLevel;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerLevelRange;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerMp;
+import com.l2jserver.gameserver.model.conditions.ConditionPlayerHasAgathion;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerPkCount;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerPledgeClass;
 import com.l2jserver.gameserver.model.conditions.ConditionPlayerRace;
@@ -243,8 +245,8 @@ public abstract class DocumentBase {
 			value = Double.parseDouble(valueString);
 		}
 		
-		final Condition applayCond = parseCondition(n.getFirstChild(), template);
-		final FuncTemplate ft = new FuncTemplate(attachCond, applayCond, functionName, order, stat, value);
+		final Condition applyCond = parseCondition(n.getFirstChild(), template);
+		final FuncTemplate ft = new FuncTemplate(attachCond, applyCond, functionName, order, stat, value);
 		if (template instanceof L2Item) {
 			((L2Item) template).attach(ft);
 		} else if (template instanceof AbstractEffect) {
@@ -267,13 +269,13 @@ public abstract class DocumentBase {
 		}
 		
 		final StatsSet parameters = parseParameters(n.getFirstChild(), template);
-		final Condition applayCond = parseCondition(n.getFirstChild(), template);
+		final Condition applyCond = parseCondition(n.getFirstChild(), template);
 		
 		if (template instanceof IIdentifiable) {
 			set.set("id", ((IIdentifiable) template).getId());
 		}
 		
-		final AbstractEffect effect = AbstractEffect.createEffect(attachCond, applayCond, set, parameters);
+		final AbstractEffect effect = AbstractEffect.createEffect(attachCond, applyCond, set, parameters);
 		parseTemplate(n, effect);
 		if (template instanceof L2Item) {
 			_log.severe("Item " + template + " with effects!!!");
@@ -756,6 +758,18 @@ public abstract class DocumentBase {
 					cond = joinAnd(cond, new ConditionCategoryType(array));
 					break;
 				}
+				case "hasagathion": {
+					cond = joinAnd(cond, new ConditionPlayerHasAgathion(Boolean.parseBoolean(a.getNodeValue())));
+					break;
+				}
+				case "agathionenergy": {
+					cond = joinAnd(cond, new ConditionPlayerAgathionEnergy(Integer.decode(getValue(a.getNodeValue(), null))));
+					break;
+				}
+				default: {
+					_log.severe("Unrecognized <player> condition " + a.getNodeName().toLowerCase() + " in " + _file);
+					break;
+				}
 			}
 		}
 		
@@ -887,13 +901,8 @@ public abstract class DocumentBase {
 					String values = getValue(a.getNodeValue(), template).trim();
 					String[] valuesSplit = values.split(",");
 					InstanceType[] types = new InstanceType[valuesSplit.length];
-					InstanceType type;
 					for (int j = 0; j < valuesSplit.length; j++) {
-						type = Enum.valueOf(InstanceType.class, valuesSplit[j]);
-						if (type == null) {
-							throw new IllegalArgumentException("Instance type not recognized: " + valuesSplit[j]);
-						}
-						types[j] = type;
+						types[j] = Enum.valueOf(InstanceType.class, valuesSplit[j]);
 					}
 					cond = joinAnd(cond, new ConditionTargetNpcType(types));
 					break;
@@ -1054,7 +1063,7 @@ public abstract class DocumentBase {
 			if (template instanceof Skill) {
 				return getTableValue(value);
 			} else if (template instanceof Integer) {
-				return getTableValue(value, ((Integer) template).intValue());
+				return getTableValue(value, (Integer) template);
 			} else {
 				throw new IllegalStateException();
 			}

+ 9 - 10
src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -72,6 +72,7 @@ import com.l2jserver.gameserver.RecipeController;
 import com.l2jserver.gameserver.SevenSigns;
 import com.l2jserver.gameserver.SevenSignsFestival;
 import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.agathion.repository.AgathionRepository;
 import com.l2jserver.gameserver.ai.CtrlIntention;
 import com.l2jserver.gameserver.ai.L2CharacterAI;
 import com.l2jserver.gameserver.ai.L2PlayerAI;
@@ -277,6 +278,7 @@ import com.l2jserver.gameserver.network.serverpackets.CharInfo;
 import com.l2jserver.gameserver.network.serverpackets.ConfirmDlg;
 import com.l2jserver.gameserver.network.serverpackets.EtcStatusUpdate;
 import com.l2jserver.gameserver.network.serverpackets.ExAutoSoulShot;
+import com.l2jserver.gameserver.network.serverpackets.ExBR_AgathionEnergyInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
 import com.l2jserver.gameserver.network.serverpackets.ExDominionWarStart;
 import com.l2jserver.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
@@ -1890,6 +1892,12 @@ public final class L2PcInstance extends L2Playable {
 			sendPacket(new ExStorageMaxCount(this));
 		}
 		
+		// If item is agathion with energy, then send info to client.
+		final var agathionInfo = AgathionRepository.getInstance().getByItemId(item.getId());
+		if ((agathionInfo != null) && agathionInfo.getMaxEnergy() > 0) {
+			sendPacket(new ExBR_AgathionEnergyInfo(List.of(item)));
+		}
+		
 		// Notify to scripts
 		EventDispatcher.getInstance().notifyEventAsync(new OnPlayerEquipItem(this, item), this);
 	}
@@ -3893,7 +3901,7 @@ public final class L2PcInstance extends L2Playable {
 				}
 			}
 			
-			if ((target.getItemLootShedule() != null) && ((target.getOwnerId() == getObjectId()) || isInLooterParty(target.getOwnerId()))) {
+			if ((target.getItemLootSchedule() != null) && ((target.getOwnerId() == getObjectId()) || isInLooterParty(target.getOwnerId()))) {
 				target.resetOwnerTimer();
 			}
 			
@@ -9592,16 +9600,10 @@ public final class L2PcInstance extends L2Playable {
 		sendPacket(sm);
 	}
 	
-	/**
-	 * @return
-	 */
 	public int getAgathionId() {
 		return _agathionId;
 	}
 	
-	/**
-	 * @param npcId
-	 */
 	public void setAgathionId(int npcId) {
 		_agathionId = npcId;
 	}
@@ -9610,9 +9612,6 @@ public final class L2PcInstance extends L2Playable {
 		return getStat().getVitalityPoints();
 	}
 	
-	/**
-	 * @return Vitality Level
-	 */
 	public int getVitalityLevel() {
 		return getStat().getVitalityLevel();
 	}

+ 1 - 1
src/main/java/com/l2jserver/gameserver/model/actor/instance/L2PetInstance.java

@@ -478,7 +478,7 @@ public class L2PetInstance extends L2Summon {
 				return;
 			}
 			
-			if ((target.getItemLootShedule() != null) && ((target.getOwnerId() == getOwner().getObjectId()) || getOwner().isInLooterParty(target.getOwnerId()))) {
+			if ((target.getItemLootSchedule() != null) && ((target.getOwnerId() == getOwner().getObjectId()) || getOwner().isInLooterParty(target.getOwnerId()))) {
 				target.resetOwnerTimer();
 			}
 			

+ 59 - 0
src/main/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerAgathionEnergy.java

@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2004-2020 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * L2J Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model.conditions;
+
+import static com.l2jserver.gameserver.model.itemcontainer.Inventory.PAPERDOLL_LBRACELET;
+
+import com.l2jserver.gameserver.agathion.repository.AgathionRepository;
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.items.L2Item;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * Condition agathion energy.
+ * @author Zoey76
+ * @version 2.6.2.0
+ */
+public class ConditionPlayerAgathionEnergy extends Condition {
+	
+	private final int energy;
+	
+	public ConditionPlayerAgathionEnergy(int energy) {
+		this.energy = energy;
+	}
+	
+	@Override
+	public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item) {
+		if (!effector.isPlayer()) {
+			return false;
+		}
+		
+		final var player = effector.getActingPlayer();
+		final var agathionInfo = AgathionRepository.getInstance().getByNpcId(player.getAgathionId());
+		if ((agathionInfo == null) || (agathionInfo.getMaxEnergy() <= 0)) {
+			return false;
+		}
+		
+		final var agathionItem = player.getInventory().getPaperdollItem(PAPERDOLL_LBRACELET);
+		if ((agathionItem == null) || (agathionInfo.getItemId() != agathionItem.getId())) {
+			return false;
+		}
+		return agathionItem.getAgathionRemainingEnergy() >= energy;
+	}
+}

+ 5 - 6
src/main/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerAgathionId.java

@@ -23,21 +23,20 @@ import com.l2jserver.gameserver.model.items.L2Item;
 import com.l2jserver.gameserver.model.skills.Skill;
 
 /**
- * The Class ConditionPlayerAgathionId.
+ * Condition Player Agathion Id.
+ * @author Zoey76
+ * @version 2.6.2.0
  */
 public class ConditionPlayerAgathionId extends Condition {
+	
 	private final int _agathionId;
 	
-	/**
-	 * Instantiates a new condition player agathion id.
-	 * @param agathionId the agathion id
-	 */
 	public ConditionPlayerAgathionId(int agathionId) {
 		_agathionId = agathionId;
 	}
 	
 	@Override
 	public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item) {
-		return (effector.getActingPlayer() != null) && (effector.getActingPlayer().getAgathionId() == _agathionId);
+		return effector.isPlayer() && (effector.getActingPlayer().getAgathionId() == _agathionId);
 	}
 }

+ 42 - 0
src/main/java/com/l2jserver/gameserver/model/conditions/ConditionPlayerHasAgathion.java

@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2004-2020 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * L2J Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.model.conditions;
+
+import com.l2jserver.gameserver.model.actor.L2Character;
+import com.l2jserver.gameserver.model.items.L2Item;
+import com.l2jserver.gameserver.model.skills.Skill;
+
+/**
+ * Condition has agathion.
+ * @author Zoey76
+ * @version 2.6.2.0
+ */
+public class ConditionPlayerHasAgathion extends Condition {
+	
+	private final boolean expectedValue;
+	
+	public ConditionPlayerHasAgathion(boolean expectedValue) {
+		this.expectedValue = expectedValue;
+	}
+	
+	@Override
+	public boolean testImpl(L2Character effector, L2Character effected, Skill skill, L2Item item) {
+		return expectedValue == (effector.isPlayer() && (effector.getActingPlayer().getAgathionId() > 0));
+	}
+}

+ 7 - 9
src/main/java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java

@@ -102,7 +102,6 @@ public abstract class Inventory extends ItemContainer {
 	
 	// Recorder of alterations in inventory
 	private static final class ChangeRecorder implements PaperdollListener {
-		private final Inventory _inventory;
 		private final List<L2ItemInstance> _changed;
 		
 		/**
@@ -110,9 +109,8 @@ public abstract class Inventory extends ItemContainer {
 		 * @param inventory
 		 */
 		ChangeRecorder(Inventory inventory) {
-			_inventory = inventory;
 			_changed = new ArrayList<>();
-			_inventory.addPaperdollListener(this);
+			inventory.addPaperdollListener(this);
 		}
 		
 		/**
@@ -151,7 +149,7 @@ public abstract class Inventory extends ItemContainer {
 	}
 	
 	private static final class BowCrossRodListener implements PaperdollListener {
-		private static BowCrossRodListener instance = new BowCrossRodListener();
+		private static final BowCrossRodListener instance = new BowCrossRodListener();
 		
 		public static BowCrossRodListener getInstance() {
 			return instance;
@@ -207,7 +205,7 @@ public abstract class Inventory extends ItemContainer {
 	}
 	
 	private static final class StatsListener implements PaperdollListener {
-		private static StatsListener instance = new StatsListener();
+		private static final StatsListener instance = new StatsListener();
 		
 		public static StatsListener getInstance() {
 			return instance;
@@ -225,7 +223,7 @@ public abstract class Inventory extends ItemContainer {
 	}
 	
 	private static final class ItemSkillsListener implements PaperdollListener {
-		private static ItemSkillsListener instance = new ItemSkillsListener();
+		private static final ItemSkillsListener instance = new ItemSkillsListener();
 		
 		public static ItemSkillsListener getInstance() {
 			return instance;
@@ -402,7 +400,7 @@ public abstract class Inventory extends ItemContainer {
 	}
 	
 	private static final class ArmorSetListener implements PaperdollListener {
-		private static ArmorSetListener instance = new ArmorSetListener();
+		private static final ArmorSetListener instance = new ArmorSetListener();
 		
 		public static ArmorSetListener getInstance() {
 			return instance;
@@ -592,7 +590,7 @@ public abstract class Inventory extends ItemContainer {
 	}
 	
 	private static final class BraceletListener implements PaperdollListener {
-		private static BraceletListener instance = new BraceletListener();
+		private static final BraceletListener instance = new BraceletListener();
 		
 		public static BraceletListener getInstance() {
 			return instance;
@@ -1403,7 +1401,7 @@ public abstract class Inventory extends ItemContainer {
 	@Override
 	public void restore() {
 		try (var con = ConnectionFactory.getInstance().getConnection();
-			var ps = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time FROM items WHERE owner_id=? AND (loc=? OR loc=?) ORDER BY loc_data")) {
+			var ps = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time, agathion_energy FROM items WHERE owner_id=? AND (loc=? OR loc=?) ORDER BY loc_data")) {
 			ps.setInt(1, getOwnerId());
 			ps.setString(2, getBaseLocation().name());
 			ps.setString(3, getEquipLocation().name());

+ 1 - 1
src/main/java/com/l2jserver/gameserver/model/itemcontainer/ItemContainer.java

@@ -568,7 +568,7 @@ public abstract class ItemContainer {
 	 */
 	public void restore() {
 		try (var con = ConnectionFactory.getInstance().getConnection();
-			var ps = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time FROM items WHERE owner_id=? AND (loc=?)")) {
+			var ps = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time, agathion_energy FROM items WHERE owner_id=? AND (loc=?)")) {
 			ps.setInt(1, getOwnerId());
 			ps.setString(2, getBaseLocation().name());
 			try (var rs = ps.executeQuery()) {

+ 1 - 1
src/main/java/com/l2jserver/gameserver/model/itemcontainer/Mail.java

@@ -100,7 +100,7 @@ public class Mail extends ItemContainer {
 	@Override
 	public void restore() {
 		try (var con = ConnectionFactory.getInstance().getConnection();
-			var ps = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time FROM items WHERE owner_id=? AND loc=? AND loc_data=?")) {
+			var ps = con.prepareStatement("SELECT object_id, item_id, count, enchant_level, loc, loc_data, custom_type1, custom_type2, mana_left, time, agathion_energy FROM items WHERE owner_id=? AND loc=? AND loc_data=?")) {
 			ps.setInt(1, getOwnerId());
 			ps.setString(2, getBaseLocation().name());
 			ps.setInt(3, getMessageId());

+ 1 - 1
src/main/java/com/l2jserver/gameserver/model/itemcontainer/PcInventory.java

@@ -676,7 +676,7 @@ public class PcInventory extends Inventory {
 	public static int[][] restoreVisibleInventory(int objectId) {
 		int[][] paperdoll = new int[31][3];
 		try (var con = ConnectionFactory.getInstance().getConnection();
-			var ps = con.prepareStatement("SELECT object_id,item_id,loc_data,enchant_level FROM items WHERE owner_id=? AND loc='PAPERDOLL'")) {
+			var ps = con.prepareStatement("SELECT object_id, item_id, loc_data, enchant_level FROM items WHERE owner_id=? AND loc='PAPERDOLL'")) {
 			ps.setInt(1, objectId);
 			try (var rs = ps.executeQuery()) {
 				while (rs.next()) {

+ 1 - 9
src/main/java/com/l2jserver/gameserver/model/items/L2Armor.java

@@ -34,6 +34,7 @@ public final class L2Armor extends L2Item {
 	 * Skill that activates when armor is enchanted +4.
 	 */
 	private SkillHolder _enchant4Skill = null;
+	
 	private ArmorType _type;
 	
 	/**
@@ -77,25 +78,16 @@ public final class L2Armor extends L2Item {
 		}
 	}
 	
-	/**
-	 * @return the type of the armor.
-	 */
 	@Override
 	public ArmorType getItemType() {
 		return _type;
 	}
 	
-	/**
-	 * @return the ID of the item after applying the mask.
-	 */
 	@Override
 	public int getItemMask() {
 		return getItemType().mask();
 	}
 	
-	/**
-	 * @return skill that player get when has equipped armor +4 or more
-	 */
 	@Override
 	public Skill getEnchant4Skill() {
 		if (_enchant4Skill == null) {

+ 6 - 0
src/main/java/com/l2jserver/gameserver/model/items/L2Item.java

@@ -315,6 +315,9 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable
 		return _displayId;
 	}
 	
+	/**
+	 * @return the ID of the item after applying the mask
+	 */
 	public abstract int getItemMask();
 	
 	/**
@@ -824,6 +827,9 @@ public abstract class L2Item extends ListenersContainer implements IIdentifiable
 		return getItemType() == EtcItemType.PET_COLLAR;
 	}
 	
+	/**
+	 * @return skill that player get when has equipped armor +4 or more
+	 */
 	public Skill getEnchant4Skill() {
 		return null;
 	}

+ 70 - 76
src/main/java/com/l2jserver/gameserver/model/items/instance/L2ItemInstance.java

@@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory;
 import com.l2jserver.commons.database.ConnectionFactory;
 import com.l2jserver.gameserver.GeoData;
 import com.l2jserver.gameserver.ThreadPoolManager;
+import com.l2jserver.gameserver.agathion.repository.AgathionRepository;
 import com.l2jserver.gameserver.data.xml.impl.EnchantItemOptionsData;
 import com.l2jserver.gameserver.data.xml.impl.OptionData;
 import com.l2jserver.gameserver.datatables.ItemTable;
@@ -131,7 +132,7 @@ public final class L2ItemInstance extends L2Object {
 	private L2Augmentation _augmentation = null;
 	
 	/** Shadow item */
-	private int _mana = -1;
+	private int _mana;
 	
 	private boolean _consumingMana = false;
 	
@@ -172,7 +173,7 @@ public final class L2ItemInstance extends L2Object {
 	
 	private Elementals[] _elementals = null;
 	
-	private ScheduledFuture<?> itemLootShedule = null;
+	private ScheduledFuture<?> itemLootSchedule = null;
 	
 	private ScheduledFuture<?> _lifeTimeTask;
 	
@@ -182,6 +183,8 @@ public final class L2ItemInstance extends L2Object {
 	
 	private final List<Options> _enchantOptions = new ArrayList<>();
 	
+	private int agathionEnergy;
+	
 	/**
 	 * Constructor of the L2ItemInstance from the objectId and the itemId.
 	 * @param objectId : int designating the ID of the object in the world
@@ -204,12 +207,14 @@ public final class L2ItemInstance extends L2Object {
 		_mana = _item.getDuration();
 		_time = _item.getTime() == -1 ? -1 : System.currentTimeMillis() + ((long) _item.getTime() * 60 * 1000);
 		scheduleLifeTimeTask();
+		final var agathionInfo = AgathionRepository.getInstance().getByItemId(itemId);
+		agathionEnergy = agathionInfo == null ? 0 : agathionInfo.getMaxEnergy();
 	}
 	
 	/**
 	 * Constructor of the L2ItemInstance from the objetId and the description of the item given by the L2Item.
 	 * @param objectId : int designating the ID of the object in the world
-	 * @param item : L2Item containing informations of the item
+	 * @param item : L2Item containing information of the item
 	 */
 	public L2ItemInstance(int objectId, L2Item item) {
 		super(objectId);
@@ -225,6 +230,8 @@ public final class L2ItemInstance extends L2Object {
 		_mana = _item.getDuration();
 		_time = _item.getTime() == -1 ? -1 : System.currentTimeMillis() + ((long) _item.getTime() * 60 * 1000);
 		scheduleLifeTimeTask();
+		final var agathionInfo = AgathionRepository.getInstance().getByItemId(item.getId());
+		agathionEnergy = agathionInfo == null ? 0 : agathionInfo.getMaxEnergy();
 	}
 	
 	/**
@@ -392,8 +399,7 @@ public final class L2ItemInstance extends L2Object {
 	}
 	
 	/**
-	 * Sets the quantity of the item.<BR>
-	 * <BR>
+	 * Sets the quantity of the item.
 	 * @param count the new count to set
 	 */
 	public void setCount(long count) {
@@ -405,9 +411,6 @@ public final class L2ItemInstance extends L2Object {
 		_storedInDb = false;
 	}
 	
-	/**
-	 * @return Returns the count.
-	 */
 	public long getCount() {
 		return _count;
 	}
@@ -674,7 +677,7 @@ public final class L2ItemInstance extends L2Object {
 	 * @return boolean
 	 */
 	public boolean isDropable() {
-		return isAugmented() ? false : _item.isDropable();
+		return !isAugmented() && _item.isDropable();
 	}
 	
 	/**
@@ -690,7 +693,7 @@ public final class L2ItemInstance extends L2Object {
 	 * @return boolean
 	 */
 	public boolean isTradeable() {
-		return isAugmented() ? false : _item.isTradeable();
+		return !isAugmented() && _item.isTradeable();
 	}
 	
 	/**
@@ -698,7 +701,7 @@ public final class L2ItemInstance extends L2Object {
 	 * @return boolean
 	 */
 	public boolean isSellable() {
-		return isAugmented() ? false : _item.isSellable();
+		return !isAugmented() && _item.isSellable();
 	}
 	
 	/**
@@ -712,11 +715,8 @@ public final class L2ItemInstance extends L2Object {
 		}
 		if (!isPrivateWareHouse) {
 			// augmented not tradeable
-			if (!isTradeable() || isShadowItem()) {
-				return false;
-			}
+			return isTradeable() && !isShadowItem();
 		}
-		
 		return true;
 	}
 	
@@ -1243,59 +1243,46 @@ public final class L2ItemInstance extends L2Object {
 	}
 	
 	/**
-	 * Returns a L2ItemInstance stored in database from its objectID
-	 * @param ownerId
-	 * @param rs
-	 * @return L2ItemInstance
+	 * Restores an item from the database.
+	 * @param ownerId the owner Id
+	 * @param rs the result set
+	 * @return the item instance
 	 */
 	public static L2ItemInstance restoreFromDb(int ownerId, ResultSet rs) {
-		L2ItemInstance inst = null;
-		int objectId, itemId, loc_data, enchant_level, custom_type1, custom_type2, manaLeft;
-		long time, count;
-		ItemLocation loc;
 		try {
-			objectId = rs.getInt(1);
-			itemId = rs.getInt("item_id");
-			count = rs.getLong("count");
-			loc = ItemLocation.valueOf(rs.getString("loc"));
-			loc_data = rs.getInt("loc_data");
-			enchant_level = rs.getInt("enchant_level");
-			custom_type1 = rs.getInt("custom_type1");
-			custom_type2 = rs.getInt("custom_type2");
-			manaLeft = rs.getInt("mana_left");
-			time = rs.getLong("time");
+			final var objectId = rs.getInt(1);
+			final var itemId = rs.getInt("item_id");
+			final var template = ItemTable.getInstance().getTemplate(itemId);
+			if (template == null) {
+				LOG.error("Item Id {} not known, object Id {} by owner Id {}!", itemId, objectId, ownerId);
+				return null;
+			}
+			
+			final var item = new L2ItemInstance(objectId, template);
+			item._ownerId = ownerId;
+			item.setCount(rs.getLong("count"));
+			item._enchantLevel = rs.getInt("enchant_level");
+			item._type1 = rs.getInt("custom_type1");
+			item._type2 = rs.getInt("custom_type2");
+			item._loc = ItemLocation.valueOf(rs.getString("loc"));
+			item._locData = rs.getInt("loc_data");
+			item._existsInDb = true;
+			item._storedInDb = true;
+			// Support shadow weapons
+			item._mana = rs.getInt("mana_left");
+			item._time = rs.getLong("time");
+			// Support Agathion energy
+			item.agathionEnergy = rs.getInt("agathion_energy");
+			
+			// load augmentation and elemental enchant
+			if (item.isEquipable()) {
+				item.restoreAttributes();
+			}
+			return item;
 		} catch (Exception ex) {
 			LOG.warn("Could not restore an item owned by {} from database!", ownerId, ex);
 			return null;
 		}
-		
-		L2Item item = ItemTable.getInstance().getTemplate(itemId);
-		if (item == null) {
-			LOG.error("Item Id {} not known, object Id {} by owner Id {}!", itemId, objectId, ownerId);
-			return null;
-		}
-		
-		inst = new L2ItemInstance(objectId, item);
-		inst._ownerId = ownerId;
-		inst.setCount(count);
-		inst._enchantLevel = enchant_level;
-		inst._type1 = custom_type1;
-		inst._type2 = custom_type2;
-		inst._loc = loc;
-		inst._locData = loc_data;
-		inst._existsInDb = true;
-		inst._storedInDb = true;
-		
-		// Setup life time for shadow weapons
-		inst._mana = manaLeft;
-		inst._time = time;
-		
-		// load augmentation and elemental enchant
-		if (inst.isEquipable()) {
-			inst.restoreAttributes();
-		}
-		
-		return inst;
 	}
 	
 	/**
@@ -1395,7 +1382,7 @@ public final class L2ItemInstance extends L2Object {
 		}
 		
 		try (var con = ConnectionFactory.getInstance().getConnection();
-			var ps = con.prepareStatement("UPDATE items SET owner_id=?,count=?,loc=?,loc_data=?,enchant_level=?,custom_type1=?,custom_type2=?,mana_left=?,time=? " + "WHERE object_id = ?")) {
+			var ps = con.prepareStatement("UPDATE items SET owner_id=?, count=?, loc=?, loc_data=?, enchant_level=?, custom_type1=?, custom_type2=?, mana_left=?, time=?, agathion_energy=? WHERE object_id=?")) {
 			ps.setInt(1, _ownerId);
 			ps.setLong(2, getCount());
 			ps.setString(3, _loc.name());
@@ -1405,7 +1392,8 @@ public final class L2ItemInstance extends L2Object {
 			ps.setInt(7, getCustomType2());
 			ps.setInt(8, getMana());
 			ps.setLong(9, getTime());
-			ps.setInt(10, getObjectId());
+			ps.setInt(10, getAgathionRemainingEnergy());
+			ps.setInt(11, getObjectId());
 			ps.executeUpdate();
 			_existsInDb = true;
 			_storedInDb = true;
@@ -1422,7 +1410,7 @@ public final class L2ItemInstance extends L2Object {
 		}
 		
 		try (var con = ConnectionFactory.getInstance().getConnection();
-			var ps = con.prepareStatement("INSERT INTO items (owner_id,item_id,count,loc,loc_data,enchant_level,object_id,custom_type1,custom_type2,mana_left,time) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?)")) {
+			var ps = con.prepareStatement("INSERT INTO items (owner_id, item_id, count, loc, loc_data, enchant_level, object_id, custom_type1, custom_type2, mana_left, time, agathion_energy) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")) {
 			ps.setInt(1, _ownerId);
 			ps.setInt(2, _itemId);
 			ps.setLong(3, getCount());
@@ -1434,6 +1422,7 @@ public final class L2ItemInstance extends L2Object {
 			ps.setInt(9, _type2);
 			ps.setInt(10, getMana());
 			ps.setLong(11, getTime());
+			ps.setInt(12, getAgathionRemainingEnergy());
 			
 			ps.executeUpdate();
 			_existsInDb = true;
@@ -1485,18 +1474,18 @@ public final class L2ItemInstance extends L2Object {
 	}
 	
 	public void resetOwnerTimer() {
-		if (itemLootShedule != null) {
-			itemLootShedule.cancel(true);
+		if (itemLootSchedule != null) {
+			itemLootSchedule.cancel(true);
 		}
-		itemLootShedule = null;
+		itemLootSchedule = null;
 	}
 	
-	public void setItemLootShedule(ScheduledFuture<?> sf) {
-		itemLootShedule = sf;
+	public void setItemLootSchedule(ScheduledFuture<?> sf) {
+		itemLootSchedule = sf;
 	}
 	
-	public ScheduledFuture<?> getItemLootShedule() {
-		return itemLootShedule;
+	public ScheduledFuture<?> getItemLootSchedule() {
+		return itemLootSchedule;
 	}
 	
 	public void setProtected(boolean isProtected) {
@@ -1669,11 +1658,7 @@ public final class L2ItemInstance extends L2Object {
 		if (general().saveDroppedItem()) {
 			ItemsOnGroundManager.getInstance().removeObject(this);
 		}
-		
-		if (!super.decayMe()) {
-			return false;
-		}
-		return true;
+		return super.decayMe();
 	}
 	
 	public boolean isQuestItem() {
@@ -1861,4 +1846,13 @@ public final class L2ItemInstance extends L2Object {
 			_lifeTimeTask = null;
 		}
 	}
+	
+	public int getAgathionRemainingEnergy() {
+		return agathionEnergy;
+	}
+	
+	public void setAgathionRemainingEnergy(int agathionEnergy) {
+		this.agathionEnergy = agathionEnergy;
+		_storedInDb = false;
+	}
 }

+ 32 - 46
src/main/java/com/l2jserver/gameserver/model/skills/Skill.java

@@ -115,11 +115,11 @@ public class Skill implements IIdentifiable {
 	private final AbnormalType _abnormalType;
 	/** Abnormal time: global effect duration time. */
 	private final int _abnormalTime;
-	/** Abnormal visual effect: the visual effect displayed ingame. */
+	/** Abnormal visual effect: the visual effect displayed in game. */
 	private AbnormalVisualEffect[] _abnormalVisualEffects = null;
-	/** Abnormal visual effect special: the visual effect displayed ingame. */
+	/** Abnormal visual effect special: the visual effect displayed in game. */
 	private AbnormalVisualEffect[] _abnormalVisualEffectsSpecial = null;
-	/** Abnormal visual effect event: the visual effect displayed ingame. */
+	/** Abnormal visual effect event: the visual effect displayed in game. */
 	private AbnormalVisualEffect[] _abnormalVisualEffectsEvent = null;
 	/** If {@code true} this skill's effect should stay after death. */
 	private final boolean _stayAfterDeath;
@@ -867,7 +867,7 @@ public class Skill implements IIdentifiable {
 		// Init to null the target of the skill
 		L2Character target = null;
 		
-		// Get the L2Objcet targeted by the user of the skill at this moment
+		// Get the object targeted by the user of the skill at this moment
 		L2Object objTarget = activeChar.getTarget();
 		// If the L2Object targeted is a L2Character, it becomes the L2Character target
 		if (objTarget instanceof L2Character) {
@@ -933,7 +933,7 @@ public class Skill implements IIdentifiable {
 	 * @param sourceInArena
 	 * @return
 	 */
-	public static final boolean checkForAreaOffensiveSkills(L2Character caster, L2Character target, Skill skill, boolean sourceInArena) {
+	public static boolean checkForAreaOffensiveSkills(L2Character caster, L2Character target, Skill skill, boolean sourceInArena) {
 		if ((target == null) || target.isDead() || (target == caster)) {
 			return false;
 		}
@@ -994,38 +994,30 @@ public class Skill implements IIdentifiable {
 				return false;
 			}
 		}
-		
-		if (!GeoData.getInstance().canSeeTarget(caster, target)) {
-			return false;
-		}
-		return true;
+		return GeoData.getInstance().canSeeTarget(caster, target);
 	}
 	
-	public static final boolean addSummon(L2Character caster, L2PcInstance owner, int radius, boolean isDead) {
+	public static boolean addSummon(L2Character caster, L2PcInstance owner, int radius, boolean isDead) {
 		if (!owner.hasSummon()) {
 			return false;
 		}
 		return addCharacter(caster, owner.getSummon(), radius, isDead);
 	}
 	
-	public static final boolean addCharacter(L2Character caster, L2Character target, int radius, boolean isDead) {
+	public static boolean addCharacter(L2Character caster, L2Character target, int radius, boolean isDead) {
 		if (isDead != target.isDead()) {
 			return false;
 		}
-		
-		if ((radius > 0) && !Util.checkIfInRange(radius, caster, target, true)) {
-			return false;
-		}
-		return true;
+		return (radius <= 0) || Util.checkIfInRange(radius, caster, target, true);
 	}
 	
 	public List<AbstractFunction> getStatFuncs(AbstractEffect effect, L2Character player) {
 		if (_funcTemplates == null) {
-			return Collections.<AbstractFunction> emptyList();
+			return Collections.emptyList();
 		}
 		
 		if (!(player instanceof L2Playable) && !(player instanceof L2Attackable)) {
-			return Collections.<AbstractFunction> emptyList();
+			return Collections.emptyList();
 		}
 		
 		final List<AbstractFunction> funcs = new ArrayList<>(_funcTemplates.size());
@@ -1307,11 +1299,7 @@ public class Skill implements IIdentifiable {
 	 * @param effect the effect to add
 	 */
 	public void addEffect(EffectScope effectScope, AbstractEffect effect) {
-		List<AbstractEffect> effects = _effectLists.get(effectScope);
-		if (effects == null) {
-			effects = new ArrayList<>(1);
-			_effectLists.put(effectScope, effects);
-		}
+		final var effects = _effectLists.computeIfAbsent(effectScope, k -> new ArrayList<>(1));
 		effects.add(effect);
 	}
 	
@@ -1389,7 +1377,7 @@ public class Skill implements IIdentifiable {
 		for (String prodList : prodLists) {
 			prodData = prodList.split(",");
 			if (prodData.length < 3) {
-				_log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " -> wrong seperator!");
+				_log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " -> wrong separator!");
 			}
 			List<ItemHolder> items = null;
 			double chance = 0;
@@ -1400,13 +1388,13 @@ public class Skill implements IIdentifiable {
 					final int prodId = Integer.parseInt(prodData[j]);
 					final int quantity = Integer.parseInt(prodData[j + 1]);
 					if ((prodId <= 0) || (quantity <= 0)) {
-						_log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " wrong production Id: " + prodId + " or wrond quantity: " + quantity + "!");
+						_log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " wrong production Id: " + prodId + " or wrong quantity: " + quantity + "!");
 					}
 					items.add(new ItemHolder(prodId, quantity));
 				}
 				chance = Double.parseDouble(prodData[length]);
 			} catch (Exception e) {
-				_log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " -> incomplete/invalid production data or wrong seperator!");
+				_log.warning("Extractable skills data: Error in Skill Id: " + skillId + " Level: " + skillLvl + " -> incomplete/invalid production data or wrong separator!");
 			}
 			products.add(new L2ExtractableProductItem(items, chance));
 		}
@@ -1429,28 +1417,26 @@ public class Skill implements IIdentifiable {
 			List<AbnormalVisualEffect> aves = null;
 			for (String ave2 : data) {
 				final AbnormalVisualEffect ave = AbnormalVisualEffect.valueOf(ave2);
-				if (ave != null) {
-					if (ave.isEvent()) {
-						if (avesEvent == null) {
-							avesEvent = new ArrayList<>(1);
-						}
-						avesEvent.add(ave);
-						continue;
+				if (ave.isEvent()) {
+					if (avesEvent == null) {
+						avesEvent = new ArrayList<>(1);
 					}
-					
-					if (ave.isSpecial()) {
-						if (avesSpecial == null) {
-							avesSpecial = new ArrayList<>(1);
-						}
-						avesSpecial.add(ave);
-						continue;
-					}
-					
-					if (aves == null) {
-						aves = new ArrayList<>(1);
+					avesEvent.add(ave);
+					continue;
+				}
+
+				if (ave.isSpecial()) {
+					if (avesSpecial == null) {
+						avesSpecial = new ArrayList<>(1);
 					}
-					aves.add(ave);
+					avesSpecial.add(ave);
+					continue;
+				}
+
+				if (aves == null) {
+					aves = new ArrayList<>(1);
 				}
+				aves.add(ave);
 			}
 			
 			if (avesEvent != null) {

+ 52 - 0
src/main/java/com/l2jserver/gameserver/network/serverpackets/ExBR_AgathionEnergyInfo.java

@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2004-2020 L2J Server
+ * 
+ * This file is part of L2J Server.
+ * 
+ * L2J Server is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * L2J Server is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.l2jserver.gameserver.network.serverpackets;
+
+import java.util.List;
+
+import com.l2jserver.gameserver.agathion.repository.AgathionRepository;
+import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
+
+/**
+ * Agathion Energy Info packet.
+ * @author Zoey76
+ * @version 2.6.2.0
+ */
+public class ExBR_AgathionEnergyInfo extends L2GameServerPacket {
+	
+	private final List<L2ItemInstance> agathions;
+	
+	public ExBR_AgathionEnergyInfo(List<L2ItemInstance> agathions) {
+		this.agathions = agathions;
+	}
+	
+	@Override
+	protected final void writeImpl() {
+		writeC(0xFE);
+		writeH(0xDE);
+		writeD(agathions.size());
+		for (var agathion : agathions) {
+			writeD(agathion.getObjectId());
+			writeD(agathion.getId());
+			writeD(0x200000);
+			writeD(agathion.getAgathionRemainingEnergy());
+			writeD(AgathionRepository.getInstance().getByItemId(agathion.getId()).getEnergy());
+		}
+	}
+}

+ 32 - 15
src/main/java/com/l2jserver/gameserver/network/serverpackets/ItemList.java

@@ -18,24 +18,40 @@
  */
 package com.l2jserver.gameserver.network.serverpackets;
 
-import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 
+import com.l2jserver.gameserver.agathion.repository.AgathionRepository;
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
 
+/**
+ * Item List server packet.
+ * @author Zoey76
+ * @version 2.6.2.0
+ */
 public final class ItemList extends AbstractItemPacket {
-	private final L2PcInstance _activeChar;
-	private final List<L2ItemInstance> _items = new ArrayList<>();
-	private final boolean _showWindow;
 	
-	public ItemList(L2PcInstance activeChar, boolean showWindow) {
-		_activeChar = activeChar;
-		_showWindow = showWindow;
+	private final L2PcInstance player;
+	
+	private final List<L2ItemInstance> items = new LinkedList<>();
+	
+	private final List<L2ItemInstance> agathions = new LinkedList<>();
+	
+	private final boolean showWindow;
+	
+	public ItemList(L2PcInstance player, boolean showWindow) {
+		this.player = player;
+		this.showWindow = showWindow;
 		
-		for (L2ItemInstance item : activeChar.getInventory().getItems()) {
+		for (var item : player.getInventory().getItems()) {
 			if (!item.isQuestItem()) {
-				_items.add(item);
+				items.add(item);
+			}
+			
+			final var agathion = AgathionRepository.getInstance().getByItemId(item.getId());
+			if ((agathion != null) && (agathion.getMaxEnergy() > 0)) {
+				agathions.add(item);
 			}
 		}
 	}
@@ -43,16 +59,17 @@ public final class ItemList extends AbstractItemPacket {
 	@Override
 	protected void writeImpl() {
 		writeC(0x11);
-		writeH(_showWindow ? 0x01 : 0x00);
-		writeH(_items.size());
-		for (L2ItemInstance item : _items) {
-			writeItem(item);
+		writeH(showWindow ? 0x01 : 0x00);
+		writeH(items.size());
+		items.forEach(this::writeItem);
+		writeInventoryBlock(player.getInventory());
+		if (!agathions.isEmpty()) {
+			player.sendPacket(new ExBR_AgathionEnergyInfo(agathions));
 		}
-		writeInventoryBlock(_activeChar.getInventory());
 	}
 	
 	@Override
 	public void runImpl() {
-		getClient().sendPacket(new ExQuestItemList(_activeChar));
+		getClient().sendPacket(new ExQuestItemList(player));
 	}
 }