Merge 2009scape updates #19

Open
randy wants to merge 204 commits from 2009Scape:master into upstream
719 changed files with 33223 additions and 27176 deletions

30
.dockerignore Normal file
View file

@ -0,0 +1,30 @@
# Local volumes
/config
/data
/db
# Updated through volumes
Server/data
Server/worldprops
# Env files containing secrets
/.env
/*.env
# Log files
logs
*.log
# Git files
.git
.gitattributes
.gitignore
# Basic stuff
*.md
LICENSE
.gitlab-ci.yml
# Docker files
docker-compose.yml
Dockerfile

12
.gitignore vendored
View file

@ -18,7 +18,8 @@ Server/data/global_kill_stats.json
Server/ge_test.db Server/ge_test.db
Server/latestdump.txt Server/latestdump.txt
Management-Server/managementprops/ Management-Server/managementprops/
Server/worldprops/ Server/worldprops/*
!Server/worldprops/default.conf
**/.idea/workspace.xml **/.idea/workspace.xml
**/.idea/tasks.xml **/.idea/tasks.xml
@ -32,3 +33,12 @@ gradle
build/kotlin/sessions/ build/kotlin/sessions/
**/*.iml **/*.iml
Server/hasRan.txt Server/hasRan.txt
# Local volumes
/config
/data
/db
# Env files containing secrets
/.env
/*.env

0
.gitlab/.gitkeep Normal file
View file

View file

View file

@ -0,0 +1,17 @@
What I did:
What I expected to happen:
What actually happened:
IDs of related NPCs/items:
2009-era source (if relevant):
Screenshots or video:
LIVE SERVER username affected by this issue:
**Bug reports are not accepted by SP users. SP is often out of date and results in invalid bug reports.**
**If the bug is exploitable make sure you tick the confidential checkbox below**

View file

@ -4,14 +4,8 @@ FROM maven:3-openjdk-11-slim
# Set working directory to /app # Set working directory to /app
WORKDIR /app WORKDIR /app
# Update apt; install git and git-lfs # Copy all sources etc
RUN apt-get update && apt-get -qq -y install git git-lfs COPY . .
# Clone the 2009scape repository
RUN git clone --depth=1 https://gitlab.com/2009scape/2009scape.git
# Fake it til you make it - let's go home
WORKDIR /app/2009scape
# Make sure ./run has permissions # Make sure ./run has permissions
RUN chmod +x run RUN chmod +x run

View file

@ -125,6 +125,78 @@ Start the game server with the included run script. Use `./run -h` for more info
Start the game server with `run-server.bat` Start the game server with `run-server.bat`
#### Docker
Make sure [Docker Engine](https://docs.docker.com/engine/install/) & [Docker Compose](https://docs.docker.com/compose/install/) plugin are installed first:
Go to the project root where the git repository is cloned into:
```bash
cd /path/to/project-dir
```
To configure the database, copy the mysql env file template to a env file in the project root:
```bash
cp mysql.env.example mysql.env
```
Customize the env file however necessary.
Create a new directory called 'config' into the project root.
```bash
mkdir config
```
Copy the server config file template in the config directory:
```bash
cp Server/worldprops/default.conf config/default.conf
```
Edit the server configuration file as per needed.
Go to the project root directory and execute:
```bash
docker compose up --build
```
Which will build the docker image using the local Dockerfile and starts the server and database containers.
The previous up command should be run every time the server sources are modified to propagate the changes to the container.
For the first time, the server compilation process takes a long time. Grab some coffee in the meanwhile.
You can check (and follow) the containers logs by running the following in the project root directory (-f for follow and Ctrl+C to stop):
```bash
docker compose logs -f
```
Any compilation or runtime errors will be logged here.
If you have already compiled the server and made no changes to the sources, you can simply run without the build option (however it will be cached anyways):
```bash
docker compose up
```
To later restart the server to apply simple configuration changes, in the project root directory run:
```bash
docker compose restart server
```
To shut down / take down the server, in the project root directory run:
```bash
docker compose up --build
```
The database files, build cache and config files will be persisted on the host filesystem for easy backup management.
### License ### License
We use the AGPL 3.0 license, which can be found [here](https://www.gnu.org/licenses/agpl-3.0.en.html). Please be sure to read and understand the license. Failure to follow the guidelines outlined in the license will result in legal action. If you know or hear of anyone breaking this license, please send a report, with proof, to Red Bracket#8151, ceikry#2724, or woahscam#8535 on discord or email woahscam@hotmail.com. **We WILL NOT change the license to fit your needs.** We use the AGPL 3.0 license, which can be found [here](https://www.gnu.org/licenses/agpl-3.0.en.html). Please be sure to read and understand the license. Failure to follow the guidelines outlined in the license will result in legal action. If you know or hear of anyone breaking this license, please send a report, with proof, to Red Bracket#8151, ceikry#2724, or woahscam#8535 on discord or email woahscam@hotmail.com. **We WILL NOT change the license to fit your needs.**

View file

@ -11,7 +11,6 @@
<ObjectAction mode="remove" id="356" x="2804" y="3428" z="0"/> <ObjectAction mode="remove" id="356" x="2804" y="3428" z="0"/>
<ObjectAction mode="add" id="356" x="2804" y="3428" z="0"/> <ObjectAction mode="add" id="356" x="2804" y="3428" z="0"/>
<ObjectAction mode="add" id="2783" x="3229" y="3254" z="0"/>
<ObjectAction mode="remove" id="20228" x="2537" y="3573" z="0"/> <ObjectAction mode="remove" id="20228" x="2537" y="3573" z="0"/>
<ObjectAction mode="add" id="27663" x="2537" y="3573" z="0" direction="w"/> <ObjectAction mode="add" id="27663" x="2537" y="3573" z="0" direction="w"/>

View file

@ -125,7 +125,7 @@
"start_graphic": "232,96", "start_graphic": "232,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "226,40,36,32,32,15,0", "projectile": "226,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "813", "itemId": "813",
@ -133,7 +133,7 @@
"start_graphic": "233,96", "start_graphic": "233,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "227,40,36,32,32,15,0", "projectile": "227,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "814", "itemId": "814",
@ -141,7 +141,7 @@
"start_graphic": "234,96", "start_graphic": "234,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "228,40,36,32,32,15,0", "projectile": "228,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "815", "itemId": "815",
@ -149,7 +149,7 @@
"start_graphic": "235,96", "start_graphic": "235,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "229,40,36,32,32,15,0", "projectile": "229,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "816", "itemId": "816",
@ -157,7 +157,7 @@
"start_graphic": "236,96", "start_graphic": "236,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "230,40,36,32,32,15,0", "projectile": "230,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "817", "itemId": "817",
@ -165,7 +165,7 @@
"start_graphic": "237,96", "start_graphic": "237,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "231,40,36,32,32,15,0", "projectile": "231,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "825", "itemId": "825",
@ -221,7 +221,7 @@
"start_graphic": "206,96", "start_graphic": "206,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "200,40,36,32,32,15,0", "projectile": "200,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "832", "itemId": "832",
@ -229,7 +229,7 @@
"start_graphic": "207,96", "start_graphic": "207,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "201,40,36,32,32,15,0", "projectile": "201,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "833", "itemId": "833",
@ -237,7 +237,7 @@
"start_graphic": "208,96", "start_graphic": "208,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "202,40,36,32,32,15,0", "projectile": "202,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "834", "itemId": "834",
@ -245,7 +245,7 @@
"start_graphic": "209,96", "start_graphic": "209,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "203,40,36,32,32,15,0", "projectile": "203,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "835", "itemId": "835",
@ -253,7 +253,7 @@
"start_graphic": "210,96", "start_graphic": "210,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "204,40,36,32,32,15,0", "projectile": "204,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "836", "itemId": "836",
@ -261,7 +261,7 @@
"start_graphic": "211,96", "start_graphic": "211,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "205,40,36,32,32,15,0", "projectile": "205,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "863", "itemId": "863",
@ -325,7 +325,7 @@
"start_graphic": "219,96", "start_graphic": "219,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "212,40,36,32,32,15,0", "projectile": "212,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "871", "itemId": "871",
@ -333,7 +333,7 @@
"start_graphic": "220,96", "start_graphic": "220,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "213,40,36,32,32,15,0", "projectile": "213,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "872", "itemId": "872",
@ -341,7 +341,7 @@
"start_graphic": "221,96", "start_graphic": "221,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "214,40,36,32,32,15,0", "projectile": "214,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "873", "itemId": "873",
@ -349,7 +349,7 @@
"start_graphic": "223,96", "start_graphic": "223,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "216,40,36,32,32,15,0", "projectile": "216,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "874", "itemId": "874",
@ -357,7 +357,7 @@
"start_graphic": "222,96", "start_graphic": "222,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "215,40,36,32,32,15,0", "projectile": "215,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "875", "itemId": "875",
@ -365,7 +365,7 @@
"start_graphic": "224,96", "start_graphic": "224,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "217,40,36,32,32,15,0", "projectile": "217,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "876", "itemId": "876",
@ -373,7 +373,7 @@
"start_graphic": "225,96", "start_graphic": "225,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "218,40,36,32,32,15,0", "projectile": "218,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "877", "itemId": "877",
@ -389,7 +389,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "879", "itemId": "879",
@ -421,7 +421,7 @@
"start_graphic": "19,96", "start_graphic": "19,96",
"darkbow_graphic": "1104,96", "darkbow_graphic": "1104,96",
"projectile": "10,40,36,41,46,5,0", "projectile": "10,40,36,41,46,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "884", "itemId": "884",
@ -437,7 +437,7 @@
"start_graphic": "18,96", "start_graphic": "18,96",
"darkbow_graphic": "1105,96", "darkbow_graphic": "1105,96",
"projectile": "9,40,36,41,46,5,0", "projectile": "9,40,36,41,46,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "886", "itemId": "886",
@ -453,7 +453,7 @@
"start_graphic": "20,96", "start_graphic": "20,96",
"darkbow_graphic": "1106,96", "darkbow_graphic": "1106,96",
"projectile": "11,40,36,41,46,5,0", "projectile": "11,40,36,41,46,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "888", "itemId": "888",
@ -469,7 +469,7 @@
"start_graphic": "21,96", "start_graphic": "21,96",
"darkbow_graphic": "1107,96", "darkbow_graphic": "1107,96",
"projectile": "12,40,36,41,46,5,0", "projectile": "12,40,36,41,46,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "890", "itemId": "890",
@ -485,7 +485,7 @@
"start_graphic": "22,96", "start_graphic": "22,96",
"darkbow_graphic": "1108,96", "darkbow_graphic": "1108,96",
"projectile": "13,40,36,41,46,5,0", "projectile": "13,40,36,41,46,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "892", "itemId": "892",
@ -501,7 +501,7 @@
"start_graphic": "24,96", "start_graphic": "24,96",
"darkbow_graphic": "1109,96", "darkbow_graphic": "1109,96",
"projectile": "15,40,36,41,46,5,0", "projectile": "15,40,36,41,46,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "2532", "itemId": "2532",
@ -565,7 +565,7 @@
"start_graphic": "273,96", "start_graphic": "273,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "227,40,36,32,32,15,0", "projectile": "227,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "4160", "itemId": "4160",
@ -725,7 +725,7 @@
"start_graphic": "19,96", "start_graphic": "19,96",
"darkbow_graphic": "1104,96", "darkbow_graphic": "1104,96",
"projectile": "10,40,36,41,46,5,0", "projectile": "10,40,36,41,46,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5617", "itemId": "5617",
@ -733,7 +733,7 @@
"start_graphic": "18,96", "start_graphic": "18,96",
"darkbow_graphic": "1105,96", "darkbow_graphic": "1105,96",
"projectile": "9,40,36,41,46,5,0", "projectile": "9,40,36,41,46,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5618", "itemId": "5618",
@ -741,7 +741,7 @@
"start_graphic": "20,96", "start_graphic": "20,96",
"darkbow_graphic": "1106,96", "darkbow_graphic": "1106,96",
"projectile": "11,40,36,41,46,5,0", "projectile": "11,40,36,41,46,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5619", "itemId": "5619",
@ -749,7 +749,7 @@
"start_graphic": "21,96", "start_graphic": "21,96",
"darkbow_graphic": "1107,96", "darkbow_graphic": "1107,96",
"projectile": "12,40,36,41,46,5,0", "projectile": "12,40,36,41,46,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5620", "itemId": "5620",
@ -757,7 +757,7 @@
"start_graphic": "22,96", "start_graphic": "22,96",
"darkbow_graphic": "1108,96", "darkbow_graphic": "1108,96",
"projectile": "13,40,36,41,46,5,0", "projectile": "13,40,36,41,46,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5621", "itemId": "5621",
@ -773,7 +773,7 @@
"start_graphic": "19,96", "start_graphic": "19,96",
"darkbow_graphic": "1104,96", "darkbow_graphic": "1104,96",
"projectile": "10,40,36,41,46,5,0", "projectile": "10,40,36,41,46,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5623", "itemId": "5623",
@ -781,7 +781,7 @@
"start_graphic": "18,96", "start_graphic": "18,96",
"darkbow_graphic": "1105,96", "darkbow_graphic": "1105,96",
"projectile": "9,40,36,41,46,5,0", "projectile": "9,40,36,41,46,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5624", "itemId": "5624",
@ -789,7 +789,7 @@
"start_graphic": "20,96", "start_graphic": "20,96",
"darkbow_graphic": "1106,96", "darkbow_graphic": "1106,96",
"projectile": "11,40,36,41,46,5,0", "projectile": "11,40,36,41,46,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5625", "itemId": "5625",
@ -797,7 +797,7 @@
"start_graphic": "21,96", "start_graphic": "21,96",
"darkbow_graphic": "1107,96", "darkbow_graphic": "1107,96",
"projectile": "12,40,36,41,46,5,0", "projectile": "12,40,36,41,46,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5626", "itemId": "5626",
@ -805,7 +805,7 @@
"start_graphic": "22,96", "start_graphic": "22,96",
"darkbow_graphic": "1108,96", "darkbow_graphic": "1108,96",
"projectile": "13,40,36,41,46,5,0", "projectile": "13,40,36,41,46,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5627", "itemId": "5627",
@ -813,7 +813,7 @@
"start_graphic": "24,96", "start_graphic": "24,96",
"darkbow_graphic": "1109,96", "darkbow_graphic": "1109,96",
"projectile": "15,40,36,41,46,5,0", "projectile": "15,40,36,41,46,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5628", "itemId": "5628",
@ -821,7 +821,7 @@
"start_graphic": "232,96", "start_graphic": "232,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "226,40,36,32,32,15,0", "projectile": "226,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5629", "itemId": "5629",
@ -829,7 +829,7 @@
"start_graphic": "233,96", "start_graphic": "233,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "227,40,36,32,32,15,0", "projectile": "227,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5630", "itemId": "5630",
@ -837,7 +837,7 @@
"start_graphic": "235,96", "start_graphic": "235,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "229,40,36,32,32,15,0", "projectile": "229,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5631", "itemId": "5631",
@ -845,7 +845,7 @@
"start_graphic": "273,96", "start_graphic": "273,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "227,40,36,32,32,15,0", "projectile": "227,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5633", "itemId": "5633",
@ -853,7 +853,7 @@
"start_graphic": "236,96", "start_graphic": "236,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "230,40,36,32,32,15,0", "projectile": "230,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5634", "itemId": "5634",
@ -861,7 +861,7 @@
"start_graphic": "237,96", "start_graphic": "237,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "231,40,36,32,32,15,0", "projectile": "231,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5635", "itemId": "5635",
@ -869,7 +869,7 @@
"start_graphic": "232,96", "start_graphic": "232,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "226,40,36,32,32,15,0", "projectile": "226,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5636", "itemId": "5636",
@ -877,7 +877,7 @@
"start_graphic": "233,96", "start_graphic": "233,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "227,40,36,32,32,15,0", "projectile": "227,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5637", "itemId": "5637",
@ -885,7 +885,7 @@
"start_graphic": "234,96", "start_graphic": "234,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "228,40,36,32,32,15,0", "projectile": "228,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5638", "itemId": "5638",
@ -893,7 +893,7 @@
"start_graphic": "273,96", "start_graphic": "273,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "227,40,36,32,32,15,0", "projectile": "227,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5639", "itemId": "5639",
@ -901,7 +901,7 @@
"start_graphic": "235,96", "start_graphic": "235,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "229,40,36,32,32,15,0", "projectile": "229,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5640", "itemId": "5640",
@ -909,7 +909,7 @@
"start_graphic": "236,96", "start_graphic": "236,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "230,40,36,32,32,15,0", "projectile": "230,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5641", "itemId": "5641",
@ -917,7 +917,7 @@
"start_graphic": "237,96", "start_graphic": "237,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "231,40,36,32,32,15,0", "projectile": "231,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5642", "itemId": "5642",
@ -925,7 +925,7 @@
"start_graphic": "206,96", "start_graphic": "206,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "200,40,36,32,32,15,0", "projectile": "200,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5643", "itemId": "5643",
@ -933,7 +933,7 @@
"start_graphic": "207,96", "start_graphic": "207,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "201,40,36,32,32,15,0", "projectile": "201,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5644", "itemId": "5644",
@ -941,7 +941,7 @@
"start_graphic": "208,96", "start_graphic": "208,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "202,40,36,32,32,15,0", "projectile": "202,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5645", "itemId": "5645",
@ -949,7 +949,7 @@
"start_graphic": "209,96", "start_graphic": "209,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "203,40,36,32,32,15,0", "projectile": "203,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5646", "itemId": "5646",
@ -957,7 +957,7 @@
"start_graphic": "210,96", "start_graphic": "210,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "204,40,36,32,32,15,0", "projectile": "204,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5647", "itemId": "5647",
@ -965,7 +965,7 @@
"start_graphic": "211,96", "start_graphic": "211,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "205,40,36,32,32,15,0", "projectile": "205,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5648", "itemId": "5648",
@ -973,7 +973,7 @@
"start_graphic": "206,96", "start_graphic": "206,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "200,40,36,32,32,15,0", "projectile": "200,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5649", "itemId": "5649",
@ -981,7 +981,7 @@
"start_graphic": "207,96", "start_graphic": "207,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "201,40,36,32,32,15,0", "projectile": "201,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5650", "itemId": "5650",
@ -989,7 +989,7 @@
"start_graphic": "208,96", "start_graphic": "208,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "202,40,36,32,32,15,0", "projectile": "202,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5651", "itemId": "5651",
@ -997,7 +997,7 @@
"start_graphic": "209,96", "start_graphic": "209,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "203,40,36,32,32,15,0", "projectile": "203,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5652", "itemId": "5652",
@ -1005,7 +1005,7 @@
"start_graphic": "210,96", "start_graphic": "210,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "204,40,36,32,32,15,0", "projectile": "204,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5653", "itemId": "5653",
@ -1013,7 +1013,7 @@
"start_graphic": "211,96", "start_graphic": "211,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "205,40,36,32,32,15,0", "projectile": "205,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5654", "itemId": "5654",
@ -1021,7 +1021,7 @@
"start_graphic": "219,96", "start_graphic": "219,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "212,40,36,32,32,15,0", "projectile": "212,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5655", "itemId": "5655",
@ -1029,7 +1029,7 @@
"start_graphic": "220,96", "start_graphic": "220,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "213,40,36,32,32,15,0", "projectile": "213,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5656", "itemId": "5656",
@ -1037,7 +1037,7 @@
"start_graphic": "221,96", "start_graphic": "221,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "214,40,36,32,32,15,0", "projectile": "214,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5657", "itemId": "5657",
@ -1045,7 +1045,7 @@
"start_graphic": "223,96", "start_graphic": "223,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "216,40,36,32,32,15,0", "projectile": "216,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5658", "itemId": "5658",
@ -1053,7 +1053,7 @@
"start_graphic": "222,96", "start_graphic": "222,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "215,40,36,32,32,15,0", "projectile": "215,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5659", "itemId": "5659",
@ -1061,7 +1061,7 @@
"start_graphic": "224,96", "start_graphic": "224,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "217,40,36,32,32,15,0", "projectile": "217,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5660", "itemId": "5660",
@ -1069,7 +1069,7 @@
"start_graphic": "225,96", "start_graphic": "225,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "218,40,36,32,32,15,0", "projectile": "218,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "5661", "itemId": "5661",
@ -1077,7 +1077,7 @@
"start_graphic": "219,96", "start_graphic": "219,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "212,40,36,32,32,15,0", "projectile": "212,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5662", "itemId": "5662",
@ -1085,7 +1085,7 @@
"start_graphic": "220,96", "start_graphic": "220,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "213,40,36,32,32,15,0", "projectile": "213,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5663", "itemId": "5663",
@ -1093,7 +1093,7 @@
"start_graphic": "221,96", "start_graphic": "221,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "214,40,36,32,32,15,0", "projectile": "214,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5664", "itemId": "5664",
@ -1101,7 +1101,7 @@
"start_graphic": "223,96", "start_graphic": "223,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "216,40,36,32,32,15,0", "projectile": "216,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5665", "itemId": "5665",
@ -1109,7 +1109,7 @@
"start_graphic": "222,96", "start_graphic": "222,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "215,40,36,32,32,15,0", "projectile": "215,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5666", "itemId": "5666",
@ -1117,7 +1117,7 @@
"start_graphic": "224,96", "start_graphic": "224,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "217,40,36,32,32,15,0", "projectile": "217,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "5667", "itemId": "5667",
@ -1125,7 +1125,7 @@
"start_graphic": "225,96", "start_graphic": "225,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "218,40,36,32,32,15,0", "projectile": "218,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "6061", "itemId": "6061",
@ -1133,7 +1133,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "6062", "itemId": "6062",
@ -1141,7 +1141,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "6522", "itemId": "6522",
@ -1293,7 +1293,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "9287", "itemId": "9287",
@ -1301,7 +1301,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "9288", "itemId": "9288",
@ -1309,7 +1309,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "9289", "itemId": "9289",
@ -1317,7 +1317,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "9290", "itemId": "9290",
@ -1325,7 +1325,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "9291", "itemId": "9291",
@ -1333,7 +1333,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "9293", "itemId": "9293",
@ -1341,7 +1341,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "9294", "itemId": "9294",
@ -1349,7 +1349,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "9295", "itemId": "9295",
@ -1357,7 +1357,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "9296", "itemId": "9296",
@ -1365,7 +1365,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "9297", "itemId": "9297",
@ -1373,7 +1373,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "9298", "itemId": "9298",
@ -1381,7 +1381,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "9300", "itemId": "9300",
@ -1389,7 +1389,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "9301", "itemId": "9301",
@ -1397,7 +1397,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "9302", "itemId": "9302",
@ -1405,7 +1405,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "9303", "itemId": "9303",
@ -1413,7 +1413,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "9304", "itemId": "9304",
@ -1421,7 +1421,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "9305", "itemId": "9305",
@ -1429,7 +1429,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "9335", "itemId": "9335",
@ -1557,7 +1557,7 @@
"start_graphic": "1116,96", "start_graphic": "1116,96",
"darkbow_graphic": "1114,96", "darkbow_graphic": "1114,96",
"projectile": "1120,40,36,41,46,5,0", "projectile": "1120,40,36,41,46,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "11228", "itemId": "11228",
@ -1565,7 +1565,7 @@
"start_graphic": "1116,96", "start_graphic": "1116,96",
"darkbow_graphic": "1114,96", "darkbow_graphic": "1114,96",
"projectile": "1120,40,36,41,46,5,0", "projectile": "1120,40,36,41,46,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "11229", "itemId": "11229",
@ -1573,7 +1573,7 @@
"start_graphic": "1116,96", "start_graphic": "1116,96",
"darkbow_graphic": "1114,96", "darkbow_graphic": "1114,96",
"projectile": "1120,40,36,41,46,5,0", "projectile": "1120,40,36,41,46,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "11230", "itemId": "11230",
@ -1589,7 +1589,7 @@
"start_graphic": "1123,96", "start_graphic": "1123,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1122,40,36,32,32,15,0", "projectile": "1122,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "11233", "itemId": "11233",
@ -1597,7 +1597,7 @@
"start_graphic": "1123,96", "start_graphic": "1123,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1122,40,36,32,32,15,0", "projectile": "1122,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "11234", "itemId": "11234",
@ -1605,7 +1605,7 @@
"start_graphic": "1123,96", "start_graphic": "1123,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1122,40,36,32,32,15,0", "projectile": "1122,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "13083", "itemId": "13083",
@ -1621,7 +1621,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "13085", "itemId": "13085",
@ -1629,7 +1629,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "13086", "itemId": "13086",
@ -1637,7 +1637,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "27,38,36,41,32,5,0", "projectile": "27,38,36,41,32,5,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "13280", "itemId": "13280",
@ -1661,7 +1661,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1837,40,36,32,32,15,0", "projectile": "1837,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "13881", "itemId": "13881",
@ -1669,7 +1669,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1837,40,36,32,32,15,0", "projectile": "1837,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "13882", "itemId": "13882",
@ -1677,7 +1677,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1837,40,36,32,32,15,0", "projectile": "1837,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "13883", "itemId": "13883",
@ -1701,7 +1701,7 @@
"start_graphic": "-1,0", "start_graphic": "-1,0",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1837,40,36,32,32,15,0", "projectile": "1837,40,36,32,32,15,0",
"poison_damage": "28" "poison_damage": "10"
}, },
{ {
"itemId": "13955", "itemId": "13955",
@ -1709,7 +1709,7 @@
"start_graphic": "1837,96", "start_graphic": "1837,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1840,40,36,32,32,15,0", "projectile": "1840,40,36,32,32,15,0",
"poison_damage": "38" "poison_damage": "15"
}, },
{ {
"itemId": "13956", "itemId": "13956",
@ -1717,7 +1717,7 @@
"start_graphic": "1837,96", "start_graphic": "1837,96",
"darkbow_graphic": "", "darkbow_graphic": "",
"projectile": "1840,40,36,32,32,15,0", "projectile": "1840,40,36,32,32,15,0",
"poison_damage": "48" "poison_damage": "20"
}, },
{ {
"itemId": "13957", "itemId": "13957",

View file

@ -343,7 +343,7 @@
}, },
{ {
"id": "2054", "id": "2054",
"replaceId": "24375", "replaceId": "2055",
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
}, },
@ -419,18 +419,6 @@
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
}, },
{
"id": "2391",
"replaceId": "1561",
"fence": "false",
"metal": "true"
},
{
"id": "2392",
"replaceId": "1561",
"fence": "false",
"metal": "true"
},
{ {
"id": "2397", "id": "2397",
"replaceId": "24383", "replaceId": "24383",
@ -1439,6 +1427,12 @@
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
}, },
{
"id": "11470",
"replaceId": "11471",
"fence": "false",
"metal": "false"
},
{ {
"id": "11483", "id": "11483",
"replaceId": "11708", "replaceId": "11708",
@ -2163,7 +2157,7 @@
}, },
{ {
"id": "24376", "id": "24376",
"replaceId": "24377", "replaceId": "24375",
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
}, },

View file

@ -8021,16 +8021,9 @@
} }
], ],
"charm": [], "charm": [],
"ids": "128,1479,1875,4343", "ids": "128,1479,1875",
"description": "", "description": "",
"main": [ "main": []
{
"minAmount": "1",
"weight": "25.0",
"id": "7862",
"maxAmount": "1"
}
]
}, },
{ {
"default": [ "default": [
@ -31660,7 +31653,7 @@
{ {
"minAmount": "1", "minAmount": "1",
"weight": "100.0", "weight": "100.0",
"id": "532", "id": "526",
"maxAmount": "1" "maxAmount": "1"
} }
], ],
@ -31696,26 +31689,6 @@
"maxAmount": "1" "maxAmount": "1"
} }
], ],
"tertiary": [
{
"minAmount": "1",
"weight": "9973.0",
"id": "0",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "10976",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "2.0",
"id": "10977",
"maxAmount": "1"
}
],
"ids": "2783", "ids": "2783",
"description": "", "description": "",
"main": [ "main": [
@ -36478,12 +36451,6 @@
"weight": "100.0", "weight": "100.0",
"id": "532", "id": "532",
"maxAmount": "1" "maxAmount": "1"
},
{
"minAmount": "3",
"weight": "100.0",
"id": "526",
"maxAmount": "3"
} }
], ],
"charm": [], "charm": [],
@ -58799,5 +58766,25 @@
"ids": "8127", "ids": "8127",
"description": "Dark energy core", "description": "Dark energy core",
"main": [] "main": []
},
{
"default": [
{
"minAmount": "1",
"weight": "1.0",
"id": "6287",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "1.0",
"id": "526",
"maxAmount": "1"
}
],
"charm": [],
"ids": "4343",
"description": "",
"main": []
} }
] ]

View file

@ -141,7 +141,7 @@
}, },
{ {
"item_id": "401", "item_id": "401",
"loc_data": "{1,2959,2959,0,160}-{1,2943,2950,0,160}-{1,2866,2976,0,160}-{1,2854,2977,0,160}-{1,2839,2975,0,160}-{1,2757,2947,0,160}-{1,2755,2952,0,160}-{1,2786,2960,0,160}-{1,2782,2987,0,160}-{1,2771,2995,0,160}-{1,2761,3000,0,160}-{1,3829,3053,0,160}-{1,3813,3066,0,160}-{1,3814,3064,0,160}-{1,3808,3060,0,160}-{1,2945,3068,0,160}-{1,2975,3013,0,160}-{1,2955,3010,0,160}-{1,2755,3008,0,160}-{1,2754,3017,0,160}-{1,2756,3060,0,160}-{1,2755,3070,0,160}-{1,2896,3119,0,160}-{1,2914,3111,0,160}-{1,2926,3110,0,160}-{1,2939,3102,0,160}-{1,2938,3073,0,160}-{1,2756,3074,0,160}-{1,2806,3128,0,160}-{1,2764,3131,0,160}-{1,2753,3125,0,160}-{1,2757,3109,0,160}-{1,2864,3195,0,160}-{1,2810,3387,0,160}-{1,2809,3388,0,160}-{1,2809,3385,0,160}-{1,2807,3386,0,160}-{1,2804,3385,0,160}-{1,2807,3384,0,160}-{1,2805,3384,0,160}-{1,2802,3382,0,160}-{1,2805,3381,0,160}-{1,2804,3380,0,160}-{1,2693,3727,0,160}-{1,2698,3729,0,160}-{1,2700,3731,0,160}-{1,2708,3728,0,160}-{1,2725,3731,0,160}-{1,2721,3730,0,160}-{1,2719,3733,0,160}-{1,2714,3733,0,160}-{1,2712,3732,0,160}-" "loc_data": "{1,2959,2959,0,160}-{1,2866,2976,0,160}-{1,2854,2977,0,160}-{1,2839,2975,0,160}-{1,2943,2950,0,160}-{1,2757,2947,0,160}-{1,2755,2952,0,160}-{1,2786,2960,0,160}-{1,2782,2987,0,160}-{1,2771,2995,0,160}-{1,2761,3000,0,160}-{1,2945,3068,0,160}-{1,2975,3013,0,160}-{1,2955,3010,0,160}-{1,3829,3053,0,160}-{1,3813,3066,0,160}-{1,3814,3064,0,160}-{1,3808,3060,0,160}-{1,2755,3008,0,160}-{1,2754,3017,0,160}-{1,2756,3060,0,160}-{1,2755,3070,0,160}-{1,2896,3119,0,160}-{1,2914,3111,0,160}-{1,2926,3110,0,160}-{1,2939,3102,0,160}-{1,2938,3073,0,160}-{1,2756,3074,0,160}-{1,2806,3128,0,160}-{1,2764,3131,0,160}-{1,2753,3125,0,160}-{1,2757,3109,0,160}-{1,2864,3195,0,160}-{1,2810,3387,0,160}-{1,2809,3388,0,160}-{1,2809,3385,0,160}-{1,2807,3386,0,160}-{1,2804,3385,0,160}-{1,2807,3384,0,160}-{1,2805,3384,0,160}-{1,2802,3382,0,160}-{1,2805,3381,0,160}-{1,2804,3380,0,160}-{1,2693,3727,0,160}-{1,2698,3729,0,160}-{1,2700,3731,0,160}-{1,2708,3728,0,160}-{1,2725,3731,0,160}-{1,2721,3730,0,160}-{1,2719,3733,0,160}-{1,2714,3733,0,160}-{1,2712,3732,0,160}-"
}, },
{ {
"item_id": "444", "item_id": "444",
@ -207,6 +207,10 @@
"item_id": "590", "item_id": "590",
"loc_data": "{1,2368,3135,0,140}-{1,2431,3072,0,140}-{1,3112,3369,2,140}-{1,3209,3734,0,100}-" "loc_data": "{1,2368,3135,0,140}-{1,2431,3072,0,140}-{1,3112,3369,2,140}-{1,3209,3734,0,100}-"
}, },
{
"item_id": "600",
"loc_data": "{1,2438,3187,0,200}-"
},
{ {
"item_id": "677", "item_id": "677",
"loc_data": "{1,3369,3378,0,150}-" "loc_data": "{1,3369,3378,0,150}-"
@ -233,7 +237,7 @@
}, },
{ {
"item_id": "946", "item_id": "946",
"loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,3218,9887,0,33}-{1,2700,3407,0,100}-" "loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,2700,3407,0,100}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,2653,9767,0,30}-{1,3218,9887,0,33}-"
}, },
{ {
"item_id": "952", "item_id": "952",
@ -365,7 +369,7 @@
}, },
{ {
"item_id": "1573", "item_id": "1573",
"loc_data": "{1,2559,2975,0,10}-{1,2560,2974,0,10}-{1,2561,2973,0,10}-{1,2561,2976,0,10}-{1,2740,3637,0,30}-{1,2736,3638,0,30}-{1,2735,3636,0,30}-{1,2743,3636,0,30}-{1,2739,3634,0,30}-{1,2743,3640,0,30}-{1,2741,3639,0,30}-{1,2736,3641,0,30}-{1,2738,3641,0,30}-{1,2734,3640,0,30}-{1,2738,3636,0,30}-" "loc_data": "{1,2560,2974,0,10}-{1,2561,2973,0,10}-{1,2561,2976,0,10}-{1,2559,2975,0,10}-{1,2740,3637,0,30}-{1,2736,3638,0,30}-{1,2735,3636,0,30}-{1,2743,3636,0,30}-{1,2739,3634,0,30}-{1,2743,3640,0,30}-{1,2741,3639,0,30}-{1,2736,3641,0,30}-{1,2738,3641,0,30}-{1,2734,3640,0,30}-{1,2738,3636,0,30}-"
}, },
{ {
"item_id": "1590", "item_id": "1590",
@ -415,6 +419,14 @@
"item_id": "1785", "item_id": "1785",
"loc_data": "{1,2822,3355,0,150}-" "loc_data": "{1,2822,3355,0,150}-"
}, },
{
"item_id": "1812",
"loc_data": "{1,2747,3579,0,100}-"
},
{
"item_id": "1813",
"loc_data": "{1,2746,3578,0,100}-"
},
{ {
"item_id": "1856", "item_id": "1856",
"loc_data": "{1,2638,3292,0,150}-" "loc_data": "{1,2638,3292,0,150}-"
@ -457,7 +469,7 @@
}, },
{ {
"item_id": "1931", "item_id": "1931",
"loc_data": "{1,3209,3214,0,80}-{1,3166,3310,0,90}-{1,3144,3449,2,90}-" "loc_data": "{1,3209,3214,0,80}-{1,3166,3310,0,90}-{1,3144,3449,2,90}-{1,2918,10191,1,90}-"
}, },
{ {
"item_id": "1935", "item_id": "1935",
@ -465,7 +477,7 @@
}, },
{ {
"item_id": "1939", "item_id": "1939",
"loc_data": "{1,3193,3181,0,150}-{1,3194,3168,0,150}-{1,3191,3162,0,150}-{1,3189,3163,0,150}-{1,3185,3161,0,150}-{1,3182,3165,0,150}-{1,3172,3166,0,150}-{1,3170,3167,0,150}-{1,3164,3169,0,150}-{1,3171,3177,0,150}-{1,3173,3178,0,150}-{1,3164,3180,0,150}-{1,3165,3187,0,150}-{1,3171,3191,0,150}-{1,3178,3190,0,150}-{1,3181,3193,0,150}-{1,3182,3181,0,150}-{1,3493,3408,0,30}-{1,3494,3402,0,30}-{1,3494,3396,0,30}-{1,3499,3401,0,30}-" "loc_data": "{1,3193,3181,0,150}-{1,3194,3168,0,150}-{1,3191,3162,0,150}-{1,3189,3163,0,150}-{1,3185,3161,0,150}-{1,3182,3165,0,150}-{1,3172,3166,0,150}-{1,3170,3167,0,150}-{1,3164,3169,0,150}-{1,3171,3177,0,150}-{1,3173,3178,0,150}-{1,3164,3180,0,150}-{1,3165,3187,0,150}-{1,3171,3191,0,150}-{1,3178,3190,0,150}-{1,3181,3193,0,150}-{1,3182,3181,0,150}-{1,3428,3322,0,45}-{1,3436,3311,0,45}-{1,3437,3298,0,45}-{1,3428,3293,0,45}-{1,3422,3286,0,45}-{1,3451,3320,0,45}-{1,3434,3277,0,45}-{1,3446,3281,0,45}-{1,3447,3269,0,45}-{1,3450,3359,0,45}-{1,3451,3359,0,45}-{1,3452,3379,0,45}-{1,3452,3380,0,45}-{1,3438,3379,0,45}-{1,3440,3377,0,45}-{1,3414,3367,0,45}-{1,3409,3363,0,45}-{1,3452,3390,0,45}-{1,3452,3391,0,45}-{1,3466,3377,0,45}-{1,3460,3374,0,45}-{1,3459,3370,0,45}-{1,3469,3363,0,45}-{1,3476,3365,0,45}-{1,3460,3353,0,45}-{1,3462,3349,0,45}-{1,3472,3344,0,45}-{1,3493,3408,0,30}-{1,3494,3402,0,30}-{1,3494,3396,0,30}-{1,3499,3401,0,30}-{1,3464,3432,0,45}-{1,3469,3434,0,45}-{1,3473,3435,0,45}-{1,3471,3430,0,45}-{1,3478,3440,0,45}-{1,3477,3444,0,45}-{1,3472,3447,0,45}-{1,3458,3418,0,45}-{1,3460,3414,0,45}-{1,3467,3417,0,45}-{1,3472,3419,0,45}-{1,3474,3415,0,45}-{1,3480,3419,0,45}-{1,3481,3427,0,45}-{1,3460,3406,0,45}-{1,3471,3403,0,45}-{1,3428,3437,0,45}-{1,3434,3433,0,45}-{1,3435,3425,0,45}-{1,3441,3438,0,45}-{1,3445,3435,0,45}-{1,3449,3434,0,45}-{1,3448,3430,0,45}-{1,3454,3441,0,45}-{1,3441,3415,0,45}-{1,3442,3414,0,45}-{1,3436,3403,0,45}-{1,3432,3402,0,45}-{1,3450,3416,0,45}-{1,3445,3405,0,45}-{1,3453,3402,0,45}-"
}, },
{ {
"item_id": "1944", "item_id": "1944",
@ -597,7 +609,7 @@
}, },
{ {
"item_id": "3138", "item_id": "3138",
"loc_data": "{1,3463,9478,2,45}-{1,3461,9480,2,45}-{1,3461,9482,2,45}-{1,3461,9484,2,45}-" "loc_data": "{1,3461,9480,2,30}-{1,3460,9484,2,30}-{1,3465,9477,2,30}-{1,3467,9493,0,30}-{1,3486,9517,0,30}-{1,3474,9509,0,30}-{1,3470,9502,0,30}-{1,3480,9483,0,30}-"
}, },
{ {
"item_id": "3711", "item_id": "3711",
@ -663,6 +675,10 @@
"item_id": "11065", "item_id": "11065",
"loc_data": "{1,2928,3289,0,90}-" "loc_data": "{1,2928,3289,0,90}-"
}, },
{
"item_id": "11656",
"loc_data": "{1,2438,3185,0,200}-"
},
{ {
"item_id": "12494", "item_id": "12494",
"loc_data": "{1,2762,2973,0,60}-" "loc_data": "{1,2762,2973,0,60}-"

File diff suppressed because it is too large Load diff

View file

@ -887,6 +887,10 @@
"region": "10390", "region": "10390",
"id": "102" "id": "102"
}, },
{
"region": "10391",
"id": "478"
},
{ {
"region": "10393", "region": "10393",
"id": "346" "id": "346"
@ -1095,6 +1099,10 @@
"region": "10829", "region": "10829",
"id": "378" "id": "378"
}, },
{
"region": "10831",
"id": "393"
},
{ {
"region": "10833", "region": "10833",
"id": "249" "id": "249"

File diff suppressed because it is too large Load diff

View file

@ -133,7 +133,7 @@
}, },
{ {
"npc_id": "41", "npc_id": "41",
"loc_data": "{2851,3370,0,1,3}-{2846,3374,0,1,3}-{2853,3372,0,1,3}-{2847,3373,0,1,3}-{2850,3371,0,1,1}-{2851,3373,0,1,4}-{2852,3370,0,1,4}-{2819,3561,0,1,4}-{2818,3559,0,1,6}-{3110,9573,0,1,6}-{3140,3096,0,1,3}-{3140,3093,0,1,0}-{3138,3094,0,1,1}-{3140,3093,0,1,3}-{3138,3093,0,1,1}-{3138,3094,0,1,0}-{3140,3093,0,1,1}-{3187,3276,0,1,5}-{3188,3278,0,1,4}-{3197,3356,0,1,4}-{2655,3441,0,1,6}-{2649,3438,0,1,7}-{2649,3446,0,1,6}-{2653,3444,0,1,6}-{2647,3441,0,1,1}-{2674,3652,0,1,3}-{2672,3655,0,1,6}-{2677,3655,0,1,6}-{3234,3297,0,1,3}-{3230,3296,0,1,5}-{3236,3288,0,1,6}-{3236,3300,0,1,2}-{3234,3293,0,1,4}-{3229,3298,0,1,1}-{3228,3296,0,1,4}-{2694,3274,0,1,6}-{2695,3275,0,1,3}-{2965,3336,0,1,4}-{2784,3062,0,1,4}-{2789,3063,0,1,4}-{2815,3560,0,1,7}-" "loc_data": "{2851,3370,0,1,3}-{2846,3374,0,1,3}-{2853,3372,0,1,3}-{2847,3373,0,1,3}-{2850,3371,0,1,1}-{2851,3373,0,1,4}-{2852,3370,0,1,4}-{2819,3561,0,1,4}-{2818,3559,0,1,6}-{3110,9573,0,1,6}-{3140,3096,0,1,3}-{3140,3093,0,1,0}-{3138,3094,0,1,1}-{3140,3093,0,1,3}-{3138,3093,0,1,1}-{3138,3094,0,1,0}-{3140,3093,0,1,1}-{3187,3276,0,1,5}-{3188,3278,0,1,4}-{3197,3356,0,1,4}-{3197,3353,0,1,0}-{3196,3358,0,1,0}-{2655,3441,0,1,6}-{2649,3438,0,1,7}-{2649,3446,0,1,6}-{2653,3444,0,1,6}-{2647,3441,0,1,1}-{2674,3652,0,1,3}-{2672,3655,0,1,6}-{2677,3655,0,1,6}-{3234,3297,0,1,3}-{3230,3296,0,1,5}-{3236,3288,0,1,6}-{3236,3300,0,1,2}-{3234,3293,0,1,4}-{3229,3298,0,1,1}-{3228,3296,0,1,4}-{2694,3274,0,1,6}-{2695,3275,0,1,3}-{2965,3336,0,1,4}-{2784,3062,0,1,4}-{2789,3063,0,1,4}-{2815,3560,0,1,7}-"
}, },
{ {
"npc_id": "42", "npc_id": "42",
@ -157,7 +157,7 @@
}, },
{ {
"npc_id": "47", "npc_id": "47",
"loc_data": "{2821,3170,0,1,1}-{3341,3267,0,1,5}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2801,3158,0,1,2}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-" "loc_data": "{2821,3170,0,1,1}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3341,3267,0,1,5}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2339,9356,0,1,0}-{2354,9390,0,1,0}-{2361,9403,0,1,0}-{2362,9347,0,1,0}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2801,3158,0,1,2}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-"
}, },
{ {
"npc_id": "48", "npc_id": "48",
@ -193,7 +193,7 @@
}, },
{ {
"npc_id": "59", "npc_id": "59",
"loc_data": "{3082,3362,0,1,4}-{2602,9640,0,1,0}-{2603,9635,0,1,0}-{2603,9638,0,1,0}-{2605,9637,0,1,0}-{2605,9639,0,1,0}-{2606,9635,0,1,0}-{2606,9646,0,1,0}-{2607,9637,0,1,0}-{2607,9641,0,1,0}-{2607,9644,0,1,0}-{2607,9648,0,1,0}-{2608,9635,0,1,0}-{2608,9642,0,1,0}-{2609,9639,0,1,0}-{2609,9643,0,1,0}-{3102,9881,0,1,3}-{3095,9883,0,1,2}-{3182,3244,0,1,1}-{3162,3223,0,1,7}-{3164,3242,0,1,0}-{3169,3246,0,1,0}-{3170,3250,0,1,0}-{3166,3247,0,1,0}-{3164,3249,0,1,0}-{3157,3226,0,1,0}-{3163,3227,0,1,0}-{3165,3223,0,1,0}-{3194,3236,0,1,0}-{3146,3347,0,1,3}-{2648,9766,0,1,4}-{2653,9761,0,1,3}-{2483,2877,0,1,3}-{2481,2876,0,1,4}-{2457,2867,0,1,4}-{2481,2847,0,1,0}-{2475,2854,0,1,3}-{2482,2873,0,1,3}-{2485,2876,0,1,2}-{2449,2865,0,1,1}-{2461,2880,0,1,5}-{2489,2935,0,1,7}-{2492,2907,0,1,1}-{2487,2894,0,1,2}-{2487,2888,0,1,7}-{2478,2916,0,1,5}-{2485,2902,0,1,3}-{2487,2902,0,1,2}-{2489,2894,0,1,2}-{2490,2905,0,1,7}-{2490,2917,0,1,5}-{2484,2890,0,1,1}-{2491,2927,0,1,1}-{3250,3239,0,1,1}-{3241,3241,0,1,1}-{3249,3249,0,1,1}-{3218,9890,0,1,3}-{3220,9887,0,1,0}-{3218,9887,0,1,1}-{3218,9889,0,1,5}-{3213,9890,0,1,1}-{2496,2890,0,1,4}-{2503,2889,0,1,1}-{2497,2939,0,1,2}-{2369,3374,0,1,0}-{2372,3379,0,1,0}-{2378,3366,0,1,0}-{2379,3378,0,1,0}-{2387,3370,0,1,0}-{2394,3365,0,1,0}-{2402,3386,0,1,0}-{2405,3381,0,1,0}-{2407,3387,0,1,0}-{2412,3384,0,1,0}-" "loc_data": "{3082,3362,0,1,4}-{2602,9640,0,1,0}-{2603,9635,0,1,0}-{2603,9638,0,1,0}-{2605,9637,0,1,0}-{2605,9639,0,1,0}-{2606,9635,0,1,0}-{2606,9646,0,1,0}-{2607,9637,0,1,0}-{2607,9641,0,1,0}-{2607,9644,0,1,0}-{2607,9648,0,1,0}-{2608,9635,0,1,0}-{2608,9642,0,1,0}-{2609,9639,0,1,0}-{2609,9643,0,1,0}-{3102,9881,0,1,3}-{3095,9883,0,1,2}-{3182,3244,0,1,1}-{3162,3223,0,1,7}-{3164,3242,0,1,0}-{3169,3246,0,1,0}-{3170,3250,0,1,0}-{3166,3247,0,1,0}-{3164,3249,0,1,0}-{3157,3226,0,1,0}-{3163,3227,0,1,0}-{3165,3223,0,1,0}-{3194,3236,0,1,0}-{3146,3347,0,1,3}-{2369,3374,0,1,0}-{2372,3379,0,1,0}-{2378,3366,0,1,0}-{2379,3378,0,1,0}-{2387,3370,0,1,0}-{2394,3365,0,1,0}-{2402,3386,0,1,0}-{2405,3381,0,1,0}-{2407,3387,0,1,0}-{2412,3384,0,1,0}-{2648,9766,0,1,4}-{2653,9761,0,1,3}-{2483,2877,0,1,3}-{2481,2876,0,1,4}-{2457,2867,0,1,4}-{2481,2847,0,1,0}-{2475,2854,0,1,3}-{2482,2873,0,1,3}-{2485,2876,0,1,2}-{2449,2865,0,1,1}-{2461,2880,0,1,5}-{2489,2935,0,1,7}-{2492,2907,0,1,1}-{2487,2894,0,1,2}-{2487,2888,0,1,7}-{2478,2916,0,1,5}-{2485,2902,0,1,3}-{2487,2902,0,1,2}-{2489,2894,0,1,2}-{2490,2905,0,1,7}-{2490,2917,0,1,5}-{2484,2890,0,1,1}-{2491,2927,0,1,1}-{3250,3239,0,1,1}-{3241,3241,0,1,1}-{3249,3249,0,1,1}-{3218,9890,0,1,3}-{3220,9887,0,1,0}-{3218,9887,0,1,1}-{3218,9889,0,1,5}-{3213,9890,0,1,1}-{2496,2890,0,1,4}-{2503,2889,0,1,1}-{2497,2939,0,1,2}-"
}, },
{ {
"npc_id": "60", "npc_id": "60",
@ -217,15 +217,15 @@
}, },
{ {
"npc_id": "66", "npc_id": "66",
"loc_data": "{2417,3493,1,1,0}-{2418,3495,1,1,0}-{2383,3452,0,1,0}-{2401,3417,0,1,0}-{2402,3422,0,1,0}-{2402,3441,0,1,0}-{2403,3430,0,1,0}-{2408,3441,0,1,0}-{2409,3430,0,1,0}-{2423,3426,0,1,0}-{2427,3428,0,1,0}-{2427,3440,0,1,0}-{2526,3168,0,1,0}-{2529,3163,0,1,0}-{2530,3172,0,1,0}-{2536,3169,0,1,0}-{2435,3460,0,1,0}-{2440,3470,0,1,0}-{2447,3502,0,1,0}-{2457,3462,0,1,0}-{2478,3502,0,1,0}-{2449,3492,1,1,0}-{2450,3490,1,1,0}-{2474,3490,1,1,0}-{2482,3492,1,1,0}-{2482,3498,1,1,0}-{2399,3356,0,1,0}-" "loc_data": "{2399,3356,0,1,0}-{2383,3452,0,1,0}-{2401,3417,0,1,0}-{2402,3422,0,1,0}-{2402,3441,0,1,0}-{2403,3430,0,1,0}-{2408,3441,0,1,0}-{2409,3430,0,1,0}-{2423,3426,0,1,0}-{2427,3428,0,1,0}-{2427,3440,0,1,0}-{2417,3493,1,1,0}-{2418,3495,1,1,0}-{2435,3460,0,1,0}-{2440,3470,0,1,0}-{2447,3502,0,1,0}-{2457,3462,0,1,0}-{2478,3502,0,1,0}-{2449,3492,1,1,0}-{2450,3490,1,1,0}-{2474,3490,1,1,0}-{2482,3492,1,1,0}-{2482,3498,1,1,0}-{2526,3168,0,1,0}-{2529,3163,0,1,0}-{2530,3172,0,1,0}-{2536,3169,0,1,0}-"
}, },
{ {
"npc_id": "67", "npc_id": "67",
"loc_data": "{2556,3226,0,1,0}-{2456,3425,0,1,0}-{2459,3421,0,1,0}-{2462,3431,0,1,0}-{2394,3500,1,1,0}-{2417,3483,1,1,0}-{2377,3442,0,1,0}-{2380,3425,0,1,0}-{2383,3433,0,1,0}-{2405,3447,0,1,0}-{2406,3440,0,1,0}-{2393,3451,1,1,0}-{2408,3437,1,1,0}-{2521,3169,0,1,0}-{2521,3171,0,1,0}-{2033,5530,1,1,0}-{2437,3478,0,1,0}-{2442,3465,0,1,0}-{2456,3467,0,1,0}-{2471,3496,0,1,0}-{2474,3508,0,1,0}-{2475,3471,0,1,0}-{2479,3468,0,1,0}-{2486,3470,0,1,0}-{2492,3474,0,1,0}-{2443,3464,1,1,0}-{2443,3502,1,1,0}-{2448,3496,1,1,0}-{2449,3506,1,1,0}-{2457,3498,1,1,0}-{2474,3498,1,1,0}-{2480,3502,1,1,0}-{2481,3482,1,1,0}-{2490,3503,1,1,0}-{2400,3356,0,1,0}-" "loc_data": "{2400,3356,0,1,0}-{2377,3442,0,1,0}-{2380,3425,0,1,0}-{2383,3433,0,1,0}-{2405,3447,0,1,0}-{2406,3440,0,1,0}-{2393,3451,1,1,0}-{2408,3437,1,1,0}-{2394,3500,1,1,0}-{2417,3483,1,1,0}-{2456,3425,0,1,0}-{2459,3421,0,1,0}-{2462,3431,0,1,0}-{2437,3478,0,1,0}-{2442,3465,0,1,0}-{2456,3467,0,1,0}-{2471,3496,0,1,0}-{2474,3508,0,1,0}-{2475,3471,0,1,0}-{2479,3468,0,1,0}-{2486,3470,0,1,0}-{2492,3474,0,1,0}-{2443,3464,1,1,0}-{2443,3502,1,1,0}-{2448,3496,1,1,0}-{2449,3506,1,1,0}-{2457,3498,1,1,0}-{2474,3498,1,1,0}-{2480,3502,1,1,0}-{2481,3482,1,1,0}-{2490,3503,1,1,0}-{2521,3169,0,1,0}-{2521,3171,0,1,0}-{2556,3226,0,1,0}-{2033,5530,1,1,0}-"
}, },
{ {
"npc_id": "68", "npc_id": "68",
"loc_data": "{2400,3514,1,1,0}-{2418,3485,1,1,0}-{2378,3423,0,1,0}-{2393,3435,0,1,0}-{2394,3425,0,1,0}-{2395,3449,0,1,0}-{2403,3433,0,1,0}-{2420,3429,0,1,0}-{2420,3438,0,1,0}-{2522,3172,0,1,0}-{2433,3474,0,1,0}-{2433,3492,0,1,0}-{2458,3497,0,1,0}-{2464,3505,0,1,0}-{2476,3458,0,1,0}-{2445,3502,1,1,0}-{2453,3488,1,1,0}-{2475,3502,1,1,0}-{2465,3490,2,1,0}-{2401,3357,0,1,0}-" "loc_data": "{2401,3357,0,1,0}-{2378,3423,0,1,0}-{2393,3435,0,1,0}-{2394,3425,0,1,0}-{2395,3449,0,1,0}-{2403,3433,0,1,0}-{2420,3429,0,1,0}-{2420,3438,0,1,0}-{2400,3514,1,1,0}-{2418,3485,1,1,0}-{2433,3474,0,1,0}-{2433,3492,0,1,0}-{2458,3497,0,1,0}-{2464,3505,0,1,0}-{2476,3458,0,1,0}-{2445,3502,1,1,0}-{2453,3488,1,1,0}-{2475,3502,1,1,0}-{2465,3490,2,1,0}-{2522,3172,0,1,0}-"
}, },
{ {
"npc_id": "73", "npc_id": "73",
@ -325,11 +325,11 @@
}, },
{ {
"npc_id": "100", "npc_id": "100",
"loc_data": "{2567,3440,0,1,3}-{2564,9653,0,1,0}-{2565,9655,0,1,0}-{2566,9626,0,1,0}-{2567,9653,0,1,0}-{2569,9633,0,1,0}-{2607,9621,0,1,0}-{2551,3408,0,1,6}-{2553,3405,0,1,3}-{2559,3452,0,1,3}-" "loc_data": "{2567,3440,0,1,3}-{2316,9392,0,1,0}-{2319,9367,0,1,0}-{2321,9402,0,1,0}-{2322,9387,0,1,0}-{2325,9360,0,1,0}-{2333,9346,0,1,0}-{2335,9382,0,1,0}-{2337,9387,0,1,0}-{2343,9360,0,1,0}-{2344,9369,0,1,0}-{2348,9390,0,1,0}-{2349,9380,0,1,0}-{2349,9402,0,1,0}-{2359,9345,0,1,0}-{2359,9359,0,1,0}-{2359,9374,0,1,0}-{2359,9382,0,1,0}-{2363,9403,0,1,0}-{2564,9653,0,1,0}-{2565,9655,0,1,0}-{2566,9626,0,1,0}-{2567,9653,0,1,0}-{2569,9633,0,1,0}-{2607,9621,0,1,0}-{2551,3408,0,1,6}-{2553,3405,0,1,3}-{2559,3452,0,1,3}-"
}, },
{ {
"npc_id": "101", "npc_id": "101",
"loc_data": "{2622,3389,0,1,4}-{2619,3390,0,1,4}-{2573,3437,0,1,3}-{2562,9659,0,1,0}-{2563,9661,0,1,0}-{2599,9626,0,1,0}-{2601,9627,0,1,0}-{2605,9621,0,1,0}-{2610,9620,0,1,0}-{2624,3391,0,1,1}-{2555,3407,0,1,3}-{2553,3457,0,1,3}-" "loc_data": "{2622,3389,0,1,4}-{2619,3390,0,1,4}-{2573,3437,0,1,3}-{2305,9385,0,1,0}-{2307,9359,0,1,0}-{2307,9403,0,1,0}-{2310,9396,0,1,0}-{2317,9371,0,1,0}-{2317,9383,0,1,0}-{2324,9404,0,1,0}-{2333,9366,0,1,0}-{2335,9393,0,1,0}-{2339,9403,0,1,0}-{2342,9347,0,1,0}-{2351,9359,0,1,0}-{2359,9392,0,1,0}-{2562,9659,0,1,0}-{2563,9661,0,1,0}-{2599,9626,0,1,0}-{2601,9627,0,1,0}-{2605,9621,0,1,0}-{2610,9620,0,1,0}-{2624,3391,0,1,1}-{2555,3407,0,1,3}-{2553,3457,0,1,3}-"
}, },
{ {
"npc_id": "102", "npc_id": "102",
@ -345,7 +345,7 @@
}, },
{ {
"npc_id": "105", "npc_id": "105",
"loc_data": "{3100,3594,0,1,6}-{3107,3608,0,1,2}-{3099,3602,0,1,0}-{2632,3280,0,1,1}-{2633,3274,0,1,3}-{2696,3329,0,1,4}-{2708,3336,0,1,4}-{3230,3500,0,1,5}-{2988,3671,0,1,0}-{3001,3674,0,1,0}-{2497,3164,0,1,2}-{2387,3376,0,1,0}-{2398,3366,0,1,0}-{2412,3378,0,1,0}-{2419,3372,0,1,0}-" "loc_data": "{3100,3594,0,1,6}-{3107,3608,0,1,2}-{3099,3602,0,1,0}-{2632,3280,0,1,1}-{2633,3274,0,1,3}-{2387,3376,0,1,0}-{2398,3366,0,1,0}-{2412,3378,0,1,0}-{2419,3372,0,1,0}-{2696,3329,0,1,4}-{2708,3336,0,1,4}-{3230,3500,0,1,5}-{2988,3671,0,1,0}-{3001,3674,0,1,0}-{2497,3164,0,1,2}-"
}, },
{ {
"npc_id": "106", "npc_id": "106",
@ -365,7 +365,7 @@
}, },
{ {
"npc_id": "110", "npc_id": "110",
"loc_data": "{2564,9887,0,1,4}-{2581,9897,0,1,1}-{2577,9888,0,1,1}-{3234,5497,0,1,1}-{3305,9400,0,1,1}-{3244,9356,0,1,1}-{3252,9370,0,1,1}-{3294,9375,0,1,3}-{3050,10337,0,1,4}-{3047,10340,0,1,4}-{3048,10346,0,1,4}-{3048,10346,0,1,3}-" "loc_data": "{2564,9887,0,1,4}-{2581,9897,0,1,1}-{2577,9888,0,1,1}-{3234,5497,0,1,1}-{3244,9356,0,1,1}-{3252,9370,0,1,1}-{3305,9400,0,1,1}-{3294,9375,0,1,3}-{3050,10337,0,1,4}-{3047,10340,0,1,4}-{3048,10346,0,1,4}-{3048,10346,0,1,3}-"
}, },
{ {
"npc_id": "111", "npc_id": "111",
@ -389,7 +389,7 @@
}, },
{ {
"npc_id": "117", "npc_id": "117",
"loc_data": "{2369,3404,0,1,0}-{3118,9845,0,1,4}-{3111,9844,0,1,6}-{3123,9845,0,1,3}-{3114,9833,0,1,3}-{3110,9841,0,1,1}-{3119,9839,0,1,1}-{3097,9832,0,1,0}-{3101,9832,0,1,1}-{3107,9829,0,1,3}-{3115,9831,0,1,4}-{3109,9835,0,1,4}-{2904,9734,0,1,0}-{2548,3146,0,1,1}-{2542,3145,0,1,4}-{2503,3150,0,1,4}-{3300,3649,0,1,0}-{3044,10321,0,1,2}-{3044,10316,0,1,4}-{3045,10308,0,1,4}-{3048,10317,0,1,2}-" "loc_data": "{3118,9845,0,1,4}-{3111,9844,0,1,6}-{3123,9845,0,1,3}-{3114,9833,0,1,3}-{3110,9841,0,1,1}-{3119,9839,0,1,1}-{3097,9832,0,1,0}-{3101,9832,0,1,1}-{3107,9829,0,1,3}-{3115,9831,0,1,4}-{3109,9835,0,1,4}-{2369,3404,0,1,0}-{2904,9734,0,1,0}-{2439,3214,0,1,0}-{2548,3146,0,1,1}-{2542,3145,0,1,4}-{2503,3150,0,1,4}-{3300,3649,0,1,0}-{3044,10321,0,1,2}-{3044,10316,0,1,4}-{3045,10308,0,1,4}-{3048,10317,0,1,2}-"
}, },
{ {
"npc_id": "118", "npc_id": "118",
@ -489,23 +489,23 @@
}, },
{ {
"npc_id": "153", "npc_id": "153",
"loc_data": "{2540,9820,0,1,0}-{2543,9813,0,1,0}-{2546,9817,0,1,0}-{2464,4421,0,1,0}-{2466,4423,0,1,0}-{2486,4464,0,1,0}-{2556,3444,0,1,0}-{3082,3077,0,1,0}-{3092,3082,0,1,0}-{3109,3090,0,1,0}-{3112,3093,0,1,0}-{2249,3260,0,1,0}-{2250,3257,0,1,0}-{2250,3259,0,1,0}-{2252,3261,0,1,0}-{2253,3256,0,1,0}-{2262,3226,0,1,0}-{2264,3225,0,1,0}-{2266,3229,0,1,0}-{2268,3227,0,1,0}-{2269,3222,0,1,0}-{2269,3224,0,1,0}-{2270,3223,0,1,0}-{2270,3226,0,1,0}-{3200,5954,0,1,0}-{3202,5958,0,1,0}-{3204,5955,0,1,0}-{3204,5959,0,1,0}-{3231,5967,0,1,0}-{3236,5974,0,1,0}-{3237,5968,0,1,0}-{3240,5992,0,1,0}-{3240,5994,0,1,0}-{3242,5990,0,1,0}-{3242,5993,0,1,0}-{3244,5994,0,1,0}-{3246,5989,0,1,0}-{2196,3191,0,1,0}-{2197,3189,0,1,0}-{2198,3181,0,1,0}-{2198,3187,0,1,0}-{2199,3183,0,1,0}-{2199,3187,0,1,0}-{2200,3185,0,1,0}-{2201,3185,0,1,0}-{2204,3180,0,1,0}-{2324,4599,0,1,0}-{2325,4597,0,1,0}-{2326,4589,0,1,0}-{2326,4595,0,1,0}-{2327,4591,0,1,0}-{2327,4595,0,1,0}-{2328,4593,0,1,0}-{2329,4593,0,1,0}-{2332,4588,0,1,0}-{2176,3202,0,1,0}-{2178,3206,0,1,0}-{2180,3203,0,1,0}-{2180,3207,0,1,0}-{2207,3215,0,1,0}-{2212,3222,0,1,0}-{2213,3216,0,1,0}-{2216,3240,0,1,0}-{2216,3242,0,1,0}-{2218,3238,0,1,0}-{2218,3241,0,1,0}-{2220,3242,0,1,0}-{2222,3237,0,1,0}-{2437,3425,0,1,0}-{2438,3422,0,1,0}-{2450,3419,0,1,0}-{2415,4466,0,1,0}-{2419,4427,0,1,0}-{2421,4468,0,1,0}-{2426,4431,0,1,0}-{3175,3226,0,1,0}-{3178,3228,0,1,0}-{3179,3226,0,1,0}-{3182,3251,0,1,0}-{3183,3254,0,1,0}-{2697,6204,0,1,0}-{2698,6201,0,1,0}-{2698,6203,0,1,0}-{2700,6205,0,1,0}-{2701,6200,0,1,0}-{2710,6170,0,1,0}-{2712,6169,0,1,0}-{2714,6173,0,1,0}-{2716,6171,0,1,0}-{2717,6166,0,1,0}-{2717,6168,0,1,0}-{2718,6167,0,1,0}-{2718,6170,0,1,0}-{2478,3373,0,1,0}-{2479,3381,0,1,0}-{2481,3384,0,1,0}-{2490,3371,0,1,0}-{2689,6083,0,1,0}-{2689,6088,0,1,0}-{2690,6094,0,1,0}-{2691,6084,0,1,0}-{2692,6081,0,1,0}-{2692,6090,0,1,0}-{2693,6083,0,1,0}-{2693,6085,0,1,0}-{2693,6090,0,1,0}-{2694,6083,0,1,0}-{2694,6086,0,1,0}-{2695,6082,0,1,0}-{2695,6085,0,1,0}-{2695,6088,0,1,0}-{2695,6091,0,1,0}-{2695,6121,0,1,0}-{2698,6121,0,1,0}-{2699,6082,0,1,0}-{2699,6085,0,1,0}-{2700,6084,0,1,0}-{2701,6085,0,1,0}-{2702,6081,0,1,0}-{2702,6083,0,1,0}-{2703,6119,0,1,0}-{2704,6117,0,1,0}-{2705,6121,0,1,0}-{2730,6091,0,1,0}-{2732,6095,0,1,0}-{2734,6090,0,1,0}-{2735,6094,0,1,0}-{2735,6097,0,1,0}-{2738,6098,0,1,0}-{2416,3404,0,1,0}-{2424,3410,0,1,0}-{2430,3405,0,1,0}-{1906,5223,0,1,0}-{1907,5221,0,1,0}-{3273,6012,0,1,0}-{3274,6009,0,1,0}-{3274,6011,0,1,0}-{3276,6013,0,1,0}-{3277,6008,0,1,0}-{3286,5978,0,1,0}-{3288,5977,0,1,0}-{3290,5981,0,1,0}-{3292,5979,0,1,0}-{3293,5974,0,1,0}-{3293,5976,0,1,0}-{3294,5975,0,1,0}-{3294,5978,0,1,0}-{2828,5091,0,1,0}-{2832,5108,0,1,0}-{2835,5079,0,1,0}-{2846,5067,0,1,0}-{2850,5111,0,1,0}-{2853,5086,0,1,0}-{2864,5071,0,1,0}-{2549,3139,0,1,0}-{2241,3139,0,1,0}-{2241,3144,0,1,0}-{2242,3150,0,1,0}-{2243,3140,0,1,0}-{2244,3137,0,1,0}-{2244,3146,0,1,0}-{2245,3139,0,1,0}-{2245,3141,0,1,0}-{2245,3146,0,1,0}-{2246,3139,0,1,0}-{2246,3142,0,1,0}-{2247,3138,0,1,0}-{2247,3141,0,1,0}-{2247,3144,0,1,0}-{2247,3147,0,1,0}-{2247,3177,0,1,0}-{2250,3177,0,1,0}-{2251,3138,0,1,0}-{2251,3141,0,1,0}-{2252,3140,0,1,0}-{2253,3141,0,1,0}-{2254,3137,0,1,0}-{2254,3139,0,1,0}-{2255,3175,0,1,0}-{2256,3173,0,1,0}-{2257,3177,0,1,0}-{2282,3147,0,1,0}-{2284,3151,0,1,0}-{2286,3146,0,1,0}-{2287,3150,0,1,0}-{2287,3153,0,1,0}-{2290,3154,0,1,0}-" "loc_data": "{3082,3077,0,1,0}-{3092,3082,0,1,0}-{3109,3090,0,1,0}-{3112,3093,0,1,0}-{2324,4599,0,1,0}-{2325,4597,0,1,0}-{2326,4589,0,1,0}-{2326,4595,0,1,0}-{2327,4591,0,1,0}-{2327,4595,0,1,0}-{2328,4593,0,1,0}-{2329,4593,0,1,0}-{2332,4588,0,1,0}-{2828,5091,0,1,0}-{2832,5108,0,1,0}-{2835,5079,0,1,0}-{2846,5067,0,1,0}-{2850,5111,0,1,0}-{2853,5086,0,1,0}-{2864,5071,0,1,0}-{3175,3226,0,1,0}-{3178,3228,0,1,0}-{3179,3226,0,1,0}-{3182,3251,0,1,0}-{3183,3254,0,1,0}-{2416,3404,0,1,0}-{2424,3410,0,1,0}-{2430,3405,0,1,0}-{2415,4466,0,1,0}-{2419,4427,0,1,0}-{2421,4468,0,1,0}-{2426,4431,0,1,0}-{1906,5223,0,1,0}-{1907,5221,0,1,0}-{2196,3191,0,1,0}-{2197,3189,0,1,0}-{2198,3181,0,1,0}-{2198,3187,0,1,0}-{2199,3183,0,1,0}-{2199,3187,0,1,0}-{2200,3185,0,1,0}-{2201,3185,0,1,0}-{2204,3180,0,1,0}-{2176,3202,0,1,0}-{2178,3206,0,1,0}-{2180,3203,0,1,0}-{2180,3207,0,1,0}-{2207,3215,0,1,0}-{2212,3222,0,1,0}-{2213,3216,0,1,0}-{2216,3240,0,1,0}-{2216,3242,0,1,0}-{2218,3238,0,1,0}-{2218,3241,0,1,0}-{2220,3242,0,1,0}-{2222,3237,0,1,0}-{2478,3373,0,1,0}-{2479,3381,0,1,0}-{2481,3384,0,1,0}-{2490,3371,0,1,0}-{2437,3425,0,1,0}-{2438,3422,0,1,0}-{2450,3419,0,1,0}-{2464,4421,0,1,0}-{2466,4423,0,1,0}-{2486,4464,0,1,0}-{3200,5954,0,1,0}-{3202,5958,0,1,0}-{3204,5955,0,1,0}-{3204,5959,0,1,0}-{3231,5967,0,1,0}-{3236,5974,0,1,0}-{3237,5968,0,1,0}-{3240,5992,0,1,0}-{3240,5994,0,1,0}-{3242,5990,0,1,0}-{3242,5993,0,1,0}-{3244,5994,0,1,0}-{3246,5989,0,1,0}-{2689,6083,0,1,0}-{2689,6088,0,1,0}-{2690,6094,0,1,0}-{2691,6084,0,1,0}-{2692,6081,0,1,0}-{2692,6090,0,1,0}-{2693,6083,0,1,0}-{2693,6085,0,1,0}-{2693,6090,0,1,0}-{2694,6083,0,1,0}-{2694,6086,0,1,0}-{2695,6082,0,1,0}-{2695,6085,0,1,0}-{2695,6088,0,1,0}-{2695,6091,0,1,0}-{2695,6121,0,1,0}-{2698,6121,0,1,0}-{2699,6082,0,1,0}-{2699,6085,0,1,0}-{2700,6084,0,1,0}-{2701,6085,0,1,0}-{2702,6081,0,1,0}-{2702,6083,0,1,0}-{2703,6119,0,1,0}-{2704,6117,0,1,0}-{2705,6121,0,1,0}-{2730,6091,0,1,0}-{2732,6095,0,1,0}-{2734,6090,0,1,0}-{2735,6094,0,1,0}-{2735,6097,0,1,0}-{2738,6098,0,1,0}-{2697,6204,0,1,0}-{2698,6201,0,1,0}-{2698,6203,0,1,0}-{2700,6205,0,1,0}-{2701,6200,0,1,0}-{2710,6170,0,1,0}-{2712,6169,0,1,0}-{2714,6173,0,1,0}-{2716,6171,0,1,0}-{2717,6166,0,1,0}-{2717,6168,0,1,0}-{2718,6167,0,1,0}-{2718,6170,0,1,0}-{2549,3139,0,1,0}-{2241,3139,0,1,0}-{2241,3144,0,1,0}-{2242,3150,0,1,0}-{2243,3140,0,1,0}-{2244,3137,0,1,0}-{2244,3146,0,1,0}-{2245,3139,0,1,0}-{2245,3141,0,1,0}-{2245,3146,0,1,0}-{2246,3139,0,1,0}-{2246,3142,0,1,0}-{2247,3138,0,1,0}-{2247,3141,0,1,0}-{2247,3144,0,1,0}-{2247,3147,0,1,0}-{2247,3177,0,1,0}-{2250,3177,0,1,0}-{2251,3138,0,1,0}-{2251,3141,0,1,0}-{2252,3140,0,1,0}-{2253,3141,0,1,0}-{2254,3137,0,1,0}-{2254,3139,0,1,0}-{2255,3175,0,1,0}-{2256,3173,0,1,0}-{2257,3177,0,1,0}-{2282,3147,0,1,0}-{2284,3151,0,1,0}-{2286,3146,0,1,0}-{2287,3150,0,1,0}-{2287,3153,0,1,0}-{2290,3154,0,1,0}-{2249,3260,0,1,0}-{2250,3257,0,1,0}-{2250,3259,0,1,0}-{2252,3261,0,1,0}-{2253,3256,0,1,0}-{2262,3226,0,1,0}-{2264,3225,0,1,0}-{2266,3229,0,1,0}-{2268,3227,0,1,0}-{2269,3222,0,1,0}-{2269,3224,0,1,0}-{2270,3223,0,1,0}-{2270,3226,0,1,0}-{2556,3444,0,1,0}-{3273,6012,0,1,0}-{3274,6009,0,1,0}-{3274,6011,0,1,0}-{3276,6013,0,1,0}-{3277,6008,0,1,0}-{3286,5978,0,1,0}-{3288,5977,0,1,0}-{3290,5981,0,1,0}-{3292,5979,0,1,0}-{3293,5974,0,1,0}-{3293,5976,0,1,0}-{3294,5975,0,1,0}-{3294,5978,0,1,0}-{2540,9820,0,1,0}-{2543,9813,0,1,0}-{2546,9817,0,1,0}-"
}, },
{ {
"npc_id": "154", "npc_id": "154",
"loc_data": "{2475,4459,0,1,0}-{2480,4458,0,1,0}-{2481,4454,0,1,0}-{2488,4465,0,1,0}-{3125,3084,0,1,0}-{2268,3228,0,1,0}-{3202,5955,0,1,0}-{3206,5953,0,1,0}-{3231,5976,0,1,0}-{3233,5974,0,1,0}-{3235,5970,0,1,0}-{3241,5996,0,1,0}-{3242,5988,0,1,0}-{3244,5992,0,1,0}-{2180,3173,0,1,0}-{2193,3187,0,1,0}-{2196,3184,0,1,0}-{2200,3181,0,1,0}-{2200,3188,0,1,0}-{2203,3189,0,1,0}-{2308,4581,0,1,0}-{2321,4595,0,1,0}-{2324,4592,0,1,0}-{2328,4589,0,1,0}-{2328,4596,0,1,0}-{2331,4597,0,1,0}-{2178,3203,0,1,0}-{2182,3201,0,1,0}-{2207,3224,0,1,0}-{2209,3222,0,1,0}-{2211,3218,0,1,0}-{2217,3244,0,1,0}-{2218,3236,0,1,0}-{2220,3240,0,1,0}-{2446,3396,0,1,0}-{2470,3397,0,1,0}-{2394,4453,0,1,0}-{2394,4457,0,1,0}-{2406,4447,0,1,0}-{2422,3489,0,1,0}-{2716,6172,0,1,0}-{2688,6092,0,1,0}-{2690,6087,0,1,0}-{2690,6095,0,1,0}-{2692,6082,0,1,0}-{2692,6088,0,1,0}-{2692,6123,0,1,0}-{2693,6081,0,1,0}-{2694,6125,0,1,0}-{2695,6087,0,1,0}-{2697,6086,0,1,0}-{2697,6087,0,1,0}-{2698,6081,0,1,0}-{2698,6124,0,1,0}-{2700,6083,0,1,0}-{2702,6084,0,1,0}-{2726,6085,0,1,0}-{2727,6081,0,1,0}-{2729,6083,0,1,0}-{2732,6084,0,1,0}-{2378,3418,0,1,0}-{2380,3422,0,1,0}-{2393,3442,0,1,0}-{2397,3440,0,1,0}-{2423,3399,0,1,0}-{2425,3406,0,1,0}-{2427,3402,0,1,0}-{1908,5222,0,1,0}-{3292,5980,0,1,0}-{2831,5070,0,1,0}-{2843,5106,0,1,0}-{2844,5080,0,1,0}-{2860,5079,0,1,0}-{2866,5104,0,1,0}-{2868,5096,0,1,0}-{2240,3148,0,1,0}-{2242,3143,0,1,0}-{2242,3151,0,1,0}-{2244,3138,0,1,0}-{2244,3144,0,1,0}-{2244,3179,0,1,0}-{2245,3137,0,1,0}-{2246,3181,0,1,0}-{2247,3143,0,1,0}-{2249,3142,0,1,0}-{2249,3143,0,1,0}-{2250,3137,0,1,0}-{2250,3180,0,1,0}-{2252,3139,0,1,0}-{2254,3140,0,1,0}-{2278,3141,0,1,0}-{2279,3137,0,1,0}-{2281,3139,0,1,0}-{2284,3140,0,1,0}-" "loc_data": "{3125,3084,0,1,0}-{2308,4581,0,1,0}-{2321,4595,0,1,0}-{2324,4592,0,1,0}-{2328,4589,0,1,0}-{2328,4596,0,1,0}-{2331,4597,0,1,0}-{2831,5070,0,1,0}-{2843,5106,0,1,0}-{2844,5080,0,1,0}-{2860,5079,0,1,0}-{2866,5104,0,1,0}-{2868,5096,0,1,0}-{2378,3418,0,1,0}-{2380,3422,0,1,0}-{2393,3442,0,1,0}-{2397,3440,0,1,0}-{2423,3399,0,1,0}-{2425,3406,0,1,0}-{2427,3402,0,1,0}-{2422,3489,0,1,0}-{2394,4453,0,1,0}-{2394,4457,0,1,0}-{2406,4447,0,1,0}-{1908,5222,0,1,0}-{2180,3173,0,1,0}-{2193,3187,0,1,0}-{2196,3184,0,1,0}-{2200,3181,0,1,0}-{2200,3188,0,1,0}-{2203,3189,0,1,0}-{2178,3203,0,1,0}-{2182,3201,0,1,0}-{2207,3224,0,1,0}-{2209,3222,0,1,0}-{2211,3218,0,1,0}-{2217,3244,0,1,0}-{2218,3236,0,1,0}-{2220,3240,0,1,0}-{2446,3396,0,1,0}-{2470,3397,0,1,0}-{2475,4459,0,1,0}-{2480,4458,0,1,0}-{2481,4454,0,1,0}-{2488,4465,0,1,0}-{3202,5955,0,1,0}-{3206,5953,0,1,0}-{3231,5976,0,1,0}-{3233,5974,0,1,0}-{3235,5970,0,1,0}-{3241,5996,0,1,0}-{3242,5988,0,1,0}-{3244,5992,0,1,0}-{2688,6092,0,1,0}-{2690,6087,0,1,0}-{2690,6095,0,1,0}-{2692,6082,0,1,0}-{2692,6088,0,1,0}-{2692,6123,0,1,0}-{2693,6081,0,1,0}-{2694,6125,0,1,0}-{2695,6087,0,1,0}-{2697,6086,0,1,0}-{2697,6087,0,1,0}-{2698,6081,0,1,0}-{2698,6124,0,1,0}-{2700,6083,0,1,0}-{2702,6084,0,1,0}-{2726,6085,0,1,0}-{2727,6081,0,1,0}-{2729,6083,0,1,0}-{2732,6084,0,1,0}-{2716,6172,0,1,0}-{2240,3148,0,1,0}-{2242,3143,0,1,0}-{2242,3151,0,1,0}-{2244,3138,0,1,0}-{2244,3144,0,1,0}-{2244,3179,0,1,0}-{2245,3137,0,1,0}-{2246,3181,0,1,0}-{2247,3143,0,1,0}-{2249,3142,0,1,0}-{2249,3143,0,1,0}-{2250,3137,0,1,0}-{2250,3180,0,1,0}-{2252,3139,0,1,0}-{2254,3140,0,1,0}-{2278,3141,0,1,0}-{2279,3137,0,1,0}-{2281,3139,0,1,0}-{2284,3140,0,1,0}-{2268,3228,0,1,0}-{3292,5980,0,1,0}-"
}, },
{ {
"npc_id": "155", "npc_id": "155",
"loc_data": "{3093,3086,0,1,0}-{3097,3085,0,1,0}-{3129,3091,0,1,0}-{3135,3084,0,1,0}-{2190,3180,0,1,0}-{2318,4588,0,1,0}-{2374,3469,0,1,0}-{2376,3466,0,1,0}-{3254,3230,0,1,0}-{1986,5564,0,1,0}-{2434,3516,0,1,0}-{2479,3501,0,1,0}-" "loc_data": "{3093,3086,0,1,0}-{3097,3085,0,1,0}-{3129,3091,0,1,0}-{3135,3084,0,1,0}-{2318,4588,0,1,0}-{2374,3469,0,1,0}-{2376,3466,0,1,0}-{2190,3180,0,1,0}-{3254,3230,0,1,0}-{2434,3516,0,1,0}-{2479,3501,0,1,0}-{1986,5564,0,1,0}-"
}, },
{ {
"npc_id": "156", "npc_id": "156",
"loc_data": "{2371,3460,0,1,0}-{2372,3456,0,1,0}-{2422,3467,0,1,0}-{2725,6127,0,1,0}-{2444,3491,0,1,0}-{2277,3183,0,1,0}-" "loc_data": "{2371,3460,0,1,0}-{2372,3456,0,1,0}-{2422,3467,0,1,0}-{2444,3491,0,1,0}-{2725,6127,0,1,0}-{2277,3183,0,1,0}-"
}, },
{ {
"npc_id": "157", "npc_id": "157",
"loc_data": "{2180,2798,0,1,0}-{2209,2812,0,1,0}-{2217,2780,0,1,0}-{1921,5931,0,1,0}-{1947,5908,0,1,0}-{1955,5949,0,1,0}-{1973,5888,0,1,0}-{1975,5918,0,1,0}-{1988,5870,0,1,0}-{2017,5884,0,1,0}-{2025,5852,0,1,0}-{2182,2979,0,1,0}-{2211,2963,0,1,0}-{1931,6038,0,1,0}-{1983,6037,0,1,0}-{2153,2810,0,1,0}-{2172,2806,0,1,0}-{1961,5882,0,1,0}-{1980,5878,0,1,0}-{2242,2788,0,1,0}-{2248,2858,0,1,0}-{2256,2828,0,1,0}-{2284,2874,0,1,0}-{2255,3216,0,1,0}-{2262,3210,0,1,0}-{2271,3204,0,1,0}-{2294,3219,0,1,0}-{2296,3206,0,1,0}-{2298,3201,0,1,0}-{2056,5930,0,1,0}-{2064,5900,0,1,0}-{2092,5946,0,1,0}-{2050,5860,0,1,0}-{3201,5986,0,1,0}-{3254,5972,0,1,0}-{3255,5986,0,1,0}-{3256,6008,0,1,0}-{3257,5973,0,1,0}-{3257,5975,0,1,0}-{3260,5974,0,1,0}-{3261,5977,0,1,0}-{3262,5957,0,1,0}-{2194,3158,0,1,0}-{2216,3188,0,1,0}-{2217,3190,0,1,0}-{2220,3158,0,1,0}-{2222,3141,0,1,0}-{2229,3138,0,1,0}-{2231,3181,0,1,0}-{2236,3155,0,1,0}-{2278,2956,0,1,0}-{2322,4566,0,1,0}-{2344,4596,0,1,0}-{2345,4598,0,1,0}-{2348,4566,0,1,0}-{2350,4549,0,1,0}-{2357,4546,0,1,0}-{2359,4589,0,1,0}-{2364,4563,0,1,0}-{2177,3234,0,1,0}-{2230,3220,0,1,0}-{2231,3234,0,1,0}-{2232,3256,0,1,0}-{2233,3221,0,1,0}-{2233,3223,0,1,0}-{2236,3222,0,1,0}-{2237,3225,0,1,0}-{2238,3205,0,1,0}-{2479,3396,0,1,0}-{2102,2942,0,1,0}-{2108,2919,0,1,0}-{2104,2873,0,1,0}-{2122,6032,0,1,0}-{1912,5945,0,1,0}-{3143,3210,0,1,0}-{3155,3253,0,1,0}-{3163,3261,0,1,0}-{3168,3258,0,1,0}-{2086,6028,0,1,0}-{2703,6160,0,1,0}-{2710,6154,0,1,0}-{2719,6148,0,1,0}-{2742,6163,0,1,0}-{2744,6150,0,1,0}-{2746,6145,0,1,0}-{2314,2960,0,1,0}-{2723,6105,0,1,0}-{2739,6123,0,1,0}-{2744,6108,0,1,0}-{2326,2894,0,1,0}-{2333,2920,0,1,0}-{3279,5968,0,1,0}-{3286,5962,0,1,0}-{3295,5956,0,1,0}-{3318,5971,0,1,0}-{3320,5958,0,1,0}-{3322,5953,0,1,0}-{2134,5966,0,1,0}-{2141,5992,0,1,0}-{2123,2966,0,1,0}-{2175,2965,0,1,0}-{1910,6014,0,1,0}-{1916,5991,0,1,0}-{2540,3167,0,1,0}-{2110,2955,0,1,0}-{1990,6051,0,1,0}-{2019,6035,0,1,0}-{2447,3467,0,1,0}-{2448,3469,0,1,0}-{1918,6027,0,1,0}-{2275,3161,0,1,0}-{2291,3179,0,1,0}-{2296,3164,0,1,0}-{2113,2859,0,1,0}-{2139,2836,0,1,0}-{2147,2877,0,1,0}-{2165,2816,0,1,0}-{2167,2846,0,1,0}-" "loc_data": "{2104,2873,0,1,0}-{2102,2942,0,1,0}-{2108,2919,0,1,0}-{2326,2894,0,1,0}-{2333,2920,0,1,0}-{2314,2960,0,1,0}-{2110,2955,0,1,0}-{2322,4566,0,1,0}-{2344,4596,0,1,0}-{2345,4598,0,1,0}-{2348,4566,0,1,0}-{2350,4549,0,1,0}-{2357,4546,0,1,0}-{2359,4589,0,1,0}-{2364,4563,0,1,0}-{2050,5860,0,1,0}-{2056,5930,0,1,0}-{2064,5900,0,1,0}-{2092,5946,0,1,0}-{2086,6028,0,1,0}-{2153,2810,0,1,0}-{2172,2806,0,1,0}-{2113,2859,0,1,0}-{2139,2836,0,1,0}-{2147,2877,0,1,0}-{2165,2816,0,1,0}-{2167,2846,0,1,0}-{2123,2966,0,1,0}-{2175,2965,0,1,0}-{3143,3210,0,1,0}-{3155,3253,0,1,0}-{3163,3261,0,1,0}-{3168,3258,0,1,0}-{1912,5945,0,1,0}-{2134,5966,0,1,0}-{2141,5992,0,1,0}-{1910,6014,0,1,0}-{1916,5991,0,1,0}-{2122,6032,0,1,0}-{1918,6027,0,1,0}-{2180,2798,0,1,0}-{2209,2812,0,1,0}-{2217,2780,0,1,0}-{2182,2979,0,1,0}-{2211,2963,0,1,0}-{2194,3158,0,1,0}-{2216,3188,0,1,0}-{2217,3190,0,1,0}-{2220,3158,0,1,0}-{2222,3141,0,1,0}-{2229,3138,0,1,0}-{2231,3181,0,1,0}-{2236,3155,0,1,0}-{2177,3234,0,1,0}-{2230,3220,0,1,0}-{2231,3234,0,1,0}-{2232,3256,0,1,0}-{2233,3221,0,1,0}-{2233,3223,0,1,0}-{2236,3222,0,1,0}-{2237,3225,0,1,0}-{2238,3205,0,1,0}-{2479,3396,0,1,0}-{2447,3467,0,1,0}-{2448,3469,0,1,0}-{1961,5882,0,1,0}-{1980,5878,0,1,0}-{1921,5931,0,1,0}-{1947,5908,0,1,0}-{1955,5949,0,1,0}-{1973,5888,0,1,0}-{1975,5918,0,1,0}-{3201,5986,0,1,0}-{3254,5972,0,1,0}-{3255,5986,0,1,0}-{3256,6008,0,1,0}-{3257,5973,0,1,0}-{3257,5975,0,1,0}-{3260,5974,0,1,0}-{3261,5977,0,1,0}-{3262,5957,0,1,0}-{1931,6038,0,1,0}-{1983,6037,0,1,0}-{2723,6105,0,1,0}-{2739,6123,0,1,0}-{2744,6108,0,1,0}-{2703,6160,0,1,0}-{2710,6154,0,1,0}-{2719,6148,0,1,0}-{2742,6163,0,1,0}-{2744,6150,0,1,0}-{2746,6145,0,1,0}-{2242,2788,0,1,0}-{2248,2858,0,1,0}-{2256,2828,0,1,0}-{2284,2874,0,1,0}-{2278,2956,0,1,0}-{2540,3167,0,1,0}-{2275,3161,0,1,0}-{2291,3179,0,1,0}-{2296,3164,0,1,0}-{2255,3216,0,1,0}-{2262,3210,0,1,0}-{2271,3204,0,1,0}-{2294,3219,0,1,0}-{2296,3206,0,1,0}-{2298,3201,0,1,0}-{1988,5870,0,1,0}-{2017,5884,0,1,0}-{2025,5852,0,1,0}-{3279,5968,0,1,0}-{3286,5962,0,1,0}-{3295,5956,0,1,0}-{3318,5971,0,1,0}-{3320,5958,0,1,0}-{3322,5953,0,1,0}-{1990,6051,0,1,0}-{2019,6035,0,1,0}-"
}, },
{ {
"npc_id": "158", "npc_id": "158",
@ -513,7 +513,7 @@
}, },
{ {
"npc_id": "159", "npc_id": "159",
"loc_data": "{2392,3475,0,1,0}-{2394,3506,0,1,0}-{2396,3471,0,1,0}-{2405,3499,0,1,0}-{2416,3487,0,1,0}-{2413,3445,1,1,0}-{2415,3435,1,1,0}-{2416,3416,1,1,0}-{2424,3434,1,1,0}-{2483,3500,1,1,0}-" "loc_data": "{2413,3445,1,1,0}-{2415,3435,1,1,0}-{2416,3416,1,1,0}-{2424,3434,1,1,0}-{2392,3475,0,1,0}-{2394,3506,0,1,0}-{2396,3471,0,1,0}-{2405,3499,0,1,0}-{2416,3487,0,1,0}-{2483,3500,1,1,0}-"
}, },
{ {
"npc_id": "160", "npc_id": "160",
@ -529,11 +529,11 @@
}, },
{ {
"npc_id": "163", "npc_id": "163",
"loc_data": "{2451,3414,0,1,0}-{2459,3395,0,1,0}-{2459,3438,0,1,0}-{2462,3395,0,1,0}-{2445,3429,1,1,0}-{2409,3470,1,1,0}-{2416,3466,1,1,0}-{2420,3466,1,1,0}-{2461,9895,0,1,0}-{2465,9894,0,1,0}-{2465,9899,0,1,0}-{2459,3385,0,1,0}-{2463,3385,0,1,0}-{2392,3454,0,1,0}-{2394,3436,0,1,0}-{2408,3452,0,1,0}-{2421,3413,0,1,0}-{2442,3489,0,1,0}-{2450,3485,0,1,0}-{2451,3507,0,1,0}-{2453,3490,0,1,0}-{2459,3503,0,1,0}-{2461,3509,0,1,0}-{2464,3465,0,1,0}-{2464,3468,0,1,0}-{2468,3465,0,1,0}-{2468,3468,0,1,0}-{2468,3506,0,1,0}-{2472,3484,0,1,0}-{2475,3490,0,1,0}-{2475,3502,0,1,0}-{2477,3512,0,1,0}-{2481,3485,0,1,0}-{2482,3501,0,1,0}-{2467,3495,1,1,0}-{2473,3495,1,1,0}-{2448,3497,2,1,0}-{2463,3480,2,1,0}-{2465,3497,2,1,0}-{2465,3510,2,1,0}-{2466,3480,2,1,0}-" "loc_data": "{2392,3454,0,1,0}-{2394,3436,0,1,0}-{2408,3452,0,1,0}-{2421,3413,0,1,0}-{2409,3470,1,1,0}-{2416,3466,1,1,0}-{2420,3466,1,1,0}-{2459,3385,0,1,0}-{2463,3385,0,1,0}-{2451,3414,0,1,0}-{2459,3395,0,1,0}-{2459,3438,0,1,0}-{2462,3395,0,1,0}-{2445,3429,1,1,0}-{2442,3489,0,1,0}-{2450,3485,0,1,0}-{2451,3507,0,1,0}-{2453,3490,0,1,0}-{2459,3503,0,1,0}-{2461,3509,0,1,0}-{2464,3465,0,1,0}-{2464,3468,0,1,0}-{2468,3465,0,1,0}-{2468,3468,0,1,0}-{2468,3506,0,1,0}-{2472,3484,0,1,0}-{2475,3490,0,1,0}-{2475,3502,0,1,0}-{2477,3512,0,1,0}-{2481,3485,0,1,0}-{2482,3501,0,1,0}-{2467,3495,1,1,0}-{2473,3495,1,1,0}-{2448,3497,2,1,0}-{2463,3480,2,1,0}-{2465,3497,2,1,0}-{2465,3510,2,1,0}-{2466,3480,2,1,0}-{2461,9895,0,1,0}-{2465,9894,0,1,0}-{2465,9899,0,1,0}-"
}, },
{ {
"npc_id": "164", "npc_id": "164",
"loc_data": "{2459,3392,0,1,0}-{2461,3422,0,1,0}-{2462,3392,0,1,0}-{2460,3382,0,1,0}-{2462,3382,0,1,0}-{2410,3416,0,1,0}-{2420,3435,0,1,0}-{2420,3447,0,1,0}-{2427,3410,0,1,0}-{2012,5535,2,1,0}-{2023,5544,2,1,0}-{2441,3497,0,1,0}-{2447,3510,0,1,0}-{2461,3487,0,1,0}-{2464,3472,0,1,0}-{2464,3489,0,1,0}-{2467,3489,0,1,0}-{2468,3472,0,1,0}-{2473,3503,0,1,0}-{2478,3497,0,1,0}-{2464,3496,1,1,0}-{2448,3495,2,1,0}-{2460,3487,2,1,0}-{2467,3494,2,1,0}-{2467,3510,2,1,0}-{2471,3496,2,1,0}-{2483,3495,2,1,0}-{2483,3497,2,1,0}-" "loc_data": "{2410,3416,0,1,0}-{2420,3435,0,1,0}-{2420,3447,0,1,0}-{2427,3410,0,1,0}-{2460,3382,0,1,0}-{2462,3382,0,1,0}-{2459,3392,0,1,0}-{2461,3422,0,1,0}-{2462,3392,0,1,0}-{2441,3497,0,1,0}-{2447,3510,0,1,0}-{2461,3487,0,1,0}-{2464,3472,0,1,0}-{2464,3489,0,1,0}-{2467,3489,0,1,0}-{2468,3472,0,1,0}-{2473,3503,0,1,0}-{2478,3497,0,1,0}-{2464,3496,1,1,0}-{2448,3495,2,1,0}-{2460,3487,2,1,0}-{2467,3494,2,1,0}-{2467,3510,2,1,0}-{2471,3496,2,1,0}-{2483,3495,2,1,0}-{2483,3497,2,1,0}-{2012,5535,2,1,0}-{2023,5544,2,1,0}-"
}, },
{ {
"npc_id": "166", "npc_id": "166",
@ -541,11 +541,11 @@
}, },
{ {
"npc_id": "168", "npc_id": "168",
"loc_data": "{2434,3436,0,1,0}-{2437,3451,0,1,0}-{2438,3427,0,1,0}-{2441,3411,0,1,0}-{2466,3449,0,1,0}-{2470,3399,0,1,0}-{2472,3400,0,1,0}-{2473,3412,0,1,0}-{2476,3454,0,1,0}-{2482,3397,0,1,0}-{2489,3401,0,1,0}-{2479,3407,1,1,0}-{2379,3482,0,1,0}-{2381,3496,0,1,0}-{2384,3497,0,1,0}-{2391,3476,0,1,0}-{2410,3496,0,1,0}-{2421,3481,0,1,0}-{2397,3514,1,1,0}-{2398,3451,1,1,0}-{2414,3447,1,1,0}-{2438,3465,0,1,0}-{2442,3505,0,1,0}-{2448,3486,0,1,0}-{2449,3487,0,1,0}-{2450,3489,0,1,0}-{2450,3505,0,1,0}-{2454,3465,0,1,0}-{2449,3486,1,1,0}-{2457,3488,1,1,0}-{2476,3488,1,1,0}-{2450,3496,2,1,0}-{2467,3488,2,1,0}-{2470,3503,2,1,0}-{2481,3498,2,1,0}-" "loc_data": "{2398,3451,1,1,0}-{2414,3447,1,1,0}-{2379,3482,0,1,0}-{2381,3496,0,1,0}-{2384,3497,0,1,0}-{2391,3476,0,1,0}-{2410,3496,0,1,0}-{2421,3481,0,1,0}-{2397,3514,1,1,0}-{2434,3436,0,1,0}-{2437,3451,0,1,0}-{2438,3427,0,1,0}-{2441,3411,0,1,0}-{2466,3449,0,1,0}-{2470,3399,0,1,0}-{2472,3400,0,1,0}-{2473,3412,0,1,0}-{2476,3454,0,1,0}-{2482,3397,0,1,0}-{2489,3401,0,1,0}-{2479,3407,1,1,0}-{2438,3465,0,1,0}-{2442,3505,0,1,0}-{2448,3486,0,1,0}-{2449,3487,0,1,0}-{2450,3489,0,1,0}-{2450,3505,0,1,0}-{2454,3465,0,1,0}-{2449,3486,1,1,0}-{2457,3488,1,1,0}-{2476,3488,1,1,0}-{2450,3496,2,1,0}-{2467,3488,2,1,0}-{2470,3503,2,1,0}-{2481,3498,2,1,0}-"
}, },
{ {
"npc_id": "169", "npc_id": "169",
"loc_data": "{2439,3433,0,1,0}-{2441,3449,0,1,0}-{2442,3428,0,1,0}-{2446,3403,0,1,0}-{2450,3416,0,1,0}-{2468,3441,0,1,0}-{2480,3408,0,1,0}-{2480,3406,1,1,0}-{2486,3400,1,1,0}-{2378,3482,0,1,0}-{2383,3496,0,1,0}-{2402,3507,0,1,0}-{2406,3476,0,1,0}-{2422,3485,0,1,0}-{2382,3506,1,1,0}-{2418,3472,1,1,0}-{2392,3450,1,1,0}-{2415,3415,1,1,0}-{2416,3434,1,1,0}-{2423,3425,1,1,0}-{2424,3442,1,1,0}-{2448,3489,0,1,0}-{2450,3488,0,1,0}-{2463,3508,0,1,0}-{2473,3489,0,1,0}-{2474,3457,0,1,0}-{2479,3503,0,1,0}-{2486,3467,0,1,0}-{2437,3463,1,1,0}-{2448,3489,1,1,0}-{2482,3508,1,1,0}-" "loc_data": "{2392,3450,1,1,0}-{2415,3415,1,1,0}-{2416,3434,1,1,0}-{2423,3425,1,1,0}-{2424,3442,1,1,0}-{2378,3482,0,1,0}-{2383,3496,0,1,0}-{2402,3507,0,1,0}-{2406,3476,0,1,0}-{2422,3485,0,1,0}-{2382,3506,1,1,0}-{2418,3472,1,1,0}-{2439,3433,0,1,0}-{2441,3449,0,1,0}-{2442,3428,0,1,0}-{2446,3403,0,1,0}-{2450,3416,0,1,0}-{2468,3441,0,1,0}-{2480,3408,0,1,0}-{2480,3406,1,1,0}-{2486,3400,1,1,0}-{2448,3489,0,1,0}-{2450,3488,0,1,0}-{2463,3508,0,1,0}-{2473,3489,0,1,0}-{2474,3457,0,1,0}-{2479,3503,0,1,0}-{2486,3467,0,1,0}-{2437,3463,1,1,0}-{2448,3489,1,1,0}-{2482,3508,1,1,0}-"
}, },
{ {
"npc_id": "170", "npc_id": "170",
@ -849,7 +849,7 @@
}, },
{ {
"npc_id": "278", "npc_id": "278",
"loc_data": "{3209,3215,0,0,0}-" "loc_data": "{3209,3215,0,1,0}-"
}, },
{ {
"npc_id": "279", "npc_id": "279",
@ -1357,11 +1357,11 @@
}, },
{ {
"npc_id": "479", "npc_id": "479",
"loc_data": "{1970,5522,3,1,0}-{2384,3481,0,1,0}-{2388,3473,0,1,0}-{2418,3474,3,1,0}-{2415,3433,3,1,0}-{2466,3500,2,1,0}-" "loc_data": "{2415,3433,3,1,0}-{2384,3481,0,1,0}-{2388,3473,0,1,0}-{2418,3474,3,1,0}-{2466,3500,2,1,0}-{1970,5522,3,1,0}-"
}, },
{ {
"npc_id": "480", "npc_id": "480",
"loc_data": "{1964,5522,3,1,0}-{2458,3417,1,1,0}-{2460,3417,1,1,0}-{2409,3507,0,1,0}-{2412,3474,3,1,0}-{2463,3504,2,1,0}-" "loc_data": "{2409,3507,0,1,0}-{2412,3474,3,1,0}-{2458,3417,1,1,0}-{2460,3417,1,1,0}-{2463,3504,2,1,0}-{1964,5522,3,1,0}-"
}, },
{ {
"npc_id": "481", "npc_id": "481",
@ -1387,6 +1387,10 @@
"npc_id": "490", "npc_id": "490",
"loc_data": "{1887,5026,0,0,6}-" "loc_data": "{1887,5026,0,0,6}-"
}, },
{
"npc_id": "492",
"loc_data": "{2464,3227,0,1,0}-"
},
{ {
"npc_id": "494", "npc_id": "494",
"loc_data": "{2615,3094,0,0,3}-{2615,3092,0,0,3}-{2615,3092,0,0,3}-{2615,3094,0,0,3}-{3122,3125,0,0,6}-{3120,3125,0,0,6}-{3090,3242,0,0,4}-{3090,3245,0,0,4}-{3090,3243,0,0,4}-{2618,3330,0,0,0}-{2619,3330,0,0,0}-{2584,3422,0,0,4}-{2584,3419,0,0,4}-{2584,3418,0,0,4}-{2657,3283,0,0,3}-{2657,3286,0,0,3}-{2807,3443,0,0,6}-{2810,3443,0,0,6}-" "loc_data": "{2615,3094,0,0,3}-{2615,3092,0,0,3}-{2615,3092,0,0,3}-{2615,3094,0,0,3}-{3122,3125,0,0,6}-{3120,3125,0,0,6}-{3090,3242,0,0,4}-{3090,3245,0,0,4}-{3090,3243,0,0,4}-{2618,3330,0,0,0}-{2619,3330,0,0,0}-{2584,3422,0,0,4}-{2584,3419,0,0,4}-{2584,3418,0,0,4}-{2657,3283,0,0,3}-{2657,3286,0,0,3}-{2807,3443,0,0,6}-{2810,3443,0,0,6}-"
@ -2351,14 +2355,46 @@
"npc_id": "805", "npc_id": "805",
"loc_data": "{2936,3288,0,1,4}-" "loc_data": "{2936,3288,0,1,4}-"
}, },
{
"npc_id": "806",
"loc_data": "{2745,3576,1,0,4}-"
},
{
"npc_id": "807",
"loc_data": "{2750,3576,0,0,4}-"
},
{
"npc_id": "808",
"loc_data": "{2736,3575,0,1,1}-"
},
{
"npc_id": "809",
"loc_data": "{2734,3581,0,1,1}-"
},
{
"npc_id": "810",
"loc_data": "{2736,3576,1,1,1}-"
},
{
"npc_id": "811",
"loc_data": "{2731,3579,0,1,4}-"
},
{ {
"npc_id": "812", "npc_id": "812",
"loc_data": "{2738,3473,0,0,1}-{2733,3473,0,0,1}-" "loc_data": "{2741,3562,0,1,0}-"
},
{
"npc_id": "813",
"loc_data": "{2741,3552,0,1,1}-"
}, },
{ {
"npc_id": "820", "npc_id": "820",
"loc_data": "{2697,3496,0,0,0}-" "loc_data": "{2697,3496,0,0,0}-"
}, },
{
"npc_id": "821",
"loc_data": "{2750,3580,0,1,0}-"
},
{ {
"npc_id": "822", "npc_id": "822",
"loc_data": "{3302,9466,0,1,6}-" "loc_data": "{3302,9466,0,1,6}-"
@ -2401,11 +2437,11 @@
}, },
{ {
"npc_id": "839", "npc_id": "839",
"loc_data": "{3265,3066,0,1,0}-{3267,3066,0,1,0}-{3310,3068,0,1,0}-{3322,3011,0,1,0}-{3322,3052,0,1,0}-{3324,3030,0,1,0}-{3150,3044,0,1,0}-{3172,3009,0,1,0}-{3197,3012,0,1,0}-{3198,3040,0,1,0}-{3217,3092,0,1,0}-{3235,3074,0,1,0}-{3252,3125,0,1,0}-{3258,3078,0,1,0}-{3237,2968,0,1,0}-{3224,3013,0,1,0}-{3225,3034,0,1,0}-{3226,3060,0,1,0}-{3250,3057,0,1,0}-{3283,3108,0,1,0}-{3323,3094,0,1,0}-" "loc_data": "{3150,3044,0,1,0}-{3172,3009,0,1,0}-{3197,3012,0,1,0}-{3198,3040,0,1,0}-{3237,2968,0,1,0}-{3224,3013,0,1,0}-{3225,3034,0,1,0}-{3226,3060,0,1,0}-{3250,3057,0,1,0}-{3217,3092,0,1,0}-{3235,3074,0,1,0}-{3252,3125,0,1,0}-{3258,3078,0,1,0}-{3265,3066,0,1,0}-{3267,3066,0,1,0}-{3310,3068,0,1,0}-{3322,3011,0,1,0}-{3322,3052,0,1,0}-{3324,3030,0,1,0}-{3283,3108,0,1,0}-{3323,3094,0,1,0}-"
}, },
{ {
"npc_id": "840", "npc_id": "840",
"loc_data": "{3268,3052,0,1,0}-{3281,3056,0,1,0}-{3307,3055,0,1,0}-{3318,3020,0,1,0}-{3318,3040,0,1,0}-{3190,3054,0,1,0}-{3192,3016,0,1,0}-{3217,3111,0,1,0}-{3222,3086,0,1,0}-{3238,3101,0,1,0}-{3244,3080,0,1,0}-{3253,3116,0,1,0}-{3255,3095,0,1,0}-{3237,3000,0,1,0}-{3245,2960,0,1,0}-{3208,3032,0,1,0}-{3217,3064,0,1,0}-{3238,3015,0,1,0}-{3258,3063,0,1,0}-{3267,3077,0,1,0}-{3269,3110,0,1,0}-{3275,3094,0,1,0}-{3291,3078,0,1,0}-{3291,3100,0,1,0}-{3305,3089,0,1,0}-{3318,3078,0,1,0}-{3321,3104,0,1,0}-" "loc_data": "{3190,3054,0,1,0}-{3192,3016,0,1,0}-{3237,3000,0,1,0}-{3245,2960,0,1,0}-{3208,3032,0,1,0}-{3217,3064,0,1,0}-{3238,3015,0,1,0}-{3258,3063,0,1,0}-{3217,3111,0,1,0}-{3222,3086,0,1,0}-{3238,3101,0,1,0}-{3244,3080,0,1,0}-{3253,3116,0,1,0}-{3255,3095,0,1,0}-{3268,3052,0,1,0}-{3281,3056,0,1,0}-{3307,3055,0,1,0}-{3318,3020,0,1,0}-{3318,3040,0,1,0}-{3267,3077,0,1,0}-{3269,3110,0,1,0}-{3275,3094,0,1,0}-{3291,3078,0,1,0}-{3291,3100,0,1,0}-{3305,3089,0,1,0}-{3318,3078,0,1,0}-{3321,3104,0,1,0}-"
}, },
{ {
"npc_id": "841", "npc_id": "841",
@ -2537,7 +2573,11 @@
}, },
{ {
"npc_id": "885", "npc_id": "885",
"loc_data": "{2565,3271,0,0,0}-{2573,3268,1,0,0}-" "loc_data": "{2565,3271,0,1,0}-{2573,3268,1,1,0}-"
},
{
"npc_id": "886",
"loc_data": "{2567,9669,0,1,0}-"
}, },
{ {
"npc_id": "887", "npc_id": "887",
@ -2545,15 +2585,27 @@
}, },
{ {
"npc_id": "888", "npc_id": "888",
"loc_data": "{2565,3273,0,0,0}-" "loc_data": "{2565,3273,0,1,0}-"
}, },
{ {
"npc_id": "889", "npc_id": "889",
"loc_data": "{2571,3270,0,0,0}-" "loc_data": "{2571,3270,0,1,0}-"
}, },
{ {
"npc_id": "890", "npc_id": "890",
"loc_data": "{2569,3272,0,0,0}-{2573,3269,1,0,0}-" "loc_data": "{2569,3272,0,1,0}-{2573,3269,1,1,0}-"
},
{
"npc_id": "891",
"loc_data": "{2609,9670,0,1,0}-"
},
{
"npc_id": "893",
"loc_data": "{2567,9683,0,1,0}-"
},
{
"npc_id": "894",
"loc_data": "{2609,9686,0,1,0}-{2607,9681,0,1,0}-{2609,9674,0,1,0}-{2608,9672,0,1,0}-{2604,9674,0,1,0}-{2605,9671,0,1,0}-"
}, },
{ {
"npc_id": "895", "npc_id": "895",
@ -2745,7 +2797,7 @@
}, },
{ {
"npc_id": "1017", "npc_id": "1017",
"loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-" "loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{3198,3355,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-"
}, },
{ {
"npc_id": "1019", "npc_id": "1019",
@ -2777,11 +2829,11 @@
}, },
{ {
"npc_id": "1038", "npc_id": "1038",
"loc_data": "{3507,3496,1,1,1}-{3508,3494,0,1,1}-" "loc_data": "{3508,3494,0,1,1}-"
}, },
{ {
"npc_id": "1039", "npc_id": "1039",
"loc_data": "{3499,3506,1,1,5}-{3500,3505,0,1,5}-" "loc_data": "{3500,3505,0,1,5}-"
}, },
{ {
"npc_id": "1040", "npc_id": "1040",
@ -2789,7 +2841,7 @@
}, },
{ {
"npc_id": "1041", "npc_id": "1041",
"loc_data": "{3490,3503,1,0,0}-{3490,3500,0,1,4}-" "loc_data": "{3490,3500,0,1,4}-"
}, },
{ {
"npc_id": "1042", "npc_id": "1042",
@ -2797,7 +2849,7 @@
}, },
{ {
"npc_id": "1043", "npc_id": "1043",
"loc_data": "{3726,3381,0,0,0}-{3745,3359,0,0,0}-{3749,3365,0,0,0}-{3750,3354,0,0,0}-{3757,3363,0,0,0}-{3763,3337,0,0,0}-{3459,3457,0,0,0}-{3460,3462,0,0,0}-{3462,3459,0,0,0}-{3463,3490,0,0,0}-{3464,3511,0,0,0}-{3465,3466,0,0,0}-{3466,3495,0,0,0}-{3466,3497,0,0,0}-{3467,3485,0,0,0}-{3467,3497,0,0,0}-{3467,3509,0,0,0}-{3469,3470,0,0,0}-{3470,3469,0,0,0}-{3471,3477,0,0,0}-{3474,3505,0,0,0}-{3476,3507,0,0,0}-{3479,3511,0,0,0}-{3480,3468,0,0,0}-{3480,3470,0,0,0}-{3482,3469,0,0,0}-{3483,3511,0,0,0}-{3484,3464,0,0,0}-{3485,3509,0,0,0}-{3490,3461,0,0,0}-{3491,3460,0,0,0}-{3494,3461,0,0,0}-{3494,3512,0,0,0}-{3498,3461,0,0,0}-{3499,3513,0,0,0}-{3501,3513,0,0,0}-{3502,3464,0,0,0}-{3504,3463,0,0,0}-{3506,3512,0,0,0}-{3506,3515,0,0,0}-{3507,3515,0,0,0}-{3509,3512,0,0,0}-{3511,3488,0,0,0}-{3513,3467,0,0,0}-{3513,3487,0,0,0}-{3513,3489,0,0,0}-{3513,3503,0,0,0}-{3514,3490,0,0,0}-{3515,3495,0,0,0}-{3515,3499,0,0,0}-{3516,3469,0,0,0}-{3409,3369,0,0,0}-{3420,3349,0,0,0}-{3430,3340,0,0,0}-{3435,3330,0,0,0}-{3435,3359,0,0,0}-{3437,3374,0,0,0}-{3446,3385,0,0,0}-{3447,3388,0,0,0}-{3450,3370,0,0,0}-{3450,3387,0,0,0}-{3451,3336,0,0,0}-{3452,3355,0,0,0}-{3726,3289,0,0,0}-{3732,3291,0,0,0}-{3737,3280,0,0,0}-{3745,3285,0,0,0}-{3418,3420,0,0,0}-{3424,3452,0,0,0}-{3428,3409,0,0,0}-{3433,3416,0,0,0}-{3434,3394,0,0,0}-{3436,3407,0,0,0}-{3438,3414,0,0,0}-{3439,3449,0,0,0}-{3446,3439,0,0,0}-{3454,3410,0,0,0}-{3454,3423,0,0,0}-{2852,4561,0,0,0}-{2853,4566,0,0,0}-{2856,4568,0,0,0}-{2864,4561,0,0,0}-{2864,4563,0,0,0}-" "loc_data": "{2852,4561,0,0,0}-{2853,4566,0,0,0}-{2856,4568,0,0,0}-{2864,4561,0,0,0}-{2864,4563,0,0,0}-{3409,3369,0,0,0}-{3420,3349,0,0,0}-{3430,3340,0,0,0}-{3435,3330,0,0,0}-{3435,3359,0,0,0}-{3437,3374,0,0,0}-{3446,3385,0,0,0}-{3447,3388,0,0,0}-{3450,3370,0,0,0}-{3450,3387,0,0,0}-{3451,3336,0,0,0}-{3452,3355,0,0,0}-{3418,3420,0,0,0}-{3424,3452,0,0,0}-{3428,3409,0,0,0}-{3433,3416,0,0,0}-{3434,3394,0,0,0}-{3436,3407,0,0,0}-{3438,3414,0,0,0}-{3439,3449,0,0,0}-{3446,3439,0,0,0}-{3454,3410,0,0,0}-{3454,3423,0,0,0}-{3726,3289,0,0,0}-{3732,3291,0,0,0}-{3737,3280,0,0,0}-{3745,3285,0,0,0}-{3726,3381,0,0,0}-{3745,3359,0,0,0}-{3749,3365,0,0,0}-{3750,3354,0,0,0}-{3757,3363,0,0,0}-{3763,3337,0,0,0}-{3459,3457,0,0,0}-{3460,3462,0,0,0}-{3462,3459,0,0,0}-{3463,3490,0,0,0}-{3464,3511,0,0,0}-{3465,3466,0,0,0}-{3466,3495,0,0,0}-{3466,3497,0,0,0}-{3467,3485,0,0,0}-{3467,3497,0,0,0}-{3467,3509,0,0,0}-{3469,3470,0,0,0}-{3470,3469,0,0,0}-{3471,3477,0,0,0}-{3474,3505,0,0,0}-{3476,3507,0,0,0}-{3479,3511,0,0,0}-{3480,3468,0,0,0}-{3480,3470,0,0,0}-{3482,3469,0,0,0}-{3483,3511,0,0,0}-{3484,3464,0,0,0}-{3485,3509,0,0,0}-{3490,3461,0,0,0}-{3491,3460,0,0,0}-{3494,3461,0,0,0}-{3494,3512,0,0,0}-{3498,3461,0,0,0}-{3499,3513,0,0,0}-{3501,3513,0,0,0}-{3502,3464,0,0,0}-{3504,3463,0,0,0}-{3506,3512,0,0,0}-{3506,3515,0,0,0}-{3507,3515,0,0,0}-{3509,3512,0,0,0}-{3511,3488,0,0,0}-{3513,3467,0,0,0}-{3513,3487,0,0,0}-{3513,3489,0,0,0}-{3513,3503,0,0,0}-{3514,3490,0,0,0}-{3515,3495,0,0,0}-{3515,3499,0,0,0}-{3516,3469,0,0,0}-"
}, },
{ {
"npc_id": "1044", "npc_id": "1044",
@ -3313,11 +3365,11 @@
}, },
{ {
"npc_id": "1212", "npc_id": "1212",
"loc_data": "{2247,3226,0,0,0}-{2249,3227,0,0,0}-{2249,3258,0,0,0}-{2251,3260,0,0,0}-{2259,3211,0,0,0}-{2267,3223,0,0,0}-{2267,3225,0,0,0}-{2298,3262,0,0,0}-{3202,5990,0,0,0}-{3232,5977,0,0,0}-{3234,5969,0,0,0}-{3237,5995,0,0,0}-{3242,5997,0,0,0}-{3244,5995,0,0,0}-{3245,5995,0,0,0}-{2194,3189,0,0,0}-{2196,3187,0,0,0}-{2196,3189,0,0,0}-{2206,3164,0,0,0}-{2209,3164,0,0,0}-{2216,3142,0,0,0}-{2218,3139,0,0,0}-{2178,3238,0,0,0}-{2208,3225,0,0,0}-{2210,3217,0,0,0}-{2213,3243,0,0,0}-{2218,3245,0,0,0}-{2220,3243,0,0,0}-{2221,3243,0,0,0}-{2695,6170,0,0,0}-{2697,6171,0,0,0}-{2697,6202,0,0,0}-{2699,6204,0,0,0}-{2707,6155,0,0,0}-{2715,6167,0,0,0}-{2715,6169,0,0,0}-{2746,6206,0,0,0}-{2729,6086,0,0,0}-{2731,6080,0,0,0}-{2731,6089,0,0,0}-{2744,6139,0,0,0}-{3271,5978,0,0,0}-{3273,5979,0,0,0}-{3273,6010,0,0,0}-{3275,6012,0,0,0}-{3283,5963,0,0,0}-{3291,5975,0,0,0}-{3291,5977,0,0,0}-{3322,6014,0,0,0}-{2281,3142,0,0,0}-{2283,3136,0,0,0}-{2283,3145,0,0,0}-{2296,3195,0,0,0}-" "loc_data": "{2194,3189,0,0,0}-{2196,3187,0,0,0}-{2196,3189,0,0,0}-{2206,3164,0,0,0}-{2209,3164,0,0,0}-{2216,3142,0,0,0}-{2218,3139,0,0,0}-{2178,3238,0,0,0}-{2208,3225,0,0,0}-{2210,3217,0,0,0}-{2213,3243,0,0,0}-{2218,3245,0,0,0}-{2220,3243,0,0,0}-{2221,3243,0,0,0}-{3202,5990,0,0,0}-{3232,5977,0,0,0}-{3234,5969,0,0,0}-{3237,5995,0,0,0}-{3242,5997,0,0,0}-{3244,5995,0,0,0}-{3245,5995,0,0,0}-{2729,6086,0,0,0}-{2731,6080,0,0,0}-{2731,6089,0,0,0}-{2744,6139,0,0,0}-{2695,6170,0,0,0}-{2697,6171,0,0,0}-{2697,6202,0,0,0}-{2699,6204,0,0,0}-{2707,6155,0,0,0}-{2715,6167,0,0,0}-{2715,6169,0,0,0}-{2746,6206,0,0,0}-{2281,3142,0,0,0}-{2283,3136,0,0,0}-{2283,3145,0,0,0}-{2296,3195,0,0,0}-{2247,3226,0,0,0}-{2249,3227,0,0,0}-{2249,3258,0,0,0}-{2251,3260,0,0,0}-{2259,3211,0,0,0}-{2267,3223,0,0,0}-{2267,3225,0,0,0}-{2298,3262,0,0,0}-{3271,5978,0,0,0}-{3273,5979,0,0,0}-{3273,6010,0,0,0}-{3275,6012,0,0,0}-{3283,5963,0,0,0}-{3291,5975,0,0,0}-{3291,5977,0,0,0}-{3322,6014,0,0,0}-"
}, },
{ {
"npc_id": "1213", "npc_id": "1213",
"loc_data": "{2248,3225,0,0,0}-{2248,3227,0,0,0}-{2251,3257,0,0,0}-{2253,3259,0,0,0}-{2268,3224,0,0,0}-{2291,3262,0,0,0}-{3204,5988,0,0,0}-{3232,5979,0,0,0}-{3234,5967,0,0,0}-{3234,5976,0,0,0}-{3238,5996,0,0,0}-{3239,5997,0,0,0}-{3243,5996,0,0,0}-{2192,3188,0,0,0}-{2192,3191,0,0,0}-{2194,3190,0,0,0}-{2208,3163,0,0,0}-{2209,3163,0,0,0}-{2216,3136,0,0,0}-{2216,3140,0,0,0}-{2180,3236,0,0,0}-{2208,3227,0,0,0}-{2210,3215,0,0,0}-{2210,3224,0,0,0}-{2214,3244,0,0,0}-{2215,3245,0,0,0}-{2219,3244,0,0,0}-{2696,6169,0,0,0}-{2696,6171,0,0,0}-{2699,6201,0,0,0}-{2701,6203,0,0,0}-{2716,6168,0,0,0}-{2739,6206,0,0,0}-{2730,6084,0,0,0}-{3272,5977,0,0,0}-{3272,5979,0,0,0}-{3275,6009,0,0,0}-{3277,6011,0,0,0}-{3292,5976,0,0,0}-{3315,6014,0,0,0}-{2282,3140,0,0,0}-" "loc_data": "{2192,3188,0,0,0}-{2192,3191,0,0,0}-{2194,3190,0,0,0}-{2208,3163,0,0,0}-{2209,3163,0,0,0}-{2216,3136,0,0,0}-{2216,3140,0,0,0}-{2180,3236,0,0,0}-{2208,3227,0,0,0}-{2210,3215,0,0,0}-{2210,3224,0,0,0}-{2214,3244,0,0,0}-{2215,3245,0,0,0}-{2219,3244,0,0,0}-{3204,5988,0,0,0}-{3232,5979,0,0,0}-{3234,5967,0,0,0}-{3234,5976,0,0,0}-{3238,5996,0,0,0}-{3239,5997,0,0,0}-{3243,5996,0,0,0}-{2730,6084,0,0,0}-{2696,6169,0,0,0}-{2696,6171,0,0,0}-{2699,6201,0,0,0}-{2701,6203,0,0,0}-{2716,6168,0,0,0}-{2739,6206,0,0,0}-{2282,3140,0,0,0}-{2248,3225,0,0,0}-{2248,3227,0,0,0}-{2251,3257,0,0,0}-{2253,3259,0,0,0}-{2268,3224,0,0,0}-{2291,3262,0,0,0}-{3272,5977,0,0,0}-{3272,5979,0,0,0}-{3275,6009,0,0,0}-{3277,6011,0,0,0}-{3292,5976,0,0,0}-{3315,6014,0,0,0}-"
}, },
{ {
"npc_id": "1214", "npc_id": "1214",
@ -3353,7 +3405,7 @@
}, },
{ {
"npc_id": "1227", "npc_id": "1227",
"loc_data": "{3424,3318,0,1,0}-{3423,3312,0,1,4}-{3494,3388,0,1,0}-{3507,3435,0,1,4}-{3511,3455,0,1,0}-{3508,3420,0,1,3}-{3508,3420,0,1,4}-{3506,3402,0,1,7}-{3502,3392,0,1,3}-{3484,3456,0,1,0}-{3486,3458,0,1,4}-" "loc_data": "{3424,3318,0,1,0}-{3423,3312,0,1,4}-{3426,3381,0,1,0}-{3418,3375,0,1,0}-{3414,3363,0,1,0}-{3411,3358,0,1,0}-{3441,3356,0,1,0}-{3424,3426,0,1,0}-{3414,3413,0,1,0}-{3421,3408,0,1,0}-{3422,3408,0,1,0}-{3440,3406,0,1,0}-{3412,3392,0,1,0}-{3494,3388,0,1,0}-{3467,3346,0,1,0}-{3465,3347,0,1,0}-{3507,3435,0,1,4}-{3511,3455,0,1,0}-{3508,3420,0,1,3}-{3508,3420,0,1,4}-{3506,3402,0,1,7}-{3502,3392,0,1,3}-{3481,3446,0,1,0}-{3480,3445,0,1,0}-{3479,3443,0,1,0}-{3471,3433,0,1,0}-{3459,3432,0,1,0}-{3459,3426,0,1,0}-{3459,3418,0,1,0}-{3456,3415,0,1,0}-{3484,3456,0,1,0}-{3486,3458,0,1,4}-{3563,3441,0,1,0}-{3544,3430,0,1,0}-{3540,3413,0,1,0}-{3529,3441,0,1,0}-"
}, },
{ {
"npc_id": "1228", "npc_id": "1228",
@ -3361,11 +3413,11 @@
}, },
{ {
"npc_id": "1229", "npc_id": "1229",
"loc_data": "{3421,3302,0,1,4}-{3417,3291,0,1,4}-{3423,3288,0,1,4}-{3418,3284,0,1,6}-{3427,3298,0,1,3}-{3431,3303,0,1,1}-{3432,3311,0,1,1}-{3502,3455,0,1,2}-{3516,3415,0,1,4}-{3511,3401,0,1,1}-{3492,3457,0,1,1}-" "loc_data": "{3421,3302,0,1,4}-{3417,3291,0,1,4}-{3423,3288,0,1,4}-{3418,3284,0,1,6}-{3427,3298,0,1,3}-{3431,3303,0,1,1}-{3432,3311,0,1,1}-{3427,3376,0,1,0}-{3420,3407,0,1,0}-{3425,3403,0,1,0}-{3438,3399,0,1,0}-{3446,3406,0,1,0}-{3420,3426,0,1,0}-{3477,3368,0,1,0}-{3479,3367,0,1,0}-{3502,3455,0,1,2}-{3516,3415,0,1,4}-{3511,3401,0,1,1}-{3484,3443,0,1,0}-{3483,3442,0,1,0}-{3457,3416,0,1,0}-{3469,3402,0,1,0}-{3471,3401,0,1,0}-{3492,3457,0,1,1}-"
}, },
{ {
"npc_id": "1230", "npc_id": "1230",
"loc_data": "{3419,3280,0,1,4}-{3421,3277,0,1,4}-{3431,3275,0,1,3}-{3428,3314,0,1,1}-{3436,3318,0,1,5}-{3434,3322,0,1,6}-{3496,3447,0,1,7}-{3520,3437,0,1,4}-" "loc_data": "{3419,3280,0,1,4}-{3421,3277,0,1,4}-{3431,3275,0,1,3}-{3428,3314,0,1,1}-{3436,3318,0,1,5}-{3434,3322,0,1,6}-{3476,3350,0,1,0}-{3496,3447,0,1,7}-{3481,3442,0,1,0}-{3520,3437,0,1,4}-"
}, },
{ {
"npc_id": "1231", "npc_id": "1231",
@ -3373,7 +3425,7 @@
}, },
{ {
"npc_id": "1232", "npc_id": "1232",
"loc_data": "{3441,3265,0,1,5}-{3438,3277,0,1,7}-{3438,3283,0,1,4}-{3439,3315,0,1,3}-{3439,3310,0,1,1}-{3435,3302,0,1,3}-{3508,3420,0,1,1}-{3514,3415,0,1,7}-{3525,3417,0,1,3}-" "loc_data": "{3441,3265,0,1,5}-{3438,3277,0,1,7}-{3438,3283,0,1,4}-{3439,3315,0,1,3}-{3439,3310,0,1,1}-{3435,3302,0,1,3}-{3411,3362,0,1,0}-{3415,3365,0,1,0}-{3415,3371,0,1,0}-{3413,3373,0,1,0}-{3431,3383,0,1,0}-{3508,3420,0,1,1}-{3514,3415,0,1,7}-{3470,3400,0,1,0}-{3464,3405,0,1,0}-{3474,3417,0,1,0}-{3474,3419,0,1,0}-{3477,3419,0,1,0}-{3480,3441,0,1,0}-{3525,3417,0,1,3}-"
}, },
{ {
"npc_id": "1233", "npc_id": "1233",
@ -3381,7 +3433,7 @@
}, },
{ {
"npc_id": "1234", "npc_id": "1234",
"loc_data": "{3446,3282,0,1,1}-{3446,3298,0,1,3}-{3449,3304,0,1,1}-{3513,3383,0,1,0}-{3491,3388,0,1,3}-{3493,3454,0,1,2}-{3493,3454,0,1,0}-{3518,3454,0,1,2}-{3519,3441,0,1,7}-{3506,3417,0,1,5}-{3519,3401,0,1,2}-{3499,3420,0,1,3}-{3516,3410,0,1,7}-{3520,3412,0,1,0}-" "loc_data": "{3446,3282,0,1,1}-{3446,3298,0,1,3}-{3449,3304,0,1,1}-{3409,3387,0,1,0}-{3424,3377,0,1,0}-{3438,3351,0,1,0}-{3513,3383,0,1,0}-{3491,3388,0,1,3}-{3461,3355,0,1,0}-{3473,3348,0,1,0}-{3477,3367,0,1,0}-{3493,3454,0,1,2}-{3493,3454,0,1,0}-{3518,3454,0,1,2}-{3519,3441,0,1,7}-{3506,3417,0,1,5}-{3519,3401,0,1,2}-{3499,3420,0,1,3}-{3516,3410,0,1,7}-{3483,3444,0,1,0}-{3479,3423,0,1,0}-{3466,3408,0,1,0}-{3466,3407,0,1,0}-{3520,3412,0,1,0}-"
}, },
{ {
"npc_id": "1235", "npc_id": "1235",
@ -3739,6 +3791,10 @@
"npc_id": "1427", "npc_id": "1427",
"loc_data": "{2957,3025,0,0,0}-" "loc_data": "{2957,3025,0,0,0}-"
}, },
{
"npc_id": "1433",
"loc_data": "{2770,2789,0,1,6}-"
},
{ {
"npc_id": "1434", "npc_id": "1434",
"loc_data": "{2753,2770,0,1,6}-" "loc_data": "{2753,2770,0,1,6}-"
@ -4025,7 +4081,7 @@
}, },
{ {
"npc_id": "1633", "npc_id": "1633",
"loc_data": "{1837,3244,0,1,0}-{1836,3250,0,1,0}-{1845,3251,0,1,0}-{1845,3247,0,1,0}-{1849,3241,0,1,0}-{1853,3247,0,1,0}-{1848,3254,0,1,0}-{1858,3251,0,1,0}-{1935,3217,0,1,0}-{1933,3209,0,1,0}-{1930,3208,0,1,0}-{1929,3217,0,1,0}-{1927,3219,0,1,0}-{1924,3211,0,1,0}-{1920,3216,0,1,0}-{1925,3213,0,1,0}-{3263,9399,0,1,3}-{3274,9397,0,1,1}-{3275,9393,0,1,6}-{3271,9384,0,1,0}-{3270,9380,0,1,2}-{3283,9378,0,1,6}-{3285,9386,0,1,5}-{3284,9401,0,1,4}-{3278,9353,0,1,1}-{3299,9380,0,1,1}-{3319,9402,0,1,1}-{3305,9350,0,1,4}-{3248,9374,0,1,3}-{3253,9363,0,1,3}-{3249,9355,0,1,3}-{2761,10007,0,1,0}-{2757,10010,0,1,3}-{2763,10000,0,1,5}-{2760,10011,0,1,0}-{2761,9997,0,1,4}-" "loc_data": "{1837,3244,0,1,0}-{1836,3250,0,1,0}-{1845,3251,0,1,0}-{1845,3247,0,1,0}-{1849,3241,0,1,0}-{1853,3247,0,1,0}-{1848,3254,0,1,0}-{1858,3251,0,1,0}-{1935,3217,0,1,0}-{1933,3209,0,1,0}-{1930,3208,0,1,0}-{1929,3217,0,1,0}-{1927,3219,0,1,0}-{1924,3211,0,1,0}-{1920,3216,0,1,0}-{1925,3213,0,1,0}-{3263,9399,0,1,3}-{3248,9374,0,1,3}-{3253,9363,0,1,3}-{3249,9355,0,1,3}-{3274,9397,0,1,1}-{3275,9393,0,1,6}-{3271,9384,0,1,0}-{3270,9380,0,1,2}-{3283,9378,0,1,6}-{3285,9386,0,1,5}-{3284,9401,0,1,4}-{3278,9353,0,1,1}-{3299,9380,0,1,1}-{3319,9402,0,1,1}-{3305,9350,0,1,4}-{2761,10007,0,1,0}-{2757,10010,0,1,3}-{2763,10000,0,1,5}-{2760,10011,0,1,0}-{2761,9997,0,1,4}-"
}, },
{ {
"npc_id": "1634", "npc_id": "1634",
@ -4225,7 +4281,7 @@
}, },
{ {
"npc_id": "1752", "npc_id": "1752",
"loc_data": "{2437,3442,0,1,0}-{2449,3421,0,1,0}-{2457,3394,0,1,0}-{2464,3394,0,1,0}-{2480,3406,0,1,0}-{2432,3387,0,1,0}-{2442,3388,0,1,0}-{2453,3363,0,1,0}-{2463,3375,0,1,0}-{2381,3428,0,1,0}-{2392,3405,0,1,0}-{2413,3397,0,1,0}-{2415,3408,0,1,0}-{2463,3456,0,1,0}-{2468,3456,0,1,0}-" "loc_data": "{2381,3428,0,1,0}-{2392,3405,0,1,0}-{2413,3397,0,1,0}-{2415,3408,0,1,0}-{2432,3387,0,1,0}-{2442,3388,0,1,0}-{2453,3363,0,1,0}-{2463,3375,0,1,0}-{2437,3442,0,1,0}-{2449,3421,0,1,0}-{2457,3394,0,1,0}-{2464,3394,0,1,0}-{2480,3406,0,1,0}-{2463,3456,0,1,0}-{2468,3456,0,1,0}-"
}, },
{ {
"npc_id": "1754", "npc_id": "1754",
@ -4509,7 +4565,7 @@
}, },
{ {
"npc_id": "1874", "npc_id": "1874",
"loc_data": "{3371,9301,0,1,0}-{3371,9303,0,1,0}-{3371,9305,0,1,0}-{3371,9307,0,1,0}-{3371,9309,0,1,0}-{3373,9301,0,1,0}-{3373,9303,0,1,0}-{3373,9306,0,1,0}-{3373,9308,0,1,0}-{3375,9301,0,1,0}-{3375,9303,0,1,0}-{3375,9305,0,1,0}-{3375,9307,0,1,0}-{3375,9309,0,1,0}-{3403,2963,0,1,0}-{3429,2976,0,1,0}-{3328,2952,0,1,0}-{3328,2957,0,1,0}-{3331,2955,0,1,0}-{3331,2961,0,1,0}-{3266,2955,0,1,0}-{3271,2967,0,1,0}-{3279,2957,0,1,0}-{3280,2975,0,1,0}-{3284,2959,0,1,0}-{3294,2964,0,1,0}-{3295,2978,0,1,0}-{3305,2966,0,1,0}-{3307,2959,0,1,0}-{3309,2973,0,1,0}-{3396,3029,0,1,0}-{3397,3044,0,1,0}-{3398,3038,0,1,0}-" "loc_data": "{3328,2952,0,1,0}-{3328,2957,0,1,0}-{3331,2955,0,1,0}-{3331,2961,0,1,0}-{3371,9301,0,1,0}-{3371,9303,0,1,0}-{3371,9305,0,1,0}-{3371,9307,0,1,0}-{3371,9309,0,1,0}-{3373,9301,0,1,0}-{3373,9303,0,1,0}-{3373,9306,0,1,0}-{3373,9308,0,1,0}-{3375,9301,0,1,0}-{3375,9303,0,1,0}-{3375,9305,0,1,0}-{3375,9307,0,1,0}-{3375,9309,0,1,0}-{3403,2963,0,1,0}-{3429,2976,0,1,0}-{3396,3029,0,1,0}-{3397,3044,0,1,0}-{3398,3038,0,1,0}-{3266,2955,0,1,0}-{3271,2967,0,1,0}-{3279,2957,0,1,0}-{3280,2975,0,1,0}-{3284,2959,0,1,0}-{3294,2964,0,1,0}-{3295,2978,0,1,0}-{3305,2966,0,1,0}-{3307,2959,0,1,0}-{3309,2973,0,1,0}-"
}, },
{ {
"npc_id": "1875", "npc_id": "1875",
@ -4669,19 +4725,19 @@
}, },
{ {
"npc_id": "1961", "npc_id": "1961",
"loc_data": "{3156,5477,0,1,5}-{3162,5479,0,1,4}-{3159,5477,0,1,6}-{3150,5474,0,1,3}-{3147,5480,0,1,1}-{3159,5484,0,1,3}-{2764,4944,1,1,0}-{2796,4976,1,1,0}-{2798,4950,1,1,0}-{2806,4939,1,1,0}-{2832,4959,2,1,0}-{3201,9293,0,1,0}-{3205,9303,0,1,0}-{3206,9328,0,1,0}-{3207,9310,0,1,0}-{3211,9284,0,1,0}-{3220,9289,0,1,0}-{3224,9334,0,1,0}-{3249,9286,0,1,0}-{3251,9303,0,1,0}-{3252,9327,0,1,0}-{3252,9332,0,1,0}-{3255,9315,0,1,0}-{3261,9296,0,1,0}-{3261,9306,0,1,0}-" "loc_data": "{2832,4959,2,1,0}-{3156,5477,0,1,5}-{3162,5479,0,1,4}-{3159,5477,0,1,6}-{3150,5474,0,1,3}-{3147,5480,0,1,1}-{3159,5484,0,1,3}-{3201,9293,0,1,0}-{3205,9303,0,1,0}-{3206,9328,0,1,0}-{3207,9310,0,1,0}-{3211,9284,0,1,0}-{3220,9289,0,1,0}-{3224,9334,0,1,0}-{3249,9286,0,1,0}-{3251,9303,0,1,0}-{3252,9327,0,1,0}-{3252,9332,0,1,0}-{3255,9315,0,1,0}-{3261,9296,0,1,0}-{3261,9306,0,1,0}-{2764,4944,1,1,0}-{2796,4976,1,1,0}-{2798,4950,1,1,0}-{2806,4939,1,1,0}-"
}, },
{ {
"npc_id": "1962", "npc_id": "1962",
"loc_data": "{3168,5458,0,1,2}-{2900,4948,3,1,0}-{2762,4962,1,1,0}-{2763,4973,1,1,0}-{2780,4977,1,1,0}-{2787,4967,1,1,0}-{2796,4959,1,1,0}-{2838,4948,2,1,0}-{3205,9329,0,1,0}-{3210,9292,0,1,0}-{3221,9310,0,1,0}-{3225,9323,0,1,0}-{3243,9310,0,1,0}-{3246,9290,0,1,0}-{3255,9301,0,1,0}-{3255,9321,0,1,0}-{3261,9331,0,1,0}-" "loc_data": "{2838,4948,2,1,0}-{2900,4948,3,1,0}-{3168,5458,0,1,2}-{3205,9329,0,1,0}-{3210,9292,0,1,0}-{3221,9310,0,1,0}-{3225,9323,0,1,0}-{3243,9310,0,1,0}-{3246,9290,0,1,0}-{3255,9301,0,1,0}-{3255,9321,0,1,0}-{3261,9331,0,1,0}-{2762,4962,1,1,0}-{2763,4973,1,1,0}-{2780,4977,1,1,0}-{2787,4967,1,1,0}-{2796,4959,1,1,0}-"
}, },
{ {
"npc_id": "1963", "npc_id": "1963",
"loc_data": "{3166,5465,0,1,7}-{3168,5462,0,1,0}-{3167,5467,0,1,1}-{3167,5467,0,1,7}-{2926,4965,3,1,0}-{2771,4947,1,1,0}-{2775,4963,1,1,0}-{2781,4948,1,1,0}-{2792,4942,1,1,0}-{2798,4954,1,1,0}-{2858,4964,2,1,0}-{3204,9309,0,1,0}-{3214,9333,0,1,0}-{3219,9297,0,1,0}-{3239,9300,0,1,0}-{3240,9286,0,1,0}-{3240,9330,0,1,0}-{3245,9306,0,1,0}-{3250,9316,0,1,0}-{3250,9317,0,1,0}-{3257,9290,0,1,0}-" "loc_data": "{2858,4964,2,1,0}-{2926,4965,3,1,0}-{3166,5465,0,1,7}-{3168,5462,0,1,0}-{3167,5467,0,1,1}-{3167,5467,0,1,7}-{3204,9309,0,1,0}-{3214,9333,0,1,0}-{3219,9297,0,1,0}-{3239,9300,0,1,0}-{3240,9286,0,1,0}-{3240,9330,0,1,0}-{3245,9306,0,1,0}-{3250,9316,0,1,0}-{3250,9317,0,1,0}-{3257,9290,0,1,0}-{2771,4947,1,1,0}-{2775,4963,1,1,0}-{2781,4948,1,1,0}-{2792,4942,1,1,0}-{2798,4954,1,1,0}-"
}, },
{ {
"npc_id": "1964", "npc_id": "1964",
"loc_data": "{2761,4950,1,1,0}-{2765,4938,1,1,0}-{2770,4955,1,1,0}-{2772,4940,1,1,0}-{2777,4943,1,1,0}-{2782,4967,1,1,0}-{2797,4965,1,1,0}-{2799,4937,1,1,0}-{2799,4941,1,1,0}-{2807,4968,1,1,0}-{2808,4975,1,1,0}-{2809,4953,1,1,0}-{2864,4946,2,1,0}-{3202,9283,0,1,0}-{3206,9333,0,1,0}-{3209,9299,0,1,0}-{3219,9301,0,1,0}-{3226,9285,0,1,0}-{3227,9303,0,1,0}-{3228,9293,0,1,0}-{3229,9333,0,1,0}-{3237,9293,0,1,0}-{3246,9321,0,1,0}-{3256,9296,0,1,0}-{3260,9285,0,1,0}-{3262,9317,0,1,0}-" "loc_data": "{2864,4946,2,1,0}-{3202,9283,0,1,0}-{3206,9333,0,1,0}-{3209,9299,0,1,0}-{3219,9301,0,1,0}-{3226,9285,0,1,0}-{3227,9303,0,1,0}-{3228,9293,0,1,0}-{3229,9333,0,1,0}-{3237,9293,0,1,0}-{3246,9321,0,1,0}-{3256,9296,0,1,0}-{3260,9285,0,1,0}-{3262,9317,0,1,0}-{2761,4950,1,1,0}-{2765,4938,1,1,0}-{2770,4955,1,1,0}-{2772,4940,1,1,0}-{2777,4943,1,1,0}-{2782,4967,1,1,0}-{2797,4965,1,1,0}-{2799,4937,1,1,0}-{2799,4941,1,1,0}-{2807,4968,1,1,0}-{2808,4975,1,1,0}-{2809,4953,1,1,0}-"
}, },
{ {
"npc_id": "1970", "npc_id": "1970",
@ -4693,7 +4749,7 @@
}, },
{ {
"npc_id": "1973", "npc_id": "1973",
"loc_data": "{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-" "loc_data": "{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-"
}, },
{ {
"npc_id": "1976", "npc_id": "1976",
@ -4705,11 +4761,11 @@
}, },
{ {
"npc_id": "1993", "npc_id": "1993",
"loc_data": "{3264,2886,0,1,0}-{3267,2891,0,1,0}-{3268,2881,0,1,0}-{3269,2885,0,1,0}-{3296,2912,0,1,0}-{3297,2919,0,1,0}-{3301,2920,0,1,0}-{3308,2916,0,1,0}-{3258,2868,0,1,0}-{3259,2823,0,1,0}-{3259,2845,0,1,0}-{3260,2830,0,1,0}-{3260,2859,0,1,0}-{3261,2819,0,1,0}-{3261,2851,0,1,0}-{3337,2922,0,1,0}-{3343,2931,0,1,0}-{3349,2922,0,1,0}-{3351,2927,0,1,0}-{3357,2922,0,1,0}-{3359,2927,0,1,0}-{3364,2937,0,1,0}-{3268,2854,0,1,0}-{3269,2827,0,1,0}-{3269,2866,0,1,0}-{3269,2875,0,1,0}-{3270,2818,0,1,0}-{3272,2841,0,1,0}-{3276,2842,0,1,0}-{3282,2839,0,1,0}-{3290,2847,0,1,0}-" "loc_data": "{3337,2922,0,1,0}-{3343,2931,0,1,0}-{3349,2922,0,1,0}-{3351,2927,0,1,0}-{3357,2922,0,1,0}-{3359,2927,0,1,0}-{3364,2937,0,1,0}-{3258,2868,0,1,0}-{3259,2823,0,1,0}-{3259,2845,0,1,0}-{3260,2830,0,1,0}-{3260,2859,0,1,0}-{3261,2819,0,1,0}-{3261,2851,0,1,0}-{3268,2854,0,1,0}-{3269,2827,0,1,0}-{3269,2866,0,1,0}-{3269,2875,0,1,0}-{3270,2818,0,1,0}-{3272,2841,0,1,0}-{3276,2842,0,1,0}-{3282,2839,0,1,0}-{3290,2847,0,1,0}-{3264,2886,0,1,0}-{3267,2891,0,1,0}-{3268,2881,0,1,0}-{3269,2885,0,1,0}-{3296,2912,0,1,0}-{3297,2919,0,1,0}-{3301,2920,0,1,0}-{3308,2916,0,1,0}-"
}, },
{ {
"npc_id": "1994", "npc_id": "1994",
"loc_data": "{3265,2931,0,1,0}-{3265,2935,0,1,0}-{3268,2932,0,1,0}-{3268,2935,0,1,0}-{3316,2900,0,1,0}-{3319,2897,0,1,0}-{3320,2901,0,1,0}-{3321,2899,0,1,0}-{3212,2863,0,1,0}-{3213,2866,0,1,0}-{3215,2863,0,1,0}-{3216,2865,0,1,0}-{3216,2868,0,1,0}-{3218,2831,0,1,0}-{3220,2830,0,1,0}-{3220,2833,0,1,0}-{3221,2831,0,1,0}-{3238,2845,0,1,0}-{3240,2845,0,1,0}-{3241,2843,0,1,0}-{3241,2847,0,1,0}-{3400,2997,0,1,0}-{3402,2999,0,1,0}-{3403,2997,0,1,0}-{3445,2993,0,1,0}-{3446,2992,0,1,0}-{3448,2991,0,1,0}-{3448,2994,0,1,0}-{3329,2933,0,1,0}-{3330,2931,0,1,0}-{3331,2933,0,1,0}-{3343,2895,0,1,0}-{3345,2896,0,1,0}-{3346,2894,0,1,0}-{3348,2894,0,1,0}-{3376,2934,0,1,0}-{3378,2933,0,1,0}-{3378,2935,0,1,0}-{3381,2907,0,1,0}-{3383,2905,0,1,0}-{3383,2908,0,1,0}-{3384,2907,0,1,0}-{3306,2817,0,1,0}-{3308,2818,0,1,0}-{3309,2816,0,1,0}-{3312,2817,0,1,0}-{3314,2861,0,1,0}-{3319,2873,0,1,0}-{3321,2871,0,1,0}-{3324,2870,0,1,0}-{3327,2858,0,1,0}-{3406,3014,0,1,0}-{3408,3013,0,1,0}-{3408,3016,0,1,0}-{3410,3015,0,1,0}-" "loc_data": "{3329,2933,0,1,0}-{3330,2931,0,1,0}-{3331,2933,0,1,0}-{3343,2895,0,1,0}-{3345,2896,0,1,0}-{3346,2894,0,1,0}-{3348,2894,0,1,0}-{3376,2934,0,1,0}-{3378,2933,0,1,0}-{3378,2935,0,1,0}-{3381,2907,0,1,0}-{3383,2905,0,1,0}-{3383,2908,0,1,0}-{3384,2907,0,1,0}-{3400,2997,0,1,0}-{3402,2999,0,1,0}-{3403,2997,0,1,0}-{3445,2993,0,1,0}-{3446,2992,0,1,0}-{3448,2991,0,1,0}-{3448,2994,0,1,0}-{3406,3014,0,1,0}-{3408,3013,0,1,0}-{3408,3016,0,1,0}-{3410,3015,0,1,0}-{3212,2863,0,1,0}-{3213,2866,0,1,0}-{3215,2863,0,1,0}-{3216,2865,0,1,0}-{3216,2868,0,1,0}-{3218,2831,0,1,0}-{3220,2830,0,1,0}-{3220,2833,0,1,0}-{3221,2831,0,1,0}-{3238,2845,0,1,0}-{3240,2845,0,1,0}-{3241,2843,0,1,0}-{3241,2847,0,1,0}-{3306,2817,0,1,0}-{3308,2818,0,1,0}-{3309,2816,0,1,0}-{3312,2817,0,1,0}-{3314,2861,0,1,0}-{3319,2873,0,1,0}-{3321,2871,0,1,0}-{3324,2870,0,1,0}-{3327,2858,0,1,0}-{3265,2931,0,1,0}-{3265,2935,0,1,0}-{3268,2932,0,1,0}-{3268,2935,0,1,0}-{3316,2900,0,1,0}-{3319,2897,0,1,0}-{3320,2901,0,1,0}-{3321,2899,0,1,0}-"
}, },
{ {
"npc_id": "1995", "npc_id": "1995",
@ -4861,7 +4917,11 @@
}, },
{ {
"npc_id": "2057", "npc_id": "2057",
"loc_data": "{2442,9436,2,1,0}-{2458,9413,2,1,0}-{2470,9435,2,1,0}-{2472,9460,2,1,0}-{2483,9413,2,1,0}-{2485,9447,2,1,0}-{2480,3046,0,1,0}-{2453,9393,2,1,0}-{2461,9403,2,1,0}-{2464,9380,2,1,0}-" "loc_data": "{2480,3046,0,1,0}-{2453,9393,2,1,0}-{2461,9403,2,1,0}-{2464,9380,2,1,0}-{2442,9436,2,1,0}-{2458,9413,2,1,0}-{2470,9435,2,1,0}-{2472,9460,2,1,0}-{2483,9413,2,1,0}-{2485,9447,2,1,0}-"
},
{
"npc_id": "2058",
"loc_data": "{3161,9547,0,0,7}-{3164,9556,0,0,7}-{3162,9574,0,0,7}-{3198,9554,0,0,7}-{3198,9572,0,0,7}-{3215,9560,0,0,7}-{3216,9588,0,0,7}-"
}, },
{ {
"npc_id": "2059", "npc_id": "2059",
@ -5329,7 +5389,7 @@
}, },
{ {
"npc_id": "2265", "npc_id": "2265",
"loc_data": "{3038,4809,0,1,6}-{3024,4850,0,1,3}-{3052,4808,0,1,5}-{3021,4847,0,1,3}-{3058,4811,0,1,4}-{3055,4848,0,1,0}-{3062,4822,0,1,6}-{3017,4837,0,1,3}-{3017,4817,0,1,7}-{3025,4812,0,1,1}-{3060,4825,0,1,3}-{3062,4838,0,1,3}-{3054,4850,0,1,6}-{3020,4914,0,1,2}-{3059,4890,0,1,3}-{3031,4901,0,1,7}-{3044,4915,0,1,6}-{3044,4883,0,1,4}-{3039,4885,0,1,1}-{3048,4917,0,1,5}-{3059,4888,0,1,5}-{3047,4874,0,1,2}-{3055,4908,0,1,5}-{3016,4876,0,1,1}-{3029,4890,0,1,5}-{3059,4906,0,1,1}-{3021,4875,0,1,3}-{3032,4903,0,1,3}-{3026,4914,0,1,6}-" "loc_data": "{3038,4809,0,1,6}-{3024,4850,0,1,3}-{3052,4808,0,1,5}-{3021,4847,0,1,3}-{3058,4811,0,1,4}-{3055,4848,0,1,0}-{3062,4822,0,1,6}-{3017,4837,0,1,3}-{3017,4817,0,1,7}-{3025,4812,0,1,1}-{3060,4825,0,1,3}-{3062,4838,0,1,3}-{3054,4850,0,1,6}-{3020,4914,0,1,2}-{3059,4890,0,1,3}-{3031,4901,0,1,7}-{3044,4915,0,1,6}-{3044,4883,0,1,4}-{3039,4885,0,1,1}-{3048,4917,0,1,5}-{3059,4888,0,1,5}-{3047,4874,0,1,2}-{3055,4908,0,1,5}-{3017,4876,0,1,1}-{3029,4890,0,1,5}-{3059,4906,0,1,1}-{3021,4875,0,1,3}-{3032,4903,0,1,3}-{3026,4914,0,1,6}-"
}, },
{ {
"npc_id": "2266", "npc_id": "2266",
@ -5503,6 +5563,10 @@
"npc_id": "2321", "npc_id": "2321",
"loc_data": "{2915,10194,1,1,0}-" "loc_data": "{2915,10194,1,1,0}-"
}, },
{
"npc_id": "2322",
"loc_data": "{3679,9957,0,1,1}-"
},
{ {
"npc_id": "2323", "npc_id": "2323",
"loc_data": "{3056,3306,0,1,1}-" "loc_data": "{3056,3306,0,1,1}-"
@ -5545,7 +5609,7 @@
}, },
{ {
"npc_id": "2335", "npc_id": "2335",
"loc_data": "{3181,3359,0,0,0}-" "loc_data": "{3181,3359,0,1,0}-"
}, },
{ {
"npc_id": "2336", "npc_id": "2336",
@ -5799,14 +5863,6 @@
"npc_id": "2488", "npc_id": "2488",
"loc_data": "{2799,3058,0,0,0}-" "loc_data": "{2799,3058,0,0,0}-"
}, },
{
"npc_id": "2489",
"loc_data": "{3703,3040,0,1,3}-{3706,3051,0,1,1}-{3664,3013,0,1,7}-{3749,3000,0,1,6}-{3723,2998,0,1,2}-{3731,2991,0,1,1}-{3775,3033,0,1,4}-{3766,3010,0,1,4}-{3764,3020,0,1,1}-{3738,3010,0,1,3}-{3720,3040,0,1,6}-{3719,3045,0,1,6}-{3781,3031,0,1,5}-{3780,3022,0,1,1}-{3788,3011,0,1,2}-{3793,3019,0,1,5}-{3779,3045,0,1,1}-{3784,3040,0,1,3}-{3802,3037,0,1,2}-{3808,3026,0,1,3}-{3799,3024,0,1,4}-"
},
{
"npc_id": "2490",
"loc_data": "{3782,3016,0,1,7}-"
},
{ {
"npc_id": "2491", "npc_id": "2491",
"loc_data": "{2679,3080,0,1,6}-{2684,3084,0,1,4}-{2682,3093,0,1,4}-{2678,3095,0,1,3}-{2679,3102,0,1,1}-{2681,3110,0,1,4}-{2683,3115,0,1,6}-{2675,3108,0,1,3}-{2671,3109,0,1,3}-{2671,3113,0,1,4}-{2676,3090,0,1,4}-{2670,3088,0,1,6}-{2671,3086,0,1,6}-{2664,3088,0,1,7}-{2660,3086,0,1,6}-{2662,3088,0,1,6}-{2670,3082,0,1,7}-{2674,3081,0,1,3}-{2663,3086,0,1,6}-{2679,3082,0,1,1}-{2682,3093,0,1,3}-" "loc_data": "{2679,3080,0,1,6}-{2684,3084,0,1,4}-{2682,3093,0,1,4}-{2678,3095,0,1,3}-{2679,3102,0,1,1}-{2681,3110,0,1,4}-{2683,3115,0,1,6}-{2675,3108,0,1,3}-{2671,3109,0,1,3}-{2671,3113,0,1,4}-{2676,3090,0,1,4}-{2670,3088,0,1,6}-{2671,3086,0,1,6}-{2664,3088,0,1,7}-{2660,3086,0,1,6}-{2662,3088,0,1,6}-{2670,3082,0,1,7}-{2674,3081,0,1,3}-{2663,3086,0,1,6}-{2679,3082,0,1,1}-{2682,3093,0,1,3}-"
@ -6277,7 +6333,7 @@
}, },
{ {
"npc_id": "2803", "npc_id": "2803",
"loc_data": "{3387,3068,0,1,0}-{3387,3017,0,1,0}-{3404,3062,0,1,0}-{3441,3061,0,1,0}-{3445,3034,0,1,0}-{3338,2804,0,1,0}-{3339,2815,0,1,0}-{3342,2809,0,1,0}-{3344,2800,0,1,0}-{3348,2809,0,1,0}-{3349,2814,0,1,0}-{3357,2813,0,1,0}-{3357,2806,0,1,0}-{3365,2815,0,1,0}-" "loc_data": "{3338,2804,0,1,0}-{3339,2815,0,1,0}-{3342,2809,0,1,0}-{3344,2800,0,1,0}-{3348,2809,0,1,0}-{3349,2814,0,1,0}-{3357,2813,0,1,0}-{3357,2806,0,1,0}-{3365,2815,0,1,0}-{3387,3068,0,1,0}-{3387,3017,0,1,0}-{3404,3062,0,1,0}-{3441,3061,0,1,0}-{3445,3034,0,1,0}-"
}, },
{ {
"npc_id": "2804", "npc_id": "2804",
@ -6727,6 +6783,10 @@
"npc_id": "3205", "npc_id": "3205",
"loc_data": "{3139,3448,0,1,3}-" "loc_data": "{3139,3448,0,1,3}-"
}, },
{
"npc_id": "3207",
"loc_data": "{1970,5002,0,1,4}-"
},
{ {
"npc_id": "3213", "npc_id": "3213",
"loc_data": "{2568,3334,0,1,0}-" "loc_data": "{2568,3334,0,1,0}-"
@ -6987,6 +7047,10 @@
"npc_id": "3288", "npc_id": "3288",
"loc_data": "{2987,3446,0,1,7}-{3034,3437,0,1,0}-" "loc_data": "{2987,3446,0,1,7}-{3034,3437,0,1,0}-"
}, },
{
"npc_id": "3293",
"loc_data": "{3113,3369,1,0,0}-{3122,3353,0,0,3}-{3124,3360,0,0,2}-{3115,3362,0,0,1}-"
},
{ {
"npc_id": "3294", "npc_id": "3294",
"loc_data": "{3014,3339,0,1,2}-" "loc_data": "{3014,3339,0,1,2}-"
@ -7189,7 +7253,7 @@
}, },
{ {
"npc_id": "3675", "npc_id": "3675",
"loc_data": "{3333,2864,0,1,1}-{3335,2860,0,1,2}-{3338,2864,0,1,4}-{3215,2841,0,1,0}-{3217,2845,0,1,0}-{3220,2841,0,1,0}-{3295,2866,0,1,0}-{3297,2863,0,1,0}-{3301,2864,0,1,0}-{3336,2778,0,1,0}-{3343,2793,0,1,0}-{3367,2791,0,1,0}-" "loc_data": "{3336,2778,0,1,0}-{3343,2793,0,1,0}-{3367,2791,0,1,0}-{3333,2864,0,1,1}-{3335,2860,0,1,2}-{3338,2864,0,1,4}-{3215,2841,0,1,0}-{3217,2845,0,1,0}-{3220,2841,0,1,0}-{3295,2866,0,1,0}-{3297,2863,0,1,0}-{3301,2864,0,1,0}-"
}, },
{ {
"npc_id": "3677", "npc_id": "3677",
@ -7417,7 +7481,7 @@
}, },
{ {
"npc_id": "4246", "npc_id": "4246",
"loc_data": "{3480,3484,1,0,0}-{3479,3484,0,1,3}-" "loc_data": "{3479,3484,0,1,3}-"
}, },
{ {
"npc_id": "4247", "npc_id": "4247",
@ -7551,6 +7615,10 @@
"npc_id": "4317", "npc_id": "4317",
"loc_data": "{3230,3285,0,0,0}-" "loc_data": "{3230,3285,0,0,0}-"
}, },
{
"npc_id": "4343",
"loc_data": "{3706,3051,0,1,6}-{3703,3040,0,1,3}-{3664,3013,0,1,7}-{3731,2991,0,1,1}-{3723,2998,0,1,2}-{3749,3000,0,1,6}-{3775,3033,0,1,4}-{3766,3010,0,1,4}-{3764,3020,0,1,1}-{3738,3010,0,1,3}-{3720,3040,0,1,6}-{3719,3045,0,1,6}-{3781,3031,0,1,5}-{3780,3022,0,1,1}-{3788,3011,0,1,2}-{3793,3019,0,1,5}-{3779,3045,0,1,1}-{3784,3040,0,1,3}-{3802,3037,0,1,2}-{3808,3026,0,1,3}-{3799,3024,0,1,4}-{3782,3016,0,1,7}-"
},
{ {
"npc_id": "4344", "npc_id": "4344",
"loc_data": "{3733,2972,0,1,4}-{3747,3013,0,1,4}-{3766,3034,0,1,6}-" "loc_data": "{3733,2972,0,1,4}-{3747,3013,0,1,4}-{3766,3034,0,1,6}-"
@ -8193,23 +8261,23 @@
}, },
{ {
"npc_id": "4689", "npc_id": "4689",
"loc_data": "{2369,3401,0,1,0}-{2902,9736,0,1,0}-" "loc_data": "{2369,3401,0,1,0}-{2902,9736,0,1,0}-{2440,3213,0,1,0}-"
}, },
{ {
"npc_id": "4690", "npc_id": "4690",
"loc_data": "{2372,3401,0,1,0}-{3104,3875,0,1,2}-{2912,9731,0,1,0}-{3256,3624,0,1,5}-{3308,3661,0,1,2}-" "loc_data": "{3104,3875,0,1,2}-{2372,3401,0,1,0}-{2912,9731,0,1,0}-{2439,3211,0,1,0}-{3256,3624,0,1,5}-{3308,3661,0,1,2}-"
}, },
{ {
"npc_id": "4691", "npc_id": "4691",
"loc_data": "{2371,3398,0,1,0}-{3110,3854,0,1,0}-" "loc_data": "{3110,3854,0,1,0}-{2371,3398,0,1,0}-{2439,3208,0,1,0}-"
}, },
{ {
"npc_id": "4692", "npc_id": "4692",
"loc_data": "{2372,3395,0,1,0}-{3116,3858,0,1,0}-" "loc_data": "{3116,3858,0,1,0}-{2372,3395,0,1,0}-{2442,3210,0,1,0}-"
}, },
{ {
"npc_id": "4693", "npc_id": "4693",
"loc_data": "{2369,3394,0,1,0}-{3094,3849,0,1,0}-{2912,9741,0,1,0}-{2906,9736,0,1,0}-" "loc_data": "{3094,3849,0,1,0}-{2369,3394,0,1,0}-{2912,9741,0,1,0}-{2906,9736,0,1,0}-{2444,3208,0,1,0}-"
}, },
{ {
"npc_id": "4694", "npc_id": "4694",
@ -8961,7 +9029,7 @@
}, },
{ {
"npc_id": "5359", "npc_id": "5359",
"loc_data": "{2693,5065,0,1,0}-{2693,5089,0,1,0}-{2704,5091,0,1,0}-{2710,5095,0,1,0}-{2712,5076,0,1,0}-{2714,5108,0,1,0}-{2716,5092,0,1,0}-{2719,5071,0,1,0}-{2722,5061,0,1,0}-{2732,5087,0,1,0}-{2739,5078,0,1,0}-{2740,5104,0,1,0}-{2747,5083,0,1,0}-{2627,5093,0,1,0}-{2629,5061,0,1,0}-{2638,5090,0,1,0}-{2651,5105,0,1,0}-{2654,5079,0,1,0}-{2663,5116,0,1,0}-{2683,5059,0,1,0}-{2685,5111,0,1,0}-" "loc_data": "{2627,5093,0,1,0}-{2629,5061,0,1,0}-{2638,5090,0,1,0}-{2651,5105,0,1,0}-{2654,5079,0,1,0}-{2663,5116,0,1,0}-{2683,5059,0,1,0}-{2685,5111,0,1,0}-{2693,5065,0,1,0}-{2693,5089,0,1,0}-{2704,5091,0,1,0}-{2710,5095,0,1,0}-{2712,5076,0,1,0}-{2714,5108,0,1,0}-{2716,5092,0,1,0}-{2719,5071,0,1,0}-{2722,5061,0,1,0}-{2732,5087,0,1,0}-{2739,5078,0,1,0}-{2740,5104,0,1,0}-{2747,5083,0,1,0}-"
}, },
{ {
"npc_id": "5361", "npc_id": "5361",
@ -9621,7 +9689,7 @@
}, },
{ {
"npc_id": "5748", "npc_id": "5748",
"loc_data": "{3429,3276,0,0,0}-{3440,3281,0,0,0}-{3437,3272,0,0,0}-{3440,3271,0,0,0}-{3443,3272,0,0,0}-{3445,3279,0,0,0}-{3445,3274,0,0,0}-{3434,3417,0,0,0}-{3431,3415,0,0,0}-{3440,3410,0,0,0}-{3424,3409,0,0,0}-{3425,3410,0,0,0}-{3425,3407,0,0,0}-{3483,3449,0,0,0}-{3490,3444,0,0,0}-{3479,3434,0,0,0}-{3479,3430,0,0,0}-{3481,3473,0,0,0}-" "loc_data": "{3429,3276,0,0,0}-{3440,3281,0,0,0}-{3437,3272,0,0,0}-{3440,3271,0,0,0}-{3443,3272,0,0,0}-{3445,3279,0,0,0}-{3445,3274,0,0,0}-{3434,3417,0,0,0}-{3431,3415,0,0,0}-{3440,3410,0,0,0}-{3424,3409,0,0,0}-{3425,3410,0,0,0}-{3425,3407,0,0,0}-{3483,3449,0,0,0}-{3490,3444,0,0,0}-{3479,3434,0,0,0}-{3479,3430,0,0,0}-"
}, },
{ {
"npc_id": "5750", "npc_id": "5750",
@ -10175,13 +10243,17 @@
"npc_id": "6028", "npc_id": "6028",
"loc_data": "{3497,3497,0,1,2}-" "loc_data": "{3497,3497,0,1,2}-"
}, },
{
"npc_id": "6029",
"loc_data": "{3474,3475,0,1,0}-"
},
{ {
"npc_id": "6030", "npc_id": "6030",
"loc_data": "{3496,3476,0,1,2}-" "loc_data": "{3496,3476,0,1,2}-"
}, },
{ {
"npc_id": "6031", "npc_id": "6031",
"loc_data": "{3511,3482,1,0,0}-" "loc_data": "{3511,3482,0,1,0}-"
}, },
{ {
"npc_id": "6032", "npc_id": "6032",
@ -10201,7 +10273,7 @@
}, },
{ {
"npc_id": "6036", "npc_id": "6036",
"loc_data": "{3499,3474,1,0,0}-" "loc_data": "{3499,3474,1,1,0}-"
}, },
{ {
"npc_id": "6037", "npc_id": "6037",
@ -10209,7 +10281,7 @@
}, },
{ {
"npc_id": "6038", "npc_id": "6038",
"loc_data": "{3490,3472,1,0,0}-" "loc_data": "{3490,3472,1,1,0}-"
}, },
{ {
"npc_id": "6039", "npc_id": "6039",
@ -10217,7 +10289,7 @@
}, },
{ {
"npc_id": "6040", "npc_id": "6040",
"loc_data": "{3498,3472,1,0,0}-" "loc_data": "{3498,3472,1,1,0}-"
}, },
{ {
"npc_id": "6041", "npc_id": "6041",
@ -10225,15 +10297,19 @@
}, },
{ {
"npc_id": "6042", "npc_id": "6042",
"loc_data": "{3479,3498,0,1,4}-" "loc_data": "{3480,3499,0,1,4}-"
},
{
"npc_id": "6043",
"loc_data": "{3490,3473,0,1,0}-"
}, },
{ {
"npc_id": "6044", "npc_id": "6044",
"loc_data": "{3505,3491,1,0,0}-" "loc_data": "{3505,3491,0,1,0}-"
}, },
{ {
"npc_id": "6045", "npc_id": "6045",
"loc_data": "{3479,3498,1,0,0}-" "loc_data": "{3479,3498,0,1,0}-"
}, },
{ {
"npc_id": "6046", "npc_id": "6046",
@ -10245,11 +10321,11 @@
}, },
{ {
"npc_id": "6050", "npc_id": "6050",
"loc_data": "{3264,3008,0,1,0}-{3266,3008,0,1,0}-{3285,3066,0,1,0}-{3322,3032,0,1,0}-{3323,3055,0,1,0}-{3325,3010,0,1,0}-{3174,3010,0,1,0}-{3198,3061,0,1,0}-{3199,3016,0,1,0}-{3219,3125,0,1,0}-{3233,3075,0,1,0}-{3250,3126,0,1,0}-{3223,3011,0,1,0}-{3228,3060,0,1,0}-{3251,3059,0,1,0}-{3310,3076,0,1,0}-" "loc_data": "{3174,3010,0,1,0}-{3198,3061,0,1,0}-{3199,3016,0,1,0}-{3223,3011,0,1,0}-{3228,3060,0,1,0}-{3251,3059,0,1,0}-{3219,3125,0,1,0}-{3233,3075,0,1,0}-{3250,3126,0,1,0}-{3264,3008,0,1,0}-{3266,3008,0,1,0}-{3285,3066,0,1,0}-{3322,3032,0,1,0}-{3323,3055,0,1,0}-{3325,3010,0,1,0}-{3310,3076,0,1,0}-"
}, },
{ {
"npc_id": "6051", "npc_id": "6051",
"loc_data": "{3266,3010,0,1,0}-{3267,3068,0,1,0}-{3287,3065,0,1,0}-{3287,3067,0,1,0}-{3310,3070,0,1,0}-{3312,3068,0,1,0}-{3320,3054,0,1,0}-{3324,3013,0,1,0}-{3325,3033,0,1,0}-{3153,3047,0,1,0}-{3196,3063,0,1,0}-{3199,3036,0,1,0}-{3215,3092,0,1,0}-{3217,3124,0,1,0}-{3260,3077,0,1,0}-{3223,3035,0,1,0}-{3225,3011,0,1,0}-{3283,3084,0,1,0}-" "loc_data": "{3153,3047,0,1,0}-{3196,3063,0,1,0}-{3199,3036,0,1,0}-{3223,3035,0,1,0}-{3225,3011,0,1,0}-{3215,3092,0,1,0}-{3217,3124,0,1,0}-{3260,3077,0,1,0}-{3266,3010,0,1,0}-{3267,3068,0,1,0}-{3287,3065,0,1,0}-{3287,3067,0,1,0}-{3310,3070,0,1,0}-{3312,3068,0,1,0}-{3320,3054,0,1,0}-{3324,3013,0,1,0}-{3325,3033,0,1,0}-{3283,3084,0,1,0}-"
}, },
{ {
"npc_id": "6052", "npc_id": "6052",
@ -10375,6 +10451,38 @@
"npc_id": "6117", "npc_id": "6117",
"loc_data": "{1884,5020,0,0,6}-" "loc_data": "{1884,5020,0,0,6}-"
}, },
{
"npc_id": "6118",
"loc_data": "{2443,3190,0,0,6}-"
},
{
"npc_id": "6119",
"loc_data": "{2439,3186,0,1,4}-"
},
{
"npc_id": "6120",
"loc_data": "{2437,3160,1,1,4}-"
},
{
"npc_id": "6122",
"loc_data": "{2327,9394,0,0,1}-"
},
{
"npc_id": "6123",
"loc_data": "{2364,9399,0,0,1}-"
},
{
"npc_id": "6124",
"loc_data": "{2364,9398,0,0,1}-"
},
{
"npc_id": "6125",
"loc_data": "{2323,9377,0,1,0}-"
},
{
"npc_id": "6126",
"loc_data": "{2351,9358,0,1,0}-"
},
{ {
"npc_id": "6127", "npc_id": "6127",
"loc_data": "{2467,3183,0,0,3}-" "loc_data": "{2467,3183,0,0,3}-"
@ -10455,6 +10563,38 @@
"npc_id": "6190", "npc_id": "6190",
"loc_data": "{1906,4270,0,1,0}-" "loc_data": "{1906,4270,0,1,0}-"
}, },
{
"npc_id": "6191",
"loc_data": "{2739,3577,0,1,0}-{2739,3579,1,1,0}-"
},
{
"npc_id": "6192",
"loc_data": "{2734,3575,0,1,0}-"
},
{
"npc_id": "6193",
"loc_data": "{2748,3559,0,1,0}-"
},
{
"npc_id": "6194",
"loc_data": "{2734,3581,1,1,0}-"
},
{
"npc_id": "6195",
"loc_data": "{2739,3581,0,1,0}-"
},
{
"npc_id": "6196",
"loc_data": "{2746,3581,1,1,0}-"
},
{
"npc_id": "6197",
"loc_data": "{2742,3577,0,1,0}-"
},
{
"npc_id": "6199",
"loc_data": "{2737,3466,0,1,0}-"
},
{ {
"npc_id": "6200", "npc_id": "6200",
"loc_data": "{2947,3366,0,0,1}-{2949,3366,0,0,1}-{2946,3366,0,0,1}-{2948,3366,0,0,1}-{2945,3366,0,0,1}-{3010,3353,0,0,1}-{3011,3353,0,0,1}-{3012,3353,0,0,1}-{3013,3353,0,0,1}-{3014,3353,0,0,1}-{3015,3353,0,0,1}-" "loc_data": "{2947,3366,0,0,1}-{2949,3366,0,0,1}-{2946,3366,0,0,1}-{2948,3366,0,0,1}-{2945,3366,0,0,1}-{3010,3353,0,0,1}-{3011,3353,0,0,1}-{3012,3353,0,0,1}-{3013,3353,0,0,1}-{3014,3353,0,0,1}-{3015,3353,0,0,1}-"
@ -12059,10 +12199,6 @@
"npc_id": "7804", "npc_id": "7804",
"loc_data": "{3279,4350,0,1,0}-{3294,4353,0,1,0}-{3294,4366,0,1,0}-" "loc_data": "{3279,4350,0,1,0}-{3294,4353,0,1,0}-{3294,4366,0,1,0}-"
}, },
{
"npc_id": "7823",
"loc_data": "{3161,9547,0,0,3}-{3164,9556,0,0,4}-{3162,9574,0,0,3}-{3198,9554,0,0,7}-{3198,9572,0,0,1}-{3215,9560,0,0,1}-{3216,9588,0,0,1}-"
},
{ {
"npc_id": "7891", "npc_id": "7891",
"loc_data": "{3207,3250,0,0,0}-{3208,3250,0,0,0}-{3209,3250,0,0,0}-" "loc_data": "{3207,3250,0,0,0}-{3208,3250,0,0,0}-{3209,3250,0,0,0}-"
@ -12225,7 +12361,7 @@
}, },
{ {
"npc_id": "8324", "npc_id": "8324",
"loc_data": "{2911,3811,0,1,0}-{2911,3812,0,1,0}-{2911,3813,0,1,0}-{2925,3821,0,1,0}-{2925,3822,0,1,0}-{2925,3823,0,1,0}-{2929,3798,0,1,0}-{2936,3790,0,1,0}-{2936,3810,0,1,0}-{2939,3823,0,1,0}-{2949,3819,1,1,0}-{2949,3822,1,1,0}-{2955,3822,1,1,0}-{2957,3822,1,1,0}-{3016,9977,1,1,0}-{3021,9939,1,1,0}-{3024,9954,1,1,0}-{3025,9943,1,1,0}-{3025,9954,1,1,0}-{3026,9966,1,1,0}-{3032,9952,1,1,0}-{3039,9954,1,1,0}-{3044,9967,1,1,0}-{3044,9971,1,1,0}-{3057,9936,1,1,0}-{3059,9953,1,1,0}-{3041,9975,2,1,0}-{3043,9975,2,1,0}-{3045,9975,2,1,0}-{3016,10022,2,1,0}-{3017,10039,2,1,0}-{3027,10028,2,1,0}-{3029,10013,2,1,0}-{3036,10038,2,1,0}-{3037,10006,2,1,0}-{3041,10024,2,1,0}-{3043,10032,2,1,0}-{3057,10002,2,1,0}-{3058,10021,2,1,0}-{3065,10006,2,1,0}-{3027,10092,1,1,0}-{3035,10097,1,1,0}-{3051,10099,1,1,0}-{3427,5102,0,1,0}-{3428,5099,0,1,0}-{3428,5102,0,1,0}-{3430,5099,0,1,0}-" "loc_data": "{2911,3811,0,1,0}-{2911,3812,0,1,0}-{2911,3813,0,1,0}-{2925,3821,0,1,0}-{2925,3822,0,1,0}-{2925,3823,0,1,0}-{2929,3798,0,1,0}-{2936,3790,0,1,0}-{2936,3810,0,1,0}-{2939,3823,0,1,0}-{3427,5102,0,1,0}-{3428,5099,0,1,0}-{3428,5102,0,1,0}-{3430,5099,0,1,0}-{2949,3819,1,1,0}-{2949,3822,1,1,0}-{2955,3822,1,1,0}-{2957,3822,1,1,0}-{3016,9977,1,1,0}-{3021,9939,1,1,0}-{3024,9954,1,1,0}-{3025,9943,1,1,0}-{3025,9954,1,1,0}-{3026,9966,1,1,0}-{3032,9952,1,1,0}-{3039,9954,1,1,0}-{3044,9967,1,1,0}-{3044,9971,1,1,0}-{3057,9936,1,1,0}-{3059,9953,1,1,0}-{3041,9975,2,1,0}-{3043,9975,2,1,0}-{3045,9975,2,1,0}-{3016,10022,2,1,0}-{3017,10039,2,1,0}-{3027,10028,2,1,0}-{3029,10013,2,1,0}-{3036,10038,2,1,0}-{3037,10006,2,1,0}-{3041,10024,2,1,0}-{3043,10032,2,1,0}-{3057,10002,2,1,0}-{3058,10021,2,1,0}-{3065,10006,2,1,0}-{3027,10092,1,1,0}-{3035,10097,1,1,0}-{3051,10099,1,1,0}-"
}, },
{ {
"npc_id": "8328", "npc_id": "8328",

View file

@ -19168,87 +19168,87 @@
"ids": "13614" "ids": "13614"
}, },
{ {
"examine": "A gateway to Varrock", "examine": "A gateway to Varrock.",
"ids": "13615" "ids": "13615"
}, },
{ {
"examine": "A gateway to Lumbridge", "examine": "A gateway to Lumbridge.",
"ids": "13616" "ids": "13616"
}, },
{ {
"examine": "A gateway to Falador", "examine": "A gateway to Falador.",
"ids": "13617" "ids": "13617"
}, },
{ {
"examine": "A gateway to Camelot", "examine": "A gateway to Camelot.",
"ids": "13618" "ids": "13618"
}, },
{ {
"examine": "A gateway to Ardougne", "examine": "A gateway to Ardougne.",
"ids": "13619" "ids": "13619"
}, },
{ {
"examine": "A gateway to the Yanille watchtower", "examine": "A gateway to the Yanille watchtower.",
"ids": "13620" "ids": "13620"
}, },
{ {
"examine": "A gateway to Trollheim", "examine": "A gateway to Kharyrll.",
"ids": "13621" "ids": "13621"
}, },
{ {
"examine": "A gateway to Varrock", "examine": "A gateway to Varrock.",
"ids": "13622" "ids": "13622"
}, },
{ {
"examine": "A gateway to Lumbridge", "examine": "A gateway to Lumbridge.",
"ids": "13623" "ids": "13623"
}, },
{ {
"examine": "A gateway to Falador", "examine": "A gateway to Falador.",
"ids": "13624" "ids": "13624"
}, },
{ {
"examine": "A gateway to Camelot", "examine": "A gateway to Camelot.",
"ids": "13625" "ids": "13625"
}, },
{ {
"examine": "A gateway to Ardougne", "examine": "A gateway to Ardougne.",
"ids": "13626" "ids": "13626"
}, },
{ {
"examine": "A gateway to the Yanille watchtower", "examine": "A gateway to the Yanille watchtower.",
"ids": "13627" "ids": "13627"
}, },
{ {
"examine": "A gateway to Trollheim", "examine": "A gateway to Kharyrll.",
"ids": "13628" "ids": "13628"
}, },
{ {
"examine": "A gateway to Varrock", "examine": "A gateway to Varrock.",
"ids": "13629" "ids": "13629"
}, },
{ {
"examine": "A gateway to Lumbridge", "examine": "A gateway to Lumbridge.",
"ids": "13630" "ids": "13630"
}, },
{ {
"examine": "A gateway to Falador", "examine": "A gateway to Falador.",
"ids": "13631" "ids": "13631"
}, },
{ {
"examine": "A gateway to Camelot", "examine": "A gateway to Camelot.",
"ids": "13632" "ids": "13632"
}, },
{ {
"examine": "A gateway to Ardougne", "examine": "A gateway to Ardougne.",
"ids": "13633" "ids": "13633"
}, },
{ {
"examine": "A gateway to the Yanille watchtower", "examine": "A gateway to the Yanille watchtower.",
"ids": "13634" "ids": "13634"
}, },
{ {
"examine": "A gateway to Trollheim", "examine": "A gateway to Kharyrll.",
"ids": "13635" "ids": "13635"
}, },
{ {
@ -20055,6 +20055,10 @@
"examine": "Home sweet home?", "examine": "Home sweet home?",
"ids": "15480" "ids": "15480"
}, },
{
"examine": "Baby bread.",
"ids": "15506,15507"
},
{ {
"examine": "Home sweet home?", "examine": "Home sweet home?",
"ids": "15748" "ids": "15748"
@ -20183,6 +20187,18 @@
"examine": "A short longboat!", "examine": "A short longboat!",
"ids": "21834" "ids": "21834"
}, },
{
"examine": "A place to sit and watch furniture grow.",
"ids": "28627"
},
{
"examine": "It's not rolling, but it seems to have gathered some moss.",
"ids": "28635"
},
{
"examine": "A thick metal gate.",
"ids": "28690,28691,28692,28693"
},
{ {
"examine": "Contains traces of summoning energy.", "examine": "Contains traces of summoning energy.",
"ids": "29939,29943,29944,29945,29947,29951,29952,29953,29954" "ids": "29939,29943,29944,29945,29947,29951,29952,29953,29954"

View file

@ -1546,5 +1546,41 @@
"animation": "426", "animation": "426",
"drop_ammo": "true", "drop_ammo": "true",
"ammunition": "14202,14203,14204,14205,14206" "ammunition": "14202,14203,14204,14205,14206"
},
{
"itemId": "10149",
"name": "Swamp lizard",
"ammo_slot": "13",
"weapon_type": "0",
"animation": "5247",
"drop_ammo": "false",
"ammunition": "10142"
},
{
"itemId": "10146",
"name": "Orange salamander",
"ammo_slot": "13",
"weapon_type": "0",
"animation": "5247",
"drop_ammo": "false",
"ammunition": "10143"
},
{
"itemId": "10147",
"name": "Red salamander",
"ammo_slot": "13",
"weapon_type": "0",
"animation": "5247",
"drop_ammo": "false",
"ammunition": "10144"
},
{
"itemId": "10148",
"name": "Black salamander",
"ammo_slot": "13",
"weapon_type": "0",
"animation": "5247",
"drop_ammo": "false",
"ammunition": "10145"
} }
] ]

View file

@ -177,7 +177,7 @@
"general_store": "true", "general_store": "true",
"id": "21", "id": "21",
"title": "Gunslik's Assorted Items", "title": "Gunslik's Assorted Items",
"stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" "stock": "{1935,10,100}-{1925,30,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{36,10,100}-{596,10,100}-{973,10,100}-{1059,10,100}-{229,300,100}-{233,10,100}-{954,10,100}"
}, },
{ {
"npcs": "1334", "npcs": "1334",

View file

@ -9,18 +9,19 @@ import core.game.event.TeleportEvent
import core.game.interaction.QueueStrength import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager import core.game.node.entity.player.link.TeleportManager
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item import core.game.node.item.Item
import core.game.system.task.Pulse import core.game.world.GameWorld
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics import core.game.world.update.flag.context.Graphics
import core.tools.Log
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.world.GameWorld.Pulser
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
import java.util.* import java.util.*
/** /**
* Represents an enchanted jewellery. * Represents a piece of enchanted jewellery.
* @author Vexia, downthecrop, Player Name * @author Vexia, downthecrop, Player Name
*/ */
enum class EnchantedJewellery( enum class EnchantedJewellery(
@ -73,17 +74,17 @@ enum class EnchantedJewellery(
), ),
AMULET_OF_GLORY( AMULET_OF_GLORY(
arrayOf( arrayOf(
"Edgeville.", "Edgeville",
"Karamja.", "Karamja",
"Draynor Village.", "Draynor Village",
"Al-Kharid.", "Al Kharid",
"Nowhere." "Nowhere"
), ),
arrayOf( arrayOf(
Location.create(3087, 3495, 0), Location.create(3087, 3495, 0),
Location.create(2919, 3175, 0), Location.create(2919, 3175, 0),
Location.create(3104, 3249, 0), Location.create(3104, 3249, 0),
Location.create(3304, 3124, 0) Location.create(3292, 3175, 0)
), ),
Items.AMULET_OF_GLORY4_1712, Items.AMULET_OF_GLORY4_1712,
Items.AMULET_OF_GLORY3_1710, Items.AMULET_OF_GLORY3_1710,
@ -209,7 +210,7 @@ enum class EnchantedJewellery(
constructor(options: Array<String>, locations: Array<Location>, vararg ids: Int) : this(options, locations, false, *ids) constructor(options: Array<String>, locations: Array<Location>, vararg ids: Int) : this(options, locations, false, *ids)
/** /**
* Method used when the player "Use"s the jewellery piece. * Method used when the player clicks one of the options in the jewellery piece's options dialog.
* @param player the player. * @param player the player.
* @param item the used jewellery item. * @param item the used jewellery item.
* @param buttonID the button id. * @param buttonID the button id.
@ -222,7 +223,7 @@ enum class EnchantedJewellery(
} }
return return
} }
attemptTeleport(player, item, buttonID, isEquipped) attemptTeleport(player, item, buttonID, true, isEquipped)
} }
/** /**
@ -230,43 +231,74 @@ enum class EnchantedJewellery(
* @param player the player. * @param player the player.
* @param item the used jewellery item. * @param item the used jewellery item.
* @param buttonID the button id. * @param buttonID the button id.
* @param replace Whether to attempt replacing the item with its lower-charge version. Always true unless you generated a fake item in code.
* @param isEquipped If the player is operating. * @param isEquipped If the player is operating.
*/ */
fun attemptTeleport(player: Player, item: Item, buttonID: Int, isEquipped: Boolean): Boolean { fun attemptTeleport(player: Player, item: Item, buttonID: Int, replace: Boolean, isEquipped: Boolean): Boolean {
val itemIndex = getItemIndex(item) val itemIndex = getItemIndex(item)
val nextJewellery = Item(getNext(itemIndex)) val nextJewellery = Item(getNext(itemIndex))
if (!canTeleport(player, nextJewellery)) { if (!canTeleport(player, nextJewellery)) {
return false return false
} }
Pulser.submit(object : Pulse(0) { val location = getLocation(buttonID)
private var count = 0 player.scripts.delay = GameWorld.ticks + 4
private var location = getLocation(buttonID) queueScript(player, 0, QueueStrength.SOFT) { stage ->
override fun pulse(): Boolean { when (stage) {
when (count) {
0 -> { 0 -> {
lock(player, 4) lock(player, 4)
visualize(player, ANIMATION, GRAPHICS) visualize(player, ANIMATION, GRAPHICS)
playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
player.impactHandler.disabledTicks = 4 player.impactHandler.disabledTicks = 4
closeInterface(player) closeInterface(player)
return@queueScript delayScript(player, 3)
} }
3 -> { 1 -> {
teleport(player, location) teleport(player, location)
resetAnimator(player) resetAnimator(player)
unlock(player)
player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location))
if (DIGSITE_PENDANT.ids.contains(item.id)) {
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 10)
}
if (!replace) {
return@queueScript stopExecuting(player)
}
if (isLastItemIndex(itemIndex)) { if (isLastItemIndex(itemIndex)) {
if (isCrumble) crumbleJewellery(player, item, isEquipped) if (isSlayerRing(item)) {
if (isEquipped) {
// Remove it now, but only addItemOrDrop the gem after the teleport has procced
if (removeItem(player, item, Container.EQUIPMENT)) {
return@queueScript delayScript(player, 1)
}
log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (removeItem from equipment)")
}
// Not equipped -> can replace fluently
if (replaceSlot(player, item.slot, Item(Items.ENCHANTED_GEM_4155), item) == item) {
return@queueScript stopExecuting(player)
}
log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (replaceSlot)")
}
// Not slayer ring
if (isCrumble) {
val removeFrom = if (isEquipped) Container.EQUIPMENT else Container.INVENTORY
if (removeItem(player, item, removeFrom)) {
return@queueScript stopExecuting(player)
}
log(this.javaClass, Log.ERR, "Error crumbling jewelry")
}
} else { } else {
replaceJewellery(player, item, nextJewellery, isEquipped) replaceJewellery(player, item, nextJewellery, isEquipped)
} }
unlock(player) }
player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location)) 2 -> {
return true addItemOrDrop(player, Items.ENCHANTED_GEM_4155)
sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.")
} }
} }
count += 1 return@queueScript stopExecuting(player)
return false
} }
})
return true return true
} }
@ -278,21 +310,6 @@ enum class EnchantedJewellery(
} }
} }
private fun crumbleJewellery(player: Player, item: Item, isEquipped: Boolean) {
if (isEquipped) {
removeItem(player, item, Container.EQUIPMENT)
} else {
removeItem(player, item)
}
if (isSlayerRing(item)) {
queueScript(player, 1, QueueStrength.SOFT) {
addItemOrDrop(player, Items.ENCHANTED_GEM_4155)
sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.")
return@queueScript stopExecuting(player)
}
}
}
private fun isSlayerRing(item: Item): Boolean { private fun isSlayerRing(item: Item): Boolean {
return (item.id in RING_OF_SLAYING.ids) return (item.id in RING_OF_SLAYING.ids)
} }

View file

@ -1,87 +0,0 @@
package content.data;
import core.game.node.item.Item;
/**
* Represents the repair item type.
* @author Vexia
*/
public enum RepairItem {
BRONZE_HATCHET(new Item(494, 1), new Item(1351, 1), 0),
BRONZE_PICKAXE(new Item(468, 1), new Item(1265, 1), 0),
IRON_HATCHET(new Item(496, 1), new Item(1349, 1), 0),
IRON_PICKAXE(new Item(470, 1), new Item(1267, 1), 0),
STEEL_HATCHET(new Item(498, 1), new Item(1353, 1), 0),
STEEL_PICKAXE(new Item(472, 1), new Item(1269, 1), 14),
BLACK_HATCHET(new Item(500, 1), new Item(1361, 1), 10),
MITHRIL_HATCHET(new Item(502, 1), new Item(1355, 1), 18),
MITHRIL_PICKAXE(new Item(474, 1), new Item(1273, 1), 43),
ADAMANT_HATCHET(new Item(504, 1), new Item(1357, 1), 43),
ADAMANT_PICKAXE(new Item(476, 1), new Item(1271, 1), 107),
RUNE_HATCHET(new Item(506, 1), new Item(1359, 1), 427),
RUNE_PICKAXE(new Item(478, 1), new Item(1275, 1), 1100),
DRAGON_HATCHET(new Item(6741, 1), new Item(6739, 1), 1800);
/**
* The item id.
*/
private final Item item;
/**
* The product item.
*/
private final Item product;
/**
* The cost of the money to repair.
*/
private final int cost;
/**
* Constructs a new {@code BobRepairItem} {@code Object}.
* @param item the item.
* @param product the product.
* @param cost the cost.
*/
RepairItem(Item item, Item product, int cost) {
this.item = item;
this.product = product;
this.cost = cost;
}
/**
* Gets the item.
* @return The item.
*/
public Item getItem() {
return item;
}
/**
* Gets the product.
* @return The product.
*/
public Item getProduct() {
return product;
}
/**
* Gets the cost.
* @return The cost.
*/
public int getCost() {
return cost;
}
/**
* Gets the reapir item by the id.
* @param id the id.
* @return the repair item.
*/
public static RepairItem forId(int id) {
for (RepairItem item : RepairItem.values())
if (item.item.getId() == id)
return item;
return null;
}
}

View file

@ -0,0 +1,43 @@
package content.data
import core.game.node.item.Item
/**
* Represents the repair item type.
* @author Vexia
* @author Damighty - Kotlin conversion
*/
enum class RepairItem(
val item: Item,
val product: Item,
val cost: Int
) {
BRONZE_HATCHET(Item(494, 1), Item(1351, 1), 0),
BRONZE_PICKAXE(Item(468, 1), Item(1265, 1), 0),
IRON_HATCHET(Item(496, 1), Item(1349, 1), 0),
IRON_PICKAXE(Item(470, 1), Item(1267, 1), 0),
STEEL_HATCHET(Item(498, 1), Item(1353, 1), 0),
STEEL_PICKAXE(Item(472, 1), Item(1269, 1), 14),
BLACK_HATCHET(Item(500, 1), Item(1361, 1), 10),
MITHRIL_HATCHET(Item(502, 1), Item(1355, 1), 18),
MITHRIL_PICKAXE(Item(474, 1), Item(1273, 1), 43),
ADAMANT_HATCHET(Item(504, 1), Item(1357, 1), 43),
ADAMANT_PICKAXE(Item(476, 1), Item(1271, 1), 107),
RUNE_HATCHET(Item(506, 1), Item(1359, 1), 427),
RUNE_PICKAXE(Item(478, 1), Item(1275, 1), 1100),
DRAGON_HATCHET(Item(6741, 1), Item(6739, 1), 1800);
companion object {
/**
* List of all repairable item IDs.
*/
@JvmStatic
val repairableItemIds: List<Int> = values().map { it.item.id }
/**
* Gets the repair item by the broken items ID.
*/
@JvmStatic
fun forId(id: Int): RepairItem? = values().firstOrNull { it.item.id == id }
}
}

View file

@ -118,6 +118,8 @@ public enum Consumables {
EGG_AND_TOMATO(new Food(new int[] {7064, 1923}, new HealingEffect(8))), EGG_AND_TOMATO(new Food(new int[] {7064, 1923}, new HealingEffect(8))),
SWEET_CORN(new Food(new int[] {5988}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))), SWEET_CORN(new Food(new int[] {5988}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))),
SWEETCORN_BOWL(new Food(new int[] {7088, 1923}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))), SWEETCORN_BOWL(new Food(new int[] {7088, 1923}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))),
CHOPPED_TUNA(new Food(new int[] {7086, 1923}, new HealingEffect(10))),
CHOPPED_ONION(new Food(new int[] {1871, 1923}, new HealingEffect(1))),
POTATO_WITH_BUTTER(new Food(new int[] {6703}, new HealingEffect(7))), POTATO_WITH_BUTTER(new Food(new int[] {6703}, new HealingEffect(7))),
CHILLI_POTATO(new Food(new int[] {7054}, new HealingEffect(14))), CHILLI_POTATO(new Food(new int[] {7054}, new HealingEffect(14))),
FRIED_ONIONS(new Food(new int[] {7084, 1923}, new HealingEffect(5))), FRIED_ONIONS(new Food(new int[] {7084, 1923}, new HealingEffect(5))),
@ -201,48 +203,56 @@ public enum Consumables {
/** Ales */ /** Ales */
ASGOLDIAN_ALE(new FakeConsumable(7508, new String[] {"I don't think I'd like gold in beer thanks. Leave it for the dwarves."})), ASGOLDIAN_ALE(new FakeConsumable(7508, new String[] {"I don't think I'd like gold in beer thanks. Leave it for the dwarves."})),
ASGARNIAN_ALE(new Drink(new int[] {1905, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), ASGARNIAN_ALE(new Drink(new int[] {1905, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
ASGARNIAN_ALE_POH(new Drink(new int[] {7744, 7742}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
ASGARNIAN_ALE_KEG(new Drink(new int[] {5785, 5783, 5781, 5779, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), ASGARNIAN_ALE_KEG(new Drink(new int[] {5785, 5783, 5781, 5779, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
ASGARNIAN_ALE_M(new Drink(new int[] {5739, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), ASGARNIAN_ALE_M(new Drink(new int[] {5739, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
ASGARNIAN_ALE_M_KEG(new Drink(new int[] {5865, 5863, 5861, 5859, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))), ASGARNIAN_ALE_M_KEG(new Drink(new int[] {5865, 5863, 5861, 5859, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
AXEMANS_FOLLY(new Drink(new int[] {5751, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)))), AXEMANS_FOLLY(new Drink(new int[] {5751, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)))),
AXEMANS_FOLLY_KEG(new Drink(new int[] {5825, 5823, 5821, 5819, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)), new Animation(2289))), AXEMANS_FOLLY_KEG(new Drink(new int[] {5825, 5823, 5821, 5819, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)), new Animation(2289))),
AXEMANS_FOLLY_M(new Drink(new int[] {5753, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), AXEMANS_FOLLY_M(new Drink(new int[] {5753, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)))),
AXEMANS_FOLLY_M_KEG(new Drink(new int[] {5905, 5903, 5901, 5899, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))), AXEMANS_FOLLY_M_KEG(new Drink(new int[] {5905, 5903, 5901, 5899, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))),
BANDITS_BREW(new Drink(new int[] {4627, 1919}, new MultiEffect(new SkillEffect(Skills.THIEVING, 1, 0), new SkillEffect(Skills.ATTACK, 1, 0), new SkillEffect(Skills.STRENGTH, -1, 0), new SkillEffect(Skills.DEFENCE, -6, 0), new HealingEffect(1)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")), BANDITS_BREW(new Drink(new int[] {4627, 1919}, new MultiEffect(new SkillEffect(Skills.THIEVING, 1, 0), new SkillEffect(Skills.ATTACK, 1, 0), new SkillEffect(Skills.STRENGTH, -1, 0), new SkillEffect(Skills.DEFENCE, -6, 0), new HealingEffect(1)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
BEER(new Drink(new int[] {1917, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")), BEER(new Drink(new int[] {1917, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
BEER_POH(new Drink(new int[] {7740, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
BEER_TANKARD(new Drink(new int[] {3803, 3805}, new MultiEffect(new SkillEffect(Skills.ATTACK, -9, 0), new SkillEffect(Skills.STRENGTH, 4, 0)), "You quaff the beer. You feel slightly reinvigorated...", "...but very dizzy too.")), BEER_TANKARD(new Drink(new int[] {3803, 3805}, new MultiEffect(new SkillEffect(Skills.ATTACK, -9, 0), new SkillEffect(Skills.STRENGTH, 4, 0)), "You quaff the beer. You feel slightly reinvigorated...", "...but very dizzy too.")),
KEG_OF_BEER(new Drink(new int[] {3801}, new KegOfBeerEffect(), new Animation(1330), "You chug the keg. You feel reinvigorated...", "...but extremely drunk too.")), KEG_OF_BEER(new Drink(new int[] {3801}, new KegOfBeerEffect(), new Animation(1330), "You chug the keg. You feel reinvigorated...", "...but extremely drunk too.")),
CHEFS_DELIGHT(new Drink(new int[] {5755, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), CHEFS_DELIGHT(new Drink(new int[] {5755, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
CHEFS_DELIGHT_POH(new Drink(new int[] {7754, 7742}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
CHEFS_DELIGHT_KEG(new Drink(new int[] {5833, 5831, 5829, 5827, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), CHEFS_DELIGHT_KEG(new Drink(new int[] {5833, 5831, 5829, 5827, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
CHEFS_DELIGHT_M(new Drink(new int[] {5757, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)))), CHEFS_DELIGHT_M(new Drink(new int[] {5757, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)))),
CHEFS_DELIGHT_M_KEG(new Drink(new int[] {5913, 5911, 5909, 5907, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)), new Animation(2289))), CHEFS_DELIGHT_M_KEG(new Drink(new int[] {5913, 5911, 5909, 5907, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)), new Animation(2289))),
CIDER(new Drink(new int[] {5763, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))), CIDER(new Drink(new int[] {5763, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))),
CIDER_POH(new Drink(new int[] {7752, 7742}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))),
CIDER_KEG(new Drink(new int[] {5849, 5847, 5845, 5843, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))), new Animation(2289))), CIDER_KEG(new Drink(new int[] {5849, 5847, 5845, 5843, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))), new Animation(2289))),
MATURE_CIDER(new Drink(new int[] {5765, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))))), MATURE_CIDER(new Drink(new int[] {5765, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))))),
CIDER_M_KEG(new Drink(new int[] {5929, 5927, 5925, 5923, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))), new Animation(2289))), CIDER_M_KEG(new Drink(new int[] {5929, 5927, 5925, 5923, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))), new Animation(2289))),
DRAGON_BITTER(new Drink(new int[] {1911, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), DRAGON_BITTER(new Drink(new int[] {1911, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))),
DRAGON_BITTER_POH(new Drink(new int[] {7748, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))),
DRAGON_BITTER_KEG(new Drink(new int[] {5809, 5807, 5805, 5803, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))), DRAGON_BITTER_KEG(new Drink(new int[] {5809, 5807, 5805, 5803, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))),
DRAGON_BITTER_M(new Drink(new int[] {5745, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), DRAGON_BITTER_M(new Drink(new int[] {5745, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))),
DRAGON_BITTER_M_KEG(new Drink(new int[] {5889, 5887, 5885, 5883, 5769}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))), DRAGON_BITTER_M_KEG(new Drink(new int[] {5889, 5887, 5885, 5883, 5769}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))),
DWARVEN_STOUT(new Drink(new int[] {1913, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), DWARVEN_STOUT(new Drink(new int[] {1913, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
DWARVEN_STOUT_KEG(new Drink(new int[] {5777, 5775, 5773, 5771, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), DWARVEN_STOUT_KEG(new Drink(new int[] {5777, 5775, 5773, 5771, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
DWARVEN_STOUT_M(new Drink(new int[] {5747, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)))), DWARVEN_STOUT_M(new Drink(new int[] {5747, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
DWARVEN_STOUT_M_KEG(new Drink(new int[] {5857, 5855, 5853, 5851, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), new Animation(2289))), DWARVEN_STOUT_M_KEG(new Drink(new int[] {5857, 5855, 5853, 5851, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
GREENMANS_ALE(new Drink(new int[] {1909, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))), GREENMANS_ALE(new Drink(new int[] {1909, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))),
GREENMANS_ALE_POH(new Drink(new int[] {7746, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))),
GREENMANS_ALE_KEG(new Drink(new int[] {5793, 5791, 5789, 5787, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)), new Animation(2289))), GREENMANS_ALE_KEG(new Drink(new int[] {5793, 5791, 5789, 5787, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)), new Animation(2289))),
GREENMANS_ALE_M(new Drink(new int[] {5743, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), GREENMANS_ALE_M(new Drink(new int[] {5743, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
GREENMANS_ALE_M_KEG(new Drink(new int[] {5873, 5871, 5869, 5867, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), GREENMANS_ALE_M_KEG(new Drink(new int[] {5873, 5871, 5869, 5867, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
GROG(new Drink(new int[] {1915, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), GROG(new Drink(new int[] {1915, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))),
MOONLIGHT_MEAD(new Drink(new int[] {2955, 1919}, new HealingEffect(4), "It tastes like something just died in your mouth.")), MOONLIGHT_MEAD(new Drink(new int[] {2955, 1919}, new HealingEffect(5), "It tastes like something just died in your mouth.")),
MOONLIGHT_MEAD_KEG(new Drink(new int[] {5817, 5815, 5813, 5811, 5769}, new HealingEffect(4), new Animation(2289), "It tastes like something just died in your mouth.")), MOONLIGHT_MEAD_KEG(new Drink(new int[] {5817, 5815, 5813, 5811, 5769}, new HealingEffect(5), new Animation(2289), "It tastes like something just died in your mouth.")),
MOONLIGHT_MEAD_M(new Drink(new int[] {5749, 1919}, new HealingEffect(6))), MOONLIGHT_MEAD_M(new Drink(new int[] {5749, 1919}, new HealingEffect(4), "It tastes like something just died in your mouth.")),
MOONLIGHT_MEAD_M_KEG(new Drink(new int[] {5897, 5895, 5893, 5891, 5769}, new HealingEffect(6), new Animation(2289))), MOONLIGHT_MEAD_M_KEG(new Drink(new int[] {5897, 5895, 5893, 5891, 5769}, new HealingEffect(4), new Animation(2289), "It tastes like something just died in your mouth.")),
SLAYERS_RESPITE(new Drink(new int[] {5759, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), SLAYERS_RESPITE(new Drink(new int[] {5759, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
SLAYERS_RESPITE_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), SLAYERS_RESPITE_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
SLAYERS_RESPITE_M(new Drink(new int[] {5761, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), SLAYERS_RESPITE_M(new Drink(new int[] {5761, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
SLAYERS_RESPITE_M_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), SLAYERS_RESPITE_M_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
WIZARDS_MIND_BOMB(new Drink(new int[] {1907, 1919}, new WizardsMindBombEffect(), "You drink the Wizard's Mind Bomb.", "You feel very strange.")), WIZARDS_MIND_BOMB(new Drink(new int[] {1907, 1919}, new WizardsMindBombEffect(), "You drink the Wizard's Mind Bomb.", "You feel very strange.")),
MATURE_WMB(new Drink(new int[] {5741, 1919}, new MatureWmbEffect())), WIZARDS_MIND_BOMB_KEG(new Drink(new int[] {5801, 5799, 5797, 5795, 5769}, new WizardsMindBombEffect(), new Animation(2289), "You drink the Wizard's Mind Bomb.", "You feel very strange.")),
MATURE_WMB(new Drink(new int[] {5741, 1919}, new MatureWmbEffect(), "You drink the mature Wizard's Mind Bomb.", "You feel very strange.")),
MATURE_WMB_KEG(new Drink(new int[] {5881, 5879, 5877, 5875, 5769}, new MatureWmbEffect(), new Animation(2289), "You drink the mature Wizard's Mind Bomb.", "You feel very strange.")),
/** Cocktails */ /** Cocktails */
FRUIT_BLAST(new Drink(new int[] {2084, 2026}, new HealingEffect(9))), FRUIT_BLAST(new Drink(new int[] {2084, 2026}, new HealingEffect(9))),
@ -285,16 +295,19 @@ public enum Consumables {
/** Tea */ /** Tea */
CUP_OF_TEA(new Drink(new int[] {712, 1980}, new MultiEffect(new HealingEffect(3), new SkillEffect(Skills.ATTACK, 3, 0)), "Aaah, nothing like a nice cuppa tea!")), CUP_OF_TEA(new Drink(new int[] {712, 1980}, new MultiEffect(new HealingEffect(3), new SkillEffect(Skills.ATTACK, 3, 0)), "Aaah, nothing like a nice cuppa tea!")),
CUP_OF_TEA_NETTLE(new Drink(new int[] {4242, 1980}, new EnergyEffect(10))), NETTLE_WATER(new Drink(new int[] {Items.NETTLE_WATER_4237, Items.BOWL_1923}, new HealingEffect((1)))),
CUP_OF_TEA_MILKY_NETTLE(new Drink(new int[] {4243, 1980}, new EnergyEffect(10))), CUP_OF_TEA_NETTLE(new Drink(new int[] {4242, 1980}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
NETTLE_TEA(new Drink(new int[] {4239, 1923}, new NettleTeaEffect())), CUP_OF_TEA_MILKY_NETTLE(new Drink(new int[] {4243, 1980}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
NETTLE_TEA_MILKY(new Drink(new int[] {4240, 1980}, new NettleTeaEffect())), CUP_OF_TEA_NETTLE_PORCELAIN(new Drink(new int[] {4245, 4244}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
CUP_OF_TEA_MILKY_NETTLE_PORCELAIN(new Drink(new int[] {4246, 4244}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
NETTLE_TEA(new Drink(new int[] {4239, 1923}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
NETTLE_TEA_MILKY(new Drink(new int[] {4240, 1923}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
CUP_OF_TEA_CLAY(new Drink(new int[] {7730, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")), CUP_OF_TEA_CLAY(new Drink(new int[] {7730, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")),
CUP_OF_TEA_CLAY_MILKY(new Drink(new int[] {7731, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0))), CUP_OF_TEA_CLAY_MILKY(new Drink(new int[] {7731, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")),
CUP_OF_TEA_WHITE(new Drink(new int[] {7733, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")), CUP_OF_TEA_WHITE(new Drink(new int[] {7733, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")),
CUP_OF_TEA_WHITE_MILKY(new Drink(new int[] {7734, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0))), CUP_OF_TEA_WHITE_MILKY(new Drink(new int[] {7734, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")),
CUP_OF_TEA_GOLD(new Drink(new int[] {7736, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")), CUP_OF_TEA_GOLD(new Drink(new int[] {7736, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")),
CUP_OF_TEA_GOLD_MILKY(new Drink(new int[] {7737, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0))), CUP_OF_TEA_GOLD_MILKY(new Drink(new int[] {7737, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")),
/** Miscellaneous */ /** Miscellaneous */
CHOCOLATE_BAR(new Food(new int[] {1973}, new HealingEffect(3))), CHOCOLATE_BAR(new Food(new int[] {1973}, new HealingEffect(3))),
@ -306,6 +319,7 @@ public enum Consumables {
TCHIKI_MONKEY_PASTE(new Food(new int[] {7575}, new HealingEffect(5), "You eat the Tchiki monkey nut paste. It sticks to the roof of your mouth.")), TCHIKI_MONKEY_PASTE(new Food(new int[] {7575}, new HealingEffect(5), "You eat the Tchiki monkey nut paste. It sticks to the roof of your mouth.")),
OOMLIE_WRAP(new Food(new int[] {Items.COOKED_OOMLIE_WRAP_2343}, new MultiEffect(new HealingEffect(14), new AchievementEffect(DiaryType.KARAMJA, 2, 2)))), OOMLIE_WRAP(new Food(new int[] {Items.COOKED_OOMLIE_WRAP_2343}, new MultiEffect(new HealingEffect(14), new AchievementEffect(DiaryType.KARAMJA, 2, 2)))),
ROE(new Food(new int[]{11324}, new HealingEffect(3))), ROE(new Food(new int[]{11324}, new HealingEffect(3))),
CAVIAR(new Food(new int[]{11326}, new HealingEffect(5))),
EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))), EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))),
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))), CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))),
EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))), EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))),
@ -342,7 +356,7 @@ public enum Consumables {
ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1)))), ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1)))),
ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))), ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))),
GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))), GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))),
MAGIC_ESS(new Potion(new int[] {11491, 11489}, new SkillEffect(Skills.MAGIC,3,0))), MAGIC_ESS(new Potion(new int[] {9021, 9022, 9023, 9024}, new SkillEffect(Skills.MAGIC,3,0))),
SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25, true), new AddTimerEffect("poison:immunity", secondsToTicks(90)), new RemoveTimerEffect("disease")))), SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25, true), new AddTimerEffect("poison:immunity", secondsToTicks(90)), new RemoveTimerEffect("disease")))),
SUPER_ENERGY(new Potion(new int[] {3016, 3018, 3020, 3022}, new EnergyEffect(20))), SUPER_ENERGY(new Potion(new int[] {3016, 3018, 3020, 3022}, new EnergyEffect(20))),
BLAMISH_OIL(new FakeConsumable(1582, new String[] {"You know... I'd really rather not."})), BLAMISH_OIL(new FakeConsumable(1582, new String[] {"You know... I'd really rather not."})),
@ -365,9 +379,13 @@ public enum Consumables {
SUPER_ENERGY_MIX(new BarbarianMix(new int[] {11481, 11483}, new MultiEffect(new EnergyEffect(20), new HealingEffect(6)))), SUPER_ENERGY_MIX(new BarbarianMix(new int[] {11481, 11483}, new MultiEffect(new EnergyEffect(20), new HealingEffect(6)))),
HUNTING_MIX(new BarbarianMix(new int[] {11517, 11519}, new MultiEffect(new SkillEffect(Skills.HUNTER, 3, 0), new HealingEffect(6)))), HUNTING_MIX(new BarbarianMix(new int[] {11517, 11519}, new MultiEffect(new SkillEffect(Skills.HUNTER, 3, 0), new HealingEffect(6)))),
SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))), SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))),
ANTIDOTE_PLUS_MIX(new BarbarianMix(new int[] {11501, 11503}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(9)), new RandomHealthEffect(3, 7)))), ANTIDOTE_PLUS_MIX(new BarbarianMix(new int[] {11501, 11503}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(9)), new HealingEffect(6)))),
ANTIP_SUPERMIX(new BarbarianMix(new int[] {11473, 11475}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(6)), new RandomHealthEffect(3, 7)))), ANTIP_SUPERMIX(new BarbarianMix(new int[] {11473, 11475}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(6)), new HealingEffect(6)))),
ANTIFIRE_MIX(new BarbarianMix(new int[] {11505, 11507}, new MultiEffect(new AddTimerEffect("dragonfire:immunity", 600, true), new RandomHealthEffect(3, 7)))), ANTIFIRE_MIX(new BarbarianMix(new int[] {11505, 11507}, new MultiEffect(new AddTimerEffect("dragonfire:immunity", 600, true), new HealingEffect(6)))),
MAGIC_ESS_MIX(new BarbarianMix(new int[] {11489, 11491}, new MultiEffect(new SkillEffect(Skills.MAGIC, 3, 0), new HealingEffect(6)))),
SUPER_DEF_MIX(new BarbarianMix(new int[] {11497, 11499}, new MultiEffect(new SkillEffect(Skills.DEFENCE, 5, 0.15), new HealingEffect(6)))),
RANGING_MIX(new BarbarianMix(new int[] {11509, 11511}, new MultiEffect(new SkillEffect(Skills.RANGE, 4, 0.1), new HealingEffect(6)))),
MAGIC_MIX(new BarbarianMix(new int[] {11513, 11515}, new MultiEffect(new SkillEffect(Skills.MAGIC, 4, 0), new HealingEffect(6)))),
/** Stealing creation potions */ /** Stealing creation potions */
SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))), SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))),

View file

@ -1,20 +0,0 @@
package content.data.consumables.effects;
import core.game.consumable.ConsumableEffect;
import core.game.node.entity.player.Player;
public class NettleTeaEffect extends ConsumableEffect {
private final static int healing = 3;
@Override
public void activate(Player p) {
final ConsumableEffect effect = p.getSkills().getLifepoints() < p.getSkills().getMaximumLifepoints() ? new MultiEffect(new HealingEffect(3), new EnergyEffect(5)) : new HealingEffect(3);
effect.activate(p);
}
@Override
public int getHealthEffectValue(Player player) {
return healing;
}
}

View file

@ -1,103 +0,0 @@
package content.data.skill;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.game.world.repository.Repository;
/**
* Represents the skilling pets obtained randomly.
* @author Empathy
*
*/
public enum SkillingPets {
BABY_RED_CHINCHOMPA(new Item(14823), "Baby Chinchompa", Skills.HUNTER),
BABY_GREY_CHINCHOMPA(new Item(14824), "Baby Chinchompa", Skills.HUNTER),
BEAVER(new Item(14821), "Beaver", Skills.WOODCUTTING),
GOLEM(new Item(14822), "Rock Golem", Skills.MINING),
HERON(new Item(14827), "Heron", Skills.FISHING);
/**
* The pet item drop.
*/
private final Item pet;
/**
* The name.
*/
private final String name;
/**
* The skill.
*/
private final int skill;
/**
* Constructs a new {@code SkillingPets} object.
* @param skill The skill id.
* @param pet The pet item.
*/
SkillingPets(Item pet, String name, int skill) {
this.pet = pet;
this.name = name;
this.skill = skill;
}
/**
* Checks the pet drop.
* @param player The player.
* @param pet The pet drop to check.
*/
public static void checkPetDrop(Player player, SkillingPets pet) {
if (pet == null) {
return;
}
int defaultChance = 15000;
int newChance = (defaultChance / player.getSkills().getStaticLevel(pet.getSkill()) * 55);
int outOf = (newChance > defaultChance ? defaultChance : newChance);
int getChance = outOf;
if (getChance != 1) {
return;
}
if (player.hasItem(pet.getPet())) {
return;
}
if (player.getFamiliarManager().hasFamiliar() && player.getInventory().isFull()) {
return;
}
if (player.getFamiliarManager().hasFamiliar()) {
if (player.getFamiliarManager().getFamiliar().getName().equalsIgnoreCase(pet.getName())) {
return;
}
player.getInventory().add(pet.getPet());
player.sendNotificationMessage("You feel something weird sneaking into your backpack.");
} else {
player.getFamiliarManager().summon(pet.getPet(), true);
player.sendNotificationMessage("You have a funny feeling like you're being followed.");
}
Repository.sendNews(player.getUsername() + " has found a " + pet.getPet().getName() + "!");
}
/**
* @return the pet
*/
public Item getPet() {
return pet;
}
/**
* @return the pet name.
*/
public String getName() {
return name;
}
/**
* @return the skill.
*/
public int getSkill() {
return skill;
}
}

View file

@ -45,35 +45,35 @@ class ChampionChallengeListener : InteractionListener, MapArea {
private val IMP_SCROLL_TEXT = arrayOf( private val IMP_SCROLL_TEXT = arrayOf(
"How about picking on someone your own size? I'll", "How about picking on someone your own size? I'll",
"see you at the Champion's Guild.", "see you at the Champions' Guild.",
"", "",
"Champion of Imps" "Champion of Imps"
) )
private val GOBLIN_SCROLL_TEXT = arrayOf( private val GOBLIN_SCROLL_TEXT = arrayOf(
"Fight me if you think you can human, I'll wait", "Fight me if you think you can human, I'll wait",
"for you in the Champion's Guild.", "for you in the Champions' Guild.",
"", "",
"Champion of Goblins" "Champion of Goblins"
) )
private val SKELETON_SCROLL_TEXT = arrayOf( private val SKELETON_SCROLL_TEXT = arrayOf(
"I'll be waiting at the Champions' Guild to", "I'll be waiting at the Champions' Guild to collect",
"collect your bones.", "your bones.",
"", "",
"Champion of Skeletons" "Champion of Skeletons"
) )
private val ZOMBIE_SCROLL_TEXT = arrayOf( private val ZOMBIE_SCROLL_TEXT = arrayOf(
"You come to Champions' Guild, you fight me,", "You come to Champions' Guild, you fight me, I",
"I squish you, I get brains!", "squish you, I get brains!",
"", "",
"Champion of Zombies" "Champion of Zombies"
) )
private val GIANT_SCROLL_TEXT = arrayOf( private val GIANT_SCROLL_TEXT = arrayOf(
"Get yourself to the Champions' Guild, if you", "Get yourself to the Champions' Guild, if you dare",
"dare to face me puny human.", "to face me puny human.",
"", "",
"Champion of Giants" "Champion of Giants"
) )
@ -93,21 +93,22 @@ class ChampionChallengeListener : InteractionListener, MapArea {
) )
private val EARTH_WARRIOR_TEXT = arrayOf( private val EARTH_WARRIOR_TEXT = arrayOf(
"I challenge you to a duel, come to the arena beneath", "I challenge you to a duel, come to the arena",
"the Champion's Guild and fight me if you dare.", "beneath the Champions' Guild and fight me if you",
"dare.",
"", "",
"Champion of Earth Warriors" "Champion of Earth Warriors"
) )
private val JOGRE_SCROLL_TEXT = arrayOf( private val JOGRE_SCROLL_TEXT = arrayOf(
"You think you can defeat me? Come to the", "You think you can defeat me? Come to the",
"Champion's Guild and prove it!", "Champions' Guild and prove it!",
"", "",
"Champion of Jogres" "Champion of Jogres"
) )
private val LESSER_DEMON_SCROLL_TEXT = arrayOf( private val LESSER_DEMON_SCROLL_TEXT = arrayOf(
"Come to the Champion's Guild so I can banish", "Come to the Champions' Guild so I can banish",
"you mortal!", "you mortal!",
"", "",
"Champion of Lesser Demons" "Champion of Lesser Demons"

View file

@ -70,7 +70,7 @@ class ChampionScrollsDropHandler : ChampionScrollsEventHookBase() {
NPCs.CAVE_GOBLIN_GUARD_2073, NPCs.CAVE_GOBLIN_GUARD_2074, NPCs.CAVE_GOBLIN_GUARD_2073, NPCs.CAVE_GOBLIN_GUARD_2074,
NPCs.GOBLIN_GUARD_489, NPCs.GOBLIN_GUARD_6496, NPCs.GOBLIN_GUARD_6497, NPCs.GOBLIN_GUARD_6496, NPCs.GOBLIN_GUARD_6497,
NPCs.SERGEANT_GRIMSPIKE_6265, NPCs.SERGEANT_GRIMSPIKE_6265,
NPCs.SERGEANT_STEELWILL_6263, NPCs.SERGEANT_STEELWILL_6263,
NPCs.SERGEANT_STRONGSTACK_6261 NPCs.SERGEANT_STRONGSTACK_6261

View file

@ -27,24 +27,24 @@ class LarxusDialogue(val ChallengeStart: Boolean = false) : DialogueFile() {
0 -> { 0 -> {
face(findNPC(NPCs.LARXUS_3050)!!, player!!, 1) face(findNPC(NPCs.LARXUS_3050)!!, player!!, 1)
for (i in scrolls)when{ for (i in scrolls)when{
inInventory(player!!,Items.CHAMPION_SCROLL_6798) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use prayer's. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6798) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Prayers. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6799) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only weapons. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6799) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to take Weapons, no other items are allowed. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6800) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only melee combat skill. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6800) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Melee attacks, no Ranged or Magic. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6801) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only magic skill. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6801) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Magic attacks, no Melee or Ranged. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6802) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use melee combat skills. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6802) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Melee attacks. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6803) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use weapons with special attack. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6803) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Special Attacks. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6804) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use ranged skill. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6804) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Ranged attacks. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6805) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only equipment. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6805) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed any Weapons or Armour. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6806) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only ranged skill. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6806) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Ranged attacks, no Melee or Magic. Do you still want to proceed?").also { stage = 1 }
inInventory(player!!,Items.CHAMPION_SCROLL_6807) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use magic skill. Do you still want to proceed?").also { stage = 1 } inInventory(player!!,Items.CHAMPION_SCROLL_6807) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Magic attacks. Do you still want to proceed?").also { stage = 1 }
else -> { else -> {
sendMessage(player!!, "Nothing interesting happens.").also { stage = END_DIALOGUE } } sendMessage(player!!, "Nothing interesting happens.").also { stage = END_DIALOGUE } }
} }
} }
1 -> options("Yes, let me at him!", "No, thanks I'll pass.").also { stage = 2 } 1 -> options("Yes, let me at him!", "No thanks, I'll pass.").also { stage = 2 }
2 -> when (buttonID) { 2 -> when (buttonID) {
1 -> playerl("Yes, let me at him!").also { stage = 3 } 1 -> playerl("Yes, let me at him!").also { stage = 3 }
2 -> playerl("No, thanks I'll pass.").also { stage = END_DIALOGUE } 2 -> playerl("No thanks, I'll pass.").also { stage = END_DIALOGUE }
} }
3 -> npcl("Your challenger is ready, please go down through the trapdoor when you're ready.").also { stage = 4 } 3 -> npcl("Your challenger is ready, please go down through the trapdoor when you're ready.").also { stage = 4 }
4 -> { 4 -> {
@ -65,7 +65,7 @@ class LarxusDialogue(val ChallengeStart: Boolean = false) : DialogueFile() {
3 -> playerl("Nothing thanks.").also { stage = END_DIALOGUE } 3 -> playerl("Nothing thanks.").also { stage = END_DIALOGUE }
} }
3 -> npcl("Well pass it here and we'll get you started.").also { stage = END_DIALOGUE } 3 -> npcl("Well pass it here and we'll get you started.").also { stage = END_DIALOGUE }
4 -> npcl("This is the champions' arena, the champions of various, races use it to duel those they deem worthy of the, honour.").also { stage = END_DIALOGUE } 4 -> npcl("This is the champions' arena. The champions of various races use it to duel those they deem worthy of the honour. If you find a challenge scroll in your travels, bring it here to face your challenger.").also { stage = END_DIALOGUE }
} }
} }
} }

View file

@ -3,8 +3,6 @@ package content.global.activity.cchallange.npc
import core.api.* import core.api.*
import core.game.node.entity.Entity import core.game.node.entity.Entity
import core.game.node.entity.combat.BattleState import core.game.node.entity.combat.BattleState
import core.game.node.entity.combat.CombatStyle
import core.game.node.entity.combat.equipment.WeaponInterface
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
@ -63,21 +61,11 @@ class ImpChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,
super.checkImpact(state) super.checkImpact(state)
val player = state.attacker val player = state.attacker
if (player is Player) { if (player is Player) {
val w = player.getExtension<WeaponInterface>(WeaponInterface::class.java)
if (state.style == CombatStyle.MELEE || state.style == CombatStyle.MAGIC || state.style == CombatStyle.RANGE) { //somehow the maximumHit is determined to be zero by this point if you're using a melee special attack.
if (state.maximumHit == 0) {
state.neutralizeHits() state.neutralizeHits()
state.estimatedHit = state.maximumHit sendMessage(player, "Larxus said you couldn't use special attacks in this duel.")
}
if (w.weaponInterface.interfaceId == 10) {
sendMessage(player, "You cannot use special attack in this challenge.")
if (state.estimatedHit > -1) {
state.estimatedHit = 0
return
}
if (state.secondaryHit > -1) {
state.secondaryHit = 0
return
}
} }
} }
} }

View file

@ -1,8 +1,6 @@
package content.global.activity.cchallange.npc package content.global.activity.cchallange.npc
import core.api.* import core.api.*
import core.game.container.impl.EquipmentContainer
import core.game.global.action.EquipHandler
import core.game.node.entity.Entity import core.game.node.entity.Entity
import core.game.node.entity.combat.BattleState import core.game.node.entity.combat.BattleState
import core.game.node.entity.npc.AbstractNPC import core.game.node.entity.npc.AbstractNPC
@ -62,12 +60,11 @@ class LesserDemonChampionNPC(id: Int = 0, location: Location? = null) : Abstract
super.checkImpact(state) super.checkImpact(state)
val player = state.attacker val player = state.attacker
if (player is Player) { if (player is Player) {
if (!player.equipment[3].hasItemPlugin()) { if (player.equipment.isEmpty) {
state.neutralizeHits() state.neutralizeHits()
state.estimatedHit = state.maximumHit state.estimatedHit = state.maximumHit
} else { } else {
EquipHandler.unequip(player, EquipmentContainer.SLOT_WEAPON, id) sendMessage(player, "You cannot wear any equipment in this challenge.")
sendMessage(player, "You cannot use weapons in this challenge.")
if (state.estimatedHit > -1) { if (state.estimatedHit > -1) {
state.estimatedHit = 0 state.estimatedHit = 0
return return

View file

@ -63,8 +63,8 @@ class ZombieChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(i
val player = state.attacker val player = state.attacker
if (player is Player) { if (player is Player) {
if (state.style == CombatStyle.MELEE || state.style == CombatStyle.RANGE) { if (state.style == CombatStyle.MELEE || state.style == CombatStyle.RANGE) {
state.estimatedHit = state.maximumHit
state.neutralizeHits() state.neutralizeHits()
state.estimatedHit = state.maximumHit
} }
if (state.style == CombatStyle.MAGIC) { if (state.style == CombatStyle.MAGIC) {
sendMessage(player, "You cannot use spells in this challenge.") sendMessage(player, "You cannot use spells in this challenge.")

View file

@ -30,7 +30,7 @@ class PenguinManager{
return tagMapping[Penguin.forLocation(location)?.ordinal]?.contains(player.username.toLowerCase()) ?: false return tagMapping[Penguin.forLocation(location)?.ordinal]?.contains(player.username.toLowerCase()) ?: false
} }
private fun updateStoreFile(){ fun updateStoreFile(){
val jsonTags = JSONArray() val jsonTags = JSONArray()
tagMapping.filter { it.value.isNotEmpty() }.forEach { (ordinal,taggers) -> tagMapping.filter { it.value.isNotEmpty() }.forEach { (ordinal,taggers) ->
log(this::class.java, Log.FINE, "$ordinal - ${taggers.first()}") log(this::class.java, Log.FINE, "$ordinal - ${taggers.first()}")

View file

@ -44,18 +44,65 @@ enum class Penguin(val id: Int, val hint: String, val location: Location){
BUSH_8(NPCs.BUSH_8105,"located in the kingdom of Asgarnia.",Location.create(2951, 3511, 0)), BUSH_8(NPCs.BUSH_8105,"located in the kingdom of Asgarnia.",Location.create(2951, 3511, 0)),
BUSH_9(NPCs.BUSH_8105,"located in the northern desert.",Location.create(3350, 3311, 0)), BUSH_9(NPCs.BUSH_8105,"located in the northern desert.",Location.create(3350, 3311, 0)),
BUSH_10(NPCs.BUSH_8105,"located somewhere in the kingdom of Kandarin.",Location.create(2633, 3501, 0)), BUSH_10(NPCs.BUSH_8105,"located somewhere in the kingdom of Kandarin.",Location.create(2633, 3501, 0)),
BUSH_11(NPCs.BUSH_8105,"located south of Ardougne.",Location.create(2440, 3206, 0)), BUSH_11(NPCs.BUSH_8105,"located where wizards study.",Location.create(3112, 3149, 0)),
BUSH_12(NPCs.BUSH_8105,"located where wizards study.",Location.create(3112, 3149, 0)),
ROCK_1(NPCs.ROCK_8109,"located where the Imperial Guard train.",Location.create(2852, 3578, 0)), ROCK_1(NPCs.ROCK_8109,"located where the Imperial Guard train.",Location.create(2852, 3578, 0)),
ROCK_2(NPCs.ROCK_8109,"located in the kingdom of Misthalin.",Location.create(3356, 3416, 0)), ROCK_2(NPCs.ROCK_8109,"located in the kingdom of Misthalin.",Location.create(3356, 3416, 0)),
ROCK_3(NPCs.ROCK_8109,"located near some ogres.",Location.create(2631, 2980, 0)), ROCK_3(NPCs.ROCK_8109,"located near some ogres.",Location.create(2631, 2980, 0)), //potentially incorrect location
ROCK_4(NPCs.ROCK_8109,"located in the Kingdom of Asgarnia.",Location.create(3013, 3501, 0)), ROCK_4(NPCs.ROCK_8109,"located in the Kingdom of Asgarnia.",Location.create(3013, 3501, 0)),
ROCK_5(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2532, 3630, 0)), ROCK_5(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2532, 3630, 0)),
CRATE_1(NPCs.CRATE_8108,"located in the kingdom of Misthalin.",Location.create(3112, 3332, 0)), CRATE_1(NPCs.CRATE_8108,"located in the kingdom of Misthalin.",Location.create(3112, 3332, 0)),
CRATE_2(NPCs.CRATE_8108,"located in the Kingdom of Misthalin.",Location.create(3305, 3508, 0)), CRATE_2(NPCs.CRATE_8108,"located in the Kingdom of Misthalin.",Location.create(3305, 3508, 0)),
BARREL_1(NPCs.CRATE_8108,"located where no weapons may go.",Location.create(2806, 3383, 0)), CRATE_3(NPCs.CRATE_8108,"located south of Ardougne.",Location.create(2440, 3206, 0)),
BARREL_1(NPCs.BARREL_8104,"located where no weapons may go.",Location.create(2806, 3383, 0)),
TOADSTOOL_1(NPCs.TOADSTOOL_8110,"located in the kingdom of Misthalin.",Location.create(3156, 3178, 0)), TOADSTOOL_1(NPCs.TOADSTOOL_8110,"located in the kingdom of Misthalin.",Location.create(3156, 3178, 0)),
TOADSTOOL_2(NPCs.TOADSTOOL_8110,"located in the fairy realm.",Location.create(2409, 4462, 0)); TOADSTOOL_2(NPCs.TOADSTOOL_8110,"located in the fairy realm.",Location.create(2409, 4462, 0)), //potentially a spawn from 2010
BUSH_12(NPCs.BUSH_8105,"located on an island.",Location.create(2534, 3871, 0)),
BARREL_2(NPCs.BARREL_8104,"located near the ghost town.",Location.create(3654, 3491, 0)),
BUSH_13(NPCs.BUSH_8105,"located where bloodsuckers rule.",Location.create(3600, 3487, 0)),
BUSH_14(NPCs.BUSH_8105,"located on islands where brothers quarrel.",Location.create(2355, 3848, 0)),
ROCK_6(NPCs.ROCK_8109,"located on a large crescent island.",Location.create(2118, 3943, 0)),
ROCK_7(NPCs.ROCK_8109,"located on islands where brothers quarrel.",Location.create(2357, 3797, 0)),
ROCK_8(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3169, 3650, 0)),
BARREL_3(NPCs.BARREL_8104,"located where pirates feel mostly harmless.",Location.create(3738, 3001, 0)),
CACTUS_3(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3276, 2797, 0)),
TOADSTOOL_3(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2314, 3174, 0)),
BUSH_15(NPCs.BUSH_8105,"located deep in the jungle.",Location.create(2938, 2978, 0)),
TOADSTOOL_4(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2219, 3227, 0)),
BARREL_4(NPCs.BARREL_8104,"located south of Ardougne.",Location.create(2662, 3152, 0)),
//BARREL_5(NPCs.BARREL_8104,"located where monkeys rule.",Location.create(2751, 2700, 0)),
//currently not well accessible, will need to add when Ape Atoll is sorted.
//BUSH_16(NPCs.BUSH_8105,"located on islands where brothers quarrel.",Location.create(2353, 3834, 0)),
//currently not well accessible, will need to add when Neitiznot bridges are fixed.
ROCK_9(NPCs.ROCK_8109,"located near a mountain of wolves.",Location.create(2852, 3504, 0)),
ROCK_10(NPCs.ROCK_8109,"located on islands where brothers quarrel.",Location.create(2413, 3846, 0)),
BUSH_17(NPCs.BUSH_8105,"located near some ogres.",Location.create(2578, 2909, 0)),
CRATE_4(NPCs.CRATE_8108,"located where banana smugglers dwell.",Location.create(2869, 3157, 0)),
//CRATE_5(NPCs.CRATE_8108,"located near the island of Dragontooth.",Location.create(3824, 3562, 0)),
//current not accessible, will need to add when Dragontooth island is sorted.
ROCK_11(NPCs.ROCK_8109,"located where bloodsuckers rule.",Location.create(3550, 3439, 0)),
TOADSTOOL_5(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2181, 3172, 0)),
BUSH_18(NPCs.BUSH_8105,"located where bloodsuckers rule.",Location.create(3472, 3392, 0)),
BUSH_19(NPCs.BUSH_8105,"located near Port Sarim.",Location.create(2989, 3121, 0)),
CRATE_6(NPCs.CRATE_8108,"located where fishers colonise.",Location.create(2322, 3658, 0)),
ROCK_12(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2675, 3717, 0)),
ROCK_13(NPCs.ROCK_8109,"located near the pointy-eared ones.",Location.create(2296, 3270, 0)),
CRATE_7(NPCs.CRATE_8108,"located where bloodsuckers rule.",Location.create(3637, 3486, 0)),
TOADSTOOL_6(NPCs.TOADSTOOL_8110,"located where bloodsuckers rule.",Location.create(3416, 3437, 0)),
BUSH_20(NPCs.BUSH_8105,"located where monkeys rule.",Location.create(2802, 2806, 0)),
ROCK_14(NPCs.ROCK_8109,"located near some ogres.",Location.create(2438, 3050, 0)),
CACTUS_4(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3252, 2963, 0)),
ROCK_15(NPCs.ROCK_8109,"located near some ogres.",Location.create(2340, 3064, 0)),
ROCK_16(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3108, 3837, 0)),
CACTUS_5(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3433, 3000, 0)),
CACTUS_6(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3274, 2813, 0)),
ROCK_17(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3019, 3866, 0)),
ROCK_18(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(2991, 3824, 0)),
BUSH_21(NPCs.BUSH_8105,"located north of Ardougne.",Location.create(2398, 3361, 0)),
ROCK_19(NPCs.ROCK_8109,"located near the coast.",Location.create(2733, 3283, 0)),
ROCK_20(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3236, 3927, 0));
companion object { companion object {
private val locationMap = values().map { it.location.toString() to it }.toMap() private val locationMap = values().map { it.location.toString() to it }.toMap()

View file

@ -49,7 +49,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
"South-west Varrock mine" to Location.create(3176, 3362, 0), // South-west Varrock mine / Champion's Guild mine "South-west Varrock mine" to Location.create(3176, 3362, 0), // South-west Varrock mine / Champion's Guild mine
"Varrock east bank" to Location.create(3259, 3407, 0), // Varrock east bank / Rune shop "Varrock east bank" to Location.create(3259, 3407, 0), // Varrock east bank / Rune shop
"Lumbridge Swamp south-east mine" to Location.create(3227, 3150, 0), // Lumbridge Swamp south-east mine "Lumbridge Swamp south-east mine" to Location.create(3227, 3150, 0), // Lumbridge Swamp south-east mine
//"Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter) "Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter)
"Canifis Bank" to Location.create(3504, 3487, 0), // Canifis bank "Canifis Bank" to Location.create(3504, 3487, 0), // Canifis bank
"Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires quest to enter but is currently accessible for Slayer) "Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires quest to enter but is currently accessible for Slayer)
"Gnome stronghold Bank" to Location.create(2460, 3432, 0), // Gnome stronghold bank "Gnome stronghold Bank" to Location.create(2460, 3432, 0), // Gnome stronghold bank

View file

@ -6,6 +6,7 @@ import core.game.node.entity.player.Player
import core.game.node.entity.skill.SkillPulse import core.game.node.entity.skill.SkillPulse
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import content.data.skill.SkillingTool import content.data.skill.SkillingTool
import core.ServerConstants
import core.game.node.item.Item import core.game.node.item.Item
import core.tools.RandomFunction import core.tools.RandomFunction
import org.rs09.consts.Items import org.rs09.consts.Items
@ -13,6 +14,9 @@ import core.game.world.GameWorld
import core.game.world.repository.Repository import core.game.world.repository.Repository
import core.tools.colorize import core.tools.colorize
// TODO: Shooting stars should roll for bonus gems while mining
// See: https://youtu.be/6OqZ2TGc6fM?si=U8nB5IDQREhWXApD
/** /**
* The pulse used to handle mining shooting stars. * The pulse used to handle mining shooting stars.
*/ */
@ -46,9 +50,8 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
//checks if the star has been discovered and if not, awards the bonus xp. Xp can be awarded regardless of mining level as per the wiki. //checks if the star has been discovered and if not, awards the bonus xp. Xp can be awarded regardless of mining level as per the wiki.
if (!star.isDiscovered && !player.isArtificial) { if (!star.isDiscovered && !player.isArtificial) {
val bonusXp = 75 * player.skills.getStaticLevel(Skills.MINING) val bonusXp = 75 * player.skills.getStaticLevel(Skills.MINING)
player.incrementAttribute("/save:shooting-star:bonus-xp", bonusXp) rewardXP(player, Skills.MINING, bonusXp.toDouble())
Repository.sendNews(player.username + " is the discoverer of the crashed star near " + star.location + "!") Repository.sendNews(player.username + " is the discoverer of the crashed star near " + star.location + "!")
player.sendMessage("You have ${player.skills.experienceMultiplier * player.getAttribute("shooting-star:bonus-xp", 0).toDouble()} bonus xp towards mining stardust.")
ShootingStarPlugin.submitScoreBoard(player) ShootingStarPlugin.submitScoreBoard(player)
star.isDiscovered = true star.isDiscovered = true
ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered
@ -88,6 +91,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
val bonusXp = player.getAttribute("shooting-star:bonus-xp", 0).toDouble() val bonusXp = player.getAttribute("shooting-star:bonus-xp", 0).toDouble()
var xp = star.level.exp.toDouble() var xp = star.level.exp.toDouble()
if(bonusXp > 0) { if(bonusXp > 0) {
// legacy: shooting star bonus xp used to be handed out in an inauthentic way; see GL !2092
val delta = Math.min(bonusXp, xp) val delta = Math.min(bonusXp, xp)
player.incrementAttribute("/save:shooting-star:bonus-xp", (-delta).toInt()) player.incrementAttribute("/save:shooting-star:bonus-xp", (-delta).toInt())
xp += delta xp += delta
@ -100,7 +104,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
if (ShootingStarPlugin.getStarDust(player) < 200) { if (ShootingStarPlugin.getStarDust(player) < 200) {
player.inventory.add(Item(ShootingStarPlugin.STAR_DUST, 1)) player.inventory.add(Item(ShootingStarPlugin.STAR_DUST, 1))
} }
if(!inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && !inBank(player, Items.ANCIENT_BLUEPRINT_14651)){ if (ServerConstants.SHOOTING_STAR_RING && hasAnItem(player, Items.ANCIENT_BLUEPRINT_14651).container == null) {
rollBlueprint(player) rollBlueprint(player)
} }
@ -130,7 +134,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
override fun message(type: Int) { override fun message(type: Int) {
when (type) { when (type) {
0 -> player.packetDispatch.sendMessage("You swing your pickaxe at the rock...") 0 -> player.packetDispatch.sendMessage("You swing your pickaxe at the rock.")
} }
} }

View file

@ -97,7 +97,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
fun teleportToStar(player: Player) { fun teleportToStar(player: Player) {
val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) { val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) {
"canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")} "canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")}
//"burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} //disabled: crash "burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)}
"crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)} "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)}
"lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)} "lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)}
"jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} "jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)}
@ -120,7 +120,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ } 1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ }
2 -> player.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ } 2 -> player.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ }
3 -> when (buttonID) { 3 -> when (buttonID) {
1 -> end().also { teleportToStar(player) } 1 -> teleportToStar(player)
2 -> end() 2 -> end()
} }
} }
@ -133,16 +133,16 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
} }
override fun defineCommands() { override fun defineCommands() {
define("tostar", Privilege.ADMIN) { player, _ -> define("tostar", Privilege.ADMIN, description = "Teleports you adjacent to the currently active star.") { player, _ ->
teleport(player, star.starObject.location.transform(1,1,0)) teleport(player, star.starObject.location.transform(1,1,0))
} }
define("submit", Privilege.ADMIN) { _, _ -> define("submit", Privilege.ADMIN, description = "Rebuilds and fires the shooting star event immediately.") { _, _ ->
star.rebuildVars() star.rebuildVars()
star.fire() star.fire()
} }
define("resetsprite", Privilege.ADMIN) { player, _ -> define("resetsprite", Privilege.ADMIN, description = "Resets your star sprite reward cooldown.") { player, _ ->
player.savedData.globalData.starSpriteDelay = 0L player.savedData.globalData.starSpriteDelay = 0L
} }
} }

View file

@ -2,27 +2,58 @@ package content.global.ame
import core.ServerConstants import core.ServerConstants
import core.api.* import core.api.*
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager.TeleportType import core.game.node.entity.player.link.TeleportManager.TeleportType
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Sounds
fun kidnapPlayer(player: Player, loc: Location, type: TeleportType) { fun kidnapPlayer(npc: NPC, player: Player, dest: Location, playerLine: String? = null, callback: (player: Player, npc: NPC) -> Unit) {
clearScripts(player)
val lockDuration = if (playerLine != null) 4 else 6
lock(player, lockDuration)
queueScript(player, 1, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
if (playerLine != null) {
sendChat(player, playerLine)
return@queueScript delayScript(player, 2)
}
return@queueScript delayScript(player, 0)
}
1 -> {
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
2 -> {
setAttribute(player, "kidnapped-by-random", true) setAttribute(player, "kidnapped-by-random", true)
if (getAttribute(player, "/save:original-loc", null) == null) { if (getAttribute<Location?>(player, "/save:original-loc", null) == null) {
setAttribute(player, "/save:original-loc", player.location) setAttribute(player, "/save:original-loc", player.location)
} }
teleport(player, loc, type) teleport(player, dest, TeleportType.INSTANT)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player, 8941)
resetAnimator(player)
callback(player, npc)
return@queueScript delayScript(player, 2)
}
3 -> {
removeAttribute(player, "kidnapped-by-random") //this is not needed at this point anymore and will reenable the original-loc sanity check tick action
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
} }
fun returnPlayer(player: Player) { fun returnPlayer(player: Player) {
// Prevent returning more than once and sending the player back to HOME_LOCATION
if (getAttribute<Location?>(player, "kidnapped-by-random", null) == null) {
return
}
player.locks.unlockTeleport() player.locks.unlockTeleport()
val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0)) val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION)
teleport(player, destination) teleport(player, destination!!)
unlock(player) unlock(player)
removeAttributes(player, "/save:original-loc", "kidnapped-by-random") removeAttributes(player, "/save:original-loc", "kidnapped-by-random")
} }

View file

@ -1,9 +1,10 @@
package content.global.ame package content.global.ame
import content.global.ame.events.MysteriousOldManNPC import content.global.ame.events.surpriseexam.MysteriousOldManNPC
import core.api.playGlobalAudio import core.api.playGlobalAudio
import core.api.poofClear import core.api.poofClear
import core.api.sendMessage import core.api.sendMessage
import core.api.setAttribute
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.interaction.MovementPulse import core.game.interaction.MovementPulse
import core.game.node.entity.Entity import core.game.node.entity.Entity
@ -19,8 +20,10 @@ import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Graphics import core.game.world.update.flag.context.Graphics
import core.integrations.discord.Discord import core.integrations.discord.Discord
import core.tools.RandomFunction
import core.tools.secondsToTicks import core.tools.secondsToTicks
import core.tools.ticksToCycles import core.tools.ticksToCycles
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
import kotlin.math.ceil import kotlin.math.ceil
import kotlin.math.min import kotlin.math.min
@ -43,6 +46,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
event.loot = loot event.loot = loot
event.player = player event.player = player
event.spawnLocation = RegionManager.getSpawnLocation(player, this) event.spawnLocation = RegionManager.getSpawnLocation(player, this)
setAttribute(event, "spawned-by-ame", true)
return event return event
} }
@ -101,7 +105,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
} }
open fun onTimeUp() { open fun onTimeUp() {
noteAndTeleport()
terminate() terminate()
} }
@ -144,4 +147,23 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1 val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1
return ids[index] return ids[index]
} }
fun sayLine(npc: NPC, phrases: Array<String>, hasOpeningPhrase: Boolean, hasOverTimePhrase: Boolean) {
if (!timerPaused && (ticksLeft % 20 == 0 || ticksLeft <= 2)) { //unless the Certer interface is up, speak every 20 ticks, or in the 2nd-to-last tick before attack/note-&-teleport
var playDwarfWhistle = true
if (ticksLeft == secondsToTicks(180) && hasOpeningPhrase) {
sendChat(phrases[0])
} else if (ticksLeft <= 2 && hasOverTimePhrase) {
sendChat(phrases[phrases.size - 1])
playDwarfWhistle = false
} else {
val start = if (hasOpeningPhrase) 0 else 1
val end = if (hasOverTimePhrase) phrases.size - 2 else phrases.size - 1
sendChat(phrases[RandomFunction.random(start, end + 1)])
}
if (npc.id == NPCs.DRUNKEN_DWARF_956 && playDwarfWhistle) {
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
}
}
}
} }

View file

@ -1,7 +1,7 @@
package content.global.ame package content.global.ame
import org.rs09.consts.Items import org.rs09.consts.Items
import content.global.ame.events.MysteriousOldManNPC import content.global.ame.events.surpriseexam.MysteriousOldManNPC
import content.global.ame.events.certer.CerterNPC import content.global.ame.events.certer.CerterNPC
import content.global.ame.events.drilldemon.SergeantDamienNPC import content.global.ame.events.drilldemon.SergeantDamienNPC
import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC
@ -10,6 +10,7 @@ import content.global.ame.events.evilchicken.EvilChickenNPC
import content.global.ame.events.freakyforester.FreakyForesterNPC import content.global.ame.events.freakyforester.FreakyForesterNPC
import content.global.ame.events.maze.MazeNPC import content.global.ame.events.maze.MazeNPC
import content.global.ame.events.genie.GenieNPC import content.global.ame.events.genie.GenieNPC
import content.global.ame.events.candlelight.PiousPeteNPC
import content.global.ame.events.pillory.PilloryNPC import content.global.ame.events.pillory.PilloryNPC
import content.global.ame.events.rickturpentine.RickTurpentineNPC import content.global.ame.events.rickturpentine.RickTurpentineNPC
import content.global.ame.events.rivertroll.RiverTrollRENPC import content.global.ame.events.rivertroll.RiverTrollRENPC
@ -21,6 +22,7 @@ import content.global.ame.events.strangeplant.StrangePlantNPC
import content.global.ame.events.swarm.SwarmNPC import content.global.ame.events.swarm.SwarmNPC
import content.global.ame.events.treespirit.TreeSpiritRENPC import content.global.ame.events.treespirit.TreeSpiritRENPC
import content.global.ame.events.zombie.ZombieRENPC import content.global.ame.events.zombie.ZombieRENPC
import core.ServerConstants
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.api.utils.WeightedItem import core.api.utils.WeightedItem
@ -29,6 +31,7 @@ import core.game.node.entity.skill.Skills
enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = null, val skillIds: IntArray = intArrayOf(), val type: String = "") { enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = null, val skillIds: IntArray = intArrayOf(), val type: String = "") {
SANDWICH_LADY(npc = SandwichLadyRENPC()), SANDWICH_LADY(npc = SandwichLadyRENPC()),
GENIE(npc = GenieNPC()), GENIE(npc = GenieNPC()),
CANDLELIGHT(npc = PiousPeteNPC(), skillIds = intArrayOf(Skills.PRAYER)),
CERTER(npc = CerterNPC(), loot = WeightBasedTable.create( CERTER(npc = CerterNPC(), loot = WeightBasedTable.create(
WeightedItem(Items.UNCUT_SAPPHIRE_1623,1,1,3.4), WeightedItem(Items.UNCUT_SAPPHIRE_1623,1,1,3.4),
WeightedItem(Items.KEBAB_1971,1,1,1.7), WeightedItem(Items.KEBAB_1971,1,1,1.7),
@ -82,6 +85,9 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
private fun populateMappings() { private fun populateMappings() {
for (event in values()) { for (event in values()) {
if (!ServerConstants.INAUTHENTIC_CANDLELIGHT_RANDOM && event == CANDLELIGHT) {
continue
}
for (id in event.skillIds) { for (id in event.skillIds) {
val list = skillMap[id] ?: ArrayList<RandomEvents>().also { skillMap[id] = it } val list = skillMap[id] ?: ArrayList<RandomEvents>().also { skillMap[id] = it }
list.add (event) list.add (event)
@ -91,5 +97,4 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
} }
} }
} }
} }

View file

@ -1,5 +1,6 @@
package content.global.ame.events package content.global.ame.events
import core.api.getAttribute
import core.game.node.entity.Entity import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior import core.game.node.entity.npc.NPCBehavior
@ -8,12 +9,12 @@ import org.rs09.consts.NPCs
class HostileRandomEventBehavior : NPCBehavior( class HostileRandomEventBehavior : NPCBehavior(
NPCs.EVIL_CHICKEN_2463, NPCs.EVIL_CHICKEN_2464, NPCs.EVIL_CHICKEN_2465, NPCs.EVIL_CHICKEN_2466, NPCs.EVIL_CHICKEN_2467, NPCs.EVIL_CHICKEN_2468, NPCs.EVIL_CHICKEN_2463, NPCs.EVIL_CHICKEN_2464, NPCs.EVIL_CHICKEN_2465, NPCs.EVIL_CHICKEN_2466, NPCs.EVIL_CHICKEN_2467, NPCs.EVIL_CHICKEN_2468,
NPCs.RIVER_TROLL_391, NPCs.RIVER_TROLL_392, NPCs.RIVER_TROLL_393, NPCs.RIVER_TROLL_394, NPCs.RIVER_TROLL_395, NPCs.RIVER_TROLL_396, NPCs.RIVER_TROLL_391, NPCs.RIVER_TROLL_392, NPCs.RIVER_TROLL_393, NPCs.RIVER_TROLL_394, NPCs.RIVER_TROLL_395, NPCs.RIVER_TROLL_396,
NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418,
NPCs.SHADE_425, NPCs.SHADE_426, NPCs.SHADE_427, NPCs.SHADE_428, NPCs.SHADE_429, NPCs.SHADE_430, NPCs.SHADE_431, NPCs.SHADE_425, NPCs.SHADE_426, NPCs.SHADE_427, NPCs.SHADE_428, NPCs.SHADE_429, NPCs.SHADE_430, NPCs.SHADE_431,
NPCs.TREE_SPIRIT_438, NPCs.TREE_SPIRIT_439, NPCs.TREE_SPIRIT_440, NPCs.TREE_SPIRIT_441, NPCs.TREE_SPIRIT_442, NPCs.TREE_SPIRIT_443, NPCs.TREE_SPIRIT_438, NPCs.TREE_SPIRIT_439, NPCs.TREE_SPIRIT_440, NPCs.TREE_SPIRIT_441, NPCs.TREE_SPIRIT_442, NPCs.TREE_SPIRIT_443,
NPCs.ZOMBIE_419, NPCs.ZOMBIE_420, NPCs.ZOMBIE_421, NPCs.ZOMBIE_422, NPCs.ZOMBIE_423, NPCs.ZOMBIE_424 NPCs.ZOMBIE_419, NPCs.ZOMBIE_420, NPCs.ZOMBIE_421, NPCs.ZOMBIE_422, NPCs.ZOMBIE_423, NPCs.ZOMBIE_424
) { ) {
override fun getXpMultiplier(self: NPC, attacker: Entity): Double { override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
return super.getXpMultiplier(self, attacker) / 16.0 val xprate = super.getXpMultiplier(self, attacker)
return if (getAttribute(self, "spawned-by-ame", false)) xprate / 16.0 else xprate
} }
} }

View file

@ -0,0 +1,164 @@
package content.global.ame.events.candlelight
import core.api.*
import core.api.utils.PlayerCamera
import core.game.interaction.InteractionListener
import core.game.interaction.InterfaceListener
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.world.map.Direction
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
import org.rs09.consts.Scenery
/**
* Candlelight Interface CANDLELIGHT_178
*
*/
class CandlelightInterface : InterfaceListener, InteractionListener, MapArea {
companion object {
const val CANDLELIGHT_INTERFACE = 178
const val CANDLELIGHT_RETURN_LOC = "/save:original-loc"
const val CANDLELIGHT_CANDLE_ARRAY = "/save:candlelight:candle-array"
const val CANDLELIGHT_CAMERA_AT = "candlelight:camera-at"
val CANDLE_LOC_ARRAY = arrayOf(
Location(1967, 4997),
Location(1968, 4998),
Location(1967, 4999),
Location(1968, 5000),
Location(1967, 5001),
Location(1968, 5002),
Location(1967, 5003),
Location(1968, 5004),
Location(1967, 5005),
Location(1968, 5006),
Location(1967, 5007),
)
fun initCandlelight(player: Player) {
val candleArray = intArrayOf(0,0,0,0,0,0,2,2,2,2,2)
candleArray.shuffle()
setAttribute(player, CANDLELIGHT_CANDLE_ARRAY, candleArray)
for (candleIndex in 0..10) {
setVarbit(player, 1771 + candleIndex, candleArray[candleIndex])
}
}
fun areCandlesLit(player: Player): Boolean {
val candleArray = getAttribute(player, CANDLELIGHT_CANDLE_ARRAY, intArrayOf(0,0,0,0,0,0,0,0,0,0,0))
for (candle in candleArray) {
if (candle == 0) {
return false
}
}
return true
}
fun lightCandle(player: Player) {
var currentCamLoc = getAttribute(player, CANDLELIGHT_CAMERA_AT, Location(1968, 5002))
val candleIndex = CANDLE_LOC_ARRAY.indexOf(currentCamLoc)
val varbit = candleIndex + 1771 // Essentially all varbits are 1771 .. 1881
if (candleIndex != -1) {
val candleArray = getAttribute(player, CANDLELIGHT_CANDLE_ARRAY, intArrayOf(0,0,0,0,0,0,0,0,0,0,0))
if (candleArray[candleIndex] == 0) {
candleArray[candleIndex] = 1
setAttribute(player, CANDLELIGHT_CANDLE_ARRAY, candleArray)
setVarbit(player, varbit, 1)
sendMessage(player, "You light the candle.")
} else if (candleArray[candleIndex] == 1) {
sendMessage(player, "This candle is already lit.")
} else {
sendMessage(player, "This candle is too short to light.")
}
} else {
sendMessage(player, "There is nothing to light here.")
}
}
fun moveCamera(player: Player, direction: Direction, firstTime: Boolean = false) {
var currentCamLoc = getAttribute(player, CANDLELIGHT_CAMERA_AT, Location(1968, 5002))
when(direction) {
Direction.NORTH -> currentCamLoc = currentCamLoc.transform(Direction.NORTH)
Direction.SOUTH -> currentCamLoc = currentCamLoc.transform(Direction.SOUTH)
Direction.EAST -> currentCamLoc = currentCamLoc.transform(Direction.EAST)
Direction.WEST -> currentCamLoc = currentCamLoc.transform(Direction.WEST)
else -> {}
}
if (currentCamLoc.x < 1967) { currentCamLoc.x = 1967 }
if (currentCamLoc.x > 1968) { currentCamLoc.x = 1968 }
if (currentCamLoc.y < 4997) { currentCamLoc.y = 4997 }
if (currentCamLoc.y > 5007) { currentCamLoc.y = 5007 }
setAttribute(player, CANDLELIGHT_CAMERA_AT, currentCamLoc)
PlayerCamera(player).rotateTo(currentCamLoc.x - 30, currentCamLoc.y,0,200) // height is kind of a relative value?
PlayerCamera(player).panTo(currentCamLoc.x + 2, currentCamLoc.y,350, if(firstTime) 400 else 10)
}
}
override fun defineInterfaceListeners() {
on(CANDLELIGHT_INTERFACE){ player, component, opcode, buttonID, slot, itemID ->
when (buttonID) {
1 -> moveCamera(player, Direction.WEST)
2 -> moveCamera(player, Direction.EAST)
3 -> lightCandle(player)/* Light */
4 -> moveCamera(player, Direction.SOUTH)
5 -> moveCamera(player, Direction.NORTH)
9 -> closeInterface(player)
}
return@on true
}
onOpen(CANDLELIGHT_INTERFACE){ player, component ->
// Move camera
return@onOpen true
}
onClose(CANDLELIGHT_INTERFACE){ player, component ->
PlayerCamera(player).reset()
// Reset camera
return@onClose true
}
}
override fun defineListeners() {
on((11364 .. 11394).toIntArray(), SCENERY, "light") { player, node ->
setAttribute(player, CANDLELIGHT_CAMERA_AT, Location(node.location.x, node.location.y))
moveCamera(player, Direction.NORTH_WEST, true)
openInterface(player, CANDLELIGHT_INTERFACE)
return@on true
}
}
override fun defineDestinationOverrides() {
setDest(SCENERY, (11364 .. 11394).toIntArray(),"light"){ player, node ->
return@setDest Location(1970, node.location.y)
}
}
override fun defineAreaBorders(): Array<ZoneBorders> {
return arrayOf(ZoneBorders.forRegion(7758))
}
override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
}
override fun areaEnter(entity: Entity) {
if (entity is Player) {
initCandlelight(entity)
entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12)
}
}
override fun areaLeave(entity: Entity, logout: Boolean) {
if (entity is Player) {
entity.interfaceManager.restoreTabs()
}
}
}

View file

@ -0,0 +1,94 @@
package content.global.ame.events.candlelight
import content.global.ame.RandomEvents
import content.global.ame.events.pillory.PilloryInterface
import content.global.ame.returnPlayer
import core.api.*
import core.game.dialogue.*
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
import core.plugin.Initializable
import core.tools.END_DIALOGUE
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
// iface 178
@Initializable
class PiousPeteDialogue (player: Player? = null) : DialoguePlugin(player) {
override fun newInstance(player: Player): DialoguePlugin {
return PiousPeteDialogue(player)
}
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
openDialogue(player, PiousPeteDialogueFile(), npc)
return false
}
override fun getIds(): IntArray {
return intArrayOf(NPCs.PIOUS_PETE_3207, NPCs._6564)
}
}
class PiousPeteDialogueFile : DialogueLabeller() {
override fun addConversation() {
npc(ChatAnim.THINKING, "Have you lit all the tall candles?")
exec { player, npc ->
if (CandlelightInterface.areCandlesLit(player)) {
loadLabel(player, "yeslit")
} else {
loadLabel(player, "nolit")
}
}
label("nolit")
player(ChatAnim.HALF_GUILTY, "Sorry, not yet.")
npc(ChatAnim.SAD, "Please help me in lighting the candles. I just need you to light all the tall candles, but not the short ones.")
line("Click on the pillars to open an interface", "to move around and light the candles.")
label("yeslit")
player(ChatAnim.FRIENDLY, "Yes, the tall ones are all lit.")
npc(ChatAnim.HAPPY, "Thank you my brother! I will now return you where you came from with a parting gift.")
npc(ChatAnim.FRIENDLY, "Take care brother!")
exec { player, npc ->
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
returnPlayer(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
closeInterface(player)
return@queueScript delayScript(player, 3)
}
2 -> {
val loot = RandomEvents.CERTER.loot!!.roll(player)[0]
addItemOrDrop(player, loot.id, loot.amount)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
}
}
}
}
class PiousPeteStartingDialogueFile : DialogueLabeller() {
override fun addConversation() {
npc("I'm sorry to drag you away from your tasks, but I need a little help with something.")
player(ChatAnim.THINKING,"How can I help?")
npc("This is a chapel dedicated to our lord, Saradomin, and I'm tasked with maintaining this chapel.")
npc(ChatAnim.SAD,"My task is to light the chapel candles, but I couldn't reach them myself and I kept getting dazzled by the light whenever I tried.")
npc("So I need your help in lighting the candles. I need you to light all the tall candles, but not the short ones.")
npc(ChatAnim.FRIENDLY, "Once all the tall candles are all lit, come back and see me, and I will reward you for your work.")
}
}

View file

@ -0,0 +1,26 @@
package content.global.ame.events.candlelight
import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.*
import core.api.utils.WeightBasedTable
import core.game.node.entity.npc.NPC
import core.game.world.map.Location
import org.rs09.consts.NPCs
class PiousPeteNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PRIEST_3206) {
override fun init() {
super.init()
// Supposed to be "I'm sorry to drag you away from your tasks, but I need a little help with something." but it's too goddamn long.
sendChat("${player.username}! I need a little help with something.")
face(player)
kidnapPlayer(this, player, Location(1972, 5002, 0)) { player, _ ->
CandlelightInterface.initCandlelight(player)
openDialogue(player, PiousPeteStartingDialogueFile(), NPC(NPCs.PIOUS_PETE_3207))
}
}
override fun talkTo(npc: NPC) {
player.dialogueInterpreter.open(PiousPeteDialogueFile(),npc)
}
}

View file

@ -2,29 +2,19 @@ package content.global.ame.events.certer
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.emote.Emotes import core.game.node.entity.player.link.emote.Emotes
import core.tools.RandomFunction
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.animate import core.api.animate
import core.api.lock
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) { class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) {
lateinit var pName: String
lateinit var phrases: Array<String> lateinit var phrases: Array<String>
override fun tick() { override fun tick() {
// Don't speak if we have the interface opened sayLine(this, phrases, true, true)
if (!timerPaused) { if (ticksLeft == 2) {
// Over allotted time phrase lock(player, 2)
if (ticksLeft <= 2) {
player.lock(2)
sendChat(phrases[4])
// Say a phrase every 20 ticks starting at 280 ticks
// as to not interfere with the init chat phrase
} else if (ticksLeft <= 280 && ticksLeft % 20 == 0) {
sendChat(phrases[RandomFunction.random(1, 3)])
}
} }
super.tick() super.tick()
} }
@ -36,15 +26,20 @@ class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NP
override fun init() { override fun init() {
super.init() super.init()
pName = player.username.capitalize() phrases = arrayOf(
phrases = arrayOf("Greetings $pName, I need your help.", "Greetings ${player.username}, I need your help.",
"ehem... Hello $pName, please talk to me!", "ehem... Hello ${player.username}, please talk to me!",
"Hello, are you there $pName?", "Hello, are you there ${player.username}?",
"It's really rude to ignore someone, $pName!", "It's really rude to ignore someone, ${player.username}!",
"No-one ignores me!") "No-one ignores me!"
)
player.setAttribute("random:pause", false) player.setAttribute("random:pause", false)
player.setAttribute("certer:reward", false) player.setAttribute("certer:reward", false)
sendChat(phrases[0])
animate(this, Emotes.BOW.animation, true) animate(this, Emotes.BOW.animation, true)
} }
override fun onTimeUp() {
noteAndTeleport()
terminate()
}
} }

View file

@ -1,12 +1,9 @@
package content.global.ame.events.drilldemon package content.global.ame.events.drilldemon
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer import content.global.ame.returnPlayer
import core.api.* import core.api.*
import core.game.interaction.QueueStrength import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import org.rs09.consts.Items import org.rs09.consts.Items
@ -24,13 +21,6 @@ object DrillDemonUtils {
val DD_AREA = ZoneBorders(3158, 4817, 3168, 4823) val DD_AREA = ZoneBorders(3158, 4817, 3168, 4823)
val DD_NPC = NPCs.SERGEANT_DAMIEN_2790 val DD_NPC = NPCs.SERGEANT_DAMIEN_2790
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT)
player.interfaceManager.closeDefaultTabs()
setComponentVisibility(player, 548, 69, true)
setComponentVisibility(player, 746, 12, true)
}
fun changeSignsAndAssignTask(player: Player) { fun changeSignsAndAssignTask(player: Player) {
setVarp(player, DD_SIGN_VARP, 0) setVarp(player, DD_SIGN_VARP, 0)
val tempList = arrayListOf(DD_SIGN_JOG, DD_SIGN_JUMP, DD_SIGN_PUSHUP, DD_SIGN_SITUP).shuffled().toMutableList() val tempList = arrayListOf(DD_SIGN_JOG, DD_SIGN_JUMP, DD_SIGN_PUSHUP, DD_SIGN_SITUP).shuffled().toMutableList()
@ -94,6 +84,5 @@ object DrillDemonUtils {
} }
return@queueScript stopExecuting(player) return@queueScript stopExecuting(player)
} }
} }
} }

View file

@ -3,32 +3,22 @@ package content.global.ame.events.drilldemon
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.* import core.api.*
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength import core.game.world.map.Location
import core.game.system.timer.impl.AntiMacro
import core.tools.secondsToTicks
class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) { class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
override fun init() { override fun init() {
super.init() super.init()
sendChat(player.username+ "! Drop and give me 20!") sendChat("${player.username}! Drop and give me 20!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> face(player)
when (stage) { kidnapPlayer(this, player, Location(3163, 4819, 0)) { player, _ ->
0 -> { player.interfaceManager.closeDefaultTabs()
lock(player, secondsToTicks(30)) setComponentVisibility(player, 548, 69, true)
DrillDemonUtils.teleport(player) setComponentVisibility(player, 746, 12, true)
AntiMacro.terminateEventNpc(player)
return@queueScript delayScript(player, 2)
}
1 -> {
openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790) openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
} }
} }

View file

@ -9,36 +9,28 @@ import org.rs09.consts.NPCs
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.DRUNKEN_DWARF_956) { class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.DRUNKEN_DWARF_956) {
private val phrases = arrayOf("Oi, are you der @name!","Dunt ignore your matey!","Aww comeon, talk to ikle me @name!") lateinit var phrases: Array<String>
private var attackPhrase = false
private var attackDelay = 0 private var attackDelay = 0
private var lastPhraseTime = 0
private fun sendPhrases() {
if (getWorldTicks() > lastPhraseTime + 5) {
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
sendChat(this, phrases.random().replace("@name",player.username.capitalize()))
this.face(player)
lastPhraseTime = getWorldTicks()
}
}
override fun init() { override fun init() {
super.init() super.init()
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297) phrases = arrayOf(
sendChat(this, "'Ello der ${player.username.capitalize()}! *hic*") "'Ello der ${player.username}! *hic*",
"Oi, are you der ${player.username}!",
"Dunt ignore your matey!",
"Aww comeon, talk to ikle me ${player.username}!",
"I hates you, ${player.username}!"
)
} }
override fun tick() { override fun tick() {
if (RandomFunction.roll(20) && !attackPhrase) sayLine(this, phrases, true, true)
sendPhrases()
if (ticksLeft <= 10) { if (ticksLeft <= 10) {
ticksLeft = 10 ticksLeft = 10
if (!attackPhrase) if (attackDelay <= getWorldTicks()) {
sendChat("I hates you, ${player.username.capitalize()}!").also { attackPhrase = true }
if (attackDelay <= getWorldTicks())
this.attack(player) this.attack(player)
} }
}
super.tick() super.tick()
} }
@ -47,4 +39,10 @@ class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEvent
this.pulseManager.clear() this.pulseManager.clear()
openDialogue(player, DrunkenDwarfDialogue(), this.asNpc()) openDialogue(player, DrunkenDwarfDialogue(), this.asNpc())
} }
override fun onTimeUp() {
if (attackDelay <= getWorldTicks()) {
this.attack(player)
}
}
} }

View file

@ -1,40 +1,22 @@
package content.global.ame.events.evilbob package content.global.ame.events.evilbob
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.* import core.api.*
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.system.timer.impl.AntiMacro import core.game.world.map.Location
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
class EvilBobNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.EVIL_BOB_2478) { class EvilBobNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.EVIL_BOB_2478) {
override fun init() { override fun init() {
super.init() super.init()
sendChat("meow") sendChat("meow")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> face(player)
when (stage) { kidnapPlayer(this, player, Location(3419, 4776, 0), "No... what? Nooooooooooooo!") { player, _ ->
0 -> {
lock(player, 6)
sendChat(player, "No... what? Nooooooooooooo!")
animate(player, EvilBobUtils.teleAnim)
player.graphics(EvilBobUtils.telegfx)
playAudio(player, Sounds.TELEPORT_ALL_200)
EvilBobUtils.giveEventFishingSpot(player) EvilBobUtils.giveEventFishingSpot(player)
return@queueScript delayScript(player, 3)
}
1 -> {
sendMessage(player, "Welcome to Scape2009.") sendMessage(player, "Welcome to Scape2009.")
EvilBobUtils.teleport(player)
resetAnimator(player)
openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479)
AntiMacro.terminateEventNpc(player)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
} }
} }

View file

@ -1,12 +1,8 @@
package content.global.ame.events.evilbob package content.global.ame.events.evilbob
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.* import core.api.*
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics import core.game.world.update.flag.context.Graphics
@ -53,10 +49,6 @@ object EvilBobUtils {
} }
} }
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player) { fun cleanup(player: Player) {
removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen) removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
removeAll(player, Items.FISHLIKE_THING_6202) removeAll(player, Items.FISHLIKE_THING_6202)

View file

@ -3,38 +3,47 @@ package content.global.ame.events.evilbob
import core.api.* import core.api.*
import core.game.activity.Cutscene import core.game.activity.Cutscene
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.world.map.Direction
class ServantCutsceneN(player: Player) : Cutscene(player) { class ServantCutsceneN(player: Player) : Cutscene(player) {
override fun setup() { override fun setup() {
setExit(player.location.transform(0, 0, 0)) setExit(player.location.transform(0, 0, 0))
loadRegion(13642) loadRegion(13642)
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
} }
override fun runStage(stage: Int) { override fun runStage(stage: Int) {
when (stage) { when (stage) {
0 -> { 0 -> {
fadeToBlack() teleport(player, 30, 41)
timedUpdate(4) moveCamera(30, 37, 400, 255)
rotateCamera(30, 50, 400, 255)
openInterface(player, 186)
timedUpdate(0)
} }
1 -> { 1 -> {
teleport(player, 29, 41) timedUpdate(0)
moveCamera(30, 43) // +7 from statue }
openInterface(player, 186) 2 -> { // Slow start
moveCamera(30, 49, 400, 2)
timedUpdate(2) timedUpdate(2)
} }
2 -> { 3 -> { // Fast middle
moveCamera(30, 44, 380, 4)
timedUpdate(6)
}
4 -> { // Slow end
moveCamera(30, 45, 340, 2)
timedUpdate(2) timedUpdate(2)
rotateCamera(30, 51, 300, 100) // the statue loc
fadeFromBlack()
} }
3 -> { 5 -> {
timedUpdate(9) timedUpdate(2)
moveCamera(30, 46, 300, 2) // +4 from statue
} }
4 -> { 6 -> {
end{ player.locks.lockTeleport(1000000) }
closeInterface(player) closeInterface(player)
end(fade = false) { player.locks.lockTeleport(1000000) }
} }
} }
} }
@ -45,32 +54,40 @@ class ServantCutsceneS(player: Player) : Cutscene(player) {
override fun setup() { override fun setup() {
setExit(player.location.transform(0, 0, 0)) setExit(player.location.transform(0, 0, 0))
loadRegion(13642) loadRegion(13642)
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
} }
override fun runStage(stage: Int) { override fun runStage(stage: Int) {
when (stage) { when (stage) {
0 -> { 0 -> {
fadeToBlack() teleport(player, 30, 41)
timedUpdate(4) moveCamera(31, 46, 365, 255)
rotateCamera(29, 30, 365, 255)
openInterface(player, 186)
timedUpdate(0)
} }
1 -> { 1 -> {
teleport(player, 29, 41) timedUpdate(0)
moveCamera(29, 38) // +7 from statue
openInterface(player, 186)
timedUpdate(2)
} }
2 -> { 2 -> {
moveCamera(31, 43, 480, 2)
timedUpdate(2) timedUpdate(2)
rotateCamera(29, 30, 300, 100) // the statue loc
fadeFromBlack()
} }
3 -> { 3 -> {
timedUpdate(9) moveCamera(31, 37, 455, 4)
moveCamera(29, 35, 300, 2) // +4 from statue timedUpdate(8)
} }
4 -> { 4 -> {
end{ player.locks.lockTeleport(1000000) } moveCamera(31, 36, 395, 2)
timedUpdate(2)
}
5 -> {
timedUpdate(3)
}
6 -> {
closeInterface(player) closeInterface(player)
end(fade = false) { player.locks.lockTeleport(1000000) }
} }
} }
} }
@ -81,32 +98,40 @@ class ServantCutsceneE(player: Player) : Cutscene(player) {
override fun setup() { override fun setup() {
setExit(player.location.transform(0, 0, 0)) setExit(player.location.transform(0, 0, 0))
loadRegion(13642) loadRegion(13642)
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
} }
override fun runStage(stage: Int) { override fun runStage(stage: Int) {
when (stage) { when (stage) {
0 -> { 0 -> {
fadeToBlack() teleport(player, 30, 41)
timedUpdate(4) moveCamera(25, 41, 440, 255)
rotateCamera(42, 41, 440, 255)
openInterface(player, 186)
timedUpdate(0)
} }
1 -> { 1 -> {
teleport(player, 29, 41) timedUpdate(0)
moveCamera(35, 41) // +7 from statue }
openInterface(player, 186) 2 -> { // Slow start
moveCamera(28, 41, 500, 3)
timedUpdate(2) timedUpdate(2)
} }
2 -> { 3 -> { // Fast middle
moveCamera(34, 41, 390, 5)
timedUpdate(6)
}
4 -> { // Slow end
moveCamera(36, 41, 340, 2)
timedUpdate(2) timedUpdate(2)
rotateCamera(43, 41, 300, 100) // the statue loc
fadeFromBlack()
} }
3 -> { 5 -> {
timedUpdate(9) timedUpdate(4)
moveCamera(38, 41, 300, 2) // +4 from statue
} }
4 -> { 6 -> {
end{ player.locks.lockTeleport(1000000) }
closeInterface(player) closeInterface(player)
end(fade = false) { player.locks.lockTeleport(1000000) }
} }
} }
} }
@ -117,34 +142,41 @@ class ServantCutsceneW(player: Player) : Cutscene(player) {
override fun setup() { override fun setup() {
setExit(player.location.transform(0, 0, 0)) setExit(player.location.transform(0, 0, 0))
loadRegion(13642) loadRegion(13642)
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
} }
override fun runStage(stage: Int) { override fun runStage(stage: Int) {
when (stage) { when (stage) {
0 -> { 0 -> {
fadeToBlack() teleport(player, 30, 41)
timedUpdate(4) moveCamera(34, 41, 325, 255)
rotateCamera(16, 40, 300, 255)
openInterface(player, 186)
timedUpdate(0)
} }
1 -> { 1 -> {
teleport(player, 29, 41) timedUpdate(0)
moveCamera(25, 40) // +7 from statue }
openInterface(player, 186) 2 -> { // Slow start
moveCamera(31, 41, 440, 3)
timedUpdate(2) timedUpdate(2)
} }
2 -> { 3 -> { // Fast middle
moveCamera(24, 41, 330, 5)
timedUpdate(7)
}
4 -> { // Slow end
moveCamera(23, 41, 300, 2)
timedUpdate(2) timedUpdate(2)
rotateCamera(18, 40, 300, 100) // the statue loc
fadeFromBlack()
} }
3 -> { 5 -> {
timedUpdate(9) timedUpdate(3)
moveCamera(22, 40, 300, 2) // +4 from statue
} }
4 -> { 6 -> {
end{ player.locks.lockTeleport(1000000) }
closeInterface(player) closeInterface(player)
} end(fade = false) { player.locks.lockTeleport(1000000) }
}
} }
} }
} }

View file

@ -1,13 +1,10 @@
package content.global.ame.events.freakyforester package content.global.ame.events.freakyforester
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer import content.global.ame.returnPlayer
import core.api.* import core.api.*
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import core.tools.RandomFunction import core.tools.RandomFunction
@ -28,10 +25,6 @@ object FreakUtils{
player.dialogueInterpreter.open(FreakyForesterDialogue(), freakNpc) player.dialogueInterpreter.open(FreakyForesterDialogue(), freakNpc)
} }
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player) { fun cleanup(player: Player) {
returnPlayer(player) returnPlayer(player)
removeAttributes(player, freakTask, freakComplete, pheasantKilled) removeAttributes(player, freakTask, freakComplete, pheasantKilled)

View file

@ -1,39 +1,21 @@
package content.global.ame.events.freakyforester package content.global.ame.events.freakyforester
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer
import core.api.* import core.api.*
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.system.timer.impl.AntiMacro import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Sounds
class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.FREAKY_FORESTER_2458) { class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.FREAKY_FORESTER_2458) {
override fun init() { override fun init() {
super.init() super.init()
sendChat("Ah, ${player.username}, just the person I need!") sendChat("Ah, ${player.username}, just the person I need!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> face(player)
when (stage) { kidnapPlayer(this, player, Location(2599, 4777, 0)) { player, _ ->
0 -> {
lock(player, 6)
sendGraphics(Graphics(308, 100, 50), player.location)
animate(player,714)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
FreakUtils.teleport(player)
FreakUtils.giveFreakTask(player) FreakUtils.giveFreakTask(player)
AntiMacro.terminateEventNpc(player)
openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc) openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc)
resetAnimator(player)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
} }
} }

View file

@ -4,27 +4,40 @@ import core.game.node.entity.npc.NPC
import core.tools.RandomFunction import core.tools.RandomFunction
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.lock
import core.api.playAudio import core.api.playAudio
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GENIE_409) { class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GENIE_409) {
val phrases = arrayOf("Greetings, @name!","Ehem... Master @name?","Are you there, Master @name?","No one ignores me!") lateinit var phrases: Array<String>
override fun tick() { override fun tick() {
if(RandomFunction.random(1,15) == 5){ sayLine(this, phrases, true, true)
sendChat(phrases.random().replace("@name",player.username.capitalize())) if (ticksLeft == 2) {
lock(player, 2)
} }
super.tick() super.tick()
} }
override fun init() { override fun init() {
super.init() super.init()
val honorific = if (player.isMale) "Master" else "Mistress"
phrases = arrayOf(
"Greetings, ${player.username}!",
"Ehem... $honorific ${player.username}?",
"Are you there, $honorific ${player.username}?",
"No one ignores me!"
)
playAudio(player, Sounds.GENIE_APPEAR_2301) playAudio(player, Sounds.GENIE_APPEAR_2301)
sendChat(phrases.random().replace("@name",player.username.capitalize()))
} }
override fun talkTo(npc: NPC) { override fun talkTo(npc: NPC) {
player.dialogueInterpreter.open(GenieDialogue(),npc) player.dialogueInterpreter.open(GenieDialogue(),npc)
} }
override fun onTimeUp() {
noteAndTeleport()
terminate()
}
} }

View file

@ -160,7 +160,7 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
animate(player, 536) animate(player, 536)
// val actualScenery = RegionManager.getObject(node.location.z, node.location.x, node.location.y, 3626) // val actualScenery = RegionManager.getObject(node.location.z, node.location.x, node.location.y, 3626)
val tableRoll = CHEST_REWARDS.roll() val tableRoll = CHEST_REWARDS.roll()
addItemOrBank(player, tableRoll[0].id) addItemOrBank(player, tableRoll[0].id, tableRoll[0].amount)
when (tableRoll[0].id){ when (tableRoll[0].id){
Items.AIR_RUNE_556 -> sendItemDialogue(player, Items.AIR_RUNE_556, "You've found some air runes!") Items.AIR_RUNE_556 -> sendItemDialogue(player, Items.AIR_RUNE_556, "You've found some air runes!")
Items.WATER_RUNE_555 -> sendItemDialogue(player, Items.WATER_RUNE_555, "You've found some water runes!") Items.WATER_RUNE_555 -> sendItemDialogue(player, Items.WATER_RUNE_555, "You've found some water runes!")
@ -199,17 +199,16 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
on(Scenery.STRANGE_SHRINE_3634, IntType.SCENERY, "touch") { player, node -> on(Scenery.STRANGE_SHRINE_3634, IntType.SCENERY, "touch") { player, node ->
player.unhook(this) player.unhook(this)
lock(player, 12)
closeOverlay(player) closeOverlay(player)
queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
when (stage) { when (stage) {
0 -> { 0 -> {
lock(player, 6)
sendGraphics(Graphics(86, 0, 3), player.location) sendGraphics(Graphics(86, 0, 3), player.location)
animate(player,862) animate(player,862)
return@queueScript delayScript(player, 6) return@queueScript delayScript(player, 6)
} }
1 -> { 1 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location) sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939) animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200) playAudio(player, Sounds.TELEPORT_ALL_200)

View file

@ -4,33 +4,14 @@ import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer import content.global.ame.kidnapPlayer
import core.api.* import core.api.*
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.TeleportManager
import core.game.system.timer.impl.AntiMacro
import core.game.world.map.Location
import core.game.world.map.build.DynamicRegion
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) { class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
override fun init() { override fun init() {
super.init() super.init()
sendChat("Aha, you'll do ${player.username}!") sendChat("Aha, you'll do ${player.username}!")
face(player) face(player)
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
MazeInterface.initMaze(player)
// Note: This event is NOT instanced: // Note: This event is NOT instanced:
// Sources: // Sources:
// https://youtu.be/2gpzn9oNdy0 (2007) // https://youtu.be/2gpzn9oNdy0 (2007)
@ -39,19 +20,13 @@ class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null
// https://youtu.be/0oBCkLArUmc (2011 - even with personal Mysterious Old Man) - "Sorry, this is not the old man you are looking for." // https://youtu.be/0oBCkLArUmc (2011 - even with personal Mysterious Old Man) - "Sorry, this is not the old man you are looking for."
// https://youtu.be/FMuKZm-Ikgs (2011) // https://youtu.be/FMuKZm-Ikgs (2011)
// val region = DynamicRegion.create(11591) // val region = DynamicRegion.create(11591)
kidnapPlayer(player, MazeInterface.STARTING_POINTS.random(), TeleportManager.TeleportType.INSTANT) // 10 random spots kidnapPlayer(this, player, MazeInterface.STARTING_POINTS.random()) { player, _ ->
AntiMacro.terminateEventNpc(player) MazeInterface.initMaze(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN) removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
} }
} }
override fun talkTo(npc: NPC) { override fun talkTo(npc: NPC) {
// Do nothing. sendMessage(player, "He isn't interested in talking to you.")
} }
} }

View file

@ -4,47 +4,22 @@ import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer import content.global.ame.kidnapPlayer
import core.api.* import core.api.*
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength import core.game.component.Component.setUnclosable
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.TeleportManager
import core.game.system.timer.impl.AntiMacro
import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
// "::revent [-p] <lt>player name<gt> [-e <lt>event name<gt>]"
class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PILLORY_GUARD_2791) { class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PILLORY_GUARD_2791) {
override fun init() { override fun init() {
super.init() super.init()
sendChat("${player.username}, you're under arrest!") sendChat("${player.username}, you're under arrest!")
face(player) face(player)
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.") kidnapPlayer(this, player, PilloryInterface.LOCATIONS.random()) { player, _ ->
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) {
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
PilloryInterface.initPillory(player) PilloryInterface.initPillory(player)
val dest = PilloryInterface.LOCATIONS.random() //9 random spots! setUnclosable(player, player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from."))
kidnapPlayer(player, dest, TeleportManager.TeleportType.INSTANT)
AntiMacro.terminateEventNpc(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
} }
} }
override fun talkTo(npc: NPC) { override fun talkTo(npc: NPC) {
//player.dialogueInterpreter.open(FreakyForesterDialogue(),npc) sendMessage(player, "He isn't interested in talking to you.")
} }
} }

View file

@ -5,15 +5,17 @@ import core.ServerConstants
import core.api.* import core.api.*
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.api.utils.WeightedItem import core.api.utils.WeightedItem
import core.game.dialogue.DialogueFile import core.game.component.Component
import core.game.dialogue.DialogueLabeller
import core.game.dialogue.DialogueOption
import core.game.dialogue.FacialExpression import core.game.dialogue.FacialExpression
import core.game.interaction.QueueStrength import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.tools.END_DIALOGUE
import org.rs09.consts.Components import org.rs09.consts.Components
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs
class QuizMasterDialogueFile : DialogueFile() { class QuizMasterDialogueFile : DialogueLabeller() {
companion object { companion object {
const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191 const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191
const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct" const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct"
@ -74,56 +76,77 @@ class QuizMasterDialogueFile : DialogueFile() {
} }
override fun handle(componentID: Int, buttonID: Int) { override fun addConversation() {
when (stage) { assignToIds(NPCs.QUIZ_MASTER_2477)
0 -> npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>").also { stage++ } afterClose { player ->
1 -> player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...").also { stage++ } loadLabel(player, "question")
2 -> npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "<col=FF0000>${player?.username}</col>!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!").also { stage++ }
3 -> {
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player!!))
player!!.interfaceManager.openChatbox(QUIZMASTER_INTERFACE)
stage++
} }
4-> {
if (buttonID == getAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) { npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>", unclosable = true)
player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...", unclosable = true)
npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "<col=FF0000>${player?.username}</col>!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!", unclosable = true)
goto("question")
label("question")
manual(unclosable = true) { player, _ ->
setAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player))
val comp = Component(QUIZMASTER_INTERFACE)
player.interfaceManager.openChatbox(comp)
return@manual comp
}
exec { player, _ ->
if (buttonID == getAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) {
// Correct Answer // Correct Answer
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1) setAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1)
if (getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) { if (getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) {
npc(FacialExpression.FRIENDLY,"<col=08088A>CONGRATULATIONS!</col>", "You are a <col=8A0808>WINNER</col>!", "Please choose your <col=08088A>PRIZE</col>!") goto("winner")
stage = 5
} else { } else {
npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!") goto("right")
stage = 3
} }
} else { } else {
// Wrong Answer goto("wrong")
npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!")
stage = 3
} }
} }
// Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas.
5 -> options("1000 Coins", "Random Item").also { stage++ } label("right")
6 -> { npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!", unclosable = true)
resetAnimator(player!!) goto("question")
returnPlayer(player!!)
when (buttonID) { label("wrong")
1 -> { npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!", unclosable = true)
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int -> goto("question")
addItemOrDrop(player!!, Items.COINS_995, 1000)
return@queueScript stopExecuting(player!!) label("winner")
npc(FacialExpression.FRIENDLY,"<col=08088A>CONGRATULATIONS!</col>", "You are a <col=8A0808>WINNER</col>!", "Please choose your <col=08088A>PRIZE</col>!", unclosable = true)
options(
DialogueOption("money", "1000 Coins", skipPlayer = true),
DialogueOption("item", "Random Item", skipPlayer = true)
)
label("money")
exec { player, _ ->
queueScript(player, 0, QueueStrength.SOFT) { _ ->
addItemOrDrop(player, Items.COINS_995, 1000)
return@queueScript stopExecuting(player)
} }
} }
2 -> { goto("cleanup")
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
addItemOrDrop(player!!, tableRoll.roll()[0].id) label("item")
return@queueScript stopExecuting(player!!) exec { player, _ ->
queueScript(player, 0, QueueStrength.SOFT) { _ ->
addItemOrDrop(player, tableRoll.roll()[0].id)
return@queueScript stopExecuting(player)
} }
} }
goto("cleanup")
label("cleanup")
exec { player, _ ->
resetAnimator(player)
returnPlayer(player)
removeAttributes(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
} }
removeAttributes(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER) goto("nowhere")
stage = END_DIALOGUE
end()
}
}
} }
} }

View file

@ -4,14 +4,9 @@ import content.global.ame.RandomEventNPC
import content.global.ame.kidnapPlayer import content.global.ame.kidnapPlayer
import core.api.* import core.api.*
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.interaction.QueueStrength
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.link.TeleportManager
import core.game.system.timer.impl.AntiMacro
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import org.rs09.consts.Sounds
/** /**
* Quiz Master NPC: * Quiz Master NPC:
@ -27,35 +22,14 @@ class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable?
override fun init() { override fun init() {
super.init() super.init()
sendChat("Hey ${player.username}! It's your lucky day!") sendChat("Hey ${player.username}! It's your lucky day!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> face(player)
when (stage) { kidnapPlayer(this, player, Location(1952, 4764, 0)) { player, _ ->
0 -> {
lock(player, 6)
sendGraphics(Graphics(1576, 0, 0), player.location)
animate(player,8939)
playAudio(player, Sounds.TELEPORT_ALL_200)
return@queueScript delayScript(player, 3)
}
1 -> {
kidnapPlayer(player, Location(1952, 4764, 1), TeleportManager.TeleportType.INSTANT)
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
AntiMacro.terminateEventNpc(player)
sendGraphics(Graphics(1577, 0, 0), player.location)
animate(player,8941)
sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.") sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.")
sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case. sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case.
return@queueScript delayScript(player, 6)
}
2 -> {
face(player, Location(1952, 4768, 1)) face(player, Location(1952, 4768, 1))
animate(player,2378) animate(player,2378)
// This is not needed as when you enter the QuizMasterBorders, it should fire off the dialogue // Quiz dialogue gets opened automatically on zone entry.
// openDialogue(player, QuizMasterDialogueFile(), this.asNpc())
return@queueScript stopExecuting(player)
}
else -> return@queueScript stopExecuting(player)
}
} }
} }

View file

@ -0,0 +1,86 @@
package content.global.ame.events.rockgolem
import core.game.node.entity.Entity
import core.game.node.entity.combat.BattleState
import core.game.node.entity.combat.CombatStyle
import core.game.node.entity.combat.CombatSwingHandler
import core.game.node.entity.combat.InteractionType
import core.game.node.entity.impl.Projectile
import core.game.node.entity.npc.NPC
import core.game.node.entity.npc.NPCBehavior
import core.game.world.update.flag.context.Animation
import org.rs09.consts.NPCs
class RockGolemBehavior() : NPCBehavior(NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418) {
private val swingHandler = RockGolemSwingHandler()
override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler {
return swingHandler
}
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
return super.getXpMultiplier(self, attacker) / 16.0
}
}
private class RockGolemSwingHandler : CombatSwingHandler(CombatStyle.RANGE) {
override fun canSwing(entity: Entity, victim: Entity): InteractionType? {
return type?.swingHandler?.canSwing(entity, victim)
}
override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int {
if (entity == null || victim == null) return -1
val prayingRange = victim.hasProtectionPrayer(CombatStyle.RANGE)
type = if (prayingRange) {
CombatStyle.MELEE
} else {
CombatStyle.RANGE
}
if (type == CombatStyle.MELEE && entity.location.getDistance(victim.location) > 1) return -1
return type?.swingHandler?.swing(entity, victim, state) ?: 0
}
override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) {
type?.swingHandler?.impact(entity, victim, state)
}
override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) {
type?.swingHandler?.visualizeImpact(entity, victim, state)
}
override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) {
when (type) {
CombatStyle.MELEE -> {
entity.animate(Animation(153))
}
CombatStyle.RANGE -> {
val speed = (100 + (Projectile.getLocation(entity).getDistance(victim!!.getLocation()) * 5)).toInt()
Projectile.create(entity, victim, 968, 48, 36, 80, speed, 5, entity.size() shl 5).send()
entity.animate(Animation(5347))
}
else -> {}
}
}
override fun calculateAccuracy(entity: Entity?): Int {
return type?.swingHandler?.calculateAccuracy(entity) ?: 0
}
override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int {
return type?.swingHandler?.calculateHit(entity, victim, modifier) ?: 0
}
override fun calculateDefence(victim: Entity?, attacker: Entity?): Int {
return type?.swingHandler?.calculateDefence(victim, attacker) ?: 0
}
override fun getSetMultiplier(e: Entity?, skillId: Int): Double {
return type?.swingHandler?.getSetMultiplier(e, skillId) ?: 0.0
}
}

View file

@ -5,24 +5,41 @@ import core.tools.RandomFunction
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.lock
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
class SandwichLadyRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SANDWICH_LADY_3117) { class SandwichLadyRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SANDWICH_LADY_3117) {
val phrases = arrayOf("Hello, @name, can you hear me?","Sandwiches, @name!","Are you ignoring me, @name??","Yoohoo! Sandwiches, @name!","Hello, @name?", "Come get your sandwiches, @name!", "How could you ignore me like this, @name?!", "Do you even want your sandwiches, @name?") lateinit var phrases: Array<String>
var assigned_item = 0 var assigned_item = 0
val items = arrayOf(Items.BAGUETTE_6961, Items.TRIANGLE_SANDWICH_6962, Items.SQUARE_SANDWICH_6965, Items.ROLL_6963, Items.MEAT_PIE_2327, Items.KEBAB_1971, Items.CHOCOLATE_BAR_1973) val items = arrayOf(Items.BAGUETTE_6961, Items.TRIANGLE_SANDWICH_6962, Items.SQUARE_SANDWICH_6965, Items.ROLL_6963, Items.MEAT_PIE_2327, Items.KEBAB_1971, Items.CHOCOLATE_BAR_1973)
override fun tick() { override fun tick() {
if(RandomFunction.random(1,15) == 5){ sayLine(this, phrases, true, true)
sendChat(phrases.random().replace("@name",player.username.capitalize())) if (ticksLeft == 2) {
lock(player, 2)
} }
super.tick() super.tick()
} }
override fun init() { override fun init() {
super.init() super.init()
phrases = arrayOf(
// https://www.youtube.com/watch?v=ek8r3ZS929E
// She always starts with "Sandwiches, ${player.username}!" but she ALSO picks that at random, hence duplicate it with hasOpeningPhrase = true
"Sandwiches, ${player.username}!",
"Sandwiches, ${player.username}!",
"Come on ${player.username}, I made these specially!!",
"All types of sandwiches, ${player.username}.",
"Did you hear me ${player.username}?",
"You think I made these just for fun?!!?",
"How could you ignore me like this, ${player.username}?!" //unknown if authentic but it was already here
)
assignItem() assignItem()
sendChat(phrases.random().replace("@name",player.username.capitalize())) }
override fun onTimeUp() {
noteAndTeleport()
terminate()
} }
fun assignItem(){ fun assignItem(){

View file

@ -1,41 +0,0 @@
package content.global.ame.events
import core.game.node.entity.player.Player
import content.global.ame.events.surpriseexam.SurpriseExamUtils
import core.game.dialogue.DialogueFile
import core.game.system.timer.impl.AntiMacro
class MysteriousOldManDialogue(val type: String) : DialogueFile() {
val CHOICE_STAGE = 50000
override fun handle(componentID: Int, buttonID: Int) {
if(type == "sexam" && stage < CHOICE_STAGE){
npc("Would you like to come do a surprise exam?")
stage = CHOICE_STAGE
}
else if(stage >= CHOICE_STAGE){
when(stage) {
CHOICE_STAGE -> options("Yeah, sure!", "No, thanks.").also { stage++ }
CHOICE_STAGE.substage(1) -> when(buttonID){
1 -> {
end()
teleport(player!!,type)
AntiMacro.terminateEventNpc(player!!)
}
2 -> {
end()
AntiMacro.terminateEventNpc(player!!)
}
}
}
}
}
fun teleport(player: Player,type: String){
when(type){
"sexam" -> SurpriseExamUtils.teleport(player)
}
}
}

View file

@ -1,31 +1,24 @@
package content.global.ame.events package content.global.ame.events.surpriseexam
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.game.node.entity.npc.NPC import content.global.ame.kidnapPlayer
import core.tools.RandomFunction import core.api.*
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import core.game.node.entity.npc.NPC
import core.game.world.map.Location
class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) { class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
override fun init() { override fun init() {
super.init() super.init()
sayLine() sendChat("Surprise exam, ${player.username}!")
} face(player)
kidnapPlayer(this, player, Location(1886, 5025, 0)) { _, _ ->
override fun tick() { /* nothing needed */
super.tick()
if(RandomFunction.random(1,10) == 5) sayLine()
}
fun sayLine() {
when(type){
"sexam" -> sendChat("Surprise exam, ${player.username.capitalize()}!")
} }
} }
override fun talkTo(npc: NPC) { override fun talkTo(npc: NPC) {
when(type){ sendMessage(player, "He isn't interested in talking to you.")
"sexam" -> player.dialogueInterpreter.open(MysteriousOldManDialogue("sexam"),this.asNpc())
}
} }
} }

View file

@ -2,7 +2,6 @@ package content.global.ame.events.surpriseexam
import core.game.component.Component import core.game.component.Component
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.world.map.Location import core.game.world.map.Location
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
@ -66,6 +65,6 @@ class SupriseExamListeners : InteractionListener, MapArea {
} }
override fun getRestrictions(): Array<ZoneRestriction> { override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
} }
} }

View file

@ -1,15 +1,12 @@
package content.global.ame.events.surpriseexam package content.global.ame.events.surpriseexam
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer import content.global.ame.returnPlayer
import core.api.* import core.api.*
import core.game.node.entity.impl.PulseType import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.system.task.Pulse import core.game.system.task.Pulse
import core.game.world.map.Location
import org.rs09.consts.Components import org.rs09.consts.Components
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.node.entity.player.link.TeleportManager
object SurpriseExamUtils { object SurpriseExamUtils {
val SE_KEY_INDEX = "supexam:index" val SE_KEY_INDEX = "supexam:index"
@ -26,10 +23,6 @@ object SurpriseExamUtils {
intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311) intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311)
) )
fun teleport(player: Player) {
kidnapPlayer(player, Location.create(1886, 5025, 0), TeleportManager.TeleportType.INSTANT)
}
fun cleanup(player: Player){ fun cleanup(player: Player){
returnPlayer(player) returnPlayer(player)
removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT) removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT)

View file

@ -1,12 +1,12 @@
package content.global.bots package content.global.bots
import content.global.skill.fletching.log.LogCraftInfo
import content.global.skill.fletching.log.CraftItemWithLogScript
import core.game.bots.Script
import core.game.bots.SkillingBotAssembler
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import content.global.skill.fletching.Fletching
import content.global.skill.fletching.FletchingPulse
import core.game.node.item.Item import core.game.node.item.Item
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.bots.SkillingBotAssembler
import core.game.bots.Script
class FletchingBankstander : Script(){ class FletchingBankstander : Script(){
var state = State.FLETCHING var state = State.FLETCHING
@ -17,7 +17,7 @@ class FletchingBankstander : Script(){
State.FLETCHING -> { State.FLETCHING -> {
bot.inventory.add(Item(Items.KNIFE_946)) bot.inventory.add(Item(Items.KNIFE_946))
bot.inventory.add(Item(Items.LOGS_1511,27)) bot.inventory.add(Item(Items.LOGS_1511,27))
bot.pulseManager.run(FletchingPulse(bot, Item(Items.LOGS_1511),27, Fletching.FletchingItems.ARROW_SHAFT)) CraftItemWithLogScript(bot, LogCraftInfo.ARROW_SHAFT, 27).invoke()
State.BANKING State.BANKING
} }

View file

@ -1,31 +1,37 @@
package content.global.bots package content.global.bots
import content.global.skill.crafting.spinning.SpinningItem
import content.global.skill.crafting.spinning.SpinningPulse
import core.game.bots.*
import core.game.interaction.DestinationFlag import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse import core.game.interaction.MovementPulse
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import content.global.skill.crafting.spinning.SpinningItem
import content.global.skill.crafting.spinning.SpinningPulse
import core.game.node.item.Item import core.game.node.item.Item
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.path.Pathfinder import core.game.world.map.path.Pathfinder
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.bots.SkillingBotAssembler
import core.game.bots.Script
@PlayerCompatible
@ScriptName("Seers' Village Flax Spinning")
@ScriptDescription("Pick flax and spin it into string. Start in the flax field near Seers' Village.")
@ScriptIdentifier("seers_flax")
class SeersFlax : Script(){ class SeersFlax : Script(){
val waypoint1 = Location(2730, 3460, 0) // South of Seers' Village
val waypoint2 = Location(2737, 3441, 0) // Outside flax field
var state = State.PICKING var state = State.PICKING
var stage = 0 var stage = 0
var doorOpen = false var doorOpen = false
override fun tick() { override fun tick() {
when(state){ when(state){
State.PICKING -> { State.PICKING -> {
val flax = scriptAPI.getNearestNode(2646,true) if (bot.inventory.freeSlots() == 0) {
flax?.interaction?.handle(bot,flax.interaction[1])
if(bot.inventory.getAmount(Items.FLAX_1779) > 25){
state = State.TO_SPINNER state = State.TO_SPINNER
return
} }
val flax = scriptAPI.getNearestNode("Flax", true)
scriptAPI.interact(bot, flax, "Pick")
} }
State.TO_SPINNER -> { State.TO_SPINNER -> {
@ -101,14 +107,13 @@ class SeersFlax : Script(){
} }
State.RETURN_TO_FLAX -> { State.RETURN_TO_FLAX -> {
if(bot.location == Location.create(2756, 3478, 0)) val flax = scriptAPI.getNearestNode("Flax", true)
Pathfinder.find(bot,Location.create(2726, 3486, 0)).walk(bot) if (flax != null) {
if(stage == 0) state = State.PICKING
Pathfinder.find(bot,Location.create(2726, 3486, 0)).walk(bot).also { stage++ } } else if (bot.location.withinMaxnormDistance(waypoint1, 5)) {
when(bot.location){ Pathfinder.find(bot, waypoint2).walk(bot)
Location.create(2726, 3486, 0) -> Pathfinder.find(bot,Location.create(2729, 3469, 0)).walk(bot) } else {
Location.create(2729, 3469, 0) -> Pathfinder.find(bot,Location.create(2734, 3447, 0)).walk(bot) Pathfinder.find(bot, waypoint1).walk(bot)
Location.create(2734, 3447, 0) -> state = State.PICKING.also { stage = 0 }
} }
} }
@ -124,7 +129,6 @@ class SeersFlax : Script(){
State.TELE_CAMELOT -> { State.TELE_CAMELOT -> {
scriptAPI.teleport(Location.create(2756, 3478, 0)) scriptAPI.teleport(Location.create(2756, 3478, 0))
stage = 0
state = State.RETURN_TO_FLAX state = State.RETURN_TO_FLAX
} }

View file

@ -1,10 +1,13 @@
package content.global.bots package content.global.bots
import content.data.Quests
import core.game.bots.* import core.game.bots.*
import core.game.interaction.DestinationFlag import core.game.interaction.DestinationFlag
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.interaction.InteractionListeners import core.game.interaction.InteractionListeners
import core.game.interaction.MovementPulse import core.game.interaction.MovementPulse
import core.game.node.entity.skill.Skills
import core.game.node.item.Item
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items import org.rs09.consts.Items
@ -24,6 +27,11 @@ class VarrockEssenceMiner : Script(){
when(state){ when(state){
State.TO_ESSENCE -> { State.TO_ESSENCE -> {
bot.interfaceManager.close() bot.interfaceManager.close()
if (bot.bank.getAmount(Items.PURE_ESSENCE_7936) > 500) {
state = State.TELE_GE
return
}
if(!auburyZone.insideBorder(bot)) if(!auburyZone.insideBorder(bot))
scriptAPI.walkTo(auburyZone.randomLoc) scriptAPI.walkTo(auburyZone.randomLoc)
else { else {
@ -99,7 +107,6 @@ class VarrockEssenceMiner : Script(){
scriptAPI.sellOnGE(Items.PURE_ESSENCE_7936) scriptAPI.sellOnGE(Items.PURE_ESSENCE_7936)
state = State.TO_ESSENCE state = State.TO_ESSENCE
} }
} }
} }
@ -118,4 +125,10 @@ class VarrockEssenceMiner : Script(){
script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation)
return script return script
} }
init {
quests.add(Quests.RUNE_MYSTERIES)
inventory.add(Item(Items.ADAMANT_PICKAXE_1271))
skills[Skills.MINING] = 31
}
} }

View file

@ -1,181 +0,0 @@
package content.global.dialogue
import core.api.*
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.IronmanMode
import core.plugin.Initializable
import core.game.dialogue.IfTopic
import core.game.dialogue.Topic
import content.global.handlers.npc.BankerNPC
import core.tools.END_DIALOGUE
import core.tools.START_DIALOGUE
@Initializable
class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) {
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
when (stage) {
START_DIALOGUE -> when {
hasIronmanRestriction(player, IronmanMode.ULTIMATE) -> {
npcl(
core.game.dialogue.FacialExpression.ANNOYED,
"My apologies, dear ${if (player.isMale) "sir" else "madam"}, " +
"our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}"
).also { stage = END_DIALOGUE }
}
else -> {
npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"Good day, how may I help you?"
).also {
if (hasAwaitingGrandExchangeCollections(player)) {
stage++
} else {
stage += 2
}
}
}
}
1 -> npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"Before we go any further, I should inform you that you " +
"have items ready for collection from the Grand Exchange."
).also { stage++ }
2 -> showTopics(
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to access my bank account, please.", 10),
IfTopic(
core.game.dialogue.FacialExpression.FRIENDLY,
"I'd like to switch to my ${getBankAccountName(player, true)} bank account.",
13,
hasActivatedSecondaryBankAccount(player)
),
IfTopic(
core.game.dialogue.FacialExpression.FRIENDLY,
"I'd like to open a secondary bank account.",
20,
!hasActivatedSecondaryBankAccount(player)
),
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to check my PIN settings.", 11),
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to collect items.", 12),
Topic(core.game.dialogue.FacialExpression.ASKING, "What is this place?", 3),
)
3 -> npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"This is a branch of the Bank of Gielinor. We have branches in many towns."
).also { stage++ }
4 -> playerl(
core.game.dialogue.FacialExpression.ASKING,
"And what do you do?"
).also { stage++ }
5 -> npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"We will look after your items and money for you. " +
"Leave your valuables with us if you want to keep them safe."
).also { stage = END_DIALOGUE }
10 -> {
openBankAccount(player)
end()
}
11 -> {
openBankPinSettings(player)
end()
}
12 -> {
openGrandExchangeCollectionBox(player)
end()
}
13 -> {
toggleBankAccount(player)
npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"Your active bank account has been switched. " +
"You can now access your ${getBankAccountName(player)} account."
).also { stage = 2 }
}
20 -> npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"Certainly. We offer secondary accounts to all our customers."
).also { stage++ }
21 -> npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable " +
"and account activation is permanent."
).also { stage++ }
22 -> npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"If your inventory does not contain enough money to cover the costs, we will complement " +
"the amount with the money inside your primary bank account."
).also { stage++ }
23 -> npcl(
core.game.dialogue.FacialExpression.ASKING,
"Knowing all this, would you like to proceed with opening your secondary bank account?"
).also { stage++ }
24 -> showTopics(
Topic(core.game.dialogue.FacialExpression.HAPPY, "Yes, I am still interested.", 25),
Topic(core.game.dialogue.FacialExpression.ANNOYED, "Actually, I've changed my mind.", 26)
)
25 -> {
when (activateSecondaryBankAccount(player)) {
SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> {
npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"Your bank account was already activated, there is no need to pay twice."
).also { stage = END_DIALOGUE }
}
SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> {
npcl(
core.game.dialogue.FacialExpression.ANNOYED,
"I must apologize, the transaction was not successful. Please check your " +
"primary bank account and your inventory - if there's money missing, please " +
"screenshot your chat box and contact the game developers."
).also { stage = END_DIALOGUE }
}
SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> {
npcl(
core.game.dialogue.FacialExpression.ANNOYED,
"It appears that you do not have the money necessary to cover the costs " +
"associated with opening a secondary bank account. I will be waiting here " +
"until you do."
).also { stage = END_DIALOGUE }
}
SecondaryBankAccountActivationResult.SUCCESS -> {
npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"Your secondary bank account has been opened and can be accessed through any " +
"of the Bank of Gielinor's employees. Thank you for choosing our services."
).also { stage = END_DIALOGUE }
}
}
}
26 -> npcl(
core.game.dialogue.FacialExpression.FRIENDLY,
"Very well. Should you decide a secondary bank account is needed, do not hesitate to " +
"contact any of the Bank of Gielinor's stationary employees. We will be happy to help."
).also { stage = END_DIALOGUE }
}
return true
}
override fun getIds(): IntArray = BankerNPC.NPC_IDS
}

View file

@ -30,6 +30,17 @@ public final class AutocastSelectPlugin extends ComponentPlugin {
if (!player.getAttribute("autocast_select", false)) { if (!player.getAttribute("autocast_select", false)) {
return true; return true;
} }
if (player.timers.getTimer("spellbook:swap") != null) {
player.getPacketDispatch().sendMessage("You cannot autocast while using Spellbook Swap.");
player.removeAttribute("autocast_select");
player.removeAttribute("autocast_component");
final WeaponInterface w = player.getExtension(WeaponInterface.class);
if (w != null) {
w.setAttackStyle(3);
player.getInterfaceManager().openTab(w);
}
return true;
}
player.removeAttribute("autocast_select"); player.removeAttribute("autocast_select");
final WeaponInterface w = player.getExtension(WeaponInterface.class); final WeaponInterface w = player.getExtension(WeaponInterface.class);
if (w != null) { if (w != null) {

View file

@ -1,5 +1,6 @@
package content.global.handlers.iface package content.global.handlers.iface
import content.global.handlers.iface.BookInterface.Companion.FANCY_BOOK_2_27
import core.api.closeInterface import core.api.closeInterface
import core.api.getAttribute import core.api.getAttribute
import core.api.openInterface import core.api.openInterface
@ -159,8 +160,21 @@ class BookInterface : InterfaceListener {
player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false) player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false)
player.packetDispatch.sendModelOnInterface(modelId, componentId, drawLineId, 0) player.packetDispatch.sendModelOnInterface(modelId, componentId, drawLineId, 0)
player.packetDispatch.sendAngleOnInterface(componentId, drawLineId, zoom, pitch, yaw) player.packetDispatch.sendAngleOnInterface(componentId, drawLineId, zoom, pitch, yaw)
} else { }
player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, true) }
/** Sets item on lineId of pageSet (0 index). Call this in the display function after pageSetup. */
fun setItemOnPage(player: Player, pageSet: Int, itemId: Int, componentId: Int, enableLineId: Int, drawLineId: Int, zoom: Int, pitch: Int, yaw: Int) {
if (pageSet == getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0)) {
player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false)
player.packetDispatch.sendItemOnInterface(itemId, 1, componentId, drawLineId)
}
}
/** Clears models(pictures) on lineId of pageSet (0 index). Call this in the display function after pageSetup. */
fun clearModelsOnPage(player: Player, componentId: Int) {
BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS.forEach { drawId ->
player.packetDispatch.sendInterfaceConfig(componentId, drawId, true);
} }
} }

View file

@ -1,159 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.RunScript;
import core.game.system.communication.ClanRank;
import core.game.system.communication.ClanRepository;
import core.net.amsc.MSPacketRepository;
import core.net.amsc.WorldCommunicator;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.tools.StringUtils;
import kotlin.Unit;
import static core.api.ContentAPIKt.sendInputDialogue;
import static core.api.ContentAPIKt.setInterfaceText;
/**
* Represents the plugin used to handle the clan interfaces.
* @author Vexia
*/
@Initializable
public final class ClanInterfacePlugin extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(590, this);
ComponentDefinition.put(589, this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
switch (component.getId()) {
case 589:
switch (button) {
case 9:
if (player.getInterfaceManager().getComponent(590) != null) {
player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'");
return true;
}
ClanRepository.openSettings(player);
return true;
case 14:
if (player.getIronmanManager().checkRestriction()) {
return false;
}
player.getDetails().getCommunication().toggleLootshare(player);
return true;
}
break;
case 590:
final ClanRepository clan = ClanRepository.get(player.getName(), true);
switch (button) {
case 23:
if (opcode == 155) {
clan.setJoinRequirement(ClanRank.NONE);
} else {
clan.setJoinRequirement(getRank(opcode));
}
player.getDetails().getCommunication().setJoinRequirement(clan.getJoinRequirement());
MSPacketRepository.setClanSetting(player, 0, clan.getJoinRequirement());
player.getPacketDispatch().sendString(clan.getJoinRequirement().getInfo(), 590, 23);
break;
case 24:
clan.setMessageRequirement(getRank(opcode));
player.getDetails().getCommunication().setMessageRequirement(clan.getMessageRequirement());
MSPacketRepository.setClanSetting(player, 1, clan.getMessageRequirement());
player.getPacketDispatch().sendString(clan.getMessageRequirement().getInfo(), 590, 24);
break;
case 25:
clan.setKickRequirement(getRank(opcode));
player.getDetails().getCommunication().setKickRequirement(clan.getKickRequirement());
MSPacketRepository.setClanSetting(player, 2, clan.getKickRequirement());
player.getPacketDispatch().sendString(clan.getKickRequirement().getInfo(), 590, 25);
clan.update();
break;
case 26:
if (opcode == 230) {
clan.setLootRequirement(ClanRank.ADMINISTRATOR);
} else {
clan.setLootRequirement(getRank(opcode));
}
player.getDetails().getCommunication().setLootRequirement(clan.getLootRequirement());
MSPacketRepository.setClanSetting(player, 3, clan.getLootRequirement());
player.getPacketDispatch().sendString(clan.getLootRequirement().getInfo(), 590, 26);
break;
case 22:
switch (opcode) {
case 196:
clan.setName("Chat disabled");
player.getCommunication().setClanName("");
player.getPacketDispatch().sendString(clan.getName(), 590, 22);
if (WorldCommunicator.isEnabled()) {
MSPacketRepository.sendClanRename(player, "");
break;
}
clan.clean(true);
break;
default:
sendInputDialogue(player, false, "Enter clan prefix:", (value) -> {
String name = StringUtils.formatDisplayName((String) value);
setInterfaceText(player, name, 590, 22);
if(WorldCommunicator.isEnabled()){
MSPacketRepository.sendClanRename(player, name);
clan.setName(name);
return Unit.INSTANCE;
}
if (clan.getName().equals("Chat disabled")) {
player.getPacketDispatch().sendMessage("Your clan channel has now been enabled!");
player.getPacketDispatch().sendMessage("Join your channel by clicking 'Join Chat' and typing: " + player.getUsername());
}
clan.setName(name);
player.getCommunication().setClanName(name);
clan.update();
return Unit.INSTANCE;
});
break;
}
break;
}
break;
}
return true;
}
/**
* Gets the value to set.
* @param opcode the opcode.
* @return the value.
*/
public static ClanRank getRank(int opcode) {
switch (opcode) {
case 155:
return ClanRank.NONE;
case 196:
return ClanRank.FRIEND;
case 124:
return ClanRank.RECRUIT;
case 199:
return ClanRank.CORPORAL;
case 234:
return ClanRank.SERGEANT;
case 168:
return ClanRank.LIEUTENANT;
case 166:
return ClanRank.CAPTAIN;
case 64:
return ClanRank.GENERAL;
case 53:
return ClanRank.OWNER;
}
return ClanRank.NONE;
}
}

View file

@ -1,50 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.plugin.Initializable;
import core.plugin.Plugin;
@Initializable
public class CrystalKeyChestPlugin extends ComponentPlugin {
private final Integer CHEST_INTERFACE = 501;
private Player player;
public CrystalKeyChestPlugin() {
/*
* Empty
*/
}
public CrystalKeyChestPlugin(Player player) {
this.player = player;
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(CHEST_INTERFACE, this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
return false;
}
public void constructInterface(Player player) {
Integer[] hiddenChildren = new Integer[] { 3, 4, 5, 6, 7};
Component component = new Component(CHEST_INTERFACE);
for (int i = 3; i < hiddenChildren.length; i++) {
player.getPacketDispatch().sendInterfaceConfig(CHEST_INTERFACE, i, true);
}
player.getPacketDispatch().sendItemOnInterface(989, 1, CHEST_INTERFACE, hiddenChildren[2]);
player.getInterfaceManager().open(component);
this.player = player;
}
}

View file

@ -0,0 +1,17 @@
package content.global.handlers.iface
import core.api.closeInterface
import core.game.interaction.InterfaceListener
import org.rs09.consts.Components
class DeathInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(Components.AIDE_DEATH_153) { player, _, _, buttonID, _, _ ->
if (buttonID == 1) {
player.savedData.globalData.setDisableDeathScreen(true)
closeInterface(player)
}
return@on true
}
}
}

View file

@ -1,32 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the death interface.
* @author Vexia
*/
@Initializable
public final class DeathInterfacePlugin extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.forId(153).setPlugin(this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
if (button == 1) {
player.getSavedData().getGlobalData().setDisableDeathScreen(true);
player.getInterfaceManager().close();
}
return true;
}
}

View file

@ -1,30 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.emote.Emotes;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the emote tab interface.
* @author Vexia
*
*/
@Initializable
public final class EmoteTabInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(464, this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
Emotes.handle(player, button);
return true;
}
}

View file

@ -1,231 +0,0 @@
package content.global.handlers.iface;
import content.global.skill.summoning.familiar.BurdenBeast;
import core.api.ContentAPIKt;
import core.cache.def.impl.ItemDefinition;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.container.Container;
import core.game.container.ContainerEvent;
import core.game.container.ContainerListener;
import core.game.container.access.InterfaceContainer;
import core.game.container.impl.EquipmentContainer;
import core.game.interaction.OptionHandler;
import core.game.node.entity.combat.DeathTask;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.prayer.PrayerType;
import core.game.node.item.Item;
import core.game.system.task.Pulse;
import core.net.packet.PacketRepository;
import core.net.packet.context.ContainerContext;
import core.net.packet.out.ContainerPacket;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.game.global.action.EquipHandler;
import core.game.interaction.IntType;
import core.game.interaction.InteractionListeners;
import core.game.world.GameWorld;
import core.tools.Log;
/**
* Represents the equipment interface.
* @author Emperor
*
*/
@Initializable
public final class EquipmentInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(102, this);
ComponentDefinition.put(387, this);
ComponentDefinition.put(667, this);
ComponentDefinition.put(670, this);
return this;
}
@Override
public boolean handle(final Player p, Component component, int opcode, int button, final int slot, final int itemId) {
if (component.getId() == 667) {
if (button != 14) {
return false;
}
switch (opcode) {
case 155:
p.getPulseManager().clear();
GameWorld.getPulser().submit(new Pulse(1, p) {
@Override
public boolean pulse() {
EquipHandler.unequip(p, slot, itemId);
return true;
}
});
return true;
case 9:
p.sendMessage(p.getEquipment().get(slot).getDefinition().getExamine());
return true;
case 196:
GameWorld.getPulser().submit(new Pulse(1, p) {
@Override
public boolean pulse() {
operate(p, slot, itemId);
return true;
}
});
return true;
}
return false;
}
else if (component.getId() == 670) {
switch (opcode) {
case 155:
p.getPulseManager().clear();
final Item item = p.getInventory().get(slot);
GameWorld.getPulser().submit(new Pulse(1, p) {
@Override
public boolean pulse() {
if (item == null) return true;
InteractionListeners.run(item.getId(), IntType.ITEM,"equip",p, item);
return true;
}
});
return true;
case 9:
p.sendMessage(p.getInventory().get(slot).getDefinition().getExamine());
return true;
}
}
switch (opcode) {
case 206:
if (button != 28) {
return false;
}
GameWorld.getPulser().submit(new Pulse(1, p) {
@Override
public boolean pulse() {
operate(p, slot, itemId);
return true;
}
});
return true;
default:
switch (button) {
case 52:
if (p.getInterfaceManager().isOpened() && p.getInterfaceManager().getOpened().getId() == 102) {
return true;
}
// (Highlight white items are auto destroyed on death Enum#616 (Items kept on death interface) TODO: Parse server sided
// SCRIPT 118 - Items kept on death interface CS
// ARG 0: Safe location check Takes: 0 Safe Area/2 in POH/3 in Castle Wars/4 in Trouble Brewing/5 in Barbass
int zoneType = p.getZoneMonitor().getType();
// ARG 1: Amount of items kept on death Takes: 0/1/3/4
Container[] itemArray = DeathTask.getContainers(p);
Container kept = itemArray[0];
int amtKeptOnDeath = kept.itemCount();
if (amtKeptOnDeath > 4 && zoneType == 0) {
ContentAPIKt.log(this.getClass(), Log.ERR, "Items kept on death interface should not contain more than 4 items when not in a safe zone!");
}
// ARG 2: Item kept on death slot 0
int slot0 = kept.getId(0);
// ARG 3: Item kept on death slot 1
int slot1 = kept.getId(1);
// ARG 4: Item kept on death slot 2
int slot2 = kept.getId(2);
// ARG 5: Item kept on death slot 3
int slot3 = kept.getId(3);
// ARG 6: Player skulled Takes: 0 not skulled/1 skulled
int skulled = p.getSkullManager().isSkulled() ? 1 : 0;
// ARG 7: Player has summoning creature out Takes: 0 not out/1 Creature summoned
int hasBoB;
if (p.getFamiliarManager().hasFamiliar()) {
if (p.getFamiliarManager().getFamiliar().isBurdenBeast()) {
hasBoB = ((BurdenBeast) p.getFamiliarManager().getFamiliar()).getContainer().isEmpty() ? 0 : 1;
} else {
hasBoB = 0;
}
} else {
hasBoB = 0;
}
// ARG 8: String for effect:
// if (arg1 == 0) arg8 + " This reduces the items you keep from three to zero!"
// if (arg1 == 1) arg8 + " This reduces the items you keep from three to zero!" + "<br>" + "<br>" + "However, you also have the " + "<col=ff3333>" + "Protect Items" + "<col=ff981f>" + " prayer active, which saves you one extra item!");
Object[] params = new Object[] { hasBoB, skulled, slot3, slot2, slot1, slot0, amtKeptOnDeath, zoneType, "You are skulled." };
p.getPacketDispatch().sendRunScript(118, "siiooooii", params);
p.getInterfaceManager().openComponent(102);
break;
case 28:
if (opcode == 81) {
p.getPulseManager().clear();
GameWorld.getPulser().submit(new Pulse(1, p) {
@Override
public boolean pulse() {
EquipHandler.unequip(p, slot, itemId);
return true;
}
});
return true;
}
break;
case 55:
if (p.getInterfaceManager().isOpened() && p.getInterfaceManager().getOpened().getId() == 667) {
return true;
}
final ContainerListener listener = new ContainerListener() {
@Override
public void update(Container c, ContainerEvent e) {
PacketRepository.send(ContainerPacket.class, new ContainerContext(p, -1, -1, 98, e.getItems(), false, e.getSlots()));
}
@Override
public void refresh(Container c) {
PacketRepository.send(ContainerPacket.class, new ContainerContext(p, -1, -1, 98, c, false));
}
};
p.getInterfaceManager().openComponent(667).setCloseEvent((player, c) -> {
player.removeAttribute("equip_stats_open");
player.getInterfaceManager().closeSingleTab();
player.getInventory().getListeners().remove(listener);
return true;
});
p.setAttribute("equip_stats_open", true);
EquipmentContainer.update(p);
p.getInterfaceManager().openSingleTab(new Component(670));
InterfaceContainer.generateItems(p, p.getInventory().toArray(), new String[] { "Equip" }, 670, 0, 7, 4, 93);
p.getInventory().getListeners().add(listener);
p.getInventory().refresh();
ItemDefinition.statsUpdate(p);
p.getPacketDispatch().sendIfaceSettings(1278, 14, 667, 0, 13);
break;
}
}
return true;
}
/**
* Operates an item.
* @param player The player.
* @param slot The container slot.
* @param itemId The item id.
*/
public void operate(Player player, int slot, int itemId) {
if (slot < 0 || slot > 13) {
return;
}
Item item = player.getEquipment().get(slot);
if (item == null) {
return;
}
if(InteractionListeners.run(item.getId(),IntType.ITEM,"operate",player,item)){
return;
}
OptionHandler handler = item.getOperateHandler();
if (handler != null && handler.handle(player, item, "operate")) {
return;
}
player.getPacketDispatch().sendMessage("You can't operate that.");
}
}

View file

@ -6,6 +6,7 @@ import core.game.component.ComponentDefinition
import core.game.component.ComponentPlugin import core.game.component.ComponentPlugin
import core.game.container.access.InterfaceContainer import core.game.container.access.InterfaceContainer
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item import core.game.node.item.Item
import core.plugin.Initializable import core.plugin.Initializable
import core.plugin.Plugin import core.plugin.Plugin
@ -162,9 +163,14 @@ class FurClothingInterface : ComponentPlugin(){
return return
} }
removeItem(player, requiredFur, Container.INVENTORY) if (removeItem(player, requiredFur, Container.INVENTORY) &&
removeItem(player, coins, Container.INVENTORY) removeItem(player, coins, Container.INVENTORY)) {
addItem(player, clothing.product.id, amount) addItem(player, clothing.product.id, amount)
if (clothing == FUR_CLOTHING.DASH_CAPE) {
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 2)
}
}
} }
override fun newInstance(arg: Any?): Plugin<Any> { override fun newInstance(arg: Any?): Plugin<Any> {

View file

@ -1,185 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.plugin.Initializable;
import core.game.node.entity.combat.equipment.WeaponInterface;
import core.game.node.entity.combat.equipment.WeaponInterface.WeaponInterfaces;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.info.Rights;
import core.game.world.GameWorld;
import core.plugin.Plugin;
/**
* Represents the component plugin used for the game interface.
* @author Vexia
*
*/
@Initializable
public final class GameInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(740, this);
return this;
}
@Override
public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) {
switch (component.getId()) {
case 740:
switch (button){
case 3:
player.getInterfaceManager().closeChatbox();
break;
}
return true;
case 746:
switch (button){
case 12:
player.getPacketDispatch().sendString("When you have finished playing " + GameWorld.getSettings().getName() + ", always use the button below to logout safely. ", 182, 0);
break;
case 49:
player.getPacketDispatch().sendString("Friends List - " + GameWorld.getSettings().getName() + " " + GameWorld.getSettings().getWorldId(), 550, 3);
break;
case 110:
configureWorldMap(player);
break;
}
return true;
case 548:
if (button >= 38 && button<= 44 || button >= 20 && button <= 26) {
player.getInterfaceManager().setCurrentTabIndex(getTabIndex(button));
}
//Interface buttons that advance the Tutorial Island stages
switch (button) {
case 21://Friends Tab
player.getPacketDispatch().sendString("Friends List -" + GameWorld.getSettings().getName() + " " + GameWorld.getSettings().getWorldId(), 550, 3);
break;
case 22://Ignore Tab
break;
case 24://Settings Tab
break;
case 25://Emotes Tab
break;
case 26://Music Tab
break;
case 38://Attack Tab
if (player.getExtension(WeaponInterface.class) == WeaponInterfaces.STAFF) {
final Component c = new Component(WeaponInterfaces.STAFF.getInterfaceId());
player.getInterfaceManager().openTab(0, c);
final WeaponInterface inter = player.getExtension(WeaponInterface.class);
inter.updateInterface();
}
break;
case 39://Skill Tab
break;
case 40://Quest Tab
/*if (GameWorld.isEconomyWorld()) {
player.getQuestRepository().syncronizeTab(player);
} else {
player.getSavedData().getSpawnData().drawStatsTab(player);
}*/
player.getQuestRepository().syncronizeTab(player);
break;
case 41://Inventory Tab
player.getInventory().refresh();
break;
case 42://Worn Equipment Tab
break;
case 43://Prayer Tab
break;
case 44://Magic Tab
break;
case 66://World map
case 110:
configureWorldMap(player);
break;
case 69://Logout
player.getPacketDispatch().sendString("When you have finished playing " + GameWorld.getSettings().getName() + ", always use the button below to logout safely. ", 182, 0);
break;
}
return true;
case 750:
switch (opcode) {
case 155:
switch (button) {
case 1:
player.getSettings().toggleRun();
break;
}
break;
}
return true;
case 751:
switch (opcode) {
case 155:
switch (button) {
case 27:
openReport(player);
break;
}
break;
}
return true;
}
return true;
}
/**
* World map
* Thanks, Snickerize!
*/
private void configureWorldMap(Player player) {
if (player.inCombat()) {
player.getPacketDispatch().sendMessage("It wouldn't be very wise opening the world map during combat.");
return;
}
if(player.getLocks().isInteractionLocked() || player.getLocks().isMovementLocked()){
player.getPacketDispatch().sendMessage("You can't do this right now.");
return;
}
player.getInterfaceManager().openWindowsPane(new Component(755));
int posHash = (player.getLocation().getZ() << 28) | (player.getLocation().getX() << 14) | player.getLocation().getY();
player.getPacketDispatch().sendScriptConfigs(622, posHash, "", 0);
player.getPacketDispatch().sendScriptConfigs(674, posHash, "", 0);
}
/**
* Method used to open the report interface.
* @param player the player.
*/
public static void openReport(final Player player) {
player.getInterfaceManager().open(new Component(553)).setCloseEvent((player1, c) -> {
player1.getPacketDispatch().sendRunScript(80, "");
player1.getPacketDispatch().sendRunScript(137, "");
return true;
});
player.getPacketDispatch().sendRunScript(508, "");
if (player.getDetails().getRights() != Rights.REGULAR_PLAYER) {
for (int i = 0; i < 18; i++) {
player.getPacketDispatch().sendInterfaceConfig(553, i, false);
}
}
}
/**
* Gets the tab index.
* @param button The button id.
* @return The tab index.
*/
private static int getTabIndex(int button) {
int tabIndex = button - 38;
if (button < 27) {
tabIndex = (button - 20) + 7;
}
return tabIndex;
}
/**
* Configures the world map for a player.
* @param player The player.
*/
}

View file

@ -152,8 +152,8 @@ class HairDresserInterface : ComponentPlugin(){
player.setAttribute("beard-setting",false) player.setAttribute("beard-setting",false)
if(!pl.getAttribute("hairdresser-paid",false)){ if(!pl.getAttribute("hairdresser-paid",false)){
val original_hair = player.getAttribute("original-hair",0) val original_hair = player.getAttribute("original-hair",0)
val original_beard = player.getAttribute("original_beard",-1) val original_beard = player.getAttribute("original-beard",-1)
val original_color = player.getAttribute("original_color",0) val original_color = player.getAttribute("original-color",0)
pl.appearance.hair.changeLook(original_hair) pl.appearance.hair.changeLook(original_hair)
pl.appearance.hair.changeColor(original_color) pl.appearance.hair.changeColor(original_color)
if (original_beard != -1) { if (original_beard != -1) {
@ -174,7 +174,7 @@ class HairDresserInterface : ComponentPlugin(){
when(button){ when(button){
199 -> player.setAttribute("beard-setting",false) 199 -> player.setAttribute("beard-setting",false)
200 -> player.setAttribute("beard-setting",true) 200 -> player.setAttribute("beard-setting",true)
68,196,274 -> pay(player) 196,274,68,100 -> pay(player)
else -> when(component?.id){ else -> when(component?.id){
592 -> { //Female 592 -> { //Female
if(femaleColorButtonRange.contains(button)){ if(femaleColorButtonRange.contains(button)){

View file

@ -0,0 +1,34 @@
package content.global.handlers.iface
import core.api.closeInterface
import core.api.runTask
import core.game.interaction.InterfaceListener
import core.game.node.entity.player.info.login.LoginConfiguration
import org.rs09.consts.Components
class LoginInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(Components.WELCOME_SCREEN_378) { player, _, _, buttonID, _, _ ->
val playButton = 140
val creditButton = 145
val discordButton = 204
when (buttonID) {
playButton -> {
player.locks.lock("login", 2)
closeInterface(player)
runTask(player, 1, 0) {
LoginConfiguration.configureGameWorld(player)
}
}
creditButton -> return@on true
discordButton -> return@on true
}
return@on true
}
onClose(Components.WELCOME_SCREEN_378) { player, _ ->
return@onClose player.locks.isLocked("login")
}
}
}

View file

@ -1,51 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.info.login.LoginConfiguration;
import core.game.system.task.Pulse;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Represents the plugin used for the login interface.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class LoginInterfacePlugin extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(378, this);
return null;
}
@Override
public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) {
switch (button) {
case 140:
if (player.getLocks().isLocked("login")) {
return true;
}
player.getLocks().lock("login", 2);
player.getInterfaceManager().close();
player.getPulseManager().run(new Pulse(1) {
@Override
public boolean pulse() {
LoginConfiguration.configureGameWorld(player);
return true;
}
});
break;
case 145://credits
break;
case 204://message centre
break;
}
return true;
}
}

View file

@ -1,42 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.world.GameWorld;
import core.plugin.Initializable;
import core.plugin.Plugin;
import core.game.world.repository.Repository;
/**
* Represents the interface used to logout of the game.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class LogoutInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(182, this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
if (!player.getZoneMonitor().canLogout()) {
return true;
}
if (player.inCombat()) {
player.getPacketDispatch().sendMessage("You can't log out until 10 seconds after the end of combat.");
return true;
}
if (player.isTeleporting()) {
player.sendMessage("Please finish your teleport before logging out.");
return true;
}
Repository.getDisconnectionQueue().add(player);
return true;
}
}

View file

@ -1,50 +0,0 @@
package content.global.handlers.iface;
import content.global.skill.magic.SpellListener;
import content.global.skill.magic.SpellListeners;
import content.global.skill.magic.SpellUtils;
import core.game.event.SpellCastEvent;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.world.GameWorld;
import core.plugin.Plugin;
/**
* Represents the magic book interface handling of non-combat spells.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class MagicBookInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(192, this);
ComponentDefinition.put(193, this);
ComponentDefinition.put(430, this);
return this;
}
@Override
public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) {
if (GameWorld.getTicks() < player.getAttribute("magic:delay", -1)) {
return true;
}
SpellBook spellBook = component.getId() == 192
? SpellBook.MODERN
: component.getId() == 193
? SpellBook.ANCIENT
: SpellBook.LUNAR;
SpellListeners.run(button, SpellListener.NONE, SpellUtils.getBookFromInterface(component.getId()),player,null);
boolean result = MagicSpell.castSpell(player, spellBook, button, player);
return result;
}
}

View file

@ -31,32 +31,13 @@ class MainGameInterface : InterfaceListener {
} }
on(TOPLEVEL_FS){player, _, _, buttonID, _, _ -> on(TOPLEVEL_FS){player, _, _, buttonID, _, _ ->
when (buttonID) { if (buttonID == 110)
12 -> setInterfaceText(player, configureWorldMap(player)
"When you have finished playing " + settings!!.name + ", always use the button below to logout safely. ",
182,
0
)
49 -> setInterfaceText(player,
"Friends List - " + settings!!.name + " " + settings!!.worldId,
550,
3
)
110 -> configureWorldMap(player)
}
return@on true return@on true
} }
on(TOPLEVEL){player, _, _, buttonID, _, _ -> on(TOPLEVEL){player, _, _, buttonID, _, _ ->
when (buttonID) { when (buttonID) {
21 -> {
player.packetDispatch.sendString(
"Friends List -" + settings!!.name + " " + settings!!.worldId,
550,
3
)
}
38 -> { 38 -> {
if (player.getExtension<Any>(WeaponInterface::class.java) === WeaponInterfaces.STAFF) { if (player.getExtension<Any>(WeaponInterface::class.java) === WeaponInterfaces.STAFF) {
val c = Component(WeaponInterfaces.STAFF.interfaceId) val c = Component(WeaponInterfaces.STAFF.interfaceId)
@ -67,12 +48,7 @@ class MainGameInterface : InterfaceListener {
} }
40 -> player.questRepository.syncronizeTab(player) 40 -> player.questRepository.syncronizeTab(player)
41 -> player.inventory.refresh() 41 -> player.inventory.refresh()
66, 110 -> configureWorldMap(player) 66 -> configureWorldMap(player)
69 -> player.packetDispatch.sendString(
"When you have finished playing " + settings!!.name + ", always use the button below to logout safely. ",
182,
0
)
} }
return@on true return@on true
} }
@ -95,11 +71,11 @@ class MainGameInterface : InterfaceListener {
private fun configureWorldMap(player: Player) { private fun configureWorldMap(player: Player) {
if (player.inCombat()) { if (player.inCombat()) {
player.packetDispatch.sendMessage("It wouldn't be very wise opening the world map during combat.") sendMessage(player, "It wouldn't be very wise opening the world map during combat.")
return return
} }
if (player.locks.isInteractionLocked || player.locks.isMovementLocked) { if (player.locks.isInteractionLocked || player.locks.isMovementLocked) {
player.packetDispatch.sendMessage("You can't do this right now.") sendMessage(player, "You can't do this right now.")
return return
} }
player.interfaceManager.close() player.interfaceManager.close()

View file

@ -1,57 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.info.Rights;
import core.game.node.entity.player.link.music.MusicEntry;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the interface tab buttons.
* @author Emperor
*/
@Initializable
public final class MusicTabInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(187, this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
switch (opcode) {
case 155:
switch (button) {
case 11:
player.getMusicPlayer().toggleLooping();
return true;
case 1:
MusicEntry entry = player.getMusicPlayer().getUnlocked().get(slot);
if (entry == null) {
if(player.getRights().equals(Rights.ADMINISTRATOR)){
for(MusicEntry ent : MusicEntry.getSongs().values()){
if(ent.getIndex() == slot){
player.getMusicPlayer().unlock(ent.getId());
break;
}
}
} else {
player.getPacketDispatch().sendMessage("You have not unlocked this piece of music yet!</col>");
}
return true;
}
player.getMusicPlayer().setPlaying(false);
player.getMusicPlayer().play(entry);
return true;
}
break;
}
return false;
}
}

View file

@ -0,0 +1,57 @@
package content.global.handlers.iface
import core.api.*
import core.game.dialogue.FacialExpression
import core.game.interaction.InterfaceListener
import core.game.node.item.Item
import core.tools.StringUtils
import org.rs09.consts.Items
import org.rs09.consts.NPCs
class MysticStaffEnchantInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(INTERFACE_332) { player, _, _, buttonID, _, _ ->
val staff = buttonMap[buttonID] ?: return@on true
if (!inInventory(player, staff.basicID)) {
sendMessage(player, "You don't have a${if (StringUtils.isPlusN(getItemName(staff.basicID))) "n" else ""} ${getItemName(staff.basicID)} to enchant.")
return@on true
}
closeInterface(player)
if (!inInventory(player, Items.COINS_995, 40000)) {
sendNPCDialogue(player, NPCs.THORMAC_389, "I need ${String.format("%,d", 40000)} coins for materials. Come back when you have the money!", FacialExpression.NEUTRAL)
return@on true
}
if (removeItem(player, Item(staff.basicID, 1)) && removeItem(player, Item(Items.COINS_995, 40000))) {
sendNPCDialogue(player, NPCs.THORMAC_389, "Just a moment... hang on... hocus pocus abra-cadabra... there you go! Enjoy your enchanted staff!", FacialExpression.NEUTRAL)
addItem(player, staff.enchantedID, 1)
}
return@on true
}
}
enum class EnchantedStaff(val enchantedID: Int, val basicID: Int, val buttonID: Int) {
AIR(Items.MYSTIC_AIR_STAFF_1405, Items.AIR_BATTLESTAFF_1397, 21),
WATER(Items.MYSTIC_WATER_STAFF_1403, Items.WATER_BATTLESTAFF_1395, 22),
EARTH(Items.MYSTIC_EARTH_STAFF_1407, Items.EARTH_BATTLESTAFF_1399, 23),
FIRE(Items.MYSTIC_FIRE_STAFF_1401, Items.FIRE_BATTLESTAFF_1393, 24),
LAVA(Items.MYSTIC_LAVA_STAFF_3054, Items.LAVA_BATTLESTAFF_3053, 25),
MUD(Items.MYSTIC_MUD_STAFF_6563, Items.MUD_BATTLESTAFF_6562, 26),
STEAM(Items.MYSTIC_STEAM_STAFF_11738, Items.STEAM_BATTLESTAFF_11736, 27),
}
companion object {
private const val INTERFACE_332 = 332
val buttonMap = HashMap<Int, EnchantedStaff>()
init {
for (staff in EnchantedStaff.values()) {
buttonMap[staff.buttonID] = staff
}
}
}
}

View file

@ -1,95 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import org.rs09.consts.Items;
import core.game.node.entity.player.Player;
import core.game.node.item.Item;
import core.plugin.Plugin;
import core.plugin.Initializable;
import core.tools.StringUtils;
import java.util.HashMap;
/**
* Represents the plugin used to handle the agility ticket interface.
* @author afaroutdude
*/
@Initializable
public final class MysticStaffEnchantingPlugin extends ComponentPlugin {
private final Component COMPONENT = new Component(332);
protected enum EnchantedStaff {
AIR(Items.MYSTIC_AIR_STAFF_1405, Items.AIR_BATTLESTAFF_1397, 21),
WATER(Items.MYSTIC_WATER_STAFF_1403, Items.WATER_BATTLESTAFF_1395, 22),
EARTH(Items.MYSTIC_EARTH_STAFF_1407, Items.EARTH_BATTLESTAFF_1399, 23),
FIRE(Items.MYSTIC_FIRE_STAFF_1401, Items.FIRE_BATTLESTAFF_1393, 24),
LAVA(Items.MYSTIC_LAVA_STAFF_3054, Items.LAVA_BATTLESTAFF_3053, 25),
MUD(Items.MYSTIC_MUD_STAFF_6563, Items.MUD_BATTLESTAFF_6562, 26),
STEAM(Items.MYSTIC_STEAM_STAFF_11738, Items.STEAM_BATTLESTAFF_11736, 27);
public final int enchanted;
public final int basic;
public final int child;
private static final HashMap<Integer, Integer> basicToEnchanted = new HashMap<>();
private static final HashMap<Integer, Integer> childToBasic = new HashMap<>();
static {
for (EnchantedStaff staff : EnchantedStaff.values()) {
basicToEnchanted.put(staff.basic, staff.enchanted);
childToBasic.put(staff.child, staff.basic);
}
}
EnchantedStaff(int enchantedId, int basicId, int childId) {
this.enchanted = enchantedId;
this.basic = basicId;
this.child = childId;
}
}
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.forId(332).setPlugin(this);
return this;
}
@Override
public void open(Player player, Component component) {
super.open(player, component);
// zoom doesn't work, but based on https://youtu.be/qxxhhCdxBsQ?t=75 seems correct anyway
for (EnchantedStaff staff : EnchantedStaff.values()) {
player.getPacketDispatch().sendItemZoomOnInterface(staff.basic, 240, COMPONENT.getId(), staff.child);
}
}
@Override
public boolean handle(Player player, Component component, int opcode, int buttonId, int slot, int itemId) {
if (EnchantedStaff.childToBasic.containsKey(buttonId)) {
Item basicStaff = new Item(EnchantedStaff.childToBasic.get(buttonId));
Item enchantedStaff = new Item(EnchantedStaff.basicToEnchanted.get(basicStaff.getId()));
if (!player.getInventory().containsItem(basicStaff)) {
player.getPacketDispatch().sendMessage("You don't have a" + (StringUtils.isPlusN(basicStaff.getName()) ? "n " : " ") + basicStaff.getName() + " to enchant.");
return true;
}
int cost = player.getEquipment().contains(Items.SEERS_HEADBAND_14631, 1)? 27000 : 40000;
if (!player.getInventory().contains(995, cost)) {
player.getInterfaceManager().close();
player.getDialogueInterpreter().sendDialogues(389, null, "I need " + String.format("%,d", cost) + " coins for materials. Come", "back when you have the money!");
return true;
}
if (player.getInventory().remove(basicStaff, new Item(995, cost))) {
player.getInterfaceManager().close();
player.getDialogueInterpreter().sendDialogues(389, null, "Just a moment... hang on... hocus pocus abra-", "cadabra... there you go! Enjoy your enchanted staff!");
player.getInventory().add(enchantedStaff);
}
}
return true;
}
}

View file

@ -1,39 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.prayer.PrayerType;
import core.plugin.Initializable;
import core.plugin.Plugin;
import static core.api.ContentAPIKt.hasRequirement;
import content.data.Quests;
/**
* Represents the prayer interface.
* @author 'Vexia
*/
@Initializable
public final class PrayerTabInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(271, this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
final PrayerType type = PrayerType.get(button);
if (type == PrayerType.CHIVALRY || type == PrayerType.PIETY)
if (!hasRequirement(player, Quests.KINGS_RANSOM))
return true;
if (type == null) {
return true;
}
player.getPrayer().toggle(type);
return true;
}
}

View file

@ -1,71 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.diary.AchievementDiary;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.entity.player.link.quest.Quest;
import core.plugin.Initializable;
import core.plugin.Plugin;
/**
* Handles the quest tab reward buttons.
* @author Emperor
* @author Vexia
*/
@Initializable
public class QuestTabInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(274, this); // Quests
ComponentDefinition.put(259, this); // Achievement diary
return this;
}
@Override
public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) {
p.getPulseManager().clear();
switch (component.getId()) {
case 274:
// if (!GameWorld.isEconomyWorld()) {
// p.getSavedData().getSpawnData().handleButton(p, button);
// }
switch (button) {
case 3:
p.getAchievementDiaryManager().openTab();
return true;
case 10:
break;
default:
// if (GameWorld.isEconomyWorld()) {
Quest quest = p.getQuestRepository().forButtonId(button);
if (quest != null) {
p.getInterfaceManager().open(new Component(275));
quest.drawJournal(p, quest.getStage(p));
return true;
} else QuestTabUtils.showRequirementsInterface(p, button);
// }
return false;
}
break;
case 259:
switch (button) {
case 8:
p.getInterfaceManager().openTab(2, new Component(274));
return true;
default:
AchievementDiary diary = p.getAchievementDiaryManager().getDiary(DiaryType.forChild(button));
if (diary != null) {
diary.open(p);
}
return true;
}
}
return true;
}
}

View file

@ -1,89 +0,0 @@
package content.global.handlers.iface;
import static core.api.ContentAPIKt.*;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.plugin.Initializable;
import core.game.node.entity.player.Player;
import core.plugin.Plugin;
/**
* @author 'Vexia
*/
@Initializable
public class SettingTabInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(261, this);
return this;
}
@Override
public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) {
switch (button) {
case 10:// brightness
int brightness = button - 7;
p.getSettings().setBrightness(brightness);
break;
case 11:
case 12:
case 13:
case 14:
case 15:// music
int volume = 15 - button;
p.getSettings().setMusicVolume(volume);
break;
case 16://530 settings
/* if (TutorialSession.getExtension(p).getStage() != TutorialSession.MAX_STAGE) {
p.sendMessage("You must finish the tutorial before opening the graphic settings.");
break;
}*/
p.getInterfaceManager().open(new Component(742));
break;
case 18://530 settings
p.getInterfaceManager().open(new Component(743));
break;
case 17:
case 19:
case 20:// sonund
int volume1 = 20 - button;
p.getSettings().setSoundEffectVolume(volume1);
break;
case 29:
case 30:
case 31:
case 32:
case 33:// all sound
int volume11 = 33 - button;
p.getSettings().setAreaSoundVolume(volume11);
break;
case 6:// mouse
p.getSettings().toggleMouseButton();
break;
case 4:// effects
p.getSettings().toggleChatEffects();
break;
case 5:// private chat
p.getSettings().toggleSplitPrivateChat();
break;
case 7:// aid
if (p.getIronmanManager().checkRestriction()) {
return true;
}
p.getSettings().toggleAcceptAid();
break;
case 3:// run
p.getSettings().toggleRun();
break;
case 8:// house
p.getInterfaceManager().close();
setVarp(p, 261, getVarp(p, 261) & 0x1);
p.getInterfaceManager().openSingleTab(new Component(398));
break;
}
return true;
}
}

View file

@ -1,32 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.player.Player;
import core.plugin.Initializable;
import core.plugin.Plugin;
import static core.api.ContentAPIKt.*;
/**
* Represents the plugin used for the skilling interface.
* @author 'Vexia
* @version 1.0
*/
@Initializable
public final class SkillInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(499, this);
return this;
}
@Override
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
setVarbit(player, 3288, player.getAttribute("skillMenu", -1));
setVarbit(player, 3289, button - 10);
return true;
}
}

View file

@ -1,162 +0,0 @@
package content.global.handlers.iface;
import core.game.component.Component;
import core.game.component.ComponentDefinition;
import core.game.component.ComponentPlugin;
import core.game.node.entity.skill.LevelUp;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.player.Player;
import core.game.world.GameWorld;
import core.plugin.Initializable;
import core.plugin.Plugin;
import static core.api.ContentAPIKt.*;
/**
* Represents the plugin used to handle the skilling tab.
* @author Vexia
* @author Splinter
* @version 1.1
*/
@Initializable
public final class SkillTabInterface extends ComponentPlugin {
@Override
public Plugin<Object> newInstance(Object arg) throws Throwable {
ComponentDefinition.put(320, this);
return this;
}
@Override
public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) {
final SkillConfig config = SkillConfig.forId(button);
if (config == null) {
return true;
}
if (!GameWorld.getSettings().isPvp()) {
if (p.getAttribute("levelup:" + config.getSkillId(), false)) {
p.removeAttribute("levelup:" + config.getSkillId());
LevelUp.sendFlashingIcons(p, -1);
setVarp(p, 1230, ADVANCE_CONFIGS[config.getSkillId()]);
p.getInterfaceManager().open(new Component(741));
} else {
p.getPulseManager().clear();
p.getInterfaceManager().open(new Component(499));
setVarp(p, 965, config.getConfig());
p.getAttributes().put("skillMenu", config.getConfig());
}
} else {
if (config.getSkillId() > 6) {
p.getPacketDispatch().sendMessage("You cannot set a target level for this skill.");
return false;
}
if (p.canSpawn()) {
p.sendMessage("You must be inside Edgeville bank to set levels.");
return false;
}
}
return true;
}
/**
* Holds all the config values of the skill advances.
*/
public static final int[] ADVANCE_CONFIGS = {
9, 40, 17, 49,
25, 57, 33, 641,
659, 664, 121, 649,
89, 114, 107, 72,
64, 80, 673, 680,
99, 698, 689, 705,
};
public enum SkillConfig {
ATTACK(125, 1, Skills.ATTACK),
STRENGTH(126, 2, Skills.STRENGTH),
DEFENCE(127, 5, Skills.DEFENCE),
RANGE(128, 3, Skills.RANGE),
PRAYER(129, 7, Skills.PRAYER),
MAGIC(130, 4, Skills.MAGIC),
RUNECRAFTING(131, 12, Skills.RUNECRAFTING),
HITPOINTS(133, 6, Skills.HITPOINTS),
AGILITY(134, 8, Skills.AGILITY),
HERBLORE(135, 9, Skills.HERBLORE),
THIEVING(136, 10, Skills.THIEVING),
CRAFTING(137, 11, Skills.CRAFTING),
FLETCHING(138, 19, Skills.FLETCHING),
SLAYER(139, 20, Skills.SLAYER),
MINING(141, 13, Skills.MINING),
SMITHING(142, 14, Skills.SMITHING),
FISHING(143, 15, Skills.FISHING),
COOKING(144, 16, Skills.COOKING),
FIREMAKING(145, 17, Skills.FIREMAKING),
WOODCUTTING(146, 18, Skills.WOODCUTTING),
FARMING(147, 21, Skills.FARMING),
CONSTRUCTION(132, 22, Skills.CONSTRUCTION),
HUNTER(140, 23, Skills.HUNTER),
SUMMONING(148, 24, Skills.SUMMONING);
/**
* Constructs a new {@code SkillConfig} {@code Object}.
* @param button the button.
* @param config the config.
*/
SkillConfig(int button, int config, int skillId) {
this.button = button;
this.config = config;
this.skillId = skillId;
}
/**
* Represents the button.
*/
private int button;
/**
* Represents the config.
*/
private int config;
/**
* The skill id.
*/
private int skillId;
/**
* Gets the skill config.
* @param id the id.
* @return the skill config.
*/
public static SkillConfig forId(int id) {
for (SkillConfig config : SkillConfig.values()) {
if (config.button == id)
return config;
}
return null;
}
/**
* Gets the button.
* @return the button.
*/
public int getButton() {
return button;
}
/**
* Gets the config.
* @return the config.
*/
public int getConfig() {
return config;
}
/**
* Gets the skill id.
* @return The skill id.
*/
public int getSkillId() {
return skillId;
}
}
}

View file

@ -0,0 +1,109 @@
package content.global.handlers.iface.tabs
import core.api.sendInputDialogue
import core.api.sendMessage
import core.game.interaction.InterfaceListener
import core.game.system.communication.ClanRank
import core.game.system.communication.ClanRepository
import core.net.amsc.MSPacketRepository
import core.net.amsc.WorldCommunicator
import core.tools.StringUtils
import org.rs09.consts.Components
class ClanTabInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(Components.CLANJOIN_589) { player, _, _, buttonID, _, _ ->
if (buttonID == 9) {
if (player.interfaceManager.opened != null) {
sendMessage(player, "Please close the interface you have open before using 'Clan Setup'")
} else {
ClanRepository.openSettings(player)
}
}
if (buttonID == 14) {
player.communication.toggleLootshare(player)
}
return@on true
}
on(Components.CLANSETUP_590) { player, _, opcode, buttonID, _, _ ->
val clan = ClanRepository.get(player.name, true)
when (buttonID) {
22 -> {
if (opcode == 155) {
sendInputDialogue(player, false, "Enter clan prefix:", ) { value ->
val clanName = StringUtils.formatDisplayName(value.toString())
if (WorldCommunicator.isEnabled()) { MSPacketRepository.sendClanRename(player, clanName) }
if (clan.name == "Chat disabled") {
sendMessage(player, "Your clan channel has now been enabled!")
sendMessage(player, "Join your channel by clicking 'Join Chat' and typing: ${player.username}")
}
clan.name = clanName
player.communication.clanName = clanName
clan.updateSettings(player)
clan.update()
}
}
if (opcode == 196) {
clan.name = "Chat disabled"
player.communication.clanName = ""
if (WorldCommunicator.isEnabled()) { MSPacketRepository.sendClanRename(player, player.communication.clanName) }
clan.updateSettings(player)
clan.delete()
}
}
23 -> {
clan.joinRequirement = getRank(opcode)
player.communication.joinRequirement = clan.joinRequirement
MSPacketRepository.setClanSetting(player, 0, clan.joinRequirement)
}
24 -> {
clan.messageRequirement = getRank(opcode)
player.communication.messageRequirement = clan.messageRequirement
MSPacketRepository.setClanSetting(player, 1, clan.messageRequirement)
}
25 -> {
clan.kickRequirement = getRank(opcode)
player.communication.kickRequirement = clan.kickRequirement
MSPacketRepository.setClanSetting(player, 2, clan.kickRequirement)
}
26 -> {
clan.lootRequirement = if (opcode == 155) ClanRank.ADMINISTRATOR else getRank(opcode)
player.communication.lootRequirement = clan.lootRequirement
MSPacketRepository.setClanSetting(player, 3, clan.lootRequirement)
}
33 -> sendMessage(player, "CoinShare is not available.")
}
clan.updateSettings(player)
clan.update()
return@on true
}
}
fun getRank(opcode: Int): ClanRank {
return when (opcode) {
155 -> ClanRank.NONE
196 -> ClanRank.FRIEND
124 -> ClanRank.RECRUIT
199 -> ClanRank.CORPORAL
234 -> ClanRank.SERGEANT
168 -> ClanRank.LIEUTENANT
166 -> ClanRank.CAPTAIN
64 -> ClanRank.GENERAL
53 -> ClanRank.OWNER
else -> ClanRank.NONE
}
}
}

View file

@ -1,4 +1,4 @@
package content.global.handlers.iface; package content.global.handlers.iface.tabs;
import core.game.component.Component; import core.game.component.Component;
import core.game.component.ComponentDefinition; import core.game.component.ComponentDefinition;

View file

@ -0,0 +1,14 @@
package content.global.handlers.iface.tabs
import core.game.interaction.InterfaceListener
import core.game.node.entity.player.link.emote.Emotes
import org.rs09.consts.Components
class EmoteTabInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(Components.EMOTES_464) { player, _, _, buttonID, _, _ ->
Emotes.handle(player, buttonID)
return@on true
}
}
}

View file

@ -0,0 +1,136 @@
package content.global.handlers.iface.tabs
import content.global.skill.summoning.familiar.BurdenBeast
import core.api.*
import core.game.container.access.InterfaceContainer
import core.game.container.impl.EquipmentContainer
import core.game.global.action.EquipHandler
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
import core.game.interaction.InterfaceListener
import core.game.node.entity.combat.DeathTask
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.prayer.PrayerType
import core.tools.Log
import org.rs09.consts.Components
import org.rs09.consts.Items
class EquipmentTabInterface : InterfaceListener {
override fun defineInterfaceListeners() {
onOpen(ITEMS_KEPT_ON_DEATH_102) { player, component ->
/**
* (Highlight white items are auto destroyed on death Enum#616 (Items kept on death interface) TODO: Parse server sided
* CS2 Script 118 - Items kept on death interface
* Credit Woahscam for figuring this all out.
* @arg_0 (Int): Zone type - 0 Default/1 Safe/2 POH/3 Castle Wars/4 Trouble Brewing/5 Barbarian Assault
* @arg_1 (Int): Amount of items kept on death - 0/1/3/4
* @arg_2 (Object): Item kept on death - slot 0 item id
* @arg_3 (Object): Item kept on death - slot 1 item id
* @arg_4 (Object): Item kept on death - slot 2 item id
* @arg_5 (Object): Item kept on death - slot 3 item id
* @arg_6 (Int): Player is skulled - 0 Not Skulled/1 Skulled
* @arg_7 (Int): Player has BoB summoned with items - 0 BoB not summoned or has no items /1 BoB summoned with items
* @arg_8 (String): String to append based on amount of items kept on death.
*/
val zoneType = player.zoneMonitor.type
val itemsKeptOnDeath = DeathTask.getContainers(player)[0]
val amountKeptOnDeath = if (!player.skullManager.isSkulled && itemsKeptOnDeath.itemCount() < 3) {
if (player.prayer[PrayerType.PROTECT_ITEMS]) 4 else 3
} else {
itemsKeptOnDeath.itemCount()
}
val slot0 = itemsKeptOnDeath.getId(0)
val slot1 = itemsKeptOnDeath.getId(1)
val slot2 = itemsKeptOnDeath.getId(2)
val slot3 = itemsKeptOnDeath.getId(3)
val hasSkull = if (player.skullManager.isSkulled) 1 else 0
val beast: BurdenBeast? = if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar.isBurdenBeast) player.familiarManager.familiar as BurdenBeast else null
val hasBob = if (beast != null && !beast.container.isEmpty) 1 else 0
val message = "You are skulled."
val cs2Args = arrayOf<Any>(hasBob, hasSkull, slot3, slot2, slot1, slot0, amountKeptOnDeath, zoneType, message)
if (amountKeptOnDeath > 4 && zoneType == 0) {
log(this::class.java, Log.ERR, "Items kept on death interface should not contain more than 4 items when not in a safe zone!")
}
player.packetDispatch.sendRunScript(118, "siiooooii", *cs2Args)
val settings = IfaceSettingsBuilder().enableAllOptions().build()
player.packetDispatch.sendIfaceSettings(settings, 18, component.id, 0, itemsKeptOnDeath.itemCount())
player.packetDispatch.sendIfaceSettings(settings, 21, component.id, 0, DeathTask.getContainers(player)[1].itemCount())
return@onOpen true
}
on(Components.WORNITEMS_387) { player, component, opcode, buttonID, slot, itemID ->
when (buttonID) {
28 -> {
if (opcode == 81) EquipHandler.unequip(player, slot, itemID)
if (opcode == 206) operateItem(player, slot)
}
52 -> openInterface(player, ITEMS_KEPT_ON_DEATH_102)
55 -> openInterface(player, Components.EQUIP_SCREEN2_667)
}
return@on true
}
onOpen(Components.EQUIP_SCREEN2_667) { player, component ->
val settings = IfaceSettingsBuilder().enableAllOptions().build()
player.packetDispatch.sendIfaceSettings(settings, 14, component.id, 0, 13)
EquipmentContainer.update(player)
openSingleTab(player, Components.INVENTORY_WEAR2_670)
return@onOpen true
}
on(Components.EQUIP_SCREEN2_667) { player, _, opcode, buttonID, slot, itemID ->
if (buttonID == 14) {
when (opcode) {
9 -> sendMessage(player, player.equipment.get(slot).definition.examine)
155 -> EquipHandler.unequip(player, slot, itemID)
196 -> operateItem(player, slot)
}
}
return@on true
}
onClose(Components.EQUIP_SCREEN2_667) { player, _ ->
closeTabInterface(player)
return@onClose true
}
onOpen(Components.INVENTORY_WEAR2_670) { player, component ->
InterfaceContainer.generateItems(player, player.inventory.toArray(), arrayOf("Equip"), component.id, 0, 7, 4, 93)
return@onOpen true
}
on(Components.INVENTORY_WEAR2_670) { player, _, opcode, _, slot, _ ->
if (opcode == 9) sendMessage(player, player.inventory.get(slot).definition.examine)
if (opcode == 155) equipItem(player, slot)
return@on true
}
}
private fun equipItem(player: Player, slot: Int) {
val item = player.inventory.get(slot) ?: return
if (item.definition.options.any { it in arrayOf("Equip", "Wield", "Wear") } || item.id == Items.BEER_1917) {
InteractionListeners.run(item.id, IntType.ITEM, "equip", player, item)
} else {
sendMessage(player, "You can't wear that.")
}
}
private fun operateItem(player: Player, slot: Int) {
val item = player.equipment.get(slot) ?: return
when {
InteractionListeners.run(item.id, IntType.ITEM, "operate", player, item) -> return
item.operateHandler?.handle(player, item, "operate") == true -> return
else -> sendMessage(player, "You can't operate that.")
}
}
companion object {
private const val ITEMS_KEPT_ON_DEATH_102 = 102
}
}

View file

@ -0,0 +1,34 @@
package content.global.handlers.iface.tabs
import core.api.sendMessage
import core.game.interaction.InterfaceListener
import core.game.world.repository.Repository
import org.rs09.consts.Components
class LogoutTabInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(Components.LOGOUT_182) { player, _, _, buttonID, _, _ ->
if (buttonID == 6) {
return@on when {
!player.zoneMonitor.canLogout() -> true
player.inCombat() -> {
sendMessage(player, "You can't log out until 10 seconds after the end of combat.")
true
}
player.isTeleporting -> {
sendMessage(player, "Please finish your teleport before logging out.")
true
}
else -> {
Repository.disconnectionQueue.add(player)
true
}
}
}
return@on true
}
}
}

View file

@ -0,0 +1,23 @@
package content.global.handlers.iface.tabs
import content.global.skill.magic.SpellListener
import content.global.skill.magic.SpellListeners
import core.api.getAttribute
import core.game.interaction.InterfaceListener
import core.game.node.entity.combat.spell.MagicSpell
import core.game.node.entity.player.link.SpellBookManager.SpellBook
import core.game.world.GameWorld
class MagicTabInterface : InterfaceListener {
override fun defineInterfaceListeners() {
SpellBook.values().forEach {
on(it.interfaceId) { player, _, _, buttonID, _, _ ->
if (GameWorld.ticks < getAttribute(player, "magic:delay", -1)) return@on true
SpellListeners.run(buttonID, SpellListener.NONE, it.name.lowercase(), player)
return@on MagicSpell.castSpell(player, it, buttonID, player)
}
}
}
}

View file

@ -0,0 +1,38 @@
package content.global.handlers.iface.tabs
import core.api.sendMessage
import core.game.interaction.InterfaceListener
import core.game.node.entity.player.link.music.MusicEntry
import org.rs09.consts.Components
class MusicTabInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(Components.MUSIC_V3_187) { player, _, opcode, buttonID, slot, _ ->
if (opcode == 155) {
if (buttonID == 11) {
player.musicPlayer.toggleLooping()
return@on true
}
if (buttonID == 1) {
if (player.musicPlayer.unlocked[slot] != null) {
player.musicPlayer.play(player.musicPlayer.unlocked[slot])
return@on true
}
if (player.isAdmin) {
for (entry in MusicEntry.getSongs().values) {
if (entry.index == slot) {
player.musicPlayer.unlock(entry.id)
}
}
} else {
sendMessage(player, "You have not unlocked this piece of music yet!")
}
return@on true
}
}
return@on true
}
}
}

View file

@ -0,0 +1,14 @@
package content.global.handlers.iface.tabs
import core.game.interaction.InterfaceListener
import core.game.node.entity.player.link.prayer.PrayerType
import org.rs09.consts.Components
class PrayerTabInterface : InterfaceListener {
override fun defineInterfaceListeners() {
on(Components.PRAYER_271) { player, _, _, buttonID, _, _ ->
val prayer = PrayerType.get(buttonID) ?: return@on true
return@on player.prayer.toggle(prayer)
}
}
}

Some files were not shown because too many files have changed in this diff Show more