mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-23 11:25:11 -06:00
Merge branch 2009scape:master into master
This commit is contained in:
commit
094bc4ac6b
102 changed files with 3667 additions and 1692 deletions
30
.dockerignore
Normal file
30
.dockerignore
Normal 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
12
.gitignore
vendored
|
|
@ -18,7 +18,8 @@ Server/data/global_kill_stats.json
|
|||
Server/ge_test.db
|
||||
Server/latestdump.txt
|
||||
Management-Server/managementprops/
|
||||
Server/worldprops/
|
||||
Server/worldprops/*
|
||||
!Server/worldprops/default.conf
|
||||
|
||||
**/.idea/workspace.xml
|
||||
**/.idea/tasks.xml
|
||||
|
|
@ -32,3 +33,12 @@ gradle
|
|||
build/kotlin/sessions/
|
||||
**/*.iml
|
||||
Server/hasRan.txt
|
||||
|
||||
# Local volumes
|
||||
/config
|
||||
/data
|
||||
/db
|
||||
|
||||
# Env files containing secrets
|
||||
/.env
|
||||
/*.env
|
||||
|
|
|
|||
10
Dockerfile
10
Dockerfile
|
|
@ -4,14 +4,8 @@ FROM maven:3-openjdk-11-slim
|
|||
# Set working directory to /app
|
||||
WORKDIR /app
|
||||
|
||||
# Update apt; install git and git-lfs
|
||||
RUN apt-get update && apt-get -qq -y install git git-lfs
|
||||
|
||||
# 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
|
||||
# Copy all sources etc
|
||||
COPY . .
|
||||
|
||||
# Make sure ./run has permissions
|
||||
RUN chmod +x run
|
||||
|
|
|
|||
72
README.md
72
README.md
|
|
@ -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`
|
||||
|
||||
#### 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
|
||||
|
||||
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.**
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@
|
|||
"start_graphic": "232,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "226,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "813",
|
||||
|
|
@ -133,7 +133,7 @@
|
|||
"start_graphic": "233,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "227,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "814",
|
||||
|
|
@ -141,7 +141,7 @@
|
|||
"start_graphic": "234,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "228,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "815",
|
||||
|
|
@ -149,7 +149,7 @@
|
|||
"start_graphic": "235,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "229,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "816",
|
||||
|
|
@ -157,7 +157,7 @@
|
|||
"start_graphic": "236,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "230,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "817",
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
"start_graphic": "237,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "231,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "825",
|
||||
|
|
@ -221,7 +221,7 @@
|
|||
"start_graphic": "206,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "200,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "832",
|
||||
|
|
@ -229,7 +229,7 @@
|
|||
"start_graphic": "207,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "201,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "833",
|
||||
|
|
@ -237,7 +237,7 @@
|
|||
"start_graphic": "208,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "202,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "834",
|
||||
|
|
@ -245,7 +245,7 @@
|
|||
"start_graphic": "209,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "203,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "835",
|
||||
|
|
@ -253,7 +253,7 @@
|
|||
"start_graphic": "210,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "204,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "836",
|
||||
|
|
@ -261,7 +261,7 @@
|
|||
"start_graphic": "211,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "205,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "863",
|
||||
|
|
@ -325,7 +325,7 @@
|
|||
"start_graphic": "219,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "212,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "871",
|
||||
|
|
@ -333,7 +333,7 @@
|
|||
"start_graphic": "220,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "213,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "872",
|
||||
|
|
@ -341,7 +341,7 @@
|
|||
"start_graphic": "221,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "214,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "873",
|
||||
|
|
@ -349,7 +349,7 @@
|
|||
"start_graphic": "223,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "216,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "874",
|
||||
|
|
@ -357,7 +357,7 @@
|
|||
"start_graphic": "222,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "215,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "875",
|
||||
|
|
@ -365,7 +365,7 @@
|
|||
"start_graphic": "224,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "217,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "876",
|
||||
|
|
@ -373,7 +373,7 @@
|
|||
"start_graphic": "225,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "218,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "877",
|
||||
|
|
@ -389,7 +389,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "879",
|
||||
|
|
@ -421,7 +421,7 @@
|
|||
"start_graphic": "19,96",
|
||||
"darkbow_graphic": "1104,96",
|
||||
"projectile": "10,40,36,41,46,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "884",
|
||||
|
|
@ -437,7 +437,7 @@
|
|||
"start_graphic": "18,96",
|
||||
"darkbow_graphic": "1105,96",
|
||||
"projectile": "9,40,36,41,46,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "886",
|
||||
|
|
@ -453,7 +453,7 @@
|
|||
"start_graphic": "20,96",
|
||||
"darkbow_graphic": "1106,96",
|
||||
"projectile": "11,40,36,41,46,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "888",
|
||||
|
|
@ -469,7 +469,7 @@
|
|||
"start_graphic": "21,96",
|
||||
"darkbow_graphic": "1107,96",
|
||||
"projectile": "12,40,36,41,46,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "890",
|
||||
|
|
@ -485,7 +485,7 @@
|
|||
"start_graphic": "22,96",
|
||||
"darkbow_graphic": "1108,96",
|
||||
"projectile": "13,40,36,41,46,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "892",
|
||||
|
|
@ -501,7 +501,7 @@
|
|||
"start_graphic": "24,96",
|
||||
"darkbow_graphic": "1109,96",
|
||||
"projectile": "15,40,36,41,46,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "2532",
|
||||
|
|
@ -565,7 +565,7 @@
|
|||
"start_graphic": "273,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "227,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "4160",
|
||||
|
|
@ -725,7 +725,7 @@
|
|||
"start_graphic": "19,96",
|
||||
"darkbow_graphic": "1104,96",
|
||||
"projectile": "10,40,36,41,46,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5617",
|
||||
|
|
@ -733,7 +733,7 @@
|
|||
"start_graphic": "18,96",
|
||||
"darkbow_graphic": "1105,96",
|
||||
"projectile": "9,40,36,41,46,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5618",
|
||||
|
|
@ -741,7 +741,7 @@
|
|||
"start_graphic": "20,96",
|
||||
"darkbow_graphic": "1106,96",
|
||||
"projectile": "11,40,36,41,46,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5619",
|
||||
|
|
@ -749,7 +749,7 @@
|
|||
"start_graphic": "21,96",
|
||||
"darkbow_graphic": "1107,96",
|
||||
"projectile": "12,40,36,41,46,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5620",
|
||||
|
|
@ -757,7 +757,7 @@
|
|||
"start_graphic": "22,96",
|
||||
"darkbow_graphic": "1108,96",
|
||||
"projectile": "13,40,36,41,46,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5621",
|
||||
|
|
@ -773,7 +773,7 @@
|
|||
"start_graphic": "19,96",
|
||||
"darkbow_graphic": "1104,96",
|
||||
"projectile": "10,40,36,41,46,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5623",
|
||||
|
|
@ -781,7 +781,7 @@
|
|||
"start_graphic": "18,96",
|
||||
"darkbow_graphic": "1105,96",
|
||||
"projectile": "9,40,36,41,46,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5624",
|
||||
|
|
@ -789,7 +789,7 @@
|
|||
"start_graphic": "20,96",
|
||||
"darkbow_graphic": "1106,96",
|
||||
"projectile": "11,40,36,41,46,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5625",
|
||||
|
|
@ -797,7 +797,7 @@
|
|||
"start_graphic": "21,96",
|
||||
"darkbow_graphic": "1107,96",
|
||||
"projectile": "12,40,36,41,46,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5626",
|
||||
|
|
@ -805,7 +805,7 @@
|
|||
"start_graphic": "22,96",
|
||||
"darkbow_graphic": "1108,96",
|
||||
"projectile": "13,40,36,41,46,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5627",
|
||||
|
|
@ -813,7 +813,7 @@
|
|||
"start_graphic": "24,96",
|
||||
"darkbow_graphic": "1109,96",
|
||||
"projectile": "15,40,36,41,46,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5628",
|
||||
|
|
@ -821,7 +821,7 @@
|
|||
"start_graphic": "232,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "226,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5629",
|
||||
|
|
@ -829,7 +829,7 @@
|
|||
"start_graphic": "233,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "227,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5630",
|
||||
|
|
@ -837,7 +837,7 @@
|
|||
"start_graphic": "235,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "229,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5631",
|
||||
|
|
@ -845,7 +845,7 @@
|
|||
"start_graphic": "273,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "227,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5633",
|
||||
|
|
@ -853,7 +853,7 @@
|
|||
"start_graphic": "236,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "230,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5634",
|
||||
|
|
@ -861,7 +861,7 @@
|
|||
"start_graphic": "237,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "231,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5635",
|
||||
|
|
@ -869,7 +869,7 @@
|
|||
"start_graphic": "232,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "226,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5636",
|
||||
|
|
@ -877,7 +877,7 @@
|
|||
"start_graphic": "233,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "227,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5637",
|
||||
|
|
@ -885,7 +885,7 @@
|
|||
"start_graphic": "234,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "228,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5638",
|
||||
|
|
@ -893,7 +893,7 @@
|
|||
"start_graphic": "273,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "227,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5639",
|
||||
|
|
@ -901,7 +901,7 @@
|
|||
"start_graphic": "235,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "229,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5640",
|
||||
|
|
@ -909,7 +909,7 @@
|
|||
"start_graphic": "236,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "230,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5641",
|
||||
|
|
@ -917,7 +917,7 @@
|
|||
"start_graphic": "237,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "231,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5642",
|
||||
|
|
@ -925,7 +925,7 @@
|
|||
"start_graphic": "206,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "200,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5643",
|
||||
|
|
@ -933,7 +933,7 @@
|
|||
"start_graphic": "207,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "201,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5644",
|
||||
|
|
@ -941,7 +941,7 @@
|
|||
"start_graphic": "208,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "202,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5645",
|
||||
|
|
@ -949,7 +949,7 @@
|
|||
"start_graphic": "209,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "203,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5646",
|
||||
|
|
@ -957,7 +957,7 @@
|
|||
"start_graphic": "210,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "204,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5647",
|
||||
|
|
@ -965,7 +965,7 @@
|
|||
"start_graphic": "211,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "205,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5648",
|
||||
|
|
@ -973,7 +973,7 @@
|
|||
"start_graphic": "206,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "200,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5649",
|
||||
|
|
@ -981,7 +981,7 @@
|
|||
"start_graphic": "207,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "201,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5650",
|
||||
|
|
@ -989,7 +989,7 @@
|
|||
"start_graphic": "208,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "202,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5651",
|
||||
|
|
@ -997,7 +997,7 @@
|
|||
"start_graphic": "209,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "203,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5652",
|
||||
|
|
@ -1005,7 +1005,7 @@
|
|||
"start_graphic": "210,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "204,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5653",
|
||||
|
|
@ -1013,7 +1013,7 @@
|
|||
"start_graphic": "211,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "205,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5654",
|
||||
|
|
@ -1021,7 +1021,7 @@
|
|||
"start_graphic": "219,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "212,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5655",
|
||||
|
|
@ -1029,7 +1029,7 @@
|
|||
"start_graphic": "220,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "213,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5656",
|
||||
|
|
@ -1037,7 +1037,7 @@
|
|||
"start_graphic": "221,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "214,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5657",
|
||||
|
|
@ -1045,7 +1045,7 @@
|
|||
"start_graphic": "223,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "216,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5658",
|
||||
|
|
@ -1053,7 +1053,7 @@
|
|||
"start_graphic": "222,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "215,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5659",
|
||||
|
|
@ -1061,7 +1061,7 @@
|
|||
"start_graphic": "224,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "217,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5660",
|
||||
|
|
@ -1069,7 +1069,7 @@
|
|||
"start_graphic": "225,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "218,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "5661",
|
||||
|
|
@ -1077,7 +1077,7 @@
|
|||
"start_graphic": "219,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "212,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5662",
|
||||
|
|
@ -1085,7 +1085,7 @@
|
|||
"start_graphic": "220,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "213,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5663",
|
||||
|
|
@ -1093,7 +1093,7 @@
|
|||
"start_graphic": "221,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "214,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5664",
|
||||
|
|
@ -1101,7 +1101,7 @@
|
|||
"start_graphic": "223,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "216,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5665",
|
||||
|
|
@ -1109,7 +1109,7 @@
|
|||
"start_graphic": "222,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "215,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5666",
|
||||
|
|
@ -1117,7 +1117,7 @@
|
|||
"start_graphic": "224,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "217,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "5667",
|
||||
|
|
@ -1125,7 +1125,7 @@
|
|||
"start_graphic": "225,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "218,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "6061",
|
||||
|
|
@ -1133,7 +1133,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "6062",
|
||||
|
|
@ -1141,7 +1141,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "6522",
|
||||
|
|
@ -1293,7 +1293,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "9287",
|
||||
|
|
@ -1301,7 +1301,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "9288",
|
||||
|
|
@ -1309,7 +1309,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "9289",
|
||||
|
|
@ -1317,7 +1317,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "9290",
|
||||
|
|
@ -1325,7 +1325,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "9291",
|
||||
|
|
@ -1333,7 +1333,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "9293",
|
||||
|
|
@ -1341,7 +1341,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "9294",
|
||||
|
|
@ -1349,7 +1349,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "9295",
|
||||
|
|
@ -1357,7 +1357,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "9296",
|
||||
|
|
@ -1365,7 +1365,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "9297",
|
||||
|
|
@ -1373,7 +1373,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "9298",
|
||||
|
|
@ -1381,7 +1381,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "9300",
|
||||
|
|
@ -1389,7 +1389,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "9301",
|
||||
|
|
@ -1397,7 +1397,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "9302",
|
||||
|
|
@ -1405,7 +1405,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "9303",
|
||||
|
|
@ -1413,7 +1413,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "9304",
|
||||
|
|
@ -1421,7 +1421,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "9305",
|
||||
|
|
@ -1429,7 +1429,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "9335",
|
||||
|
|
@ -1557,7 +1557,7 @@
|
|||
"start_graphic": "1116,96",
|
||||
"darkbow_graphic": "1114,96",
|
||||
"projectile": "1120,40,36,41,46,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "11228",
|
||||
|
|
@ -1565,7 +1565,7 @@
|
|||
"start_graphic": "1116,96",
|
||||
"darkbow_graphic": "1114,96",
|
||||
"projectile": "1120,40,36,41,46,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "11229",
|
||||
|
|
@ -1573,7 +1573,7 @@
|
|||
"start_graphic": "1116,96",
|
||||
"darkbow_graphic": "1114,96",
|
||||
"projectile": "1120,40,36,41,46,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "11230",
|
||||
|
|
@ -1589,7 +1589,7 @@
|
|||
"start_graphic": "1123,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1122,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "11233",
|
||||
|
|
@ -1597,7 +1597,7 @@
|
|||
"start_graphic": "1123,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1122,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "11234",
|
||||
|
|
@ -1605,7 +1605,7 @@
|
|||
"start_graphic": "1123,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1122,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "13083",
|
||||
|
|
@ -1621,7 +1621,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "13085",
|
||||
|
|
@ -1629,7 +1629,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "13086",
|
||||
|
|
@ -1637,7 +1637,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "27,38,36,41,32,5,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "13280",
|
||||
|
|
@ -1661,7 +1661,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1837,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "13881",
|
||||
|
|
@ -1669,7 +1669,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1837,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "13882",
|
||||
|
|
@ -1677,7 +1677,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1837,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "13883",
|
||||
|
|
@ -1701,7 +1701,7 @@
|
|||
"start_graphic": "-1,0",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1837,40,36,32,32,15,0",
|
||||
"poison_damage": "28"
|
||||
"poison_damage": "10"
|
||||
},
|
||||
{
|
||||
"itemId": "13955",
|
||||
|
|
@ -1709,7 +1709,7 @@
|
|||
"start_graphic": "1837,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1840,40,36,32,32,15,0",
|
||||
"poison_damage": "38"
|
||||
"poison_damage": "15"
|
||||
},
|
||||
{
|
||||
"itemId": "13956",
|
||||
|
|
@ -1717,7 +1717,7 @@
|
|||
"start_graphic": "1837,96",
|
||||
"darkbow_graphic": "",
|
||||
"projectile": "1840,40,36,32,32,15,0",
|
||||
"poison_damage": "48"
|
||||
"poison_damage": "20"
|
||||
},
|
||||
{
|
||||
"itemId": "13957",
|
||||
|
|
|
|||
|
|
@ -1439,6 +1439,12 @@
|
|||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
{
|
||||
"id": "11470",
|
||||
"replaceId": "11471",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
{
|
||||
"id": "11483",
|
||||
"replaceId": "11708",
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@
|
|||
},
|
||||
{
|
||||
"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,3218,9887,0,33}-"
|
||||
},
|
||||
{
|
||||
"item_id": "952",
|
||||
|
|
@ -415,6 +415,14 @@
|
|||
"item_id": "1785",
|
||||
"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",
|
||||
"loc_data": "{1,2638,3292,0,150}-"
|
||||
|
|
@ -597,7 +605,7 @@
|
|||
},
|
||||
{
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -18946,7 +18946,7 @@
|
|||
"equipment_slot": "2"
|
||||
},
|
||||
{
|
||||
"examine": "Anna's shiny silver coated necklace.",
|
||||
"examine": "Anna's shiny silver coated necklace coated with a thin layer of flour.",
|
||||
"durability": null,
|
||||
"name": "Silver necklace",
|
||||
"weight": "1",
|
||||
|
|
@ -18964,7 +18964,7 @@
|
|||
"id": "1798"
|
||||
},
|
||||
{
|
||||
"examine": "Bob's shiny silver coated tea cup.",
|
||||
"examine": "Bob's shiny silver coated tea cup coated with a thin layer of flour.",
|
||||
"durability": null,
|
||||
"name": "Silver cup",
|
||||
"tradeable": "false",
|
||||
|
|
@ -18982,7 +18982,7 @@
|
|||
"id": "1800"
|
||||
},
|
||||
{
|
||||
"examine": "Carol's shiny silver coated bottle.",
|
||||
"examine": "Carol's shiny silver coated bottle coated with a thin layer of flour.",
|
||||
"durability": null,
|
||||
"name": "Silver bottle",
|
||||
"tradeable": "false",
|
||||
|
|
@ -19000,7 +19000,7 @@
|
|||
"id": "1802"
|
||||
},
|
||||
{
|
||||
"examine": "David's shiny silver coated book.",
|
||||
"examine": "David's shiny silver coated book coated with a thin layer of flour.",
|
||||
"durability": null,
|
||||
"name": "Silver book",
|
||||
"tradeable": "false",
|
||||
|
|
@ -19018,7 +19018,7 @@
|
|||
"id": "1804"
|
||||
},
|
||||
{
|
||||
"examine": "Elizabeth's shiny silver coated needle.",
|
||||
"examine": "Elizabeth's shiny silver coated needle coated with a thin layer of flour.",
|
||||
"durability": null,
|
||||
"name": "Silver needle",
|
||||
"tradeable": "false",
|
||||
|
|
@ -19036,7 +19036,7 @@
|
|||
"id": "1806"
|
||||
},
|
||||
{
|
||||
"examine": "Frank's shiny silver coated pot.",
|
||||
"examine": "Frank's shiny silver coated pot coated with a thin layer of flour.",
|
||||
"durability": null,
|
||||
"name": "Silver pot",
|
||||
"tradeable": "false",
|
||||
|
|
@ -19045,7 +19045,7 @@
|
|||
"id": "1807"
|
||||
},
|
||||
{
|
||||
"examine": "Some (colour) thread found at the murder scene.",
|
||||
"examine": "Some red thread found at the murder scene.",
|
||||
"durability": null,
|
||||
"name": "Criminal's thread",
|
||||
"tradeable": "false",
|
||||
|
|
@ -19054,7 +19054,7 @@
|
|||
"id": "1808"
|
||||
},
|
||||
{
|
||||
"examine": "Some (colour) thread found at the murder scene.",
|
||||
"examine": "Some green thread found at the murder scene.",
|
||||
"durability": null,
|
||||
"name": "Criminal's thread",
|
||||
"tradeable": "false",
|
||||
|
|
@ -19063,7 +19063,7 @@
|
|||
"id": "1809"
|
||||
},
|
||||
{
|
||||
"examine": "Some (colour) thread found at the murder scene.",
|
||||
"examine": "Some blue thread found at the murder scene.",
|
||||
"durability": null,
|
||||
"name": "Criminal's thread",
|
||||
"tradeable": "false",
|
||||
|
|
@ -19090,7 +19090,7 @@
|
|||
"id": "1812"
|
||||
},
|
||||
{
|
||||
"examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.",
|
||||
"examine": "A flimsy-looking dagger found at the crime scene.",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"durability": null,
|
||||
"name": "Criminal's dagger",
|
||||
|
|
@ -19098,7 +19098,7 @@
|
|||
"id": "1813"
|
||||
},
|
||||
{
|
||||
"examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.",
|
||||
"examine": "A flimsy looking dagger found at the crime scene coated with a thin layer of flour.",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"durability": null,
|
||||
"name": "Criminal's dagger",
|
||||
|
|
@ -51573,6 +51573,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "483",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Iron dagger(p+)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51601,6 +51602,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "350",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Bronze dagger(p+)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51630,6 +51632,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "575",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Steel dagger(p+)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51659,6 +51662,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "538",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Mithril dagger(p+)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51684,6 +51688,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "800",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Adamant dagger(p+)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51711,6 +51716,7 @@
|
|||
"equip_audio": "2248",
|
||||
"render_anim": "2584",
|
||||
"equipment_slot": "3",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"lendable": "true",
|
||||
"grand_exchange_price": "4538",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
|
|
@ -51779,6 +51785,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "664",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Black dagger(p+)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51826,6 +51833,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "4128",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Iron dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51854,6 +51862,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "5088",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Br'ze dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51883,6 +51892,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "4729",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Steel dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51912,6 +51922,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "3476",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Mithril dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51937,6 +51948,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "4612",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Adamant dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -51967,6 +51979,7 @@
|
|||
"lendable": "true",
|
||||
"grand_exchange_price": "5061",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Rune dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -52032,6 +52045,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "4921",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "Black dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -60306,6 +60320,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "497",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "White dagger(p)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -60335,6 +60350,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "982",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "White dagger(p+)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -60364,6 +60380,7 @@
|
|||
"equipment_slot": "3",
|
||||
"grand_exchange_price": "8422",
|
||||
"attack_audios": "2517,2517,2500,2517",
|
||||
"attack_anims": "400,400,401,400",
|
||||
"name": "White dagger(p++)",
|
||||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -89019,7 +89036,7 @@
|
|||
"id": "10383"
|
||||
},
|
||||
{
|
||||
"requirements": "{1,70}-{4,40}",
|
||||
"requirements": "{1,40}-{4,70}",
|
||||
"ge_buy_limit": "2",
|
||||
"examine": "Saradomin blessed dragonhide vambraces.",
|
||||
"durability": null,
|
||||
|
|
@ -90178,9 +90195,13 @@
|
|||
"weight": "1.1",
|
||||
"attack_speed": "5",
|
||||
"weapon_interface": "2",
|
||||
"equip_audio": "2229",
|
||||
"render_anim": "2586",
|
||||
"defence_anim": "397",
|
||||
"equipment_slot": "3",
|
||||
"attack_anims": "395,395,401,395",
|
||||
"destroy_message": "I can obtain a replacement axe from the Burthorpe Slayer Master.",
|
||||
"attack_audios": "2498,2498,2497,2498",
|
||||
"name": "Blessed axe",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -130463,7 +130484,7 @@
|
|||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "14497",
|
||||
"bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,2,0"
|
||||
"bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,2,0,0"
|
||||
},
|
||||
{
|
||||
"shop_price": "120000",
|
||||
|
|
@ -130519,7 +130540,7 @@
|
|||
"tradeable": "true",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "14501",
|
||||
"bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,2,0"
|
||||
"bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,2,0,0"
|
||||
},
|
||||
{
|
||||
"shop_price": "80000",
|
||||
|
|
|
|||
|
|
@ -1095,6 +1095,10 @@
|
|||
"region": "10829",
|
||||
"id": "378"
|
||||
},
|
||||
{
|
||||
"region": "10831",
|
||||
"id": "393"
|
||||
},
|
||||
{
|
||||
"region": "10833",
|
||||
"id": "249"
|
||||
|
|
|
|||
|
|
@ -2006,7 +2006,7 @@
|
|||
"defence_animation": "6255",
|
||||
"weakness": "0",
|
||||
"slayer_exp": "23",
|
||||
"poison_amount": "3",
|
||||
"poison_amount": "15",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "6256",
|
||||
"name": "Poison Scorpion",
|
||||
|
|
@ -2517,7 +2517,7 @@
|
|||
"respawn_delay": "30",
|
||||
"defence_animation": "5328",
|
||||
"weakness": "2",
|
||||
"poison_amount": "6",
|
||||
"poison_amount": "30",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "5329",
|
||||
"name": "Poison spider",
|
||||
|
|
@ -3330,7 +3330,7 @@
|
|||
"respawn_delay": "50",
|
||||
"defence_animation": "0",
|
||||
"weakness": "8",
|
||||
"poison_amount": "11",
|
||||
"poison_amount": "55",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "836",
|
||||
"name": "Tribesman",
|
||||
|
|
@ -8816,7 +8816,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "Big",
|
||||
"examine": "Big, noisy, and scary looking!",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"defence_animation": "0",
|
||||
|
|
@ -10513,7 +10513,7 @@
|
|||
"respawn_delay": "30",
|
||||
"defence_animation": "5328",
|
||||
"weakness": "2",
|
||||
"poison_amount": "6",
|
||||
"poison_amount": "30",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "5329",
|
||||
"name": "Poison spider",
|
||||
|
|
@ -12353,7 +12353,7 @@
|
|||
"defence_animation": "6227",
|
||||
"weakness": "7",
|
||||
"slayer_exp": "90",
|
||||
"poison_amount": "4",
|
||||
"poison_amount": "20",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "6228",
|
||||
"name": "Kalphite Soldier",
|
||||
|
|
@ -12377,7 +12377,7 @@
|
|||
"respawn_delay": "65",
|
||||
"defence_animation": "6232",
|
||||
"weakness": "7",
|
||||
"poison_amount": "6",
|
||||
"poison_amount": "30",
|
||||
"magic_animation": "6223",
|
||||
"death_animation": "6230",
|
||||
"name": "Kalphite Guardian",
|
||||
|
|
@ -12424,7 +12424,7 @@
|
|||
"respawn_delay": "65",
|
||||
"defence_animation": "6232",
|
||||
"weakness": "7",
|
||||
"poison_amount": "6",
|
||||
"poison_amount": "30",
|
||||
"magic_animation": "6223",
|
||||
"death_animation": "6230",
|
||||
"name": "Kalphite Guardian",
|
||||
|
|
@ -12444,7 +12444,7 @@
|
|||
"melee_animation": "6241",
|
||||
"range_animation": "6241",
|
||||
"attack_speed": "4",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "150",
|
||||
"respawn_delay": "0",
|
||||
"defence_animation": "6232",
|
||||
|
|
@ -13455,6 +13455,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"weakness": "3",
|
||||
"poison_amount": "30",
|
||||
"magic_animation": "811",
|
||||
"death_animation": "836",
|
||||
"name": "Saradomin wizard",
|
||||
|
|
@ -16454,6 +16455,7 @@
|
|||
"defence_animation": "267",
|
||||
"weakness": "1",
|
||||
"slayer_exp": "22",
|
||||
"poison_amount": "40",
|
||||
"magic_animation": "266",
|
||||
"death_animation": "265",
|
||||
"name": "Cave crawler",
|
||||
|
|
@ -16476,6 +16478,7 @@
|
|||
"respawn_delay": "25",
|
||||
"defence_animation": "267",
|
||||
"slayer_exp": "22",
|
||||
"poison_amount": "40",
|
||||
"magic_animation": "266",
|
||||
"death_animation": "265",
|
||||
"name": "Cave crawler",
|
||||
|
|
@ -16498,6 +16501,7 @@
|
|||
"respawn_delay": "25",
|
||||
"defence_animation": "267",
|
||||
"slayer_exp": "22",
|
||||
"poison_amount": "40",
|
||||
"magic_animation": "266",
|
||||
"death_animation": "265",
|
||||
"name": "Cave crawler",
|
||||
|
|
@ -16520,6 +16524,7 @@
|
|||
"respawn_delay": "25",
|
||||
"defence_animation": "267",
|
||||
"slayer_exp": "22",
|
||||
"poison_amount": "40",
|
||||
"magic_animation": "266",
|
||||
"death_animation": "265",
|
||||
"name": "Cave crawler",
|
||||
|
|
@ -19313,7 +19318,7 @@
|
|||
"defence_animation": "0",
|
||||
"weakness": "1",
|
||||
"slayer_exp": "25",
|
||||
"poison_amount": "3",
|
||||
"poison_amount": "15",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "1792",
|
||||
"name": "Cave slime",
|
||||
|
|
@ -20627,6 +20632,7 @@
|
|||
"poisonous": "true",
|
||||
"defence_animation": "1946",
|
||||
"weakness": "7",
|
||||
"poison_amount": "15",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "5464",
|
||||
"name": "Scarabs",
|
||||
|
|
@ -20964,6 +20970,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"weakness": "6",
|
||||
"poison_amount": "15",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "1946",
|
||||
"name": "Scarab swarm",
|
||||
|
|
@ -21678,7 +21685,7 @@
|
|||
"range_animation": "0",
|
||||
"combat_audio": "931,923,922",
|
||||
"attack_speed": "5",
|
||||
"respawn_delay": "60",
|
||||
"respawn_delay": "0",
|
||||
"defence_animation": "0",
|
||||
"weakness": "7",
|
||||
"slayer_exp": "30",
|
||||
|
|
@ -25076,7 +25083,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"weakness": "1",
|
||||
"poison_amount": "11",
|
||||
"poison_amount": "55",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "278",
|
||||
"name": "Bush snake",
|
||||
|
|
@ -25095,7 +25102,7 @@
|
|||
"poisonous": "true",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "276",
|
||||
"poison_amount": "11",
|
||||
"poison_amount": "55",
|
||||
"death_animation": "278",
|
||||
"name": "Bush snake",
|
||||
"defence_level": "1",
|
||||
|
|
@ -25211,7 +25218,7 @@
|
|||
"respawn_delay": "50",
|
||||
"defence_animation": "0",
|
||||
"weakness": "9",
|
||||
"poison_amount": "11",
|
||||
"poison_amount": "55",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "836",
|
||||
"name": "Tribesman",
|
||||
|
|
@ -29571,6 +29578,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "2937",
|
||||
"weakness": "9",
|
||||
"poison_amount": "40",
|
||||
"magic_animation": "2936",
|
||||
"death_animation": "2938",
|
||||
"name": "Jogre Champion",
|
||||
|
|
@ -29609,7 +29617,7 @@
|
|||
"examine": "Champion of the jogres.",
|
||||
"melee_animation": "5485",
|
||||
"range_animation": "5493",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "5493",
|
||||
"weakness": "9",
|
||||
|
|
@ -32631,6 +32639,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"weakness": "10",
|
||||
"poison_amount": "35",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "7249",
|
||||
"name": "Wild jade vine",
|
||||
|
|
@ -32652,6 +32661,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"weakness": "10",
|
||||
"poison_amount": "35",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "7249",
|
||||
"name": "Wild jade vine",
|
||||
|
|
@ -32673,6 +32683,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"weakness": "10",
|
||||
"poison_amount": "35",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "7249",
|
||||
"name": "Wild jade vine",
|
||||
|
|
@ -32694,6 +32705,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"weakness": "10",
|
||||
"poison_amount": "35",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "7249",
|
||||
"name": "Wild jade vine",
|
||||
|
|
@ -33773,7 +33785,7 @@
|
|||
"respawn_delay": "60",
|
||||
"defence_animation": "6227",
|
||||
"weakness": "6",
|
||||
"poison_amount": "4",
|
||||
"poison_amount": "20",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "6228",
|
||||
"name": "Kalphite Soldier",
|
||||
|
|
@ -46891,15 +46903,15 @@
|
|||
{
|
||||
"examine": "A fiendish embodiment of water.",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "1582",
|
||||
"range_animation": "1582",
|
||||
"melee_animation": "299",
|
||||
"range_animation": "299",
|
||||
"combat_audio": "3774,3773,3772",
|
||||
"attack_speed": "4",
|
||||
"magic_level": "105",
|
||||
"defence_animation": "1581",
|
||||
"defence_animation": "301",
|
||||
"weakness": "4",
|
||||
"magic_animation": "1582",
|
||||
"death_animation": "1580",
|
||||
"magic_animation": "299",
|
||||
"death_animation": "300",
|
||||
"name": "Waterfiend",
|
||||
"defence_level": "128",
|
||||
"poison_immune": "true",
|
||||
|
|
@ -53854,11 +53866,11 @@
|
|||
"examine": "A servant of the god Zamorak. ",
|
||||
"melee_animation": "6945",
|
||||
"attack_speed": "6",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"respawn_delay": "150",
|
||||
"weakness": "9",
|
||||
"slayer_exp": "350",
|
||||
"poison_amount": "16",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "6945",
|
||||
"death_animation": "6946",
|
||||
"lifepoints": "255",
|
||||
|
|
@ -54957,7 +54969,7 @@
|
|||
"combat_style": "2",
|
||||
"melee_animation": "811",
|
||||
"range_animation": "811",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "60",
|
||||
"respawn_delay": "25",
|
||||
"end_gfx": "76",
|
||||
|
|
@ -58380,11 +58392,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -58536,11 +58548,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -58695,11 +58707,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -58756,11 +58768,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -58836,11 +58848,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -59159,11 +59171,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -59239,11 +59251,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -59441,6 +59453,7 @@
|
|||
"examine": "A ghost of an ork slain during the god wars.",
|
||||
"melee_animation": "7411",
|
||||
"range_animation": "7518",
|
||||
"poisonous": "",
|
||||
"magic_level": "70",
|
||||
"defence_animation": "7413",
|
||||
"magic_animation": "7505",
|
||||
|
|
@ -59460,11 +59473,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -59619,11 +59632,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -59634,7 +59647,8 @@
|
|||
"id": "6673",
|
||||
"clue_level": "2",
|
||||
"range_level": "80",
|
||||
"attack_level": "80"
|
||||
"attack_level": "80",
|
||||
"prj_height": ""
|
||||
},
|
||||
{
|
||||
"spawn_animation": "7426",
|
||||
|
|
@ -59680,11 +59694,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -60003,11 +60017,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -60440,11 +60454,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -60681,11 +60695,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -60760,11 +60774,11 @@
|
|||
"examine": "A ghost of a knight slain during the god wars.",
|
||||
"melee_animation": "7441",
|
||||
"range_animation": "7522",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"magic_level": "80",
|
||||
"defence_animation": "7443",
|
||||
"slayer_exp": "143",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "7508",
|
||||
"death_animation": "7442",
|
||||
"name": "Revenant knight",
|
||||
|
|
@ -63824,9 +63838,9 @@
|
|||
"melee_animation": "8591",
|
||||
"range_animation": "8594",
|
||||
"combat_audio": "408,410,409",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"defence_animation": "8592",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "8594",
|
||||
"death_animation": "8593",
|
||||
"name": "Revenant dragon",
|
||||
|
|
@ -63845,9 +63859,9 @@
|
|||
"melee_animation": "8591",
|
||||
"range_animation": "8594",
|
||||
"combat_audio": "408,410,409",
|
||||
"poisonous": "true",
|
||||
"poisonous": "",
|
||||
"defence_animation": "8592",
|
||||
"poison_amount": "8",
|
||||
"poison_amount": "",
|
||||
"magic_animation": "8594",
|
||||
"death_animation": "8593",
|
||||
"name": "Revenant dragon",
|
||||
|
|
@ -64590,6 +64604,7 @@
|
|||
"death_animation": "8756",
|
||||
"name": "Bork",
|
||||
"defence_level": "80",
|
||||
"poison_immune": "true",
|
||||
"lifepoints": "300",
|
||||
"strength_level": "90",
|
||||
"id": "7133",
|
||||
|
|
@ -64707,6 +64722,7 @@
|
|||
"name": "Bork",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
"poison_immune": "true",
|
||||
"lifepoints": "300",
|
||||
"strength_level": "1",
|
||||
"id": "7134",
|
||||
|
|
@ -68962,13 +68978,13 @@
|
|||
"examine": "A big, scary hand! ",
|
||||
"melee_animation": "1802",
|
||||
"attack_speed": "6",
|
||||
"respawn_delay": "60",
|
||||
"respawn_delay": "0",
|
||||
"defence_animation": "1803",
|
||||
"slayer_exp": "105",
|
||||
"death_animation": "1804",
|
||||
"name": "Wall Beast",
|
||||
"defence_level": "38",
|
||||
"movement_radius": "1",
|
||||
"movement_radius": "0",
|
||||
"safespot": null,
|
||||
"lifepoints": "105",
|
||||
"strength_level": "38",
|
||||
|
|
@ -73958,46 +73974,57 @@
|
|||
"id": "797"
|
||||
},
|
||||
{
|
||||
"examine": "His job doesn't look very fun...",
|
||||
"name": "Pierre",
|
||||
"id": "807"
|
||||
},
|
||||
{
|
||||
"examine": "He looks kind of stuck up...",
|
||||
"name": "Hobbes",
|
||||
"id": "808"
|
||||
},
|
||||
{
|
||||
"examine": "She looks like she enjoys her job.",
|
||||
"name": "Louisa",
|
||||
"id": "809"
|
||||
},
|
||||
{
|
||||
"examine": "She looks very nervous...",
|
||||
"name": "Mary",
|
||||
"id": "810"
|
||||
},
|
||||
{
|
||||
"examine": "He looks like he spends a lot of time outdoor.",
|
||||
"name": "Stanford",
|
||||
"id": "811"
|
||||
},
|
||||
{
|
||||
"examine": "She's dressed in a red top and green trousers.",
|
||||
"name": "Anna",
|
||||
"id": "814"
|
||||
},
|
||||
{
|
||||
"examine": "He's dressed all in red.",
|
||||
"name": "Bob",
|
||||
"id": "815"
|
||||
},
|
||||
{
|
||||
"examine": "She's wearing a blue top and red trousers.",
|
||||
"name": "Carol",
|
||||
"id": "816"
|
||||
},
|
||||
{
|
||||
"examine": "He's dressed all in green.",
|
||||
"name": "David",
|
||||
"id": "817"
|
||||
},
|
||||
{
|
||||
"examine": "She's wearing a green top and blue trousers.",
|
||||
"name": "Elizabeth",
|
||||
"id": "818"
|
||||
},
|
||||
{
|
||||
"examine": "He's dressed all in blue.",
|
||||
"name": "Frank",
|
||||
"id": "819"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2351,14 +2351,46 @@
|
|||
"npc_id": "805",
|
||||
"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",
|
||||
"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",
|
||||
"loc_data": "{2697,3496,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "821",
|
||||
"loc_data": "{2750,3580,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "822",
|
||||
"loc_data": "{3302,9466,0,1,6}-"
|
||||
|
|
@ -4863,6 +4895,10 @@
|
|||
"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}-"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"loc_data": "{2588,3088,0,1,3}-"
|
||||
|
|
@ -6991,6 +7027,10 @@
|
|||
"npc_id": "3288",
|
||||
"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",
|
||||
"loc_data": "{3014,3339,0,1,2}-"
|
||||
|
|
@ -10459,6 +10499,38 @@
|
|||
"npc_id": "6190",
|
||||
"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",
|
||||
"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}-"
|
||||
|
|
@ -12065,7 +12137,7 @@
|
|||
},
|
||||
{
|
||||
"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}-"
|
||||
"loc_data": ""
|
||||
},
|
||||
{
|
||||
"npc_id": "7891",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
package content.global.bots
|
||||
|
||||
import content.data.Quests
|
||||
import core.game.bots.*
|
||||
import core.game.interaction.DestinationFlag
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListeners
|
||||
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.zone.ZoneBorders
|
||||
import org.rs09.consts.Items
|
||||
|
|
@ -24,6 +27,11 @@ class VarrockEssenceMiner : Script(){
|
|||
when(state){
|
||||
State.TO_ESSENCE -> {
|
||||
bot.interfaceManager.close()
|
||||
if (bot.bank.getAmount(Items.PURE_ESSENCE_7936) > 500) {
|
||||
state = State.TELE_GE
|
||||
return
|
||||
}
|
||||
|
||||
if(!auburyZone.insideBorder(bot))
|
||||
scriptAPI.walkTo(auburyZone.randomLoc)
|
||||
else {
|
||||
|
|
@ -99,7 +107,6 @@ class VarrockEssenceMiner : Script(){
|
|||
scriptAPI.sellOnGE(Items.PURE_ESSENCE_7936)
|
||||
state = State.TO_ESSENCE
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -118,4 +125,10 @@ class VarrockEssenceMiner : Script(){
|
|||
script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation)
|
||||
return script
|
||||
}
|
||||
|
||||
init {
|
||||
quests.add(Quests.RUNE_MYSTERIES)
|
||||
inventory.add(Item(Items.ADAMANT_PICKAXE_1271))
|
||||
skills[Skills.MINING] = 31
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ class MysticStaffEnchantInterface : InterfaceListener {
|
|||
override fun defineInterfaceListeners() {
|
||||
on(INTERFACE_332) { player, _, _, buttonID, _, _ ->
|
||||
val staff = buttonMap[buttonID] ?: return@on true
|
||||
val price = if (inEquipment(player, Items.SEERS_HEADBAND_14631)) 27000 else 40000
|
||||
|
||||
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.")
|
||||
|
|
@ -21,12 +20,12 @@ class MysticStaffEnchantInterface : InterfaceListener {
|
|||
|
||||
closeInterface(player)
|
||||
|
||||
if (!inInventory(player, Items.COINS_995, price)) {
|
||||
sendNPCDialogue(player, NPCs.THORMAC_389, "I need ${String.format("%,d", price)} coins for materials. Come back when you have the money!", FacialExpression.NEUTRAL)
|
||||
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, price))) {
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler {
|
|||
}
|
||||
}
|
||||
entity.getSkills().addExperience(Skills.HITPOINTS, hit * 1.33, true);
|
||||
if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_DEFENSIVE) {
|
||||
if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_LONG_RANGE) {
|
||||
entity.getSkills().addExperience(Skills.RANGE, hit * 2, true);
|
||||
entity.getSkills().addExperience(Skills.DEFENCE, hit * 2, true);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ class BattlestaffListener : InteractionListener {
|
|||
onUseWith(IntType.ITEM, orbs, battlestaff) { player, used, with ->
|
||||
val product = BattlestaffProduct.productMap[used.id] ?: return@onUseWith true
|
||||
|
||||
fun getMaxAmount(_unused: Int = 0): Int {
|
||||
return min(amountInInventory(player, with.id), amountInInventory(player, used.id))
|
||||
}
|
||||
|
||||
if (!hasLevelDyn(player, Skills.CRAFTING, product.minimumLevel)) {
|
||||
sendMessage(player, "You need a Crafting level of ${product.minimumLevel} to make this.")
|
||||
return@onUseWith true
|
||||
|
|
@ -41,7 +45,7 @@ class BattlestaffListener : InteractionListener {
|
|||
withItems(product.producedItemId)
|
||||
create { _, amount ->
|
||||
|
||||
runTask(player, 2, amount) {
|
||||
runTask(player, 2, min(amount, getMaxAmount())) {
|
||||
if (amount < 1) return@runTask
|
||||
|
||||
if (removeItem(player, product.requiredOrbItemId) && removeItem(player, Items.BATTLESTAFF_1391)) {
|
||||
|
|
@ -55,9 +59,7 @@ class BattlestaffListener : InteractionListener {
|
|||
}
|
||||
}
|
||||
|
||||
calculateMaxAmount { _ ->
|
||||
min(amountInInventory(player, with.id), amountInInventory(player, used.id))
|
||||
}
|
||||
calculateMaxAmount(::getMaxAmount)
|
||||
}
|
||||
|
||||
return@onUseWith true
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import core.cache.def.impl.SceneryDefinition
|
|||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
|
|
@ -42,6 +43,9 @@ class HealthChecker : OptionHandler() {
|
|||
}
|
||||
PatchType.FRUIT_TREE_PATCH -> {
|
||||
patch.setCurrentState(patch.getCurrentState() - 14)
|
||||
if (fPatch == FarmingPatch.BRIMHAVEN_FRUIT_TREE) {
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 12)
|
||||
}
|
||||
sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.")
|
||||
}
|
||||
PatchType.SPIRIT_TREE_PATCH -> {
|
||||
|
|
|
|||
|
|
@ -373,8 +373,6 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
setCurrentState(getCurrentState() + 1)
|
||||
isWatered = false
|
||||
}
|
||||
|
||||
regrowIfTreeStump()
|
||||
}
|
||||
|
||||
fun regrowIfTreeStump() {
|
||||
|
|
|
|||
5
Server/src/main/content/global/skill/farming/Stump.kt
Normal file
5
Server/src/main/content/global/skill/farming/Stump.kt
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
package content.global.skill.farming
|
||||
|
||||
class Stump(val varbit: Int, val TTL: Long) {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package content.global.skill.farming.timers
|
||||
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.system.timer.*
|
||||
import core.game.node.entity.player.Player
|
||||
import content.global.skill.farming.*
|
||||
import core.tools.ticksToSeconds
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.json.simple.*
|
||||
|
||||
class StumpGrowth : PersistTimer (1, "farming:stump", isSoft = true) {
|
||||
val stumps = ArrayList<Stump>()
|
||||
lateinit var player: Player
|
||||
|
||||
fun addStump(varbit: Int, ttl: Int){
|
||||
stumps.add(
|
||||
Stump(
|
||||
varbit,
|
||||
System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(ticksToSeconds(ttl).toLong())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRegister (entity: Entity) {
|
||||
player = (entity as? Player)!!
|
||||
}
|
||||
|
||||
override fun run (entity: Entity) : Boolean {
|
||||
val removeList = ArrayList<Stump>()
|
||||
for (stump in stumps) {
|
||||
if (System.currentTimeMillis() > stump.TTL) {
|
||||
FarmingPatch.patches[stump.varbit]?.getPatchFor(player)?.regrowIfTreeStump()
|
||||
removeList.add(stump)
|
||||
}
|
||||
}
|
||||
stumps.removeAll(removeList)
|
||||
return stumps.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun save(root: JSONObject, entity: Entity) {
|
||||
val stumpArray = JSONArray()
|
||||
for(s in stumps){
|
||||
val seed = JSONObject()
|
||||
seed["patch"] = s.varbit
|
||||
seed["ttl"] = s.TTL
|
||||
stumpArray.add(seed)
|
||||
}
|
||||
root.put("stumps",stumpArray)
|
||||
}
|
||||
|
||||
override fun parse(root: JSONObject, entity: Entity) {
|
||||
(root["stumps"] as JSONArray).forEach {
|
||||
val s = it as JSONObject
|
||||
val id = s["patch"].toString().toInt()
|
||||
val ttl = s["ttl"].toString().toLong()
|
||||
stumps.add(Stump(id,ttl))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package content.global.skill.gather.fishing
|
||||
|
||||
import content.data.skill.SkillingPets
|
||||
import content.global.skill.fishing.Fish
|
||||
import content.global.skill.fishing.FishingOption
|
||||
import content.global.skill.skillcapeperks.SkillcapePerks
|
||||
|
|
@ -124,7 +123,6 @@ class FishingPulse(player: Player?, npc: NPC, private val option: FishingOption?
|
|||
updateSkillTask()
|
||||
}
|
||||
player.dispatch(ResourceProducedEvent(fish!!.id, 1, node!!))
|
||||
SkillingPets.checkPetDrop(player, SkillingPets.HERON)
|
||||
val item = fish!!
|
||||
if (isActive(SkillcapePerks.GREAT_AIM, player) && RandomFunction.random(100) <= 5) {
|
||||
addItemOrDrop(player, item.id)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package content.global.skill.gather.mining
|
||||
|
||||
import content.data.skill.SkillingPets
|
||||
import content.data.skill.SkillingTool
|
||||
import content.global.skill.skillcapeperks.SkillcapePerks
|
||||
import content.global.activity.shootingstar.StarBonus
|
||||
|
|
@ -67,7 +66,6 @@ class MiningListener : InteractionListener {
|
|||
rewardAmount = calculateRewardAmount(player, isEssence, reward) // calculate amount
|
||||
|
||||
player.dispatch(ResourceProducedEvent(reward, rewardAmount, node))
|
||||
SkillingPets.checkPetDrop(player, SkillingPets.GOLEM) // roll for pet
|
||||
|
||||
// Reward mining experience
|
||||
val experience = resource!!.experience * rewardAmount
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package content.global.skill.gather.mining
|
|||
import core.api.*
|
||||
import core.game.event.ResourceProducedEvent
|
||||
import core.cache.def.impl.ItemDefinition
|
||||
import content.data.skill.SkillingPets
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.impl.Animator
|
||||
import core.game.node.entity.npc.drop.DropFrequency
|
||||
|
|
@ -132,7 +131,6 @@ class MiningSkillPulse(private val player: Player, private val node: Node) : Pul
|
|||
rewardAmount = calculateRewardAmount(reward) // calculate amount
|
||||
|
||||
player.dispatch(ResourceProducedEvent(reward, rewardAmount, node))
|
||||
SkillingPets.checkPetDrop(player, SkillingPets.GOLEM) // roll for pet
|
||||
|
||||
// Reward mining experience
|
||||
val experience = resource!!.experience * rewardAmount
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package content.global.skill.gather.woodcutting
|
||||
|
||||
import content.data.skill.SkillingPets
|
||||
import content.data.skill.SkillingTool
|
||||
import content.data.tables.BirdNest
|
||||
import content.global.skill.farming.FarmingPatch.Companion.forObject
|
||||
import content.global.skill.farming.timers.StumpGrowth
|
||||
import content.global.skill.firemaking.Log
|
||||
import content.global.skill.skillcapeperks.SkillcapePerks
|
||||
import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive
|
||||
|
|
@ -72,7 +72,7 @@ class WoodcuttingListener : InteractionListener {
|
|||
|
||||
if (clockReady(player, Clocks.SKILLING)) {
|
||||
animateWoodcutting(player)
|
||||
if (!checkReward(player, resource, tool))
|
||||
if (!checkReward(player, resource, tool) && !getAttribute(player, "instachop", false))
|
||||
return delayClock(player, Clocks.SKILLING, 3)
|
||||
|
||||
val reward = resource.getReward()
|
||||
|
|
@ -93,7 +93,9 @@ class WoodcuttingListener : InteractionListener {
|
|||
).send()
|
||||
|
||||
//add woodcutting experience
|
||||
player.getSkills().addExperience(Skills.WOODCUTTING, resource.getExperience())
|
||||
rewardAmount = calculateRewardAmount(player, reward) // calculate amount
|
||||
val experience: Double = calculateExperience(player, resource, rewardAmount)
|
||||
player.getSkills().addExperience(Skills.WOODCUTTING, experience, true)
|
||||
|
||||
//nullcheck the fire, and only if it exists award the firemaking XP
|
||||
val fire = Log.forId(reward)
|
||||
|
|
@ -107,7 +109,6 @@ class WoodcuttingListener : InteractionListener {
|
|||
|
||||
if (reward > 0) {
|
||||
rewardAmount = calculateRewardAmount(player, reward) // calculate amount
|
||||
SkillingPets.checkPetDrop(player, SkillingPets.BEAVER) // roll for pet
|
||||
|
||||
//add experience
|
||||
val experience: Double = calculateExperience(player, resource, rewardAmount)
|
||||
|
|
@ -156,7 +157,7 @@ class WoodcuttingListener : InteractionListener {
|
|||
//OSRS: https://oldschool.runescape.wiki/w/Woodcutting scroll down to the mechanics section
|
||||
//RS3 : https://runescape.wiki/w/Woodcutting scroll down to the mechanics section, and expand the tree felling chances table
|
||||
if (resource.getRespawnRate() > 0) {
|
||||
if (RandomFunction.roll(8) || listOf(1, 2, 3, 4, 6).contains(resource.identifier.toInt())){
|
||||
if (RandomFunction.roll(8) || listOf(1, 2, 3, 4, 6).contains(resource.identifier.toInt()) || getAttribute(player, "instachop", false)){
|
||||
if (resource.isFarming()) {
|
||||
val fPatch = forObject(node.asScenery())
|
||||
if (fPatch != null) {
|
||||
|
|
@ -168,6 +169,8 @@ class WoodcuttingListener : InteractionListener {
|
|||
node.isActive = true
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
val stumps = getOrStartTimer <StumpGrowth> (player)
|
||||
stumps.addStump(fPatch.varbit, resource.respawnDuration)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import core.game.event.ResourceProducedEvent;
|
|||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.game.container.impl.EquipmentContainer;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import content.data.skill.SkillingPets;
|
||||
import core.game.node.entity.impl.Animator;
|
||||
import core.game.node.entity.impl.Projectile;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
|
@ -157,7 +156,6 @@ public class WoodcuttingSkillPulse extends Pulse {
|
|||
if (reward > 0) {
|
||||
reward = calculateReward(reward); // calculate rewards
|
||||
rewardAmount = calculateRewardAmount(reward); // calculate amount
|
||||
SkillingPets.checkPetDrop(player, SkillingPets.BEAVER); // roll for pet
|
||||
|
||||
//add experience
|
||||
double experience = calculateExperience(resource.reward, rewardAmount);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package content.global.skill.hunter;
|
||||
|
||||
import content.data.skill.SkillingPets;
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
|
@ -95,13 +94,6 @@ public final class TrapDismantlePulse extends SkillPulse<Scenery> {
|
|||
if (wrapper.getType().getSettings().clear(wrapper, 1)) {
|
||||
instance.deregister(wrapper);
|
||||
if (wrapper.isCaught()) {
|
||||
if (wrapper.getType().equals(Traps.BOX_TRAP)) {
|
||||
for (int i : wrapper.getReward().getNpcIds()) {
|
||||
if (i == 5080 || i == 5079) {
|
||||
SkillingPets.checkPetDrop(player, i == 5080 ? SkillingPets.BABY_RED_CHINCHOMPA : SkillingPets.BABY_GREY_CHINCHOMPA);
|
||||
}
|
||||
}
|
||||
}
|
||||
player.getSkills().addExperience(Skills.HUNTER, wrapper.getReward().getExperience(), true);
|
||||
}
|
||||
player.getPacketDispatch().sendMessage("You dismantle the trap.");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package content.global.skill.hunter;
|
||||
|
||||
import content.data.skill.SkillingPets;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
|
|
@ -123,8 +122,4 @@ public class TrapNode {
|
|||
return objectIds;
|
||||
}
|
||||
|
||||
public SkillingPets getPet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import org.rs09.consts.Items
|
|||
import org.rs09.consts.NPCs
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.game.world.GameWorld
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
|
|
@ -262,6 +263,7 @@ class PitfallListeners : InteractionListener {
|
|||
}
|
||||
on(GRAAHK_PIT, IntType.SCENERY, "dismantle") { player, node ->
|
||||
lootCorpse(player, node as Scenery, 240.0, Items.GRAAHK_FUR_10099, Items.TATTY_GRAAHK_FUR_10097)
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 13)
|
||||
sendMessage(player, "You've caught a horned graahk!")
|
||||
return@on true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import core.game.node.scenery.Scenery
|
|||
import core.game.system.command.Privilege
|
||||
import core.game.system.config.NPCConfigParser
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.system.timer.impl.PoisonImmunity
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.game.world.repository.Repository
|
||||
|
|
@ -379,7 +380,7 @@ class LunarListeners : SpellListener("lunar"), Commands {
|
|||
setInterfaceText(player, "Hitpoints : ${npc.definition.handlers[NPCConfigParser.LIFEPOINTS] ?: 0}", Components.DREAM_MONSTER_STAT_522, 2)
|
||||
setInterfaceText(player, "Max hit : ${npc.getSwingHandler(false).calculateHit(npc, player, 1.0)}", Components.DREAM_MONSTER_STAT_522, 3)
|
||||
|
||||
val poisonStatus = if(npc.definition.handlers.getOrDefault(NPCConfigParser.POISON_IMMUNE,false) == true){
|
||||
val poisonStatus = if(npc.isPoisonImmune){
|
||||
"This creature is immune to poison."
|
||||
} else "This creature is not immune to poison."
|
||||
|
||||
|
|
@ -437,7 +438,7 @@ class LunarListeners : SpellListener("lunar"), Commands {
|
|||
|
||||
if(playerEmpties.isEmpty()) {
|
||||
sendMessage(player, "You have nothing in your inventory that this spell can humidify.")
|
||||
return
|
||||
throw IllegalStateException()
|
||||
}
|
||||
|
||||
removeRunes(player)
|
||||
|
|
@ -818,7 +819,10 @@ class LunarListeners : SpellListener("lunar"), Commands {
|
|||
return@define
|
||||
}
|
||||
if(dmg != null) {
|
||||
p.let { applyPoison(it, it, dmg) }
|
||||
p.let {
|
||||
removeTimer<PoisonImmunity>(it)
|
||||
applyPoison(it, it, dmg)
|
||||
}
|
||||
} else {
|
||||
sendMessage(player, "Damage must be an integer. Format:")
|
||||
sendMessage(player, "::poison username damage")
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class WaterfiendBehavior : NPCBehavior(*Tasks.WATERFIENDS.ids) {
|
|||
true,
|
||||
SwitchAttack(
|
||||
CombatStyle.MAGIC.swingHandler,
|
||||
Animation(1581, Priority.HIGH),
|
||||
Animation(302, Priority.HIGH), // 299 = attack animation, 302 = idle animation. (authentic bug)
|
||||
null,
|
||||
null,
|
||||
Projectile.create(
|
||||
|
|
@ -33,7 +33,7 @@ class WaterfiendBehavior : NPCBehavior(*Tasks.WATERFIENDS.ids) {
|
|||
),
|
||||
SwitchAttack(
|
||||
CombatStyle.RANGE.swingHandler,
|
||||
Animation(1581, Priority.HIGH),
|
||||
Animation(302, Priority.HIGH), // 299 = attack animation, 302 = idle animation. (authentic bug)
|
||||
null,
|
||||
null,
|
||||
Projectile.create(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import java.util.Map;
|
|||
* Handles the lumbridge dungeon.
|
||||
* @author Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public final class LumbridgeDungeon extends MapZone implements Plugin<Object> {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -55,31 +55,6 @@ public enum Pets {
|
|||
*/
|
||||
TERRIER(12512, 12513, -1, 6958, 6959, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_1(12700, 12701, -1, 7237, 7238, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_2(12702, 12703, -1, 7239, 7240, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526),
|
||||
|
||||
/**
|
||||
* A creeping hand pet.
|
||||
*/
|
||||
//CREEPING_HAND(14652, -1, -1, 8619, -1, -1, 0.0033333333333333, 4, 1059),
|
||||
|
||||
/**
|
||||
* Minitrice pet.
|
||||
*/
|
||||
//MINITRICE(14653, -1, -1, 8620, -1, -1, 0.0033333333333333, 4, 225),
|
||||
|
||||
/**
|
||||
* Baby basilisk pet.
|
||||
*/
|
||||
//BABY_BASILISK(14654, -1, -1, 8621, -1, -1, 0.0033333333333333, 4, 221),
|
||||
|
||||
/**
|
||||
* Baby kurask pet.
|
||||
*/
|
||||
//BABY_KURASK(14655, -1, -1, 8622, -1, -1, 0.0033333333333333, 4, 526),
|
||||
|
||||
/**
|
||||
* Abyssal minion pet.
|
||||
*/
|
||||
//ABYSSAL_MINION(14651, -1, -1, 8624, -1, -1, 0.0033333333333333, 4, 592),
|
||||
|
||||
/**
|
||||
* Gecko pet.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public final class ShipCharter {
|
|||
*/
|
||||
public static int getCost(final Player player, Destination destination) {
|
||||
int cost = destination.getCost(player, destination);
|
||||
if (player.getQuestRepository().isComplete(Quests.CABIN_FEVER)) {
|
||||
if (hasRequirement(player, Quests.CABIN_FEVER)) {
|
||||
cost -= Math.round((cost / 2.));
|
||||
}
|
||||
if (player.getEquipment().containsItem(RING_OF_CHAROS)) {
|
||||
|
|
@ -139,7 +139,7 @@ public final class ShipCharter {
|
|||
* @author 'Vexia
|
||||
*/
|
||||
public enum Destination {
|
||||
CATHERBY(Location.create(2792, 3417, 1), 25, new int[] { 480, 0, 480, 625, 1600, 3250, 1000, 1600, 3200, 3400 }, Location.create(2797, 3414, 0), 3, 14),
|
||||
CATHERBY(Location.create(2792, 3417, 1), 25, new int[] { 480, 0, 480, 1250, 1600, 3250, 1000, 1600, 3200, 3400 }, Location.create(2797, 3414, 0), 3, 14),
|
||||
PORT_PHASMATYS(Location.create(3705, 3503, 1), 24, new int[] { 3650, 3250, 1850, 0, 0, 0, 2050, 1850, 3200, 1100 }, Location.create(3702, 3502, 0), 2, 13) {
|
||||
@Override
|
||||
public boolean checkTravel(Player player) {
|
||||
|
|
@ -152,7 +152,7 @@ public final class ShipCharter {
|
|||
return requireQuest(player, Quests.DRAGON_SLAYER, "to go there.");
|
||||
}
|
||||
},
|
||||
BRIMHAVEN(Location.create(2763, 3238, 1), 28, new int[] { 0, 480, 480, 925, 400, 3650, 1600, 400, 3200, 3800 }, Location.create(2760, 3238, 0), 6, 17){
|
||||
BRIMHAVEN(Location.create(2763, 3238, 1), 28, new int[] { 0, 480, 480, 1950, 400, 3650, 1600, 400, 3200, 3800 }, Location.create(2760, 3238, 0), 6, 17){
|
||||
@Override
|
||||
public int getCost(Player player, Destination destination) {
|
||||
boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player);
|
||||
|
|
@ -160,7 +160,7 @@ public final class ShipCharter {
|
|||
return super.getCost(player, destination);
|
||||
}
|
||||
},
|
||||
PORT_SARIM(Location.create(3038, 3189, 1), 30, new int[] { 1600, 1000, 0, 325, 1280, 650, 1280, 400, 3200, 1400 }, Location.create(3039, 3193, 0), 8, 19){
|
||||
PORT_SARIM(Location.create(3038, 3189, 1), 30, new int[] { 1600, 1000, 0, 650, 1280, 650, 1280, 400, 3200, 1400 }, Location.create(3039, 3193, 0), 8, 19){
|
||||
@Override
|
||||
public int getCost(Player player, Destination destination) {
|
||||
boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player);
|
||||
|
|
@ -168,14 +168,14 @@ public final class ShipCharter {
|
|||
return super.getCost(player, destination);
|
||||
}
|
||||
},
|
||||
PORT_TYRAS(Location.create(2142, 3122, 0), 23, new int[] { 3200, 3200, 3200, 1600, 3200, 3200, 3200, 3200, 0, 3200 }, Location.create(2143, 3122, 0), 1, 12) {
|
||||
PORT_TYRAS(Location.create(2142, 3122, 0), 23, new int[] { 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 0, 3200 }, Location.create(2143, 3122, 0), 1, 12) {
|
||||
@Override
|
||||
public boolean checkTravel(Player player) {
|
||||
return hasRequirement(player, Quests.REGICIDE);
|
||||
}
|
||||
|
||||
},
|
||||
KARAMJA(Location.create(2957, 3158, 1), 27, new int[] { 200, 480, 0, 225, 400, 1850, 0, 200, 3200, 2000 }, Location.create(2954, 3156, 0), 5, 16) {
|
||||
KARAMJA(Location.create(2957, 3158, 1), 27, new int[] { 200, 480, 0, 450, 400, 1850, 0, 200, 3200, 2000 }, Location.create(2954, 3156, 0), 5, 16) {
|
||||
@Override
|
||||
public int getCost(Player player, Destination destination) {
|
||||
boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player);
|
||||
|
|
@ -183,7 +183,7 @@ public final class ShipCharter {
|
|||
return super.getCost(player, destination);
|
||||
}
|
||||
},
|
||||
PORT_KHAZARD(Location.create(2674, 3141, 1), 29, new int[] { 1600, 1000, 0, 325, 180, 650, 1280, 400, 3200, 1400 }, Location.create(2674, 3144, 0), 7, 18){
|
||||
PORT_KHAZARD(Location.create(2674, 3141, 1), 29, new int[] { 1600, 1000, 0, 2050, 180, 650, 1280, 400, 3200, 1400 }, Location.create(2674, 3144, 0), 7, 18){
|
||||
@Override
|
||||
public int getCost(Player player, Destination destination) {
|
||||
boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player);
|
||||
|
|
@ -191,14 +191,14 @@ public final class ShipCharter {
|
|||
return super.getCost(player, destination);
|
||||
}
|
||||
},
|
||||
SHIPYARD(Location.create(3001, 3032, 0), 26, new int[] { 400, 1600, 200, 225, 720, 1850, 400, 0, 3200, 900 }, Location.create(3001, 3032, 0), 4, 15) {
|
||||
SHIPYARD(Location.create(3001, 3032, 0), 26, new int[] { 400, 1600, 200, 450, 720, 1850, 400, 0, 3200, 900 }, Location.create(3001, 3032, 0), 4, 15) {
|
||||
@Override
|
||||
public boolean checkTravel(Player player) {
|
||||
return requireQuest(player, Quests.THE_GRAND_TREE, "to go there.");
|
||||
}
|
||||
},
|
||||
OO_GLOG(Location.create(2623, 2857, 0), 33, new int[] { 300, 3400, 2000, 550, 5000, 2800, 1400, 900, 3200, 0}, Location.create(2622, 2857, 0), 11, 22),
|
||||
MOS_LE_HARMLESS(Location.create(3671, 2931, 0), 31, new int[] { 725, 625, 1025, 0, 1025, 0, 325, 275, 1600, 500 }, Location.create(3671, 2933, 0), 9, 20) {
|
||||
OO_GLOG(Location.create(2623, 2857, 0), 33, new int[] { 300, 3400, 2000, 1100, 5000, 2800, 1400, 900, 3200, 0}, Location.create(2622, 2857, 0), 11, 22),
|
||||
MOS_LE_HARMLESS(Location.create(3671, 2931, 0), 31, new int[] { 1550, 1250, 2050, 0, 2050, 0, 650, 550, 3200, 1000 }, Location.create(3671, 2933, 0), 9, 20) {
|
||||
@Override
|
||||
public boolean checkTravel(Player player) {
|
||||
return hasRequirement(player, Quests.CABIN_FEVER);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import org.rs09.consts.Items
|
|||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.api.*
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Handles repairing and climbing of the 3 beacon shortcuts needed to access them
|
||||
|
|
@ -55,8 +54,8 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
private fun repair(player: Player,rco: RepairClimbObject){
|
||||
if (rco == RepairClimbObject.TEMPLE){
|
||||
// You can do this 2 different ways
|
||||
val hasSmithingLevel = getDynLevel(player, Skills.SMITHING) >= 70
|
||||
val hasConstructionLevel = getDynLevel(player, Skills.CONSTRUCTION) >= 59
|
||||
val hasSmithingLevel = getStatLevel(player, Skills.SMITHING) >= 70
|
||||
val hasConstructionLevel = getStatLevel(player, Skills.CONSTRUCTION) >= 59
|
||||
|
||||
if (!hasConstructionLevel && !hasSmithingLevel){
|
||||
sendDialogue(player, "You need level 70 smithing or 59 construction for this.")
|
||||
|
|
@ -93,8 +92,8 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
}
|
||||
val skill = rco.levelRequirement?.first ?: 0
|
||||
val level = rco.levelRequirement?.second ?: 0
|
||||
if(player.skills.getLevel(skill) < level){
|
||||
player.dialogueInterpreter.sendDialogue("You need level $level ${Skills.SKILL_NAME[skill]} for this.")
|
||||
if(getStatLevel(player, skill) < level){
|
||||
sendDialogue(player, "You need level $level ${Skills.SKILL_NAME[skill]} for this.")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -102,40 +101,37 @@ class AFURepairClimbHandler : InteractionListener {
|
|||
|
||||
val requiredItems = when(rco){
|
||||
RepairClimbObject.DEATH_PLATEAU -> {
|
||||
arrayOf(Item(Items.PLANK_960,2))
|
||||
Item(Items.PLANK_960,2)
|
||||
}
|
||||
|
||||
RepairClimbObject.BURTHORPE -> {
|
||||
arrayOf(Item(Items.IRON_BAR_2351,2))
|
||||
Item(Items.IRON_BAR_2351,2)
|
||||
}
|
||||
|
||||
RepairClimbObject.GWD -> {
|
||||
requiresNeedle = true
|
||||
arrayOf(Item(Items.JUTE_FIBRE_5931,3))
|
||||
Item(Items.JUTE_FIBRE_5931,3)
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
|
||||
if(requiresNeedle){
|
||||
if(player.inventory.containsItem(Item(Items.NEEDLE_1733)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) {
|
||||
player.inventory.remove(*requiredItems)
|
||||
if (Random().nextBoolean()) player.inventory.remove(Item(Items.NEEDLE_1733))
|
||||
} else {
|
||||
player.dialogueInterpreter.sendDialogue("You need a needle and ${requiredItems.map { "${it.amount} ${it.name.lowercase()}s" }.toString().replace("[","").replace("]","")} for this.")
|
||||
if (!inInventory(player, Items.NEEDLE_1733) || !removeItem(player, requiredItems)) {
|
||||
sendDialogue(player, "You need a needle and ${requiredItems.amount} ${requiredItems.name.lowercase()}s for this.")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if(player.inventory.containsItem(Item(Items.HAMMER_2347)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) {
|
||||
if(inInventory(player, Items.HAMMER_2347) && inInventory(player, requiredItems.id, requiredItems.amount)) {
|
||||
val nails = NailType.get(player,4)
|
||||
if(nails == null && rco == RepairClimbObject.DEATH_PLATEAU){
|
||||
player.dialogueInterpreter.sendDialogue("You need 4 nails for this.")
|
||||
sendDialogue(player, "You need 4 nails for this.")
|
||||
return
|
||||
} else if (rco == RepairClimbObject.DEATH_PLATEAU){
|
||||
player.inventory.remove(Item(nails.itemId,4))
|
||||
removeItem(player, Item(nails.itemId,4))
|
||||
}
|
||||
player.inventory.remove(*requiredItems)
|
||||
removeItem(player, requiredItems)
|
||||
} else {
|
||||
player.dialogueInterpreter.sendDialogue("You need a hammer and ${requiredItems.map { "${it.amount} ${it.name.lowercase()}s" }.toString().replace("[","").replace("]","")} for this.")
|
||||
sendDialogue(player, "You need a hammer and ${requiredItems.amount} ${requiredItems.name.lowercase()}s for this.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ public final class GWDTsutsarothSwingHandler extends CombatSwingHandler {
|
|||
hit = RandomFunction.random(max);
|
||||
state.setMaximumHit(max);
|
||||
if (style == CombatStyle.MELEE) {
|
||||
applyPoison(victim, entity, 16);
|
||||
applyPoison(victim, entity, 80);
|
||||
}
|
||||
if (special) {
|
||||
((Player) victim).getSkills().decrementPrayerPoints((double) hit / 2);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package content.region.desert.bandits.handlers
|
|||
|
||||
import core.api.God
|
||||
import core.api.hasGodItem
|
||||
import core.api.inEquipment
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.BattleState
|
||||
import core.game.node.entity.npc.AbstractNPC
|
||||
|
|
@ -9,6 +10,7 @@ import core.game.node.entity.player.Player
|
|||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
|
|
@ -28,7 +30,7 @@ class BanditNPC(id: Int = NPCs.BANDIT_1926, location: Location? = null) : Abstra
|
|||
sendChat("Time to die, Saradominist filth!")
|
||||
attack(player)
|
||||
break
|
||||
} else if (hasGodItem(player, God.ZAMORAK)) {
|
||||
} else if (hasGodItem(player, God.ZAMORAK) || inEquipment(player, Items.DAGONHAI_HAT_14499) || inEquipment(player, Items.DAGONHAI_ROBE_TOP_14497) || inEquipment(player, Items.DAGONHAI_ROBE_BOTTOM_14501)) {
|
||||
sendChat("Prepare to suffer, Zamorakian scum!")
|
||||
attack(player)
|
||||
break
|
||||
|
|
|
|||
|
|
@ -14,8 +14,23 @@ import org.rs09.consts.Items
|
|||
import org.rs09.consts.NPCs
|
||||
|
||||
class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) {
|
||||
private var disappearing = false
|
||||
|
||||
var clearTime = 0
|
||||
override fun tick(self: NPC): Boolean {
|
||||
if (disappearing) {
|
||||
return true
|
||||
}
|
||||
val player: Player? = getAttribute<Player?>(self, "target", null)
|
||||
if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) {
|
||||
if (player != null && !disappearing) {
|
||||
disappearing = true
|
||||
sendMessage(player, "Damis has vanished once more into the shadows...")
|
||||
removeAttribute(player, DesertTreasure.attributeDamisInstance)
|
||||
}
|
||||
poofClear(self)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
|
||||
if (attacker is Player) {
|
||||
|
|
@ -27,19 +42,6 @@ class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) {
|
|||
return false
|
||||
}
|
||||
|
||||
override fun tick(self: NPC): Boolean {
|
||||
val player: Player? = getAttribute<Player?>(self, "target", null)
|
||||
if (clearTime++ > 800) {
|
||||
clearTime = 0
|
||||
if (player != null) {
|
||||
sendMessage(player, "Damis has vanished once more into the shadows...")
|
||||
removeAttribute(player, DesertTreasure.attributeDamisInstance)
|
||||
}
|
||||
poofClear(self)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) {
|
||||
if (attacker is Player) {
|
||||
if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints && self.id == NPCs.DAMIS_1974) {
|
||||
|
|
@ -65,8 +67,6 @@ class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun onDeathFinished(self: NPC, killer: Entity) {
|
||||
if (killer is Player) {
|
||||
if (self.id == NPCs.DAMIS_1975) {
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ import core.tools.END_DIALOGUE
|
|||
import org.rs09.consts.NPCs
|
||||
|
||||
class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) {
|
||||
|
||||
var clearTime = 0
|
||||
private var disappearing = false;
|
||||
|
||||
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
|
||||
if (attacker is Player) {
|
||||
|
|
@ -34,12 +33,24 @@ class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) {
|
|||
}
|
||||
|
||||
override fun tick(self: NPC): Boolean{
|
||||
if (disappearing) {
|
||||
return true
|
||||
}
|
||||
val player: Player? = getAttribute<Player?>(self, "target", null)
|
||||
if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) {
|
||||
if (player != null && !disappearing) {
|
||||
disappearing = true
|
||||
sendMessage(player, "Dessous returns to his grave, bored of toying with you.")
|
||||
removeAttribute(player, DesertTreasure.attributeDessousInstance)
|
||||
}
|
||||
poofClear(self)
|
||||
}
|
||||
|
||||
// Dessous just continually hisses independently of projectile fires.
|
||||
if (self.id == NPCs.DESSOUS_1915 && self.properties.combatPulse.isInCombat) {
|
||||
animate(self, Animation(1914))
|
||||
}
|
||||
// This is probably the prayer flicking nonsense.
|
||||
val player: Player? = getAttribute<Player?>(self, "target", null)
|
||||
if (self.id == NPCs.DESSOUS_1914 && player != null && player.prayer.get(PrayerType.PROTECT_FROM_MELEE)) {
|
||||
self.transform(NPCs.DESSOUS_1915)
|
||||
Graphics.send(Graphics(86), self.location)
|
||||
|
|
@ -47,16 +58,7 @@ class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) {
|
|||
self.transform(NPCs.DESSOUS_1914)
|
||||
Graphics.send(Graphics(86), self.location)
|
||||
}
|
||||
if (clearTime++ > 800) {
|
||||
self.transform(NPCs.DESSOUS_1914)
|
||||
clearTime = 0
|
||||
if (player != null) {
|
||||
removeAttribute(player, DesertTreasure.attributeDessousInstance)
|
||||
sendMessage(player, "Dessous returns to his grave, bored of toying with you.")
|
||||
}
|
||||
poofClear(self)
|
||||
}
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler {
|
||||
|
|
|
|||
|
|
@ -261,5 +261,4 @@ class ShadowDungeonAttack : MapArea {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,8 +14,7 @@ import org.rs09.consts.Items
|
|||
import org.rs09.consts.NPCs
|
||||
|
||||
class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
|
||||
|
||||
var clearTime = 0
|
||||
private var disappearing = false
|
||||
|
||||
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
|
||||
if (attacker is Player) {
|
||||
|
|
@ -28,10 +27,13 @@ class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
|
|||
}
|
||||
|
||||
override fun tick(self: NPC): Boolean {
|
||||
if (disappearing) {
|
||||
return true
|
||||
}
|
||||
val player: Player? = getAttribute<Player?>(self, "target", null)
|
||||
if (clearTime++ > 800) {
|
||||
clearTime = 0
|
||||
if (player != null) {
|
||||
if (player == null || !self.location.withinDistance(self.properties.spawnLocation, self.walkRadius)) {
|
||||
if (player != null && !disappearing) {
|
||||
disappearing = true
|
||||
sendMessage(player, "Fareed has lost interest in you, and returned to his flames.")
|
||||
removeAttribute(player, DesertTreasure.attributeFareedInstance)
|
||||
}
|
||||
|
|
@ -50,14 +52,14 @@ class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
|
|||
if (victim is Player) {
|
||||
if (!inEquipment(victim, Items.ICE_GLOVES_1580)) {
|
||||
val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON)
|
||||
if(weapon != null) {
|
||||
if (weapon != null) {
|
||||
EquipHandler.unequip(victim, EquipmentContainer.SLOT_WEAPON, weapon.id)
|
||||
sendMessage(victim, "The heat from the warrior causes you to drop your weapon.")
|
||||
}
|
||||
// val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON)
|
||||
// if(weapon != null && removeItem(victim, weapon.id, Container.EQUIPMENT)) {
|
||||
// addItemOrDrop(victim, weapon.id)
|
||||
// }
|
||||
sendMessage(victim, "The heat from the warrior causes you to drop your weapon.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -72,5 +74,4 @@ class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -14,8 +14,7 @@ import org.rs09.consts.NPCs
|
|||
// https://www.youtube.com/watch?v=xeu6Ncmt1fY
|
||||
|
||||
class KamilBehavior : NPCBehavior(NPCs.KAMIL_1913) {
|
||||
|
||||
var clearTime = 0
|
||||
private var disappearing = false
|
||||
|
||||
override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean {
|
||||
if (attacker is Player) {
|
||||
|
|
@ -28,10 +27,13 @@ class KamilBehavior : NPCBehavior(NPCs.KAMIL_1913) {
|
|||
}
|
||||
|
||||
override fun tick(self: NPC): Boolean {
|
||||
if (disappearing) {
|
||||
return true
|
||||
}
|
||||
val player: Player? = getAttribute<Player?>(self, "target", null)
|
||||
if (clearTime++ > 800) {
|
||||
clearTime = 0
|
||||
if (player != null) {
|
||||
if (player == null || !self.location.withinDistance(self.properties.spawnLocation, (self.walkRadius*1.5).toInt())) {
|
||||
if (player != null && !disappearing) {
|
||||
disappearing = true
|
||||
sendMessage(player, "Kamil vanishes on an icy wind...")
|
||||
removeAttribute(player, DesertTreasure.attributeKamilInstance)
|
||||
}
|
||||
|
|
@ -64,16 +66,19 @@ class KamilCombatHandler: MultiSwingHandler(
|
|||
// This is following RevenantCombatHandler.java, no idea if this is good.
|
||||
// I can't be bothered to fix fucking frozen. The player can hit through frozen. What the fuck is frozen for then, to glue his fucking legs???
|
||||
if (RandomFunction.roll(3) && !hasTimerActive(victim, "frozen") && !hasTimerActive(victim, "frozen:immunity")) {
|
||||
sendChat(entity as NPC, "Sallamakar Ro!") // Salad maker roll.
|
||||
impact(victim, 5)
|
||||
impact(victim, 5)
|
||||
registerTimer(victim, spawnTimer("frozen", 7, true))
|
||||
sendMessage(victim, "You've been frozen!")
|
||||
sendChat(entity as NPC, "Sallamakar Ro!") // Salad maker roll.
|
||||
// FIXME: before the below vfx hits, there should be another one that looks kinda like a wind wave exploding at the player's feet. Hope somebody finds the id.
|
||||
sendGraphics(539, victim.location)
|
||||
victim.properties.combatPulse.stop() // Force the victim to stop fighting. Whatever.
|
||||
// Audio?
|
||||
// FIXME: sfx
|
||||
}else {
|
||||
animate(entity!!, Animation(440))
|
||||
}
|
||||
}
|
||||
super.impact(entity, victim, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,20 @@
|
|||
package content.region.fremennik.rellekka.quest.thefremenniktrials
|
||||
|
||||
import core.api.addItem
|
||||
import core.api.dumpContainer
|
||||
import core.api.getQuestStage
|
||||
import core.api.removeItem
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.plugin.Initializable
|
||||
import core.tools.RandomFunction
|
||||
import core.tools.END_DIALOGUE
|
||||
import kotlin.random.Random
|
||||
import content.data.Quests
|
||||
import core.api.*
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.node.entity.player.link.IronmanMode
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class PeerTheSeerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) {
|
||||
class PeerTheSeerDialogue(player: Player? = null) : DialoguePlugin(player) {
|
||||
val predictionOne = arrayOf("one","two","three","four","five","six","seven","eight","ten")
|
||||
val predictionTwo = arrayOf("black","blue","brown","cyan","green","pink","purple","red","yellow")
|
||||
val predictionThree = arrayOf("fire giant","ghosts","giant","goblin","green dragon","hobgoblin","lesser demon","moss giant","ogre","zombie")
|
||||
|
|
@ -31,232 +32,230 @@ class PeerTheSeerDialogue(player: Player? = null) : core.game.dialogue.DialogueP
|
|||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
if(player.inventory.contains(3710,1)){
|
||||
playerl(core.game.dialogue.FacialExpression.HAPPY,"Can I have a weather forecast now please?")
|
||||
playerl(FacialExpression.HAPPY,"Can I have a weather forecast now please?")
|
||||
stage = 15
|
||||
return true
|
||||
}
|
||||
else if(player.inventory.contains(3705,1)){
|
||||
playerl(core.game.dialogue.FacialExpression.ASKING,"So, about this forecast...")
|
||||
playerl(FacialExpression.ASKING,"So, about this forecast...")
|
||||
stage = 20
|
||||
return true
|
||||
}
|
||||
else if(player.getAttribute("sigmundreturning",false) == true){
|
||||
playerl(core.game.dialogue.FacialExpression.ASKING,"I've got an item to trade but I don't know if it's for you.")
|
||||
playerl(FacialExpression.ASKING,"I've got an item to trade but I don't know if it's for you.")
|
||||
stage = 26
|
||||
return true
|
||||
}
|
||||
else if(player.getAttribute("sigmund-steps", 0) == 10){
|
||||
playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a brave and powerful warrior to act as a bodyguard?")
|
||||
playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a brave and powerful warrior to act as a bodyguard?")
|
||||
stage = 8
|
||||
return true
|
||||
}
|
||||
else if(player.getAttribute("sigmund-steps", 0) == 9){
|
||||
playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a weather forecast from the Fremennik Seer do you?")
|
||||
playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a weather forecast from the Fremennik Seer do you?")
|
||||
stage = 1
|
||||
return true
|
||||
}
|
||||
else if(player.getAttribute("PeerStarted",false) && !player.inventory.isEmpty || !player.equipment.isEmpty){
|
||||
npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
else if(player.getAttribute("PeerStarted",false) && !(player.inventory.isEmpty && player.equipment.isEmpty)){
|
||||
npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
stage = 100
|
||||
return true
|
||||
}
|
||||
else if(player.getAttribute("PeerStarted",false) && player.inventory.isEmpty && player.equipment.isEmpty){
|
||||
npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
stage = 110
|
||||
return true
|
||||
}
|
||||
else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:peer-vote",false)) {
|
||||
npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
stage = 120
|
||||
return true
|
||||
}
|
||||
else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){
|
||||
npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
stage = 150
|
||||
return true
|
||||
}
|
||||
else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0){
|
||||
npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
npcl(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?")
|
||||
stage = 50
|
||||
return true
|
||||
}
|
||||
if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) == 0) {
|
||||
npc(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?").also { stage = 300 }
|
||||
npc(FacialExpression.SAD,"Uuuh... What was that dark presence I felt?").also { stage = 300 }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
when(stage){
|
||||
1 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Er.... Yes, because I AM the Fremennik Seer.").also { stage++ }
|
||||
2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Can I have a weather forecast then please?").also { stage++ }
|
||||
3 -> npcl(core.game.dialogue.FacialExpression.THINKING,"You require a divination of the weather? This is a simple matter for me, but I will require something in return from you for this small service.").also { stage++ }
|
||||
4 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I knew you were going to say that...").also { stage++ }
|
||||
5 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Do not fret, outerlander; it is a fairly simple matter. I require a bodyguard for protection. Find someone willing to offer me this service.").also { stage++ }
|
||||
6 -> playerl(core.game.dialogue.FacialExpression.ASKING,"That's all?").also { stage++ }
|
||||
7 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is all.").also {
|
||||
1 -> npcl(FacialExpression.ANNOYED,"Er.... Yes, because I AM the Fremennik Seer.").also { stage++ }
|
||||
2 -> playerl(FacialExpression.ASKING,"Can I have a weather forecast then please?").also { stage++ }
|
||||
3 -> npcl(FacialExpression.THINKING,"You require a divination of the weather? This is a simple matter for me, but I will require something in return from you for this small service.").also { stage++ }
|
||||
4 -> playerl(FacialExpression.ASKING,"I knew you were going to say that...").also { stage++ }
|
||||
5 -> npcl(FacialExpression.HAPPY,"Do not fret, outerlander; it is a fairly simple matter. I require a bodyguard for protection. Find someone willing to offer me this service.").also { stage++ }
|
||||
6 -> playerl(FacialExpression.ASKING,"That's all?").also { stage++ }
|
||||
7 -> npcl(FacialExpression.HAPPY,"That is all.").also {
|
||||
player?.incrementAttribute("sigmund-steps",1)
|
||||
stage = 1000
|
||||
}
|
||||
10 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"If I did, then I would simply have asked them myself now, wouldn't I, outerlander?").also { stage = 1000 }
|
||||
10 -> npcl(FacialExpression.ANNOYED,"If I did, then I would simply have asked them myself now, wouldn't I, outerlander?").also { stage = 1000 }
|
||||
|
||||
15 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"I have already told you outerlander; You may have a reading from me when I have a signed contract from a warrior guaranteeing my protection.").also { stage++ }
|
||||
16 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Yeah, I know; I have one right here from Thorvald.").also {
|
||||
15 -> npcl(FacialExpression.ANNOYED,"I have already told you outerlander; You may have a reading from me when I have a signed contract from a warrior guaranteeing my protection.").also { stage++ }
|
||||
16 -> playerl(FacialExpression.HAPPY,"Yeah, I know; I have one right here from Thorvald.").also {
|
||||
removeItem(player,3710)
|
||||
addItem(player,3705)
|
||||
stage++
|
||||
}
|
||||
17 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"You have not only persuaded one of the Fremennik to act as a servant to me, but you have enlisted the aid of mighty Thorvald himself???").also { stage++ }
|
||||
18 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You may take this forecast with my blessing outerlander. You have offered me the greatest security I can imagine.").also { stage = 1000 }
|
||||
17 -> npcl(FacialExpression.AMAZED,"You have not only persuaded one of the Fremennik to act as a servant to me, but you have enlisted the aid of mighty Thorvald himself???").also { stage++ }
|
||||
18 -> npcl(FacialExpression.HAPPY,"You may take this forecast with my blessing outerlander. You have offered me the greatest security I can imagine.").also { stage = 1000 }
|
||||
|
||||
20 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Yes, outerlander?").also { stage++ }
|
||||
21 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I still don't know why you didn't just let me have one anyway in the first place. Surely it means nothing to you?").also { stage++ }
|
||||
22 -> npcl(core.game.dialogue.FacialExpression.THINKING,"That is not true, outerlander. Although I see glimpses of the future all of the time, using my powers brings the attention of the gods to me.").also { stage++ }
|
||||
23 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Some of the gods are spiteful and cruel, and I fear if I use my powers too much then I will meet with unpredictable accidents.").also { stage++ }
|
||||
24 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"This is why I needed protection.").also { stage++ }
|
||||
25 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Okay... I... think I understand...").also { stage = 1000 }
|
||||
20 -> npcl(FacialExpression.THINKING,"Yes, outerlander?").also { stage++ }
|
||||
21 -> playerl(FacialExpression.ASKING,"I still don't know why you didn't just let me have one anyway in the first place. Surely it means nothing to you?").also { stage++ }
|
||||
22 -> npcl(FacialExpression.THINKING,"That is not true, outerlander. Although I see glimpses of the future all of the time, using my powers brings the attention of the gods to me.").also { stage++ }
|
||||
23 -> npcl(FacialExpression.THINKING,"Some of the gods are spiteful and cruel, and I fear if I use my powers too much then I will meet with unpredictable accidents.").also { stage++ }
|
||||
24 -> npcl(FacialExpression.HAPPY,"This is why I needed protection.").also { stage++ }
|
||||
25 -> playerl(FacialExpression.THINKING,"Okay... I... think I understand...").also { stage = 1000 }
|
||||
|
||||
26 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Not me, I'm afraid.").also { stage++ }
|
||||
26 -> npcl(FacialExpression.ANNOYED,"Not me, I'm afraid.").also { stage++ }
|
||||
|
||||
//The Seer's Trial
|
||||
50 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ }
|
||||
51 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ }
|
||||
52 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Hello. I'm looking for members of the council of elders to vote for me to become a Fremennik.").also { stage++ }
|
||||
53 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Are you now? Well that is interesting. Usually outerlanders do not concern themselves with our ways like that.").also { stage++ }
|
||||
54 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"I am one of the members of the council of elders, and should you be able to prove to me that you have something to offer my clan I will vote in your favour at the next meeting.").also { stage++ }
|
||||
55 -> playerl(core.game.dialogue.FacialExpression.ASKING,"How can I prove that to you?").also { stage++ }
|
||||
56 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, I have but a simple test. This building behind me is my house. Inside I have constructed a puzzle.").also { stage++ }
|
||||
57 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As a Seer to the clan, I value intelligence very highly, so you may think of it as an intelligence test of sorts.").also { stage++ }
|
||||
58 -> playerl(core.game.dialogue.FacialExpression.THINKING,"An intelligence test? I thought barbarians were stupid!").also { stage++ }
|
||||
59 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"That is the opinion that outerlanders usually hold of my people, it is true. But that is because people often confuse knowledge with wisdom.").also { stage++ }
|
||||
60 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"My puzzle tests not what you know, but what you can work out. All members of our clan have been tested when they took their trials.").also { stage++ }
|
||||
61 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So what exactly does this puzzle consist of, then?").also { stage++ }
|
||||
62 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, firstly you must enter my house with no items, weapons or armour. Then it is a simple matter of entering through one door and leaving by the other.").also { stage++ }
|
||||
63 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I can't take anything in there with me?").also { stage++ }
|
||||
64 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander. Everything you need to complete the puzzle you will find inside the building. Nothing more.").also { stage++ }
|
||||
65 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"So what say you outerlander? You think you have the wit to earn yourself my vote?").also { stage++ }
|
||||
50 -> npcl(FacialExpression.AMAZED,"!").also { stage++ }
|
||||
51 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ }
|
||||
52 -> playerl(FacialExpression.ASKING,"Hello. I'm looking for members of the council of elders to vote for me to become a Fremennik.").also { stage++ }
|
||||
53 -> npcl(FacialExpression.THINKING,"Are you now? Well that is interesting. Usually outerlanders do not concern themselves with our ways like that.").also { stage++ }
|
||||
54 -> npcl(FacialExpression.HAPPY,"I am one of the members of the council of elders, and should you be able to prove to me that you have something to offer my clan I will vote in your favour at the next meeting.").also { stage++ }
|
||||
55 -> playerl(FacialExpression.ASKING,"How can I prove that to you?").also { stage++ }
|
||||
56 -> npcl(FacialExpression.HAPPY,"Well, I have but a simple test. This building behind me is my house. Inside I have constructed a puzzle.").also { stage++ }
|
||||
57 -> npcl(FacialExpression.HAPPY,"As a Seer to the clan, I value intelligence very highly, so you may think of it as an intelligence test of sorts.").also { stage++ }
|
||||
58 -> playerl(FacialExpression.THINKING,"An intelligence test? I thought barbarians were stupid!").also { stage++ }
|
||||
59 -> npcl(FacialExpression.ANNOYED,"That is the opinion that outerlanders usually hold of my people, it is true. But that is because people often confuse knowledge with wisdom.").also { stage++ }
|
||||
60 -> npcl(FacialExpression.ANNOYED,"My puzzle tests not what you know, but what you can work out. All members of our clan have been tested when they took their trials.").also { stage++ }
|
||||
61 -> playerl(FacialExpression.ASKING,"So what exactly does this puzzle consist of, then?").also { stage++ }
|
||||
62 -> npcl(FacialExpression.HAPPY,"Well, firstly you must enter my house with no items, weapons or armour. Then it is a simple matter of entering through one door and leaving by the other.").also { stage++ }
|
||||
63 -> playerl(FacialExpression.ASKING,"I can't take anything in there with me?").also { stage++ }
|
||||
64 -> npcl(FacialExpression.HAPPY,"That is correct outerlander. Everything you need to complete the puzzle you will find inside the building. Nothing more.").also { stage++ }
|
||||
65 -> npcl(FacialExpression.HAPPY,"So what say you outerlander? You think you have the wit to earn yourself my vote?").also { stage++ }
|
||||
66 -> options("Yes","No").also { stage++ }
|
||||
67 -> when(buttonId){
|
||||
1 ->{ playerl(core.game.dialogue.FacialExpression.HAPPY,"Yes, I accept your challenge, I have one small question, however...")
|
||||
1 ->{ playerl(FacialExpression.HAPPY,"Yes, I accept your challenge, I have one small question, however...")
|
||||
player?.setAttribute("/save:PeerStarted",true)
|
||||
player?.setAttribute("/save:PeerRiddle", Random.nextInt(0,3))
|
||||
stage = 70
|
||||
}
|
||||
2 ->{ playerl(core.game.dialogue.FacialExpression.HAPPY,"No, thinking about stuff isn't really my 'thing'. I'd rather go kill something. I'll find someone else to vote for me")
|
||||
2 ->{ playerl(FacialExpression.HAPPY,"No, thinking about stuff isn't really my 'thing'. I'd rather go kill something. I'll find someone else to vote for me")
|
||||
stage++
|
||||
}
|
||||
}
|
||||
//No to challenge
|
||||
68 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish, outerlander.").also { stage = 1000 }
|
||||
68 -> npcl(FacialExpression.HAPPY,"As you wish, outerlander.").also { stage = 1000 }
|
||||
|
||||
//Yes to challenge
|
||||
70 -> npcl(core.game.dialogue.FacialExpression.ASKING,"Yes outerlander?").also { stage++ }
|
||||
71 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Well... you say I can bring nothing with me when I enter your house...").also { stage++ }
|
||||
72 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Yes outerlander??").also { stage++ }
|
||||
73 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Well...").also { stage++ }
|
||||
74 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"Yes, outerlander???").also { stage++ }
|
||||
75 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Where is the nearest bank?").also { stage++ }
|
||||
76 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah, I see your problem outerlander. The nearest bank to here is the place known to outerlanders as the Seers Village.").also { stage++ }
|
||||
77 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"It is some way South. I do however have an alternative, should you wish to take it.").also { stage++ }
|
||||
78 -> playerl(core.game.dialogue.FacialExpression.ASKING,"And what is that?").also { stage++ }
|
||||
79 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"I can store all the weapons, armour and items that you have upon you directly into your bank account.").also { stage++ }
|
||||
80 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"This will tax what little magic I possess however, so you will have to travel to the bank to withdraw them again.").also { stage++ }
|
||||
81 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"What say you outerlander? Do you wish me to do this for you?").also { stage++ }
|
||||
70 -> npcl(FacialExpression.ASKING,"Yes outerlander?").also { stage++ }
|
||||
71 -> playerl(FacialExpression.THINKING,"Well... you say I can bring nothing with me when I enter your house...").also { stage++ }
|
||||
72 -> npcl(FacialExpression.ANNOYED,"Yes outerlander??").also { stage++ }
|
||||
73 -> playerl(FacialExpression.THINKING,"Well...").also { stage++ }
|
||||
74 -> npcl(FacialExpression.ANGRY,"Yes, outerlander???").also { stage++ }
|
||||
75 -> playerl(FacialExpression.ASKING,"Where is the nearest bank?").also { stage++ }
|
||||
76 -> npcl(FacialExpression.HAPPY,"Ah, I see your problem outerlander. The nearest bank to here is the place known to outerlanders as the Seers Village.").also { stage++ }
|
||||
77 -> npcl(FacialExpression.HAPPY,"It is some way South. I do however have an alternative, should you wish to take it.").also { stage++ }
|
||||
78 -> playerl(FacialExpression.ASKING,"And what is that?").also { stage++ }
|
||||
79 -> npcl(FacialExpression.HAPPY,"I can store all the weapons, armour and items that you have upon you directly into your bank account.").also { stage++ }
|
||||
80 -> npcl(FacialExpression.HAPPY,"This will tax what little magic I possess however, so you will have to travel to the bank to withdraw them again.").also { stage++ }
|
||||
81 -> npcl(FacialExpression.HAPPY,"What say you outerlander? Do you wish me to do this for you?").also { stage++ }
|
||||
82 -> options("Yes","No").also { stage++ }
|
||||
83 -> when(buttonId){
|
||||
1 -> {
|
||||
val slotAmount = player.inventory.itemCount() + player.equipment.itemCount()
|
||||
if (slotAmount < player.bank.freeSlots()){
|
||||
npcl(core.game.dialogue.FacialExpression.HAPPY,"The task is done. I wish you luck with your test, outerlander.")
|
||||
dumpContainer(player,player.inventory)
|
||||
dumpContainer(player,player.equipment)
|
||||
if (slotAmount < player.bank.freeSlots() && slotAmount == dumpContainer(player,player.inventory) + dumpContainer(player,player.equipment)){
|
||||
npcl(FacialExpression.HAPPY,"The task is done. I wish you luck with your test, outerlander.")
|
||||
stage = 1000
|
||||
}
|
||||
else {
|
||||
npcl(core.game.dialogue.FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you")
|
||||
npcl(FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you.")
|
||||
stage = 1000
|
||||
}
|
||||
}
|
||||
2 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"No thanks. Nobody touches my stuff but me!").also { stage++ }
|
||||
2 -> playerl(FacialExpression.HAPPY,"No thanks. Nobody touches my stuff but me!").also { stage++ }
|
||||
}
|
||||
|
||||
//No to banking
|
||||
84 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish, outerlander. You may attempt my little task when you have deposited your equipment in the bank").also {
|
||||
84 -> npcl(FacialExpression.HAPPY,"As you wish, outerlander. You may attempt my little task when you have deposited your equipment in the bank.").also {
|
||||
stage = 1000
|
||||
}
|
||||
|
||||
//Yes to banking but cannot bank
|
||||
90 -> npcl(core.game.dialogue.FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you").also {
|
||||
90 -> npcl(FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you.").also {
|
||||
stage = 1000
|
||||
}
|
||||
|
||||
//Returning after accepting with items.
|
||||
100 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ }
|
||||
101 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ }
|
||||
102 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So I can bring nothing with me when I enter your house?").also { stage++ }
|
||||
103 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander, but as I say, I can use my small skill in magic to send your items directly into your bank account from here.").also { stage++ }
|
||||
104 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You will need to manually go to the bank to withdraw them again however.").also { stage++ }
|
||||
105 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Would you like me to perform this small spell upon you, outerlander?").also { stage = 82 }
|
||||
100 -> npcl(FacialExpression.AMAZED,"!").also { stage++ }
|
||||
101 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ }
|
||||
102 -> playerl(FacialExpression.ASKING,"So I can bring nothing with me when I enter your house?").also { stage++ }
|
||||
103 -> npcl(FacialExpression.HAPPY,"That is correct outerlander, but as I say, I can use my small skill in magic to send your items directly into your bank account from here.").also { stage++ }
|
||||
104 -> npcl(FacialExpression.HAPPY,"You will need to manually go to the bank to withdraw them again however.").also { stage++ }
|
||||
105 -> npcl(FacialExpression.HAPPY,"Would you like me to perform this small spell upon you, outerlander?").also { stage = 82 }
|
||||
|
||||
//Returning after accepting without items.
|
||||
110 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ }
|
||||
111 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ }
|
||||
112 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So I just have to enter by one door of your house, and leave by the other?").also { stage++ }
|
||||
113 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander. Be warned it is not as easy as it may at first sound...").also { stage = 1000 }
|
||||
110 -> npcl(FacialExpression.AMAZED,"!").also { stage++ }
|
||||
111 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ }
|
||||
112 -> playerl(FacialExpression.ASKING,"So I just have to enter by one door of your house, and leave by the other?").also { stage++ }
|
||||
113 -> npcl(FacialExpression.HAPPY,"That is correct outerlander. Be warned it is not as easy as it may at first sound...").also { stage = 1000 }
|
||||
|
||||
//After completing the Seer's Trial.
|
||||
120 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ }
|
||||
121 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that.").also { stage++ }
|
||||
122 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"So you will vote for me at the council?").also { stage++ }
|
||||
123 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Absolutely, outerlander. Your wisdom in passing my test marks you as worthy in my eyes.").also { stage = 1000 }
|
||||
120 -> npcl(FacialExpression.AMAZED,"!").also { stage++ }
|
||||
121 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that.").also { stage++ }
|
||||
122 -> playerl(FacialExpression.HAPPY,"So you will vote for me at the council?").also { stage++ }
|
||||
123 -> npcl(FacialExpression.HAPPY,"Absolutely, outerlander. Your wisdom in passing my test marks you as worthy in my eyes.").also { stage = 1000 }
|
||||
|
||||
|
||||
//After The Fremennik Trials
|
||||
150 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ }
|
||||
151 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that.").also {
|
||||
stage = if(player.achievementDiaryManager.getDiary(DiaryType.FREMENNIK).isComplete(0)){
|
||||
150 -> npcl(FacialExpression.AMAZED,"!").also { stage++ }
|
||||
151 -> npcl(FacialExpression.HAPPY,"Ahem, sorry about that.").also {
|
||||
stage = if(anyInEquipment(player, Items.FREMENNIK_SEA_BOOTS_1_14571, Items.FREMENNIK_SEA_BOOTS_2_14572, Items.FREMENNIK_SEA_BOOTS_3_14573) && !hasIronmanRestriction(player, IronmanMode.ULTIMATE)){
|
||||
200
|
||||
}else 152
|
||||
}
|
||||
152 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Hello Peer.").also { stage++ }
|
||||
153 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Greetings to you, brother ${player.getAttribute("fremennikname","dingle")}! What brings you to see me again?").also { stage++ }
|
||||
152 -> playerl(FacialExpression.HAPPY,"Hello Peer.").also { stage++ }
|
||||
153 -> npcl(FacialExpression.HAPPY,"Greetings to you, brother ${player.getAttribute("fremennikname","dingle")}! What brings you to see me again?").also { stage++ }
|
||||
154 -> options("Can you tell my future?","Nothing really.").also{stage++}
|
||||
155 -> when(buttonId){
|
||||
1 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage++ }
|
||||
2 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 }
|
||||
1 -> playerl(FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage++ }
|
||||
2 -> playerl(FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 }
|
||||
}
|
||||
156 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah, you would like a prediction? I do not see that that would be so difficult... Wait a moment...").also {
|
||||
156 -> npcl(FacialExpression.HAPPY,"Ah, you would like a prediction? I do not see that that would be so difficult... Wait a moment...").also {
|
||||
stage++
|
||||
}
|
||||
157 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here is your prediction: ${PREDICTIONS[prediction]}").also { stage = 1000 }
|
||||
157 -> npcl(FacialExpression.HAPPY,"Here is your prediction: ${PREDICTIONS[prediction]}").also { stage = 1000 }
|
||||
|
||||
160 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, hello to you too!").also { stage = 1000 }
|
||||
160 -> npcl(FacialExpression.HAPPY,"Well, hello to you too!").also { stage = 1000 }
|
||||
|
||||
|
||||
200 -> options("Deposit service","Can you tell my future?","Nothing really.").also{ stage++ }
|
||||
201 -> when(buttonId){
|
||||
1 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Could you deposit some things for me, please?").also { stage++ }
|
||||
2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage = 156 }
|
||||
3 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 }
|
||||
1 -> playerl(FacialExpression.HAPPY,"Could you deposit some things for me, please?").also { stage++ }
|
||||
2 -> playerl(FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage = 156 }
|
||||
3 -> playerl(FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 }
|
||||
}
|
||||
202 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Of course, ${player.getAttribute("fremennikname","dingle")}. I am always happy to aid those who have earned the right to wear Fremennik sea boots.").also {
|
||||
202 -> npcl(FacialExpression.HAPPY,"Of course, ${player.getAttribute("fremennikname","dingle")}. I am always happy to aid those who have earned the right to wear Fremennik sea boots.").also {
|
||||
player.bank.openDepositBox()
|
||||
stage = 1000
|
||||
}
|
||||
|
||||
300 -> npc(core.game.dialogue.FacialExpression.NEUTRAL,"!").also { stage++ }
|
||||
301 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Ahem, sorry about that. I have no interest in talking to you just now outerlander.").also { stage = END_DIALOGUE }
|
||||
300 -> npc(FacialExpression.NEUTRAL,"!").also { stage++ }
|
||||
301 -> npcl(FacialExpression.NEUTRAL,"Ahem, sorry about that. I have no interest in talking to you just now outerlander.").also { stage = END_DIALOGUE }
|
||||
|
||||
1000 -> end()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin {
|
||||
override fun newInstance(player: Player?): DialoguePlugin {
|
||||
return PeerTheSeerDialogue(player)
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(1288)
|
||||
return intArrayOf(NPCs.PEER_THE_SEER_1288)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,18 @@
|
|||
package content.region.fremennik.rellekka.quest.thefremenniktrials
|
||||
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.inInventory
|
||||
import core.api.setAttribute
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.dialogue.IfTopic
|
||||
import core.game.dialogue.Topic
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import core.tools.START_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import content.data.Quests
|
||||
|
||||
@Initializable
|
||||
|
|
@ -18,12 +25,18 @@ class PoisonSalesman(player: Player? = null) : DialoguePlugin(player) {
|
|||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
//val murderMysteryStage = player.questRepository.isComplete(Quests.MURDER_MYSTERY)
|
||||
val murderMysteryStage = player.questRepository.getStage(Quests.MURDER_MYSTERY)
|
||||
val fremennikTrialsStage = player.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS)
|
||||
|
||||
when (stage) {
|
||||
START_DIALOGUE -> when (buttonId) {
|
||||
1 -> { player("Err... nevermind"); stage = END_DIALOGUE }
|
||||
1 -> {
|
||||
when (murderMysteryStage) {
|
||||
0 -> npcl(FacialExpression.NEUTRAL, "I'm afraid I'm all sold out of poison at the moment. People know a bargain when they see it!").also { stage = END_DIALOGUE }
|
||||
1 -> playerl(FacialExpression.NEUTRAL, "I'm investigating the murder at the Sinclair house.").also { stage = 50 }
|
||||
100 -> npcl(FacialExpression.NEUTRAL, "I hear you're pretty smart to have solved the Sinclair Murder!").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
2 -> { player("Hello."); stage = 10 }
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +101,42 @@ class PoisonSalesman(player: Player? = null) : DialoguePlugin(player) {
|
|||
stage++
|
||||
}
|
||||
45 -> { npc("Well come back when you do!"); stage = END_DIALOGUE }
|
||||
|
||||
//Murder Mystery
|
||||
50 -> npcl(FacialExpression.NEUTRAL, "There was a murder at the Sinclair house??? That's terrible! And I was only there the other day too! They bought the last of my Patented Multi Purpose Poison!").also { stage++ }
|
||||
51 -> showTopics(
|
||||
Topic("Patented Multi Purpose Poison?", 52),
|
||||
Topic("Who did you sell Poison to at the house?", 61),
|
||||
Topic("Can I buy some Poison?", 65),
|
||||
IfTopic("I have this pot I found at the murder scene...", 69, inInventory(player, Items.PUNGENT_POT_1812))
|
||||
)
|
||||
52 -> npcl(FacialExpression.NEUTRAL, "Aaaaah... a miracle of modern apothecaries!").also { stage++ }
|
||||
53 -> npcl(FacialExpression.NEUTRAL, "This exclusive concoction has been tested on all known forms of life and been proven to kill them all in varying dilutions from cockroaches to king dragons!").also { stage++ }
|
||||
54 -> npcl(FacialExpression.NEUTRAL, "So incredibly versatile, it can be used as pest control, a cleansing agent, drain cleaner, metal polish and washes whiter than white,").also { stage++ }
|
||||
55 -> npcl(FacialExpression.NEUTRAL, "all with our uniquely fragrant concoction that is immediately recognisable across the land as Peter Potter's Patented Poison potion!!!").also { stage++ }
|
||||
56 -> sendDialogue("The salesman stops for breath.").also { stage ++ }
|
||||
57 -> npcl(FacialExpression.NEUTRAL, "I'd love to sell you some but I've sold out recently. That's just how good it is! Three hundred and twenty eight people in this area alone cannot be wrong!").also { stage++ }
|
||||
58 -> npcl(FacialExpression.NEUTRAL, "Nine out of Ten poisoners prefer it in controlled tests!").also { stage++ }
|
||||
59 -> npcl(FacialExpression.NEUTRAL, "Can I help you with anything else? Perhaps I can take your name and add it to our mailing list of poison users? We will only send you information related to the use of poison and other Peter Potter Products!").also { stage++ }
|
||||
60 -> playerl(FacialExpression.NEUTRAL, "Uh... no, it's ok. Really.").also { stage = END_DIALOGUE }
|
||||
|
||||
61 -> npcl(FacialExpression.HAPPY, "Well, Peter Potter's Patented Multi Purpose Poison is a product of such obvious quality that I am glad to say I managed to sell a bottle to each of the Sinclairs!").also { stage++ }
|
||||
62 -> npcl(FacialExpression.HAPPY, "Anna, Bob, Carol, David, Elizabeth and Frank all bought a bottle! In fact they bought the last of my supplies!").also { stage++ }
|
||||
63 -> npcl(FacialExpression.HAPPY, "Maybe I can take your name and address and I will personally come and visit you when stocks return?").also { stage++ }
|
||||
64 -> playerl(FacialExpression.THINKING, "Uh...no, it's ok.")
|
||||
.also { setAttribute(player, attributePoisonClue, 1)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
|
||||
65 -> npcl(FacialExpression.NEUTRAL, "I'm afraid I am totally out of stock at the moment after my successful trip to the Sinclairs' House the other day.").also { stage++ }
|
||||
66 -> npcl(FacialExpression.NEUTRAL, "But don't worry! Our factories are working overtime to produce Peter Potter's Patented Multi Purpose Poison!").also { stage++ }
|
||||
67 -> npcl(FacialExpression.NEUTRAL, "Possibly the finest multi purpose poison and cleaner yet available to the general market.").also { stage++ }
|
||||
68 -> npcl(FacialExpression.NEUTRAL, "And its unique fragrance makes it the number one choice for cleaners and exterminators the whole country over!").also { stage = END_DIALOGUE }
|
||||
|
||||
69 -> sendDialogue("You show the poison salesman the pot you found at the murder", "scene with the unusual smell.").also { stage ++ }
|
||||
70 -> npcl(FacialExpression.THINKING, "Hmmm... yes, that smells exactly like my Patented Multi Purpose Poison, but I don't see how it could be. It quite clearly says on the label of all bottles").also { stage++ }
|
||||
71 -> npcl(FacialExpression.THINKING, "'Not to be taken internally - EXTREMELY POISONOUS'.").also { stage++ }
|
||||
72 -> playerl(FacialExpression.THINKING, "Perhaps someone else put it in his wine?").also { stage++ }
|
||||
73 -> npcl(FacialExpression.THINKING, "Yes... I suppose that could have happened...").also { stage = END_DIALOGUE }
|
||||
END_DIALOGUE -> end()
|
||||
}
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import core.game.node.entity.npc.NPC
|
|||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import content.data.Quests
|
||||
|
||||
|
|
@ -43,8 +42,7 @@ class ThormacDialogue(player: Player? = null) : DialoguePlugin(player) {
|
|||
)
|
||||
|
||||
ENCHANT_DIALOGUE -> {
|
||||
val cost = if (player.equipment.contains(Items.SEERS_HEADBAND_14631, 1)) 27 else 40
|
||||
npcl(FacialExpression.HAPPY, "Yes, it'll cost you $cost,000 coins for the materials needed though. " +
|
||||
npcl(FacialExpression.HAPPY, "Yes, it'll cost you 40,000 coins for the materials needed though. " +
|
||||
"Which sort of staff did you want enchanting?").also { stage++ }
|
||||
}
|
||||
ENCHANT_DIALOGUE + 1 -> {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
package content.region.kandarin.gnomestronghold.dialogue
|
||||
|
||||
import core.api.addItem
|
||||
import core.api.inInventory
|
||||
import core.api.openDialogue
|
||||
import core.api.openNpcShop
|
||||
import core.api.removeItem
|
||||
import core.api.sendMessage
|
||||
import core.game.dialogue.ChatAnim
|
||||
import core.game.dialogue.DialogueLabeller
|
||||
import core.game.dialogue.DialogueOption
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
private const val INGREDIENT_COST = 20
|
||||
private const val NOT_ENOUGH_MONEY_MESSAGE = "You do not have enough money to buy that."
|
||||
|
||||
/**
|
||||
* Handles the dialogue for the Gnome Barman NPCs in the Tree Gnome Stronghold.
|
||||
* @author Broseki
|
||||
*/
|
||||
@Initializable
|
||||
class GnomeBarmanDialogue(player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun newInstance(player: Player?): DialoguePlugin {
|
||||
return GnomeBarmanDialogue(player)
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, GnomeBarmanDialogueStart(), npc)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.BARMAN_849)
|
||||
}
|
||||
}
|
||||
|
||||
class GnomeBarmanDialogueStart : DialogueLabeller() {
|
||||
override fun addConversation() {
|
||||
npc(ChatAnim.OLD_HAPPY, "Good day to you. What can I get you to drink?")
|
||||
options(
|
||||
DialogueOption("store", "What do you have?", expression = ChatAnim.FRIENDLY, spokenText = "What do you have."),
|
||||
DialogueOption("nothing", "Nothing thanks.", expression = ChatAnim.FRIENDLY),
|
||||
DialogueOption(
|
||||
"ingredients", "Can I buy some ingredients?",
|
||||
spokenText = "I was just wanting to buy a cocktail ingredient actually.",
|
||||
expression = ChatAnim.FRIENDLY
|
||||
),
|
||||
)
|
||||
|
||||
label("store")
|
||||
npc(ChatAnim.OLD_HAPPY, "Here, take a look at our menu.")
|
||||
exec { player, npc ->
|
||||
openNpcShop(player, npc.id)
|
||||
}
|
||||
|
||||
label("nothing")
|
||||
npc(ChatAnim.OLD_HAPPY, "Okay, take it easy.")
|
||||
|
||||
label("ingredients")
|
||||
npc(ChatAnim.OLD_HAPPY, "Sure thing, what did you want?")
|
||||
options(
|
||||
DialogueOption("lemon", "A lemon.", expression = ChatAnim.FRIENDLY),
|
||||
DialogueOption("orange", "An orange.", expression = ChatAnim.FRIENDLY),
|
||||
DialogueOption("shaker", "A cocktail shaker.", expression = ChatAnim.FRIENDLY),
|
||||
DialogueOption(
|
||||
"buynothing", "Nothing thanks.",
|
||||
spokenText = "Actually nothing thanks.",
|
||||
expression = ChatAnim.FRIENDLY
|
||||
),
|
||||
)
|
||||
|
||||
label("lemon")
|
||||
npc(ChatAnim.OLD_HAPPY, "$INGREDIENT_COST coins please.")
|
||||
exec { player, _ ->
|
||||
if (removeItem(player, Item(Items.COINS_995, INGREDIENT_COST))) {
|
||||
addItem(player, Items.LEMON_2102)
|
||||
} else {
|
||||
sendMessage(player, NOT_ENOUGH_MONEY_MESSAGE)
|
||||
}
|
||||
}
|
||||
|
||||
label("orange")
|
||||
npc(ChatAnim.OLD_HAPPY, "$INGREDIENT_COST coins please.")
|
||||
exec { player, _ ->
|
||||
if (removeItem(player, Item(Items.COINS_995, INGREDIENT_COST))) {
|
||||
addItem(player, Items.ORANGE_2108)
|
||||
} else {
|
||||
sendMessage(player, NOT_ENOUGH_MONEY_MESSAGE)
|
||||
}
|
||||
}
|
||||
|
||||
label("shaker")
|
||||
npc(ChatAnim.OLD_HAPPY, "$INGREDIENT_COST coins please.")
|
||||
exec { player, _ ->
|
||||
if (removeItem(player, Item(Items.COINS_995, INGREDIENT_COST))) {
|
||||
addItem(player, Items.COCKTAIL_SHAKER_2025)
|
||||
} else {
|
||||
sendMessage(player, NOT_ENOUGH_MONEY_MESSAGE)
|
||||
}
|
||||
}
|
||||
|
||||
label("buynothing")
|
||||
// Just end the conversation here without any further dialogue
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonAnna
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class AnnaDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, AnnaDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return AnnaDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.ANNA_814, NPCs.ANNA_6192)
|
||||
}
|
||||
}
|
||||
|
||||
class AnnaDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl(FacialExpression.ASKING, "Oh really? What do you want to know then?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you when the murder happened?", 6),
|
||||
IfTopic("Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
|
||||
IfTopic("Why'd you buy poison the other day?", 10, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
3 -> npcl("It was clearly an intruder.").also { stage++ }
|
||||
4 -> playerl("Well, I don't think it was.").also { stage++ }
|
||||
5 -> npcl("It was one of our lazy servants then.").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> npcl("In the library. No one else was there so you'll just have to take my word for it.").also { stage = END_DIALOGUE }
|
||||
|
||||
7 -> sendDialogue(player!!, "You show Anna the thread from the study.")
|
||||
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1809)) stage++ else stage = 9 }
|
||||
8 -> npcl("It's some Green thread. It's not exactly uncommon is it? My trousers are made of the same material.").also { stage = END_DIALOGUE }
|
||||
|
||||
9 -> npcl("Not really, no. Thread is fairly common.").also { stage = END_DIALOGUE }
|
||||
|
||||
10 -> npcl(FacialExpression.ANNOYED, "That useless Gardener Stanford let his compost heap fester. It's an eyesore to the garden! So I bought some poison from a travelling salesman so that I could kill off some of the wildlife living in it.")
|
||||
.also { setAttribute(player!!, attributeAskPoisonAnna, true)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonBob
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class BobDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, BobDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return BobDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.BOB_815, NPCs.BOB_6193)
|
||||
}
|
||||
}
|
||||
|
||||
class BobDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl("I suppose I had better talk to you then.").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you when the murder happened?", 4),
|
||||
IfTopic(FacialExpression.THINKING, "Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
|
||||
IfTopic("Why'd you buy poison the other day?", 10, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
3 -> npcl("I don't really care as long as no one thinks it's me. Maybe it was that strange poison seller who headed towards the seers village.").also { stage = END_DIALOGUE }
|
||||
|
||||
4 -> npcl("I was walking by myself in the garden.").also { stage++ }
|
||||
5 -> playerl("And can anyone vouch for that?").also { stage++ }
|
||||
6 -> npcl("No. But I was.").also { stage = END_DIALOGUE }
|
||||
|
||||
7 -> sendDialogue(player!!, "You show him the thread you discovered.")
|
||||
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1808)) stage++ else stage = 9 }
|
||||
8 -> npcl("It's some red thread. I suppose you think that's some kind of clue? It looks like the material my trousers are made of.").also { stage = END_DIALOGUE }
|
||||
|
||||
9 -> npcl(FacialExpression.THINKING, "It's some thread. Great clue. No, really.").also { stage = END_DIALOGUE }
|
||||
|
||||
10 -> npcl(FacialExpression.THINKING, "What's it to you anyway?").also { stage++ }
|
||||
11 -> npcl(FacialExpression.ANGRY, "If you absolutely must know, we had a problem with the beehive in the garden, and as all of our servants are so pathetically useless, I decided I would deal with it myself. So I did.")
|
||||
.also { setAttribute(player!!, attributeAskPoisonBob, true)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonCarol
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class CarolDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, CarolDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return CarolDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.CAROL_816, NPCs.CAROL_6194)
|
||||
}
|
||||
}
|
||||
|
||||
class CarolDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl("Well, ask what you want to know then.").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you when the murder happened?", 4),
|
||||
IfTopic("Do you recognise this thread?", 5, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
|
||||
IfTopic("Why'd you buy poison the other day?", 8, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
3 -> npcl("I don't know. I think it's very convenient that you have arrived here so soon after it happened. Maybe it was you.").also { stage = END_DIALOGUE }
|
||||
|
||||
4 -> npcl("Why? Are you accusing me of something? You seem to have a very high opinion of yourself. I was in my room if you must know, alone.").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> sendDialogue(player!!, "You show Carol the thread found at the crime scene.")
|
||||
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1808)) stage++ else stage = 7 }
|
||||
6 -> npcl("It's some red thread... it kind of looks like the Same material as my trousers. But obviously it's not.").also { stage = END_DIALOGUE }
|
||||
|
||||
7 -> npcl("It's some thread. Sorry, do you have a point here? Or do you just enjoy wasting peoples time?").also { stage = END_DIALOGUE }
|
||||
|
||||
8 -> npcl(FacialExpression.THINKING, "I don't see what on earth it has to do with you, but the drain outside was").also { stage++ }
|
||||
9 -> npcl(FacialExpression.ANNOYED, "blocked, and as nobody else here has the intelligence to even unblock a simple drain I felt I had to do it myself.")
|
||||
.also { setAttribute(player!!, attributeAskPoisonCarol, true)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonDavid
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class DavidDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, DavidDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return DavidDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.DAVID_817, NPCs.DAVID_6195)
|
||||
}
|
||||
}
|
||||
|
||||
class DavidDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl("And? Make this quick. I have better things to do than be interrogated by halfwits all day.").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you when the murder happened?", 5),
|
||||
IfTopic("Do you recognise this thread?", 6, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
|
||||
IfTopic("Why'd you buy poison the other day?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
3 -> npcl("I don't really know or care. Frankly, the old man deserved to die.").also { stage++ }
|
||||
4 -> npcl("There was a suspicious red headed man who came to the house the other day selling poison now I think about it. Last I saw he was headed towards the tavern in the Seers village.").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> npcl("That is none of your business. Are we finished now, or are you just going to stand there irritating me with your idiotic questions all day?").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> sendDialogue(player!!, "You show him the thread you found on the study window.")
|
||||
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1809)) stage++ else stage = 8 }
|
||||
7 -> npcl("It's some Green thread, like my trousers are made of. Are you finished? I'm not sure which I dislike more bout you, your face or your general bad odour.").also { stage = END_DIALOGUE }
|
||||
|
||||
8 -> npcl("No. Can I go yet? Your face irritates me.").also { stage = END_DIALOGUE }
|
||||
|
||||
9 -> npcl(FacialExpression.ANGRY, "There was a nest of spiders upstairs between the two servants' quarters. Obviously I had to kill them before our pathetic servants whined at my father some more.").also { stage++ }
|
||||
10 -> npcl(FacialExpression.THINKING, "Honestly, it's like they expect to be treated like royalty! If I had my way I would fire the whole workshy lot of them!")
|
||||
.also { setAttribute(player!!, attributeAskPoisonDavid, true)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class DonovanDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, DonovanDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return DonovanDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.DONOVAN_THE_FAMILY_HANDYMAN_806)
|
||||
}
|
||||
}
|
||||
|
||||
class DonovanDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> npcl("I have no interest in talking to gawkers.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl("I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl("How can I help?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you at the time of the murder?", 5),
|
||||
IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)),
|
||||
IfTopic("Do you know why so much poison was bought recently?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
3 -> npcl("Oh... I really couldn't say. I wouldn't really want to point any fingers at anybody. If I had to make a guess I'd have to say it was probably Bob though.").also { stage++ }
|
||||
4 -> npcl("I saw him arguing with Lord Sinclair about some missing silverware from the Kitchen. It was a very heated argument.").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> npcl("Me? I was sound asleep here in the servants Quarters. It's very hard work as a handyman around here. There's always something to do!").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> npcl("Hmmm... No, I didn't, but I sleep very soundly at night.").also { stage++ }
|
||||
7 -> playerl("So you didn't hear any sounds of a struggle or any barking from the guard dog next to his study window?").also { stage++ }
|
||||
8 -> npcl("Now you mention it, no. It is odd I didn't hear anything like that. But I do sleep very soundly as I said and wouldn't necessarily have heard it if there was any such noise.").also { stage = END_DIALOGUE }
|
||||
|
||||
9 -> npcl("Well, I do know Frank bought some poison recently to clean the family crest that's outside.").also { stage++ }
|
||||
10 -> npcl("It's very old and rusty, and I couldn't clean it myself, so he said he would buy some cleaner and clean it himself. He probably just got some from that Poison Salesman who came to the door the other day...").also { stage++ }
|
||||
11 -> npcl("You'd really have to ask him though.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonElizabeth
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class ElizabethDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, ElizabethDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return ElizabethDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.ELIZABETH_818, NPCs.ELIZABETH_6196)
|
||||
}
|
||||
}
|
||||
|
||||
class ElizabethDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl("What's so important you need to bother me with then?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you when the murder happened?", 4),
|
||||
IfTopic("Do you recognise this thread?", 7, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
|
||||
IfTopic("Why'd you buy poison the other day?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
3 -> npcl("Could have been anyone. The old man was an idiot. He's been asking for it for years.").also { stage = END_DIALOGUE }
|
||||
|
||||
4 -> npcl("I was out.").also { stage++ }
|
||||
5 -> playerl("Care to be any more specific?").also { stage++ }
|
||||
6 -> npcl("Not really. I don't have to justify myself to the likes of you, you know. I know the King personally you know. Now are we finished here?").also { stage = END_DIALOGUE }
|
||||
|
||||
7 -> sendDialogue(player!!, "You show her the thread from the study window.")
|
||||
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1810)) stage++ else stage = 11 }
|
||||
8 -> npcl(" Looks like Blue thread to me. If you can't work that out for yourself I don't hold much hope of you solving this crime.").also { stage++ }
|
||||
9 -> playerl("It looks a lot like the material your trousers are made of doesn't it?").also { stage++ }
|
||||
10 -> npcl("I suppose it does. So what?").also { stage = END_DIALOGUE }
|
||||
|
||||
11 -> npcl(" It's some thread. You're not very good at this whole investigation thing are you?").also { stage = END_DIALOGUE }
|
||||
|
||||
12 -> npcl("There was a nest of mosquitos under the fountain in the garden, which I killed with poison the other day. You can see for yourself if you're capable of managing that, which I somehow doubt.").also { stage++ }
|
||||
13 -> playerl(FacialExpression.ANNOYED, "I hate mosquitos!").also { stage++ }
|
||||
14 -> npcl("Doesn't everyone?")
|
||||
.also { setAttribute(player!!, attributeAskPoisonElizabeth, true)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import core.api.*
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class FlypaperDialogue : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (stage) {
|
||||
0 -> sendDialogue(player!!, "There's some flypaper in there. Should I take it?").also { stage++ }
|
||||
1 -> options("Yes, it might be useful.", "No, I don't see any need for it.").also { stage++ }
|
||||
2 -> when(buttonID) {
|
||||
1 -> if (addItem(player!!, Items.FLYPAPER_1811)){
|
||||
sendDialogue(player!!, "You take a piece of fly paper. There is still plenty of fly paper left.")
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
else {
|
||||
sendDialogue(player!!, "You don't have enough space in your inventory.")
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
2 -> sendDialogue(player!!, "You leave the paper in the sack.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import core.api.*
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.tools.END_DIALOGUE
|
||||
|
||||
class FountainDialogue : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (stage) {
|
||||
0 -> sendDialogue(player!!, "The fountain is swarming with mosquitos. There's a nest of them underneath the fountain.").also { stage++ }
|
||||
1 -> playerl("I hate mosquitos, they're so annoying!").also { stage++ }
|
||||
2 -> sendDialogue(player!!, "It's certainly clear nobody's used poison here.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonFrank
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class FrankDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, FrankDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return FrankDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.FRANK_819, NPCs.FRANK_6197)
|
||||
}
|
||||
}
|
||||
|
||||
class FrankDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl("Good for you. Now what do you want?").also { stage++ }
|
||||
2 -> npcl(FacialExpression.SAD, "...And can you spare me any money? I'm a little short...").also { stage++ }
|
||||
3 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 4),
|
||||
Topic( "Where were you when the murder happened?", 5),
|
||||
IfTopic("Do you recognise this thread?", 6, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810)),
|
||||
IfTopic("Why'd you buy poison the other day?", 9, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
4 -> npcl("I don't know. You don't know how long it takes an inheritance to come through do you? I could really use that money pretty soon...").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> npcl("I don't know, somewhere around here probably. Could you spare me a few coins? I'll be able to pay you back double tomorrow it's just there's this poker night tonight in town...").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> sendDialogue(player!!, "Frank examines the thread from the crime scene.")
|
||||
.also { if (inInventory(player!!, Items.CRIMINALS_THREAD_1810)) stage++ else stage = 8 }
|
||||
7 -> npcl("It kind of looks like the same material as my trousers are made of... same colour anyway. Think it's worth anything? Can I have it? Or just some money?").also { stage = END_DIALOGUE }
|
||||
|
||||
8 -> npcl("It looks like thread to me, but I'm not exactly an expert. Is it worth something? Can I have it? Actually, can you spare me a few gold?").also { stage = END_DIALOGUE }
|
||||
|
||||
9 -> npcl("Would you like to buy some? I'm kind of strapped for cash right now. I'll sell it to you cheap. It's hardly been used at all.").also { stage++ }
|
||||
10 -> npcl("I just used a bit to clean that family crest outside up a bit. Do you think I could get much money for the family crest, actually? It's cleaned up a bit now.")
|
||||
.also { setAttribute(player!!, attributeAskPoisonFrank, true)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Apparently you aren't as stupid as you look.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class GossipDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, GossipDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return GossipDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.GOSSIP_813)
|
||||
}
|
||||
}
|
||||
|
||||
class GossipDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> npcl("There's some kind of commotion up at the Sinclair place I hear. Not surprising all things considered.").also { stage = END_DIALOGUE}
|
||||
1 -> when (stage) {
|
||||
0 -> playerl("I'm investigating the murder up at the Sinclair place.").also { stage++ }
|
||||
1 -> npcl("Murder is it? Well, I'm not really surprised...").also { stage++ }
|
||||
2 -> options("What can you tell me about the Sinclairs?", "Who do you think was responsible?", "I think the butler did it.", "I am so confused about who did it.").also { stage++ }
|
||||
3 -> when(buttonID) {
|
||||
1 -> playerl("What can you tell me about the Sinclairs?").also { stage = 4 }
|
||||
2 -> playerl("Who do you think was responsible?").also { stage = 40 }
|
||||
3 -> playerl("I think the butler did it.").also { stage = 42 }
|
||||
4 -> playerl("I am so confused about who did it.").also { stage = 43 }
|
||||
}
|
||||
4 -> npcl("Well, what do you want to know?").also { stage++ }
|
||||
5 -> options("Tell me about Lord Sinclair.", "Why do the Sinclairs live so far from town?", "What can you tell me about his sons?", "What can you tell me about his daughters?").also { stage++ }
|
||||
6 -> when(buttonID) {
|
||||
1 -> playerl("Tell me about Lord Sinclair.").also { stage = 7 }
|
||||
2 -> playerl("Why do the Sinclairs live so far from town?").also { stage = 10 }
|
||||
3 -> playerl("What can you tell me about his sons?").also { stage = 12 }
|
||||
4 -> playerl("What can you tell me about his daughters?").also { stage = 15 }
|
||||
}
|
||||
7 -> npcl("Old Lord Sinclair was a great man with a lot of respect around these parts. More than his worthless children have anyway.").also { stage++ }
|
||||
8 -> playerl("His children? They have something to gain by his death?").also { stage++ }
|
||||
9 -> npcl("Yes. You could say that. Not that I am one to gossip.").also { stage = END_DIALOGUE }
|
||||
|
||||
10 -> npcl("Well, they used to live in the big castle, but old Lord Sinclair gave it up so that those strange knights could live there instead. So the king built him a new house to the North.").also { stage++ }
|
||||
11 -> npcl("It's more cramped than his old place, but he seemed to like it. His children were furious at him for doing it though!").also { stage = END_DIALOGUE }
|
||||
|
||||
12 -> npcl("His sons eh? They all have their own skeletons in their cupboards. You'll have to be more specific. Who are you interested in exactly?").also { stage++ }
|
||||
13 -> options("Tell me about Bob.", "Tell me about David.", "Tell me about Frank.").also { stage++ }
|
||||
14 -> when(buttonID) {
|
||||
1 -> playerl("Tell me about Bob.").also { stage = 18 }
|
||||
2 -> playerl("Tell me about David.").also { stage = 23 }
|
||||
3 -> playerl("Tell me about Frank.").also { stage = 27 }
|
||||
}
|
||||
|
||||
15 -> npcl("His daughters eh? They're all nasty pieces of work, which of them specifically did you want to know about?").also { stage++ }
|
||||
16 -> options("Tell me about Anna.", "Tell me about Carol.", "Tell me about Elizabeth.").also { stage++ }
|
||||
17 -> when(buttonID) {
|
||||
1 -> playerl("Tell me about Anna.").also { stage = 30 }
|
||||
2 -> playerl("Tell me about Carol.").also { stage = 33 }
|
||||
3 -> playerl("Tell me about Elizabeth.").also { stage = 36 }
|
||||
}
|
||||
|
||||
18 -> npcl("Bob is an odd character indeed... I'm not one to gossip, but I heard Bob is addicted to Tea. He can't make").also { stage++ }
|
||||
19 -> npcl("it through the day without having at least 20 cups!").also { stage++ }
|
||||
20 -> npcl("You might not think that's such a big thing, but he has spent thousands of gold to feed his habit!").also { stage++ }
|
||||
21 -> npcl("At one point he stole a lot of silverware from the kitchen and pawned it just so he could afford to buy his daily tea allowance.").also { stage++ }
|
||||
22 -> npcl("If his father ever found out, he would be in so much trouble... he might even get disowned!").also { stage = END_DIALOGUE }
|
||||
|
||||
23 -> npcl("David... oh David... not many people know this, but David really has an anger problem. He's always screaming and shouting").also { stage++ }
|
||||
24 -> npcl("at the household servants when he's angry, and they live in a state of fear, always walking on eggshells around him, but none of them have the courage").also { stage++ }
|
||||
25 -> npcl("to talk to his father about his behaviour. If they did, Lord Sinclair would almost certainly").also { stage++ }
|
||||
26 -> npcl("kick him out of the house, as some of the servants have been there longer than he has, and he definitely has no right to treat them like he does... but I'm not one to gossip about people.").also { stage = END_DIALOGUE }
|
||||
|
||||
27 -> npcl("I'm not one to talk ill of people behind their back, but Frank is a real piece of work. He is an absolutely terrible gambler...he can't pass 2 dogs in the street without putting a bet on which one will bark first!").also { stage++ }
|
||||
28 -> npcl("He has already squandered all of his allowance, and I heard he had stolen a number of paintings of his fathers to sell to try and cover his debts, but he still owes a lot of people a lot of").also { stage++ }
|
||||
29 -> npcl("money. If his father ever found out, he would stop his income, and then he would be in serious trouble!").also { stage = END_DIALOGUE }
|
||||
|
||||
30 -> npcl("Anna... ah yes... Anna has 2 great loves:").also { stage++ }
|
||||
31 -> npcl("Sewing and gardening. But one thing she has kept secret is that she once had an affair with Stanford the gardener, and tried to get him fired when they broke up,").also { stage++ }
|
||||
32 -> npcl("by killing all of the flowers in the garden. If her father ever found out she had done that he would be so furious he would probably disown her.").also { stage = END_DIALOGUE }
|
||||
|
||||
33 -> npcl("Oh Carol... she is such a fool. You didn't hear this from me, but I heard a while ago she was conned out of a lot of money by a travelling salesman who sold her a box full").also { stage++ }
|
||||
34 -> npcl("of beans by telling her they were magic. But they weren't. She sold some rare books from the library to cover her debts, but").also { stage++ }
|
||||
35 -> npcl("her father would be incredibly annoyed if he ever found out - he might even throw her out of the house!").also { stage = END_DIALOGUE }
|
||||
|
||||
36 -> npcl("Elizabeth? Elizabeth has a strange problem... She cannot help herself, but is always stealing small objects - it's pretty sad that she is rich enough to afford to buy things, but would rather steal them instead.").also { stage++ }
|
||||
37 -> npcl("Now, I don't want to spread stories, but I heard she even stole a silver needle from her father that had great sentimental value for him.").also { stage++ }
|
||||
38 -> npcl("He was devastated when it was lost, and cried for a week thinking he had lost it!").also { stage++ }
|
||||
39 -> npcl("If he ever found out that it was her who had stolen it he would go absolutely mental, maybe even disowning her!").also { stage = END_DIALOGUE }
|
||||
|
||||
40 -> npcl("Well, I guess it could have been an intruder, but with that big guard dog of theirs I seriously doubt it. I suspect it was someone closer to home...").also { stage ++ }
|
||||
41 -> npcl("Especially as I heard that the poison salesman in the Seers' village made a big sale to one of the family the other day.")
|
||||
.also { setAttribute(player!!, attributeNoiseClue, true)}
|
||||
.also { stage = END_DIALOGUE }
|
||||
|
||||
42 -> npcl("And I think you've been reading too many cheap detective novels. Hobbes is kind of uptight, but his loyalty to old Lord Sinclair is beyond question.").also { stage = END_DIALOGUE }
|
||||
|
||||
43 -> playerl("Think you could give me any hints?")
|
||||
.also { when (RandomFunction.random(4)) { //RS3 wiki seems to indicate this is fully random, not based off of progression
|
||||
0 -> stage = 44
|
||||
1 -> stage = 46
|
||||
2 -> stage = 47
|
||||
3 -> stage = 48
|
||||
4 -> stage = 51
|
||||
}
|
||||
}
|
||||
44 -> npcl("Well, I don't know if it's related, but I heard from that Poison Salesman in town that he sold some poison to one of the Sinclair family").also { stage++ }
|
||||
45 -> npcl("the other day. I don't think he has any stock left now though...").also { stage = END_DIALOGUE }
|
||||
|
||||
46 -> npcl("Well, I don't know how much help this is, but I heard their guard dog will bark loudly at anyone it doesn't recognise. Maybe you should find out if anyone heard anything suspicious?")
|
||||
.also { stage = END_DIALOGUE }
|
||||
|
||||
47 -> npcl("Well, this might be of some help to you. My father was in the guards when he was younger and he always said that there isn't a crime that can't be solved through careful examination of the crime scene and all surrounding areas.").also { stage = END_DIALOGUE }
|
||||
|
||||
48 -> npcl("I don't know how much help this is to you, but my dad was in the guard once and he told me the marks on your hands are totally unique. He calls them 'finger prints'.").also { stage++ }
|
||||
49 -> npcl("He said you can find them easily on any shiny metallic surface, by using a fine powder to mark out where the marks are and then using some sticky paper to lift the print from the object.").also { stage++ }
|
||||
50 -> npcl("I bet if you could find a way to get everyone's 'finger prints' you could solve the crime pretty easily!").also { stage = END_DIALOGUE }
|
||||
|
||||
51 -> npcl("My father used to be in the guard, he always wrote himself notes on a piece of paper so he could keep track of information easily.").also { stage++ }
|
||||
52 -> npcl("Maybe you should try that? Don't forget to thank me if I help you solve the case!").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeRandomMurderer
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.clueCount
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.solvedMystery
|
||||
import core.ServerConstants.Companion.SERVER_NAME
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class GuardDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, GuardDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return GuardDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.GUARD_812, NPCs.GUARD_6191)
|
||||
}
|
||||
}
|
||||
|
||||
class GuardDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
val KILLER = when (getAttribute(player!!, attributeRandomMurderer, 0)) {
|
||||
0 -> "Anna"
|
||||
1 -> "Bob"
|
||||
2 -> "Carol"
|
||||
3 -> "David"
|
||||
4 -> "Elizabeth"
|
||||
5 -> "Frank"
|
||||
else -> "Anna"
|
||||
}
|
||||
val POISONSPOT = when (getAttribute(player!!, attributeRandomMurderer, 0)) {
|
||||
0 -> "compost heap"
|
||||
1 -> "beehive"
|
||||
2 -> "drain"
|
||||
3 -> "spiders nest"
|
||||
4 -> "fountain"
|
||||
5 -> "Sinclair Crest"
|
||||
else -> "compost heap"
|
||||
}
|
||||
val KILLERMALE = when (getAttribute(player!!, attributeRandomMurderer, 0)) {
|
||||
1, 3, 5 -> true
|
||||
else -> false
|
||||
}
|
||||
val EVIDENCE = (1796..1822).toList().toIntArray() //All Murder Mystery related items are between these item ids
|
||||
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "What's going on here?").also { stage++ }
|
||||
1 -> npcl(FacialExpression.SAD, "Oh, it's terrible! Lord Sinclair has been murdered and we don't have any clues as to who or why. We're totally baffled!").also { stage++ }
|
||||
2 -> npcl(FacialExpression.SAD, "If you can help us we will be very grateful.").also { stage++ }
|
||||
3 -> options("Sure, I'll help.", "You should do your own dirty work.").also { stage++ }
|
||||
4 -> when (buttonID) {
|
||||
1 -> playerl(FacialExpression.HAPPY, "Sure, I'll help.").also { stage++ }
|
||||
2 -> playerl("You should do your own dirty work.").also { stage = 8 }
|
||||
}
|
||||
5 -> npcl(FacialExpression.HAPPY, "Thanks a lot!").also { stage++ }
|
||||
6 -> playerl(FacialExpression.NEUTRAL, "What should I be doing to help?").also { stage++ }
|
||||
7 -> npcl(FacialExpression.NEUTRAL, "Look around and investigate who might be responsible. The Sarge said every murder leaves clues to who done it, but frankly we're out of our depth here.")
|
||||
.also { setAttribute(player!!, attributeRandomMurderer, RandomFunction.random(5))}
|
||||
.also { setQuestStage(player!!, Quests.MURDER_MYSTERY, 1) }
|
||||
.also { stage = END_DIALOGUE }
|
||||
|
||||
8 -> npcl("Get lost then, this is private property! ...Unless you'd like to be taken in for questioning yourself?").also { stage = END_DIALOGUE }
|
||||
}
|
||||
1 -> when (stage) {
|
||||
0 -> options("What should I be doing to help again?", "How did Lord Sinclair die?", "I know who did it!").also { stage++ }
|
||||
1 -> when(buttonID) {
|
||||
1 -> playerl("What should I be doing to help?").also { stage = 2 }
|
||||
2 -> playerl("How did Lord Sinclair die?").also { stage = 3 }
|
||||
3 -> playerl(FacialExpression.HAPPY, "I know who did it!")
|
||||
.also {
|
||||
stage = if (solvedMystery(player!!)) 46
|
||||
else if (clueCount(player!!) == 1) {
|
||||
if (inInventory(player!!, Items.KILLERS_PRINT_1815)) {
|
||||
41
|
||||
}
|
||||
else if (getAttribute(player!!, attributePoisonClue,0) == 2) {
|
||||
37
|
||||
}
|
||||
else 33
|
||||
}
|
||||
else if (clueCount(player!!) > 1) 32
|
||||
else 6
|
||||
}
|
||||
}
|
||||
2 -> npcl("Look around and investigate who might be responsible. The Sarge said every murder leaves clues to who done it, but frankly we're out of our depth here.").also { stage = END_DIALOGUE }
|
||||
|
||||
3 -> npcl("Well, it's all very mysterious. Mary, the maid, found the body in the study next to his bedroom on the east wing of the ground floor.").also { stage++ }
|
||||
4 -> npcl("The door was found locked from the inside, and he seemed to have been stabbed, but there was an odd smell in the room. Frankly, I'm stumped.").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> npcl("Really? That was quick work! Who?").also { stage++ }
|
||||
6 -> options("It was an intruder!", "The butler did it!", "It was one of the servants!", "It was one of his family!").also { stage++ }
|
||||
7 -> when (buttonID) {
|
||||
1 -> playerl("It was an intruder!").also { stage = 10 }
|
||||
2 -> playerl("The butler did it!").also { stage = 8 }
|
||||
3 -> playerl("It was one of the servants!").also { stage = 13 }
|
||||
4 -> playerl("It was one of his family!").also { stage = 20 }
|
||||
}
|
||||
8 -> npcl("I hope you have proof to that effect. We have to arrest someone for this and it seems to me that only the actual murderer would gain by falsely accusing someone.").also { stage++ }
|
||||
9 -> npcl("Although having said that the butler is kind of shifty looking...").also { stage = END_DIALOGUE }
|
||||
|
||||
10 -> npcl("That's what we were thinking too. That someone broke in to steal something, was discovered by Lord Sinclair, stabbed him and ran.").also { stage++ }
|
||||
11 -> npcl("It's odd that apparently nothing was stolen though... Find out something has been stolen,").also { stage++ }
|
||||
12 -> npcl("and the case is closed, but the murdered man was a friend of the King and it's more than my job's worth not to investigate fully.").also { stage = END_DIALOGUE }
|
||||
|
||||
13 -> npcl("Oh really? Which one?").also { stage++ }
|
||||
14 -> options("It was one of the women.", "It was one of the men.").also { stage++ }
|
||||
15 -> when (buttonID) {
|
||||
1 -> playerl("It was one of the women.").also { stage = 16 }
|
||||
2 -> playerl("It was one of the men.").also { stage = 18 }
|
||||
}
|
||||
16 -> options("It was so obviously Louisa The Cook.", "It must have been Mary The Maid.").also { stage++ }
|
||||
17 -> when (buttonID) {
|
||||
1 -> playerl("It was so obviously Louisa The Cook.").also { stage = 27 }
|
||||
2 -> playerl("It must have been Mary The Maid.").also { stage = 27 }
|
||||
}
|
||||
|
||||
18 -> options("It can only be Donovan the Handyman.", "Pierre the Dog Handler. No question", "Hobbes the Butler. The butler *always* did it.", "You must know it was Stanford The Gardener.").also { stage++ }
|
||||
19-> when (buttonID) {
|
||||
1 -> playerl("It can only be Donovan the Handyman.").also { stage = 27 }
|
||||
2 -> playerl("Pierre the Dog Handler. No question.").also { stage = 27 }
|
||||
3 -> playerl("Hobbes the Butler. The butler *always* did it.").also { stage = 8 }
|
||||
4 -> playerl("You must know it was Stanford The Gardener.").also { stage = 27 }
|
||||
}
|
||||
|
||||
20 -> npcl("Oh really? Which one?").also { stage++ }
|
||||
21 -> options("It was one of the women.", "It was one of the men.").also { stage++ }
|
||||
22 -> when (buttonID) {
|
||||
1 -> playerl("It was one of the women.").also { stage = 23 }
|
||||
2 -> playerl("It was one of the men.").also { stage = 25 }
|
||||
}
|
||||
23 -> options("I know it was Anna.", "I am so sure it was Carol.", "I'll bet you anything it was Elizabeth.").also { stage++ }
|
||||
24 -> when (buttonID) {
|
||||
1 -> playerl("I know it was Anna.").also { stage = 27 }
|
||||
2 -> playerl("I am so sure it was Carol.").also { stage = 27 }
|
||||
3 -> playerl("I'll bet you anything it was Elizabeth.").also { stage = 27 }
|
||||
}
|
||||
25 -> options("I'm certain it was Bob.", "It was David. No doubt about it.", "If it wasn't Frank I'll eat my shoes.").also { stage++ }
|
||||
26 -> when (buttonID) {
|
||||
1 -> playerl("I'm certain it was Bob.").also { stage = 27 }
|
||||
2 -> playerl("It was David. No doubt about it.").also { stage = 27 }
|
||||
3 -> playerl("If it wasn't Frank I'll eat my shoes.").also { stage = 27 }
|
||||
}
|
||||
27 -> sendDialogue(player!!, "You tell the guard who you suspect of the crime.").also { stage++ }
|
||||
28 -> npcl("Great work, show me the evidence and we'll take them to the dungeons.").also { stage++ }
|
||||
29 -> npcl("You *DO* have evidence of their crime, right?").also { stage++ }
|
||||
30 -> playerl("Uh...").also { stage++ }
|
||||
31 -> npcl("Tch. You wouldn't last a day in the guards with sloppy thinking like that. Come see me when you have some proof of your accusations.").also { stage = END_DIALOGUE }
|
||||
|
||||
32 -> showTopics(
|
||||
IfTopic("I have proof that it wasn't any of the servants.", 33, inInventory(player!!, Items.CRIMINALS_THREAD_1808) || inInventory(player!!, Items.CRIMINALS_THREAD_1809) || inInventory(player!!, Items.CRIMINALS_THREAD_1810), true),
|
||||
IfTopic("I have proof one of the family lied about the poison.", 37, getAttribute(player!!, attributePoisonClue, 0) == 2, true),
|
||||
IfTopic("I have the finger prints of the culprit.", 41, inInventory(player!!, Items.KILLERS_PRINT_1815), true)
|
||||
)
|
||||
33 -> playerl("I have proof that it wasn't any of the servants!").also { stage++ }
|
||||
34 -> sendDialogue(player!!, "You show the guard the thread you found on the window.").also { stage ++ }
|
||||
35 -> playerl("All the servants dress in black so it couldn't have been one of them.").also { stage++ }
|
||||
36 -> npcl("That's some good work there. I guess it wasn't a servant. You still haven't proved who did do it though.").also { stage = END_DIALOGUE }
|
||||
|
||||
37 -> playerl("I have proof that $KILLER is lying about the poison.").also { stage++ }
|
||||
38 -> npcl("Oh really? How did you get that?").also { stage++ }
|
||||
39 -> sendDialogue(player!!, "You tell the guard about the " +
|
||||
when (getAttribute(player!!, attributeRandomMurderer, 0)) {
|
||||
4 -> "mosquitos at the fountain."
|
||||
5 -> "tarnished family crest."
|
||||
else -> "$POISONSPOT."
|
||||
}).also { stage++ }
|
||||
40 -> npcl("Hmm. That's some good detective work there, we need more evidence before we can close the case though. Keep up the good work.").also { stage = END_DIALOGUE }
|
||||
|
||||
41 -> playerl("I have the fingerprints of the culprit!").also { stage++ }
|
||||
42 -> playerl("I have $KILLER's fingerprints here, you can see for yourself they match the fingerprints on the murder weapon exactly.").also { stage++ }
|
||||
43 -> sendDialogue(player!!,"You show the guard the finger prints evidence.").also { stage++ }
|
||||
44 -> npcl("... I'm impressed. How on earth did you think of something like that? I've never heard of such a technique for finding criminals before!").also { stage++ }
|
||||
45 -> npcl("This will come in very handy in the future but we can't arrest someone on just this. I'm afraid you'll still need to find more evidence before we can close this case completely.").also { stage = END_DIALOGUE }
|
||||
|
||||
46 -> playerl(FacialExpression.HAPPY, "I have conclusive proof who the killer was.").also { stage++ }
|
||||
47 -> npcl(FacialExpression.HAPPY, "You do? That's excellent work. Let's hear it then.").also { stage++ }
|
||||
48 -> playerl("I don't think it was an intruder, and I don't think Lord Sinclair was killed by being stabbed.").also { stage++ }
|
||||
49 -> npcl("Hmmm? Really? Why not?").also { stage++ }
|
||||
50 -> playerl(FacialExpression.HAPPY, "Nobody heard the guard dog barking, which it would have if it had been an intruder who was responsible.").also { stage++ }
|
||||
51 -> playerl("Nobody heard any signs of a struggle either. I think the knife was there to throw suspicion away from the real culprit.").also { stage++ }
|
||||
52 -> npcl("Yes, that makes sense. But who did do it then?").also { stage++ }
|
||||
53 -> sendDialogue(player!!, "You prove to the guard the thread matches $KILLER's clothes.").also { stage++ }
|
||||
54 -> npcl("Yes, I'd have to agree with that... but we need more evidence!").also { stage++ }
|
||||
55 -> sendDialogue(player!!, "You prove to the guard $KILLER did not use the poison on the $POISONSPOT.").also { stage++ }
|
||||
56 -> npcl("Excellent work - have you considered a career as a detective? But I'm afraid it's still not quite enough...").also { stage++ }
|
||||
57 -> sendDialogue(player!!, "You match $KILLER's finger prints with those on the dagger found in the body of Lord Sinclair.").also { stage++ }
|
||||
58 -> npcl(FacialExpression.HAPPY, "Yes. There's no doubt about it. It must have been $KILLER who killed " + if (KILLERMALE) {"his"} else {"her"} + " father. All of the guards must congratulate you on your excellent work in helping us to solve this case.").also { stage++ }
|
||||
59 -> npcl("We don't have many murders here in $SERVER_NAME and I'm afraid we wouldn't have been able to solve it by ourselves. We will hold " + if (KILLERMALE) {"him"} else {"her"} + " here under house arrest until such time as we bring " + if (KILLERMALE) {"him"} else {"her"} + " to trial.").also { stage++ }
|
||||
60 -> npcl("You have our gratitude, and I'm sure the rest of the family's as well, in helping to apprehend the murderer. I'll just take the evidence from you now.").also { stage++ }
|
||||
61 -> sendDialogue(player!!, "You hand over all the evidence.").also { stage++ }
|
||||
62 -> npcl(FacialExpression.HAPPY, "Please accept this reward from the family!").also { stage++ }
|
||||
63 -> finishQuest(player!!, Quests.MURDER_MYSTERY)
|
||||
.also {
|
||||
player!!.inventory.removeAll(EVIDENCE)
|
||||
player!!.bank.removeAll(EVIDENCE)
|
||||
player!!.equipment.removeAll(EVIDENCE)
|
||||
}
|
||||
.also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> when (stage) {
|
||||
0 -> npcl("Excellent work on solving the murder! All of the guards I know are very impressed, and don't worry, we have the murderer under guard until they can be taken to trial.").also { stage++ }
|
||||
1 -> playerl("Is there anything else I can do? Seems awfully quiet up at the house, considering their sibling has just been arrested.").also { stage++ }
|
||||
2 -> npcl("Nothing right now, we have it all under control.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class HobbesDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, HobbesDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return HobbesDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.HOBBES_808)
|
||||
}
|
||||
}
|
||||
|
||||
class HobbesDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> npcl("This is private property! Please leave!").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you at the time of the murder?", 6),
|
||||
IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)),
|
||||
IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
|
||||
3 -> npcl("Well, in my considered opinion it must be David. The man is nothing more than a bully And I happen to know that poor Lord Sinclair and David had a massive argument in the living").also { stage++ }
|
||||
4 -> npcl("room about the way he treats the staff, the other day. I did not intend to overhear their conversation, but they were shouting so loudly I could not help but Overhear it. David definitely used the words").also { stage++ }
|
||||
5 -> npcl("'I am going to kill you!' as well. I think he should be the prime suspect. He has a nasty temper that one.").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> npcl("I was assisting the cook with the evening meal. I gave Mary His Lordships' dinner, and sent her to take it to him, then heard the scream as she found the body.").also { stage = END_DIALOGUE }
|
||||
|
||||
7 -> npcl("How do you mean 'suspicious'?").also { stage++ }
|
||||
8 -> playerl("Any sounds of a struggle with Lord Sinclair?").also { stage++ }
|
||||
9 -> npcl("No, I definitely didn't hear anything like that.").also { stage++ }
|
||||
10 -> playerl("How about the guard dog barking at all?").also { stage++ }
|
||||
11 -> npcl("You know, now you come to mention it I don't believe I did. I suppose that is Proof enough that it could not have been an intruder who is responsible.").also { stage = END_DIALOGUE }
|
||||
|
||||
12 -> npcl("Well, I do know that Elizabeth was extremely annoyed by the mosquito nest under the fountain in the garden, and was going to do something about it. I suspect any poison she bought would have been").also { stage++ }
|
||||
13 -> npcl ("enough to get rid of it. A Good job, too. I hate mosquitos.").also { stage++ }
|
||||
14 -> playerl("Yeah, so do I.").also { stage++ }
|
||||
15 -> npcl("You'd really have to ask her though.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class LouisaDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, LouisaDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return LouisaDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.LOUISA_809)
|
||||
}
|
||||
}
|
||||
|
||||
class LouisaDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> npcl("I'm far too upset to talk to random people right now.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you at the time of the murder?", 6),
|
||||
IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)),
|
||||
IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
|
||||
3 -> npcl("Elizabeth.").also { stage ++ }
|
||||
4 -> npcl("Her father confronted her about her constant petty thieving, and was devastated to find she had stolen a silver needle which had meant a lot to him.").also { stage++ }
|
||||
5 -> npcl("You could hear their argument from Lumbridge!").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> npcl("I was right here with Hobbes and Mary. You can't suspect me surely!").also { stage = END_DIALOGUE }
|
||||
|
||||
7 -> npcl("Suspicious? What do you mean suspicious?").also { stage++ }
|
||||
8 -> playerl("Any sounds of a struggle with an intruder for example?").also { stage++ }
|
||||
9 -> npcl("No, I'm sure I don't recall any such thing.").also { stage++ }
|
||||
10 -> playerl("How about the guard dog barking at an intruder?").also { stage++ }
|
||||
11 -> npcl("No, I didn't. If you don't have anything else to ask can You go and leave me alone now? I have a lot of cooking to do for this evening.").also { stage = END_DIALOGUE }
|
||||
|
||||
12 -> npcl("I told Carol to buy some from that strange poison salesman and clean the drains before they began to smell any worse. She was the one who blocked them in the first place with a load").also { stage++ }
|
||||
13 -> npcl("of beans that she bought for some reason. There were far too many to eat, and they were almost rotten when she bought them anyway! You'd really have to ask her though.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class MaryDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, MaryDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return MaryDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.MARY_810)
|
||||
}
|
||||
}
|
||||
|
||||
class MaryDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> sendDialogue(player!!, "They are ignoring you.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you at the time of the murder?", 5),
|
||||
IfTopic("Did you hear any suspicious noises at all?", 7, getAttribute(player!!, attributeNoiseClue, false)),
|
||||
IfTopic("Do you know why so much poison was bought recently?", 12, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
|
||||
3 -> npcl("Oh I don't know... Frank was acting kind of funny... After that big argument him and the Lord had the other day by the beehive... so").also { stage ++ }
|
||||
4 -> npcl("I guess maybe him... but it's really scary to think someone here might have been responsible. I actually hope it was a burglar...").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> npcl("I was with Hobbes and Louisa in the Kitchen helping to prepare Lord Sinclair's meal, and then when I took it to his study... I saw... oh, it was horrible... he was...").also { stage++ }
|
||||
6 -> sendDialogue(player!!, "She seems to be on the verge of crying. You decide not to push her anymore for details.").also { stage = END_DIALOGUE}
|
||||
|
||||
7 -> npcl("I don't really remember hearing anything out of the ordinary.").also { stage++ }
|
||||
8 -> playerl("No sounds of a struggle then?").also { stage++ }
|
||||
9 -> npcl("No, I don't remember hearing anything like that.").also { stage++ }
|
||||
10 -> playerl("How about the guard dog barking?").also { stage++ }
|
||||
11 -> npcl("Oh that horrible dog is always barking at noting but I don't think I did...").also { stage = END_DIALOGUE }
|
||||
|
||||
12 -> npcl("I overheard Anna saying to Stanford that if he didn't do something about the state of his compost heap, she was going to.").also { stage++ }
|
||||
13 -> npcl("She really doesn't get on well with Stanford, I really have no idea why. You'd really have to ask her though.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.link.quest.Quest
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Items
|
||||
|
||||
// https://www.youtube.com/watch?v=f1Eou5i5hBo at 2:29
|
||||
// https://www.youtube.com/watch?v=BwO4JhZdQKo at 25:20
|
||||
// https://www.youtube.com/watch?v=u5Osw_jas4A at 26:35
|
||||
// https://www.youtube.com/watch?v=f1Eou5i5hBo
|
||||
// https://www.youtube.com/watch?v=9Q2aLUg44SQ at 10:02
|
||||
// https://www.youtube.com/watch?v=_lTUessdfOM 6:18
|
||||
|
||||
/**
|
||||
* Murder Mystery Quest
|
||||
*/
|
||||
@Initializable
|
||||
class MurderMystery : Quest(Quests.MURDER_MYSTERY, 93, 92, 3, 192, 0, 1, 2) {
|
||||
|
||||
companion object {
|
||||
const val questName = "Murder Mystery"
|
||||
|
||||
const val attributeRandomMurderer = "/save:quest:murdermystery-randommurderer" //Alphabetical, 0 for Anna, 1 for Bob, 2 for Carol, 3 for David, 4 for Elizabeth, 5 for Frank
|
||||
const val attributeTakenThread = "/save:quest:murdermystery-takenthread" //true after taking thread for the first time from window
|
||||
const val attributeNoiseClue = "/save:quest:murdermystery-noiseclue" //true on learning of the barking dog for the first time
|
||||
const val attributePoisonClue = "/save:quest:murdermystery-poisonclue" //1 after learning poison was bought, 2 after finding liar
|
||||
const val attributeAskPoisonAnna = "/save:quest:murdermystery-askpoisonanna" //true after asking Anna about poison
|
||||
const val attributeAskPoisonBob = "/save:quest:murdermystery-askpoisonbob" //true after asking Bob about poison
|
||||
const val attributeAskPoisonCarol = "/save:quest:murdermystery-askpoisoncarol" //true after asking Carol about poison
|
||||
const val attributeAskPoisonDavid = "/save:quest:murdermystery-askpoisondavid" //true after asking David about poison
|
||||
const val attributeAskPoisonElizabeth = "/save:quest:murdermystery-askpoisonelizabeth" //true after asking Elizabeth about poison
|
||||
const val attributeAskPoisonFrank = "/save:quest:murdermystery-askpoisonfrank" //true after asking Anna about poison
|
||||
|
||||
fun clueCount(player: Player) : Int {
|
||||
var count = 0
|
||||
if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) {
|
||||
count++
|
||||
}
|
||||
if (inInventory(player, Items.KILLERS_PRINT_1815)) {
|
||||
count ++
|
||||
}
|
||||
if (getAttribute(player, attributePoisonClue,0) == 2) {
|
||||
count ++
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
fun solvedMystery(player: Player) : Boolean {
|
||||
return (
|
||||
( inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810) )
|
||||
&& inInventory(player, Items.KILLERS_PRINT_1815)
|
||||
&& getAttribute(player, attributePoisonClue,0) == 2
|
||||
&& getAttribute(player, attributeNoiseClue, false)
|
||||
)
|
||||
}
|
||||
}
|
||||
override fun drawJournal(player: Player, stage: Int) {
|
||||
super.drawJournal(player, stage)
|
||||
var line = 12
|
||||
var stage = getStage(player)
|
||||
|
||||
var started = getQuestStage(player, Quests.MURDER_MYSTERY) > 0
|
||||
|
||||
if (!started) {
|
||||
line(player, "I can start this quest by speaking to one of the !!Guards?? at", line++, false)
|
||||
line(player, "the !!Sinclair Mansion??, North of the !!Seer's Village??.", line++, false)
|
||||
} else if (stage < 100) {
|
||||
line(player, "Lord Sinclair, a prominent nobleman, had been horribly", line++, true)
|
||||
line(player, "murdered at his mansion. The guards had been sent to", line++, true)
|
||||
line(player, "investigate his murder, but have been completely stuck.", line++, true)
|
||||
|
||||
if (solvedMystery(player)) {
|
||||
line(player, "One of the guards asked me for my help in solving the", line++, true)
|
||||
line(player, "murder. After careful examination of the crime scene and", line++, true)
|
||||
line(player, "interrogating all suspects, I worked out who was guilty.", line++, true)
|
||||
} else {
|
||||
line(player, "One of the !!guards?? has asked me for my help in solving the", line++, false)
|
||||
line(player, "murder. I should !!examine the crime scene?? very closely for", line++, false)
|
||||
line(player, "evidence, and !!interrogate everybody?? in the area carefully.", line++, false)
|
||||
}
|
||||
|
||||
// This may not be a stage but an attribute when all the evidence is collected.
|
||||
if (solvedMystery(player)) {
|
||||
line(player, "I have !!indisputable evidence?? of who the murderer must be.", line++, false)
|
||||
line(player, "I should take it to one of the !!Guards?? immediately.", line++, false)
|
||||
} else {
|
||||
line++
|
||||
if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) {
|
||||
line(player, "I have found some !!coloured thread??. It might be useful.", line++, false)
|
||||
}
|
||||
if (inInventory(player, Items.CRIMINALS_DAGGER_1813) || inInventory(player, Items.CRIMINALS_DAGGER_1814)) {
|
||||
line(player, "I have taken the !!murder weapon??. I think it might help me.", line++, false)
|
||||
}
|
||||
if (inInventory(player, Items.PUNGENT_POT_1812)) {
|
||||
line(player, "I have a !!strange smelling pot??. It seems like a clue.", line++, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
line(player, "One of the guards asked me for my help in solving the", line++, true)
|
||||
line(player, "murder. After careful examination of the crime scene and", line++, true)
|
||||
line(player, "interrogating all suspects, I worked out who was guilty.", line++, true)
|
||||
line(player, "I took the evidence I had collected to the Guards and", line++, true)
|
||||
line(player, "explained how it could identify the killer. Impressed", line++, true)
|
||||
line(player, "with my deductions, the killer was arrested and I was", line++, true)
|
||||
line(player, "given a fair reward for my help in solving the crime.", line++, true)
|
||||
line++
|
||||
line(player,"<col=FF0000>QUEST COMPLETE!</col>", line)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun reset(player: Player) {
|
||||
removeAttribute(player, attributeRandomMurderer)
|
||||
removeAttribute(player, attributeNoiseClue)
|
||||
removeAttribute(player, attributePoisonClue)
|
||||
removeAttribute(player, attributeTakenThread)
|
||||
removeAttribute(player, attributeAskPoisonAnna)
|
||||
removeAttribute(player, attributeAskPoisonBob)
|
||||
removeAttribute(player, attributeAskPoisonCarol)
|
||||
removeAttribute(player, attributeAskPoisonDavid)
|
||||
removeAttribute(player, attributeAskPoisonElizabeth)
|
||||
removeAttribute(player, attributeAskPoisonFrank)
|
||||
}
|
||||
|
||||
override fun finish(player: Player) {
|
||||
var ln = 10
|
||||
super.finish(player)
|
||||
player.packetDispatch.sendString("You have completed the Murder Mystery quest!", 277, 4)
|
||||
player.packetDispatch.sendItemZoomOnInterface(Items.COINS_617, 230, 277, 5)
|
||||
|
||||
drawReward(player, "3 Quest Points", ln++)
|
||||
drawReward(player, "2000 coins", ln++)
|
||||
drawReward(player, "1406 Crafting XP", ln++)
|
||||
|
||||
addItem(player, Items.COINS_995, 2000)
|
||||
rewardXP(player, Skills.CRAFTING, 1406.0)
|
||||
|
||||
removeAttribute(player, attributeNoiseClue)
|
||||
removeAttribute(player, attributePoisonClue)
|
||||
removeAttribute(player, attributeTakenThread)
|
||||
removeAttribute(player, attributeAskPoisonAnna)
|
||||
removeAttribute(player, attributeAskPoisonBob)
|
||||
removeAttribute(player, attributeAskPoisonCarol)
|
||||
removeAttribute(player, attributeAskPoisonDavid)
|
||||
removeAttribute(player, attributeAskPoisonElizabeth)
|
||||
removeAttribute(player, attributeAskPoisonFrank)
|
||||
}
|
||||
|
||||
override fun newInstance(`object`: Any?): Quest {
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonAnna
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonBob
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonCarol
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonDavid
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonElizabeth
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeAskPoisonFrank
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeRandomMurderer
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeTakenThread
|
||||
import core.api.*
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.item.GroundItem
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class MurderMysteryListeners : InteractionListener {
|
||||
companion object {
|
||||
val UNDUSTEDEVIDENCE = intArrayOf(
|
||||
Items.CRIMINALS_DAGGER_1813,
|
||||
Items.PUNGENT_POT_1812,
|
||||
Items.SILVER_NECKLACE_1796,
|
||||
Items.SILVER_CUP_1798,
|
||||
Items.SILVER_BOTTLE_1800,
|
||||
Items.SILVER_BOOK_1802,
|
||||
Items.SILVER_NEEDLE_1804,
|
||||
Items.SILVER_POT_1806
|
||||
)
|
||||
val DUSTEDEVIDENCE = intArrayOf(
|
||||
Items.CRIMINALS_DAGGER_1814,
|
||||
Items.SILVER_NECKLACE_1797,
|
||||
Items.SILVER_CUP_1799,
|
||||
Items.SILVER_BOTTLE_1801,
|
||||
Items.SILVER_BOOK_1803,
|
||||
Items.SILVER_NEEDLE_1805,
|
||||
Items.SILVER_POT_1807
|
||||
)
|
||||
val SILVERBARRELS = intArrayOf(
|
||||
Scenery.ANNA_S_BARREL_2656,
|
||||
Scenery.BOB_S_BARREL_2657,
|
||||
Scenery.CAROL_S_BARREL_2658,
|
||||
Scenery.DAVID_S_BARREL_2659,
|
||||
Scenery.ELIZABETH_S_BARREL_2660,
|
||||
Scenery.FRANK_S_BARREL_2661
|
||||
)
|
||||
val POISONSPOTS = intArrayOf(
|
||||
Scenery.SINCLAIR_FAMILY_COMPOST_HEAP_26120,
|
||||
Scenery.SINCLAIR_FAMILY_BEEHIVE_26121,
|
||||
Scenery.SINCLAIR_MANSION_DRAIN_2843,
|
||||
Scenery.SPIDERS__NEST_26109,
|
||||
Scenery.SINCLAIR_FAMILY_FOUNTAIN_2654,
|
||||
Scenery.SINCLAIR_FAMILY_CREST_2655
|
||||
)
|
||||
val SUSPECTPRINTS = intArrayOf(
|
||||
Items.ANNAS_PRINT_1816,
|
||||
Items.BOBS_PRINT_1817,
|
||||
Items.CAROLS_PRINT_1818,
|
||||
Items.DAVIDS_PRINT_1819,
|
||||
Items.ELIZABETHS_PRINT_1820,
|
||||
Items.FRANKS_PRINT_1821
|
||||
)
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Items.CRIMINALS_DAGGER_1813, GROUNDITEM, "take") { player, groundItem ->
|
||||
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
|
||||
1 -> {
|
||||
if (inInventory(player, Items.CRIMINALS_DAGGER_1813) || inInventory(player, Items.CRIMINALS_DAGGER_1814)) {
|
||||
sendDialogue(player, "I already have the murder weapon.")
|
||||
}
|
||||
else if (addItem(player, Items.CRIMINALS_DAGGER_1813)) {
|
||||
removeGroundItem(groundItem as GroundItem)
|
||||
sendDialogue(player, "This knife doesn't seem sturdy enough to have killed Lord Sinclair.")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
else -> {
|
||||
sendDialogue(player, "You need the guards' permission to do that.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
on(Items.PUNGENT_POT_1812, GROUNDITEM, "take") { player, groundItem ->
|
||||
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
|
||||
1 -> {
|
||||
if (inInventory(player, Items.PUNGENT_POT_1812)) {
|
||||
sendDialogue(player, "I already have the poisoned pot.")
|
||||
} else if (addItem(player, Items.PUNGENT_POT_1812)) {
|
||||
removeGroundItem(groundItem as GroundItem)
|
||||
sendDialogue(player, "It seems like Lord Sinclair was drinking from this before he died.")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
else -> {
|
||||
sendDialogue(player, "You need the guards' permission to do that.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
on(intArrayOf(Scenery.STURDY_WOODEN_GATE_2664, Scenery.STURDY_WOODEN_GATE_2665), SCENERY, "investigate") { player, _ ->
|
||||
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
|
||||
1 -> {
|
||||
sendDialogue(player, "As you approach the gate the guard dog starts barking loudly at you. There is no way an intruder could have committed the murder. It must have been someone the dog knew to get past it quietly.")
|
||||
setAttribute(player, attributeNoiseClue, true)
|
||||
return@on true
|
||||
}
|
||||
else -> {
|
||||
sendDialogue(player, "You need the guards' permission to do that.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
on(Scenery.SMASHED_WINDOW_26110, SCENERY, "investigate") { player, _ ->
|
||||
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
|
||||
1 -> {
|
||||
sendDialogue(player, "Some thread seems to have been caught on a loose nail on the window.")
|
||||
if (inInventory(player, Items.CRIMINALS_THREAD_1808) || inInventory(player, Items.CRIMINALS_THREAD_1809) || inInventory(player, Items.CRIMINALS_THREAD_1810)) {
|
||||
sendMessage(player, "You have already taken the thread.")
|
||||
}
|
||||
else if (getAttribute(player, attributeTakenThread, false)) {
|
||||
if (hasSpaceFor(player, Item(Items.CRIMINALS_THREAD_1808))) {
|
||||
when (getAttribute(player, attributeRandomMurderer, 0)) {
|
||||
1, 2 -> addItem(player, Items.CRIMINALS_THREAD_1808)
|
||||
0, 3 -> addItem(player, Items.CRIMINALS_THREAD_1809)
|
||||
else -> addItem(player, Items.CRIMINALS_THREAD_1810)
|
||||
}
|
||||
sendMessage(player, "Lucky for you there's some thread left. You should be less careless in the future.")
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (hasSpaceFor(player, Item(Items.CRIMINALS_THREAD_1808))) {
|
||||
when (getAttribute(player, attributeRandomMurderer, 0)) {
|
||||
1, 2 -> addItem(player, Items.CRIMINALS_THREAD_1808)
|
||||
0, 3 -> addItem(player, Items.CRIMINALS_THREAD_1809)
|
||||
else -> addItem(player, Items.CRIMINALS_THREAD_1810)
|
||||
}
|
||||
sendMessage(player, "You take the thread.")
|
||||
setAttribute(player, attributeTakenThread, true)
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
else -> {
|
||||
sendDialogue(player, "You need the guards' permission to do that.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
on(Scenery.SMASHED_WINDOW_26110, SCENERY, "break") { player, _ ->
|
||||
sendDialogue(player, "You don't want to damage evidence!")
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.SACKS_2663, SCENERY, "investigate") { player, _ ->
|
||||
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
|
||||
1 -> {
|
||||
openDialogue(player, FlypaperDialogue())
|
||||
return@on true
|
||||
}
|
||||
else -> {
|
||||
sendDialogue(player, "You need the guards' permission to do that.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
on(SILVERBARRELS, SCENERY, "search") { player, node ->
|
||||
when (getQuestStage(player, Quests.MURDER_MYSTERY)) {
|
||||
1 -> {
|
||||
when (node.id) {
|
||||
Scenery.ANNA_S_BARREL_2656 -> {
|
||||
if (inInventory(player, Items.SILVER_NECKLACE_1796) || inInventory(player, Items.SILVER_NECKLACE_1797)) {
|
||||
sendDialogue(player, "I already have Anna's Necklace.")
|
||||
}
|
||||
else if (addItem(player, Items.SILVER_NECKLACE_1796)){
|
||||
sendDialogue(player, "There's something shiny hidden at the bottom. You take Anna's Silver Necklace.")
|
||||
}
|
||||
}
|
||||
Scenery.BOB_S_BARREL_2657 -> {
|
||||
if (inInventory(player, Items.SILVER_CUP_1798) || inInventory(player, Items.SILVER_CUP_1799)) {
|
||||
sendDialogue(player, "I already have Bob's cup.")
|
||||
}
|
||||
else if (addItem(player, Items.SILVER_CUP_1798)){
|
||||
sendDialogue(player, "There's something shiny hidden at the bottom. You take Bob's silver cup.")
|
||||
}
|
||||
}
|
||||
Scenery.CAROL_S_BARREL_2658 -> {
|
||||
if (inInventory(player, Items.SILVER_BOTTLE_1800) || inInventory(player, Items.SILVER_BOTTLE_1801)) {
|
||||
sendDialogue(player, "I already have Carol's bottle.")
|
||||
}
|
||||
else if (addItem(player, Items.SILVER_BOTTLE_1800)){
|
||||
sendDialogue(player, "There's something shiny hidden at the bottom. You take Carol's silver bottle.")
|
||||
}
|
||||
}
|
||||
Scenery.DAVID_S_BARREL_2659 -> {
|
||||
if (inInventory(player, Items.SILVER_BOOK_1802) || inInventory(player, Items.SILVER_BOOK_1803)) {
|
||||
sendDialogue(player, "I already have David's book.")
|
||||
}
|
||||
else if (addItem(player, Items.SILVER_BOOK_1802)){
|
||||
sendDialogue(player, "There's something shiny hidden at the bottom. You take David's silver book.")
|
||||
}
|
||||
}
|
||||
Scenery.ELIZABETH_S_BARREL_2660 -> {
|
||||
if (inInventory(player, Items.SILVER_NEEDLE_1804) || inInventory(player, Items.SILVER_NEEDLE_1805)) {
|
||||
sendDialogue(player, "I already have Elizabeth's Needle.")
|
||||
}
|
||||
else if (addItem(player, Items.SILVER_NEEDLE_1804)){
|
||||
sendDialogue(player, "There's something shiny hidden at the bottom. You take Elizabeth's silver needle.")
|
||||
}
|
||||
}
|
||||
Scenery.FRANK_S_BARREL_2661 -> {
|
||||
if (inInventory(player, Items.SILVER_POT_1806) || inInventory(player, Items.SILVER_POT_1807)) {
|
||||
sendDialogue(player, "I already have Frank's pot.")
|
||||
}
|
||||
else if (addItem(player, Items.SILVER_POT_1806)){
|
||||
sendDialogue(player, "There's something shiny hidden at the bottom. You take Frank's silver pot.")
|
||||
}
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
else -> {
|
||||
sendDialogue(player, "You need the guards' permission to do that.")
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
on(POISONSPOTS, SCENERY, "investigate") { player, node ->
|
||||
when (node.id) {
|
||||
Scenery.SINCLAIR_FAMILY_COMPOST_HEAP_26120 -> {
|
||||
if (!getAttribute(player, attributeAskPoisonAnna, false)) {
|
||||
sendDialogue(player, "It's a heap of compost.")
|
||||
}
|
||||
else if (getAttribute(player, attributeRandomMurderer, 0) == 0) {
|
||||
sendDialogue(player, "The compost is teeming with maggots. Somebody should really do something about it. It's certainly clear nobody's used poison here.")
|
||||
setAttribute(player, attributePoisonClue, 2)
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "There is a faint smell of poison behind the smell of the compost.")
|
||||
}
|
||||
}
|
||||
Scenery.SINCLAIR_FAMILY_BEEHIVE_26121 -> {
|
||||
if (!getAttribute(player, attributeAskPoisonBob, false)) {
|
||||
sendDialogue(player, "It's a very old beehive.")
|
||||
}
|
||||
else if (getAttribute(player, attributeRandomMurderer, 0) == 1) {
|
||||
sendDialogue(player, "The beehive buzzes with activity. These bees definitely don't seem poisoned at all.")
|
||||
setAttribute(player, attributePoisonClue, 2)
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "The hive is empty. There are a few dead bees and a faint smell of poison.")
|
||||
}
|
||||
}
|
||||
Scenery.SINCLAIR_MANSION_DRAIN_2843 -> {
|
||||
if (!getAttribute(player, attributeAskPoisonCarol, false)) {
|
||||
sendDialogue(player, "It's the drains from the kitchen.")
|
||||
}
|
||||
else if (getAttribute(player, attributeRandomMurderer, 0) == 2) {
|
||||
sendDialogue(player, "The drain is totally blocked. It really stinks. No, it REALLY smells bad. It's certainly clear nobody's cleaned it recently.")
|
||||
setAttribute(player, attributePoisonClue, 2)
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "The drain seems to have been recently cleaned. You can still smell the faint aroma of poison.")
|
||||
}
|
||||
}
|
||||
Scenery.SPIDERS__NEST_26109 -> {
|
||||
if (!getAttribute(player, attributeAskPoisonDavid, false)) {
|
||||
sendDialogue(player, "It looks like a spiders' nest of some kind...")
|
||||
}
|
||||
else if (getAttribute(player, attributeRandomMurderer, 0) == 3) {
|
||||
sendDialogue(player, "There is a spiders' nest here. You estimate there must be at least a few hundred spiders ready to hatch. It's certainly clear nobody's used poison here.")
|
||||
setAttribute(player, attributePoisonClue, 2)
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "A faint smell of poison and a few dead spiders is all that remains of the spiders nest.")
|
||||
}
|
||||
}
|
||||
Scenery.SINCLAIR_FAMILY_FOUNTAIN_2654 -> {
|
||||
if (!getAttribute(player, attributeAskPoisonElizabeth, false)) {
|
||||
sendDialogue(player, "A fountain with large numbers of insects around the base.")
|
||||
}
|
||||
else if (getAttribute(player, attributeRandomMurderer, 0) == 4) {
|
||||
openDialogue(player, FountainDialogue())
|
||||
setAttribute(player, attributePoisonClue, 2)
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "There are a lot of dead mosquitos around the base of the fountain. A faint smell of poison is in the air, but the water seems clean.")
|
||||
}
|
||||
}
|
||||
Scenery.SINCLAIR_FAMILY_CREST_2655 -> {
|
||||
if (!getAttribute(player, attributeAskPoisonFrank, false)) {
|
||||
sendDialogue(player, "The Sinclair Family Crest is hung up here.")
|
||||
}
|
||||
else if (getAttribute(player, attributeRandomMurderer, 0) == 5) {
|
||||
sendDialogue(player, "It looks like the Sinclair family crest but it is very dirty. You can barely make it out under all of the grime. It's certainly clear nobody's cleaned it recently.")
|
||||
setAttribute(player, attributePoisonClue, 2)
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "The Sinclair family crest. It's shiny and freshly polished and has a slight smell of poison.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
onUseWith(ITEM, UNDUSTEDEVIDENCE, Items.POT_OF_FLOUR_1933) { player, used, _ ->
|
||||
when (used.id) {
|
||||
Items.CRIMINALS_DAGGER_1813 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.CRIMINALS_DAGGER_1814)
|
||||
sendMessage(player, "You sprinkle a small amount of flour on the murder weapon.")
|
||||
sendMessage(player, "The murder weapon is now coated with a thin layer of flour.")
|
||||
}
|
||||
Items.PUNGENT_POT_1812 -> {
|
||||
sendMessage(player, "You sprinkle a small amount of flour on the strange smelling pot.")
|
||||
sendMessage(player, "The surface isn't shiny enough to take a fingerprint from.")
|
||||
}
|
||||
Items.SILVER_NECKLACE_1796 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_NECKLACE_1797)
|
||||
sendMessage(player, "You sprinkle the flour on Anna's necklace.")
|
||||
sendMessage(player, "The necklace is now coated with a thin layer of flour.")
|
||||
}
|
||||
Items.SILVER_CUP_1798 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_CUP_1799)
|
||||
sendMessage(player, "You sprinkle the flour on Bob's cup.")
|
||||
sendMessage(player, "The cup is now coated with a thin layer of flour.")
|
||||
}
|
||||
Items.SILVER_BOTTLE_1800 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_BOTTLE_1801)
|
||||
sendMessage(player, "You sprinkle the flour on Carol's bottle.")
|
||||
sendMessage(player, "The bottle is now coated with a thin layer of flour.")
|
||||
}
|
||||
Items.SILVER_BOOK_1802 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_BOOK_1803)
|
||||
sendMessage(player, "You sprinkle the flour on David's book.")
|
||||
sendMessage(player, "The Book is now coated with a thin layer of flour.")
|
||||
}
|
||||
Items.SILVER_NEEDLE_1804 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_NEEDLE_1805)
|
||||
sendMessage(player, "You sprinkle the flour on Elizabeth's needle.")
|
||||
sendMessage(player, "The Needle is now coated with a thin layer of flour.")
|
||||
}
|
||||
Items.SILVER_POT_1806 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_POT_1807)
|
||||
sendMessage(player, "You sprinkle the flour on Frank's pot")
|
||||
sendMessage(player, "The Pot is now coated with a thin layer of flour.")
|
||||
}
|
||||
}
|
||||
removeItem(player, Items.POT_OF_FLOUR_1933)
|
||||
addItem(player, Items.EMPTY_POT_1931)
|
||||
return@onUseWith true
|
||||
}
|
||||
onUseWith(ITEM, DUSTEDEVIDENCE, Items.FLYPAPER_1811) { player, used, _ ->
|
||||
removeItem(player, Items.FLYPAPER_1811)
|
||||
when (used.id) {
|
||||
Items.CRIMINALS_DAGGER_1814 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.CRIMINALS_DAGGER_1813)
|
||||
addItem(player, Items.UNKNOWN_PRINT_1822)
|
||||
sendMessage(player, "You use the flypaper on the floury dagger.")
|
||||
sendMessage(player, "You have a clean impression of the murderer's finger prints.")
|
||||
}
|
||||
Items.SILVER_NECKLACE_1797 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_NECKLACE_1796)
|
||||
addItem(player, Items.ANNAS_PRINT_1816)
|
||||
sendMessage(player, "You use the flypaper on the flour covered necklace.")
|
||||
sendMessage(player, "You have a clean impression of Anna's finger prints.")
|
||||
}
|
||||
Items.SILVER_CUP_1799 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_CUP_1798)
|
||||
addItem(player, Items.BOBS_PRINT_1817)
|
||||
sendMessage(player, "You use the flypaper on the flour covered cup.")
|
||||
sendMessage(player, "You have a clean impression of Bob's finger prints.")
|
||||
}
|
||||
Items.SILVER_BOTTLE_1801 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_BOTTLE_1800)
|
||||
addItem(player, Items.CAROLS_PRINT_1818)
|
||||
sendMessage(player, "You use the flypaper on the flour covered bottle.")
|
||||
sendMessage(player, "You have a clean impression of Carol's finger prints.")
|
||||
}
|
||||
Items.SILVER_BOOK_1803 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_BOOK_1802)
|
||||
addItem(player, Items.DAVIDS_PRINT_1819)
|
||||
sendMessage(player, "You use the flypaper on the flour covered book.")
|
||||
sendMessage(player, "You have a clean impression of David's finger prints.")
|
||||
}
|
||||
Items.SILVER_NEEDLE_1805 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_NEEDLE_1804)
|
||||
addItem(player, Items.ELIZABETHS_PRINT_1820)
|
||||
sendMessage(player, "You use the flypaper on the flour covered needle.")
|
||||
sendMessage(player, "You have a clean impression of Elizabeth's finger prints.")
|
||||
}
|
||||
Items.SILVER_POT_1807 -> {
|
||||
removeItem(player, used)
|
||||
addItem(player, Items.SILVER_POT_1806)
|
||||
addItem(player, Items.FRANKS_PRINT_1821)
|
||||
sendMessage(player, "You use the flypaper on the flour covered pot.")
|
||||
sendMessage(player, "You have a clean impression of Frank's finger prints.")
|
||||
}
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
onUseWith(ITEM, SUSPECTPRINTS, Items.UNKNOWN_PRINT_1822) { player, used, with ->
|
||||
val SUSPECT = when (used.id) {
|
||||
Items.ANNAS_PRINT_1816 -> "Anna"
|
||||
Items.BOBS_PRINT_1817 -> "Bob"
|
||||
Items.CAROLS_PRINT_1818 -> "Carol"
|
||||
Items.DAVIDS_PRINT_1819 -> "David"
|
||||
Items.ELIZABETHS_PRINT_1820 -> "Elizabeth"
|
||||
Items.FRANKS_PRINT_1821 -> "Frank"
|
||||
else -> "Anna"
|
||||
}
|
||||
if (used.id == getAttribute(player, attributeRandomMurderer, 0) + Items.ANNAS_PRINT_1816) {
|
||||
sendDialogue(player, "The fingerprints are an exact match to $SUSPECT's.")
|
||||
removeItem(player, with.id)
|
||||
addItem(player, Items.KILLERS_PRINT_1815)
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "They don't seem to be the same. I guess that clears $SUSPECT of the crime. You destroy the useless fingerprint.")
|
||||
removeItem(player, used.id)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
onUseWith(SCENERY, intArrayOf(Items.SILVER_POT_1806, Items.PUNGENT_POT_1812), Scenery.BARREL_OF_FLOUR_26122) { player, _, _ ->
|
||||
sendDialogue(player, "You probably shouldn't use evidence from a crime scene to keep flour in.")
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class PierreDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, PierreDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return PierreDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.PIERRE_807)
|
||||
}
|
||||
}
|
||||
|
||||
class PierreDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> npcl("The Guards told me not to talk to anyone.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you at the time of the murder?", 5),
|
||||
IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)),
|
||||
IfTopic("Do you know why so much poison was bought recently?", 11, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
|
||||
3 -> npcl("Honestly? I think it was Carol.").also { stage++ }
|
||||
4 -> npcl("I saw her in a huge argument with Lord Sinclair in the library the other day. It was something to do with stolen books. She definitely seemed upset enough to have done it afterwards.").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> npcl("I was in town at the inn. When I got back the house was swarming with guards who told me what had happened. Sorry.").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> npcl("Well, like what?").also { stage++ }
|
||||
7 -> playerl("Any sounds of a struggle with Lord Sinclair?").also { stage++ }
|
||||
8 -> npcl("No, I don't remember hearing anything like that.").also { stage++ }
|
||||
9 -> playerl("How about the guard dog barking at all?").also { stage++ }
|
||||
10 -> npcl("I hear him bark all the time. It's one of his favourite things to do. I can't say I did the night of the murder though as I wasn't close enough to hear either way.").also { stage = END_DIALOGUE }
|
||||
|
||||
11 -> npcl("Well, I know David said that he was going to do something about the spiders' nest that's between the two servants' quarters upstairs.").also { stage++ }
|
||||
12 -> npcl("He made a big deal about it to Mary the Maid, calling her useless and incompetent. I felt quite sorry for her actually. You'd really have to ask him though.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package content.region.kandarin.quest.murdermystery
|
||||
|
||||
import content.data.Quests
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributeNoiseClue
|
||||
import content.region.kandarin.quest.murdermystery.MurderMystery.Companion.attributePoisonClue
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class StanfordDialogue (player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
openDialogue(player, StanfordDialogueFile(), npc)
|
||||
return true
|
||||
}
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return StanfordDialogue(player)
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.STANFORD_811)
|
||||
}
|
||||
}
|
||||
|
||||
class StanfordDialogueFile : DialogueFile() {
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (getQuestStage(player!!, Quests.MURDER_MYSTERY)){
|
||||
0 -> npcl("Have you no shame? We are all grieving at the moment.").also { stage = END_DIALOGUE }
|
||||
1 -> when (stage) {
|
||||
0 -> playerl(FacialExpression.NEUTRAL, "I'm here to help the guards with their investigation.").also { stage++ }
|
||||
1 -> npcl(FacialExpression.ASKING, "How can I help?").also { stage++ }
|
||||
2 -> showTopics(
|
||||
Topic("Who do you think is responsible?", 3),
|
||||
Topic( "Where were you at the time of the murder?", 5),
|
||||
IfTopic("Did you hear any suspicious noises at all?", 6, getAttribute(player!!, attributeNoiseClue, false)),
|
||||
IfTopic("Do you know why so much poison was bought recently?", 11, getAttribute(player!!, attributePoisonClue, 0) > 0)
|
||||
)
|
||||
|
||||
3 -> npcl("It was Anna. She is seriously unbalanced. She trashed the garden once then tried to blame it on me! I bet it was her. It's just the kind of thing she'd do!").also { stage++ }
|
||||
4 -> npcl("She really hates me and was arguing with Lord Sinclair about trashing the garden a few days ago.").also { stage = END_DIALOGUE }
|
||||
|
||||
5 -> npcl("Right here, by my little shed. It's very cosy to sit and think in.").also { stage = END_DIALOGUE }
|
||||
|
||||
6 -> npcl("Not that I remember.").also { stage++ }
|
||||
7 -> playerl("So no sounds of a struggle between Lord Sinclair and an intruder?").also { stage++ }
|
||||
8 -> npcl("Not to the best of my recollection.").also { stage++ }
|
||||
9 -> playerl("How about the guard dog barking?").also { stage++ }
|
||||
10 -> npcl("Not that I can recall.").also { stage = END_DIALOGUE }
|
||||
|
||||
11 -> npcl("Well, Bob mentioned to me the other day he wanted to get rid of the bees in that hive over there. I think I saw him buying poison").also { stage++ }
|
||||
12 -> npcl("from that poison salesman the other day. I assume it was to sort out those bees. You'd really have to ask him though.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
100 -> npcl("Thank you for all your help in solving the murder.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -52,6 +52,6 @@ public final class CamelotGuardDialogue extends DialoguePlugin {
|
|||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 812 };
|
||||
return new int[] { 6183, 6184 };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
package content.region.karamja.handlers;
|
||||
|
||||
import core.game.node.entity.npc.AbstractNPC;
|
||||
import core.game.world.map.Location;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.system.config.NPCConfigParser;
|
||||
|
||||
/**
|
||||
* Represents the tribesamn npc.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class TribesmanNPC extends AbstractNPC {
|
||||
|
||||
/**
|
||||
* Represents the npc ids.
|
||||
*/
|
||||
private static final int[] IDS = new int[] { 191, 2496, 2497 };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TribesmanNPC} {@code Object}.
|
||||
* @param id the id.
|
||||
* @param location the location.
|
||||
*/
|
||||
public TribesmanNPC(int id, Location location) {
|
||||
super(id, location, true);
|
||||
getDefinition().getHandlers().put(NPCConfigParser.POISONOUS, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TribesmanNPC} {@code Object}.
|
||||
*/
|
||||
public TribesmanNPC() {
|
||||
super(0, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractNPC construct(int id, Location location, Object... objects) {
|
||||
return new TribesmanNPC(id, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return IDS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package content.region.karamja.tzhaar.handlers
|
||||
|
||||
import core.api.openNpcShop
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.dialogue.Topic
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
@Initializable
|
||||
class TzHaarDialogue(player: Player? = null) : DialoguePlugin(player) {
|
||||
override fun open(vararg args: Any): Boolean {
|
||||
npc = args[0] as NPC
|
||||
npcl(FacialExpression.HALF_GUILTY, "Can I help you JalYt-Ket-${player.username}?").also { stage = 0 }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
when (stage) {
|
||||
0 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "What do you have to trade?", 10, true),
|
||||
Topic(FacialExpression.HALF_GUILTY, "What did you call me?", 20),
|
||||
Topic(FacialExpression.HALF_GUILTY, "No I'm fine thanks.", END_DIALOGUE),
|
||||
)
|
||||
10 -> end().also { openNpcShop(player, npc.id) }
|
||||
20 -> npcl(FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?").also { stage++ }
|
||||
21 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "What's a 'JalYt-Ket'?", 22),
|
||||
Topic(FacialExpression.HALF_GUILTY, "I guess so...", 25),
|
||||
Topic(FacialExpression.HALF_GUILTY, "No I'm not!", END_DIALOGUE)
|
||||
)
|
||||
|
||||
22 -> npcl(FacialExpression.HALF_GUILTY, "That what you are... you tough and strong no?").also { stage++ }
|
||||
23 -> playerl(FacialExpression.HALF_GUILTY, "Well yes I suppose I am...").also { stage++ }
|
||||
24 -> npcl(FacialExpression.HALF_GUILTY, "Then you JalYt-Ket!").also { stage = END_DIALOGUE }
|
||||
|
||||
25 -> npcl(FacialExpression.HALF_GUILTY, "Well then, no problems.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.TZHAAR_HUR_TEL_2620, NPCs.TZHAAR_HUR_LEK_2622, NPCs.TZHAAR_MEJ_ROH_2623)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,313 +0,0 @@
|
|||
package content.region.karamja.tzhaar.handlers;
|
||||
|
||||
import core.game.dialogue.DialogueInterpreter;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.item.Item;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.world.GameWorld;
|
||||
|
||||
/**
|
||||
* Handles the TzHaarMejJal dialogue.
|
||||
* @author 'Vexia
|
||||
* @author Empathy
|
||||
* @author Logg
|
||||
*/
|
||||
@Initializable
|
||||
public class TzHaarMejJah extends DialoguePlugin {
|
||||
private static final Item APPEARANCE_FEE = new Item(6529, 8000); // 8000 tokkul, about the same as you get from failing jad
|
||||
|
||||
public TzHaarMejJah() {
|
||||
|
||||
}
|
||||
|
||||
public TzHaarMejJah(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
|
||||
return new TzHaarMejJah(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You want help JalYt-Ket-" + player.getUsername() + "?");
|
||||
stage = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
if (GameWorld.getSettings().getJad_practice_enabled()) {
|
||||
if (player.getAttribute("fc_practice_jad", false)) {
|
||||
interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "About my challenge...", "No I'm fine thanks.");
|
||||
} else {
|
||||
interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "I want to challenge Jad directly.", "No I'm fine thanks.");
|
||||
}
|
||||
} else {
|
||||
interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "No I'm fine thanks.");
|
||||
}
|
||||
stage = 1;
|
||||
break;
|
||||
case 1:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
if (player.getInventory().containItems(6570)) {
|
||||
interpreter.open(DialogueInterpreter.getDialogueKey("firecape-exchange"), npc);
|
||||
break;
|
||||
}
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?");
|
||||
stage = 10;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What did you call me?");
|
||||
stage = 20;
|
||||
break;
|
||||
case 3:
|
||||
if (GameWorld.getSettings().getJad_practice_enabled()) {
|
||||
if (player.getAttribute("fc_practice_jad", false)) {
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "About my challenge...");
|
||||
stage = 64;
|
||||
} else {
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "The challenge is too long.", "I want to challenge Jad directly.");
|
||||
stage = 50;
|
||||
}
|
||||
} else {
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm fine thanks.");
|
||||
stage = 30;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm fine thanks.");
|
||||
stage = 30;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is the fight caves, TzHaar-Xil made it for practice,", "but many JalYt come here to fight too.", "Just enter the cave and make sure you're prepared.");
|
||||
stage = 11;
|
||||
break;
|
||||
case 11:
|
||||
interpreter.sendOptions("Select an Option", "Are there any rules?", "Ok thanks.");
|
||||
stage = 12;
|
||||
break;
|
||||
case 12:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Are there any rules?");
|
||||
stage = 14;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok thanks.");
|
||||
stage = 13;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
end();
|
||||
break;
|
||||
case 14:
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Rules? Survival is the only rule in there.");
|
||||
stage = 15;
|
||||
break;
|
||||
case 15:
|
||||
interpreter.sendOptions("Select an Option", "Do I win anything?", "Sounds good.");
|
||||
stage = 16;
|
||||
break;
|
||||
case 16:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do I win anything?");
|
||||
stage = 17;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sounds good.");
|
||||
stage = 13;
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You ask a lot of questions.", "Might give you TokKul if you last long enough.");
|
||||
stage = 18;
|
||||
break;
|
||||
case 18:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "...");
|
||||
stage = 19;
|
||||
break;
|
||||
case 19:
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Before you ask, TokKul is like your Coins.");
|
||||
stage = 500;
|
||||
break;
|
||||
case 500:
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Gold is like you JalYt, soft and easily broken, we use", "hard rock forged in fire like TzHaar!");
|
||||
stage = 501;
|
||||
break;
|
||||
case 501:
|
||||
end();
|
||||
break;
|
||||
case 20:
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?");
|
||||
stage = 21;
|
||||
break;
|
||||
case 21:
|
||||
interpreter.sendOptions("Select an Option", "What's a 'JalYt-Ket'?", "I guess so...", "No I'm not!");
|
||||
stage = 22;
|
||||
break;
|
||||
case 22:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a 'JalYt-Ket'?");
|
||||
stage = 100;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess so...");
|
||||
stage = 200;
|
||||
break;
|
||||
case 3:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm not!");
|
||||
stage = 300;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 100:
|
||||
interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That what you are... you tough and strong no?");
|
||||
stage = 101;
|
||||
break;
|
||||
case 101:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well yes I suppose I am...");
|
||||
stage = 102;
|
||||
break;
|
||||
case 102:
|
||||
end();
|
||||
break;
|
||||
case 200:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess so....");
|
||||
stage = 201;
|
||||
break;
|
||||
case 201:
|
||||
end();
|
||||
break;
|
||||
case 300:
|
||||
end();
|
||||
break;
|
||||
case 30:
|
||||
end();
|
||||
break;
|
||||
|
||||
case 50:
|
||||
interpreter.sendDialogues(npc, FacialExpression.DISGUSTED_HEAD_SHAKE, "I thought you strong and tough", "but you want skip endurance training?");
|
||||
stage = 57;
|
||||
break;
|
||||
case 57:
|
||||
interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Maybe you not JalYt-Ket afterall.");
|
||||
stage = 58;
|
||||
break;
|
||||
case 58:
|
||||
interpreter.sendOptions("Select an Option", "I don't have time for it, man.", "No, I'm JalYt-Ket!");
|
||||
stage = 51;
|
||||
break;
|
||||
case 51:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have time for it, man.");
|
||||
stage = 52;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, I'm JalYt-Ket! I swear!", "I'll do the training properly.");
|
||||
stage = 30;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 52:
|
||||
interpreter.sendDialogues(npc, FacialExpression.DISGUSTED_HEAD_SHAKE, "JalYt, you know you not get reward","if you not do training properly, ok?");
|
||||
stage = 56;
|
||||
break;
|
||||
case 56:
|
||||
interpreter.sendOptions("Select an Option", "That's okay, I don't need a reward.", "Oh, nevermind then.");
|
||||
stage = 53;
|
||||
break;
|
||||
case 53:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's okay, I don't need a reward.");
|
||||
stage = 54;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, nevermind then.");
|
||||
stage = 30;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 54:
|
||||
interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I just wanna fight the big guy.");
|
||||
stage = 55;
|
||||
break;
|
||||
case 55:
|
||||
interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Okay JalYt.","TzTok-Jad not show up for just anyone.");
|
||||
stage = 59;
|
||||
break;
|
||||
case 59:
|
||||
interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "You give 8000 TokKul, TzTok-Jad know you serious.", "You get it back if you victorious.");
|
||||
stage = 60;
|
||||
break;
|
||||
case 60:
|
||||
interpreter.sendOptions("Select an Option", "That's fair, here's 8000 TokKul.", "I don't have that much on me, but I'll go get it.", "TzTok-Jad must be old and tired to not just accept my challenge.");
|
||||
stage = 61;
|
||||
case 61:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's fair, here's 8000 TokKul.");
|
||||
if (!player.getInventory().containsItem(APPEARANCE_FEE)) {
|
||||
stage = 62;
|
||||
break;
|
||||
}
|
||||
if (player.getInventory().remove(APPEARANCE_FEE)) {
|
||||
stage = 69;
|
||||
} else {
|
||||
stage = 62;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have that much on me, but I'll go get it.");
|
||||
stage = 30;
|
||||
break;
|
||||
case 3:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "TzTok-Jad must be old and tired", "to not just accept my challenge.");
|
||||
stage = 63;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 62:
|
||||
interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "JalYt, you not have the TokKul.", "You come back when you are serious.");
|
||||
stage = 30;
|
||||
break;
|
||||
case 63:
|
||||
interpreter.sendDialogues(npc, FacialExpression.ANGRY, "JalYt-Mor, you the old and tired one.", "You the one not want to do proper training.");
|
||||
stage = 30;
|
||||
break;
|
||||
case 64:
|
||||
interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "TzTok-Jad is waiting for you.", "Do not make TzTok-Jad wait long.");
|
||||
stage = 30;
|
||||
break;
|
||||
case 69:
|
||||
interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Okay JalYt. Enter cave when you are prepared.", "You find TzTok-Jad waiting for JalYt challenger.");
|
||||
player.setAttribute("fc_practice_jad", true);
|
||||
stage = 30;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { DialogueInterpreter.getDialogueKey("tzhaar-mej"), 2617 };
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
package content.region.karamja.tzhaar.handlers
|
||||
|
||||
import core.api.*
|
||||
import core.game.dialogue.*
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.GameWorld.settings
|
||||
import core.plugin.Initializable
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
/**
|
||||
* Handles the TzHaarMejJal dialogue.
|
||||
* @author 'Vexia
|
||||
* @author Empathy
|
||||
* @author Logg
|
||||
*/
|
||||
@Initializable
|
||||
class TzHaarMejJal(player: Player? = null) : DialoguePlugin(player){
|
||||
|
||||
override fun open(vararg args: Any): Boolean {
|
||||
npc = args[0] as NPC
|
||||
npcl(FacialExpression.HALF_GUILTY, "You want help JalYt-Ket-${player.username}?").also { stage = 0 }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
when (stage) {
|
||||
0 -> showTopics(
|
||||
if (inInventory(player, Items.FIRE_CAPE_6570)) {
|
||||
Topic(FacialExpression.HALF_GUILTY, "I have a fire cape here.", 100)
|
||||
} else {
|
||||
Topic(FacialExpression.HALF_GUILTY, "What is this place?", 10)
|
||||
},
|
||||
Topic(FacialExpression.HALF_GUILTY, "What did you call me?", 20),
|
||||
IfTopic(FacialExpression.HALF_GUILTY, "About my challenge...", 50, getAttribute(player, "fc_practice_jad", false) && settings!!.jad_practice_enabled),
|
||||
IfTopic("I want to challenge Jad directly.", 30, !getAttribute(player, "fc_practice_jad", false) && settings!!.jad_practice_enabled, skipPlayer = true),
|
||||
Topic(FacialExpression.HALF_GUILTY, "No I'm fine thanks.", END_DIALOGUE)
|
||||
)
|
||||
|
||||
10 -> npc(FacialExpression.HALF_GUILTY,
|
||||
"This is the fight caves, TzHaar-Xil made it for practice,",
|
||||
"but many JalYt come here to fight too.",
|
||||
"Just enter the cave and make sure you're prepared."
|
||||
).also { stage++ }
|
||||
|
||||
11 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "Are there any rules?", 12),
|
||||
Topic(FacialExpression.HALF_GUILTY, "Ok thanks.", END_DIALOGUE)
|
||||
)
|
||||
|
||||
12 -> npcl(FacialExpression.HALF_GUILTY, "Rules? Survival is the only rule in there.").also { stage++ }
|
||||
13 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "Do I win anything?", 14),
|
||||
Topic(FacialExpression.HALF_GUILTY, "Sounds good.", END_DIALOGUE)
|
||||
)
|
||||
|
||||
14 -> npc(FacialExpression.HALF_GUILTY,
|
||||
"You ask a lot of questions.",
|
||||
"Might give you TokKul if you last long enough."
|
||||
).also { stage++ }
|
||||
15 -> playerl(FacialExpression.HALF_GUILTY, "...").also { stage ++ }
|
||||
16 -> npcl(FacialExpression.HALF_GUILTY, "Before you ask, TokKul is like your Coins.").also { stage++ }
|
||||
17 -> npc(FacialExpression.HALF_GUILTY,
|
||||
"Gold is like you JalYt, soft and easily broken, we use",
|
||||
"hard rock forged in fire like TzHaar!"
|
||||
).also{ stage = END_DIALOGUE }
|
||||
|
||||
20 -> npcl(FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?").also { stage++ }
|
||||
21 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "What's a 'JalYt-Ket'?", 22),
|
||||
Topic(FacialExpression.HALF_GUILTY, "I guess so...", END_DIALOGUE),
|
||||
Topic(FacialExpression.HALF_GUILTY, "No I'm not!", END_DIALOGUE)
|
||||
)
|
||||
|
||||
22 -> npcl(FacialExpression.HALF_GUILTY, "That what you are... you tough and strong no?").also { stage++ }
|
||||
23 -> playerl(FacialExpression.HALF_GUILTY, "Well yes I suppose I am...").also { stage = END_DIALOGUE }
|
||||
|
||||
30 -> player(FacialExpression.HALF_GUILTY,
|
||||
"The challenge is too long.",
|
||||
"I want to challenge Jad directly."
|
||||
).also { stage++ }
|
||||
31 -> npc(FacialExpression.DISGUSTED_HEAD_SHAKE,
|
||||
"I thought you strong and tough",
|
||||
"but you want skip endurance training?"
|
||||
).also { stage++ }
|
||||
32 -> npcl(FacialExpression.NEUTRAL, "Maybe you not JalYt-Ket afterall.").also { stage++ }
|
||||
33 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "I don't have time for it, man.", 35),
|
||||
Topic("No, I'm JalYt-Ket!", 34, skipPlayer = true)
|
||||
)
|
||||
|
||||
34 -> player(FacialExpression.HALF_GUILTY,
|
||||
"No, I'm JalYt-Ket! I swear!",
|
||||
"I'll do the training properly."
|
||||
).also { stage = END_DIALOGUE }
|
||||
|
||||
35 -> npc(FacialExpression.DISGUSTED_HEAD_SHAKE,
|
||||
"JalYt, you know you not get reward",
|
||||
"if you not do training properly, ok?"
|
||||
).also { stage++ }
|
||||
36 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "That's okay, I don't need a reward.", 37),
|
||||
Topic(FacialExpression.HALF_GUILTY, "Oh, nevermind then.", END_DIALOGUE)
|
||||
)
|
||||
|
||||
37 -> playerl(FacialExpression.NEUTRAL, "I just wanna fight the big guy.").also { stage++ }
|
||||
38 -> npc(FacialExpression.NEUTRAL,
|
||||
"Okay JalYt.",
|
||||
"TzTok-Jad not show up for just anyone."
|
||||
).also { stage++ }
|
||||
39 -> npc(FacialExpression.NEUTRAL,
|
||||
"You give 8000 TokKul, TzTok-Jad know you serious.",
|
||||
"You get it back if you victorious."
|
||||
).also { stage++ }
|
||||
40 -> showTopics(
|
||||
Topic(FacialExpression.HALF_GUILTY, "That's fair, here's 8000 TokKul.", 41),
|
||||
Topic(FacialExpression.HALF_GUILTY, "I don't have that much on me, but I'll go get it.", END_DIALOGUE),
|
||||
Topic("TzTok-Jad must be old and tired to not just accept my challenge.", 42, skipPlayer = true)
|
||||
)
|
||||
|
||||
41 -> if (removeItem(player, Item(Items.TOKKUL_6529, 8000))) {
|
||||
npc(FacialExpression.NEUTRAL,
|
||||
"Okay JalYt. Enter cave when you are prepared.",
|
||||
"You find TzTok-Jad waiting for JalYt challenger."
|
||||
)
|
||||
.also { setAttribute(player, "fc_practice_jad", true) }
|
||||
.also { stage = END_DIALOGUE }
|
||||
} else npc(FacialExpression.NEUTRAL,
|
||||
"JalYt, you not have the TokKul.",
|
||||
"You come back when you are serious."
|
||||
).also { stage = END_DIALOGUE }
|
||||
|
||||
42 -> player(FacialExpression.HALF_GUILTY,
|
||||
"TzTok-Jad must be old and tired",
|
||||
"to not just accept my challenge."
|
||||
).also { stage++ }
|
||||
43 -> npc(FacialExpression.ANGRY,
|
||||
"JalYt-Mor, you the old and tired one.",
|
||||
"You the one not want to do proper training."
|
||||
).also { stage = END_DIALOGUE }
|
||||
|
||||
50 -> npc(FacialExpression.NEUTRAL,
|
||||
"TzTok-Jad is waiting for you.",
|
||||
"Do not make TzTok-Jad wait long."
|
||||
).also { stage = END_DIALOGUE }
|
||||
|
||||
100 -> sendDialogueOptions(player, "Sell your fire cape?", "Yes, sell it for 8,000 TokKul.", "No, keep it.").also { stage++ }
|
||||
101 -> when (buttonId) {
|
||||
1 -> npcl(FacialExpression.OLD_NORMAL, "Hand your cape here, young JalYte.").also { stage++ }
|
||||
2 -> end()
|
||||
}
|
||||
102 -> end().also { if (removeItem(player, Items.FIRE_CAPE_6570)) addItem(player, Items.TOKKUL_6529, 8000) }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun newInstance(player: Player): DialoguePlugin {
|
||||
return TzHaarMejJal(player)
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(NPCs.TZHAAR_MEJ_JAL_2617)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
package content.region.karamja.tzhaar.handlers;
|
||||
|
||||
import core.cache.def.impl.NPCDefinition;
|
||||
import core.game.dialogue.DialogueInterpreter;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.FacialExpression;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.repository.Repository;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import core.plugin.Initializable;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
/**
|
||||
* Handles everything in regards to jad pet.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class TzRekJadNPC extends OptionHandler {
|
||||
|
||||
/**
|
||||
* The tzhaar mej id.
|
||||
*/
|
||||
private static final int TZHAAR_MEJ_ID = 2617;
|
||||
|
||||
/**
|
||||
* The firecape item.
|
||||
*/
|
||||
private static final Item FIRECAPE = new Item(6570);
|
||||
|
||||
/**
|
||||
* The tokkul item.
|
||||
*/
|
||||
private static final Item TOKKUL = new Item(6529);
|
||||
|
||||
/**
|
||||
* The jad item.
|
||||
*/
|
||||
private static final Item JAD_PET = new Item(14828);
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
NPCDefinition.forId(TZHAAR_MEJ_ID).getHandlers().put("option:exchange fire cape", this);
|
||||
ClassScanner.definePlugins(new TzhaarMejJalDialogue(), new TzRekJadDialogue());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
switch (option) {
|
||||
case "exchange fire cape":
|
||||
player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey(player.getInventory().containsItem(FIRECAPE) ? "firecape-exchange" : "tzhaar-mej"), node.asNpc());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the TzhaarMejJal Dialogue to gamble for jad pet.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public final class TzhaarMejJalDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TzhaarMejJalDialogue} {@code Object}.
|
||||
*/
|
||||
public TzhaarMejJalDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TzhaarMejJalDialogue} {@code Object}.
|
||||
*
|
||||
* @param player the player.
|
||||
*/
|
||||
public TzhaarMejJalDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new TzhaarMejJalDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have a fire cape here.");
|
||||
stage = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
interpreter.sendOptions("Sell your fire cape?", "Yes, sell it for 8,000 TokKul.", "No, keep it.", "Bargain for TzRek-Jad.");
|
||||
stage = 1;
|
||||
break;
|
||||
case 1:
|
||||
switch(buttonId) {
|
||||
case 1:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, player.getInventory().containsItems(FIRECAPE) ? "Hand your cape here, young JalYte." : "You not have firecape, JalYt.");
|
||||
stage = 10;
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
break;
|
||||
case 3:
|
||||
interpreter.sendOptions("Sacrifice your firecape?", "Yes, I know I won't get my cape back.", "No, I like my cape!");
|
||||
stage = 20;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (player.getInventory().containsItem(FIRECAPE)) {
|
||||
if (player.getInventory().remove(FIRECAPE)) {
|
||||
TOKKUL.setAmount(8000);
|
||||
player.getInventory().add(TOKKUL);
|
||||
TOKKUL.setAmount(1);
|
||||
}
|
||||
}
|
||||
end();
|
||||
break;
|
||||
case 20:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
if (player.hasItem(JAD_PET)) {
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Best you train one TzRek-Jad only.");
|
||||
stage = 21;
|
||||
break;
|
||||
}
|
||||
if (player.getFamiliarManager().hasFamiliar()) {
|
||||
if (player.getFamiliarManager().getFamiliar().getId() == 8650) {
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Best you train one TzRek-Jad only.");
|
||||
stage = 21;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (player.getInventory().remove(FIRECAPE)) {
|
||||
int r = RandomFunction.getRandom(200);
|
||||
if (r == 1) {
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You lucky. Better train him good else TzTok-Jad find", "you, JalYt.");
|
||||
if (!player.getFamiliarManager().hasFamiliar()) {
|
||||
player.getFamiliarManager().summon(JAD_PET, true);
|
||||
player.sendNotificationMessage("You have a funny feeling like you're being followed.");
|
||||
} else if (player.getInventory().freeSlots() > 0) {
|
||||
player.getInventory().add(JAD_PET);
|
||||
player.sendNotificationMessage("You feel something weird sneaking into your backpack.");
|
||||
}
|
||||
Repository.sendNews(player.getUsername() + " now commands a miniature TzTok-Jad!");
|
||||
} else {
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You not lucky. Maybe next time, JalYt.");
|
||||
}
|
||||
}
|
||||
stage = 21;
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 21:
|
||||
end();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { DialogueInterpreter.getDialogueKey("firecape-exchange") };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the TzRekJad dialogue.
|
||||
* @author Empathy
|
||||
*
|
||||
*/
|
||||
public final class TzRekJadDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TzRekJadDialogue} {@code Object}.
|
||||
*/
|
||||
public TzRekJadDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TzRekJadDialogue} {@code Object}.
|
||||
*
|
||||
* @param player the player.
|
||||
*/
|
||||
public TzRekJadDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new TzRekJadDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
int i = RandomFunction.getRandom(1);
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, i == 1 ? "Do you miss your people?" : "Are you hungry?");
|
||||
stage = (i == 1 ? 0 : 5);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Mej-TzTok-Jad Kot-Kl!");
|
||||
stage = 1;
|
||||
break;
|
||||
case 1:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No.. I don't think so.");
|
||||
stage = 2;
|
||||
break;
|
||||
case 2:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Jal-Zek Kl?");
|
||||
stage = 3;
|
||||
break;
|
||||
case 3:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, no, I wouldn't hurt you.");
|
||||
stage = 4;
|
||||
break;
|
||||
case 4:
|
||||
end();
|
||||
break;
|
||||
case 5:
|
||||
interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Kl-Kra!");
|
||||
stage = 6;
|
||||
break;
|
||||
case 6:
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ooookay...");
|
||||
stage = 4;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 8650 };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,203 +0,0 @@
|
|||
package content.region.karamja.tzhaar.handlers;
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.activity.ActivityManager;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.world.map.Location;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used for tzhaar city.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class TzhaarCityPlugin extends OptionHandler {
|
||||
|
||||
/**
|
||||
* Represents the locations to use.
|
||||
*/
|
||||
private static final Location[] LOCATIONS = new Location[] { Location.create(2480, 5175, 0), Location.create(2866, 9571, 0) };
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
SceneryDefinition.forId(31284).getHandlers().put("option:enter", this); //karamja cave.
|
||||
SceneryDefinition.forId(9359).getHandlers().put("option:enter", this); //tzhaar exit
|
||||
SceneryDefinition.forId(9356).getHandlers().put("option:enter", this);
|
||||
SceneryDefinition.forId(9369).getHandlers().put("option:pass", this);
|
||||
SceneryDefinition.forId(31292).getHandlers().put("option:go-through", this); //unimplemented door near fairy ring
|
||||
new TzhaarDialogue().init();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
int id = ((Scenery) node).getId();
|
||||
switch (option) {
|
||||
case "enter":
|
||||
switch (id) {
|
||||
case 31284:
|
||||
player.getProperties().setTeleportLocation(LOCATIONS[0]);
|
||||
break;
|
||||
case 9359:
|
||||
player.getProperties().setTeleportLocation(LOCATIONS[1]);
|
||||
break;
|
||||
case 9356:
|
||||
if (player.getFamiliarManager().hasFamiliar()) {
|
||||
player.getPacketDispatch().sendMessage("You can't enter this with a follower.");
|
||||
break;
|
||||
}
|
||||
ActivityManager.start(player, "fight caves", false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "pass":
|
||||
switch (id) {
|
||||
case 9369:
|
||||
ActivityManager.start(player, "fight pits", false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "go-through":
|
||||
switch (id) {
|
||||
case 31292:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the dialogue plugin used for the tzhaar npcs.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
public static final class TzhaarDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TzhaarDialogue} {@code Object}.
|
||||
*/
|
||||
public TzhaarDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code TzhaarDialogue} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public TzhaarDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new TzhaarDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
npc = (NPC) args[0];
|
||||
npc("Can I help you JalYt-Ket-" + player.getUsername() + "?");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
options("What do you have to trade?", "What did you call me?", "No I'm fine thanks.");
|
||||
stage = 1;
|
||||
break;
|
||||
case 1:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
end();
|
||||
npc.openShop(player);
|
||||
break;
|
||||
case 2:
|
||||
player("What did you call me?");
|
||||
stage = 20;
|
||||
break;
|
||||
case 3:
|
||||
player("No I'm fine thanks.");
|
||||
stage = 30;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
break;
|
||||
case 20:
|
||||
npc("Are you not JalYt-Ket?");
|
||||
stage = 21;
|
||||
break;
|
||||
case 21:
|
||||
options("What's a 'JalYt-Ket'?", "I guess so...", "No I'm not!");
|
||||
stage = 22;
|
||||
break;
|
||||
case 22:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
player("What's a 'JalYt-Ket'?");
|
||||
stage = 100;
|
||||
break;
|
||||
case 2:
|
||||
player("I guess so...");
|
||||
stage = 120;
|
||||
break;
|
||||
case 3:
|
||||
player("No I'm not!");
|
||||
stage = 130;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 100:
|
||||
npc("That what you are... you tough and strong no?");
|
||||
stage = 101;
|
||||
break;
|
||||
case 101:
|
||||
player("Well yes I suppose I am...");
|
||||
stage = 102;
|
||||
break;
|
||||
case 102:
|
||||
npc("Then you JalYt-Ket!");
|
||||
stage = 103;
|
||||
break;
|
||||
case 103:
|
||||
end();
|
||||
break;
|
||||
case 120:
|
||||
npc("Well then, no problems.");
|
||||
stage = 121;
|
||||
break;
|
||||
case 121:
|
||||
end();
|
||||
break;
|
||||
case 130:
|
||||
end();
|
||||
break;
|
||||
case 23:
|
||||
end();
|
||||
break;
|
||||
case 30:
|
||||
end();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 2620, 2622, 2623 };
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ public final class TzhaarFightCavesPlugin extends ActivityPlugin {
|
|||
* @param player The player.
|
||||
*/
|
||||
public TzhaarFightCavesPlugin(Player player) {
|
||||
super("fight caves", true, true, true, ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS);
|
||||
super("fight caves", true, true, true, ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.FOLLOWERS);
|
||||
super.player = player;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package content.region.karamja.tzhaar.handlers
|
||||
|
||||
import core.api.sendNPCDialogueLines
|
||||
import core.api.teleport
|
||||
import core.game.activity.ActivityManager
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class TzhaarListeners : InteractionListener {
|
||||
override fun defineListeners() {
|
||||
on(intArrayOf(31284, 9359, 9356), IntType.SCENERY, "enter") { player, node ->
|
||||
when (node.id) {
|
||||
31284 -> teleport(player, Location.create(2480, 5175, 0))
|
||||
9359 -> teleport(player, Location.create(2866, 9571, 0))
|
||||
9356 -> {
|
||||
if (player.familiarManager.hasFamiliar()) {
|
||||
sendNPCDialogueLines(player, NPCs.TZHAAR_MEJ_JAL_2617, FacialExpression.ANGRY, false, "No Kimit-Zil in the cave! This is a fight for YOU,", "not your friends!")
|
||||
} else ActivityManager.start(player, "fight caves", false)
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(9369, IntType.SCENERY, "pass") { player, _ ->
|
||||
ActivityManager.start(player, "fight pits", false)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(31292, IntType.SCENERY, "go-through") { _, _ ->
|
||||
return@on false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -826,43 +826,53 @@ class TheDigSiteListeners : InteractionListener {
|
|||
}
|
||||
|
||||
on(Items.UNIDENTIFIED_LIQUID_702, ITEM, "drop") { player, node ->
|
||||
removeItem(player, node)
|
||||
impact(player, 25)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
if (removeItem(player, node)) {
|
||||
impact(player, 25)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
}
|
||||
return@on false
|
||||
}
|
||||
|
||||
on(Items.NITROGLYCERIN_703, ITEM, "drop") { player, node ->
|
||||
removeItem(player, node)
|
||||
impact(player, 35)
|
||||
sendChat(player, "Ow! The nitroglycerin exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
if (removeItem(player, node)) {
|
||||
impact(player, 35)
|
||||
sendChat(player, "Ow! The nitroglycerin exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
}
|
||||
return@on false
|
||||
}
|
||||
|
||||
on(Items.MIXED_CHEMICALS_705, ITEM, "drop") { player, node ->
|
||||
removeItem(player, node)
|
||||
impact(player, 45)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
if (removeItem(player, node)) {
|
||||
impact(player, 45)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
}
|
||||
return@on false
|
||||
}
|
||||
|
||||
on(Items.MIXED_CHEMICALS_706, ITEM, "drop") { player, node ->
|
||||
removeItem(player, node)
|
||||
impact(player, 55)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
if (removeItem(player, node)) {
|
||||
impact(player, 55)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
}
|
||||
return@on false
|
||||
}
|
||||
|
||||
on(Items.CHEMICAL_COMPOUND_707, ITEM, "drop") { player, node ->
|
||||
removeItem(player, node)
|
||||
impact(player, 65)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
if (removeItem(player, node)) {
|
||||
impact(player, 65)
|
||||
sendChat(player, "Ow! The liquid exploded!")
|
||||
sendMessage(player, "You were injured by the burning liquid.")
|
||||
return@on true
|
||||
}
|
||||
return@on false
|
||||
}
|
||||
|
||||
// Scenery not tied to quest
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
package content.region.misthalin.draynor.handlers
|
||||
|
||||
import core.api.hasLineOfSight
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.impl.PulseType
|
||||
import core.game.node.entity.npc.AbstractNPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.game.world.map.path.Pathfinder
|
||||
import core.plugin.Initializable
|
||||
|
||||
/**
|
||||
* Represents the Draynor Manor Chair NPC, these are the chairs that follow the player
|
||||
* around the manor.
|
||||
*
|
||||
* @author Broseki
|
||||
*/
|
||||
|
||||
private const val DRAYNOR_MANOR_CHAIR_NPC_ID = 3293
|
||||
private const val FOLLOWING_DISTANCE = 5
|
||||
private const val STOP_FOLLOWING_DISTANCE = 30
|
||||
|
||||
@Initializable
|
||||
class DraynorManorChairNPC(id: Int = DRAYNOR_MANOR_CHAIR_NPC_ID, location: Location? = null) :
|
||||
AbstractNPC(id, location) {
|
||||
|
||||
// The player this NPC is currently following, null if nobody is being followed
|
||||
private var following: Player? = null
|
||||
|
||||
override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC {
|
||||
return DraynorManorChairNPC(id, location)
|
||||
}
|
||||
|
||||
override fun handleTickActions() {
|
||||
super.handleTickActions()
|
||||
val closestPlayer = findClosestPlayer()
|
||||
// If there is a player nearby, follow them
|
||||
if (closestPlayer != null && following != closestPlayer) {
|
||||
stopFollowing()
|
||||
following = closestPlayer
|
||||
follow(closestPlayer)
|
||||
following?.let { face(it) }
|
||||
} else {
|
||||
// If we didn't find a player within `FOLLOWING_DISTANCE`
|
||||
// but we are following a player, check that they are still
|
||||
// within `STOP_FOLLOWING_DISTANCE`, if they are gone, stop
|
||||
// trying to follow them.
|
||||
following?.let { player ->
|
||||
if (findDistanceToPlayer(player) > STOP_FOLLOWING_DISTANCE
|
||||
|| !player.isActive
|
||||
|| player.isInvisible) {
|
||||
stopFollowing()
|
||||
} else {
|
||||
if (!pulseManager.hasPulseRunning()) {
|
||||
follow(player)
|
||||
}
|
||||
face(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops following `following`
|
||||
*/
|
||||
fun stopFollowing() {
|
||||
following = null
|
||||
resetWalk()
|
||||
pulseManager.clear(PulseType.STANDARD)
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the closest player to the current entity within `FOLLOWING_DISTANCE`
|
||||
* that is currently in the chair's line of sight.
|
||||
*
|
||||
* @return The Player object representing the closest player, or null if there are no players nearby.
|
||||
*/
|
||||
fun findClosestPlayer(): Player? {
|
||||
val players = RegionManager.getLocalPlayers(this, FOLLOWING_DISTANCE)
|
||||
if (players.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
var closestPlayer: Player? = null
|
||||
var closestDistance = Double.MAX_VALUE
|
||||
|
||||
for (player in players) {
|
||||
// Make sure the chair does not try to start
|
||||
// following a player in another room
|
||||
if (!hasLineOfSight(this, player)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the player is invisible, don't follow them
|
||||
if (player.isInvisible) {
|
||||
continue
|
||||
}
|
||||
|
||||
val distance = findDistanceToPlayer(player)
|
||||
if (distance < closestDistance) {
|
||||
closestDistance = distance
|
||||
closestPlayer = player
|
||||
}
|
||||
}
|
||||
|
||||
return closestPlayer
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the distance between the current entity and the specified player.
|
||||
*
|
||||
* @param player The player whose distance from the current entity is to be calculated.
|
||||
* @return The distance between the current entity and the specified player as a Double value.
|
||||
*/
|
||||
fun findDistanceToPlayer(player: Player): Double {
|
||||
return this.location.getDistance(player.location)
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers the current entity to follow the specified player using a movement pulse.
|
||||
*
|
||||
* @param player The player that the entity should follow.
|
||||
*/
|
||||
fun follow(player: Player) {
|
||||
pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) {
|
||||
override fun pulse(): Boolean {
|
||||
return false
|
||||
}
|
||||
}), PulseType.STANDARD)
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(DRAYNOR_MANOR_CHAIR_NPC_ID)
|
||||
}
|
||||
|
||||
override fun shouldPreventStacking(mover: Entity?): Boolean {
|
||||
return mover is DraynorManorChairNPC
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package content.region.misthalin.draynor.handlers
|
||||
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager.getLocalNpcs
|
||||
import core.game.world.map.path.Pathfinder
|
||||
import core.game.world.map.zone.MapZone
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneBuilder
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
|
||||
/**
|
||||
* Represents the interior of Draynor Manor.
|
||||
*
|
||||
* @author Broseki
|
||||
*/
|
||||
@Initializable
|
||||
class DraynorManorHouseZone : MapZone("Draynor Manor House", true), Plugin<Any?> {
|
||||
|
||||
override fun newInstance(arg: Any?): Plugin<Any?> {
|
||||
ZoneBuilder.configure(this)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun move(e: Entity, loc: Location?, destination: Location): Boolean {
|
||||
for (n in getLocalNpcs(e, 5)) {
|
||||
if (n.isInvisible() || n === e) {
|
||||
continue
|
||||
}
|
||||
if (n.shouldPreventStacking(e)) {
|
||||
val s1 = e.size()
|
||||
val s2 = n.size()
|
||||
val x = destination.getX()
|
||||
val y = destination.getY()
|
||||
val l = n.getLocation()
|
||||
if (Pathfinder.isStandingIn(x, y, s1, s1, l.getX(), l.getY(), s2, s2)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun enter(entity: Entity?): Boolean {
|
||||
return super.enter(entity)
|
||||
}
|
||||
|
||||
override fun fireEvent(identifier: String?, vararg args: Any?): Any? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun configure() {
|
||||
register(ZoneBorders(3097, 3373, 3119, 3364))
|
||||
register(ZoneBorders(3090, 3363, 3126, 3354))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
package content.region.misthalin.lumbridge.handlers
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.ImpactHandler.HitsplatType
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.repository.Repository
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
/**
|
||||
* NPCs.WALL_BEAST_7823 starts out as NPCs.HOLE_IN_THE_WALL_2058 first.
|
||||
* On death, it will respawn a new hole in the wall.
|
||||
*
|
||||
* h2QAZzGds9o
|
||||
*
|
||||
* npc anim 1807
|
||||
* {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}-
|
||||
*/
|
||||
class WallBeastBehavior : NPCBehavior(NPCs.HOLE_IN_THE_WALL_2058, NPCs.WALL_BEAST_7823) {
|
||||
override fun onCreation(self: NPC) {
|
||||
// This NPC should never move.
|
||||
self.walkRadius = 0
|
||||
self.isNeverWalks = true
|
||||
}
|
||||
|
||||
override fun onDeathFinished(self: NPC, entity: Entity) {
|
||||
self.reTransform()
|
||||
// I don't think this is needed since the respawn will be immediate.
|
||||
}
|
||||
}
|
||||
|
||||
class WallBeastNTrigger : MapArea {
|
||||
|
||||
companion object {
|
||||
/** Finds the nearest NPC of npcId to location. */
|
||||
fun findNearestNPC(location: Location, npcId: Int): NPC? {
|
||||
// maybe replace contentAPI's version of this
|
||||
return Repository.npcs
|
||||
.filter { it.id == npcId }
|
||||
.toMutableList()
|
||||
.sortedWith { a, b ->
|
||||
return@sortedWith (Location.getDistance(a.location, location) - Location.getDistance(b.location, location)).toInt()
|
||||
}
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
fun isHelmetInEquipment(entity: Player): Boolean {
|
||||
return inEquipment(entity, Items.SPINY_HELMET_4551) ||
|
||||
inEquipment(entity, Items.SLAYER_HELMET_13263) ||
|
||||
inEquipment(entity, Items.SPIKED_HELMET_13105) ||
|
||||
inEquipment(entity, Items.SLAYER_HELMET_E_14636) ||
|
||||
inEquipment(entity, Items.SLAYER_HELMET_CHARGED_14637)
|
||||
}
|
||||
}
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
// The goals here are in order
|
||||
return arrayOf(
|
||||
ZoneBorders(3161,9546,3161,9546),
|
||||
ZoneBorders(3164,9555,3164,9555),
|
||||
ZoneBorders(3162,9573,3162,9573),
|
||||
ZoneBorders(3198,9553,3198,9553),
|
||||
ZoneBorders(3198,9571,3198,9571),
|
||||
ZoneBorders(3215,9559,3215,9559),
|
||||
ZoneBorders(3216,9587,3216,9587),
|
||||
)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (entity is Player) {
|
||||
val nearbyWallbeast = findNearestNPC(entity.location, NPCs.HOLE_IN_THE_WALL_2058) // wallbeasts are always 1 square north.
|
||||
// println(nearbyWallbeast)
|
||||
if (nearbyWallbeast != null) {
|
||||
lock(entity, 2)
|
||||
stopWalk(entity)
|
||||
// Stop walk doesn't stop the player from walking on.
|
||||
// You have to clear the movement pulse that is continually feeding the walk location.
|
||||
val movementPulse = entity.getPulseManager().current;
|
||||
if (movementPulse is MovementPulse) {
|
||||
movementPulse.stop();
|
||||
}
|
||||
face(entity, nearbyWallbeast.location)
|
||||
queueScript(nearbyWallbeast, 2, QueueStrength.STRONG) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
if (isHelmetInEquipment(entity)) {
|
||||
animate(nearbyWallbeast, 1805)
|
||||
} else {
|
||||
animate(nearbyWallbeast, 1806)
|
||||
}
|
||||
return@queueScript delayScript(nearbyWallbeast, 1)
|
||||
}
|
||||
1 -> {
|
||||
if (isHelmetInEquipment(entity)) {
|
||||
// You can only attack the wallbeast if you have a helmet
|
||||
transformNpc(nearbyWallbeast, NPCs.WALL_BEAST_7823, 300)
|
||||
return@queueScript stopExecuting(nearbyWallbeast)
|
||||
} else {
|
||||
animate(nearbyWallbeast, 1807)
|
||||
return@queueScript delayScript(nearbyWallbeast, 4)
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
animate(nearbyWallbeast, 1808)
|
||||
return@queueScript stopExecuting(nearbyWallbeast)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(nearbyWallbeast)
|
||||
}
|
||||
}
|
||||
queueScript(entity, 2, QueueStrength.STRONG) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
if (isHelmetInEquipment(entity)) {
|
||||
return@queueScript stopExecuting(entity)
|
||||
}
|
||||
lock(entity, 5)
|
||||
return@queueScript delayScript(entity, 1)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
animate(entity, 1810) // 734
|
||||
return@queueScript delayScript(entity, 4)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
// I don't know how much they are supposed to hit... osrs says up to 18...
|
||||
impact(entity, (13 .. 18).random() , HitsplatType.NORMAL)
|
||||
animate(entity, 1811) // 734
|
||||
return@queueScript stopExecuting(entity)
|
||||
}
|
||||
|
||||
else -> return@queueScript stopExecuting(entity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package content.region.wilderness.handlers
|
||||
|
||||
import core.api.*
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
|
||||
class KingBlackDragonArea : MapArea {
|
||||
override fun defineAreaBorders() : Array<ZoneBorders> {
|
||||
return arrayOf(ZoneBorders(2256, 4680, 2287, 4711, 0, true))
|
||||
}
|
||||
override fun getRestrictions() : Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS)
|
||||
}
|
||||
}
|
||||
|
|
@ -74,8 +74,10 @@ public class RevenantCombatHandler extends MultiSwingHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!isPoisoned(victim) && (WildernessZone.getWilderness(entity) >= 50 || entity.getId() == 6998)) {
|
||||
applyPoison(victim, entity, 6);
|
||||
if (entity.getId() == 6998) {
|
||||
applyPoison(victim, entity, 40);
|
||||
} else if (WildernessZone.getWilderness(entity) >= 50) {
|
||||
applyPoison(victim, entity, 30);
|
||||
}
|
||||
super.impact(entity, victim, state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2193,6 +2193,10 @@ fun dumpContainer(player: Player, container: core.game.container.Container): Int
|
|||
var dumpedCount = 0
|
||||
|
||||
run beginDepositing@{
|
||||
if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) {
|
||||
return@beginDepositing
|
||||
}
|
||||
|
||||
container.toArray().filterNotNull().forEach { item ->
|
||||
if (!bank.hasSpaceFor(item)) {
|
||||
sendMessage(player, "You have no more space in your bank.")
|
||||
|
|
@ -3046,11 +3050,18 @@ fun applyPoison (entity: Entity, source: Entity, severity: Int) {
|
|||
if(hasTimerActive<PoisonImmunity>(entity)) {
|
||||
return
|
||||
}
|
||||
if(entity.isPoisonImmune()) {
|
||||
return
|
||||
}
|
||||
val existingTimer = getTimer<Poison>(entity)
|
||||
|
||||
if (existingTimer != null) {
|
||||
existingTimer.severity = severity
|
||||
existingTimer.damageSource = source
|
||||
if (existingTimer.severity > severity) {
|
||||
return
|
||||
} else {
|
||||
existingTimer.severity = severity
|
||||
existingTimer.damageSource = source
|
||||
}
|
||||
} else {
|
||||
registerTimer(entity, spawnTimer<Poison>(source, severity))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,14 +20,11 @@ enum class God(vararg val validItems: Int) {
|
|||
Items.BANDOS_TASSETS_11726,
|
||||
),
|
||||
SARADOMIN(
|
||||
Items.ANCIENT_SYMBOL_11181,
|
||||
Items.GILDED_KITESHIELD_3489,
|
||||
Items.DAMAGED_BOOK_3839,
|
||||
Items.HOLY_BOOK_3840,
|
||||
Items.HOLY_SYMBOL_1718,
|
||||
Items.HOLY_SYMBOL_4682,
|
||||
Items.MONKS_ROBE_542,
|
||||
Items.MONKS_ROBE_544,
|
||||
Items.RUNE_HERALDIC_HELM_8488,
|
||||
Items.SARADOMIN_BRACERS_10384,
|
||||
Items.SARADOMIN_CAPE_2412,
|
||||
Items.SARADOMIN_CHAPS_10388,
|
||||
|
|
@ -43,26 +40,16 @@ enum class God(vararg val validItems: Int) {
|
|||
Items.SARADOMIN_PLATEBODY_2661,
|
||||
Items.SARADOMIN_PLATELEGS_2663,
|
||||
Items.SARADOMIN_PLATESKIRT_3479,
|
||||
Items.SARADOMIN_PLATESKIRT_3675,
|
||||
Items.SARADOMIN_ROBE_LEGS_10464,
|
||||
Items.SARADOMIN_ROBE_TOP_10458,
|
||||
Items.SARADOMIN_STAFF_2415,
|
||||
Items.SARADOMIN_STOLE_10470,
|
||||
Items.SARADOMIN_SWORD_11730,
|
||||
Items.SARADOMIN_SYMBOL_8055,
|
||||
Items.STEEL_HERALDIC_HELM_8706,
|
||||
),
|
||||
ZAMORAK(
|
||||
Items.DAGONHAI_HAT_14499,
|
||||
Items.DAGONHAI_ROBE_TOP_14497,
|
||||
Items.DAGONHAI_ROBE_BOTTOM_14501,
|
||||
Items.DAMAGED_BOOK_3841,
|
||||
Items.RUNE_HERALDIC_HELM_8494,
|
||||
Items.STEEL_HERALDIC_HELM_8712,
|
||||
Items.UNHOLY_BOOK_3842,
|
||||
Items.UNHOLY_SYMBOL_1724,
|
||||
Items.UNHOLY_SYMBOL_3852,
|
||||
Items.UNHOLY_SYMBOL_4683,
|
||||
Items.ZAMORAK_BRACERS_10368,
|
||||
Items.ZAMORAK_CAPE_2414,
|
||||
Items.ZAMORAK_CHAPS_10372,
|
||||
|
|
@ -81,19 +68,17 @@ enum class God(vararg val validItems: Int) {
|
|||
Items.ZAMORAK_PLATEBODY_2653,
|
||||
Items.ZAMORAK_PLATELEGS_2655,
|
||||
Items.ZAMORAK_PLATESKIRT_3478,
|
||||
Items.ZAMORAK_PLATESKIRT_3674,
|
||||
Items.ZAMORAK_ROBE_LEGS_10468,
|
||||
Items.ZAMORAK_ROBE_TOP_10460,
|
||||
Items.ZAMORAK_ROBE_TOP_10786,
|
||||
Items.ZAMORAK_STAFF_2417,
|
||||
Items.ZAMORAK_STOLE_10474,
|
||||
Items.ZAMORAK_SYMBOL_8056,
|
||||
Items.ZAMORAK_ROBE_1033,
|
||||
Items.ZAMORAK_ROBE_1035,
|
||||
),
|
||||
GUTHIX(
|
||||
Items.STEEL_HERALDIC_HELM_8692,
|
||||
Items.RUNE_HERALDIC_HELM_8474,
|
||||
Items.DAMAGED_BOOK_3843,
|
||||
Items.BOOK_OF_BALANCE_3844,
|
||||
Items.GUTHIX_BRACERS_10376,
|
||||
Items.GUTHIX_CAPE_10720,
|
||||
Items.GUTHIX_CHAPS_10380,
|
||||
|
|
@ -102,24 +87,18 @@ enum class God(vararg val validItems: Int) {
|
|||
Items.GUTHIX_CROZIER_10442,
|
||||
Items.GUTHIX_DRAGONHIDE_10378,
|
||||
Items.GUTHIX_DRAGONHIDE_10794,
|
||||
Items.GUTHIX_FULL_HELM_13833,
|
||||
Items.GUTHIX_FULL_HELM_2673,
|
||||
Items.GUTHIX_KITESHIELD_13834,
|
||||
Items.GUTHIX_KITESHIELD_2675,
|
||||
Items.GUTHIX_MITRE_10454,
|
||||
Items.GUTHIX_MJOLNIR_6760,
|
||||
Items.GUTHIX_PLATEBODY_10780,
|
||||
Items.GUTHIX_PLATEBODY_2669,
|
||||
Items.GUTHIX_PLATEBODY_13830,
|
||||
Items.GUTHIX_PLATELEGS_2671,
|
||||
Items.GUTHIX_PLATELEGS_13831,
|
||||
Items.GUTHIX_PLATESKIRT_13832,
|
||||
Items.GUTHIX_PLATESKIRT_3676,
|
||||
Items.GUTHIX_ROBE_LEGS_10466,
|
||||
Items.GUTHIX_ROBE_TOP_10462,
|
||||
Items.GUTHIX_ROBE_TOP_10788,
|
||||
Items.GUTHIX_STAFF_2416,
|
||||
Items.GUTHIX_STOLE_10472,
|
||||
Items.GUTHIX_SYMBOL_8057,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,27 +42,48 @@ open class WeightBasedTable : ArrayList<WeightedItem>() {
|
|||
return roll(receiver, 1)
|
||||
}
|
||||
|
||||
open fun roll(receiver: Entity? = null, times: Int = 1): ArrayList<Item>{
|
||||
val items = ArrayList<WeightedItem>((guaranteedItems.size + 1) * times)
|
||||
open fun roll(receiver: Entity?, times: Int = 1): ArrayList<Item> {
|
||||
val weightedItemsToDrop = ArrayList<WeightedItem>()
|
||||
|
||||
for (i in 0 until times) {
|
||||
items.addAll(guaranteedItems)
|
||||
repeat(times) {
|
||||
// Guaranteed items
|
||||
for (item in guaranteedItems) {
|
||||
if (isSpecialSlot(item.id)) {
|
||||
val rolls = RandomFunction.random(item.minAmt, item.maxAmt)
|
||||
repeat(rolls) {
|
||||
weightedItemsToDrop.add(item)
|
||||
}
|
||||
} else {
|
||||
// Add just one instance with amount set by getItem()
|
||||
weightedItemsToDrop.add(item)
|
||||
}
|
||||
}
|
||||
|
||||
if (size == 1) {
|
||||
items.add(get(0))
|
||||
} else if (isNotEmpty()) {
|
||||
// Weighted roll (one per table roll)
|
||||
if (isNotEmpty()) {
|
||||
var rngWeight = RandomFunction.randomDouble(totalWeight)
|
||||
for (item in this) {
|
||||
rngWeight -= item.weight
|
||||
if (rngWeight <= 0) {
|
||||
items.add(item)
|
||||
if (isSpecialSlot(item.id)) {
|
||||
val rolls = RandomFunction.random(item.minAmt, item.maxAmt)
|
||||
repeat(rolls) {
|
||||
weightedItemsToDrop.add(item)
|
||||
}
|
||||
} else {
|
||||
weightedItemsToDrop.add(item)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return convertWeightedItems(items, receiver)
|
||||
return convertWeightedItems(weightedItemsToDrop, receiver)
|
||||
}
|
||||
|
||||
private fun isSpecialSlot(id: Int): Boolean {
|
||||
return id == SLOT_HDT || id == SLOT_USDT // extend this if a drop table is not dropping multiple times
|
||||
}
|
||||
|
||||
fun convertWeightedItems(weightedItems: ArrayList<WeightedItem>, receiver: Entity?): ArrayList<Item> {
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ abstract class DialogueFile {
|
|||
return true
|
||||
}
|
||||
else if (validTopics.size == 1) {
|
||||
val topic = topics[0]
|
||||
val topic = topics.filter { it.text == validTopics[0] }[0]
|
||||
if(topic.toStage is DialogueFile) {
|
||||
val topicFile = topic.toStage as DialogueFile
|
||||
interpreter!!.dialogue.loadFile(topicFile)
|
||||
|
|
|
|||
|
|
@ -328,7 +328,6 @@ public final class DialogueInterpreter {
|
|||
public Component sendItemMessage(int itemId, String... messages) {
|
||||
// Select interface based on number of messages - 241 (1 line) to 244 (4 lines)
|
||||
int interfaceId = 240 + messages.length;
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, false);
|
||||
player.getPacketDispatch().sendInterfaceConfig(interfaceId, 2, false);
|
||||
// Hide or empty the title, since double item messages do not have them. (Child 3)
|
||||
|
|
@ -344,6 +343,8 @@ public final class DialogueInterpreter {
|
|||
player.getPacketDispatch().sendRepositionOnInterface(interfaceId, 2, 45, 46);
|
||||
// Hide the second item which seems to be used for double items (child 1)
|
||||
player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, true);
|
||||
// Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title)
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
// These are old interfaces which made no sense to use them.
|
||||
// player.getPacketDispatch().sendString(message, 131, 1);
|
||||
// player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2);
|
||||
|
|
@ -385,7 +386,6 @@ public final class DialogueInterpreter {
|
|||
public Component sendDoubleItemMessage(Item first, Item second, String... messages) {
|
||||
// Select interface based on number of messages - 241 (1 line) to 244 (4 lines)
|
||||
int interfaceId = 240 + messages.length;
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, false);
|
||||
player.getPacketDispatch().sendInterfaceConfig(interfaceId, 2, false);
|
||||
// Hide or empty the title, since double item messages do not have them.
|
||||
|
|
@ -404,7 +404,8 @@ public final class DialogueInterpreter {
|
|||
player.getPacketDispatch().sendItemOnInterface(second.getId(), second.getAmount(), interfaceId, 2);
|
||||
player.getPacketDispatch().sendAngleOnInterface(interfaceId, 2, (int)(itemDef2.getModelZoom() / 1.5), itemDef2.getModelRotationX(), itemDef2.getModelRotationY());
|
||||
player.getPacketDispatch().sendRepositionOnInterface(interfaceId, 2, 60, 65);
|
||||
|
||||
// Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title)
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
|
|
@ -518,7 +519,6 @@ public final class DialogueInterpreter {
|
|||
if (expression == -1) {
|
||||
expression = FacialExpression.HALF_GUILTY.getAnimationId();
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
player.getPacketDispatch().sendInterfaceConfig(interfaceId, 1, true);
|
||||
player.getPacketDispatch().sendInterfaceConfig(interfaceId, 2, false);
|
||||
player.getPacketDispatch().sendAnimationInterface(expression, interfaceId, 2);
|
||||
|
|
@ -537,6 +537,8 @@ public final class DialogueInterpreter {
|
|||
player.getPacketDispatch().sendString(doSubstitutions(player, messages[i]), interfaceId, (i + 4));
|
||||
}
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, false);
|
||||
// Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title)
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
|
|
@ -556,6 +558,7 @@ public final class DialogueInterpreter {
|
|||
for (int i = 0; i < options.length; i++) {
|
||||
player.getPacketDispatch().sendString(options[i].toString(), interfaceId, i + 2);
|
||||
}
|
||||
// Open the chatbox only after everything is set to avoid lag and flashing default strings (Line 1, Title)
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,13 +101,6 @@ class GrandExchange : StartupListener, Commands {
|
|||
PriceIndex.allowItem(id)
|
||||
notify(player, "Allowed ${getItemName(id)} for GE trade.")
|
||||
}
|
||||
|
||||
define("geprivacy", Privilege.STANDARD) {player, _ ->
|
||||
val current = getAttribute(player, "ge-exclude", false)
|
||||
val new = !current
|
||||
notify(player, "Your name is now ${if (new) colorize("%RHIDDEN") else colorize("%RSHOWN")}.")
|
||||
setAttribute(player, "/save:ge-exclude", new)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
@ -131,15 +124,11 @@ class GrandExchange : StartupListener, Commands {
|
|||
|
||||
@JvmStatic
|
||||
fun getRecommendedPrice(itemID: Int, from_bot: Boolean = false): Int {
|
||||
var base = max(PriceIndex.getValue(itemID), getItemDefPrice(itemID))
|
||||
var base = PriceIndex.getValue(itemID)
|
||||
if (from_bot) base = (max(BotPrices.getPrice(itemID), base) * 1.10).toInt()
|
||||
return base
|
||||
}
|
||||
|
||||
private fun getItemDefPrice(itemID: Int): Int {
|
||||
return max(itemDefinition(itemID).getConfiguration(ItemConfigParser.GE_PRICE) ?: 0, itemDefinition(itemID).value)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getOfferStats(itemID: Int, sale: Boolean) : String
|
||||
{
|
||||
|
|
@ -235,8 +224,7 @@ class GrandExchange : StartupListener, Commands {
|
|||
//GrandExchangeRecords.getInstance(player).update(offer)
|
||||
|
||||
if (offer.sell && !player.isArtificial) {
|
||||
val username = if (getAttribute(player, "ge-exclude", false)) "?????" else player.username
|
||||
Repository.sendNews(username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE.")
|
||||
sendNews(player.username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE.")
|
||||
}
|
||||
|
||||
if (ServerConstants.I_AM_A_CHEATER) {
|
||||
|
|
|
|||
|
|
@ -146,10 +146,7 @@ class GrandExchangeOffer() {
|
|||
visualize(player)
|
||||
stmt.close()
|
||||
|
||||
val username = if (getAttribute(player ?: return@run, "ge-exclude", false)) "?????"
|
||||
else player?.username ?: "?????"
|
||||
|
||||
Discord.postNewOffer(sell, itemID, offeredValue, amount, username)
|
||||
Discord.postNewOffer(sell, itemID, offeredValue, amount, player?.username ?: return@run)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package core.game.node.entity.combat
|
|||
import content.global.skill.skillcapeperks.SkillcapePerks
|
||||
import content.global.skill.slayer.SlayerEquipmentFlags
|
||||
import content.global.skill.slayer.SlayerManager
|
||||
import content.global.skill.slayer.Tasks
|
||||
import core.api.*
|
||||
import core.api.EquipmentSlot
|
||||
import core.game.container.impl.EquipmentContainer
|
||||
|
|
@ -114,16 +115,23 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag)
|
|||
val name = entity.equipment.getNew(3).name
|
||||
var damage = -1
|
||||
if (name.contains("(p++") || name.contains("(s)") || name.contains("(kp)")) {
|
||||
damage = 68
|
||||
damage = 30
|
||||
} else if (name.contains("(p+)")) {
|
||||
damage = 58
|
||||
damage = 25
|
||||
} else if (name.contains("(p)")) {
|
||||
damage = 48
|
||||
damage = 20
|
||||
}
|
||||
if (damage > -1 && RandomFunction.random(10) < 4) {
|
||||
applyPoison (victim, entity, damage)
|
||||
}
|
||||
}
|
||||
} else if (entity is NPC) {
|
||||
val poisonous = entity.isPoisonous
|
||||
val damage = entity.poisonSeverity()
|
||||
|
||||
if (poisonous && damage > -1 && RandomFunction.random(10) < 4) {
|
||||
applyPoison (victim, entity, damage)
|
||||
}
|
||||
}
|
||||
super.adjustBattleState(entity, victim, state)
|
||||
}
|
||||
|
|
@ -156,7 +164,10 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag)
|
|||
val amuletId = getItemFromEquipment(entity, EquipmentSlot.NECK)?.id ?: 0
|
||||
if ((amuletId == Items.SALVE_AMULET_4081 || amuletId == Items.SALVE_AMULETE_10588) && checkUndead(victimName)) {
|
||||
effectiveAttackLevel *= if (amuletId == Items.SALVE_AMULET_4081) 1.15 else 1.2
|
||||
} else if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) {
|
||||
} else if (getSlayerTask(entity)?.let { task ->
|
||||
val victimId = entity.properties.combatPulse?.getVictim()?.id ?: 0
|
||||
task.ids.contains(victimId) || (task == Tasks.KALPHITES && (victimId == 1158)) // Kalphite Queen phase 1
|
||||
} == true) {
|
||||
effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape
|
||||
if (getSlayerTask(entity)?.dragon == true && inEquipment(entity, Items.DRAGON_SLAYER_GLOVES_12862))
|
||||
effectiveAttackLevel *= 1.1
|
||||
|
|
@ -192,8 +203,12 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag)
|
|||
if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE))
|
||||
effectiveStrengthLevel *= styleStrengthBonus
|
||||
else effectiveStrengthLevel *= 64
|
||||
if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true)
|
||||
if (getSlayerTask(entity)?.let { task ->
|
||||
val victimId = entity.properties.combatPulse?.getVictim()?.id ?: 0
|
||||
task.ids.contains(victimId) || (task == Tasks.KALPHITES && (victimId == 1158)) // Kalphite Queen phase 1
|
||||
} == true) {
|
||||
effectiveStrengthLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape
|
||||
}
|
||||
|
||||
return (floor((0.5 + (effectiveStrengthLevel / 640.0))) * modifier).toInt()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,13 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) : CombatSwingHandl
|
|||
if (state.estimatedHit > 0 && damage > 8 && RandomFunction.random(10) < 4) {
|
||||
applyPoison(victim, entity, damage)
|
||||
}
|
||||
} else if (entity is NPC) {
|
||||
val poisonous = entity.isPoisonous
|
||||
val damage = entity.poisonSeverity()
|
||||
|
||||
if (poisonous && damage > -1 && RandomFunction.random(10) < 4) {
|
||||
applyPoison (victim, entity, damage)
|
||||
}
|
||||
}
|
||||
super.adjustBattleState(entity, victim, state)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package core.game.node.entity.combat.spell;
|
||||
|
||||
import content.global.skill.summoning.familiar.Familiar;
|
||||
import core.game.node.entity.combat.BattleState;
|
||||
import core.game.node.entity.combat.CombatStyle;
|
||||
import core.game.node.entity.combat.InteractionType;
|
||||
|
|
@ -13,6 +14,7 @@ import core.game.node.entity.player.link.SpellBookManager;
|
|||
import core.game.node.entity.player.link.audio.Audio;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.map.zone.impl.WildernessZone;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.game.world.update.flag.context.Graphics;
|
||||
import org.rs09.consts.Sounds;
|
||||
|
|
@ -106,27 +108,42 @@ public abstract class CombatSpell extends MagicSpell {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of possible targets for a multihitting spell.
|
||||
* @param entity The caster of the spell.
|
||||
* @param target The victim.
|
||||
* @param max The max amount of victims.
|
||||
* @return The list of targets.
|
||||
*/
|
||||
public List<Entity> getMultihitTargets(Entity entity, Entity target, int max) {
|
||||
List<Entity> list = new ArrayList<>(20);
|
||||
list.add(target);
|
||||
boolean npc = target instanceof NPC;
|
||||
for (Entity e : npc ? RegionManager.getSurroundingNPCs(target) : RegionManager.getSurroundingPlayers(target)) {
|
||||
if (e != target && e != entity && CombatStyle.MAGIC.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) {
|
||||
list.add(e);
|
||||
/**
|
||||
* Gets a list of valid targets for a multihitting spell.
|
||||
* @param entity The caster of the spell.
|
||||
* @param target The primary victim.
|
||||
* @param max The maximum number of extra victims that may be hit.
|
||||
* @return The list of targets (the primary target is always at index 0).
|
||||
*/
|
||||
public List<Entity> getMultihitTargets(Entity entity, Entity target, int max) {
|
||||
List<Entity> victims = new ArrayList<>(20);
|
||||
victims.add(target);
|
||||
|
||||
List<Entity> surrounding = new ArrayList<>();
|
||||
surrounding.addAll(RegionManager.getSurroundingPlayers(target));
|
||||
surrounding.addAll(RegionManager.getSurroundingNPCs(target));
|
||||
|
||||
for (Entity e : surrounding) {
|
||||
if (e == target || e == entity) {
|
||||
continue;
|
||||
}
|
||||
if (CombatStyle.MAGIC.getSwingHandler().canSwing(entity, e) == InteractionType.NO_INTERACT) {
|
||||
continue;
|
||||
}
|
||||
if (e instanceof Familiar) {
|
||||
Player owner = ((Familiar) e).getOwner();
|
||||
if (owner != entity && WildernessZone.getInstance().continueAttack(entity, owner, CombatStyle.MAGIC, true)) {
|
||||
victims.add(e);
|
||||
}
|
||||
} else {
|
||||
victims.add(e);
|
||||
}
|
||||
if (--max < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
return victims;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visualizes the impact.
|
||||
|
|
@ -235,4 +252,4 @@ public abstract class CombatSpell extends MagicSpell {
|
|||
return SPLASH_GRAPHIC;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -563,6 +563,14 @@ public class NPC extends Entity {
|
|||
return definition.getConfiguration(NPCConfigParser.POISON_IMMUNE, false);
|
||||
}
|
||||
|
||||
public boolean isPoisonous() {
|
||||
return definition.getConfiguration(NPCConfigParser.POISONOUS, false);
|
||||
}
|
||||
|
||||
public int poisonSeverity() {
|
||||
return definition.getConfiguration(NPCConfigParser.POISON_AMOUNT, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalizeDeath(Entity killer) {
|
||||
super.finalizeDeath(killer);
|
||||
|
|
|
|||
|
|
@ -617,10 +617,13 @@ public class Player extends Entity {
|
|||
if (this.isArtificial() && killer instanceof NPC) {
|
||||
return;
|
||||
}
|
||||
if (killer instanceof Player && killer.getName() != getName() /* happens if you died via typeless damage from an external cause, e.g. bugs in a dark cave without a light source */ && getWorldTicks() - killer.getAttribute("/save:last-murder-news", 0) >= 500) {
|
||||
Item wep = getItemFromEquipment((Player) killer, EquipmentSlot.WEAPON);
|
||||
sendNews(killer.getUsername() + " has murdered " + getUsername() + " with " + (wep == null ? "their fists." : (StringUtils.isPlusN(wep.getName()) ? "an " : "a ") + wep.getName()));
|
||||
killer.setAttribute("/save:last-murder-news", getWorldTicks());
|
||||
if (killer instanceof Player && killer.getName() != getName()) { // the latter happens if you died via typeless damage from an external cause, e.g. bugs in a dark cave without a light source
|
||||
long unixSeconds = System.currentTimeMillis() / 1000L;
|
||||
if (unixSeconds - killer.getAttribute("/save:last-murder-news", 0L) >= 300) {
|
||||
Item wep = getItemFromEquipment((Player) killer, EquipmentSlot.WEAPON);
|
||||
sendNews(killer.getUsername() + " has murdered " + getUsername() + " with " + (wep == null ? "their fists." : (StringUtils.isPlusN(wep.getName()) ? "an " : "a ") + wep.getName()));
|
||||
killer.setAttribute("/save:last-murder-news", unixSeconds);
|
||||
}
|
||||
}
|
||||
getPacketDispatch().sendMessage("Oh dear, you are dead!");
|
||||
incrementAttribute("/save:"+STATS_BASE+":"+STATS_DEATHS);
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@ public enum DiaryType {
|
|||
"Use Vigroy and Hajedy's cart service",
|
||||
"Earn 100% favour in the village of Tai Bwo Wannai Cleanup", // todo tai bwo wannai cleanup
|
||||
"Cook a spider on stick", // todo tai bwo wannai cleanup
|
||||
"Charter the Lady of the Waves from Cairn Isle to Port Khazard", // todo verify
|
||||
"Charter the Lady of the Waves from Cairn Isle to Port Khazard",
|
||||
"Cut a log from a teak tree",
|
||||
"Cut a log from a mahogany tree",
|
||||
"Catch a karambwan", // todo need Tai Bwo Wannai Trio
|
||||
"Exchange gems, a gout tuber, trading sticks for a machete", // todo
|
||||
"Use the gnome glider to travel to Karamja",
|
||||
"Grow a healthy fruit tree in the patch near Brimhaven", // todo verify
|
||||
"Trap a Horned Graahk", // todo need to implement pitfall trapping
|
||||
"Grow a healthy fruit tree in the patch near Brimhaven",
|
||||
"Trap a Horned Graahk",
|
||||
"Chop the vines to gain deeper access to Brimhaven Dungeon",
|
||||
"Cross the lava using the stepping stones within Brimhaven<br><br>Dungeon",
|
||||
"Climb the stairs within Brimhaven Dungeon",
|
||||
|
|
|
|||
|
|
@ -239,6 +239,14 @@ class FunCommandSet : CommandSet(Privilege.ADMIN) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle instant woodcutting.
|
||||
*/
|
||||
define("instachop", Privilege.ADMIN, "", "Fells trees after a single log is gathered."){ player, _ ->
|
||||
player.setAttribute("instachop", !player.getAttribute("instachop", false))
|
||||
notify(player,"Instachop mode " + if (player.getAttribute("instachop", false)) "on." else "off.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun bury(player: Player){
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import core.game.node.entity.player.info.Rights
|
|||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import core.game.node.scenery.Scenery
|
||||
import core.game.system.command.Command
|
||||
import core.game.system.command.CommandMapping
|
||||
import core.game.system.command.Privilege
|
||||
import core.game.system.communication.CommunicationInfo
|
||||
|
|
@ -223,11 +224,8 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
|
|||
*/
|
||||
define("commands", Privilege.STANDARD, "::commands <lt>page<gt>", "Lists all the commands (you are here.)"){player, args ->
|
||||
val page = if (args.size > 1) (args[1].toIntOrNull() ?: 1) - 1 else 0
|
||||
var lineid = 11
|
||||
var pages = CommandMapping.getPageIndices(player.rights.ordinal)
|
||||
var end = if (page < (pages.size - 1)) pages[page + 1] else CommandMapping.getCommands().size
|
||||
|
||||
player.interfaceManager.close()
|
||||
val pages = CommandMapping.getPageIndices(player.rights.ordinal)
|
||||
val end = if (page < (pages.size - 1)) pages[page + 1] else CommandMapping.getCommands().size
|
||||
|
||||
if (page < 0) {
|
||||
reject(player, "Usage: ::commands <lt>page<gt>")
|
||||
|
|
@ -237,44 +235,106 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
|
|||
reject(player, "That page number is too high, you don't have access to that many.")
|
||||
}
|
||||
|
||||
for (i in 0..310) {
|
||||
player.packetDispatch.sendString("", Components.QUESTJOURNAL_SCROLL_275, i)
|
||||
}
|
||||
val title = "Commands" + if (pages.size > 1) " (${page + 1}/${pages.size})" else ""
|
||||
var lineId = setupScrollInterface(player, title)
|
||||
|
||||
player.packetDispatch.sendString(
|
||||
"Commands" + if (pages.size > 1) " (${page + 1}/${pages.size})" else "",
|
||||
Components.QUESTJOURNAL_SCROLL_275,
|
||||
2
|
||||
)
|
||||
|
||||
|
||||
for(i in pages[page] until end) {
|
||||
var command = CommandMapping.getCommands()[i]
|
||||
var title = "${command.name}"
|
||||
var rights = command.privilege.ordinal
|
||||
var icon = rights - 1
|
||||
val command = CommandMapping.getCommands()[i]
|
||||
lineId = displayCommandInScroll(player, command, player.rights.ordinal, lineId)
|
||||
|
||||
|
||||
if (rights > player.rights.ordinal) continue
|
||||
|
||||
if (rights > 0)
|
||||
title = "(<img=$icon>) $title"
|
||||
|
||||
player.packetDispatch.sendString(title, Components.QUESTJOURNAL_SCROLL_275, lineid++)
|
||||
|
||||
if (command.usage.isNotEmpty())
|
||||
player.packetDispatch.sendString("Usage: ${command.usage}", Components.QUESTJOURNAL_SCROLL_275, lineid++)
|
||||
|
||||
if (command.description.isNotEmpty())
|
||||
player.packetDispatch.sendString(command.description, Components.QUESTJOURNAL_SCROLL_275, lineid++)
|
||||
|
||||
player.packetDispatch.sendString("<str>-------------------------------</str>", Components.QUESTJOURNAL_SCROLL_275, lineid++)
|
||||
|
||||
if (lineid > 306) {
|
||||
player.packetDispatch.sendString("To view the next page, use ::commands ${page + 2}", Components.QUESTJOURNAL_SCROLL_275, lineid)
|
||||
if (lineId > 306) {
|
||||
player.packetDispatch.sendString("To view the next page, use ::commands ${page + 2}", Components.QUESTJOURNAL_SCROLL_275, lineId)
|
||||
break
|
||||
}
|
||||
}
|
||||
player.interfaceManager.open(Component(Components.QUESTJOURNAL_SCROLL_275))
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for commands
|
||||
*/
|
||||
define("commandsearch", Privilege.STANDARD, "::commandsearch <lt>search term<gt> [--chat]", "Searches for commands containing the given term."){player, args ->
|
||||
if (args.size < 2) {
|
||||
reject(player, "Usage: ::commandsearch <search term> [--chat]")
|
||||
return@define
|
||||
}
|
||||
val rawArguments = args.copyOfRange(1, args.size)
|
||||
val chatMode = rawArguments.any { it.equals("--chat", ignoreCase = true) }
|
||||
val searchRaw = rawArguments.filterNot { it.equals("--chat", ignoreCase = true) }
|
||||
if (searchRaw.isEmpty()) {
|
||||
reject(player, "Usage: ::commandsearch <search term> [--chat]")
|
||||
return@define
|
||||
}
|
||||
val search = searchRaw.joinToString(" ").lowercase()
|
||||
if (search.length < 2) {
|
||||
reject(player, "Search term must be at least 2 characters long")
|
||||
return@define
|
||||
}
|
||||
val playerRights = player.rights.ordinal
|
||||
val allMatchingCommands = CommandMapping.getCommands()
|
||||
.filter { command ->
|
||||
command.name.lowercase().contains(search) ||
|
||||
command.usage.lowercase().contains(search) ||
|
||||
command.description.lowercase().contains(search)
|
||||
}
|
||||
if (allMatchingCommands.isEmpty()) {
|
||||
notify(player, "No commands found matching '$search'")
|
||||
return@define
|
||||
}
|
||||
val accessibleCommands = allMatchingCommands
|
||||
.filter { it.privilege.ordinal <= playerRights }
|
||||
.sortedBy { it.name }
|
||||
val inaccessibleCount = allMatchingCommands.count { it.privilege.ordinal > playerRights }
|
||||
if (chatMode) {
|
||||
for (command in accessibleCommands) {
|
||||
val cmdargs = if (command.usage.isNotEmpty()) {
|
||||
val parts = command.usage.split(" ", limit = 2)
|
||||
if (parts.size > 1) parts[1] else ""
|
||||
} else {
|
||||
""
|
||||
}
|
||||
val formattedMessage = if (cmdargs.isNotEmpty()) {
|
||||
"CMD: ${command.name} ARGS: $cmdargs DESC: ${command.description}"
|
||||
} else {
|
||||
"CMD: ${command.name} DESC: ${command.description}"
|
||||
}
|
||||
val chunks = chunkText(formattedMessage, 70)
|
||||
chunks.forEach { notify(player, it) }
|
||||
}
|
||||
if (accessibleCommands.isEmpty()) {
|
||||
notify(player, "Found $inaccessibleCount command(s) matching '$search' but you don't have permission to use any of them")
|
||||
} else {
|
||||
val summary = "Found ${accessibleCommands.size} accessible command(s) for '$search'"
|
||||
if (inaccessibleCount > 0) {
|
||||
notify(player, summary)
|
||||
notify(player, "($inaccessibleCount additional command(s) require higher privileges)")
|
||||
} else {
|
||||
notify(player, summary)
|
||||
}
|
||||
}
|
||||
return@define
|
||||
}
|
||||
var lineId = setupScrollInterface(player, "Command Search: '$search'")
|
||||
if (accessibleCommands.isEmpty()) {
|
||||
player.packetDispatch.sendString("No accessible commands found.", Components.QUESTJOURNAL_SCROLL_275, lineId++)
|
||||
}
|
||||
for (command in accessibleCommands) {
|
||||
lineId = displayCommandInScroll(player, command, playerRights, lineId)
|
||||
if (lineId > 306) {
|
||||
player.packetDispatch.sendString(
|
||||
"Results truncated. Use ::commandsearch $search --chat",
|
||||
Components.QUESTJOURNAL_SCROLL_275,
|
||||
lineId
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (inaccessibleCount > 0 && lineId <= 306) {
|
||||
player.packetDispatch.sendString(
|
||||
"$inaccessibleCount more command(s) need higher privileges.",
|
||||
Components.QUESTJOURNAL_SCROLL_275,
|
||||
lineId
|
||||
)
|
||||
}
|
||||
player.interfaceManager.open(Component(Components.QUESTJOURNAL_SCROLL_275))
|
||||
}
|
||||
|
|
@ -640,6 +700,63 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){
|
|||
}
|
||||
}
|
||||
|
||||
fun setupScrollInterface(player: Player, title: String): Int {
|
||||
player.interfaceManager.close()
|
||||
for (i in 0..310) {
|
||||
player.packetDispatch.sendString("", Components.QUESTJOURNAL_SCROLL_275, i)
|
||||
}
|
||||
player.packetDispatch.sendString(title, Components.QUESTJOURNAL_SCROLL_275, 2)
|
||||
return 11
|
||||
}
|
||||
|
||||
fun displayCommandInScroll(player: Player, command: Command, playerRights: Int, lineId: Int): Int {
|
||||
val privilegeLevel = command.privilege.ordinal
|
||||
if (privilegeLevel > playerRights) return lineId
|
||||
val titleIcon = privilegeLevel - 1
|
||||
var title = command.name
|
||||
if (privilegeLevel > 0) {
|
||||
title = "(<img=$titleIcon>) $title"
|
||||
}
|
||||
var currentLineId = lineId
|
||||
player.packetDispatch.sendString(title, Components.QUESTJOURNAL_SCROLL_275, currentLineId++)
|
||||
if (command.usage.isNotEmpty()) {
|
||||
val usageText = "Usage: ${command.usage}"
|
||||
val usageChunks = chunkText(usageText, 70)
|
||||
for (chunk in usageChunks) {
|
||||
player.packetDispatch.sendString(chunk, Components.QUESTJOURNAL_SCROLL_275, currentLineId++)
|
||||
}
|
||||
}
|
||||
if (command.description.isNotEmpty()) {
|
||||
val descChunks = chunkText(command.description, 70)
|
||||
for (chunk in descChunks) {
|
||||
player.packetDispatch.sendString(chunk, Components.QUESTJOURNAL_SCROLL_275, currentLineId++)
|
||||
}
|
||||
}
|
||||
player.packetDispatch.sendString("<str>-------------------------------</str>", Components.QUESTJOURNAL_SCROLL_275, currentLineId++)
|
||||
return currentLineId
|
||||
}
|
||||
|
||||
fun chunkText(text: String, maxLength: Int = 70): List<String> {
|
||||
if (text.length <= maxLength) return listOf(text)
|
||||
val chunks = mutableListOf<String>()
|
||||
var remaining = text
|
||||
while (remaining.length > maxLength) {
|
||||
var breakPoint = maxLength
|
||||
for (i in maxLength downTo 1) {
|
||||
if (remaining[i - 1] == ' ') {
|
||||
breakPoint = i
|
||||
break
|
||||
}
|
||||
}
|
||||
chunks.add(remaining.take(breakPoint).trim())
|
||||
remaining = remaining.substring(breakPoint).trim()
|
||||
}
|
||||
if (remaining.isNotEmpty()) {
|
||||
chunks.add(remaining)
|
||||
}
|
||||
return chunks
|
||||
}
|
||||
|
||||
fun setPlaqueReadStatus(player: Player, status: Boolean){
|
||||
// For some reason the loop has to be this way to have read write access
|
||||
for (i in 0 until player.savedData.globalData.readPlaques.size){
|
||||
|
|
|
|||
|
|
@ -20,14 +20,6 @@ class Poison : PersistTimer (30, "poison", flags = arrayOf(TimerFlag.ClearOnDeat
|
|||
lateinit var damageSource: Entity
|
||||
|
||||
var severity = 0
|
||||
set (value) {
|
||||
if (value != field - 1 && value % 10 == 8) {//This was Arios's incorrect attempt at replicating severity, convert it to correct values.
|
||||
(damageSource as? Player)?.debug ("[PoisonTimer] Warning: Converting suspect Arios severity into true severity. If numbers look wrong, this could be why.")
|
||||
field = (value / 10) * 5
|
||||
(damageSource as? Player)?.debug ("[PoisonTimer] Warning: New Severity: $field.")
|
||||
} else field = value
|
||||
}
|
||||
|
||||
override fun save (root: JSONObject, entity: Entity) {
|
||||
root["source-uid"] = (damageSource as? Player)?.details?.uid ?: -1
|
||||
root["severity"] = severity.toString()
|
||||
|
|
|
|||
|
|
@ -31,11 +31,7 @@ class PoisonImmunity : PersistTimer (1, "poison:immunity", isSoft = true, flags
|
|||
override fun run (entity: Entity) : Boolean {
|
||||
ticksRemaining--
|
||||
|
||||
if (entity is Player && ticksRemaining == secondsToTicks(30)) {
|
||||
sendMessage(entity, colorize("%RYou have 30 seconds remaining on your poison immunity."))
|
||||
playAudio(entity, Sounds.CLOCK_TICK_1_3120, 0, 3)
|
||||
}
|
||||
else if (entity is Player && ticksRemaining == 0) {
|
||||
if (entity is Player && ticksRemaining == 0) {
|
||||
sendMessage(entity, colorize("%RYour poison immunity has expired."))
|
||||
playAudio(entity, Sounds.DRAGON_POTION_FINISHED_2607)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ class Skulled : PersistTimer (1, "skulled", flags = arrayOf(TimerFlag.ClearOnDea
|
|||
return false
|
||||
}
|
||||
|
||||
override fun onRemoval (entity: Entity) {
|
||||
if (entity !is Player) return
|
||||
entity.skullManager.reset()
|
||||
}
|
||||
|
||||
override fun getTimer (vararg args: Any) : RSTimer {
|
||||
val t = Skulled()
|
||||
t.runInterval = args.getOrNull(0) as? Int ?: 500
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import core.api.*
|
|||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.impl.WildernessZone
|
||||
import content.region.wilderness.handlers.KingBlackDragonArea
|
||||
import core.game.world.map.zone.MapZone
|
||||
import core.game.world.map.zone.ZoneBuilder
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.rs09.consts.Items
|
||||
|
|
@ -132,6 +135,28 @@ class RandomEventTests {
|
|||
}
|
||||
}
|
||||
|
||||
@Test fun randomEventShouldNotSpawnInKingBlackDragonLair() {
|
||||
TestUtils.getMockPlayer("antimacronospawninkbdlair").use { p ->
|
||||
val timer = getTimer<AntiMacro>(p) ?: Assertions.fail("AntiMacro timer was null!")
|
||||
TestUtils.advanceTicks(5, false)
|
||||
|
||||
// Manually configure KBD lair zone like ClassScanner does for MapArea instances
|
||||
val kbdArea = KingBlackDragonArea()
|
||||
val zone = object : MapZone(kbdArea.javaClass.simpleName + "MapArea", true, *kbdArea.getRestrictions()) {}
|
||||
for(border in kbdArea.defineAreaBorders()) zone.register(border)
|
||||
ZoneBuilder.configure(zone)
|
||||
|
||||
val kbdLocation = Location.create(2273, 4698, 0) // KBD spawn location
|
||||
p.location = kbdLocation
|
||||
|
||||
Assertions.assertEquals(kbdLocation, p.location)
|
||||
|
||||
timer.nextExecution = getWorldTicks() + 5
|
||||
TestUtils.advanceTicks(10, false)
|
||||
Assertions.assertNull(AntiMacro.getEventNpc(p), "Random event should not spawn in KBD lair but one was found!")
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME
|
||||
//@Test fun randomEventShouldNotSpawnIfOneAlreadyActive() {
|
||||
// TestUtils.getMockPlayer("antimacronospawnifalreadyhas").use { p ->
|
||||
|
|
|
|||
93
build
93
build
|
|
@ -2,139 +2,90 @@
|
|||
|
||||
SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P)
|
||||
|
||||
BUILD_MS=0
|
||||
CLEAN=0
|
||||
BUILD_GS=0
|
||||
CLEAN_MS=0
|
||||
CLEAN_GS=0
|
||||
SKIPTEST=""
|
||||
|
||||
GS_SRC=$SCRIPT_DIR/Server
|
||||
MS_SRC=$SCRIPT_DIR/Management-Server
|
||||
|
||||
CLEANOPT=""
|
||||
_JAR_DIR="$SCRIPT_DIR/builddir"
|
||||
|
||||
help()
|
||||
{
|
||||
echo "Usage: $0 [-h] <-m | -g> [-c <m|g>] [-o <path>]";
|
||||
echo "Usage: $0 [-h] [-q] <-g|-c> [-o <path>]";
|
||||
echo " -h: Display this message.";
|
||||
echo " -m: Build the management server.";
|
||||
echo " -g: Build the game server.";
|
||||
echo " -c: Clean: m: management, g: gameserver. "
|
||||
echo " Can specify both. Need at least one if present.";
|
||||
echo " -o: Specify jar-file directory."
|
||||
echo " -c: Clean previous build.";
|
||||
echo " -o: Specify jar-file directory.";
|
||||
echo " -q: Quick build - will skip tests.";
|
||||
}
|
||||
|
||||
error()
|
||||
{
|
||||
echo $1;
|
||||
exit -1;
|
||||
}
|
||||
|
||||
clean_ms()
|
||||
{
|
||||
cd $MS_SRC
|
||||
|
||||
if [[ "$CLEANOPT" == *"m"* ]]; then
|
||||
echo "Cleaning the management server."
|
||||
sh mvnw clean || error "Failed to clean the MS."
|
||||
fi
|
||||
echo "$1";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
clean_gs()
|
||||
{
|
||||
cd $GS_SRC;
|
||||
if [[ "$CLEANOPT" == *"g"* ]]; then
|
||||
cd $GS_SRC || error "Could not change dir to game server directory."
|
||||
echo "Cleaning the game server."
|
||||
sh mvnw clean || error "Failed to clean the game server. Giving up."
|
||||
fi
|
||||
}
|
||||
|
||||
build_ms()
|
||||
{
|
||||
cd $MS_SRC
|
||||
|
||||
sh mvnw package $SKIPTEST || \
|
||||
error "Failed to build the management server. Giving up";
|
||||
sh mvnw clean || error "Failed to clean the game server. Giving up."
|
||||
}
|
||||
|
||||
build_gs()
|
||||
{
|
||||
cd $GS_SRC;
|
||||
cd "$GS_SRC" || error "ERROR: Could not chdir to server src. Abort."
|
||||
|
||||
sh mvnw package $SKIPTEST || \
|
||||
error "Failed to build the game server. Giving up."
|
||||
}
|
||||
|
||||
while getopts "hqmgc:o:d" arg; do
|
||||
while getopts "hqgc:o:d" arg; do
|
||||
case $arg in
|
||||
h)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
m)
|
||||
BUILD_MS=1
|
||||
;;
|
||||
g)
|
||||
BUILD_GS=1
|
||||
;;
|
||||
c)
|
||||
CLEANOPT=${OPTARG}
|
||||
CLEAN=1
|
||||
;;
|
||||
o)
|
||||
_JAR_DIR=${OPTARG}
|
||||
;;
|
||||
d)
|
||||
echo "BUILD_MS=$BUILD_MS"
|
||||
echo "BUILD_GS=$BUILD_GS"
|
||||
echo "CLEANOPT=$CLEANOPT"
|
||||
echo "_JAR_DIR=$_JAR_DIR"
|
||||
;;
|
||||
q)
|
||||
SKIPTEST="-DskipTests"
|
||||
;;
|
||||
*)
|
||||
error "Argument -$arg is not a known or valid argument."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $CLEANOPT != "m" ]] \
|
||||
&& [[ $CLEANOPT != "g" ]] \
|
||||
&& [[ $CLEANOPT != "mg" ]] \
|
||||
&& [[ $CLEANOPT != "" ]];
|
||||
then
|
||||
error "Invalid cleaning option '$CLEANOPT'. Valid options are 'm', 'g', 'mg' or none."
|
||||
if [ $BUILD_GS -eq 0 ] && [ $CLEAN -eq 0 ]; then
|
||||
error "Need to either build or clean at least. See -h for details."
|
||||
fi
|
||||
|
||||
if [ $BUILD_MS -eq 0 ] && [ $BUILD_GS -eq 0 ] && [[ $CLEANOPT == "" ]]; then
|
||||
error "Need to build or clean at least one of the modules. See -h for details."
|
||||
fi
|
||||
# Inside func is cd so mgmt prob fails if no condition
|
||||
(( CLEAN )) && clean_gs
|
||||
|
||||
# Conditionals inside the functions.
|
||||
clean_gs
|
||||
clean_ms
|
||||
# -----------
|
||||
|
||||
if [ -d $_JAR_DIR ]; then
|
||||
rm -r $_JAR_DIR
|
||||
if [ -d "$_JAR_DIR" ]; then
|
||||
rm -r "$_JAR_DIR"
|
||||
fi
|
||||
|
||||
if [ $BUILD_MS -ne 1 ] && [ $BUILD_GS -ne 1 ]; then
|
||||
echo "No build options specified. Stop."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p $_JAR_DIR || error "Failed to create build directory.";
|
||||
|
||||
if [ $BUILD_MS -eq 1 ]; then
|
||||
build_ms
|
||||
|
||||
# Will never execute if build_ms fails because it quits upon failure.
|
||||
mv -v $MS_SRC/target/*-with-dependencies.jar $_JAR_DIR/ms.jar
|
||||
fi
|
||||
mkdir -p "$_JAR_DIR" || error "Failed to create build directory.";
|
||||
|
||||
if [ $BUILD_GS -eq 1 ]; then
|
||||
build_gs
|
||||
|
||||
# Will never execute if build_gs fails because it quits upon failure.
|
||||
mv -v $GS_SRC/target/*-with-dependencies.jar $_JAR_DIR/server.jar
|
||||
mv -v "$GS_SRC"/target/*-with-dependencies.jar "$_JAR_DIR"/server.jar
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -1,29 +1,33 @@
|
|||
version: '3.3'
|
||||
services:
|
||||
app:
|
||||
server:
|
||||
build: .
|
||||
container_name: "2009scape_app"
|
||||
depends_on:
|
||||
- database
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "2009scape_app:/app"
|
||||
ports:
|
||||
- "43595:43595"
|
||||
|
||||
database:
|
||||
image: mysql:5.7
|
||||
container_name: "2009scape_db"
|
||||
- db
|
||||
restart: always
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- "2009scape_db:/var/lib/mysql"
|
||||
- "bcache:/app/Server/target"
|
||||
- "mcache:/root/.m2"
|
||||
- "./Server/data:/app/Server/data"
|
||||
- "./config:/app/Server/worldprops"
|
||||
ports:
|
||||
- "43594-43600:43594-43600"
|
||||
|
||||
db:
|
||||
# current LTS (Long-Term Support) version
|
||||
image: mariadb:11.4-noble
|
||||
healthcheck:
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
start_period: 30s
|
||||
interval: 60s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
restart: always
|
||||
volumes:
|
||||
- "./db:/var/lib/mysql"
|
||||
- "./Server/db_exports/global.sql:/docker-entrypoint-initdb.d/global.sql"
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
||||
MYSQL_ROOT_PASSWORD: ""
|
||||
MYSQL_ROOT_USER: "root"
|
||||
env_file:
|
||||
- mysql.env
|
||||
|
||||
volumes:
|
||||
2009scape_app:
|
||||
2009scape_db:
|
||||
bcache:
|
||||
mcache:
|
||||
|
|
|
|||
20
mysql.env.example
Normal file
20
mysql.env.example
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Prefer no and generating a strong password for the root (+ special) user
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD="no"
|
||||
|
||||
# You can change the db name also for obscurity.
|
||||
# Has to be changed in the default.conf and in the global.sql init file then also.
|
||||
MYSQL_DATABASE="global"
|
||||
|
||||
# Beware: if not using root user, the database 'global' requires granting permissions for that user
|
||||
# Root user is created automatically so dont provide it here.
|
||||
#MYSQL_USER="dbuser"
|
||||
#MYSQL_PASSWORD="CHANGEMEIFNOTUSINGROOTANDINGLOBALCONF"
|
||||
|
||||
# Comment this out if you are using random root pw (below).
|
||||
MYSQL_ROOT_PASSWORD="ALWAYSCHANGEMEHEREANDINGLOBALCONFIFUSINGROOT"
|
||||
|
||||
# Or you can use a special non-root db user and generate a random pw for the root user instead.
|
||||
# To improve security
|
||||
# However, either initial root user access
|
||||
# or editing Server/db_exports/global.sql to add grants for 'global' to the special user above.
|
||||
MYSQL_RANDOM_ROOT_PASSWORD="no"
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue