package ai; import java.util.Collection; import java.util.HashSet; import java.util.List; import org.slf4j.LoggerFactory; import com.aionemu.gameserver.ai.AIActions; import com.aionemu.gameserver.ai.AIName; import com.aionemu.gameserver.configs.main.DropConfig; import com.aionemu.gameserver.configs.main.GroupConfig; import com.aionemu.gameserver.dataholders.DataManager; import com.aionemu.gameserver.model.gameobjects.Npc; import com.aionemu.gameserver.model.gameobjects.player.Player; import com.aionemu.gameserver.model.gameobjects.state.CreatureState; import com.aionemu.gameserver.model.team.TemporaryPlayerTeam; import com.aionemu.gameserver.model.templates.chest.ChestTemplate; import com.aionemu.gameserver.model.templates.chest.KeyItem; import com.aionemu.gameserver.services.drop.DropRegistrationService; import com.aionemu.gameserver.services.drop.DropService; import com.aionemu.gameserver.utils.PacketSendUtility; import com.aionemu.gameserver.utils.PositionUtil; import com.aionemu.gameserver.utils.audit.AuditLogger; /** * @author ATracer, xTz */ @AIName("chest") public class ChestAI extends ActionItemNpcAI { private ChestTemplate chestTemplate; public ChestAI(Npc owner) { super(owner); } @Override protected void handleDialogStart(final Player player) { chestTemplate = DataManager.CHEST_DATA.getChestTemplate(getNpcId()); if (chestTemplate == null) { LoggerFactory.getLogger(ChestAI.class).warn("Missing chest template or incorrect AI for npc " + getNpcId()); return; } super.handleDialogStart(player); } @Override protected void handleUseItemFinish(Player player) { if (tryOpening(player)) { if (getOwner().isInState(CreatureState.DEAD)) { AuditLogger.log(player, "attempted multiple chest looting!"); return; } Collection players = new HashSet<>(); TemporaryPlayerTeam playerTeam = player.getCurrentTeam(); if (playerTeam != null) { int range = DropConfig.DISABLE_RANGE_CHECK_MAPS.contains(getPosition().getMapId()) ? 9999 : GroupConfig.GROUP_MAX_DISTANCE; for (Player member : playerTeam.getOnlineMembers()) { if (PositionUtil.isInRange(member, getOwner(), range)) players.add(member); } } if (players.isEmpty()) // no team or nobody was in range players.add(player); DropRegistrationService.getInstance().registerDrop(getOwner(), player, getHighestLevel(players), players); AIActions.die(this, player); DropService.getInstance().requestDropList(player, getObjectId()); super.handleUseItemFinish(player); } else { PacketSendUtility.sendMonologue(player, 1111301); // I'll need a key to open this. } } private boolean tryOpening(Player player) { List keyItems = chestTemplate.getKeyItems(); for (KeyItem keyItem : keyItems) { // check if enough key items are available if (keyItem.getItemIds() != null && keyItem.getItemIds().stream().anyMatch(itemId -> itemId == 0)) // chest can be opened w/o keys return true; long availableKeys = 0; for (Integer keyItemId : keyItem.getItemIds()) { availableKeys += player.getInventory().getItemCountByItemId(keyItemId); } if (availableKeys < keyItem.getCount()) return false; } for (KeyItem keyItem : keyItems) { // remove key items long keyCountToDecrease = keyItem.getCount(); for (Integer keyItemId : keyItem.getItemIds()) { long availableKeys = player.getInventory().getItemCountByItemId(keyItemId); if (availableKeys >= keyCountToDecrease) { player.getInventory().decreaseByItemId(keyItemId, keyCountToDecrease); keyCountToDecrease = 0; } else { keyCountToDecrease -= availableKeys; player.getInventory().decreaseByItemId(keyItemId, availableKeys); } } } return true; } private int getHighestLevel(Collection players) { return players.stream().mapToInt(Player::getLevel).max().getAsInt(); } }