package com.asteria.game.item; import com.asteria.game.Node; import com.asteria.game.NodeType; import com.asteria.game.World; import com.asteria.game.character.player.Player; import com.asteria.game.location.Position; import com.asteria.utility.MutableNumber; /** * The node implementation that represents an item on the ground. * * @author lare96 <http://github.com/lare96> */ public class ItemNode extends Node { /** * The item concealed within this node. */ private final Item item; /** * The counter that contains the amount of ticks this node has. */ private final MutableNumber counter = new MutableNumber(); /** * The item state of this node. */ private ItemState state = ItemState.SEEN_BY_OWNER; /** * The player attached to this node. */ private Player player; /** * Creates new {@link ItemNode}. * * @param item * the item concealed within this node. * @param position * the position this node is on. * @param player * the player attached to this node. */ public ItemNode(Item item, Position position, Player player) { super(position, NodeType.ITEM); this.item = item.copy(); this.player = player; } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((counter == null) ? 0 : counter.hashCode()); result = prime * result + ((item == null) ? 0 : item.hashCode()); result = prime * result + ((player == null) ? 0 : player.hashCode()); result = prime * result + ((state == null) ? 0 : state.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (!(obj instanceof ItemNode)) return false; ItemNode other = (ItemNode) obj; if (counter == null) { if (other.counter != null) return false; } else if (!counter.equals(other.counter)) return false; if (item == null) { if (other.item != null) return false; } else if (!item.equals(other.item)) return false; if (player == null) { if (other.player != null) return false; } else if (!player.equals(other.player)) return false; if (state != other.state) return false; return true; } @Override public void create() { player.getMessages().sendGroundItem(this); } @Override public void dispose() { switch (state) { case SEEN_BY_EVERYONE: World.getPlayers().forEach(p -> { if (super.getPosition().withinDistance(p.getPosition(), 60)) { p.getMessages().sendRemoveGroundItem(this); } }); break; case SEEN_BY_OWNER: World.getPlayer(player.getUsernameHash()).ifPresent(p -> p.getMessages().sendRemoveGroundItem(this)); break; default: throw new IllegalStateException("Invalid item node state!"); } } /** * The method executed on every sequence by the item node manager. * * @throws IllegalStateException * if the item node is in an incorrect state. */ public void onSequence() { switch (state) { case SEEN_BY_OWNER: World.getPlayers().forEach(p -> { if (super.getPosition().withinDistance(p.getPosition(), 60) && !p.equals(player)) { p.getMessages().sendGroundItem(new ItemNode(item, super.getPosition(), null)); } }); player = null; state = ItemState.SEEN_BY_EVERYONE; break; case SEEN_BY_EVERYONE: super.setRegistered(false); break; default: throw new IllegalStateException("Invalid item node state!"); } } /** * The method executed when {@code player} attempts to pickup this item. * * @param player * the player attempting to pickup this item. */ public void onPickup(Player player) { ItemNodeManager.unregister(this); player.getInventory().add(item); } /** * Gets the item state of this node. * * @return the item state. */ public final ItemState getState() { return state; } /** * Sets the value for {@link ItemNode#state}. * * @param state * the new value to set. */ public final void setState(ItemState state) { this.state = state; } /** * Gets the player attached to this node. * * @return the player attached. */ public final Player getPlayer() { return player; } /** * Sets the value for {@link ItemNode#player}. * * @param player * the new value to set. */ public final void setPlayer(Player player) { this.player = player; } /** * Gets the item concealed within this node. * * @return the item concealed. */ public final Item getItem() { return item; } /** * Gets the counter that contains the amount of ticks this node has. * * @return the counter that contains the ticks. */ public final MutableNumber getCounter() { return counter; } }