diff --git a/README.md b/README.md
index 3fc1787f2..94ef0654c 100644
--- a/README.md
+++ b/README.md
@@ -7,84 +7,89 @@
An open source MMORPG emulation server
-
+
- Community Hosted Server
+ Community Hosted Server
·
Discord Invite
- · Report Bug
- ·
- Bug Board
+ · Report Bug
-NOTE: Do not report issues if you are running your own server. Chances are, the fault lies in your misconfiguration of the server or the issue has already long been fixed on live. Essentially: Your server. Your issues. We have enough to worry about with our own server.
-ATTENTION: Starting October 5th, 2020 the development team will no longer be providing support for setting up your own server. Do not ping or private message Developers asking how to build the project. This in-depth guide will be continually updated if the building process changes. We are focusing all of our efforts on the development of features and bugfixes for the live server.
+NOTE: Bug reports and support are only accepted by/offered to players of our live hosted server. We will not provide support to those running their own copies.
## Table of Contents
* [Live Server Information](#live-server-information)
-* [About the Project](#about-the-project)
+* [History of this Codebase](#history-of-this-codebase)
+* [Our Core Values](#our-core-values)
* [Contributing](#contributing)
-* [Contributing without Building](#contributing-without-building)
* [Video Setup Tutorial](#video-setup-tutorial)
-* [Getting Started](#getting-started)
+* [Setup for Content Developers](#content-developers-setting-up-the-project)
* [Github Setup](#github-setup)
* [Prerequisites](#prerequisites)
* [Prereq Installation](#prereq-installation)
-* [Project Setup](#project-setup)
-* [Running the project](#running-the-project)
+ * [Project Setup](#project-setup)
+ * [Running the project](#running-the-project)
* [License](#license)
* [Contact](#contact)
## Live Server Information
-Did you know that the 2009Scape Development Team hosts the main branch of this repo that you can connect to and play? Come join a growing community of people that love to grind out skills, quest, and hangout together. A download link for the launcher can be found here. Connecting to the live server is also one of the easiest ways to identify bugs/typos/missing features. Identifying these issues help developers, whether already on the project, or are even brand new to the project, fix bugs and issues in an expedited rate.
+Did you know that the 2009Scape Development Team hosts the main branch of this repo that you can connect to and play? Come join a growing community of people that love to grind out skills, quest, and hangout together. A download link for the launcher can be found here. Connecting to the live server is also one of the easiest ways to identify bugs/typos/missing features. Identifying these issues help developers, whether already on the project, or are even brand new to the project, fix bugs and issues in an expedited rate.
-## About The Project
+## History of this Codebase
The 2009Scape you see today has gone through a magnitude of changes. Originally starting its life as Arios498, this server saw a lot of people playing it daily, unfortunately, it was for profit and closed source. It was later upgraded to Arios530, targeting the build 530 of runescape with content in and around January 1st, 2009. Development came to a halt when a developer of the closed source project released the source code. The original developers of this server went on to create Kratos 530 back in 2015.
-This project was started out of love for the 530 revision. A small group of developers spent hundreds of hours improving on the existing source that was left to the curb. Over the past year, this project has seen many developers coming and going, fixing bugs that they find either through their own server, or bugs that they find in the live game that is currently hosted. We do not accept donations of any kind. The smiles and wonderful compliments are more than enough to keep us going! Content and bugfixes are always number one on our list, and we try our best to answer any questions that you may have, provided you have read through this readme and frequently asked questions on the discord.
+This project was started out of love for the 530 revision. A small group of developers spent thousands of hours improving on the existing source that was left to the curb. Over the past year, this project has seen many developers coming and going, fixing bugs that they find either through their own server, or bugs that they find in the live game that is currently hosted. We do not accept donations of any kind. The smiles and wonderful compliments are more than enough to keep us going! Content and bugfixes are always number one on our list, and we try our best to answer any questions that you may have, provided you have read through this readme and frequently asked questions on the discord.
+
+## Our Core Values
+
+In the current climate of RSPS in general, we believe it's important to wear our core values on our sleeves and defend them with everything we have! Below are what we hold as our core, most important values:
+
+* **We do NOT believe in profiting off RSPS.** To many of us here at the 2009scape team, what we care about most is preserving the wonderful work of the Gower brothers in the most true-to-spirit manner possible. We do NOT do this to make a profit, and in fact **we outright refuse donations.** This is a labor of love and passion for everyone involved, a love for real RS2! This is perhaps the single most central value we have. If you want to "donate" to us, do so with your time and your dedication. That is what we desire most.
+
+
+* **Authenticity is central to the work**. As a remake, one of the most important things to us is being true to the Gower spirit. What the Gowers brought to us in our childhood is what we are driven to preserve for the remainder of the world.
+
+
+* **Open Source Is Crucial**. We believe open source remakes to be crucial to preserving what we loved in our childhood, and we believe for-profit and/or closed-source servers are destined to flounder out and fail.
+
+
+* **Be Welcoming**. One of our most important goals is to provide a community of friendly and caring people that get along and love to enjoy the game with eachother. For this reason, we do tend to be very strict when it comes to toxicity. We care about quality a whole lot more than quantity!
## Contributing
-Note: A live server that the 2009Scape development team runs is the best way to find and report bugs! Any changes made should be pushed to the Development Branch, Any changes that are pushed to the main branch will be denied, and you will have to submit another PR request. We are currently in the process of rewriting the codebase in Kotlin. Any new commits should be written in Kotlin Only.
+Note: A live server that the 2009Scape development team runs is the best way to find and report bugs! We are currently in the process of rewriting the codebase in Kotlin. Any new commits should be written in Kotlin Only.
More information on Kotlin can be found here.
-We are always looking for fellow helpers and developers to help preserve history and contribute towards making the most complete emulation server! The beautiful part is you don't even have to download and build the project in order to contribute! Want to make simple edits to NPCs, Items, Music, Shops, Typos? Follow the [Contributing-without-Building](#contributing-without-building) guide below!
+There are many ways everyone can contribute! From the most seasoned programmers to those who do not have the most remote clue how code works! Below are some things that can always use some love from the community.
-## Contributing without Building
-
-First create a Github account if you do not have one already. Editing the repository directly is one of the easiest ways to contribute to the project. You will start off in the master/main branch. Switch to the **"Development Branch"** by clicking on the drop down menu which is on the left hand side where it says "Branches" and "Tags". Then navigate to the file you wish to change, for example, All definitions are located in **"Server/data/configs/"**. If you were to edit NPCSpawns.json, you would select NPCSpawns.json, and on the right hand side of the window there will be a screen icon, pencil icon, and trashcan icon. Click on the pencil icon to make changes. When you are finished with your changes, ensure you are in **development** by looking at the branch in the top left. Scroll down until you see "propose changes", and fill out the two info bars at the bottom to describe what you changed/fixed.
-
-**More information on repository file editing can be found here. **
-
-
-**Editing files that are too large for Github in-browser editing**
-
-First follow the [Github-Setup](#github-setup). After you have forked over your copy of the repo, swap over to the **Development branch**, and then download the file that you wish to edit. JSON format can be edited in any notepad program, however it is recommended to use either Atom or Notepad++ . After you are finished editing your file, navigate back to the file you wish to replace on your **Development Branch**. Select it and delete it off your branch. Then go back and on the right hand side click on "Add files" and then "Upload new files". Upload the file you are done editing and then submit a Pull request (PR). To submit a PR navigate to "Pull requests" and then click on "New pull request". On the top of the page you should see "Comparing changes". The left set of options is what you will be pushing to and the right side is where you are pushing from. On the right side, put your repo and compare to **Development**, On the left hand side put the repo as 2009scape/2009scape base: **Development**. If at anytime it tries to pull/push into its own repository, click "Compare across forks" and you should be able to select where you want to push to and from.
-
-**More information about submitting PR's can be found here. **
+* **Wiki Editors**: Did you know we have a wiki? Well it's always in need of people to fill it out and stay on top of it. Editing the wiki is one of the easiest ways you can contribute to 2009scape! If you're an active player and have the will, there's so much you could be helping out with over at the wiki. Click here to go to the wiki.
+* **JSON editors**: Did you know that the vast majority of our drop tables, stats, examines, item info, npc info, etc is all stored in a very easy-to-modify format called JSON? This is something almost anyone can help with, especially with the tool made by Ceikry to make it simple and streamlined. If you want to know what can be done to help here, get in touch in the development channel in the discord! **JSON editors are always in need and always appreciated!!**.
-## Getting Started
+* **Auditors**: As a remake, authenticity is central to our core values! We could always use someone to go through the game and create large lists of simple tasks that can be done to bring us closer to the authentic 2009 game! The preferred way to do this is one-area-at-a-time. If you want to see an example of some audits we've done in the past, take a look here.
+
+
+* **Content Developers**: As a remake, we have massive amounts of content that need to be implemented or corrected. If you know how to program or are willing to learn, this is where you could be extremely helpful! We need everything from quests to dialogue to minigames to skills that still need to be corrected or implemented, and this is perhaps one of the most valuable ways someone could help out the project! If you are interested in developing content, reach out in the development channel of the Discord.
+
+## Content Developers: Setting Up the Project.
### Github Setup
Note: This allows you to commit changes to the main repo (with approval)! Also, always stay up to date with the most recent updates by pulling into your copy when 2009Scape updates!
-1. Create a github account if you haven't done so already
+1. Create a gitlab account if you haven't done so already
-2. Go to the 2009Scape Github Page
+3. Click "Fork" in the top right hand side of our gitlab page.
-3. Click "Fork" in the top right hand side of Github
-
-**If at anytime you have an issue with Github please refer to the** Github help center.
+**If at anytime you have an issue with gitlab please refer to the** Gitlab help center.
### Prerequisites
@@ -92,7 +97,7 @@ First follow the [Github-Setup](#github-setup). After you have forked over your
Note: It is required for a developer submitting a PR to use Intellij IDEA as your integrated development environment.
* Intellij IDEA
-* Java SE Development Kit Version 1.8
+* Java SE Development Kit Version 1.8/OpenJDK 1.8 (preferred)
* Gradle (optional - Installs with Intellij on project build)
* Xampp
diff --git a/Server/data/configs/item_configs.json b/Server/data/configs/item_configs.json
index 2fc325c31..62d72fee2 100644
--- a/Server/data/configs/item_configs.json
+++ b/Server/data/configs/item_configs.json
@@ -5625,6 +5625,7 @@
"examine": "Used for medium missile spells.",
"grand_exchange_price": "320",
"durability": null,
+ "tokkul_price": "270",
"name": "Death rune",
"tradeable": "true",
"low_alchemy": "41",
@@ -5651,6 +5652,7 @@
"examine": "Used for small missile spells.",
"grand_exchange_price": "140",
"durability": null,
+ "tokkul_price": "135",
"name": "Chaos rune",
"tradeable": "true",
"low_alchemy": "18",
@@ -80752,7 +80754,7 @@
"name": "Defensive shield",
"weight": "3.6",
"archery_ticket_price": "0",
- "two_handed": "true",
+ "two_handed": "false",
"id": "8856",
"bonuses": "0,0,0,-6,-2,8,9,7,0,8,0,0,0,0,0",
"equipment_slot": "5"
diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json
index 6a356ecf9..d12a0160a 100644
--- a/Server/data/configs/npc_configs.json
+++ b/Server/data/configs/npc_configs.json
@@ -2372,7 +2372,7 @@
"slayer_task": "29",
"melee_animation": "99",
"range_animation": "0",
- "attack_speed": "6",
+ "attack_speed": "6",
"defence_animation": "0",
"weakness": "6",
"slayer_exp": "16",
@@ -16595,35 +16595,19 @@
"examine": "It's one leg short!",
"melee_animation": "9471",
"range_animation": "9471",
- "attack_speed": "5",
+ "attack_speed": "4",
+ "magic_level": "1",
"defence_animation": "9473",
"magic_animation": "9471",
"death_animation": "9472",
"name": "Turoth",
- "defence_level": "30",
+ "defence_level": "88",
"safespot": null,
"lifepoints": "27",
- "strength_level": "1",
- "id": "1622",
- "range_level": "1",
- "attack_level": "30"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "30",
- "safespot": null,
- "lifepoints": "27",
- "strength_level": "1",
+ "strength_level": "88",
"id": "1623",
"range_level": "1",
- "attack_level": "30"
+ "attack_level": "58"
},
{
"examine": "The vacuumed face of evil.",
@@ -16667,96 +16651,58 @@
"examine": "It's one leg short!",
"melee_animation": "9471",
"range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
+ "attack_speed": "4",
+ "magic_level": "1",
"defence_animation": "9473",
"magic_animation": "9471",
"death_animation": "9472",
"name": "Turoth",
- "defence_level": "75",
+ "defence_level": "86",
"safespot": null,
"lifepoints": "79",
- "strength_level": "85",
+ "strength_level": "86",
"id": "1626",
"clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
+ "range_level": "1",
+ "attack_level": "56"
},
{
"examine": "It's one leg short!",
"melee_animation": "9471",
"range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
+ "attack_speed": "4",
+ "magic_level": "1",
"defence_animation": "9473",
"magic_animation": "9471",
"death_animation": "9472",
"name": "Turoth",
- "defence_level": "75",
+ "defence_level": "84",
"safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
+ "lifepoints": "77",
+ "strength_level": "84",
"id": "1627",
"clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
+ "range_level": "1",
+ "attack_level": "54"
},
{
"examine": "It's one leg short!",
"melee_animation": "9471",
"range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
+ "attack_speed": "4",
+ "magic_level": "1",
"defence_animation": "9473",
"magic_animation": "9471",
"death_animation": "9472",
"name": "Turoth",
- "defence_level": "75",
+ "defence_level": "83",
"safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
+ "lifepoints": "76",
+ "strength_level": "83",
"id": "1628",
"clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1629",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1630",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
+ "range_level": "1",
+ "attack_level": "53"
},
{
"examine": "A rocky slug.",
@@ -90884,40 +90830,6 @@
"range_level": "1",
"attack_level": "32"
},
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "30",
- "safespot": null,
- "lifepoints": "27",
- "strength_level": "1",
- "id": "1622",
- "range_level": "1",
- "attack_level": "30"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "30",
- "safespot": null,
- "lifepoints": "27",
- "strength_level": "1",
- "id": "1623",
- "range_level": "1",
- "attack_level": "30"
- },
{
"examine": "The vacuumed face of evil.",
"slayer_task": "28",
@@ -90956,101 +90868,6 @@
"range_level": "61",
"attack_level": "105"
},
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1626",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1627",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1628",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1629",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1630",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
{
"examine": "A rocky slug.",
"slayer_task": "69",
@@ -165433,40 +165250,6 @@
"range_level": "1",
"attack_level": "32"
},
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "30",
- "safespot": null,
- "lifepoints": "27",
- "strength_level": "1",
- "id": "1622",
- "range_level": "1",
- "attack_level": "30"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "30",
- "safespot": null,
- "lifepoints": "27",
- "strength_level": "1",
- "id": "1623",
- "range_level": "1",
- "attack_level": "30"
- },
{
"examine": "The vacuumed face of evil.",
"slayer_task": "28",
@@ -165505,101 +165288,6 @@
"range_level": "61",
"attack_level": "105"
},
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1626",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1627",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1628",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1629",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1630",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
{
"examine": "A rocky slug.",
"slayer_task": "69",
@@ -239726,40 +239414,6 @@
"range_level": "1",
"attack_level": "32"
},
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "30",
- "safespot": null,
- "lifepoints": "27",
- "strength_level": "1",
- "id": "1622",
- "range_level": "1",
- "attack_level": "30"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "30",
- "safespot": null,
- "lifepoints": "27",
- "strength_level": "1",
- "id": "1623",
- "range_level": "1",
- "attack_level": "30"
- },
{
"examine": "The vacuumed face of evil.",
"slayer_task": "28",
@@ -239798,101 +239452,6 @@
"range_level": "61",
"attack_level": "105"
},
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1626",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1627",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1628",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1629",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
- {
- "examine": "It's one leg short!",
- "melee_animation": "9471",
- "range_animation": "9471",
- "attack_speed": "5",
- "magic_level": "75",
- "defence_animation": "9473",
- "magic_animation": "9471",
- "death_animation": "9472",
- "name": "Turoth",
- "defence_level": "75",
- "safespot": null,
- "lifepoints": "79",
- "strength_level": "85",
- "id": "1630",
- "clue_level": "2",
- "range_level": "75",
- "attack_level": "80"
- },
{
"examine": "A rocky slug.",
"slayer_task": "69",
diff --git a/Server/data/configs/npc_spawns.json b/Server/data/configs/npc_spawns.json
index 8d84a19ea..7b6c7a393 100644
--- a/Server/data/configs/npc_spawns.json
+++ b/Server/data/configs/npc_spawns.json
@@ -10734,5 +10734,9 @@
{
"npc_id": "312",
"loc_data": "{2421,3789,0,1,0}"
+ },
+ {
+ "npc_id": "1164",
+ "loc_data": "{2780,3058,0,1,0}"
}
]
\ No newline at end of file
diff --git a/Server/src/main/java/core/game/content/activity/wguild/catapult/CatapultRoom.java b/Server/src/main/java/core/game/content/activity/wguild/catapult/CatapultRoom.java
index f2633d42b..47b4ae155 100644
--- a/Server/src/main/java/core/game/content/activity/wguild/catapult/CatapultRoom.java
+++ b/Server/src/main/java/core/game/content/activity/wguild/catapult/CatapultRoom.java
@@ -44,7 +44,7 @@ public final class CatapultRoom extends MapZone implements Plugin {
/**
* The target location.
*/
- private static final Location TARGET = Location.create(2842, 3545, 1);
+ public static final Location TARGET = Location.create(2842, 3545, 1);
/**
* The shield item id.
diff --git a/Server/src/main/java/core/game/content/global/shop/Shop.java b/Server/src/main/java/core/game/content/global/shop/Shop.java
index 080cfca8a..5b44cfc1c 100644
--- a/Server/src/main/java/core/game/content/global/shop/Shop.java
+++ b/Server/src/main/java/core/game/content/global/shop/Shop.java
@@ -639,7 +639,10 @@ public class Shop {
}
double mod = (maxMod + minMod) / 2;
SystemLogger.logInfo("" + item.getDefinition().getAlchemyValue(highAlch) + " " + mod + " " + item.getAmount());
- int value = (int) (item.getDefinition().getAlchemyValue(highAlch) * mod * item.getAmount());
+ int baseValue = item.getDefinition().getAlchemyValue(highAlch);
+ int value = (int) (baseValue * mod * item.getAmount());
+ if(getCurrency() == Items.TOKKUL_6529 && item.getId() == Items.CHAOS_RUNE_562) value = 13;
+ if(getCurrency() == Items.TOKKUL_6529 && item.getId() == Items.DEATH_RUNE_560) value = 27;
if(item.getId() == 12183){
value = 25 * item.getAmount();
}
diff --git a/Server/src/main/java/core/game/content/quest/free/dragonslayer/DragonSlayerPlugin.java b/Server/src/main/java/core/game/content/quest/free/dragonslayer/DragonSlayerPlugin.java
index 0d1a639d2..cc8d30721 100644
--- a/Server/src/main/java/core/game/content/quest/free/dragonslayer/DragonSlayerPlugin.java
+++ b/Server/src/main/java/core/game/content/quest/free/dragonslayer/DragonSlayerPlugin.java
@@ -99,12 +99,6 @@ public final class DragonSlayerPlugin extends OptionHandler {
SceneryDefinition.forId(25161).getHandlers().put("option:climb-over", this);
NPCDefinition.forId(742).getHandlers().put("option:attack", this);
NPCDefinition.forId(745).getHandlers().put("option:attack", this);
- // reward items
- ItemDefinition.forId(1127).getHandlers().put("option:wear", this);
- ItemDefinition.forId(1135).getHandlers().put("option:wear", this);
- ItemDefinition.forId(2653).getHandlers().put("option:wear", this);
- ItemDefinition.forId(2669).getHandlers().put("option:wear", this);
- ItemDefinition.forId(2661).getHandlers().put("option:wear", this);
// guild
SceneryDefinition.forId(24357).getHandlers().put("option:climb-up", this);
SceneryDefinition.forId(10558).getHandlers().put("option:open", this);
@@ -138,17 +132,6 @@ public final class DragonSlayerPlugin extends OptionHandler {
ClimbActionHandler.climbLadder(player, (Scenery) node, "climb-up");
}
break;
- case 1127:
- case 1135:
- case 2653:
- case 2661:
- case 2669:
- if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) != 100) {
- player.getPacketDispatch().sendMessage("You need to complete the Dragon Slayer Quest in order to wear this.");
- return true;
- }
- InteractionListeners.run(node.getId(),0,"equip",player,node);
- break;
case 742:
if (player.getQuestRepository().getQuest("Dragon Slayer").getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) {
player.getPacketDispatch().sendMessage("You have already slain the dragon. Now you just need to return to Oziach for");
diff --git a/Server/src/main/java/core/game/interaction/inter/JewelleryInterface.java b/Server/src/main/java/core/game/interaction/inter/JewelleryInterface.java
index 15daafba9..781e54e9c 100644
--- a/Server/src/main/java/core/game/interaction/inter/JewelleryInterface.java
+++ b/Server/src/main/java/core/game/interaction/inter/JewelleryInterface.java
@@ -186,7 +186,7 @@ public final class JewelleryInterface extends ComponentPlugin {
});
return true;
}
- if(!player.getSlayer().getLearned()[1] && data.equals(JewelleryItem.SLAYER_RING)){
+ if(!player.getSlayer().flags.isRingUnlocked() && data.equals(JewelleryItem.SLAYER_RING)){
player.sendMessages("You don't know how to make this. Talk to any Slayer master in order to learn the", "ability that creates Slayer rings.");
return true;
}
diff --git a/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt b/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt
index fbd14fac5..b76395aed 100644
--- a/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt
+++ b/Server/src/main/java/core/game/interaction/object/sorceress/GardenObjectsPlugin.kt
@@ -478,6 +478,7 @@ class GardenObjectsPlugin : InteractionListener() {
* @author SonicForce41
* @date 31/12/2013
*/
+ @Initializable
class OsmanDialogue : DialoguePlugin {
/**
* Represents the quest instance.
@@ -538,10 +539,7 @@ class GardenObjectsPlugin : InteractionListener() {
20 -> {
if (!player.getInventory().containsItem(KEY_PRINT)) {
interpreter.sendDialogues(player, null, "Can you tell me what I need to get?")
- } else if (!player.getInventory().containsItem(BRONZE_BAR) && player.getInventory().containsItem(
- KEY_PRINT
- )
- ) {
+ } else if (!player.getInventory().containsItem(BRONZE_BAR) && player.getInventory().containsItem(KEY_PRINT)) {
interpreter.sendDialogues(
npc,
null,
diff --git a/Server/src/main/java/core/game/node/entity/skill/fletching/items/arrow/ArrowHeadPulse.java b/Server/src/main/java/core/game/node/entity/skill/fletching/items/arrow/ArrowHeadPulse.java
index 17bfe101e..2d3dd0870 100644
--- a/Server/src/main/java/core/game/node/entity/skill/fletching/items/arrow/ArrowHeadPulse.java
+++ b/Server/src/main/java/core/game/node/entity/skill/fletching/items/arrow/ArrowHeadPulse.java
@@ -43,7 +43,7 @@ public class ArrowHeadPulse extends SkillPulse- {
@Override
public boolean checkRequirements() {
if (arrow.unfinished == 4160) {
- if (!player.getSlayer().getLearned()[0]) {
+ if (!player.getSlayer().flags.isBroadsUnlocked()) {
player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad arrows.");
return false;
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/fletching/items/bolts/BoltPulse.java b/Server/src/main/java/core/game/node/entity/skill/fletching/items/bolts/BoltPulse.java
index f8581b08c..f8ec05101 100644
--- a/Server/src/main/java/core/game/node/entity/skill/fletching/items/bolts/BoltPulse.java
+++ b/Server/src/main/java/core/game/node/entity/skill/fletching/items/bolts/BoltPulse.java
@@ -60,7 +60,7 @@ public final class BoltPulse extends SkillPulse
- {
@Override
public boolean checkRequirements() {
if (bolt.getUnfinished().getId() == 13279) {
- if (!player.getSlayer().getLearned()[0]) {
+ if (!player.getSlayer().flags.isBroadsUnlocked()) {
player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad bolts.");
return false;
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/AberrantSpectreNPC.java b/Server/src/main/java/core/game/node/entity/skill/slayer/AberrantSpectreNPC.java
index 7f4b25562..1e61efe34 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/AberrantSpectreNPC.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/AberrantSpectreNPC.java
@@ -30,7 +30,7 @@ public final class AberrantSpectreNPC extends AbstractNPC {
public void impact(final Entity entity, final Entity victim, BattleState state) {
if (victim instanceof Player) {
Player player = (Player) victim;
- if (!Equipment.NOSE_PEG.hasEquipment(player)) {
+ if (!SlayerEquipmentFlags.hasNosePeg(player)) {
for (int skill : SKILLS) {
int drain = (int) (player.getSkills().getStaticLevel(skill) * 0.5);
player.getSkills().updateLevel(skill, -drain, 0);
@@ -62,7 +62,7 @@ public final class AberrantSpectreNPC extends AbstractNPC {
super.checkImpact(state);
if (state.getAttacker() instanceof Player) {
final Player player = (Player) state.getAttacker();
- if (!Equipment.NOSE_PEG.hasEquipment(player)) {
+ if (!SlayerEquipmentFlags.hasNosePeg(player)) {
state.neutralizeHits();
}
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/BansheeNPC.java b/Server/src/main/java/core/game/node/entity/skill/slayer/BansheeNPC.java
index e561f79b4..b5ab44ff0 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/BansheeNPC.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/BansheeNPC.java
@@ -105,7 +105,7 @@ public final class BansheeNPC extends AbstractNPC {
* @return {@code True} if they have it.
*/
public static boolean hasEarMuffs(Player player) {
- return Equipment.EARMUFFS.hasEquipment(player);
+ return SlayerEquipmentFlags.hasEarmuffs(player);
}
@Override
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/CaveHorrorNPC.java b/Server/src/main/java/core/game/node/entity/skill/slayer/CaveHorrorNPC.java
index b8846b460..30cc07f39 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/CaveHorrorNPC.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/CaveHorrorNPC.java
@@ -74,7 +74,7 @@ public final class CaveHorrorNPC extends AbstractNPC {
* @return {@code true} if it is equipped.
*/
public static boolean hasWitchwood(Player player) {
- return player.getEquipment().containsItem(Equipment.WITCHWOOD_ICON.getItem());
+ return SlayerEquipmentFlags.hasWitchwoodIcon(player);
}
@Override
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/DustDevilNPC.java b/Server/src/main/java/core/game/node/entity/skill/slayer/DustDevilNPC.java
index f604131ef..663c7a3ff 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/DustDevilNPC.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/DustDevilNPC.java
@@ -32,7 +32,7 @@ public final class DustDevilNPC extends AbstractNPC {
public void impact(Entity entity, Entity victim, BattleState state) {
if (victim instanceof Player) {
final Player player = (Player) victim;
- if (!Equipment.FACEMASK.hasEquipment(player)) {
+ if (!SlayerEquipmentFlags.hasFaceMask(player)) {
for (int i : SKILLS) {
player.getSkills().updateLevel(i, -player.getSkills().getStaticLevel(i), 0);
}
@@ -76,7 +76,7 @@ public final class DustDevilNPC extends AbstractNPC {
super.checkImpact(state);
if (state.getAttacker() instanceof Player) {
Player player = (Player) state.getAttacker();
- if (!Equipment.FACEMASK.hasEquipment(player)) {
+ if (!SlayerEquipmentFlags.hasFaceMask(player)) {
state.neutralizeHits();
}
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/EnchantedGemDialogue.java b/Server/src/main/java/core/game/node/entity/skill/slayer/EnchantedGemDialogue.java
index 583a59ab8..f56ed151b 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/EnchantedGemDialogue.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/EnchantedGemDialogue.java
@@ -93,8 +93,7 @@ public final class EnchantedGemDialogue extends DialoguePlugin {
break;
}
interpreter.sendDialogues(player.getSlayer().getMaster().getNpc(), FacialExpression.HALF_GUILTY, "You're currently assigned to kill " + (player.getSlayer().getTask() == Tasks.JAD ? " TzTok-Jad!" : NPCDefinition.forId((player.getSlayer().getTask().getNpcs()[0])).getName().toLowerCase() + "'s;"), "only " + player.getSlayer().getAmount() + " more to go.");
- player.varpManager.get(2502).setVarbit(1,player.getSlayer().getTask().ordinal());
- player.varpManager.get(2502).setVarbit(8,player.getSlayer().getAmount()).send(player);
+ player.varpManager.get(2502).setVarbit(0,player.getSlayer().flags.getTaskFlags() >> 4).send(player);
stage = 11;
break;
case 11:
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/Equipment.java b/Server/src/main/java/core/game/node/entity/skill/slayer/Equipment.java
deleted file mode 100644
index e4fcbcff7..000000000
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/Equipment.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package core.game.node.entity.skill.slayer;
-
-import core.game.node.entity.skill.Skills;
-import core.game.node.entity.player.Player;
-import core.game.node.item.Item;
-
-/**
- * Represents a slayer equipment.
- * @author Vexia
- */
-public enum Equipment {
- ENCHANTED_GEM(new Item(4155, 1)),
- MIRROR_SHIELD(new Item(4156, 1)) {
- @Override
- public boolean hasRequirement(final Player player) {
- return player.getSkills().getStaticLevel(Skills.DEFENCE) >= 20;
- }
- },
- LEAF_BLADED_SPEAR(new Item(4158, 1)),
- BROAD_ARROWS(new Item(4150, 1)),
- BAG_OF_SALT(new Item(4161, 1)),
- ROCK_HAMMER(new Item(4162, 1)),
- FACEMASK(new Item(4164, 1), true),
- EARMUFFS(new Item(4166, 1), true) {
- @Override
- public boolean hasRequirement(final Player player) {
- return player.getSkills().getStaticLevel(Skills.DEFENCE) >= 15;
- }
- },
- NOSE_PEG(new Item(4168, 1), true),
- SLAYERS_STAFF(new Item(4170, 1)),
- SPINY_HELMET(new Item(4551, 1), true),
- FISHING_EXPLOSIVE(new Item(6660, 1)),
- ICE_COOLER(new Item(6696, 1)),
- SLAYER_GLOVES(new Item(6708, 1)),
- UNLIT_BUG_LANTERN(new Item(7051, 1)),
- INSULATED_BOOTS(new Item(7159, 1)),
- FUNGICIDE_SPRAY_10(new Item(7421, 1)),
- FUNGICIDE(new Item(7432, 1)),
- LUMBER_PATCH(new Item(8932, 1)),
- SLAYER_BELL(new Item(10952, 1)),
- WITCHWOOD_ICON(new Item(8923, 1)),
- LIT_BUG_LANTERN(new Item(7053, 1)),
-
- //null equipment for when none is needed
- NONE(new Item(0));
-
- /**
- * The slayer helmet item.
- */
- private static final Item SLAYER_HELM = new Item(13263);
-
- /**
- * Represents the item.
- */
- private final Item item;
-
- /**
- * IF the slayer helm has this equipment.
- */
- private final boolean slayerHelm;
-
- /**
- * Constructs a new {@Code Equipment} {@Code Object}
- * @param item The item.
- * @param slayerHelm If slayer helm incorporated.
- */
- Equipment(Item item, boolean slayerHelm) {
- this.item = item;
- this.slayerHelm = slayerHelm;
- }
-
- /**
- * Constructs a new {@Code Equipment} {@Code Object}
- * @param item The item.
- */
- Equipment(Item item) {
- this(item, false);
- }
-
- /**
- * Checks if the player has the requirement for the item.
- * @param player the player.
- * @return {@code True} if so.
- */
- public boolean hasRequirement(final Player player) {
- return item.getDefinition().hasRequirement(player, false, false);
- }
-
- /**
- * Checks if the player has the equipment equipped.
- * @param player the player.
- * @return {@code True} if so.
- */
- public boolean hasEquipment(final Player player) {
- if (slayerHelm && player.getEquipment().containsItem(SLAYER_HELM)) {
- return true;
- }
- return player.getEquipment().containsItem(item);
- }
-
- /**
- * Gets the item.
- * @return The item.
- */
- public Item getItem() {
- return item;
- }
-
- /**
- * Gets the slayerHelm.
- * @return the slayerHelm.
- */
- public boolean isSlayerHelm() {
- return slayerHelm;
- }
-}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/GargoyleNPC.java b/Server/src/main/java/core/game/node/entity/skill/slayer/GargoyleNPC.java
index 06a1711ad..48ccca94a 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/GargoyleNPC.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/GargoyleNPC.java
@@ -10,6 +10,7 @@ import core.game.node.entity.player.Player;
import core.game.world.map.Location;
import core.plugin.Initializable;
import core.plugin.Plugin;
+import org.rs09.consts.Items;
import rs09.plugin.PluginManager;
/**
@@ -88,7 +89,7 @@ public final class GargoyleNPC extends AbstractNPC {
* Constructs a new {@code RockHammerHandler} {@code Object}.
*/
public RockHammerHandler() {
- super(Equipment.ROCK_HAMMER.getItem().getId());
+ super(Items.ROCK_HAMMER_4162);
}
@Override
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/MirrorShieldHandler.java b/Server/src/main/java/core/game/node/entity/skill/slayer/MirrorShieldHandler.java
index 717917bf0..db7552b92 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/MirrorShieldHandler.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/MirrorShieldHandler.java
@@ -60,7 +60,7 @@ public final class MirrorShieldHandler extends MeleeSwingHandler {
* @return {@code True} if so.
*/
private static boolean hasShield(final Player player) {
- return Equipment.MIRROR_SHIELD.hasEquipment(player);
+ return SlayerEquipmentFlags.hasMirrorShield(player);
}
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerEquipmentFlags.kt b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerEquipmentFlags.kt
new file mode 100644
index 000000000..d925e3d1f
--- /dev/null
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerEquipmentFlags.kt
@@ -0,0 +1,87 @@
+package core.game.node.entity.skill.slayer
+
+import api.ContentAPI
+import api.EquipmentSlot
+import core.game.node.entity.player.Player
+import org.rs09.consts.Items
+import rs09.game.node.entity.skill.skillcapeperks.SkillcapePerks
+
+/**
+ * Represents a slayer equipment.
+ * @author Ceikry
+ */
+object SlayerEquipmentFlags {
+
+ val blackMasks = (Items.BLACK_MASK_10_8901..Items.BLACK_MASK_8921).map { it }.toIntArray()
+ val slayerItems = intArrayOf(Items.NOSE_PEG_4168, Items.EARMUFFS_4166, Items.FACE_MASK_4164, *blackMasks, Items.SPINY_HELMET_4551, Items.SLAYER_CAPET_9787, Items.SLAYER_CAPE_9786, Items.SLAYER_HELMET_13263, Items.WITCHWOOD_ICON_8923, Items.MIRROR_SHIELD_4156)
+
+ @JvmStatic
+ fun updateFlags(player: Player){
+ var flags = 0
+ if(SkillcapePerks.isActive(SkillcapePerks.TRICKS_OF_THE_TRADE,player) && ContentAPI.getAttribute(player, "cape_perks:tott:helmet-stored", false)) flags = 0x3F
+ else if(hasItem(player, Items.SLAYER_HELMET_13263)) flags = 0x1F
+ else if(hasItem(player, Items.NOSE_PEG_4168)) flags = 1
+ else if(hasItem(player, Items.EARMUFFS_4166)) flags = flags or (1 shl 1)
+ else if(hasItem(player, Items.FACE_MASK_4164)) flags = flags or (1 shl 2)
+ else if((ContentAPI.getItemFromEquipment(player, EquipmentSlot.HAT)?.id ?: 0) in blackMasks) flags = flags or (1 shl 3)
+ else if(hasItem(player, Items.SPINY_HELMET_4551)) flags = flags or (1 shl 4)
+
+ if((ContentAPI.getItemFromEquipment(player, EquipmentSlot.AMULET)?.id ?: 0) == Items.WITCHWOOD_ICON_8923) flags = flags or (1 shl 7)
+ if((ContentAPI.getItemFromEquipment(player, EquipmentSlot.SHIELD)?.id ?: 0) == Items.MIRROR_SHIELD_4156) flags = flags or (1 shl 8)
+ player.slayer.flags.equipmentFlags = flags
+ }
+
+ @JvmStatic
+ fun hasNosePeg(player: Player): Boolean{
+ return player.slayer.flags.equipmentFlags and 1 == 1
+ }
+
+ @JvmStatic
+ fun hasEarmuffs(player: Player): Boolean {
+ return (player.slayer.flags.equipmentFlags shr 1) and 1 == 1
+ }
+
+ @JvmStatic
+ fun hasFaceMask(player: Player): Boolean {
+ return (player.slayer.flags.equipmentFlags shr 2) and 1 == 1
+ }
+
+ @JvmStatic
+ fun hasBlackMask(player: Player): Boolean {
+ return (player.slayer.flags.equipmentFlags shr 3) and 1 == 1
+ }
+
+ @JvmStatic
+ fun hasSpinyHelmet(player: Player): Boolean {
+ return (player.slayer.flags.equipmentFlags shr 4) and 1 == 1
+ }
+
+ @JvmStatic
+ fun hasWitchwoodIcon(player: Player): Boolean {
+ return (player.slayer.flags.equipmentFlags shr 7) and 1 == 1
+ }
+
+ @JvmStatic
+ fun hasMirrorShield(player: Player): Boolean {
+ return (player.slayer.flags.equipmentFlags shr 8) and 1 == 1
+ }
+
+ @JvmStatic
+ fun getDamAccBonus(player: Player): Double {
+ val isCape = player.slayer.flags.equipmentFlags == 0x3F
+ val hasMask = hasBlackMask(player)
+
+ return if(isCape) 1.075
+ else if(hasMask) 1.15
+ else 1.0
+ }
+
+ private fun hasItem(player: Player, id: Int): Boolean{
+ return (ContentAPI.getItemFromEquipment(player, EquipmentSlot.HAT)?.id ?: 0) == id
+ }
+
+ fun isSlayerEq(item: Int): Boolean{
+ return item in slayerItems
+ }
+
+}
\ No newline at end of file
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerManager.java b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerManager.java
index 9fb1b24d0..669da7a1c 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerManager.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerManager.java
@@ -8,6 +8,7 @@ import core.game.node.entity.skill.Skills;
import core.tools.RandomFunction;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
+import rs09.game.node.entity.skill.slayer.SlayerFlags;
import java.util.ArrayList;
import java.util.Collections;
@@ -26,44 +27,9 @@ public final class SlayerManager {
private final Player player;
/**
- * The current slayer master used.
+ * The player's slayer flags
*/
- private Master master;
-
- /**
- * The current task.
- */
- private Tasks task;
-
- /**
- * The amount of the hunted killed.
- */
- private int amount;
-
- /**
- * The slayer points.
- */
- private int slayerPoints;
-
- /**
- * The task streak.
- */
- private int taskCount;
-
- /**
- * Total tasks completed
- */
- private int taskTotal;
-
- /**
- * The learned rewards.
- */
- private final boolean[] learned = new boolean[3];
-
- /**
- * The removed tasks.
- */
- private final List
removed = new ArrayList<>(4);
+ public final SlayerFlags flags;
/**
* Constructs a new {@Code SlayerManager} {@Code Object}
@@ -71,37 +37,66 @@ public final class SlayerManager {
*/
public SlayerManager(Player player) {
this.player = player;
+ this.flags = new SlayerFlags(player);
}
- /**
- * If the player can earn points (taskTotal > 4)
- */
- private boolean canEarnPoints = false;
-
public void parse(JSONObject slayerData){
Object m = slayerData.get("master");
- if(m != null)
- this.master = Master.forId(Integer.parseInt(m.toString()));
+ if(m != null) {
+ flags.setMaster(Master.forId(Integer.parseInt(m.toString())));
+ }
Object t = slayerData.get("taskId");
if(t != null)
- task = Tasks.values()[Integer.parseInt(t.toString())];
+ flags.setTask(Tasks.values()[Integer.parseInt(t.toString())]);
Object a = slayerData.get("taskAmount");
if(a != null)
- amount = Integer.parseInt(a.toString());
- slayerPoints = Integer.parseInt( slayerData.get("points").toString());
- taskCount = Integer.parseInt( slayerData.get("taskStreak").toString());
- JSONArray learnedArray = (JSONArray) slayerData.get("learned_rewards");
- for(int i = 0; i < learnedArray.size(); i++){
- learned[i] = (boolean) learnedArray.get(i);
- }
+ flags.setTaskAmount(Integer.parseInt(a.toString()));
+ Object points = slayerData.get("points");
+ if(points != null){
+ flags.setPoints(Integer.parseInt(points.toString()));
+ }
+ Object taskStreak = slayerData.get("taskStreak");
+ if(taskStreak != null){
+ flags.setTaskStreak(Integer.parseInt(taskStreak.toString()));
+ }
+ Object la = slayerData.get("learned_rewards");
+ if(la != null) {
+ JSONArray learnedArray = (JSONArray) slayerData.get("learned_rewards");
+ for (int i = 0; i < learnedArray.size(); i++) {
+ boolean unlocked = (boolean) learnedArray.get(i);
+ switch(i){
+ case 0:
+ if(unlocked) flags.unlockBroads();
+ break;
+ case 1:
+ if(unlocked) flags.unlockRing();
+ break;
+ case 2:
+ if(unlocked) flags.unlockHelm();
+ break;
+ default:
+ break;
+ }
+ }
+ }
JSONArray removedTasks = (JSONArray) slayerData.get("removedTasks");
if(removedTasks != null){
for(int i = 0; i < removedTasks.size(); i++){
- removed.add(Tasks.values()[Integer.parseInt(removedTasks.get(i).toString())]);
+ flags.getRemoved().add(Tasks.values()[Integer.parseInt(removedTasks.get(i).toString())]);
}
}
- taskTotal = Integer.parseInt( slayerData.get("totalTasks").toString());
- canEarnPoints = (boolean) slayerData.get("canEarnPoints");
+ Object completedTasks = slayerData.get("totalTasks").toString();
+ if(completedTasks != null) flags.setCompletedTasks(Integer.parseInt(completedTasks.toString()));
+ if(flags.getCompletedTasks() >= 4) flags.flagCanEarnPoints();
+
+ //New system parsing
+ if(slayerData.containsKey("equipmentFlags"))
+ flags.setEquipmentFlags(Integer.parseInt(slayerData.get("equipmentFlags").toString()));
+ if(slayerData.containsKey("taskFlags"))
+ flags.setTaskFlags(Integer.parseInt(slayerData.get("taskFlags").toString()));
+ if(slayerData.containsKey("rewardFlags"))
+ flags.setRewardFlags(Integer.parseInt(slayerData.get("rewardFlags").toString()));
+
}
/**
@@ -114,25 +109,25 @@ public final class SlayerManager {
decrementAmount(1);
if (!hasTask()) {
clear();
- taskCount++;
- taskTotal++;
- if ((taskCount > 4 || canEarnPoints ) && master != Master.TURAEL && slayerPoints < 64000) {
- int points = master.getTaskPoints()[0];
- if (taskCount % 10 == 0) {
- points = master.getTaskPoints()[1];
- } else if (taskCount % 50 == 0) {
- points = master.getTaskPoints()[2];
+ flags.setTaskStreak(flags.getTaskStreak() + 1);
+ flags.setCompletedTasks(flags.getCompletedTasks() + 1);
+ if ((flags.getCompletedTasks() > 4 || flags.canEarnPoints() ) && flags.getMaster() != Master.TURAEL && flags.getPoints() < 64000) {
+ int points = flags.getMaster().getTaskPoints()[0];
+ if (flags.getTaskStreak() % 10 == 0) {
+ points = flags.getMaster().getTaskPoints()[1];
+ } else if (flags.getTaskStreak() % 50 == 0) {
+ points = flags.getMaster().getTaskPoints()[2];
}
- slayerPoints += points;
- if (slayerPoints > 64000) {
- slayerPoints = 64000;
+ flags.incrementPoints(points);
+ if (flags.getPoints() > 64000) {
+ flags.setPoints(64000);
}
- player.sendMessages("You've completed " + taskCount + " tasks in a row and received " + points + " points, with a total of " + player.getSlayer().getSlayerPoints(),"You have completed " + taskTotal + " tasks in total. Return to a Slayer master.");
- } else if(taskCount == 4){
+ player.sendMessages("You've completed " + flags.getTaskStreak() + " tasks in a row and received " + points + " points, with a total of " + flags.getPoints(),"You have completed " + flags.getCompletedTasks() + " tasks in total. Return to a Slayer master.");
+ } else if(flags.getCompletedTasks() == 4){
player.sendMessage("You've completed your task; you will start gaining points on your next task!");
- canEarnPoints = true;
+ flags.flagCanEarnPoints();
} else {
- player.sendMessages("You've completed your task; Complete " + (4 - taskCount) + " more task(s) to start gaining points.", "Return to a Slayer master.");
+ player.sendMessages("You've completed your task; Complete " + (4 - flags.getCompletedTasks()) + " more task(s) to start gaining points.", "Return to a Slayer master.");
}
} else {
//player.sendMessage("You're assigned to kill " + NPCDefinition.forId((player.getSlayer().getTask().getNpcs()[0])).getName().toLowerCase() + "s; Only " + getAmount() + " more to go.");
@@ -153,8 +148,7 @@ public final class SlayerManager {
} else if (master == Master.VANNAKA) {
player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 14);
}
- getPlayer().varpManager.get(2502).setVarbit(1,task.ordinal());
- getPlayer().varpManager.get(2502).setVarbit(8,getAmount()).send(player);
+ getPlayer().varpManager.get(2502).setVarbit(0, flags.getTaskFlags() >> 4).send(player);
}
/**
@@ -178,14 +172,13 @@ public final class SlayerManager {
}
public boolean canBeAssigned(Tasks task){
- return player.getSkills().getLevel(Skills.SLAYER) >= task.levelReq && !removed.contains(task);
+ return player.getSkills().getLevel(Skills.SLAYER) >= task.levelReq && !flags.getRemoved().contains(task);
}
/**
* Clears the task.
*/
public void clear() {
- setTask(null);
setAmount(0);
}
@@ -203,14 +196,12 @@ public final class SlayerManager {
* @return the name.
*/
public String getTaskName() {
- if (task == null) {
- return "null";
- }
+ Tasks task = flags.getTask();
if (task.getNpcs() == null) {
return "no npcs report me";
}
if (task.getNpcs().length < 1) {
- return "npc length to small report me";
+ return "npc length too small report me";
}
return NPCDefinition.forId(task.getNpcs()[0]).getName().toLowerCase();
}
@@ -220,15 +211,15 @@ public final class SlayerManager {
* @return The task.
*/
public Tasks getTask() {
- return task;
+ return flags.getTask();
}
/**
* Sets the task.
* @param task The task to set.
*/
- public void setTask(Tasks task) {
- this.task = task;
+ public void setTask(Tasks task){
+ flags.setTask(task);
}
/**
@@ -244,7 +235,7 @@ public final class SlayerManager {
* @return The master.
*/
public Master getMaster() {
- return master;
+ return flags.getMaster();
}
/**
@@ -252,7 +243,7 @@ public final class SlayerManager {
* @param master The master to set.
*/
public void setMaster(Master master) {
- this.master = master;
+ flags.setMaster(master);
}
/**
@@ -260,13 +251,7 @@ public final class SlayerManager {
* @return {@code True} if so.
*/
public boolean hasTask() {
- if (task == null) {
- return false;
- }
- if (getAmount() == 0) {
- return false;
- }
- return true;
+ return getAmount() != 0;
}
/**
@@ -274,7 +259,7 @@ public final class SlayerManager {
* @return True if so.
*/
public boolean isCompleted() {
- return amount <= 0;
+ return flags.getTaskAmount() <= 0;
}
/**
@@ -282,7 +267,7 @@ public final class SlayerManager {
* @return The amount.
*/
public int getAmount() {
- return amount;
+ return flags.getTaskAmount();
}
/**
@@ -290,7 +275,7 @@ public final class SlayerManager {
* @param amount The amount to set.
*/
public void setAmount(int amount) {
- this.amount = amount;
+ flags.setTaskAmount(amount);
}
/**
@@ -298,10 +283,8 @@ public final class SlayerManager {
* @param amount the amount.
*/
public void decrementAmount(int amount) {
- this.amount -= amount;
- if(player.varpManager.get(2502).getVarbit(1) == null) player.varpManager.get(2502).setVarbit(1,task.ordinal());
- player.varpManager.get(2502).setVarbit(8,getAmount());
- player.varpManager.get(2502).send(player);
+ flags.decrementTaskAmount(amount);
+ player.varpManager.get(2502).setVarbit(0, flags.getTaskFlags() >> 4).send(player);
}
/**
@@ -309,7 +292,7 @@ public final class SlayerManager {
* @return {@code True} if so.
*/
public boolean hasStarted() {
- return master != null;
+ return flags.getCompletedTasks() > 0 || flags.getTaskAmount() > 0;
}
/**
@@ -317,7 +300,7 @@ public final class SlayerManager {
* @return the slayerPoints.
*/
public int getSlayerPoints() {
- return slayerPoints;
+ return flags.getPoints();
}
/**
@@ -325,7 +308,7 @@ public final class SlayerManager {
* @param slayerPoints the slayerPoints to set
*/
public void setSlayerPoints(int slayerPoints) {
- this.slayerPoints = slayerPoints;
+ flags.setPoints(slayerPoints);
}
/**
@@ -333,7 +316,7 @@ public final class SlayerManager {
* @return the taskCount.
*/
public int getTaskCount() {
- return taskCount;
+ return flags.getTaskStreak();
}
/**
@@ -341,15 +324,7 @@ public final class SlayerManager {
* @param taskCount the taskCount to set
*/
public void setTaskCount(int taskCount) {
- this.taskCount = taskCount;
- }
-
- /**
- * Gets the learned.
- * @return the learned.
- */
- public boolean[] getLearned() {
- return learned;
+ flags.setTaskStreak(taskCount);
}
/**
@@ -357,13 +332,13 @@ public final class SlayerManager {
* @return the removed.
*/
public List getRemoved() {
- return removed;
+ return flags.getRemoved();
}
- public int getTotalTasks() {return taskTotal;}
+ public int getTotalTasks() {return flags.getCompletedTasks();}
public boolean isCanEarnPoints(){
- return canEarnPoints;
+ return flags.canEarnPoints();
}
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerMasterDialogue.java b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerMasterDialogue.java
index 164e902ee..ecb1aed5f 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerMasterDialogue.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerMasterDialogue.java
@@ -1,5 +1,7 @@
package core.game.node.entity.skill.slayer;
+import org.json.simple.JSONObject;
+import rs09.ServerStore;
import rs09.game.world.GameWorld;
import core.game.content.dialogue.DialoguePlugin;
import core.game.content.dialogue.FacialExpression;
@@ -13,6 +15,8 @@ import core.game.node.entity.player.link.quest.Quest;
import core.game.node.item.Item;
import core.plugin.Initializable;
+import static rs09.tools.DialogueConstKt.END_DIALOGUE;
+
/**
* Represents the dialogue plugin used for a slayer master.
*
@@ -68,6 +72,8 @@ public final class SlayerMasterDialogue extends DialoguePlugin {
private final int level = 2;
+ private int rerolls = 0;
+
/**
* Constructs a new {@code SlayerMasterDialogue} {@code Object}.
*/
@@ -117,6 +123,7 @@ public final class SlayerMasterDialogue extends DialoguePlugin {
@Override
public boolean handle(int interfaceId, int buttonId) {
+ rerolls = ServerStore.getInt(getStoreFile(), player.getUsername().toLowerCase());
if (isDiary) {
switch (stage) {
case 999:
@@ -495,8 +502,8 @@ public final class SlayerMasterDialogue extends DialoguePlugin {
break;
}
if (Master.hasSameTask(master, player)) {
- interpreter.sendDialogues(master.getNpc(), getExpression(master), "You're still hunting something. Come back when you've", "finished your task.");
- stage = 999;
+ interpreter.sendDialogues(master.getNpc(), getExpression(master), "You're still hunting something. But let me check something...");
+ stage = 847;
} else {
player.getSlayer().setTaskCount(0);
player.getSlayer().generate(master);
@@ -514,9 +521,9 @@ public final class SlayerMasterDialogue extends DialoguePlugin {
} else {
options("Got any tips for me?", "Okay, great!");
}
- stage = 854;
+ stage++;
break;
- case 854:
+ case 845:
switch (buttonId) {
case 1:
interpreter.sendDialogues(master.getNpc(), getExpression(master), player.getSlayer().getTask().getTip());
@@ -528,8 +535,45 @@ public final class SlayerMasterDialogue extends DialoguePlugin {
break;
case 3:
player("I'd like to re-roll this task.");
+ if(rerolls == 10){
+ stage++;
+ } else {
+ player.getSlayer().clear();
+ getStoreFile().put(player.getUsername().toLowerCase(), rerolls + 1);
+ stage = 701;
+ }
+ }
+ break;
+ case 846:
+ npcl(FacialExpression.NEUTRAL, "Actually, you're out of free rerolls. You can buy a reroll from my reward store, though.");
+ stage = END_DIALOGUE;
+ break;
+ case 847:
+ if(rerolls < 10){
+ npcl(FacialExpression.NEUTRAL, "You do have " + (10 - rerolls) + " rerolls left today, would you like to use one?");
+ stage++;
+ }
+ else {
+ npcl(FacialExpression.NEUTRAL, "And it also seems you're out of rerolls for today. That's unfortunate.");
+ stage = END_DIALOGUE;
+ }
+ break;
+ case 848:
+ options("Yes, please.", "No, thanks.");
+ stage++;
+ break;
+ case 849:
+ switch(buttonId){
+ case 1:
+ playerl(FacialExpression.FRIENDLY, "Yes, please.");
player.getSlayer().clear();
+ getStoreFile().put(player.getUsername().toLowerCase(), rerolls + 1);
stage = 701;
+ break;
+ case 2:
+ playerl(FacialExpression.NEUTRAL, "No, thanks.");
+ stage = END_DIALOGUE;
+ break;
}
break;
case 860:
@@ -667,4 +711,8 @@ public final class SlayerMasterDialogue extends DialoguePlugin {
return new int[]{70, 1598, 1596, 1597, 1599, 8275, 8273, 8274, 8649};
}
+ private JSONObject getStoreFile() {
+ return ServerStore.getArchive("daily-slayer-rerolls");
+ }
+
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerRewardPlugin.java b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerRewardPlugin.java
index 6f5488e4a..480ba0f22 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerRewardPlugin.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/SlayerRewardPlugin.java
@@ -132,34 +132,34 @@ public class SlayerRewardPlugin extends ComponentPlugin {
break;
case 22://Broad arrows
case 29:
- if (player.getSlayer().getLearned()[0]) {
+ if (player.getSlayer().flags.isBroadsUnlocked()) {
player.sendMessage("You don't need to learn this ability again.");
break;
}
if (purchase(player, 300)) {
- player.getSlayer().getLearned()[0] = true;
+ player.getSlayer().flags.unlockBroads();
updateInterface(player, component);
}
break;
case 23://Slayer ring
case 30:
- if (player.getSlayer().getLearned()[1]) {
+ if (player.getSlayer().flags.isRingUnlocked()) {
player.sendMessage("You don't need to learn this ability again.");
break;
}
if (purchase(player, 300)) {
- player.getSlayer().getLearned()[1] = true;
+ player.getSlayer().flags.unlockRing();
updateInterface(player, component);
}
break;
case 24://Slayer helm
case 31:
- if (player.getSlayer().getLearned()[2]) {
+ if (player.getSlayer().flags.isHelmUnlocked()) {
player.sendMessage("You don't need to learn this ability again.");
break;
}
if (purchase(player, 400)) {
- player.getSlayer().getLearned()[2] = true;
+ player.getSlayer().flags.unlockHelm();
updateInterface(player, component);
}
break;
@@ -268,8 +268,20 @@ public class SlayerRewardPlugin extends ComponentPlugin {
player.getPacketDispatch().sendString(space + player.getSlayer().getSlayerPoints(), open.getId(), 19);
break;
case 163://learn
- for (int i = 0; i < player.getSlayer().getLearned().length; i++) {
- player.getPacketDispatch().sendInterfaceConfig(open.getId(), 25 + i, !player.getSlayer().getLearned()[i]);
+ for (int i = 0; i < 3; i++) {
+ switch(i){
+ case 0:
+ player.getPacketDispatch().sendInterfaceConfig(open.getId(), 25 + i, !player.getSlayer().flags.isBroadsUnlocked());
+ break;
+ case 1:
+ player.getPacketDispatch().sendInterfaceConfig(open.getId(), 25 + i, !player.getSlayer().flags.isRingUnlocked());
+ break;
+ case 2:
+ player.getPacketDispatch().sendInterfaceConfig(open.getId(), 25 + i, !player.getSlayer().flags.isHelmUnlocked());
+ break;
+ default:
+ break;
+ }
}
player.getPacketDispatch().sendString(space + player.getSlayer().getSlayerPoints(), open.getId(), 18);
break;
@@ -370,7 +382,7 @@ public class SlayerRewardPlugin extends ComponentPlugin {
player.sendMessage("You need a Crafting level of at least 55 in order to do this.");
return true;
}
- if (!player.getSlayer().getLearned()[2]) {
+ if (!player.getSlayer().flags.isHelmUnlocked()) {
player.sendMessage("You need to unlock the ability to do that first.");
return true;
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/Tasks.java b/Server/src/main/java/core/game/node/entity/skill/slayer/Tasks.java
index ff99c093a..37c3416cc 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/Tasks.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/Tasks.java
@@ -11,96 +11,96 @@ import java.util.HashMap;
* @author ceik
*/
public enum Tasks {
- ABERRANT_SPECTRES(65, new int[] { 1604, 1605, 1606, 1607 }, new String[] { "Aberrant spectres have an extremely potent stench that drains", "stats and life points. A nose peg, protects against the stench." }, 60, true, Equipment.NOSE_PEG),
- ABYSSAL_DEMONS(85, new int[] { 1615, 4230 }, new String[] { "Abyssal Demons are nasty creatures to deal with, they aren't really part, ", "of this realm, and are able to move very quickly to trap their prey"}, 85, false, Equipment.NONE),
- ANKOU(40, new int[] { 4381, 4382, 4383 }, new String[] { "Neither skeleton nor ghost, but a combination of both." }, 1, true, Equipment.NONE),
- AVIANSIES(60, new int[] { 6245, 6243, 6235, 6232, 6244, 6246, 6233, 6241, 6238, 6237, 6240, 6242, 6239, 6234 }, new String[] { "Graceful, bird-like creature." }, 1, false, Equipment.NONE),
- BANSHEE(20, new int[] { 1612 }, new String[] { "Banshees use a piercing scream to shock their enemies, you'll", "need some Earmuffs to protect yourself from them." }, 15, true, Equipment.EARMUFFS),
- BASILISKS(40, new int[] { 1616, 1617, 4228 }, new String[] { "A mirror shield is much neccesary when hunting these", "mad creatures." }, 40, false, Equipment.NONE),
- BATS(5, new int[] { 412, 78, 1005, 2482, 3711, }, new String[] { "These little creatures are incredibly quick.", "make sure you keep your eye on them at all times." }, 1, false, Equipment.NONE),
- BEARS(13, new int[] { 106, 105, 1195, 3645, 3664, 1326, 1327 }, new String[] { "A large animal with a crunching punch." }, 1, false, Equipment.NONE),
- BIRDS(1, new int[] { 1475, 5120, 5121, 5122, 5123, 5133, 1475, 1476, 41, 951, 1017, 1401, 1402, 2313, 2314, 2315, 1016, 1550, 147, 1180, 1754, 1755, 1756, 2252, 4570, 4571, 1911, 6114, 46, 2693, 6113, 6112, 146, 149, 150, 450, 451, 1179, 1322, 1323, 1324, 1325, 1400, 2726, 2727, 3197, 138, 48, 4373, 4374, 4535, 139, 1751, 148, 1181, 6382, 2459, 2460, 2461, 2462, 2707, 2708, 6115, 6116, 3296, 6378, 1996, 3675, 3676, 6792, 6946, 7320, 7322, 7324, 7326, 7328, 1692, 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 6322, 6323, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, }, new String[] { "irds aren't the most intelligent of creatures, but watch out for their", "sharp, stabbing beaks." }, 1, false, Equipment.NONE),
- BLACK_DEMONS(80, new int[] { 84, 677, 4702, 4703, 4704, 4705 }, new String[] { "Black Demons are magic creatures that are weak to magic attacks.", "They're the strongest demon and very dangerous." }, 1, false, Equipment.NONE),
- BLACK_DRAGONS(80, new int[] {54, 4673, 4674, 4675, 4676, 3376, 50 }, new String[] { "Black dragons are the strongest dragons", "watch out for their firey breath" }, 1, false, 40 | 80 << 16, Equipment.NONE),
- BLOODVELDS(50, new int[] { 1618, 1619, 6215, 7643, 7642 }, new String[] { "Bloodvelds are strange demonic creatures, they use their long rasping tongue", "to feed on just about anything they can find." }, 50, false, Equipment.NONE),
- BLUE_DRAGONS(65, new int[] { 55, 4681, 4682, 4683, 4684, 5178, 52, 4665, 4666, }, new String[] { "Blue dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, Equipment.NONE),
- BRINE_RATS(45, new int[] { 3707 }, new String[] { "Small little creatures they are, yet so very", "powerfull." }, 47, false, Equipment.NONE),
- BRONZE_DRAGONS(75, new int[] { 1590 }, new String[] { "Bronze dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 30 | 60 << 16, Equipment.NONE),
- CATABLEPONS(35, new int[] { 4397, 4398, 4399, }, new String[] { "They use the magic spell Weaken to drain up to 15% of their", "opponent's maximum Strength level." }, 1, false, Equipment.NONE),
- CAVE_BUG(1, new int[] { 1832, 5750, }, new String[] { "It regenerates life points quickly and seems to be a good", "herblore monster." }, 7, false, Equipment.NONE),
- CAVE_CRAWLERS(10, new int[] { 1600, 1601, 1602, 1603, }, new String[] { "The poisonous parts of them are presumably removed." }, 10, false, Equipment.NONE),
- CAVE_HORRORS(85, new int[] { 4353, 4354, 4355, 4356, 4357, }, new String[] { "A Cave horror wears a creepy mask, it is", "prefered to wear a witchwood icon." }, 58, false, Equipment.NONE),
- CAVE_SLIMES(15, new int[] { 1831 }, new String[] { "These are lesser versions of jellies, watch out they can poison you." }, 17, false, Equipment.NONE),
- COCKATRICES(25, new int[] { 1620, 1621, 4227, }, new String[] { "A Mirror shield is necessary when fighting these monsters." }, 25, false, Equipment.NONE),
- COWS(5, new int[] { 1766, 1768, 2310, 81, 397, 955, 1767, 3309 }, new String[] { "Cow's may seem stupid, however they know more then", "you think. Don't under estimate them." }, 1, false, Equipment.NONE),
- CRAWLING_HAND(1,new int[] { 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 4226, 7640, 7641 }, new String[] { "Crawling Hands are undead severed hands, fast and", "dexterous they claw their victims." }, 5, true, Equipment.NONE),
- CROCODILES(50, new int[] { 1993, 6779 }, new String[] { "Crocodiles can be found near water and marshes in and near the Kharidian Desert." }, 1, false, Equipment.NONE),
- CYCLOPES(25,new int[] { 116, 4291, 4292, 6078, 6079, 6080, 6081, 6269, 6270 }, new String[] { "Large one eyed creatures who normally wield a", "large mallet." }, 1, false, Equipment.NONE),
- DAGANNOTHS(75, new int[] { 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 2454, 2455, 2456, 2881, 2882, 2883, 2887, 2888, 3591, }, new String[] { "There are many types of Dagannoth, the most powerful being the three Dagannoth Kings." }, 1, false, Equipment.NONE),
- DARK_BEASTS(90, new int[] { 2783 }, new String[] { "A dark beast can attack using magic or melee." }, 90, false, Equipment.NONE),
- DESERT_LIZARDS(15, new int[] { 2803, 2804, 2805, 2806, 2807 }, new String[] { "Desert lizards are big Slayer monsters found in the Kharidian Desert." }, 22, false, Equipment.NONE),
- DOG(15, new int[] { 98, 99, 3582, 6374, 1994, 1593, 1594, 3582, 6374 }, new String[] { "Dogs are much like Wolves, they are pack creatures which will hunt in groups." }, 1, false, Equipment.NONE),
- DUST_DEVILS(70, new int[] { 1624 }, new String[] { "Dust Devils use clouds of dust, sand, ash and whatever", "else they can inhale to blind and disorientate", "their victims." }, 65, false, Equipment.NONE),
- DWARF(6, new int[] { 118, 120, 121, 382, 3219, 3220, 3221, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3294, 3295, 4316, 5880, 5881, 5882, 5883, 5884, 5885, 2130, 2131, 2132, 2133, 3276, 3277, 3278, 3279, 119, 2423 }, new String[] { "They are slightly resistant to Magic attacks, and", "are not recommended for low levels." }, 1, false, Equipment.NONE),
- EARTH_WARRIORS(35, new int[] { 124 }, new String[] { "An Earth warrior is a monster made of earth which fights using melee." }, 1, false, Equipment.NONE),
- FIRE_GIANTS(65, new int[] { 110, 1582, 1583, 1584, 1585, 1586, 7003, 7004 }, new String[] { "Like other giants, Fire Giants often wield large weapons", "learn to recognise what kind of weapon it is, and act accordingly." }, 1, false, Equipment.NONE),
- FLESH_CRAWLERS(15, new int[] { 4389, 4390, 4391 }, new String[] { "Flesh crawlers are medium level monsters found on", "level 2 of the Stronghold of Security." }, 1, false, Equipment.NONE),
- GARGOYLES(80, new int[] { 1610, 1611, 6389 }, new String[] { "Gargoyles are winged creatures of stone. You'll need to fight them to", "near death before breaking them apart with a rock hammer." }, 75, false, Equipment.ROCK_HAMMER),
- GHOSTS(13, new int[] { 103, 104, 491, 1541, 1549, 2716, 2931, 4387, 388, 5342, 5343, 5344, 5345, 5346, 5347, 5348, 1698, 5349, 5350, 5351, 5352, 5369, 5370, 5371, 5372, 5373, 5374, 5572, 6094, 6095, 6096, 6097, 6098, 6504, 13645, 13466, 13467, 13468, 13469, 13470, 13471, 13472, 13473, 13474, 13475, 13476, 13477, 13478, 13479, 13480, 13481 }, new String[] { "A Ghost is an undead monster that is found", "in various places and dungeons. " }, 1, false, Equipment.NONE),
- GHOULS(25, new int[] { 1218, 3059 }, new String[] { "Ghouls are a humanoid race and the descendants of a long-dead society", "that degraded to the point that its people ate their dead." }, 1, false, Equipment.NONE),
- GOBLINS(1, new int[] { 100, 101, 102, 444, 445, 489, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2678, 2679, 2680, 2681, 3060, 3264, 3265, 3266, 3267, 3413, 3414, 3415, 3726, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4407, 4408, 4409, 4410, 4411, 4412, 4479, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4499, 4633, 4634, 4635, 4636, 4637, 5786, 5824, 5855, 5856, 6125, 6126, 6132, 6133, 6279, 6280, 6281, 6282, 6283, 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, 6410, 6411, 6412, 6413, 6414, 6415, 6416, 6417, 6418, 6419, 6420, 6421, 6422, 6423, 6424, 6425, 6426, 6427, 6428, 6429, 6430, 6431, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, 6440, 6441, 6442, 6443, 6444, 6445, 6446, 6447, 6448, 6449, 6450, 6451, 6452, 6453, 6454, 6455, 6456, 6457, 6458, 6459, 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, 6490, 6491, 6492, 6493, 6494, 6495, 6496, 6497 }, new String[] { "Goblins are mostly just annoying, but they can be vicious.", "Watch out for the spears they sometimes carry." }, 1, false, Equipment.NONE),
- GORAKS(70, new int[] { 4418, 6218 }, new String[] { "Goraks can be tough monsters to fight. Be prepared." }, 1, false, Equipment.NONE),
- GREATER_DEMONS(75, new int[] { 83, 4698, 4699, 4700, 4701, 6208, 6206, 6204 }, new String[] { "Greater Demons are magic creatures so they are weak to magical attacks.", "They're the strongest demon and very dangerous." }, 1, false, Equipment.NONE),
- GREEN_DRAGON(52, new int[] { 941, 4677, 4678, 4679, 4680, 5362 }, new String[] { "Green dragons are very powerfull, they have fierce", "fiery breath." }, 1, false, Equipment.NONE),
- HARPIE_BUG_SWARMS(45, new int[] { 3153 }, new String[] { "Harpie Bug Swarms are insectoid Slayer monsters." }, 33, false, Equipment.NONE),
- HELLHOUNDS(75, new int[] { 49, 3586, 6210, }, new String[] { "Hellhounds are mid to high level demons." }, 1, false, Equipment.NONE),
- HILL_GIANTS(25, new int[] { 117, 4689, 4690, 3058, 4691, 4692, 4693 }, new String[] { "Hill giants can hit up to 19 damage, and they only attack with Melee." }, 1, false, Equipment.NONE),
- HOBGOBLINS(20, new int[] { 122, 123, 2685, 2686, 3061, 6608, 6642, 6661, 6684, 6710, 6722, 6727, 2687, 2688, 3583, 4898, 6275 }, new String[] { "Mysterious goblin like creatures." }, 1, false, Equipment.NONE),
- ICE_FIENDS(20, new int[] { 3406, 6217, 7714, 7715, 7716 }, new String[] { "An Icefiend is a monster found on top of Ice Mountain." }, 1, false, Equipment.NONE),
- ICE_GIANTS(50, new int[] { 111, 3072, 4685, 4686, 4687 }, new String[] { "Ice Giants often wield large weapons, learn to recognise", "what kind of weapon it is, and act accordingly" }, 1, false, Equipment.NONE),
- ICE_WARRIOR(45, new int[] { 125, 145, 3073 }, new String[] { "Ice warriors, are cold magestic creatures." }, 1, false, Equipment.NONE),
- INFERNAL_MAGES(40, new int[] { 1643, 1644, 1645, 1646, 1647 }, new String[] { "Infernal Mages are dangerous spell users, beware of their magic", "spells an go properly prepared" }, 45, false, Equipment.NONE),
- IRON_DRAGONS(80, new int[] { 1591 }, new String[] { "Iron dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 40 | 59 << 16, Equipment.NONE),
- JELLIES(57, new int[] { 1637, 1638, 1639, 1640, 1641, 1642 }, new String[] { "Jellies are nasty cube-like gelatinous creatures which", "absorb everything they come across into themselves." }, 52, false, Equipment.NONE),
- JUNGLE_HORRORS(65, new int[] { 4348, 4349, 4350, 4351, 4352 }, new String[] { "Jungle Horrors can be found all over Mos Le'Harmless.", "They are strong and aggressive, so watch out!" }, 1, false, Equipment.NONE),
- KALPHITES(15, new int[] { 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161 }, new String[] { "Kalaphite are large insects which live in great hives under the desert sands." }, 1, false, Equipment.NONE),
- KURASKS(65, new int[] { 1608, 1609, 4229 }, new String[] { "A kurask is a very quick creature." }, 70, false, Equipment.NONE),
- LESSER_DEMONS(60, new int[] { 6203, 82, 3064, 4694, 4695, 6208, 6204, 6206, 3064, 4696, 4697, 6101 }, new String[] { "Lesser Demons are magic creatures so they are weak to magical attacks." }, 1, false, Equipment.NONE),
- MITHRIL_DRAGON(60, new int[] { 5363 }, new String[] { "Mithril dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 5 | 9 << 16, Equipment.NONE),
- MINOTAURS(7, new int[] { 4404, 4405, 4406 }, new String[] { "Minotaurs are large manlike creatures but you'll", "want to be careful of their horns." }, 1, false, Equipment.NONE),
- MONKEYS(1, new int[] { 132, 1463, 1464, 2301, 4344, 4363, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 1455, 1459, 1460, 1456, 1457, 1458 }, new String[] { "Small agile creatures, watch out they pinch!" }, 1, false, Equipment.NONE),
- MOSS_GIANTS(40, new int[] { 112, 1587, 1588, 1681, 4534, 4688, 4706 }, new String[] { "They are known to carry large sticks." }, 1, false, Equipment.NONE),
- NECHRYAELS(85, new int[] { 1613 }, new String[] { "Nechryael are demons of decay which summon small winged beings which", "help them fight their victems." }, 80, false, Equipment.NONE),
- OGRES(40, new int[] { 114, 115, 374, 3587, 6267 }, new String[] { "Ogres are brutal creatures, favouring large blunt maces and clubs", "they often attack without warning." }, 1, false, Equipment.NONE),
- OTHERWORDLY_BEING(40, new int[] { 126 }, new String[] { "A creature filled with everlasting power." }, 1, false, Equipment.NONE),
- PYREFIENDS(25, new int[] { 1633, 1634, 1635, 1636, 6216, 6631, 6641, 6660, 6668, 6683, 6709, 6721, }, new String[] { "A scorching hot creature, watch out!" }, 30, false, Equipment.NONE),
- RATS(1, new int[] { 2682, 2980, 2981, 3007, 88, 224, 4928, 4929, 4936, 4937, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 4396, 4415, 7202, 7204, 7417, 7461, 87, 446, 950, 4395, 4922, 4923, 4924, 4925, 4926, 4927, 4942, 4943, 4944, 4945, 86, 87, 446, 950, 4395, 4922, 4923, 4924, 4925, 4926, 4927, 4942, 4943, 4944, 4945 }, new String[] { "Quick little rodents!" }, 1, false, Equipment.NONE),
- ROCK_SLUGS(20, new int[] { 1631, 1632 }, new String[] { "A rock slug can leave behind a trail of his presence.." }, 20, false, Equipment.NONE),
- SCORPIONS(7, new int[] { 107, 1477, 4402, 4403, 144 }, new String[] { "A scorpion makes a piercing sound, watch out for it's", " long sharp tail." }, 1, false, Equipment.NONE),
- SHADE(30, new int[] { 3617, 1250, 1241, 1246, 1248, 1250, 428, 1240 }, new String[] { "Shades are dark and mysterious, they hide in the shadows so be wary of ambushes." }, 1, true, Equipment.NONE),
- SKELETONS(15, new int[] { 90, 91, 92, 93, 94, 459, 1471, 1575, 1973, 2036, 2037, 2715, 2717, 3065, 3151, 3291, 3581, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3844, 3850, 3851, 4384, 4385, 4386, 5332, 5333, 5334, 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5359, 5365, 5366, 5367, 5368, 5381, 5384, 5385, 5386, 5387, 5388, 5389, 5390, 5391, 5392, 5411, 5412, 5422, 6091, 6092, 6093, 6103, 6104, 6105, 6106, 6107, 6764, 6765, 6766, 6767, 6768 }, new String[] { "Skeletons are undead monsters found in various locations." }, 1, true, Equipment.NONE),
- SPIDERS(1, new int[] { 61, 1004, 1221, 1473, 1474, 63, 4401, 2034, 977, 7207, 134, 1009, 59, 60, 4400, 58, 62, 1478, 2491, 2492, 6376, 6377, }, new String[] { "Level 24 spiders are aggressive and can hit up to 60 life points." }, 1, false, Equipment.NONE),
- SPIRTUAL_MAGES(60, new int[] { 6221, 6231, 6257, 6278 }, new String[] { "They are dangerous, they hit with mage." }, 83, false, Equipment.NONE),
- SPIRTUAL_RANGERS(60, new int[] { 6220, 6230, 6256, 6276 }, new String[] { "They are dangerous, they hit with range." }, 63, false, Equipment.NONE),
- SPIRTUAL_WARRIORS(60, new int[] { 6219, 6229, 6255, 6277, }, new String[] { "They are dangerous, they hit with melee." }, 68, false, Equipment.NONE),
- STEEL_DRAGONS( 85,new int[] { 1592, 3590 }, new String[] { "Steel dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 10 | 20 << 16, Equipment.NONE),
- TROLLS(60, new int[] { 72, 3584, 1098, 1096, 1097, 1095, 1101, 1105, 1102, 1103, 1104, 1130, 1131, 1132, 1133, 1134, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1138, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 3840, 3841, 3842, 3843, 3845, 1933, 1934, }, new String[] { "Trolls have a crushing attack, it's bets to wear a high crushing defence." }, 1, false, Equipment.NONE),
- TUROTHS(60, new int[] { 1626, 1627, 1628, 1629, 1630 }, new String[] { "Turoths are Slayer monsters that require a Slayer level of 55 to kill" }, 55, false, Equipment.NONE),
- TZHAAR(45, new int[] { 2591, 2592, 2593, 2745, 2594, 2595, 2596, 2597, 2604, 2605, 2606, 2607, 2608, 2609, 7755, 7753, 2598, 2599, 2600, 2601, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2624, 2617, 2618, 2625, 2602, 2603, 7754, 7767, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2624, 2625, 2627, 2628, 2629, 2630, 2631, 2632, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767, 7768, 7769, 7770, 7771, 7747, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7757, 7765, 7769, 7768 }, new String[] { "Young Tzhaar's of the century are furious with your kind." }, 1, false, Equipment.NONE),
- VAMPIRES(35, new int[] { 1023, 1220, 1223, 1225, 6214 }, new String[] { "Vampies arr equiped with large fangs", "they can do serious damage." }, 1, false, Equipment.NONE),
- WATERFIENDS(75, new int[] { 5361 }, new String[] { "A waterfiend takes no damage from fire!" }, 1, false, Equipment.NONE),
- WEREWOLFS(60, new int[] { 1665, 6006, 6007, 6008, 6009, 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, 6025, 6212, 6213, 6607, 6609, 6614, 6617, 6625, 6632, 6644, 6663, 6675, 6686, 6701, 6712, 6724, 6728, }, new String[] { "There temper is alot more nasty then a regular wolf!" }, 1, false, Equipment.NONE),
- WOLVES(20, new int[] { 95, 96, 97, 141, 142, 143, 839, 1198, 1330, 1558, 1559, 1951, 1952, 1953, 1954, 1955, 1956, 4413, 4414, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6829, 6830, 7005 }, new String[] { "Wolves are more agressive then dog's." }, 1, false, Equipment.NONE),
- ZOMBIES(10, new int[] { 73, 74, 75, 76, 2058, 2714, 2863, 2866, 2869, 2878, 3622, 4392, 4393, 4394, 5293, 5294, 5295, 5296, 5297, 5298, 5299, 5300, 5301, 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5311, 5312, 5313, 5314, 5315, 5316, 5317, 5318, 5319, 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, 5328, 5329, 5330, 5331, 5375, 5376, 5377, 5378, 5379, 5380, 5393, 5394, 5395, 5396, 5397, 5398, 5399, 5400, 5401, 5402, 5403, 5404, 5405, 5406, 5407, 5408, 5409, 5410, 6099, 6100, 6131, }, new String[] { "Zombies are creatures with no brain, they do hit farley", "high though." }, 1, true, Equipment.NONE),
- JAD(90, new int[] { }, new String[] { "TzTok-Jad is the king of the Fight Caves." }, 1, false, 1 | 1 << 16, Equipment.NONE),
- CHAOS_ELEMENTAL(90, new int[] { 3200 }, new String[] { "The Chaos Elemental is located in the deep Wilderness." }, 1, false, 5 | 25 << 16, Equipment.NONE),
- GIANT_MOLE(75, new int[] { 3340 }, new String[] { "Fighting the Giant Mole will require a light source." }, 1, false, 5 | 25 << 16, Equipment.NONE),
- KING_BLACK_DRAGON(75, new int[] { 50 }, new String[] { "The King Black Dragon is located in the deep wilderness." }, 1, false, 5 | 25 << 16, Equipment.NONE),
- COMMANDER_ZILYANA(90, new int[] { 6247 }, new String[] { "Commander Zilyana is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16, Equipment.NONE),
- GENERAL_GRARDOOR(90, new int[] { 6260 }, new String[] { "General Grardoor is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16, Equipment.NONE),
- KRIL_TSUTSAROTH(90, new int[] { 6203 }, new String[] { "Kril Tsutsaroth is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16, Equipment.NONE),
- KREE_ARRA(90, new int[] { 6222 }, new String[] { "Kree'arra is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16, Equipment.NONE),
- SKELETAL_WYVERN(70, new int[] { 3068, 3069, 3070, 3071 }, new String[] { "A skeletal wyvern requires an elemental, mirror", "or dragonfire shield." }, 72, false, 24 | 39 << 16, Equipment.NONE);
+ ABERRANT_SPECTRES(65, new int[] { 1604, 1605, 1606, 1607 }, new String[] { "Aberrant spectres have an extremely potent stench that drains", "stats and life points. A nose peg, protects against the stench." }, 60, true),
+ ABYSSAL_DEMONS(85, new int[] { 1615, 4230 }, new String[] { "Abyssal Demons are nasty creatures to deal with, they aren't really part, ", "of this realm, and are able to move very quickly to trap their prey"}, 85, false),
+ ANKOU(40, new int[] { 4381, 4382, 4383 }, new String[] { "Neither skeleton nor ghost, but a combination of both." }, 1, true),
+ AVIANSIES(60, new int[] { 6245, 6243, 6235, 6232, 6244, 6246, 6233, 6241, 6238, 6237, 6240, 6242, 6239, 6234 }, new String[] { "Graceful, bird-like creature." }, 1, false),
+ BANSHEE(20, new int[] { 1612 }, new String[] { "Banshees use a piercing scream to shock their enemies, you'll", "need some Earmuffs to protect yourself from them." }, 15, true),
+ BASILISKS(40, new int[] { 1616, 1617, 4228 }, new String[] { "A mirror shield is much neccesary when hunting these", "mad creatures." }, 40, false),
+ BATS(5, new int[] { 412, 78, 1005, 2482, 3711, }, new String[] { "These little creatures are incredibly quick.", "make sure you keep your eye on them at all times." }, 1, false),
+ BEARS(13, new int[] { 106, 105, 1195, 3645, 3664, 1326, 1327 }, new String[] { "A large animal with a crunching punch." }, 1, false),
+ BIRDS(1, new int[] { 1475, 5120, 5121, 5122, 5123, 5133, 1475, 1476, 41, 951, 1017, 1401, 1402, 2313, 2314, 2315, 1016, 1550, 147, 1180, 1754, 1755, 1756, 2252, 4570, 4571, 1911, 6114, 46, 2693, 6113, 6112, 146, 149, 150, 450, 451, 1179, 1322, 1323, 1324, 1325, 1400, 2726, 2727, 3197, 138, 48, 4373, 4374, 4535, 139, 1751, 148, 1181, 6382, 2459, 2460, 2461, 2462, 2707, 2708, 6115, 6116, 3296, 6378, 1996, 3675, 3676, 6792, 6946, 7320, 7322, 7324, 7326, 7328, 1692, 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 6322, 6323, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, }, new String[] { "irds aren't the most intelligent of creatures, but watch out for their", "sharp, stabbing beaks." }, 1, false),
+ BLACK_DEMONS(80, new int[] { 84, 677, 4702, 4703, 4704, 4705 }, new String[] { "Black Demons are magic creatures that are weak to magic attacks.", "They're the strongest demon and very dangerous." }, 1, false),
+ BLACK_DRAGONS(80, new int[] {54, 4673, 4674, 4675, 4676, 3376, 50 }, new String[] { "Black dragons are the strongest dragons", "watch out for their firey breath" }, 1, false, 40 | 80 << 16),
+ BLOODVELDS(50, new int[] { 1618, 1619, 6215, 7643, 7642 }, new String[] { "Bloodvelds are strange demonic creatures, they use their long rasping tongue", "to feed on just about anything they can find." }, 50, false),
+ BLUE_DRAGONS(65, new int[] { 55, 4681, 4682, 4683, 4684, 5178, 52, 4665, 4666, }, new String[] { "Blue dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false),
+ BRINE_RATS(45, new int[] { 3707 }, new String[] { "Small little creatures they are, yet so very", "powerfull." }, 47, false),
+ BRONZE_DRAGONS(75, new int[] { 1590 }, new String[] { "Bronze dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 30 | 60 << 16),
+ CATABLEPONS(35, new int[] { 4397, 4398, 4399, }, new String[] { "They use the magic spell Weaken to drain up to 15% of their", "opponent's maximum Strength level." }, 1, false),
+ CAVE_BUG(1, new int[] { 1832, 5750, }, new String[] { "It regenerates life points quickly and seems to be a good", "herblore monster." }, 7, false),
+ CAVE_CRAWLERS(10, new int[] { 1600, 1601, 1602, 1603, }, new String[] { "The poisonous parts of them are presumably removed." }, 10, false),
+ CAVE_HORRORS(85, new int[] { 4353, 4354, 4355, 4356, 4357, }, new String[] { "A Cave horror wears a creepy mask, it is", "prefered to wear a witchwood icon." }, 58, false),
+ CAVE_SLIMES(15, new int[] { 1831 }, new String[] { "These are lesser versions of jellies, watch out they can poison you." }, 17, false),
+ COCKATRICES(25, new int[] { 1620, 1621, 4227, }, new String[] { "A Mirror shield is necessary when fighting these monsters." }, 25, false),
+ COWS(5, new int[] { 1766, 1768, 2310, 81, 397, 955, 1767, 3309 }, new String[] { "Cow's may seem stupid, however they know more then", "you think. Don't under estimate them." }, 1, false),
+ CRAWLING_HAND(1,new int[] { 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 4226, 7640, 7641 }, new String[] { "Crawling Hands are undead severed hands, fast and", "dexterous they claw their victims." }, 5, true),
+ CROCODILES(50, new int[] { 1993, 6779 }, new String[] { "Crocodiles can be found near water and marshes in and near the Kharidian Desert." }, 1, false),
+ CYCLOPES(25,new int[] { 116, 4291, 4292, 6078, 6079, 6080, 6081, 6269, 6270 }, new String[] { "Large one eyed creatures who normally wield a", "large mallet." }, 1, false),
+ DAGANNOTHS(75, new int[] { 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 2454, 2455, 2456, 2881, 2882, 2883, 2887, 2888, 3591, }, new String[] { "There are many types of Dagannoth, the most powerful being the three Dagannoth Kings." }, 1, false),
+ DARK_BEASTS(90, new int[] { 2783 }, new String[] { "A dark beast can attack using magic or melee." }, 90, false),
+ DESERT_LIZARDS(15, new int[] { 2803, 2804, 2805, 2806, 2807 }, new String[] { "Desert lizards are big Slayer monsters found in the Kharidian Desert." }, 22, false),
+ DOG(15, new int[] { 98, 99, 3582, 6374, 1994, 1593, 1594, 3582, 6374 }, new String[] { "Dogs are much like Wolves, they are pack creatures which will hunt in groups." }, 1, false),
+ DUST_DEVILS(70, new int[] { 1624 }, new String[] { "Dust Devils use clouds of dust, sand, ash and whatever", "else they can inhale to blind and disorientate", "their victims." }, 65, false),
+ DWARF(6, new int[] { 118, 120, 121, 382, 3219, 3220, 3221, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3294, 3295, 4316, 5880, 5881, 5882, 5883, 5884, 5885, 2130, 2131, 2132, 2133, 3276, 3277, 3278, 3279, 119, 2423 }, new String[] { "They are slightly resistant to Magic attacks, and", "are not recommended for low levels." }, 1, false),
+ EARTH_WARRIORS(35, new int[] { 124 }, new String[] { "An Earth warrior is a monster made of earth which fights using melee." }, 1, false),
+ FIRE_GIANTS(65, new int[] { 110, 1582, 1583, 1584, 1585, 1586, 7003, 7004 }, new String[] { "Like other giants, Fire Giants often wield large weapons", "learn to recognise what kind of weapon it is, and act accordingly." }, 1, false),
+ FLESH_CRAWLERS(15, new int[] { 4389, 4390, 4391 }, new String[] { "Flesh crawlers are medium level monsters found on", "level 2 of the Stronghold of Security." }, 1, false),
+ GARGOYLES(80, new int[] { 1610, 1611, 6389 }, new String[] { "Gargoyles are winged creatures of stone. You'll need to fight them to", "near death before breaking them apart with a rock hammer." }, 75, false),
+ GHOSTS(13, new int[] { 103, 104, 491, 1541, 1549, 2716, 2931, 4387, 388, 5342, 5343, 5344, 5345, 5346, 5347, 5348, 1698, 5349, 5350, 5351, 5352, 5369, 5370, 5371, 5372, 5373, 5374, 5572, 6094, 6095, 6096, 6097, 6098, 6504, 13645, 13466, 13467, 13468, 13469, 13470, 13471, 13472, 13473, 13474, 13475, 13476, 13477, 13478, 13479, 13480, 13481 }, new String[] { "A Ghost is an undead monster that is found", "in various places and dungeons. " }, 1, false),
+ GHOULS(25, new int[] { 1218, 3059 }, new String[] { "Ghouls are a humanoid race and the descendants of a long-dead society", "that degraded to the point that its people ate their dead." }, 1, false),
+ GOBLINS(1, new int[] { 100, 101, 102, 444, 445, 489, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2678, 2679, 2680, 2681, 3060, 3264, 3265, 3266, 3267, 3413, 3414, 3415, 3726, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4407, 4408, 4409, 4410, 4411, 4412, 4479, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4499, 4633, 4634, 4635, 4636, 4637, 5786, 5824, 5855, 5856, 6125, 6126, 6132, 6133, 6279, 6280, 6281, 6282, 6283, 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, 6410, 6411, 6412, 6413, 6414, 6415, 6416, 6417, 6418, 6419, 6420, 6421, 6422, 6423, 6424, 6425, 6426, 6427, 6428, 6429, 6430, 6431, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, 6440, 6441, 6442, 6443, 6444, 6445, 6446, 6447, 6448, 6449, 6450, 6451, 6452, 6453, 6454, 6455, 6456, 6457, 6458, 6459, 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, 6490, 6491, 6492, 6493, 6494, 6495, 6496, 6497 }, new String[] { "Goblins are mostly just annoying, but they can be vicious.", "Watch out for the spears they sometimes carry." }, 1, false),
+ GORAKS(70, new int[] { 4418, 6218 }, new String[] { "Goraks can be tough monsters to fight. Be prepared." }, 1, false),
+ GREATER_DEMONS(75, new int[] { 83, 4698, 4699, 4700, 4701, 6208, 6206, 6204 }, new String[] { "Greater Demons are magic creatures so they are weak to magical attacks.", "They're the strongest demon and very dangerous." }, 1, false),
+ GREEN_DRAGON(52, new int[] { 941, 4677, 4678, 4679, 4680, 5362 }, new String[] { "Green dragons are very powerfull, they have fierce", "fiery breath." }, 1, false),
+ HARPIE_BUG_SWARMS(45, new int[] { 3153 }, new String[] { "Harpie Bug Swarms are insectoid Slayer monsters." }, 33, false),
+ HELLHOUNDS(75, new int[] { 49, 3586, 6210, }, new String[] { "Hellhounds are mid to high level demons." }, 1, false),
+ HILL_GIANTS(25, new int[] { 117, 4689, 4690, 3058, 4691, 4692, 4693 }, new String[] { "Hill giants can hit up to 19 damage, and they only attack with Melee." }, 1, false),
+ HOBGOBLINS(20, new int[] { 122, 123, 2685, 2686, 3061, 6608, 6642, 6661, 6684, 6710, 6722, 6727, 2687, 2688, 3583, 4898, 6275 }, new String[] { "Mysterious goblin like creatures." }, 1, false),
+ ICE_FIENDS(20, new int[] { 3406, 6217, 7714, 7715, 7716 }, new String[] { "An Icefiend is a monster found on top of Ice Mountain." }, 1, false),
+ ICE_GIANTS(50, new int[] { 111, 3072, 4685, 4686, 4687 }, new String[] { "Ice Giants often wield large weapons, learn to recognise", "what kind of weapon it is, and act accordingly" }, 1, false),
+ ICE_WARRIOR(45, new int[] { 125, 145, 3073 }, new String[] { "Ice warriors, are cold magestic creatures." }, 1, false),
+ INFERNAL_MAGES(40, new int[] { 1643, 1644, 1645, 1646, 1647 }, new String[] { "Infernal Mages are dangerous spell users, beware of their magic", "spells an go properly prepared" }, 45, false),
+ IRON_DRAGONS(80, new int[] { 1591 }, new String[] { "Iron dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 40 | 59 << 16),
+ JELLIES(57, new int[] { 1637, 1638, 1639, 1640, 1641, 1642 }, new String[] { "Jellies are nasty cube-like gelatinous creatures which", "absorb everything they come across into themselves." }, 52, false),
+ JUNGLE_HORRORS(65, new int[] { 4348, 4349, 4350, 4351, 4352 }, new String[] { "Jungle Horrors can be found all over Mos Le'Harmless.", "They are strong and aggressive, so watch out!" }, 1, false),
+ KALPHITES(15, new int[] { 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161 }, new String[] { "Kalaphite are large insects which live in great hives under the desert sands." }, 1, false),
+ KURASKS(65, new int[] { 1608, 1609, 4229 }, new String[] { "A kurask is a very quick creature." }, 70, false),
+ LESSER_DEMONS(60, new int[] { 6203, 82, 3064, 4694, 4695, 6208, 6204, 6206, 3064, 4696, 4697, 6101 }, new String[] { "Lesser Demons are magic creatures so they are weak to magical attacks." }, 1, false),
+ MITHRIL_DRAGON(60, new int[] { 5363 }, new String[] { "Mithril dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 5 | 9 << 16),
+ MINOTAURS(7, new int[] { 4404, 4405, 4406 }, new String[] { "Minotaurs are large manlike creatures but you'll", "want to be careful of their horns." }, 1, false),
+ MONKEYS(1, new int[] { 132, 1463, 1464, 2301, 4344, 4363, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 1455, 1459, 1460, 1456, 1457, 1458 }, new String[] { "Small agile creatures, watch out they pinch!" }, 1, false),
+ MOSS_GIANTS(40, new int[] { 112, 1587, 1588, 1681, 4534, 4688, 4706 }, new String[] { "They are known to carry large sticks." }, 1, false),
+ NECHRYAELS(85, new int[] { 1613 }, new String[] { "Nechryael are demons of decay which summon small winged beings which", "help them fight their victems." }, 80, false),
+ OGRES(40, new int[] { 114, 115, 374, 3587, 6267 }, new String[] { "Ogres are brutal creatures, favouring large blunt maces and clubs", "they often attack without warning." }, 1, false),
+ OTHERWORDLY_BEING(40, new int[] { 126 }, new String[] { "A creature filled with everlasting power." }, 1, false),
+ PYREFIENDS(25, new int[] { 1633, 1634, 1635, 1636, 6216, 6631, 6641, 6660, 6668, 6683, 6709, 6721, }, new String[] { "A scorching hot creature, watch out!" }, 30, false),
+ RATS(1, new int[] { 2682, 2980, 2981, 3007, 88, 224, 4928, 4929, 4936, 4937, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 4396, 4415, 7202, 7204, 7417, 7461, 87, 446, 950, 4395, 4922, 4923, 4924, 4925, 4926, 4927, 4942, 4943, 4944, 4945, 86, 87, 446, 950, 4395, 4922, 4923, 4924, 4925, 4926, 4927, 4942, 4943, 4944, 4945 }, new String[] { "Quick little rodents!" }, 1, false),
+ ROCK_SLUGS(20, new int[] { 1631, 1632 }, new String[] { "A rock slug can leave behind a trail of his presence.." }, 20, false),
+ SCORPIONS(7, new int[] { 107, 1477, 4402, 4403, 144 }, new String[] { "A scorpion makes a piercing sound, watch out for it's", " long sharp tail." }, 1, false),
+ SHADE(30, new int[] { 3617, 1250, 1241, 1246, 1248, 1250, 428, 1240 }, new String[] { "Shades are dark and mysterious, they hide in the shadows so be wary of ambushes." }, 1, true),
+ SKELETONS(15, new int[] { 90, 91, 92, 93, 94, 459, 1471, 1575, 1973, 2036, 2037, 2715, 2717, 3065, 3151, 3291, 3581, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3844, 3850, 3851, 4384, 4385, 4386, 5332, 5333, 5334, 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5359, 5365, 5366, 5367, 5368, 5381, 5384, 5385, 5386, 5387, 5388, 5389, 5390, 5391, 5392, 5411, 5412, 5422, 6091, 6092, 6093, 6103, 6104, 6105, 6106, 6107, 6764, 6765, 6766, 6767, 6768 }, new String[] { "Skeletons are undead monsters found in various locations." }, 1, true),
+ SPIDERS(1, new int[] { 61, 1004, 1221, 1473, 1474, 63, 4401, 2034, 977, 7207, 134, 1009, 59, 60, 4400, 58, 62, 1478, 2491, 2492, 6376, 6377, }, new String[] { "Level 24 spiders are aggressive and can hit up to 60 life points." }, 1, false),
+ SPIRTUAL_MAGES(60, new int[] { 6221, 6231, 6257, 6278 }, new String[] { "They are dangerous, they hit with mage." }, 83, false),
+ SPIRTUAL_RANGERS(60, new int[] { 6220, 6230, 6256, 6276 }, new String[] { "They are dangerous, they hit with range." }, 63, false),
+ SPIRTUAL_WARRIORS(60, new int[] { 6219, 6229, 6255, 6277, }, new String[] { "They are dangerous, they hit with melee." }, 68, false),
+ STEEL_DRAGONS( 85,new int[] { 1592, 3590 }, new String[] { "Steel dragons aren't as strong as other dragons but they're still", "very powerful, watch out for their firey breath." }, 1, false, 10 | 20 << 16),
+ TROLLS(60, new int[] { 72, 3584, 1098, 1096, 1097, 1095, 1101, 1105, 1102, 1103, 1104, 1130, 1131, 1132, 1133, 1134, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1138, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 3840, 3841, 3842, 3843, 3845, 1933, 1934, }, new String[] { "Trolls have a crushing attack, it's bets to wear a high crushing defence." }, 1, false),
+ TUROTHS(60, new int[] { 1626, 1627, 1628, 1629, 1630 }, new String[] { "Turoths are Slayer monsters that require a Slayer level of 55 to kill" }, 55, false),
+ TZHAAR(45, new int[] { 2591, 2592, 2593, 2745, 2594, 2595, 2596, 2597, 2604, 2605, 2606, 2607, 2608, 2609, 7755, 7753, 2598, 2599, 2600, 2601, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2624, 2617, 2618, 2625, 2602, 2603, 7754, 7767, 2610, 2611, 2612, 2613, 2614, 2615, 2616, 2624, 2625, 2627, 2628, 2629, 2630, 2631, 2632, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7758, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767, 7768, 7769, 7770, 7771, 7747, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7757, 7765, 7769, 7768 }, new String[] { "Young Tzhaar's of the century are furious with your kind." }, 1, false),
+ VAMPIRES(35, new int[] { 1023, 1220, 1223, 1225, 6214 }, new String[] { "Vampies arr equiped with large fangs", "they can do serious damage." }, 1, false),
+ WATERFIENDS(75, new int[] { 5361 }, new String[] { "A waterfiend takes no damage from fire!" }, 1, false),
+ WEREWOLFS(60, new int[] { 1665, 6006, 6007, 6008, 6009, 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, 6025, 6212, 6213, 6607, 6609, 6614, 6617, 6625, 6632, 6644, 6663, 6675, 6686, 6701, 6712, 6724, 6728, }, new String[] { "There temper is alot more nasty then a regular wolf!" }, 1, false),
+ WOLVES(20, new int[] { 95, 96, 97, 141, 142, 143, 839, 1198, 1330, 1558, 1559, 1951, 1952, 1953, 1954, 1955, 1956, 4413, 4414, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6829, 6830, 7005 }, new String[] { "Wolves are more agressive then dog's." }, 1, false),
+ ZOMBIES(10, new int[] { 73, 74, 75, 76, 2058, 2714, 2863, 2866, 2869, 2878, 3622, 4392, 4393, 4394, 5293, 5294, 5295, 5296, 5297, 5298, 5299, 5300, 5301, 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5311, 5312, 5313, 5314, 5315, 5316, 5317, 5318, 5319, 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, 5328, 5329, 5330, 5331, 5375, 5376, 5377, 5378, 5379, 5380, 5393, 5394, 5395, 5396, 5397, 5398, 5399, 5400, 5401, 5402, 5403, 5404, 5405, 5406, 5407, 5408, 5409, 5410, 6099, 6100, 6131, }, new String[] { "Zombies are creatures with no brain, they do hit farley", "high though." }, 1, true),
+ JAD(90, new int[] { }, new String[] { "TzTok-Jad is the king of the Fight Caves." }, 1, false, 1 | 1 << 16),
+ CHAOS_ELEMENTAL(90, new int[] { 3200 }, new String[] { "The Chaos Elemental is located in the deep Wilderness." }, 1, false, 5 | 25 << 16),
+ GIANT_MOLE(75, new int[] { 3340 }, new String[] { "Fighting the Giant Mole will require a light source." }, 1, false, 5 | 25 << 16),
+ KING_BLACK_DRAGON(75, new int[] { 50 }, new String[] { "The King Black Dragon is located in the deep wilderness." }, 1, false, 5 | 25 << 16),
+ COMMANDER_ZILYANA(90, new int[] { 6247 }, new String[] { "Commander Zilyana is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16),
+ GENERAL_GRARDOOR(90, new int[] { 6260 }, new String[] { "General Grardoor is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16),
+ KRIL_TSUTSAROTH(90, new int[] { 6203 }, new String[] { "Kril Tsutsaroth is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16),
+ KREE_ARRA(90, new int[] { 6222 }, new String[] { "Kree'arra is one of the four Godwars bosses." }, 1, false, 5 | 25 << 16),
+ SKELETAL_WYVERN(70, new int[] { 3068, 3069, 3070, 3071 }, new String[] { "A skeletal wyvern requires an elemental, mirror", "or dragonfire shield." }, 72, false, 24 | 39 << 16);
static final HashMap taskMap = new HashMap<>();
static{
@@ -110,23 +110,20 @@ public enum Tasks {
public String[] info;
public int[] ids;
public boolean undead;
- public Equipment recEquip;
public int amtHash;
- Tasks(int combatCheck, int[] ids, String[] info, int levelReq, boolean undead, Equipment recEquip){
+ Tasks(int combatCheck, int[] ids, String[] info, int levelReq, boolean undead){
this.levelReq = levelReq;
this.ids = ids;
this.info = info;
this.undead = undead;
- this.recEquip = recEquip;
this.combatCheck = combatCheck;
}
- Tasks(int combatCheck,int[] ids, String[] info, int levelReq, boolean undead, int amtHash, Equipment recEquip){
+ Tasks(int combatCheck, int[] ids, String[] info, int levelReq, boolean undead, int amtHash){
this.levelReq = levelReq;
this.ids = ids;
this.info = info;
this.undead = undead;
- this.recEquip = recEquip;
this.amtHash = amtHash;
this.combatCheck = combatCheck;
}
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/LumbridgeDungeon.java b/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/LumbridgeDungeon.java
index fdc2b21d3..cfca0ec06 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/LumbridgeDungeon.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/LumbridgeDungeon.java
@@ -1,7 +1,7 @@
package core.game.node.entity.skill.slayer.dungeon;
import core.cache.def.impl.NPCDefinition;
-import core.game.node.entity.skill.slayer.Equipment;
+import core.game.node.entity.skill.slayer.SlayerEquipmentFlags;
import core.game.interaction.Option;
import core.game.node.Node;
import core.game.node.entity.Entity;
@@ -75,7 +75,7 @@ public final class LumbridgeDungeon extends MapZone implements Plugin {
* @return {@code True} if so.
*/
private boolean hasHelmet(final Player player) {
- return Equipment.SPINY_HELMET.hasEquipment(player);
+ return SlayerEquipmentFlags.hasSpinyHelmet(player);
}
@Override
diff --git a/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/SmokeDungeon.java b/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/SmokeDungeon.java
index 2d57086c0..875a6cded 100644
--- a/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/SmokeDungeon.java
+++ b/Server/src/main/java/core/game/node/entity/skill/slayer/dungeon/SmokeDungeon.java
@@ -2,7 +2,7 @@ package core.game.node.entity.skill.slayer.dungeon;
import core.cache.def.impl.SceneryDefinition;
import core.game.component.Component;
-import core.game.node.entity.skill.slayer.Equipment;
+import core.game.node.entity.skill.slayer.SlayerEquipmentFlags;
import core.game.interaction.OptionHandler;
import core.game.node.Node;
import core.game.node.entity.Entity;
@@ -164,7 +164,7 @@ public final class SmokeDungeon extends MapZone implements Plugin {
* @return {@code True} if so.
*/
private static boolean isProtected(Player player) {
- return Equipment.FACEMASK.hasEquipment(player);
+ return SlayerEquipmentFlags.hasFaceMask(player);
}
@Override
diff --git a/Server/src/main/kotlin/rs09/ServerStore.kt b/Server/src/main/kotlin/rs09/ServerStore.kt
index 195a03c98..aa42288f1 100644
--- a/Server/src/main/kotlin/rs09/ServerStore.kt
+++ b/Server/src/main/kotlin/rs09/ServerStore.kt
@@ -63,6 +63,7 @@ object ServerStore {
}
}
+ @JvmStatic
fun getArchive(name: String): JSONObject {
if(fileMap[name] == null){
fileMap[name] = JSONObject()
@@ -87,6 +88,7 @@ object ServerStore {
}
}
+ @JvmStatic
fun JSONObject.getInt(key: String): Int {
return when(val value = this[key]){
is Long -> value.toInt()
diff --git a/Server/src/main/kotlin/rs09/game/content/activity/wguild/WGuildListeners.kt b/Server/src/main/kotlin/rs09/game/content/activity/wguild/WGuildListeners.kt
new file mode 100644
index 000000000..fafd7ce09
--- /dev/null
+++ b/Server/src/main/kotlin/rs09/game/content/activity/wguild/WGuildListeners.kt
@@ -0,0 +1,42 @@
+package rs09.game.content.activity.wguild
+
+import core.game.component.Component
+import core.game.container.impl.EquipmentContainer
+import core.game.content.activity.wguild.catapult.CatapultRoom
+import core.game.node.item.Item
+import org.rs09.consts.Items
+import rs09.game.interaction.InteractionListener
+
+class WGuildListeners : InteractionListener() {
+ override fun defineListeners() {
+ onEquip(Items.DEFENSIVE_SHIELD_8856){player, node ->
+ if (node is Item) {
+ if (player.location != CatapultRoom.TARGET) {
+ player.packetDispatch.sendMessage("You may not equip this shield outside the target area in the Warrior's Guild.")
+ return@onEquip false
+ }
+ if (player.equipment[EquipmentContainer.SLOT_WEAPON] != null) {
+ player.dialogueInterpreter.sendDialogue(
+ "You will need to make sure your sword hand is free to equip this",
+ "shield."
+ )
+ return@onEquip false
+ }
+
+ player.interfaceManager.hideTabs(2, 3, 5, 6, 7, 11, 12)
+ player.interfaceManager.openTab(4, Component(411))
+ player.interfaceManager.setViewedTab(4)
+ player.interfaceManager.open(Component(410))
+ return@onEquip true
+ }
+
+ return@onEquip false
+ }
+
+ onUnequip(Items.DEFENSIVE_SHIELD_8856){player, _ ->
+ player.interfaceManager.restoreTabs()
+ player.interfaceManager.openTab(4, Component(387))
+ return@onUnequip true
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt
index 99d125d8a..e252b41cb 100644
--- a/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt
+++ b/Server/src/main/kotlin/rs09/game/content/global/action/EquipHandler.kt
@@ -6,6 +6,7 @@ import core.game.node.entity.combat.equipment.WeaponInterface
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.audio.Audio
import core.game.node.entity.player.link.diary.DiaryType
+import core.game.node.entity.skill.slayer.SlayerEquipmentFlags
import core.game.system.task.Pulse
import core.game.world.map.zone.ZoneBorders
import core.plugin.Plugin
@@ -78,6 +79,10 @@ class EquipHandler : InteractionListener() {
wif.selectAutoSpell(-1, true)
wif.openAutocastSelect()
}
+
+ if(SlayerEquipmentFlags.isSlayerEq(item.id)){
+ SlayerEquipmentFlags.updateFlags(player)
+ }
}
}
@@ -121,6 +126,10 @@ class EquipHandler : InteractionListener() {
player.dialogueInterpreter.close()
player.inventory.add(item)
}
+
+ if(SlayerEquipmentFlags.isSlayerEq(item.id)){
+ SlayerEquipmentFlags.updateFlags(player)
+ }
}
}
}
\ No newline at end of file
diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/LarryHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/LarryHandler.kt
index 8a5c30ec1..38382f1c6 100644
--- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/LarryHandler.kt
+++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/LarryHandler.kt
@@ -1,5 +1,6 @@
package rs09.game.content.global.worldevents.penguinhns
+import api.ContentAPI
import core.game.component.Component
import core.game.content.dialogue.DialoguePlugin
import core.game.content.dialogue.FacialExpression
@@ -68,19 +69,19 @@ class LarryHandler(player: Player? = null) : DialoguePlugin(player){
return true
}
- override fun handleSelectionCallback(skill: Int, player: Player?) {
- val points = player?.getAttribute("phns:points",0)
+ override fun handleSelectionCallback(skill: Int, player: Player) {
+ val points = player.getAttribute("phns:points",0)
if(points == 0){
player.sendMessage("Sorry, but you have no points to redeem.")
return
}
- val level = player?.skills?.getLevel(skill) ?: 0
+ val level = ContentAPI.getStatLevel(player, skill)
System.out.println("Level: $level")
val expGained = points?.toDouble()?.times((level * 25))
System.out.print("exp: $expGained")
- player?.skills?.addExperience(skill,expGained!!)
- player?.setAttribute("/save:phns:points",0)
+ player.skills.addExperience(skill,expGained!!)
+ player.setAttribute("/save:phns:points",0)
}
override fun getIds(): IntArray {
diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinHNSEvent.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinHNSEvent.kt
index e28aa1c3d..38f68a8da 100644
--- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinHNSEvent.kt
+++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinHNSEvent.kt
@@ -25,7 +25,6 @@ class PenguinHNSEvent : WorldEvent("penguin-hns"){
plugins = PluginSet(
LarryHandler(),
NotebookHandler(),
- PenguinSpyingHandler()
)
super.initialize()
fireEvent()
diff --git a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt
index cf90e6852..6d96d95ce 100644
--- a/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt
+++ b/Server/src/main/kotlin/rs09/game/content/global/worldevents/penguinhns/PenguinSpyingHandler.kt
@@ -11,13 +11,27 @@ import core.game.world.update.flag.context.Animation
import core.plugin.Plugin
import core.game.content.quest.PluginInteraction
import core.game.content.quest.PluginInteractionManager
+import rs09.game.interaction.InteractionListener
-class PenguinSpyingHandler : PluginInteraction(8107,8108,8104,8105,8109,8110){
+class PenguinSpyingHandler : InteractionListener(){
- class SpyPulse(val player: Player) : Pulse() {
+ override fun defineListeners() {
+ on(PENGUINS, NPC, "spy-on"){player, node ->
+ val npc = node.asNpc()
+ if(PenguinManager.hasTagged(player, npc.location)){
+ player.sendMessage("You've already tagged this penguin.")
+ } else {
+ GameWorld.submit(SpyPulse(player, npc))
+ }
+ return@on true
+ }
+ }
+
+ val PENGUINS = intArrayOf(8104,8105,8107,8108,8109,8110)
+
+ class SpyPulse(val player: Player, val npc: NPC) : Pulse() {
var stage = 0
val curPoints = player.getAttribute("phns:points",0)
- val weeklyPoints = player.getAttribute("phns:weekly",0)
val ANIMATION = Animation(10355)
@@ -26,6 +40,7 @@ class PenguinSpyingHandler : PluginInteraction(8107,8108,8104,8105,8109,8110){
0 -> player.lock().also { player.animator.animate(ANIMATION) }
1 -> player.sendMessage("You manage to spy on the penguin.").also {
player.setAttribute("/save:phns:points",curPoints + 1)
+ PenguinManager.registerTag(player, npc.location)
player.unlock()
}
2 -> return true
@@ -33,34 +48,4 @@ class PenguinSpyingHandler : PluginInteraction(8107,8108,8104,8105,8109,8110){
return false
}
}
-
- override fun handle(player: Player?, npc: NPC?, option: Option?): Boolean {
- class movePulse : MovementPulse(player,DestinationFlag.ENTITY.getDestination(player,npc)){
- override fun pulse(): Boolean {
- player.let { player?.face(npc);GameWorld.submit(SpyPulse(player!!)) }
- return true
- }
- }
- if(option?.name?.toLowerCase()?.equals("spy-on")!!){
- player ?: return false
- if(PenguinManager.hasTagged(player, npc!!.location)){
- player.sendMessage("You've already tagged this penguin.")
- } else {
- GameWorld.submit(movePulse())
- PenguinManager.registerTag(player, npc!!.location)
- }
- return true
- }
- return false
- }
-
- override fun fireEvent(identifier: String?, vararg args: Any?): Any {
- return Unit
- }
-
- override fun newInstance(arg: Any?): Plugin {
- PluginInteractionManager.register(this,PluginInteractionManager.InteractionType.NPC)
- return this
- }
-
}
\ No newline at end of file
diff --git a/Server/src/main/kotlin/rs09/game/content/quest/free/dragonslayer/DSEquipListeners.kt b/Server/src/main/kotlin/rs09/game/content/quest/free/dragonslayer/DSEquipListeners.kt
new file mode 100644
index 000000000..8c86f5482
--- /dev/null
+++ b/Server/src/main/kotlin/rs09/game/content/quest/free/dragonslayer/DSEquipListeners.kt
@@ -0,0 +1,41 @@
+package rs09.game.content.quest.free.dragonslayer
+
+import api.ContentAPI
+import org.rs09.consts.Items
+import rs09.game.interaction.InteractionListener
+
+class DSEquipListeners : InteractionListener() {
+
+ private val restrictedItems = intArrayOf(
+ Items.RUNE_PLATEBODY_1127,
+ Items.RUNE_PLATEBODY_G_10798,
+ Items.RUNE_PLATEBODY_G_2615,
+ Items.RUNE_PLATEBODY_G_13800,
+ Items.RUNE_PLATEBODY_T_10800,
+ Items.RUNE_PLATEBODY_T_13805,
+ Items.RUNE_PLATEBODY_T_2623,
+ Items.ZAMORAK_PLATEBODY_2653,
+ Items.SARADOMIN_PLATEBODY_2661,
+ Items.GUTHIX_PLATEBODY_2669,
+ Items.GREEN_DHIDE_BODY_1135,
+ Items.BLUE_DHIDE_BODY_2499,
+ Items.RED_DHIDE_BODY_2501,
+ Items.BLACK_DHIDE_BODY_2503,
+ Items.DHIDE_BODYG_7370,
+ Items.DHIDE_BODY_G_7374,
+ Items.DHIDE_BODY_T_7372,
+ Items.DHIDE_BODY_T_7376
+ )
+
+ override fun defineListeners() {
+ for(id in restrictedItems){
+ onEquip(id){ player, _ ->
+ if(!player.questRepository.isComplete("Dragon Slayer")){
+ ContentAPI.sendMessage(player, "You must have completed Dragon Slayer to equip this.")
+ return@onEquip false
+ }
+ return@onEquip true
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/kotlin/rs09/game/interaction/inter/ExperienceInterface.kt b/Server/src/main/kotlin/rs09/game/interaction/inter/ExperienceInterface.kt
index ce9dd3038..666b376f1 100644
--- a/Server/src/main/kotlin/rs09/game/interaction/inter/ExperienceInterface.kt
+++ b/Server/src/main/kotlin/rs09/game/interaction/inter/ExperienceInterface.kt
@@ -70,7 +70,6 @@ class ExperienceInterface() : ComponentPlugin() {
46 -> Skills.WOODCUTTING
40 -> Skills.FLETCHING
51 -> Skills.CONSTRUCTION
- 52 -> Skills.SUMMONING
else -> Skills.SLAYER.also { SystemLogger.logWarn("EXP_INTERFACE: Invalid SKILL CHOICE BUTTON: $button") }
}
player.setAttribute("exp_interface:skill",skill)
diff --git a/Server/src/main/kotlin/rs09/game/interaction/item/withitem/TOTTHelmOnCape.kt b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/TOTTHelmOnCape.kt
new file mode 100644
index 000000000..1eff3699f
--- /dev/null
+++ b/Server/src/main/kotlin/rs09/game/interaction/item/withitem/TOTTHelmOnCape.kt
@@ -0,0 +1,42 @@
+package rs09.game.interaction.item.withitem
+
+import api.Container
+import api.ContentAPI
+import api.DialUtils
+import org.rs09.consts.Items
+import rs09.game.content.dialogue.DialogueFile
+import rs09.game.interaction.InteractionListener
+import rs09.tools.END_DIALOGUE
+
+class TOTTHelmOnCape : InteractionListener() {
+ override fun defineListeners() {
+ onUseWith(ITEM, Items.SLAYER_HELMET_13263, Items.SLAYER_CAPE_9786, Items.SLAYER_CAPET_9787){ player, used, with ->
+ val alreadyHasHelm = ContentAPI.getAttribute(player, "cape_perks:tott:helmet-stored", false)
+
+ if(alreadyHasHelm){
+ ContentAPI.sendDialogue(player, "You've already stored the components of a helmet in this cape.")
+ } else {
+ ContentAPI.openDialogue(player, object : DialogueFile(){
+ override fun handle(componentID: Int, buttonID: Int) {
+ when(stage){
+ 0 -> dialogue("This will destroy your helmet permanently.").also { stage++ }
+ 1 -> interpreter!!.sendOptions("Continue?", "Yes", "No").also { stage++ }
+ 2 -> when(buttonID){
+ 1 -> {
+ if(ContentAPI.removeItem(player, Items.SLAYER_HELMET_13263, Container.INVENTORY)) {
+ dialogue(*DialUtils.splitLines("You disassemble the helmet and place the components into their respective pockets on your cape."))
+ ContentAPI.setAttribute(player, "/save:cape_perks:tott:helmet-stored", true)
+ stage = END_DIALOGUE
+ }
+ }
+ 2 -> end()
+ }
+ }
+ }
+ })
+ }
+
+ return@onUseWith true
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/MeleeSwingHandler.kt b/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/MeleeSwingHandler.kt
index ace2c1905..3b8346b79 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/MeleeSwingHandler.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/MeleeSwingHandler.kt
@@ -15,10 +15,13 @@ import core.game.node.entity.combat.equipment.WeaponInterface
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills
+import core.game.node.entity.skill.slayer.SlayerEquipmentFlags
import core.game.node.entity.state.EntityState
import core.game.world.map.path.Pathfinder
import core.tools.RandomFunction
import rs09.game.node.entity.combat.CombatSwingHandler
+import rs09.game.node.entity.skill.skillcapeperks.SkillcapePerks
+import kotlin.math.ceil
import kotlin.math.floor
/**
@@ -148,17 +151,16 @@ open class MeleeSwingHandler
effectiveAttackLevel = floor(effectiveAttackLevel)
effectiveAttackLevel *= (entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64)
- val helmetName = (if(entity is Player) ContentAPI.getItemFromEquipment(entity, EquipmentSlot.HAT)?.name ?: "null" else "null").toLowerCase()
val amuletName = (if(entity is Player) ContentAPI.getItemFromEquipment(entity, EquipmentSlot.AMULET)?.name ?: "null" else "null").toLowerCase()
val victimName = entity.properties.combatPulse.getVictim()?.name ?: "none"
- if (entity is Player //Slayer helm/ black mask
- && (helmetName.contains("black mask") || helmetName.contains("slayer helm"))
- && entity.slayer.task?.ids?.contains((entity.properties.combatPulse.getVictim()?.id ?: 0)) == true
- ) {
- effectiveAttackLevel *= 1.2
+ if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.PRECISION_STRIKES, entity)){ //Attack skillcape perk
+ effectiveAttackLevel += 6
}
+ if(entity is Player && entity.slayer.task?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true)
+ effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape
+
else if (entity is Player //Salve amulet
&& (amuletName.contains("salve"))
&& checkUndead(victimName)
@@ -171,7 +173,7 @@ open class MeleeSwingHandler
override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int {
val level = entity!!.skills.getLevel(Skills.STRENGTH)
- val bonus = entity.properties.bonuses[11]
+ var bonus = entity.properties.bonuses[11]
var prayer = 1.0
if (entity is Player) {
prayer += entity.prayer.getSkillBonus(Skills.STRENGTH)
@@ -182,7 +184,16 @@ open class MeleeSwingHandler
} else if (entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) {
cumulativeStr += 1.0
}
+
+ //Strength skillcape perk
+ if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.FINE_ATTUNEMENT, entity) && ContentAPI.getItemFromEquipment(entity, EquipmentSlot.WEAPON)?.definition?.getRequirement(Skills.STRENGTH) != 0)
+ bonus = ceil(bonus * 1.20).toInt()
+
cumulativeStr *= getSetMultiplier(entity, Skills.STRENGTH)
+
+ if(entity is Player && entity.slayer.task?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true)
+ cumulativeStr *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer helm/black mask/skillcape
+
/*val hit = (16 + cumulativeStr + bonus / 8 + cumulativeStr * bonus * 0.016865) * modifier
return (hit / 10).toInt() + 1*/
return (1.3 + (cumulativeStr / 10) + (bonus / 80) + ((cumulativeStr * bonus) / 640)).toInt()
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/RangeSwingHandler.kt b/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/RangeSwingHandler.kt
index 4654597d9..7072bbec3 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/RangeSwingHandler.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/combat/handlers/RangeSwingHandler.kt
@@ -26,6 +26,7 @@ import core.game.world.map.RegionManager
import core.game.world.update.flag.context.Graphics
import core.tools.RandomFunction
import rs09.game.node.entity.combat.CombatSwingHandler
+import rs09.game.node.entity.skill.skillcapeperks.SkillcapePerks
import rs09.game.system.SystemLogger
import rs09.game.world.GameWorld
import java.util.*
@@ -247,6 +248,8 @@ open class RangeSwingHandler
if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveRangedLevel += 3
effectiveRangedLevel += 8
if(entity is Player && entity.isWearingVoid(false)) effectiveRangedLevel *= 1.1
+ if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.ACCURATE_MARKSMAN,entity)) effectiveRangedLevel *= 1.1
+
effectiveRangedLevel = floor(effectiveRangedLevel)
effectiveRangedLevel *= (entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64)
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaveParser.kt b/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaveParser.kt
index 8c4a1d4ed..98e3ecbfa 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaveParser.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaveParser.kt
@@ -8,6 +8,7 @@ import core.game.node.entity.player.link.SpellBookManager
import core.game.node.entity.player.link.emote.Emotes
import core.game.node.entity.player.link.grave.GraveType
import core.game.node.entity.player.link.music.MusicEntry
+import core.game.node.entity.skill.slayer.SlayerEquipmentFlags
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.json.simple.JSONArray
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaver.kt b/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaver.kt
index 92dc0c733..2c8d65e41 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaver.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/player/info/login/PlayerSaver.kt
@@ -700,20 +700,6 @@ class PlayerSaver (val player: Player){
fun saveSlayer(root: JSONObject){
val slayer = JSONObject()
val slayerManager = player.slayer
- if(slayerManager.hasStarted()){
- slayer.put("master",slayerManager.master.npc.toString())
- }
- if(slayerManager.hasTask()){
- slayer.put("taskId",slayerManager.task.ordinal.toString())
- slayer.put("taskAmount",slayerManager.amount.toString())
- }
- slayer.put("points",slayerManager.slayerPoints.toString())
- slayer.put("taskStreak",slayerManager.taskCount.toString())
- val learnedRewards = JSONArray()
- slayerManager.learned.map {
- learnedRewards.add(it)
- }
- slayer.put("learned_rewards",learnedRewards)
if(slayerManager.removed.isNotEmpty()) {
val removedTasks = JSONArray()
slayerManager.removed.map {
@@ -721,8 +707,11 @@ class PlayerSaver (val player: Player){
}
slayer.put("removedTasks",removedTasks)
}
+ slayer.put("taskStreak",slayerManager.taskCount.toString())
slayer.put("totalTasks",slayerManager.totalTasks.toString())
- slayer.put("canEarnPoints",slayerManager.isCanEarnPoints)
+ slayer.put("equipmentFlags",slayerManager.flags.equipmentFlags)
+ slayer.put("taskFlags", slayerManager.flags.taskFlags)
+ slayer.put("rewardFlags", slayerManager.flags.rewardFlags)
root.put("slayer",slayer)
}
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CropHarvester.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CropHarvester.kt
index 892394d6b..c887ed0f6 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CropHarvester.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/CropHarvester.kt
@@ -16,6 +16,8 @@ import org.rs09.consts.Items
@Initializable
class CropHarvester : OptionHandler() {
+ val livesBased = arrayOf(PatchType.HERB, PatchType.CACTUS, PatchType.BELLADONNA, PatchType.HOPS, PatchType.ALLOTMENT,PatchType.EVIL_TURNIP)
+
val spadeAnim = Animation(830)
override fun newInstance(arg: Any?): Plugin {
@@ -67,8 +69,18 @@ class CropHarvester : OptionHandler() {
delay = 2
player.inventory.add(Item(plantable.harvestItem,1))
player.skills.addExperience(Skills.FARMING,plantable.harvestXP)
- patch.rollLivesDecrement(ContentAPI.getDynLevel(player, Skills.FARMING), requiredItem == Items.MAGIC_SECATEURS_7409)
- return patch.cropLives <= 0
+ if(patch.patch.type in livesBased){
+ patch.rollLivesDecrement(
+ ContentAPI.getDynLevel(player, Skills.FARMING),
+ requiredItem == Items.MAGIC_SECATEURS_7409
+ )
+ } else {
+ patch.harvestAmt--
+ if(patch.harvestAmt <= 0){
+ patch.clear()
+ }
+ }
+ return patch.cropLives <= 0 || patch.harvestAmt <= 0
}
})
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/Patch.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/Patch.kt
index e178d8ae8..070e38617 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/Patch.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/farming/Patch.kt
@@ -16,6 +16,10 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
var cropLives = 3
fun setNewHarvestAmount() {
+ harvestAmt = when (plantable) {
+ Plantable.LIMPWURT_SEED, Plantable.WOAD_SEED -> 3
+ else -> 1
+ }
cropLives = 3
}
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/skillcapeperks/SkillcapePerks.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/skillcapeperks/SkillcapePerks.kt
index 12c75b817..79802c385 100644
--- a/Server/src/main/kotlin/rs09/game/node/entity/skill/skillcapeperks/SkillcapePerks.kt
+++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/skillcapeperks/SkillcapePerks.kt
@@ -63,6 +63,14 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)?
player.dialogueInterpreter.sendDialogue("Your cape is still on cooldown.","Ready in " + java.util.concurrent.TimeUnit.MILLISECONDS.toMinutes(time - System.currentTimeMillis()) + " minutes.")
}
}),
+ TRICKS_OF_THE_TRADE("cape_perks:tott",{player ->
+ val hasHelmetBonus = api.ContentAPI.getAttribute(player, "cape_perks:tott:helmet-stored", false)
+ if(hasHelmetBonus){
+ api.ContentAPI.sendDialogue(player, "Your cape's pockets are lined with all the utilities you need for slayer.")
+ } else {
+ api.ContentAPI.sendDialogue(player, "Your cape is lined with empty pockets shaped like various utilities needed for slayer.")
+ }
+ }),
NONE("cape_perks:none")
;
@@ -87,7 +95,7 @@ enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)?
Skillcape.THIEVING -> NONE
Skillcape.CRAFTING -> NONE
Skillcape.FLETCHING -> NONE
- Skillcape.SLAYER -> NONE
+ Skillcape.SLAYER -> TRICKS_OF_THE_TRADE
Skillcape.CONSTRUCTION -> NONE
Skillcape.MINING -> PRECISION_MINER
Skillcape.SMITHING -> BAREFISTED_SMITHING
diff --git a/Server/src/main/kotlin/rs09/game/node/entity/skill/slayer/SlayerFlags.kt b/Server/src/main/kotlin/rs09/game/node/entity/skill/slayer/SlayerFlags.kt
new file mode 100644
index 000000000..5619c87c7
--- /dev/null
+++ b/Server/src/main/kotlin/rs09/game/node/entity/skill/slayer/SlayerFlags.kt
@@ -0,0 +1,152 @@
+package rs09.game.node.entity.skill.slayer
+
+import core.game.node.entity.player.Player
+import core.game.node.entity.skill.slayer.Master
+import core.game.node.entity.skill.slayer.Tasks
+
+/**
+ * Bitflag-based system for storing slayer-related data for a player and various helper functions.
+ * @author Ceikry
+ */
+class SlayerFlags(val player: Player) {
+ var taskFlags = 0
+ var rewardFlags = 0
+ var equipmentFlags = 0
+ var completedTasks = 0
+ var taskStreak = 0
+
+ /**
+ * The removed tasks.
+ */
+ val removed: List = ArrayList(4)
+
+ /**
+ * Get/set master flags
+ */
+ fun getMaster(): Master {
+ val ordinal = taskFlags and 0xF
+ return Master.values()[ordinal]
+ }
+
+ fun setMaster(master: Master){
+ taskFlags = (taskFlags - (taskFlags and 0xF)) or master.ordinal
+ }
+
+ /**
+ *==============================================
+ */
+
+
+ /**
+ * Get/set task flags
+ */
+ fun getTask(): Tasks {
+ val ordinal = (taskFlags shr 4) and 0x7F
+ return Tasks.values()[ordinal]
+ }
+
+ fun setTask(tasks: Tasks){
+ taskFlags = (taskFlags - (getTask().ordinal shl 4)) or (tasks.ordinal shl 4)
+ }
+
+ /**
+ *==============================================
+ */
+
+ /**
+ * Get/set/decrement task amount flag
+ */
+ fun getTaskAmount(): Int {
+ return (taskFlags shr 11) and 0xFF
+ }
+
+ fun setTaskAmount(amount: Int) {
+ taskFlags = (taskFlags - (getTaskAmount() shl 11)) or (amount shl 11)
+ }
+
+ fun decrementTaskAmount(amount: Int){
+ setTaskAmount(getTaskAmount() - amount)
+ }
+ /**
+ *==============================================
+ */
+
+ /**
+ * Get/Set canEarnPoints flag
+ */
+ fun canEarnPoints(): Boolean {
+ return (taskFlags shr 16) and 1 == 1
+ }
+
+ fun flagCanEarnPoints() {
+ taskFlags = taskFlags or (1 shl 16)
+ }
+ /**
+ *==============================================
+ */
+
+ /**
+ * Get/set reward unlock flags
+ */
+ fun isBroadsUnlocked(): Boolean{
+ return rewardFlags and 1 == 1
+ }
+
+ fun unlockBroads() {
+ rewardFlags = rewardFlags or 1
+ }
+
+ fun isRingUnlocked(): Boolean {
+ return (rewardFlags shr 1) and 1 == 1
+ }
+
+ fun unlockRing() {
+ rewardFlags = rewardFlags or (1 shl 1)
+ }
+
+ fun isHelmUnlocked(): Boolean {
+ return (rewardFlags shr 2) and 1 ==1
+ }
+
+ fun unlockHelm() {
+ rewardFlags = rewardFlags or (1 shl 2)
+ }
+
+ /**
+ *==============================================
+ */
+
+ /**
+ * Get/set/increment points flag
+ */
+ fun setPoints(amount: Int) {
+ rewardFlags = (rewardFlags - (getPoints() shl 15)) or (amount shl 15)
+ }
+
+ fun getPoints(): Int {
+ return (rewardFlags shr 15) and 0xFFFF
+ }
+
+ fun incrementPoints(amount: Int){
+ setPoints(getPoints() + amount)
+ }
+ /**
+ *==============================================
+ */
+
+ /**
+ * Reset task and task amount to 0
+ */
+ fun clearTask() {
+ setTask(Tasks.values()[0])
+ setTaskAmount(0)
+ }
+
+ /**
+ * Checks if we have a task
+ */
+ fun hasTask(): Boolean{
+ return getTaskAmount() != 0
+ }
+
+}
\ No newline at end of file