package com.asteria.game.item.container;
import com.asteria.game.character.Flag;
import com.asteria.game.character.player.Player;
import com.asteria.game.character.player.content.Requirement;
import com.asteria.game.character.player.content.WeaponAnimation;
import com.asteria.game.character.player.content.WeaponInterface;
import com.asteria.game.character.player.minigame.MinigameHandler;
import com.asteria.game.item.Item;
/**
* The container that manages the equipment for a player.
*
* @author lare96 <http://github.com/lare96>
*/
public final class Equipment extends ItemContainer {
/**
* The head identification equipment slot.
*/
public static final int HEAD_SLOT = 0;
/**
* The cape identification equipment slot.
*/
public static final int CAPE_SLOT = 1;
/**
* The amulet identification equipment slot.
*/
public static final int AMULET_SLOT = 2;
/**
* The weapon identification equipment slot.
*/
public static final int WEAPON_SLOT = 3;
/**
* The chest identification equipment slot.
*/
public static final int CHEST_SLOT = 4;
/**
* The shield identification equipment slot.
*/
public static final int SHIELD_SLOT = 5;
/**
* The legs identification equipment slot.
*/
public static final int LEGS_SLOT = 7;
/**
* The hands identification equipment slot.
*/
public static final int HANDS_SLOT = 9;
/**
* The feet identification equipment slot.
*/
public static final int FEET_SLOT = 10;
/**
* The ring identification equipment slot.
*/
public static final int RING_SLOT = 12;
/**
* The arrows identification equipment slot.
*/
public static final int ARROWS_SLOT = 13;
/**
* The player who's equipment is being managed.
*/
private final Player player;
/**
* Creates a new {@link Equipment}.
*
* @param player
* the player who's equipment is being managed.
*/
public Equipment(Player player) {
super(14, ItemContainerPolicy.NORMAL);
this.player = player;
}
/**
* Refreshes the contents of this equipment container to the interface.
*/
public void refresh() {
refresh(player, 1688);
player.sendBonus();
}
/**
* Equips the item in {@code inventorySlot} to the equipment container.
*
* @param inventorySlot
* the slot to equip the item on.
* @return {@code true} if the item was equipped, {@code false} otherwise.
*/
public boolean equipItem(int inventorySlot) {
Item item = player.getInventory().get(inventorySlot);
if (!Item.valid(item))
return false;
if (!MinigameHandler.execute(player, true, m -> m.canEquip(player, item, item.getDefinition().getEquipmentSlot())))
return false;
if (!Requirement.canEquip(player, item))
return false;
if (item.getDefinition().isStackable()) {
int designatedSlot = item.getDefinition().getEquipmentSlot();
Item equipItem = get(designatedSlot);
if (used(designatedSlot)) {
if (item.getId() == equipItem.getId()) {
set(designatedSlot, new Item(item.getId(), item.getAmount() + equipItem.getAmount()));
} else {
player.getInventory().set(inventorySlot, equipItem);
player.getInventory().refresh();
set(designatedSlot, item);
}
} else {
set(designatedSlot, item);
}
player.getInventory().remove(item, inventorySlot);
} else {
int designatedSlot = item.getDefinition().getEquipmentSlot();
if (designatedSlot == Equipment.WEAPON_SLOT && item.getDefinition().isTwoHanded() && used(Equipment.SHIELD_SLOT)) {
if (!unequipItem(Equipment.SHIELD_SLOT, true))
return false;
}
if (designatedSlot == Equipment.SHIELD_SLOT && used(Equipment.WEAPON_SLOT)) {
if (get(Equipment.WEAPON_SLOT).getDefinition().isTwoHanded()) {
if (!unequipItem(Equipment.WEAPON_SLOT, true))
return false;
}
}
if (used(designatedSlot)) {
Item equipItem = get(designatedSlot);
if (!equipItem.getDefinition().isStackable()) {
player.getInventory().set(inventorySlot, equipItem);
} else {
player.getInventory().set(inventorySlot, null);
player.getInventory().add(equipItem, inventorySlot);
}
player.getInventory().refresh();
} else {
player.getInventory().remove(item, inventorySlot);
}
set(designatedSlot, new Item(item.getId(), item.getAmount()));
}
if (item.getDefinition().getEquipmentSlot() == Equipment.WEAPON_SLOT) {
WeaponInterface.execute(player, item);
WeaponAnimation.execute(player, item);
player.setCastSpell(null);
player.setAutocastSpell(null);
player.setAutocast(false);
player.getMessages().sendByteState(108, 0);
player.getMessages().sendByteState(301, 0);
player.setSpecialActivated(false);
}
refresh();
player.getFlags().set(Flag.APPEARANCE);
return true;
}
/**
* Unequips the item in {@code equipmentSlot} from the equipment container.
*
* @param equipmentSlot
* the slot to unequip the item on.
* @param addItem
* if the unequipped item should be added to the inventory.
* @return {@code true} if the item was unequipped, {@code false} otherwise.
*/
public boolean unequipItem(int equipmentSlot, boolean addItem) {
if (free(equipmentSlot))
return false;
Item item = get(equipmentSlot);
if (!MinigameHandler.execute(player, true, m -> m.canUnequip(player, item, item.getDefinition().getEquipmentSlot())))
return false;
if (!player.getInventory().spaceFor(item)) {
player.getMessages().sendMessage("You do not have enough space in " + "your inventory!");
return false;
}
super.remove(item, equipmentSlot);
if (addItem)
player.getInventory().add(new Item(item.getId(), item.getAmount()));
if (equipmentSlot == Equipment.WEAPON_SLOT) {
WeaponInterface.execute(player, null);
player.setCastSpell(null);
player.setAutocastSpell(null);
player.setAutocast(false);
player.getMessages().sendByteState(108, 0);
player.setWeaponAnimation(null);
player.getMessages().sendByteState(301, 0);
player.setSpecialActivated(false);
}
refresh();
player.getInventory().refresh();
player.getFlags().set(Flag.APPEARANCE);
return true;
}
/**
* Unequips {@code item} from the equipment container.
*
* @param item
* the item to unequip from this container.
* @param addItem
* if the unequipped item should be added to the inventory.
* @return {@code true} if the item was unequipped, {@code false} otherwise.
*/
public boolean unequipItem(Item item, boolean addItem) {
int slot = super.searchSlot(item.getId());
if (slot == -1)
return false;
return unequipItem(slot, addItem);
}
/**
* This method is not supported by this container implementation.
*
* @throws UnsupportedOperationException
* if this method is invoked by default, this method will always
* throw an exception.
*/
@Override
public boolean add(Item item, int slot) {
throw new UnsupportedOperationException("This method is not supported" + " by this container implementation!");
}
/**
* This method is not supported by this container implementation.
*
* @throws UnsupportedOperationException
* if this method is invoked by default, this method will always
* throw an exception.
*/
@Override
public boolean remove(Item item, int slot) {
throw new UnsupportedOperationException("This method is not supported by this container implementation!");
}
}