/* * This file is part of the Illarion project. * * Copyright © 2015 - Illarion e.V. * * Illarion is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Illarion 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. */ package illarion.common.types; import illarion.common.net.NetCommReader; import illarion.common.net.NetCommWriter; import org.jetbrains.annotations.Contract; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; import javax.annotation.concurrent.ThreadSafe; import java.io.IOException; import java.io.Serializable; /** * This class is used to store the ID of a character. * * @author Martin Karing <nitram@illarion.org> */ @Immutable @ThreadSafe public final class CharacterId implements Serializable, Comparable<CharacterId> { /** * This is the mask used to find out the type of the character that is represented by this ID. */ private static final int TYPE_MASK = 0xFF000000; /** * In case the character ID fits this mask, the character is a NPC. */ private static final int NPC_MASK = 0xFF000000; /** * In case the character ID fits this mask, the character is a monster. */ private static final int MONSTER_MASK = 0xFE000000; /** * The item count. */ private final int value; /** * Constructor of this class used to set. * * @param value the value of the character ID */ public CharacterId(int value) { this.value = value; } /** * This constructor is used to decode the character ID from the network interface. * * @param reader the reader * @throws IOException in case the reading operation fails for some reason */ public CharacterId(@Nonnull NetCommReader reader) throws IOException { this(reader.readInt()); } /** * Check if this character ID is the ID of a NPC. * * @return {@code true} in case this ID marks a NPC */ @Contract(pure = true) public boolean isNPC() { return (value & TYPE_MASK) == NPC_MASK; } /** * Check if this character ID is the ID of a monster. * * @return {@code true} in case this ID marks a monster */ @Contract(pure = true) public boolean isMonster() { return (value & TYPE_MASK) == MONSTER_MASK; } /** * Check if this character ID is the ID of a human controlled character. * * @return {@code true} in case this ID marks a human controlled character */ @Contract(pure = true) public boolean isHuman() { return !isNPC() && !isMonster(); } @Override @Contract(value = "null->false", pure = true) public boolean equals(@Nullable Object obj) { return super.equals(obj) || ((obj instanceof CharacterId) && equals((CharacterId) obj)); } @Override @Contract(pure = true) public int hashCode() { return value; } @Nonnull @Override @Contract(pure = true) public String toString() { return "character ID: " + Long.toString(getValue()); } /** * Encode the value of the item count to the network interface. * * @param writer the writer that receives the value */ public void encode(@Nonnull NetCommWriter writer) { writer.writeInt(value); } /** * Check if two item count instances are equal. * * @param obj the second instance to check * @return {@code true} in case both instances represent the same value */ @Contract(value = "null->false", pure = true) public boolean equals(@Nullable CharacterId obj) { return (obj != null) && (value == obj.value); } /** * Get the value of the item count. * * @return the item count value */ @Contract(pure = true) public long getValue() { if (value < 0) { return value + (1L << Integer.SIZE); } return value; } @Contract(pure = true) public int getAsInteger() { return value; } @Override @Contract(pure = true) public int compareTo(@Nonnull CharacterId o) { if (value == o.value) { return 0; } if (getValue() < o.getValue()) { return -1; } return 1; } }