162public class Player
extends Mob {
164 private final Events events =
new Events();
166 public List<PlayerBirdHouseData> birdHouseData =
new ArrayList<>();
167 public int wintertodtPoints;
168 public int menuOpened, optionOpened = -1;
171 public Map<String, Position> waypoints =
new HashMap<>();
172 public Teleport lastTeleport =
null;
174 return gamblingManager;
177 private long lastModification;
179 public void setLastModification(
long lastModification) {
180 this.lastModification = lastModification;
183 public long getLastModification() {
184 return lastModification;
187 private boolean gambleLocked;
189 public void setGambleLock(
boolean gambleLocked) {
190 this.gambleLocked = gambleLocked;
193 public boolean isGambleLocked() {
201 public transient long lmsImmunity;
202 public long lastLMSRopeCross;
203 public List<Integer> unlockedLMSItems =
new ArrayList<>();
205 public int lmsDeaths;
207 public int answeredTrivias;
208 public int lmsPoints;
209 public int lmsTotalKills;
210 public int lmsTotalDeaths;
223 this.collectionLog = collectionLog;
226 public HashMap<WeaponInterface, FightType> fightStyles =
new HashMap<>();
229 return this.collectionLog;
232 private static final Logger logger = LogManager.getLogger(
Player.class);
233 private int memberId = -1;
235 public boolean debug;
237 public CombatSpell autocast;
238 public CombatSpell singleCast;
241 public PlayerTitle playerTitle = PlayerTitle.empty();
242 public Spellbook spellbook = Spellbook.MODERN;
243 public Spellbook spellbook_copy = Spellbook.MODERN;
244 public ChatBoxItemDialogue chatBoxItemDialogue;
245 private Optional<ChatMessage> chatMessage = Optional.empty();
246 public DailyEffect dailySlayerTaskTeleport =
new DailySlayerTaskTeleport();
247 public DailyEffect dailySlayerTaskSkip =
new DailySlayerTaskSkip();
248 public DailyEffect dailySpellBookSwap =
new DailySpellBookSwap();
250 public HashSet<Prayer> unlockedPrayers =
new HashSet<>();
251 public RangedWeaponDefinition rangedDefinition;
252 public RangedAmmunition rangedAmmo;
253 private AntifireDetails antifireDetails;
254 private WeaponInterface weapon = WeaponInterface.UNARMED;
255 private CombatSpecial combatSpecial;
256 public Optional<Player> managing;
257 public boolean completedMageArena;
258 public boolean pvpInstance;
259 public boolean hasPvPTimer;
261 public Optional<Dialogue> dialogue = Optional.empty();
262 public Optional<OptionDialogue> optionDialogue = Optional.empty();
263 public Optional<Consumer<String>> enterInputListener = Optional.empty();
264 public boolean[] barrowKills =
new boolean[BrotherData.values().length];
265 public final PlayerRelation relations =
new PlayerRelation(
this);
266 public final Donation donation =
new Donation(
this);
267 public final LostUntradeables lostUntradeables =
new LostUntradeables(
this);
268 public LinkedList<Item> lostItems =
new LinkedList<>();
269 public BrotherData hiddenBrother;
270 public int barrowsKillCount;
277 public int valueIcon = -1;
278 public int skillingPoints;
279 public int pestPoints;
280 public int votePoints;
281 public int totalVotes;
282 public int[] achievedSkills =
new int[7];
284 public int mageArenaPoints;
285 public int ringOfRecoil = 40;
286 public int whipCharges = 2500;
287 public int agsCharges = 750;
288 public int wilderness;
289 public int runEnergy;
290 public int energyRate;
291 public int glovesTier;
292 public int royaltyLevel = 1;
295 public int smallPouch;
296 public int mediumPouch;
297 public int largePouch;
298 public int giantPouch;
299 public final RunecraftPouch runecraftPouch =
new RunecraftPouch(
this);
301 public long usernameLong;
303 public boolean resting;
304 public boolean newPlayer;
305 public boolean needsStarter;
306 public boolean venged;
307 private boolean specialActivated;
308 public boolean warriorGuidTask;
309 public boolean isBot;
310 public int trapsLaid;
311 private String username =
"";
312 private String password =
"";
314 public String lastHost;
316 public String lastClan =
"";
317 public ClanChannel clanChannel;
318 public String clan =
"";
319 public String clanTag =
"";
320 public String clanTagColor =
"";
321 public final AtomicBoolean saved =
new AtomicBoolean(
false);
330 public int cooldown = 7 * 60 * 1000;
331 public long lastUsed = 0;
336 public Set<PetData> petInsurance =
new HashSet<>();
337 public Set<PetData> lostPets =
new HashSet<>();
338 public final PuzzleDisplay puzzle =
new PuzzleDisplay(
this);
339 public final ClanViewer clanViewer =
new ClanViewer(
this);
340 public final PlayerRecord gameRecord =
new PlayerRecord(
this);
341 public final Farming farming =
new Farming(
this);
342 public final ExchangeSessionManager exchangeSession =
new ExchangeSessionManager(
this);
343 public final Map<Integer, PersonalStore> viewing_shops =
new HashMap<>();
344 public final PlayerAssistant playerAssistant =
new PlayerAssistant(
this);
345 public final InterfaceManager interfaceManager =
new InterfaceManager(
this);
346 public final RequestManager requestManager =
new RequestManager(
this);
347 public final MysteryBoxManager mysteryBox =
new MysteryBoxManager(
this);
348 public final Settings settings =
new Settings(
this);
349 public final Inventory inventory =
new Inventory(
this);
350 public final Inventory inventory_copy =
new Inventory(
this);
351 public final Bank bank =
new Bank(
this);
352 public final BankVault bankVault =
new BankVault(
this);
353 public final BankPin bankPin =
new BankPin(
this);
354 public final RunePouch runePouch =
new RunePouch(
this);
355 public final RunePouch runePouch_copy =
new RunePouch(
this);
356 public final Killstreak killstreak =
new Killstreak(
this);
357 public final LootingBag lootingBag =
new LootingBag(
this);
358 public final PlayerPunishment punishment =
new PlayerPunishment(
this);
361 public final PresetManager presetManager =
new PresetManager(
this);
362 public final Prestige prestige =
new Prestige(
this);
363 public final PriceChecker priceChecker =
new PriceChecker(
this);
364 public final DonatorDeposit donatorDeposit =
new DonatorDeposit(
this);
365 public DialogueFactory dialogueFactory =
new DialogueFactory(
this);
366 public final House house =
new House(
this);
367 public Slayer slayer =
new Slayer(
this);
368 public Skulling skulling =
new Skulling(
this);
369 public SpellCasting spellCasting =
new SpellCasting(
this);
370 private final Combat<Player> combat =
new Combat<>(
this);
371 public final ActivityLogger activityLogger =
new ActivityLogger(
this);
372 private final MutableNumber poisonImmunity =
new MutableNumber();
373 private final MutableNumber venomImmunity =
new MutableNumber();
374 private final MutableNumber specialPercentage =
new MutableNumber();
375 public Deque<String> lastKilled =
new ArrayDeque<>(3);
376 public List<EmoteUnlockable> emoteUnlockable =
new LinkedList<>();
377 public List<Teleport> favoriteTeleport =
new ArrayList<>();
378 public final Set<String> hostList =
new HashSet<>();
380 public final Overrides overrides =
new Overrides(
this);
383 public HashMap<ActivityLog, Integer> loggedActivities =
new HashMap<ActivityLog, Integer>(ActivityLog.values().length) {
385 for (
final ActivityLog achievement : ActivityLog.values())
390 public HashMap<AchievementKey, Integer> playerAchievements =
new HashMap<AchievementKey, Integer>(AchievementKey.values().length) {
392 for (
final AchievementKey achievement : AchievementKey.values())
397 public float blowpipeScales;
398 public Item blowpipeDarts;
401 public int crawsBowCharges;
402 public int viggorasChainmaceCharges;
403 public int thammoranSceptreCharges;
404 public int tridentSeasCharges;
405 public int tridentSwampCharges;
407 public int celestialRingCharges;
409 public int serpentineHelmCharges;
410 public int tanzaniteHelmCharges;
411 public int magmaHelmCharges;
414 private Optional<GameSession> session = Optional.empty();
415 public int dragonfireCharges;
416 public long dragonfireUsed;
418 public Player(String username) {
420 this.username = username;
426 this.setPosition(position);
427 this.setUsername(username);
432 if (!chatMessage.isValid()) {
435 this.chatMessage = Optional.of(chatMessage);
436 this.updateFlags.add(UpdateFlag.CHAT);
439 public void setUsername(String username) {
440 this.username = username;
441 this.usernameLong = Utility.nameToLong(username);
444 public void send(OutgoingPacket encoder) {
445 encoder.execute(
this);
448 private void login() {
449 positionChange =
true;
456 mobAnimation.reset();
460 CombatSpell autocast = getAutocastSpell();
467 sendInitialPackets();
469 playerAssistant.login();
472 send(
new SendSpecialEnabled(0));
473 send(
new SendConfig(301, 0));
475 setAutocast(autocast);
476 if (isAutocast() && equipment.hasWeapon()) {
477 send(
new SendConfig(43, 3));
478 send(
new SendConfig(108, 1));
481 send(
new SendConfig(108, 0));
482 send(
new SendString(
"Spell", 18584));
486 private void sendInitialPackets() {
487 int players = World.getPlayerCount();
488 send(
new SendRunEnergy());
489 send(
new SendPlayerDetails());
490 send(
new SendCameraReset());
491 send(
new SendExpCounter(skills.getExpCounter()));
492 World.sendMessage(
"<img=15> " +getPlayer().
getName()+
" has logged in.");
493 message(
true, String.format(
"Welcome to %s. ", Config.SERVER_NAME));
494 message(
true,
"We are currently in early access.");
496 if (Config.DOUBLE_EXPERIENCE) {
497 message(
"Double experience is currently active!");
500 if (players > GameSaver.MAX_PLAYERS) {
501 GameSaver.MAX_PLAYERS = players;
507 playerAssistant.welcomeScreen();
510 private boolean canLogout() {
512 send(
new SendMessage(
"You can not logout whilst in combat!"));
516 if (!
getCombat().hasPassed(CombatConstants.COMBAT_LOGOUT_COOLDOWN)) {
517 final long seconds = TimeUnit.SECONDS.convert(
518 CombatConstants.COMBAT_LOGOUT_COOLDOWN - combat.elapsedTime(),
519 TimeUnit.MILLISECONDS);
520 send(
new SendMessage(
"You must wait " + seconds +
" second" + (seconds > 1 ?
"s" :
"")
521 +
" before you can logout as you were recently in combat."));
525 if (!interfaceManager.isMainClear()) {
526 send(
new SendMessage(
"Please close what you are doing before logging out!"));
530 return !Activity.evaluate(
this, it -> !it.canLogout(
this));
533 public final Set<PlayerOption> contextMenus =
new HashSet<>();
535 public final void logout() {
539 public final void logout(
boolean force) {
540 if (!canLogout() && !force) {
544 send(
new SendLogout());
546 World.queueLogout(
this);
549 public void loadRegion() {
550 for(PlayerBirdHouseData playerBirdHouseData : birdHouseData) {
552 if(Utility.goodDistance(playerBirdHouseData.birdhousePosition.getX(), playerBirdHouseData.birdhousePosition.getY(),
getPosition().
getX(),
getPosition().
getY(), 60)) {
553 int objectId = playerBirdHouseData.birdhouseData.objectData[playerBirdHouseData.seedAmount >= 10 ? 1 : 0];
554 send(
new SendAddObject(
new CustomGameObject(objectId, playerBirdHouseData.birdhousePosition, ObjectDirection.valueOf(playerBirdHouseData.rotation).get(), ObjectType.valueOf(playerBirdHouseData.type).get())));
558 Activity.forActivity(
this, minigame -> minigame.onRegionChange(
this));
560 Region[] surrounding = World.getRegions().getSurroundingRegions(
getPosition());
562 for (Region region : surrounding) {
563 region.sendGroundItems(
this);
564 region.sendGameObjects(
this);
567 for (Npc npc : region.getNpcs(
getHeight())) {
568 if (!npc.getCombat().inCombat())
569 npc.face(npc.faceDirection);
573 farming.regionChange(
this);
574 TrapManager.handleRegionChange(
this);
576 if (debug && PlayerRight.isDeveloper(
this)) {
577 send(
new SendMessage(
"[REGION] Loaded new region.", MessageColor.DEVELOPER));
581 public void pickup(Item item, Position position) {
582 Waypoint waypoint =
new PickupWaypoint(
this, item, position);
583 if (cachedWaypoint ==
null || (!cachedWaypoint.isRunning() || !waypoint.equals(cachedWaypoint))) {
585 action.clearNonWalkableActions();
588 World.schedule(cachedWaypoint = waypoint);
592 public void forClan(Consumer<ClanChannel> action) {
593 if (clanChannel !=
null)
594 action.accept(clanChannel);
596 public void message(String message) {
597 send(
new SendMessage(message));
602 if (!isRegistered() && !
World.getPlayers().contains(
this)) {
603 setRegistered(
World.getPlayers().add(
this));
608 logger.info(
"[REGISTERED]: " +
Utility.formatName(
getName()) +
" [" + lastHost +
"]");
615 if (!isRegistered()) {
619 if (!
World.getPlayers().contains(
this)) {
626 Activity.forActivity(
this, minigame -> minigame.onLogout(
this));
627 relations.updateLists(
false);
630 interfaceManager.close();
633 World.cancelTask(
this,
true);
637 getGambling().decline(
this);
638 logger.info(String.format(
"[UNREGISTERED]: %s [%s]",
getName(), lastHost));
643 region.addPlayer(
this);
644 aggressionTimer.reset();
649 region.removePlayer(
this);
659 playerAssistant.sequence();
662 if(
Area.inLMSLobby(
this) ||
Area.inLMSBuilding(
this)) {
671 public void onStep() {
675 if (
Activity.evaluate(
this, activity -> activity.onStep(
this))) {
687 if(Boundary.isIn(
this, GambleManager.GAMBLING_ZONE)) {
691 else if(LMSGame.inGameArea(
this)){
693 if (interfaceManager.getWalkable() != 44660)
694 interfaceManager.openWalkable(44660);
696 else if(
Area.inLMSLobby(
this) ||
Area.inLMSBuilding(
this)) {
697 if (interfaceManager.getWalkable() != 44650)
698 interfaceManager.openWalkable(44650);
701 else if (pvpInstance) {
705 }
else if (Area.inPvP(
this)) {
706 send(
new SendString(
"<col=E68A00>" + playerAssistant.getCombatRange(), 23327));
709 if (interfaceManager.getWalkable() != 23400) {
710 interfaceManager.openWalkable(23400);
714 if (!hasPvPTimer &&
getCombat().inCombat()) {
717 send(
new SendString(
"<col=36CF4D>Safe", 23327));
718 send(
new SendPlayerOption(PlayerOption.ATTACK,
false,
true));
719 send(
new SendPlayerOption(PlayerOption.DUEL_REQUEST,
false,
true));
722 if (interfaceManager.getWalkable() != 23410) {
723 interfaceManager.openWalkable(23410);
727 }
else if (Area.inWilderness(
this)) {
729 wilderness = (((modY - 3521) / 8) + 1);
730 send(
new SendString(
"Level " + wilderness, 23327));
731 send(
new SendPlayerOption(PlayerOption.ATTACK,
true));
732 send(
new SendPlayerOption(PlayerOption.DUEL_REQUEST,
false,
true));
733 if (interfaceManager.getWalkable() != 23400)
734 interfaceManager.openWalkable(23400);
737 }
else if (Area.inDuelArenaLobby(
this)) {
738 send(
new SendPlayerOption(PlayerOption.DUEL_REQUEST,
false));
739 send(
new SendPlayerOption(PlayerOption.ATTACK,
false,
true));
740 if (interfaceManager.getWalkable() != 201)
741 interfaceManager.openWalkable(201);
743 }
else if (Area.inDuelArena(
this) || Area.inDuelObsticleArena(
this)) {
744 send(
new SendPlayerOption(PlayerOption.ATTACK,
true));
745 send(
new SendPlayerOption(PlayerOption.DUEL_REQUEST,
false,
true));
746 if (interfaceManager.getWalkable() != 201)
747 interfaceManager.openWalkable(201);
758 }
else if (Area.inSuperDonatorZone(
this) && (Area.inRegularDonatorZone(
this) && !PlayerRight.isDonator(
this))) {
759 move(Config.DEFAULT_POSITION);
760 send(
new SendMessage(
"You're not supposed to be here!"));
763 }
else if (!inActivity()) {
764 send(
new SendPlayerOption(PlayerOption.GAMBLE_REQUEST,
false,
true));
765 send(
new SendPlayerOption(PlayerOption.ATTACK,
false,
true));
766 send(
new SendPlayerOption(PlayerOption.DUEL_REQUEST,
false,
true));
767 send(
new SendPlayerOption(PlayerOption.FOLLOW,
false));
768 send(
new SendPlayerOption(PlayerOption.TRADE_REQUEST,
false));
769 send(
new SendPlayerOption(PlayerOption.VIEW_PROFILE,
false));
772 interfaceManager.close();
785 return playerAssistant.getStrategy();
795 return Utility.formatName(username);
805 return (isBot || session !=
null) && super.isValid();
809 public boolean equals(Object obj) {
814 if (obj ==
null || !(obj instanceof
Player)) {
819 return Objects.equals(getIndex(), other.getIndex()) && Objects.equals(username, other.username) && Objects.equals(password, other.password) && Objects.equals(isBot, other.isBot);
823 public int hashCode() {
824 return Objects.hash(getIndex(), username);
828 public String toString() {
829 return String.format(
"Player[index=%d member_id=%d username=%s pos=%s bot=%b]", getIndex(), getMemberId(), getUsername(),
getPosition(), isBot);
832 public void message(
boolean filtered, String... messages) {
833 for (String message : messages) {
838 public void message(String... messages) {
839 for (String message : messages) {
845 return settings.autoRetaliate;
848 public boolean isSpecialActivated() {
849 return specialActivated;
852 public void setSpecialActivated(
boolean activated) {
853 this.specialActivated = activated;
856 public void setCombatSpecial(CombatSpecial special) {
857 this.combatSpecial = special;
860 public boolean isSingleCast() {
861 return singleCast !=
null;
864 CombatSpell getSingleCastSpell() {
868 public void setSingleCast(CombatSpell singleCast) {
869 this.singleCast = singleCast;
872 public boolean isAutocast() {
873 return autocast !=
null;
876 CombatSpell getAutocastSpell() {
880 public void setAutocast(CombatSpell autocast) {
881 this.autocast = autocast;
884 public MutableNumber getSpecialPercentage() {
885 return specialPercentage;
888 public final AtomicInteger teleblockTimer =
new AtomicInteger(0);
890 public void teleblock(
int time) {
891 if (time <= 0 || (teleblockTimer.get() > 0)) {
895 teleblockTimer.set(time);
896 send(
new SendMessage(
"A teleblock spell has been casted on you!"));
897 send(
new SendWidget(SendWidget.WidgetType.TELEBLOCK, (
int) ((
double) teleblockTimer.get() / 1000D * 600D)));
898 World.schedule(
new TeleblockTask(
this));
901 public boolean isTeleblocked() {
902 return teleblockTimer.get() > 0;
905 public CombatSpecial getCombatSpecial() {
906 return combatSpecial;
909 public WeaponInterface getWeapon() {
913 public void setWeapon(WeaponInterface weapon) {
914 this.weapon = weapon;
917 public Optional<AntifireDetails> getAntifireDetails() {
918 return Optional.ofNullable(antifireDetails);
921 public void setAntifireDetail(AntifireDetails antifireDetails) {
922 this.antifireDetails = antifireDetails;
925 public final MutableNumber getPoisonImmunity() {
926 return poisonImmunity;
929 public final MutableNumber getVenomImmunity() {
930 return venomImmunity;
933 public Optional<ChatMessage> getChatMessage() {
937 public String getUsername() {
941 public void setMemberId(
int memberId) {
942 this.memberId = memberId;
945 public int getMemberId() {
949 public Optional<GameSession> getSession() {
953 public void setSession(GameSession session) {
954 this.session = Optional.of(session);
956 final String host = session.getHost();
957 this.lastHost = host;
958 this.hostList.add(host);
961 public void setPassword(String password) {
962 this.password = password;
965 public String getPassword() {
969 public Appearance getAppearance() {
973 public Events getEvents() {