package com.asteria.game.character.player;
import io.netty.buffer.ByteBuf;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
import plugin.minigames.fightcaves.FightCavesHandler;
import plugin.skills.cooking.CookingData;
import com.asteria.game.GameConstants;
import com.asteria.game.NodeType;
import com.asteria.game.World;
import com.asteria.game.character.CharacterNode;
import com.asteria.game.character.Flag;
import com.asteria.game.character.Hit;
import com.asteria.game.character.combat.Combat;
import com.asteria.game.character.combat.CombatStrategy;
import com.asteria.game.character.combat.CombatType;
import com.asteria.game.character.combat.effect.CombatEffect;
import com.asteria.game.character.combat.effect.CombatEffectTask;
import com.asteria.game.character.combat.effect.CombatPoisonEffect;
import com.asteria.game.character.combat.magic.CombatSpell;
import com.asteria.game.character.combat.magic.CombatWeaken;
import com.asteria.game.character.combat.prayer.CombatPrayer;
import com.asteria.game.character.combat.ranged.CombatRangedAmmo;
import com.asteria.game.character.combat.weapon.CombatSpecial;
import com.asteria.game.character.combat.weapon.FightType;
import com.asteria.game.character.npc.Npc;
import com.asteria.game.character.npc.NpcAggression;
import com.asteria.game.character.player.content.PrivateMessage;
import com.asteria.game.character.player.content.Spellbook;
import com.asteria.game.character.player.content.TeleportSpell;
import com.asteria.game.character.player.content.TradeSession;
import com.asteria.game.character.player.content.ViewingOrb;
import com.asteria.game.character.player.content.WeaponAnimation;
import com.asteria.game.character.player.content.WeaponInterface;
import com.asteria.game.character.player.dialogue.DialogueChainBuilder;
import com.asteria.game.character.player.dialogue.OptionType;
import com.asteria.game.character.player.minigame.MinigameHandler;
import com.asteria.game.character.player.serialize.PlayerSerialization;
import com.asteria.game.character.player.skill.Skill;
import com.asteria.game.character.player.skill.Skills;
import com.asteria.game.item.Item;
import com.asteria.game.item.container.Bank;
import com.asteria.game.item.container.Equipment;
import com.asteria.game.item.container.Inventory;
import com.asteria.game.location.Location;
import com.asteria.game.location.Position;
import com.asteria.game.shop.Shop;
import com.asteria.net.PlayerIO;
import com.asteria.net.message.OutputMessages;
import com.asteria.task.Task;
import com.asteria.utility.LoggerUtils;
import com.asteria.utility.MutableNumber;
import com.asteria.utility.Stopwatch;
import com.asteria.utility.TextUtils;
/**
* The character implementation that represents a node that is operated by an
* actual person. This type of node functions solely through communication with
* the client, by reading data from and writing data to non-blocking sockets.
*
* @author lare96 <http://github.com/lare96>
*/
public final class Player extends CharacterNode {
/**
* The player appearance update white skull identifier.
*/
public static final int WHITE_SKULL = 0;
/**
* The player appearance update red skull identifier.
*/
public static final int RED_SKULL = 1;
/**
* The logger that will print important information.
*/
private static Logger logger = LoggerUtils.getLogger(Player.class);
/**
* The hash collection of the local players.
*/
private final Set<Player> localPlayers = new LinkedHashSet<>(255);
/**
* The hash collection of the local npcs.
*/
private final Set<Npc> localNpcs = new LinkedHashSet<>(255);
/**
* The hash collection of friends.
*/
private final Set<Long> friends = new HashSet<>(200);
/**
* The hash collection of ignores.
*/
private final Set<Long> ignores = new HashSet<>(100);
/**
* The container that holds the inventory items.
*/
private final Inventory inventory = new Inventory(this);
/**
* The container that holds the bank items.
*/
private final Bank bank = new Bank(this);
/**
* The container that holds the equipment items.
*/
private final Equipment equipment = new Equipment(this);
/**
* The trade session manager that manages trades for this player.
*/
private final TradeSession tradeSession = new TradeSession(this);
/**
* The private message manager that manages messages for this player.
*/
private final PrivateMessage privateMessage = new PrivateMessage(this);
/**
* The dialogue chain builder for this player.
*/
private final DialogueChainBuilder dialogueChain = new DialogueChainBuilder(this);
/**
* The I/O manager that manages I/O operations for this player.
*/
private final PlayerIO session;
/**
* The array of skills that can be trained by this player.
*/
private final Skill[] skills = new Skill[21];
/**
* The array of attack and defence bonus values.
*/
private final int[] bonus = new int[12];
/**
* The array of booleans determining which prayers are active.
*/
private final EnumSet<CombatPrayer> prayerActive = EnumSet.noneOf(CombatPrayer.class);
/**
* The collection of stopwatches used for various timing operations.
*/
private final Stopwatch eatingTimer = new Stopwatch().reset(), potionTimer = new Stopwatch().reset(), tolerance = new Stopwatch(),
lastEnergy = new Stopwatch().reset(), buryTimer = new Stopwatch(), logoutTimer = new Stopwatch();
/**
* The collection of counters used for various counting operations.
*/
private final MutableNumber poisonImmunity = new MutableNumber(), teleblockTimer = new MutableNumber(),
fireImmunity = new MutableNumber(), skullTimer = new MutableNumber(), runEnergy = new MutableNumber(100),
specialPercentage = new MutableNumber(100);
/**
* The encoder that will encode and send messages.
*/
private final OutputMessages messages;
/**
* The container of appearance values for this player.
*/
private final Appearance appearance = new Appearance();
/**
* The amount of authority this player has over others.
*/
private Rights rights = Rights.PLAYER;
/**
* The current username of this player.
*/
private String username;
/**
* The current password of this player.
*/
private String password;
/**
* The combat spell currently selected.
*/
private CombatSpell castSpell;
/**
* The type of ranged ammo currently being used.
*/
private CombatRangedAmmo rangedAmmo;
/**
* The flag that determines if the player is autocasting.
*/
private boolean autocast;
/**
* The combat spell currently being autocasted.
*/
private CombatSpell autocastSpell;
/**
* The combat special that has been activated.
*/
private CombatSpecial combatSpecial;
/**
* The ammo that was just fired with.
*/
private int fireAmmo;
/**
* The current viewing orb that this player has open.
*/
private ViewingOrb viewingOrb;
/**
* The flag that determines if this player is disabled.
*/
private boolean disabled;
/**
* The flag that determines if the special bar has been activated.
*/
private boolean specialActivated;
/**
* The skill event flag that determines if a player is executing a skill
* action.
*/
private boolean skillAction;
/**
* The current fight type the player is using.
*/
private FightType fightType = FightType.UNARMED_PUNCH;
/**
* The weapon animation for appearance updating.
*/
private WeaponAnimation weaponAnimation;
/**
* The task that handles combat prayer draining.
*/
private Task prayerDrain = null;
/**
* The wilderness level this player is in.
*/
private int wildernessLevel;
/**
* The weapon interface this player currently has open.
*/
private WeaponInterface weapon;
/**
* The current teleport stage that this player is in.
*/
private int teleportStage;
/**
* The shop that you currently have open.
*/
private String openShop;
/**
* The flag that determines if you are using a stove or not.
*/
private boolean usingStove;
/**
* The cooking data being used for the cooking skill.
*/
private CookingData cookData;
/**
* The position of the fire or stove being cooked with.
*/
private Position cookPosition;
/**
* The flag that determines if this player is banned or not.
*/
private boolean banned;
/**
* The flag that determines if this player has 'accept aid' toggled.
*/
private boolean acceptAid = true;
/**
* The option value used for npc dialogues.
*/
private OptionType option;
/**
* The identifier for the head icon of this player.
*/
private int headIcon = -1;
/**
* The identifier for the skull icon of this player.
*/
private int skullIcon = -1;
/**
* The flag that determines if a wilderness interface is present.
*/
private boolean wildernessInterface;
/**
* The flag that determines if a multicombat interface is present.
*/
private boolean multicombatInterface;
/**
* The flag that determines if this player is new.
*/
private boolean newPlayer = true;
/**
* The flag that determines if items should be inserted when banking.
*/
private boolean insertItem;
/**
* The flag that determines if a bank item should be withdrawn as a note.
*/
private boolean withdrawAsNote;
/**
* The current spellbook the player has open.
*/
private Spellbook spellbook = Spellbook.NORMAL;
/**
* The array of chat text packed into bytes.
*/
private byte[] chatText;
/**
* The current chat color the player is using.
*/
private int chatColor;
/**
* The current chat effects the player is using.
*/
private int chatEffects;
/**
* The player-npc identifier for updating.
*/
private int playerNpc = -1;
/**
* The cached player update block for updating.
*/
private ByteBuf cachedUpdateBlock;
/**
* The username hash for this player.
*/
private long usernameHash;
/**
* If the region has been updated this sequence.
*/
private boolean updateRegion;
/**
* Creates a new {@link Player}.
*
* @param session
* the I/O manager that manages I/O operations for this player.
*/
public Player(PlayerIO session) {
super(GameConstants.STARTING_POSITION, NodeType.PLAYER);
this.session = session;
this.messages = new OutputMessages(this);
}
@Override
public void create() {
OutputMessages encoder = getMessages();
encoder.sendMapRegion();
encoder.sendDetails();
super.getFlags().set(Flag.APPEARANCE);
encoder.sendSidebarInterface(1, 3917);
encoder.sendSidebarInterface(2, 638);
encoder.sendSidebarInterface(3, 3213);
encoder.sendSidebarInterface(4, 1644);
encoder.sendSidebarInterface(5, 5608);
encoder.sendSidebarInterface(6, spellbook.getId());
encoder.sendSidebarInterface(8, 5065);
encoder.sendSidebarInterface(9, 5715);
encoder.sendSidebarInterface(10, 2449);
encoder.sendSidebarInterface(11, 904);
encoder.sendSidebarInterface(12, 147);
encoder.sendSidebarInterface(13, 962);
encoder.sendSidebarInterface(0, 2423);
move(super.getPosition());
Skills.refreshAll(this);
equipment.refresh();
inventory.refresh();
encoder.sendPrivateMessageListStatus(2);
privateMessage.updateThisList();
privateMessage.updateOtherList(true);
encoder.sendContextMenu(4, "Trade with");
encoder.sendContextMenu(5, "Follow");
if (newPlayer) {
inventory.addAll(GameConstants.STARTER_PACKAGE);
encoder.sendInterface(3559);
newPlayer = false;
}
CombatEffect.values().forEach($it -> {
if ($it.onLogin(this))
World.submit(new CombatEffectTask(this, $it));
});
encoder.sendMessage(GameConstants.WELCOME_MESSAGE);
MinigameHandler.execute(this, m -> m.onLogin(this));
WeaponInterface.execute(this, equipment.get(Equipment.WEAPON_SLOT));
WeaponAnimation.execute(this, equipment.get(Equipment.WEAPON_SLOT));
encoder.sendByteState(173, super.getMovementQueue().isRunning() ? 1 : 0);
encoder.sendByteState(172, super.isAutoRetaliate() ? 0 : 1);
encoder.sendByteState(fightType.getParent(), fightType.getChild());
encoder.sendByteState(427, acceptAid ? 1 : 0);
encoder.sendByteState(108, 0);
encoder.sendByteState(301, 0);
encoder.sendString(runEnergy + "%", 149);
CombatPrayer.VALUES.forEach(c -> encoder.sendByteState(c.getConfig(), 0));
logger.info(this + " has logged in.");
session.setState(IOState.LOGGED_IN);
}
@Override
public int hashCode() {
return Long.hashCode(usernameHash);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof Player))
return false;
Player other = (Player) obj;
if (usernameHash != other.usernameHash)
return false;
return true;
}
@Override
public void dispose() {
messages.sendLogout();
}
@Override
public void sequence() throws Exception {
NpcAggression.sequence(this);
this.restoreRunEnergy();
}
@Override
public Hit decrementHealth(Hit hit) {
OutputMessages encoder = getMessages();
if (hit.getDamage() > skills[Skills.HITPOINTS].getLevel()) {
hit = new Hit(skills[Skills.HITPOINTS].getLevel(), hit.getType());
}
skills[Skills.HITPOINTS].decreaseLevel(hit.getDamage());
Skills.refresh(this, Skills.HITPOINTS);
encoder.sendCloseWindows();
return hit;
}
@Override
public CombatStrategy determineStrategy() {
if (specialActivated && castSpell == null) {
if (combatSpecial.getCombat() == CombatType.MELEE) {
return Combat.newDefaultMeleeStrategy();
} else if (combatSpecial.getCombat() == CombatType.RANGED) {
return Combat.newDefaultRangedStrategy();
} else if (combatSpecial.getCombat() == CombatType.MAGIC) {
return Combat.newDefaultMagicStrategy();
}
}
if (castSpell != null || autocastSpell != null) {
return Combat.newDefaultMagicStrategy();
}
if (weapon == WeaponInterface.SHORTBOW || weapon == WeaponInterface.LONGBOW || weapon == WeaponInterface.CROSSBOW || weapon == WeaponInterface.DART || weapon == WeaponInterface.JAVELIN || weapon == WeaponInterface.THROWNAXE || weapon == WeaponInterface.KNIFE) {
return Combat.newDefaultRangedStrategy();
}
return Combat.newDefaultMeleeStrategy();
}
@Override
public void onSuccessfulHit(CharacterNode victim, CombatType type) {
if (type == CombatType.MELEE || weapon == WeaponInterface.DART || weapon == WeaponInterface.KNIFE || weapon == WeaponInterface.THROWNAXE || weapon == WeaponInterface.JAVELIN) {
victim.poison(CombatPoisonEffect.getPoisonType(equipment.get(Equipment.WEAPON_SLOT)).orElse(null));
} else if (type == CombatType.RANGED) {
victim.poison(CombatPoisonEffect.getPoisonType(equipment.get(Equipment.ARROWS_SLOT)).orElse(null));
}
}
@Override
public int getAttackSpeed() {
int speed = weapon.getSpeed();
if (fightType == FightType.CROSSBOW_RAPID || fightType == FightType.SHORTBOW_RAPID || fightType == FightType.LONGBOW_RAPID || fightType == FightType.DART_RAPID || fightType == FightType.KNIFE_RAPID || fightType == FightType.THROWNAXE_RAPID || fightType == FightType.JAVELIN_RAPID) {
speed--;
} else if (fightType == FightType.CROSSBOW_LONGRANGE || fightType == FightType.SHORTBOW_LONGRANGE || fightType == FightType.LONGBOW_LONGRANGE || fightType == FightType.DART_LONGRANGE || fightType == FightType.KNIFE_LONGRANGE || fightType == FightType.THROWNAXE_LONGRANGE || fightType == FightType.JAVELIN_LONGRANGE) {
speed++;
}
return speed;
}
@Override
public int getCurrentHealth() {
return skills[Skills.HITPOINTS].getLevel();
}
@Override
public String toString() {
return username == null ? session.toString()
: "PLAYER[username= " + username + ", host= " + session.getHost() + ", rights= " + rights + "]";
}
@Override
public int getBaseAttack(CombatType type) {
if (type == CombatType.RANGED)
return skills[Skills.RANGED].getLevel();
else if (type == CombatType.MAGIC)
return skills[Skills.MAGIC].getLevel();
return skills[Skills.ATTACK].getLevel();
}
@Override
public int getBaseDefence(CombatType type) {
if (type == CombatType.MAGIC)
return skills[Skills.MAGIC].getLevel();
return skills[Skills.DEFENCE].getLevel();
}
@Override
public void healCharacter(int amount) {
int level = skills[Skills.HITPOINTS].getRealLevel();
if ((skills[Skills.HITPOINTS].getLevel() + amount) >= level) {
skills[Skills.HITPOINTS].setLevel(level, true);
} else {
skills[Skills.HITPOINTS].increaseLevel(amount);
}
Skills.refresh(this, Skills.HITPOINTS);
}
@Override
public boolean weaken(CombatWeaken effect) {
OutputMessages encoder = getMessages();
int id = (effect == CombatWeaken.ATTACK_LOW || effect == CombatWeaken.ATTACK_HIGH ? Skills.ATTACK
: effect == CombatWeaken.STRENGTH_LOW || effect == CombatWeaken.STRENGTH_HIGH ? Skills.STRENGTH : Skills.DEFENCE);
if (skills[id].getLevel() < skills[id].getRealLevel())
return false;
skills[id].decreaseLevel((int) ((effect.getRate()) * (skills[id].getLevel())));
encoder.sendMessage("You feel slightly weakened.");
return true;
}
/**
* Attempts to teleport this player somewhere based on {@code spell}.
*
* @param spell
* the spell the player is using to teleport.
*/
public void teleport(TeleportSpell spell) {
if (viewingOrb != null || disabled)
return;
OutputMessages encoder = getMessages();
if (teleportStage > 0)
return;
if (wildernessLevel >= 20) {
encoder.sendMessage("You must be below level 20 wilderness to teleport!");
return;
}
if (teleblockTimer.get() > 0) {
int time = teleblockTimer.get() * 600;
if (time >= 1000 && time <= 60000) {
encoder.sendMessage("You must wait approximately " + ((time) / 1000) + " seconds in order to teleport!");
return;
} else if (time > 60000) {
encoder.sendMessage("You must wait approximately " + ((time) / 60000) + " minutes in order to teleport!");
return;
}
}
if (!MinigameHandler.execute(this, true, m -> m.canTeleport(this, spell.moveTo().copy())))
return;
if (!spell.canCast(this))
return;
FightCavesHandler.remove(this);
encoder.sendWalkable(-1);
teleportStage = 1;
super.getCombatBuilder().reset();
faceCharacter(null);
setFollowing(false);
setFollowCharacter(null);
encoder.sendCloseWindows();
Skills.experience(this, spell.baseExperience(), Skills.MAGIC);
spell.type().execute(this, spell.moveTo());
}
/**
* Attempts to teleport this player somewhere based on the type of spellbook
* they have open.
*
* @param position
* the position that the player will be moved to.
*/
public void teleport(Position position) {
teleport(new TeleportSpell() {
@Override
public Position moveTo() {
return position;
}
@Override
public Spellbook type() {
return spellbook;
}
@Override
public double baseExperience() {
return 0;
}
@Override
public Optional<Item[]> itemsRequired(Player player) {
return Optional.empty();
}
@Override
public int levelRequired() {
return 1;
}
});
}
/**
* Moves this player to {@code position}.
*
* @param position
* the position to move this player to.
*/
public void move(Position position) {
OutputMessages encoder = getMessages();
dialogueChain.interrupt();
getMovementQueue().reset();
encoder.sendCloseWindows();
super.setPosition(position.copy());
setResetMovementQueue(true);
setNeedsPlacement(true);
encoder.sendMapRegion();
}
/**
* Saves the character file for this player.
*/
public void save() {
if (session.getState() != IOState.LOGGED_IN && session.getState() != IOState.LOGGING_OUT)
return;
World.getService().submit(() -> new PlayerSerialization(this).serialize());
}
/**
* Calculates and returns the combat level for this player.
*
* @return the combat level.
*/
public int determineCombatLevel() {
int magLvl = skills[Skills.MAGIC].getRealLevel();
int ranLvl = skills[Skills.RANGED].getRealLevel();
int attLvl = skills[Skills.ATTACK].getRealLevel();
int strLvl = skills[Skills.STRENGTH].getRealLevel();
int defLvl = skills[Skills.DEFENCE].getRealLevel();
int hitLvl = skills[Skills.HITPOINTS].getRealLevel();
int prayLvl = skills[Skills.PRAYER].getRealLevel();
double mag = magLvl * 1.5;
double ran = ranLvl * 1.5;
double attstr = attLvl + strLvl;
double combatLevel = 0;
if (ran > attstr && ran > mag) { // player is ranged class
combatLevel = ((defLvl) * 0.25) + ((hitLvl) * 0.25) + ((prayLvl / 2) * 0.25) + ((ranLvl) * 0.4875);
} else if (mag > attstr) { // player is mage class
combatLevel = (((defLvl) * 0.25) + ((hitLvl) * 0.25) + ((prayLvl / 2) * 0.25) + ((magLvl) * 0.4875));
} else {
combatLevel = (((defLvl) * 0.25) + ((hitLvl) * 0.25) + ((prayLvl / 2) * 0.25) + ((attLvl) * 0.325) + ((strLvl) * 0.325));
}
return (int) combatLevel;
}
/**
* Sends wilderness and multi-combat interfaces as needed.
*/
public void sendInterfaces() {
OutputMessages encoder = getMessages();
if (Location.inWilderness(this)) {
int calculateY = this.getPosition().getY() > 6400 ? super.getPosition().getY() - 6400 : super.getPosition().getY();
wildernessLevel = (((calculateY - 3520) / 8) + 1);
if (!wildernessInterface) {
encoder.sendWalkable(197);
encoder.sendContextMenu(3, "Attack");
wildernessInterface = true;
}
encoder.sendString("@yel@Level: " + wildernessLevel, 199);
} else if (wildernessInterface) {
encoder.sendContextMenu(3, "null");
encoder.sendWalkable(-1);
wildernessInterface = false;
wildernessLevel = 0;
}
if (Location.inMultiCombat(this)) {
if (!multicombatInterface) {
encoder.sendMultiIcon(false);
multicombatInterface = true;
}
} else {
encoder.sendMultiIcon(true);
multicombatInterface = false;
}
}
/**
* Calculates and writes the attack and defence bonuses to the equipment
* sidebar interface.
*/
public void sendBonus() {
OutputMessages encoder = getMessages();
Arrays.fill(bonus, 0);
for (Item item : equipment) {
if (!Item.valid(item))
continue;
for (int i = 0; i < bonus.length; i++) {
bonus[i] += item.getDefinition().getBonus()[i];
}
}
for (int i = 0; i < bonus.length; i++) {
encoder.sendString(Combat.BONUS_NAMES[i] + ": " + (bonus[i] >= 0 ? "+" : "") + bonus[i], (1675 + i + (i == 10 || i == 11 ? 1
: 0)));
}
}
/**
* Restores run energy based on the last time it was restored.
*/
public void restoreRunEnergy() {
OutputMessages encoder = getMessages();
if (lastEnergy.elapsed(3500) && runEnergy.get() < 100) {
runEnergy.incrementAndGet();
lastEnergy.reset();
encoder.sendString(runEnergy + "%", 149);
}
}
/**
* Gets the formatted version of the username for this player.
*
* @return the formatted username.
*/
public String getFormatUsername() {
return TextUtils.capitalize(username);
}
/**
* Gets the hash collection of the local players.
*
* @return the local players.
*/
public Set<Player> getLocalPlayers() {
return localPlayers;
}
/**
* Gets the hash collection of the local npcs.
*
* @return the local npcs.
*/
public Set<Npc> getLocalNpcs() {
return localNpcs;
}
/**
* Gets the hash collection of friends.
*
* @return the friends list.
*/
public Set<Long> getFriends() {
return friends;
}
/**
* Gets the hash collection of ignores.
*
* @return the ignores list.
*/
public Set<Long> getIgnores() {
return ignores;
}
/**
* Gets the container that holds the inventory items.
*
* @return the container for the inventory.
*/
public Inventory getInventory() {
return inventory;
}
/**
* Gets the container that holds the bank items.
*
* @return the container for the bank.
*/
public Bank getBank() {
return bank;
}
/**
* Gets the container that holds the equipment items.
*
* @return the container for the equipment.
*/
public Equipment getEquipment() {
return equipment;
}
/**
* Gets the trade session manager that manages trades for this player.
*
* @return the trade session manager.
*/
public TradeSession getTradeSession() {
return tradeSession;
}
/**
* Gets the private message manager that manages messages for this player.
*
* @return the private message manager.
*/
public PrivateMessage getPrivateMessage() {
return privateMessage;
}
/**
* Gets the I/O manager that manages I/O operations for this player.
*
* @return the input/output manager.
*/
public PlayerIO getSession() {
return session;
}
/**
* Gets the encoder that will encode and send messages.
*
* @return the message encoder.
*/
public OutputMessages getMessages() {
return messages;
}
/**
* Gets the array of skills that can be trained by this player.
*
* @return the skills that can be trained.
*/
public Skill[] getSkills() {
return skills;
}
/**
* Gets the array of attack and defence bonus values.
*
* @return the player bonuses.
*/
public int[] getBonus() {
return bonus;
}
/**
* Gets the array of booleans determining which prayers are active.
*
* @return the active prayers.
*/
public EnumSet<CombatPrayer> getPrayerActive() {
return prayerActive;
}
/**
* Determines if this player is executing a skill action.
*
* @return {@code true} if this player is currently executing a skill
* action, {@code false} otherwise.
*/
public boolean isSkillAction() {
return skillAction;
}
/**
* Sets the value for {@link Player#skillAction}.
*
* @param skillAction
* the new value to set.
*/
public void setSkillAction(boolean skillAction) {
this.skillAction = skillAction;
}
/**
* Gets the eating stopwatch timer.
*
* @return the eating timer.
*/
public Stopwatch getEatingTimer() {
return eatingTimer;
}
/**
* Gets the potion stopwatch timer.
*
* @return the potion timer.
*/
public Stopwatch getPotionTimer() {
return potionTimer;
}
/**
* Gets the npc tolerance stopwatch timer.
*
* @return the tolerance timer.
*/
public Stopwatch getTolerance() {
return tolerance;
}
/**
* Gets the last energy increment stopwatch timer.
*
* @return the last energy increment timer.
*/
public Stopwatch getLastEnergy() {
return lastEnergy;
}
/**
* Gets the bone bury stopwatch timer.
*
* @return the bone bury timer.
*/
public Stopwatch getBuryTimer() {
return buryTimer;
}
/**
* Gets the poison immunity counter value.
*
* @return the poison immunity counter.
*/
public MutableNumber getPoisonImmunity() {
return poisonImmunity;
}
/**
* Gets the teleblock counter value.
*
* @return the teleblock counter.
*/
public MutableNumber getTeleblockTimer() {
return teleblockTimer;
}
/**
* Gets the dragonfire immunity counter value.
*
* @return the immunity counter.
*/
public MutableNumber getFireImmunity() {
return fireImmunity;
}
/**
* Gets the skull timer counter value.
*
* @return the skull timer counter.
*/
public MutableNumber getSkullTimer() {
return skullTimer;
}
/**
* Gets the run energy percentage counter value.
*
* @return the run energy percentage counter.
*/
public MutableNumber getRunEnergy() {
return runEnergy;
}
/**
* Gets the special percentage counter value.
*
* @return the special percentage counter.
*/
public MutableNumber getSpecialPercentage() {
return specialPercentage;
}
/**
* Gets the amount of authority this player has over others.
*
* @return the authority this player has.
*/
public Rights getRights() {
return rights;
}
/**
* Sets the value for {@link Player#rights}.
*
* @param rights
* the new value to set.
*/
public void setRights(Rights rights) {
this.rights = rights;
}
/**
* Gets the shop that you currently have open.
*
* @return the shop you have open.
*/
public String getOpenShop() {
return openShop;
}
/**
* Sets the value for {@link Player#openShop}.
*
* @param openShop
* the new value to set.
*/
public void setOpenShop(String openShop) {
if (openShop == null && this.openShop != null)
Shop.SHOPS.get(this.openShop).getPlayers().remove(this);
this.openShop = openShop;
}
/**
* Gets the current username of this player.
*
* @return the username of this player.
*/
public String getUsername() {
return username;
}
/**
* Sets the value for {@link Player#username}.
*
* @param username
* the new value to set.
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Gets the current password of this player.
*
* @return the password of this player.
*/
public String getPassword() {
return password;
}
/**
* Sets the value for {@link Player#password}.
*
* @param password
* the new value to set.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Gets the combat spell currently selected.
*
* @return the selected combat spell.
*/
public CombatSpell getCastSpell() {
return castSpell;
}
/**
* Sets the value for {@link Player#castSpell}.
*
* @param castSpell
* the new value to set.
*/
public void setCastSpell(CombatSpell castSpell) {
this.castSpell = castSpell;
}
/**
* Gets the type of ranged ammo currently being used.
*
* @return the type of ranged ammo.
*/
public CombatRangedAmmo getRangedAmmo() {
return rangedAmmo;
}
/**
* Sets the value for {@link Player#rangedAmmo}.
*
* @param rangedAmmo
* the new value to set.
*/
public void setRangedAmmo(CombatRangedAmmo rangedAmmo) {
this.rangedAmmo = rangedAmmo;
}
/**
* Determines if the player is autocasting.
*
* @return {@code true} if they are autocasting, {@code false} otherwise.
*/
public boolean isAutocast() {
return autocast;
}
/**
* Sets the value for {@link Player#autocast}.
*
* @param autocast
* the new value to set.
*/
public void setAutocast(boolean autocast) {
this.autocast = autocast;
}
/**
* Gets the combat spell currently being autocasted.
*
* @return the autocast spell.
*/
public CombatSpell getAutocastSpell() {
return autocastSpell;
}
/**
* Sets the value for {@link Player#autocastSpell}.
*
* @param autocastSpell
* the new value to set.
*/
public void setAutocastSpell(CombatSpell autocastSpell) {
this.autocastSpell = autocastSpell;
}
/**
* Gets the combat special that has been activated.
*
* @return the activated combat special.
*/
public CombatSpecial getCombatSpecial() {
return combatSpecial;
}
/**
* Sets the value for {@link Player#combatSpecial}.
*
* @param combatSpecial
* the new value to set.
*/
public void setCombatSpecial(CombatSpecial combatSpecial) {
this.combatSpecial = combatSpecial;
}
/**
* Gets the ranged ammo that was just fired with.
*
* @return the ranged ammo.
*/
public int getFireAmmo() {
return fireAmmo;
}
/**
* Sets the value for {@link Player#fireAmmo}.
*
* @param fireAmmo
* the new value to set.
*/
public void setFireAmmo(int fireAmmo) {
this.fireAmmo = fireAmmo;
}
/**
* Determines if the special bar has been activated.
*
* @return {@code true} if it has been activated, {@code false} otherwise.
*/
public boolean isSpecialActivated() {
return specialActivated;
}
/**
* Sets the value for {@link Player#specialActivated}.
*
* @param specialActivated
* the new value to set.
*/
public void setSpecialActivated(boolean specialActivated) {
this.specialActivated = specialActivated;
}
/**
* Gets the current fight type the player is using.
*
* @return the current fight type.
*/
public FightType getFightType() {
return fightType;
}
/**
* Sets the value for {@link Player#fightType}.
*
* @param fightType
* the new value to set.
*/
public void setFightType(FightType fightType) {
this.fightType = fightType;
}
/**
* Gets the weapon animation for appearance updating.
*
* @return the weapon animation.
*/
public WeaponAnimation getWeaponAnimation() {
return weaponAnimation;
}
/**
* Sets the value for {@link Player#weaponAnimation}.
*
* @param weaponAnimation
* the new value to set.
*/
public void setWeaponAnimation(WeaponAnimation weaponAnimation) {
this.weaponAnimation = weaponAnimation;
}
/**
* Gets the task that handles combat prayer draining.
*
* @return the prayer drain task.
*/
public Task getPrayerDrain() {
return prayerDrain;
}
/**
* Sets the value for {@link Player#prayerDrain}.
*
* @param prayerDrain
* the new value to set.
*/
public void setPrayerDrain(Task prayerDrain) {
this.prayerDrain = prayerDrain;
}
/**
* Gets the wilderness level this player is in.
*
* @return the wilderness level.
*/
public int getWildernessLevel() {
return wildernessLevel;
}
/**
* Sets the value for {@link Player#wildernessLevel}.
*
* @param wildernessLevel
* the new value to set.
*/
public void setWildernessLevel(int wildernessLevel) {
this.wildernessLevel = wildernessLevel;
}
/**
* Gets the weapon interface this player currently has open.
*
* @return the weapon interface.
*/
public WeaponInterface getWeapon() {
return weapon;
}
/**
* Sets the value for {@link Player#weapon}.
*
* @param weapon
* the new value to set.
*/
public void setWeapon(WeaponInterface weapon) {
this.weapon = weapon;
}
/**
* Gets the current teleport stage that this player is in.
*
* @return the teleport stage.
*/
public int getTeleportStage() {
return teleportStage;
}
/**
* Sets the value for {@link Player#teleportStage}.
*
* @param teleportStage
* the new value to set.
*/
public void setTeleportStage(int teleportStage) {
this.teleportStage = teleportStage;
}
/**
* Determines if you are using a stove or not.
*
* @return {@code true} if you are using a stove, {@code false} otherwise.
*/
public boolean isUsingStove() {
return usingStove;
}
/**
* Sets the value for {@link Player#usingStove}.
*
* @param usingStove
* the new value to set.
*/
public void setUsingStove(boolean usingStove) {
this.usingStove = usingStove;
}
/**
* Gets the cooking data being used for the cooking skill.
*
* @return the cooking data.
*/
public CookingData getCookData() {
return cookData;
}
/**
* Sets the value for {@link Player#cookData}.
*
* @param cookData
* the new value to set.
*/
public void setCookData(CookingData cookData) {
this.cookData = cookData;
}
/**
* Gets the position of the fire or stove being cooked with.
*
* @return the cook position.
*/
public Position getCookPosition() {
return cookPosition;
}
/**
* Sets the value for {@link Player#cookPosition}.
*
* @param cookPosition
* the new value to set.
*/
public void setCookPosition(Position cookPosition) {
this.cookPosition = cookPosition;
}
/**
* Determines if this player is banned or not.
*
* @return {@code true} if the player is banned, {@code false} otherwise.
*/
public boolean isBanned() {
return banned;
}
/**
* Sets the value for {@link Player#banned}.
*
* @param banned
* the new value to set.
*/
public void setBanned(boolean banned) {
this.banned = banned;
}
/**
* Determines if this player has 'accept aid' toggled.
*
* @return {@code true} if the player has accept aid toggled, {@code false}
* otherwise.
*/
public boolean isAcceptAid() {
return acceptAid;
}
/**
* Sets the value for {@link Player#acceptAid}.
*
* @param acceptAid
* the new value to set.
*/
public void setAcceptAid(boolean acceptAid) {
this.acceptAid = acceptAid;
}
/**
* Gets the option value used for npc dialogues.
*
* @return the option value.
*/
public OptionType getOption() {
return option;
}
/**
* Sets the value for {@link Player#option}.
*
* @param option
* the new value to set.
*/
public void setOption(OptionType option) {
this.option = option;
}
/**
* Gets the identifier for the head icon of this player.
*
* @return the head icon.
*/
public int getHeadIcon() {
return headIcon;
}
/**
* Sets the value for {@link Player#headIcon}.
*
* @param headIcon
* the new value to set.
*/
public void setHeadIcon(int headIcon) {
this.headIcon = headIcon;
}
/**
* Gets the identifier for the skull icon of this player.
*
* @return the skull icon.
*/
public int getSkullIcon() {
return skullIcon;
}
/**
* Sets the value for {@link Player#skullIcon}.
*
* @param skullIcon
* the new value to set.
*/
public void setSkullIcon(int skullIcon) {
this.skullIcon = skullIcon;
}
/**
* Determines if a wilderness interface is present.
*
* @return {@code true} if a wilderness interface is present, {@code false}
* otherwise.
*/
public boolean isWildernessInterface() {
return wildernessInterface;
}
/**
* Sets the value for {@link Player#wildernessInterface}.
*
* @param wildernessInterface
* the new value to set.
*/
public void setWildernessInterface(boolean wildernessInterface) {
this.wildernessInterface = wildernessInterface;
}
/**
* Determines if a multicombat interface is present.
*
* @return {@code true} if a multicombat interface is present, {@code false}
* otherwise.
*/
public boolean isMulticombatInterface() {
return multicombatInterface;
}
/**
* Sets the value for {@link Player#multicombatInterface}.
*
* @param multicombatInterface
* the new value to set.
*/
public void setMulticombatInterface(boolean multicombatInterface) {
this.multicombatInterface = multicombatInterface;
}
/**
* Determines if this player is new.
*
* @return {@code true} if this player is new, {@code false} otherwise.
*/
public boolean isNewPlayer() {
return newPlayer;
}
/**
* Sets the value for {@link Player#newPlayer}.
*
* @param newPlayer
* the new value to set.
*/
public void setNewPlayer(boolean newPlayer) {
this.newPlayer = newPlayer;
}
/**
* Determines if items should be inserted when banking.
*
* @return {@code true} if items should be inserted, {@code false}
* otherwise.
*/
public boolean isInsertItem() {
return insertItem;
}
/**
* Sets the value for {@link Player#insertItem}.
*
* @param insertItem
* the new value to set.
*/
public void setInsertItem(boolean insertItem) {
this.insertItem = insertItem;
}
/**
* Determines if a bank item should be withdrawn as a note.
*
* @return {@code true} if items should be withdrawn as notes, {@code false}
* otherwise.
*/
public boolean isWithdrawAsNote() {
return withdrawAsNote;
}
/**
* Sets the value for {@link Player#withdrawAsNote}.
*
* @param withdrawAsNote
* the new value to set.
*/
public void setWithdrawAsNote(boolean withdrawAsNote) {
this.withdrawAsNote = withdrawAsNote;
}
/**
* Gets the current spellbook the player has open.
*
* @return the spellbook open.
*/
public Spellbook getSpellbook() {
return spellbook;
}
/**
* Sets the value for {@link Player#spellbook}.
*
* @param spellbook
* the new value to set.
*/
public void setSpellbook(Spellbook spellbook) {
this.spellbook = spellbook;
}
/**
* Gets the array of chat text packed into bytes.
*
* @return the array of chat text.
*/
public byte[] getChatText() {
return chatText;
}
/**
* Sets the value for {@link Player#chatText}.
*
* @param chatText
* the new value to set.
*/
public void setChatText(byte[] chatText) {
this.chatText = chatText;
}
/**
* Gets the current chat color the player is using.
*
* @return the chat color.
*/
public int getChatColor() {
return chatColor;
}
/**
* Sets the value for {@link Player#chatColor}.
*
* @param chatColor
* the new value to set.
*/
public void setChatColor(int chatColor) {
this.chatColor = chatColor;
}
/**
* Gets the current chat effects the player is using.
*
* @return the chat effects.
*/
public int getChatEffects() {
return chatEffects;
}
/**
* Sets the value for {@link Player#chatEffects}.
*
* @param chatEffects
* the new value to set.
*/
public void setChatEffects(int chatEffects) {
this.chatEffects = chatEffects;
}
/**
* Gets the player-npc identifier for updating.
*
* @return the player npc identifier.
*/
public int getPlayerNpc() {
return playerNpc;
}
/**
* Sets the value for {@link Player#playerNpc}.
*
* @param playerNpc
* the new value to set.
*/
public void setPlayerNpc(int playerNpc) {
this.playerNpc = playerNpc;
}
/**
* Gets the cached player update block for updating.
*
* @return the cached update block.
*/
public ByteBuf getCachedUpdateBlock() {
return cachedUpdateBlock;
}
/**
* Sets the value for {@link Player#cachedUpdateBlock}.
*
* @param cachedUpdateBlock
* the new value to set.
*/
public void setCachedUpdateBlock(ByteBuf cachedUpdateBlock) {
this.cachedUpdateBlock = cachedUpdateBlock;
}
/**
* Gets the username hash for this player.
*
* @return the username hash.
*/
public long getUsernameHash() {
return usernameHash;
}
/**
* Sets the value for {@link Player#usernameHash}.
*
* @param usernameHash
* the new value to set.
*/
public void setUsernameHash(long usernameHash) {
this.usernameHash = usernameHash;
}
/**
* Gets the current dialogue chain we are in.
*
* @return the dialogue chain.
*/
public DialogueChainBuilder getDialogueChain() {
return dialogueChain;
}
/**
* Determines if the region has been updated this sequence.
*
* @return {@code true} if the region has been updated, {@code false}
* otherwise.
*/
public boolean isUpdateRegion() {
return updateRegion;
}
/**
* Sets the value for {@link Player#updateRegion}.
*
* @param updateRegion
* the new value to set.
*/
public void setUpdateRegion(boolean updateRegion) {
this.updateRegion = updateRegion;
}
/**
* Gets the current viewing orb that this player has open.
*
* @return the current viewing orb.
*/
public ViewingOrb getViewingOrb() {
return viewingOrb;
}
/**
* Sets the value for {@link Player#viewingOrb}.
*
* @param viewingOrb
* the new value to set.
*/
public void setViewingOrb(ViewingOrb viewingOrb) {
this.viewingOrb = viewingOrb;
}
/**
* Gets the container of appearance values for this player.
*
* @return the container of appearance values.
*/
public Appearance getAppearance() {
return appearance;
}
/**
* Determines if this player is disabled.
*
* @return {@code true} if this player is disabled, {@code false} otherwise.
*/
public boolean isDisabled() {
return disabled;
}
/**
* Sets the value for {@link Player#disabled}.
*
* @param disabled
* the new value to set.
*/
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
/**
* Gets the stopwatch that will time logouts.
*
* @return the logout stopwatch.
*/
public Stopwatch getLogoutTimer() {
return logoutTimer;
}
}