mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-09-10 18:46:39 -06:00
Compare commits
No commits in common. "master" and "Apr-19-2026" have entirely different histories.
master
...
Apr-19-202
3504 changed files with 228098 additions and 2175873 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
variables:
|
variables:
|
||||||
# This will suppress any download for dependencies and plugins or upload messages which would clutter the console log.
|
# This will suppress any download for dependencies and plugins or upload messages which would clutter the console log.
|
||||||
# `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
|
# `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
|
||||||
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true -Xmx4g -Xms2g"
|
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true -Xmx3g"
|
||||||
# As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
|
# As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
|
||||||
# when running from the command line.
|
# when running from the command line.
|
||||||
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-fast --show-version"
|
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-fast --show-version"
|
||||||
|
|
|
||||||
49
README.md
49
README.md
|
|
@ -29,7 +29,6 @@
|
||||||
* [Prerequisites](#prerequisites)
|
* [Prerequisites](#prerequisites)
|
||||||
* [Project Setup](#project-setup)
|
* [Project Setup](#project-setup)
|
||||||
* [Running the project](#running-the-project)
|
* [Running the project](#running-the-project)
|
||||||
* [Browser WebSocket Transport](#browser-websocket-transport)
|
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
* [Contact](#contact)
|
* [Contact](#contact)
|
||||||
|
|
||||||
|
|
@ -81,20 +80,6 @@ There are many ways everyone can contribute! From the most seasoned programmers
|
||||||
|
|
||||||
* **Code Contributors**: As a remake, we have massive amounts of content that need to be implemented or corrected. If you know how to program or are willing to learn, this is where you could be extremely helpful! We need everything from quests, to dialogue, to mini-games, to skills that still need to be corrected or implemented. This is perhaps one of the most valuable ways someone could help out the project! If you are interested in developing content, reach out in the development channel of the Discord.
|
* **Code Contributors**: As a remake, we have massive amounts of content that need to be implemented or corrected. If you know how to program or are willing to learn, this is where you could be extremely helpful! We need everything from quests, to dialogue, to mini-games, to skills that still need to be corrected or implemented. This is perhaps one of the most valuable ways someone could help out the project! If you are interested in developing content, reach out in the development channel of the Discord.
|
||||||
|
|
||||||
|
|
||||||
### Policy on Use of AI Tools
|
|
||||||
|
|
||||||
You, the contributor, agree to submit quality code to the best of your ability which you have tested yourself and confirmed that it works as intended, and if it doesn’t work, you agree to take constructive feedback and fix it.
|
|
||||||
|
|
||||||
You should be able to explain or defend how any part of your code works, without the use of AI or any other assistive tools.
|
|
||||||
|
|
||||||
2009scape reserves the right to reject your MR on grounds of poor quality, poor functionality, poor code style, poor attitudes or unethical over-reliance on assistive tools.
|
|
||||||
|
|
||||||
2009scape reserves the right to bar an individual from contributing due to patterns of aforementioned behavior, and close or delete all future MRs or issues or suggestions from said person without given explanation.
|
|
||||||
|
|
||||||
AI may not be used to generate your MR description, your issue description, or any responses to any discourse present on the Gitlab at any time or in any fashion. If you use AI in any of these places, it will be assumed that your entire contribution is AI and that you have no clue how it functions, and the remainder of the policy outlined above will be applied to you immediately.
|
|
||||||
|
|
||||||
|
|
||||||
## Content Developers: Setting Up the Project.
|
## Content Developers: Setting Up the Project.
|
||||||
### GitLab Setup
|
### GitLab Setup
|
||||||
**Note: This allows you to commit changes to the main repo (with approval)! Also, always stay up to date with the most recent updates by pulling into your copy when 2009Scape updates!**
|
**Note: This allows you to commit changes to the main repo (with approval)! Also, always stay up to date with the most recent updates by pulling into your copy when 2009Scape updates!**
|
||||||
|
|
@ -140,40 +125,6 @@ Start the game server with the included run script. Use `./run -h` for more info
|
||||||
|
|
||||||
Start the game server with `run-server.bat`
|
Start the game server with `run-server.bat`
|
||||||
|
|
||||||
#### Browser WebSocket Transport
|
|
||||||
|
|
||||||
Enable the listener in `Server/worldprops/default.conf`:
|
|
||||||
|
|
||||||
```properties
|
|
||||||
websocket_enabled = true
|
|
||||||
websocket_port = 0
|
|
||||||
```
|
|
||||||
|
|
||||||
When `websocket_port = 0`, the listener uses `53594 + world_id`. For world `1`, that is `53595`.
|
|
||||||
|
|
||||||
Both plain WebSocket (`ws://`) and secure WebSocket (`wss://`) are supported. Use `ws://` for local HTTP testing. PWA requires HTTPS/WSS.
|
|
||||||
|
|
||||||
Enable WSS with a Java keystore:
|
|
||||||
|
|
||||||
```properties
|
|
||||||
websocket_tls_enabled = true
|
|
||||||
websocket_tls_keystore_path = "certs/dev-wss.p12"
|
|
||||||
websocket_tls_keystore_password = "<keystore-password>"
|
|
||||||
```
|
|
||||||
|
|
||||||
The keystore password is optional. Leave `websocket_tls_keystore_password` blank when using a PKCS12 file exported with an empty password:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
openssl pkcs12 -export \
|
|
||||||
-in fullchain.pem \
|
|
||||||
-inkey privkey.pem \
|
|
||||||
-out certs/dev-wss.p12 \
|
|
||||||
-name websocket \
|
|
||||||
-passout pass:
|
|
||||||
```
|
|
||||||
|
|
||||||
For local WSS development, create a certificate for your hostname or LAN IP that the browser will use, then point the server at a PKCS12 keystore. For production, use a normal certificate from certbot. Plain WS does not require a certificate.
|
|
||||||
|
|
||||||
#### Docker
|
#### Docker
|
||||||
|
|
||||||
Make sure [Docker Engine](https://docs.docker.com/engine/install/) & [Docker Compose](https://docs.docker.com/compose/install/) plugin are installed first:
|
Make sure [Docker Engine](https://docs.docker.com/engine/install/) & [Docker Compose](https://docs.docker.com/compose/install/) plugin are installed first:
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="Debug Server (Docker)" type="Remote">
|
|
||||||
<option name="USE_SOCKET_TRANSPORT" value="true" />
|
|
||||||
<option name="SERVER_MODE" value="false" />
|
|
||||||
<option name="SHMEM_ADDRESS" />
|
|
||||||
<option name="HOST" value="localhost" />
|
|
||||||
<option name="PORT" value="5005" />
|
|
||||||
<option name="AUTO_RESTART" value="false" />
|
|
||||||
<RunnerSettings RunnerId="Debug">
|
|
||||||
<option name="DEBUG_PORT" value="5005" />
|
|
||||||
<option name="LOCAL" value="false" />
|
|
||||||
</RunnerSettings>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
||||||
27
Server/data/ObjectParser.xml
Normal file
27
Server/data/ObjectParser.xml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<parsing>
|
||||||
|
<ObjectAction mode="add" id="1814" x="3090" y="3475" z="0" type="4" direction="nw"/>
|
||||||
|
<ObjectAction mode="add" id="2646" x="2445" y="3413" z="0" direction="nw"/>
|
||||||
|
<ObjectAction mode="add" id="2646" x="2447" y="3414" z="0" direction="e"/>
|
||||||
|
<ObjectAction mode="add" id="2646" x="2447" y="3421" z="0" direction="nw"/>
|
||||||
|
|
||||||
|
<ObjectAction mode="remove" id="37670" x="3292" y="3299" z="0"/>
|
||||||
|
<ObjectAction mode="add" id="37304" x="3292" y="3299" z="0"/>
|
||||||
|
|
||||||
|
<ObjectAction mode="add" id="20987" x="3821" y="2996" z="0"/>
|
||||||
|
|
||||||
|
<ObjectAction mode="remove" id="356" x="2804" y="3428" z="0"/>
|
||||||
|
<ObjectAction mode="add" id="356" x="2804" y="3428" z="0"/>
|
||||||
|
|
||||||
|
<ObjectAction mode="remove" id="20228" x="2537" y="3573" z="0"/>
|
||||||
|
<ObjectAction mode="add" id="27663" x="2537" y="3573" z="0" direction="w"/>
|
||||||
|
|
||||||
|
|
||||||
|
<ObjectAction mode="add" id="39237" x="2957" y="3266" z="0" direction="n"/>
|
||||||
|
<ObjectAction mode="add" id="39245" x="2956" y="3270" z="0" direction="se"/>
|
||||||
|
<ObjectAction mode="add" id="39242" x="2955" y="3273" z="0" direction="w"/>
|
||||||
|
<ObjectAction mode="add" id="39241" x="2955" y="3274" z="0" />
|
||||||
|
<ObjectAction mode="add" id="20987" x="2821" y="2996" z="0" direction="s"/>
|
||||||
|
<ObjectAction mode="add" id="21301" x="2662" y="3162" z="0" direction="e"/>
|
||||||
|
<ObjectAction mode="add" id="4176" x="2629" y="3661" z="2" type="4" direction="e"/>
|
||||||
|
|
||||||
|
</parsing>
|
||||||
|
|
@ -3080,11 +3080,5 @@
|
||||||
"replaceId": "38142",
|
"replaceId": "38142",
|
||||||
"fence": "false",
|
"fence": "false",
|
||||||
"metal": "false"
|
"metal": "false"
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "40108",
|
|
||||||
"replaceId": "40109",
|
|
||||||
"fence": "false",
|
|
||||||
"metal": "false"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -111,10 +111,6 @@
|
||||||
"item_id": "278",
|
"item_id": "278",
|
||||||
"loc_data": "{1,2604,3358,0,50}-"
|
"loc_data": "{1,2604,3358,0,50}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"item_id": "298",
|
|
||||||
"loc_data": "{1,2569,9897,0,50}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"item_id": "301",
|
"item_id": "301",
|
||||||
"loc_data": "{1,2608,3397,0,90}-"
|
"loc_data": "{1,2608,3397,0,90}-"
|
||||||
|
|
@ -149,7 +145,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_id": "444",
|
"item_id": "444",
|
||||||
"loc_data": "{1,2732,3224,0,250}-{1,3231,3739,0,250}-{1,3236,3741,0,250}-{1,3195,9821,0,150}-"
|
"loc_data": "{1,3231,3739,0,250}-{1,3236,3741,0,250}-{1,3195,9821,0,150}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_id": "480",
|
"item_id": "480",
|
||||||
|
|
@ -269,7 +265,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_id": "995",
|
"item_id": "995",
|
||||||
"loc_data": "{2,3234,3560,0,100}-{2,3106,3547,0,100}-{1,3104,3558,0,100}-{1,3106,3534,0,100}-{2,3101,3564,0,100}-{4,3103,3579,0,100}-{384,3224,3830,0,50}-{384,3220,3824,0,50}-{2,2772,4517,0,60}-{3,2770,4516,0,60}-{4,2771,4516,0,60}-{4,2772,4515,0,60}-{1,2909,9800,0,150}-{4,2912,9801,0,150}-{8,2910,9803,0,150}-{5,2907,9807,0,150}-{6,2913,9806,0,150}-{1,2922,9820,0,150}-{1,2934,9834,0,150}-{1,2917,9850,0,150}-{1,2914,9849,0,150}-{3,3195,9834,0,150}-{4,3195,9820,0,150}-{66,3191,9821,0,150}-{56,3190,9819,0,150}-{26,3188,9819,0,150}-{26,3188,9820,0,150}-{35,3189,9819,0,150}-{4,3088,9898,0,150}-{1,3088,9899,0,150}-{1,3091,9899,0,150}-"
|
"loc_data": "{2,3234,3560,0,100}-{2,3106,3547,0,100}-{1,3104,3558,0,100}-{1,3106,3534,0,100}-{2,3101,3564,0,100}-{4,3103,3579,0,100}-{384,3224,3830,0,50}-{384,3220,3824,0,50}-{1,2909,9800,0,150}-{4,2912,9801,0,150}-{8,2910,9803,0,150}-{5,2907,9807,0,150}-{6,2913,9806,0,150}-{1,2922,9820,0,150}-{1,2934,9834,0,150}-{1,2917,9850,0,150}-{1,2914,9849,0,150}-{3,3195,9834,0,150}-{4,3195,9820,0,150}-{66,3191,9821,0,150}-{56,3190,9819,0,150}-{26,3188,9819,0,150}-{26,3188,9820,0,150}-{35,3189,9819,0,150}-{4,3088,9898,0,150}-{1,3088,9899,0,150}-{1,3091,9899,0,150}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_id": "1005",
|
"item_id": "1005",
|
||||||
|
|
@ -327,21 +323,9 @@
|
||||||
"item_id": "1217",
|
"item_id": "1217",
|
||||||
"loc_data": "{1,3180,3821,0,60}-"
|
"loc_data": "{1,3180,3821,0,60}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"item_id": "1237",
|
|
||||||
"loc_data": "{1,2808,4572,0,60}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"item_id": "1265",
|
"item_id": "1265",
|
||||||
"loc_data": "{1,3229,3218,2,100}-{1,2963,3216,0,30}-{1,3081,3429,0,50}-{1,2801,4513,0,60}-{1,2801,4493,0,60}-{1,2795,4579,0,60}-{1,2812,4572,0,60}-{1,3288,9442,0,90}-{1,3288,9431,0,90}-"
|
"loc_data": "{1,3229,3218,2,100}-{1,2963,3216,0,30}-{1,3081,3429,0,50}-{1,3288,9442,0,90}-{1,3288,9431,0,90}-"
|
||||||
},
|
|
||||||
{
|
|
||||||
"item_id": "1267",
|
|
||||||
"loc_data": "{1,2770,4515,0,60}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"item_id": "1269",
|
|
||||||
"loc_data": "{1,2812,4571,0,60}-"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_id": "1321",
|
"item_id": "1321",
|
||||||
|
|
@ -429,11 +413,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_id": "1755",
|
"item_id": "1755",
|
||||||
"loc_data": "{1,2935,3286,0,90}-{1,2800,4500,0,60}-{1,2803,4491,0,60}-"
|
"loc_data": "{1,2935,3286,0,90}-"
|
||||||
},
|
|
||||||
{
|
|
||||||
"item_id": "1773",
|
|
||||||
"loc_data": "{1,2563,3261,0,100}-"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"item_id": "1785",
|
"item_id": "1785",
|
||||||
|
|
@ -691,10 +671,6 @@
|
||||||
"item_id": "7510",
|
"item_id": "7510",
|
||||||
"loc_data": "{1,2867,9875,0,44}-"
|
"loc_data": "{1,2867,9875,0,44}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"item_id": "10587",
|
|
||||||
"loc_data": "{1,3184,4634,0,60}-{1,3147,4666,0,60}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"item_id": "11065",
|
"item_id": "11065",
|
||||||
"loc_data": "{1,2928,3289,0,90}-"
|
"loc_data": "{1,2928,3289,0,90}-"
|
||||||
|
|
|
||||||
|
|
@ -203,12 +203,6 @@
|
||||||
"walkable": "false",
|
"walkable": "false",
|
||||||
"tabIndex": "-1"
|
"tabIndex": "-1"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "144",
|
|
||||||
"interfaceType": "1",
|
|
||||||
"walkable": "false",
|
|
||||||
"tabIndex": "-1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "149",
|
"id": "149",
|
||||||
"interfaceType": "2",
|
"interfaceType": "2",
|
||||||
|
|
@ -221,12 +215,6 @@
|
||||||
"walkable": "true",
|
"walkable": "true",
|
||||||
"tabIndex": "-1"
|
"tabIndex": "-1"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "170",
|
|
||||||
"interfaceType": "1",
|
|
||||||
"walkable": "true",
|
|
||||||
"tabIndex": "-1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "172",
|
"id": "172",
|
||||||
"interfaceType": "4",
|
"interfaceType": "4",
|
||||||
|
|
@ -551,12 +539,6 @@
|
||||||
"walkable": "true",
|
"walkable": "true",
|
||||||
"tabIndex": "-1"
|
"tabIndex": "-1"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "375",
|
|
||||||
"interfaceType": "3",
|
|
||||||
"walkable": "false",
|
|
||||||
"tabIndex": "-1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "377",
|
"id": "377",
|
||||||
"interfaceType": "8",
|
"interfaceType": "8",
|
||||||
|
|
@ -641,12 +623,6 @@
|
||||||
"walkable": "true",
|
"walkable": "true",
|
||||||
"tabIndex": "6"
|
"tabIndex": "6"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "433",
|
|
||||||
"interfaceType": "3",
|
|
||||||
"walkable": "false",
|
|
||||||
"tabIndex": "-1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "464",
|
"id": "464",
|
||||||
"interfaceType": "2",
|
"interfaceType": "2",
|
||||||
|
|
@ -863,12 +839,6 @@
|
||||||
"walkable": "false",
|
"walkable": "false",
|
||||||
"tabIndex": "-1"
|
"tabIndex": "-1"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "683",
|
|
||||||
"interfaceType": "3",
|
|
||||||
"walkable": "true",
|
|
||||||
"tabIndex": "-1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "695",
|
"id": "695",
|
||||||
"interfaceType": "7",
|
"interfaceType": "7",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -157,7 +157,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "47",
|
"npc_id": "47",
|
||||||
"loc_data": "{2821,3170,0,1,1}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3341,3267,0,1,5}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2339,9356,0,1,0}-{2354,9390,0,1,0}-{2361,9403,0,1,0}-{2362,9347,0,1,0}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3001,3202,0,1,5}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3490,9815,0,1,1}-{3490,9824,0,1,4}-{3478,9834,0,1,0}-{3496,9808,0,1,0}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{2801,3158,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{2798,4531,0,1,0}-{2800,4526,0,1,0}-{2803,4526,0,1,0}-{2780,4592,0,1,0}-{2783,4593,0,1,0}-{2777,4582,0,1,0}-{2785,4580,0,1,0}-{2786,4578,0,1,0}-{2787,4579,0,1,0}-{2812,4577,0,1,0}-{2802,4599,0,1,0}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-"
|
"loc_data": "{2821,3170,0,1,1}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3341,3267,0,1,5}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2339,9356,0,1,0}-{2354,9390,0,1,0}-{2361,9403,0,1,0}-{2362,9347,0,1,0}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2801,3158,0,1,2}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "48",
|
"npc_id": "48",
|
||||||
|
|
@ -245,7 +245,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "78",
|
"npc_id": "78",
|
||||||
"loc_data": "{2585,3479,0,1,1}-{2589,3480,0,1,2}-{2582,3476,0,1,3}-{2588,3485,0,1,4}-{2580,3490,0,1,5}-{2577,3482,0,1,6}-{2583,3484,0,1,7}-{3073,3961,0,1,0}-{3074,3952,0,1,0}-{3075,3955,0,1,0}-{3076,3961,0,1,0}-{3077,3949,0,1,0}-{3079,3957,0,1,0}-{3080,3961,0,1,0}-{2568,9528,0,1,5}-{2573,9530,0,1,3}-{2575,9525,0,1,6}-{2571,9528,0,1,7}-{2862,9569,0,1,4}-{2857,9571,0,1,7}-{2837,9561,0,1,1}-{2608,9818,0,1,7}-{2609,9825,0,1,5}-{2607,9830,0,1,1}-{2605,9837,0,1,1}-{2607,9833,0,1,6}-{2905,9832,0,1,0}-{2907,9831,0,1,0}-{2913,9828,0,1,0}-{2921,9826,0,1,0}-{2924,9831,0,1,0}-{2921,9834,0,1,0}-{2918,9831,0,1,0}-{2908,9838,0,1,0}-{2913,9841,0,1,0}-{2672,9805,0,1,3}-{2663,9804,0,1,4}-{2658,9809,0,1,5}-{3725,9369,0,1,1}-{3737,9390,0,1,4}-{3738,9399,0,1,0}-{3740,9407,0,1,1}-{3765,9407,0,1,1}-{3762,9395,0,1,3}-{3725,9390,0,1,3}-{3753,9387,0,1,0}-{3728,9382,0,1,3}-{3729,9360,0,1,6}-{3755,9424,0,1,0}-{3760,9440,0,1,4}-{3737,9425,0,1,7}-{3720,9430,0,1,4}-{3736,9451,0,1,3}-{3728,9463,0,1,2}-{3740,9462,0,1,4}-{3770,9463,0,1,1}-{3752,9450,0,1,6}-{3762,9432,0,1,1}-{3733,9421,0,1,7}-{2759,3402,0,1,2}-{2756,3400,0,1,0}-{2788,4503,0,1,0}-{2789,4499,0,1,0}-{3787,9459,0,1,1}-{3803,9447,0,1,4}-{3778,9438,0,1,1}-{3786,9422,0,1,4}-{3800,9419,0,1,3}-{3797,9427,0,1,4}-{3820,9432,0,1,5}-{3825,9414,0,1,3}-{3833,9415,0,1,0}-{3825,9449,0,1,3}-{3827,9459,0,1,1}-{3818,9466,0,1,4}-{3799,9460,0,1,1}-{3794,9451,0,1,1}-{2543,9564,0,1,1}-{2543,9562,0,1,1}-{2542,9557,0,1,1}-{2542,9569,0,1,4}-{2540,9566,0,1,0}-{2549,9568,0,1,6}-{2538,9568,0,1,3}-"
|
"loc_data": "{2585,3479,0,1,1}-{2589,3480,0,1,2}-{2582,3476,0,1,3}-{2588,3485,0,1,4}-{2580,3490,0,1,5}-{2577,3482,0,1,6}-{2583,3484,0,1,7}-{3073,3961,0,1,0}-{3074,3952,0,1,0}-{3075,3955,0,1,0}-{3076,3961,0,1,0}-{3077,3949,0,1,0}-{3079,3957,0,1,0}-{3080,3961,0,1,0}-{2568,9528,0,1,5}-{2573,9530,0,1,3}-{2575,9525,0,1,6}-{2571,9528,0,1,7}-{2862,9569,0,1,4}-{2857,9571,0,1,7}-{2837,9561,0,1,1}-{2608,9818,0,1,7}-{2609,9825,0,1,5}-{2607,9830,0,1,1}-{2605,9837,0,1,1}-{2607,9833,0,1,6}-{2905,9832,0,1,0}-{2907,9831,0,1,0}-{2913,9828,0,1,0}-{2921,9826,0,1,0}-{2924,9831,0,1,0}-{2921,9834,0,1,0}-{2918,9831,0,1,0}-{2908,9838,0,1,0}-{2913,9841,0,1,0}-{2672,9805,0,1,3}-{2663,9804,0,1,4}-{2658,9809,0,1,5}-{3725,9369,0,1,1}-{3737,9390,0,1,4}-{3738,9399,0,1,0}-{3740,9407,0,1,1}-{3765,9407,0,1,1}-{3762,9395,0,1,3}-{3725,9390,0,1,3}-{3753,9387,0,1,0}-{3728,9382,0,1,3}-{3729,9360,0,1,6}-{3755,9424,0,1,0}-{3760,9440,0,1,4}-{3737,9425,0,1,7}-{3720,9430,0,1,4}-{3736,9451,0,1,3}-{3728,9463,0,1,2}-{3740,9462,0,1,4}-{3770,9463,0,1,1}-{3752,9450,0,1,6}-{3762,9432,0,1,1}-{3733,9421,0,1,7}-{2759,3402,0,1,2}-{2756,3400,0,1,0}-{3787,9459,0,1,1}-{3803,9447,0,1,4}-{3778,9438,0,1,1}-{3786,9422,0,1,4}-{3800,9419,0,1,3}-{3797,9427,0,1,4}-{3820,9432,0,1,5}-{3825,9414,0,1,3}-{3833,9415,0,1,0}-{3825,9449,0,1,3}-{3827,9459,0,1,1}-{3818,9466,0,1,4}-{3799,9460,0,1,1}-{3794,9451,0,1,1}-{2543,9564,0,1,1}-{2543,9562,0,1,1}-{2542,9557,0,1,1}-{2542,9569,0,1,4}-{2540,9566,0,1,0}-{2549,9568,0,1,6}-{2538,9568,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "80",
|
"npc_id": "80",
|
||||||
|
|
@ -269,7 +269,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "86",
|
"npc_id": "86",
|
||||||
"loc_data": "{3105,9517,0,1,7}-{3101,9517,0,1,6}-{3102,9521,0,1,4}-{3106,9519,0,1,1}-{3104,9514,0,1,4}-{3104,9518,0,1,1}-{3107,9519,0,1,1}-{3109,9516,0,1,1}-{3107,9515,0,1,7}-{3105,9512,0,1,6}-{3102,9513,0,1,3}-{3100,9514,0,1,1}-{3100,9516,0,1,7}-{3099,9521,0,1,0}-{3103,9523,0,1,1}-{3098,9880,0,1,5}-{3094,9883,0,1,1}-{3119,9891,0,1,4}-{3188,3181,0,1,7}-{3181,3191,0,1,7}-{3185,3199,0,1,4}-{3176,3198,0,1,6}-{3168,3188,0,1,4}-{3172,3178,0,1,1}-{3179,3174,0,1,1}-{3189,3168,0,1,5}-{3196,3208,0,1,1}-{3196,3205,0,1,0}-{3195,3212,0,1,0}-{2632,9696,0,1,1}-{2639,9697,0,1,3}-{2646,9696,0,1,3}-{2650,9697,0,1,4}-{2646,9702,0,1,6}-{2647,9713,0,1,3}-{2641,9719,0,1,1}-{2650,9716,0,1,1}-{3212,3191,0,1,6}-{3207,3192,0,1,2}-{3216,3184,0,1,2}-{3224,3174,0,1,4}-{3229,3183,0,1,5}-{3222,3185,0,1,3}-{3216,3177,0,1,4}-{3200,3182,0,1,5}-{3202,3189,0,1,6}-{2977,3700,0,1,0}-{2967,3694,0,1,0}-{2973,3694,0,1,0}-{3495,9812,0,1,1}-{3502,9807,0,1,0}-{3249,9868,0,1,4}-{3237,9868,0,1,3}-{3221,9873,0,1,6}-{3225,9862,0,1,2}-{3237,9866,0,1,6}-{3232,9867,0,1,7}-{3219,9862,0,1,7}-{3227,9875,0,1,4}-{2518,3187,0,1,3}-{3291,3388,0,1,6}-{3049,3691,0,1,0}-{3276,9870,0,1,3}-"
|
"loc_data": "{3105,9517,0,1,7}-{3101,9517,0,1,6}-{3102,9521,0,1,4}-{3106,9519,0,1,1}-{3104,9514,0,1,4}-{3104,9518,0,1,1}-{3107,9519,0,1,1}-{3109,9516,0,1,1}-{3107,9515,0,1,7}-{3105,9512,0,1,6}-{3102,9513,0,1,3}-{3100,9514,0,1,1}-{3100,9516,0,1,7}-{3099,9521,0,1,0}-{3103,9523,0,1,1}-{3098,9880,0,1,5}-{3094,9883,0,1,1}-{3119,9891,0,1,4}-{3188,3181,0,1,7}-{3181,3191,0,1,7}-{3185,3199,0,1,4}-{3176,3198,0,1,6}-{3168,3188,0,1,4}-{3172,3178,0,1,1}-{3179,3174,0,1,1}-{3189,3168,0,1,5}-{3196,3208,0,1,1}-{3196,3205,0,1,0}-{3195,3212,0,1,0}-{2632,9696,0,1,1}-{2639,9697,0,1,3}-{2646,9696,0,1,3}-{2650,9697,0,1,4}-{2646,9702,0,1,6}-{2647,9713,0,1,3}-{2641,9719,0,1,1}-{2650,9716,0,1,1}-{3212,3191,0,1,6}-{3207,3192,0,1,2}-{3216,3184,0,1,2}-{3224,3174,0,1,4}-{3229,3183,0,1,5}-{3222,3185,0,1,3}-{3216,3177,0,1,4}-{3200,3182,0,1,5}-{3202,3189,0,1,6}-{2977,3700,0,1,0}-{2967,3694,0,1,0}-{2973,3694,0,1,0}-{3495,9812,0,1,1}-{3502,9807,0,0,4}-{3249,9868,0,1,4}-{3237,9868,0,1,3}-{3221,9873,0,1,6}-{3225,9862,0,1,2}-{3237,9866,0,1,6}-{3232,9867,0,1,7}-{3219,9862,0,1,7}-{3227,9875,0,1,4}-{2518,3187,0,1,3}-{3291,3388,0,1,6}-{3049,3691,0,1,0}-{3276,9870,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "87",
|
"npc_id": "87",
|
||||||
|
|
@ -297,7 +297,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "93",
|
"npc_id": "93",
|
||||||
"loc_data": "{2566,9507,0,1,3}-{2562,9505,0,1,1}-{2568,9509,0,1,3}-{2571,9509,0,1,1}-{2564,9504,0,1,1}-{2566,9505,0,1,1}-{2841,9625,0,1,4}-{2845,9628,0,1,3}-{2841,9638,0,1,6}-{2845,9645,0,1,1}-{3101,9956,0,1,3}-{3104,9948,0,1,0}-{3104,9955,0,1,4}-{3108,9951,0,1,4}-{3108,9954,0,1,1}-{3111,9954,0,1,6}-{3112,9958,0,1,4}-{3194,5460,0,1,6}-{3192,5466,0,1,7}-{3185,5493,0,1,4}-{3182,5494,0,1,6}-{3185,5486,0,1,7}-{3175,5492,0,1,3}-{3169,5496,0,1,4}-{3170,5492,0,1,3}-{3186,5487,0,1,4}-{3169,5491,0,1,2}-{2655,9824,0,1,1}-{2669,9824,0,1,4}-{2667,9823,0,1,5}-{2658,9830,0,1,6}-{2666,9829,0,1,6}-{2637,9891,0,1,0}-{2645,9891,0,1,0}-{2653,9892,0,1,0}-{2653,9892,0,1,0}-{2544,9841,0,1,1}-{2536,9844,0,1,6}-{2530,9842,0,1,4}-{2543,9815,0,1,3}-"
|
"loc_data": "{2566,9507,0,1,3}-{2562,9505,0,1,1}-{2568,9509,0,1,3}-{2571,9509,0,1,1}-{2564,9504,0,1,1}-{2566,9505,0,1,1}-{2841,9625,0,1,4}-{2845,9628,0,1,3}-{2841,9638,0,1,6}-{2845,9645,0,1,1}-{3101,9956,0,1,3}-{3104,9948,0,1,0}-{3104,9955,0,1,4}-{3108,9951,0,1,4}-{3108,9954,0,1,1}-{3111,9954,0,1,6}-{3112,9958,0,1,4}-{3194,5460,0,1,6}-{3192,5466,0,1,7}-{3185,5493,0,1,4}-{3182,5494,0,1,6}-{3185,5486,0,1,7}-{3175,5492,0,1,3}-{3169,5496,0,1,4}-{3170,5492,0,1,3}-{3186,5487,0,1,4}-{3169,5491,0,1,2}-{2655,9824,0,1,1}-{2669,9824,0,1,4}-{2667,9823,0,1,5}-{2658,9830,0,1,6}-{2666,9829,0,1,6}-{2637,9891,0,1,0}-{2645,9891,0,1,0}-{2653,9892,0,1,0}-{2653,9892,0,1,0}-{2544,9841,0,1,1}-{2536,9844,0,1,6}-{2527,9844,0,1,3}-{2530,9842,0,1,4}-{2543,9815,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "94",
|
"npc_id": "94",
|
||||||
|
|
@ -373,11 +373,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "112",
|
"npc_id": "112",
|
||||||
"loc_data": "{2825,3249,0,1,6}-{2560,3406,0,1,3}-{3144,3822,0,1,0}-{3165,9880,0,1,3}-{3168,9880,0,1,1}-{3159,9903,0,1,4}-{3156,9907,0,1,0}-{2699,3206,0,1,1}-{3202,5490,0,1,4}-{3237,5555,0,1,5}-{2554,3411,0,1,3}-{2554,3400,0,1,3}-{2551,3401,0,1,4}-"
|
"loc_data": "{2825,3249,0,1,6}-{2560,3406,0,1,3}-{3144,3822,0,1,0}-{3165,9880,0,1,3}-{3168,9880,0,1,1}-{3159,9903,0,1,4}-{3156,9907,0,1,0}-{2699,3206,0,1,1}-{3202,5490,0,1,4}-{3237,5555,0,1,5}-{2554,3411,0,1,3}-{2554,3400,0,1,3}-{2551,3401,0,1,4}-{2543,9823,0,1,3}-{2540,9819,0,1,5}-{2543,9817,0,1,4}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "113",
|
"npc_id": "113",
|
||||||
"loc_data": "{2622,3272,0,0,0}-{2835,9526,0,1,4}-{2832,9514,0,1,4}-{2825,9521,0,1,5}-{2846,9520,0,1,3}-{2838,9508,0,1,0}-{2832,9495,0,1,6}-{2838,9492,0,1,6}-{2851,9485,0,1,3}-{2847,9481,0,1,3}-{2865,9494,0,1,3}-{2855,9502,0,1,2}-{2870,9496,0,1,1}-{2851,9511,0,1,2}-{2853,9519,0,1,3}-{2857,9520,0,1,6}-{2863,9525,0,1,1}-{2869,9530,0,1,5}-{2865,9515,0,1,4}-{2868,9507,0,1,3}-{2874,9512,0,1,6}-{2896,2946,0,1,0}-{2918,2961,0,1,0}-{2926,2986,0,1,0}-{2930,3044,0,1,0}-{2926,3056,0,1,0}-{2916,3065,0,1,0}-"
|
"loc_data": "{2622,3272,0,0,0}-{2835,9526,0,1,4}-{2832,9514,0,1,4}-{2825,9521,0,1,5}-{2846,9520,0,1,3}-{2838,9508,0,1,0}-{2832,9495,0,1,6}-{2838,9492,0,1,6}-{2851,9485,0,1,3}-{2847,9481,0,1,3}-{2865,9494,0,1,3}-{2855,9502,0,1,2}-{2870,9496,0,1,1}-{2851,9511,0,1,2}-{2853,9519,0,1,3}-{2857,9520,0,1,6}-{2863,9525,0,1,1}-{2869,9530,0,1,5}-{2865,9515,0,1,4}-{2868,9507,0,1,3}-{2874,9512,0,1,6}-{2896,2946,0,0,0}-{2918,2961,0,0,0}-{2926,2986,0,0,0}-{2930,3044,0,0,0}-{2926,3056,0,0,0}-{2916,3065,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "115",
|
"npc_id": "115",
|
||||||
|
|
@ -1221,7 +1221,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "412",
|
"npc_id": "412",
|
||||||
"loc_data": "{3341,3478,0,1,0}-{3343,3484,0,1,0}-{3345,3484,0,1,0}-{3350,3493,0,1,0}-{3353,3494,0,1,0}-{3361,3484,0,1,0}-{3364,3489,0,1,0}-{3370,3497,0,1,0}-{3379,3478,0,1,0}-{3379,3484,0,1,0}-{3387,3483,0,1,0}-{3388,3494,0,1,0}-{3389,3483,0,1,0}-{3588,3472,0,1,0}-{3598,3509,0,1,0}-{3599,3486,0,1,0}-{3607,3462,0,1,0}-{3611,3499,0,1,0}-{3613,3482,0,1,0}-{3627,3511,0,1,0}-{3628,3473,0,1,0}-{3636,3466,0,1,0}-{3639,3510,0,1,0}-{3411,3536,0,1,0}-{3418,3522,0,1,0}-{3425,3525,0,1,0}-{3429,3522,0,1,0}-{3432,3527,0,1,0}-{3434,3521,0,1,0}-{3445,3526,0,1,0}-{3419,9646,0,1,0}-{3418,9642,0,1,0}-{3414,9643,0,1,0}-{3411,9644,0,1,0}-{3410,9641,0,1,0}-{3409,9638,0,1,0}-{3419,9630,0,1,0}-{3421,9629,0,1,0}-{3433,9638,0,1,0}-{3434,9636,0,1,0}-{3436,9636,0,1,0}-{3423,9625,0,1,0}-{2728,10122,0,1,1}-{2735,10123,0,1,3}-{2733,10129,0,1,1}-{2728,10133,0,1,6}-{2722,10133,0,1,6}-{2736,10137,0,1,1}-{2732,10142,0,1,0}-{2726,10142,0,1,6}-{2729,10140,0,1,3}-{2720,10144,0,1,6}-{2712,10142,0,1,3}-{3565,3503,0,1,0}-{3567,3481,0,1,0}-{3580,3491,0,1,0}-{2761,4500,0,1,0}-{2759,4498,0,1,0}-{2761,4496,0,1,0}-{2783,4490,0,1,0}-{2784,4487,0,1,0}-{2792,4488,0,1,0}-"
|
"loc_data": "{3341,3478,0,1,0}-{3343,3484,0,1,0}-{3345,3484,0,1,0}-{3350,3493,0,1,0}-{3353,3494,0,1,0}-{3361,3484,0,1,0}-{3364,3489,0,1,0}-{3370,3497,0,1,0}-{3379,3478,0,1,0}-{3379,3484,0,1,0}-{3387,3483,0,1,0}-{3388,3494,0,1,0}-{3389,3483,0,1,0}-{3588,3472,0,1,0}-{3598,3509,0,1,0}-{3599,3486,0,1,0}-{3607,3462,0,1,0}-{3611,3499,0,1,0}-{3613,3482,0,1,0}-{3627,3511,0,1,0}-{3628,3473,0,1,0}-{3636,3466,0,1,0}-{3639,3510,0,1,0}-{3411,3536,0,1,0}-{3418,3522,0,1,0}-{3425,3525,0,1,0}-{3429,3522,0,1,0}-{3432,3527,0,1,0}-{3434,3521,0,1,0}-{3445,3526,0,1,0}-{2728,10122,0,1,1}-{2735,10123,0,1,3}-{2733,10129,0,1,1}-{2728,10133,0,1,6}-{2722,10133,0,1,6}-{2736,10137,0,1,1}-{2732,10142,0,1,0}-{2726,10142,0,1,6}-{2729,10140,0,1,3}-{2720,10144,0,1,6}-{2712,10142,0,1,3}-{3565,3503,0,1,0}-{3567,3481,0,1,0}-{3580,3491,0,1,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "419",
|
"npc_id": "419",
|
||||||
|
|
@ -1323,10 +1323,6 @@
|
||||||
"npc_id": "462",
|
"npc_id": "462",
|
||||||
"loc_data": "{2590,3084,0,1,5}-"
|
"loc_data": "{2590,3084,0,1,5}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "464",
|
|
||||||
"loc_data": "{2668,3162,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "469",
|
"npc_id": "469",
|
||||||
"loc_data": "{2542,3169,0,1,4}-"
|
"loc_data": "{2542,3169,0,1,4}-"
|
||||||
|
|
@ -2101,7 +2097,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "708",
|
"npc_id": "708",
|
||||||
"loc_data": "{2595,3125,0,1,1}-{2601,3135,0,1,3}-{2598,3120,0,1,6}-{2615,3120,0,1,4}-{2598,3108,0,1,4}-{2865,3175,0,1,0}-{2855,3188,0,1,1}-{2838,3194,0,1,3}-{2827,3170,0,1,5}-{2598,3145,0,1,1}-{2588,3145,0,1,7}-{2603,3221,0,1,7}-{2604,3212,0,1,3}-{2612,3230,0,1,0}-{2611,3204,0,1,7}-{2942,3247,0,1,7}-{2627,3231,0,1,4}-{2932,3322,0,0,5}-{2934,3301,0,1,5}-{2934,3301,0,1,3}-{2935,3343,0,1,1}-{2941,3356,0,0,7}-{3162,3410,0,1,2}-{3189,3503,0,1,6}-{2977,3202,0,1,7}-{3219,3221,0,1,4}-{2997,3300,0,1,3}-{2957,3308,0,1,0}-{2973,3274,0,1,3}-{2994,3270,0,1,0}-{3215,3282,0,1,1}-{3242,3306,0,1,1}-{2980,3337,0,1,6}-{2977,3377,0,0,3}-{3208,3357,0,1,3}-{2962,3424,0,1,6}-{3240,3393,0,1,3}-{2715,3451,0,1,4}-{2715,3436,0,1,3}-{2733,3459,0,1,3}-{2732,3457,0,1,6}-{3239,3523,0,1,4}-{3262,3523,0,1,2}-{2806,3181,0,1,3}-{2788,3179,0,1,3}-{2753,3178,0,1,3}-{2759,3155,0,1,0}-{2544,3184,0,1,3}-{3068,3251,0,1,6}-{3031,3322,0,1,1}-{3010,3271,0,1,6}-{3011,3513,0,1,1}-"
|
"loc_data": "{2595,3125,0,1,1}-{2601,3135,0,1,3}-{2598,3120,0,1,6}-{2615,3120,0,1,4}-{2598,3108,0,1,4}-{2865,3175,0,1,0}-{2855,3188,0,1,1}-{2838,3194,0,1,3}-{2827,3170,0,1,5}-{2598,3145,0,1,1}-{2588,3145,0,1,7}-{2603,3221,0,1,7}-{2604,3212,0,1,3}-{2612,3230,0,1,0}-{2611,3204,0,1,7}-{2942,3247,0,1,7}-{2627,3231,0,1,4}-{2932,3322,0,0,5}-{2934,3301,0,1,5}-{2934,3301,0,1,3}-{2935,3343,0,1,1}-{2941,3356,0,0,7}-{3162,3410,0,1,2}-{3189,3503,0,1,6}-{3219,3221,0,1,4}-{2977,3202,0,1,7}-{2997,3300,0,1,3}-{2957,3308,0,1,0}-{2973,3274,0,1,3}-{2994,3270,0,1,0}-{3215,3282,0,1,1}-{3242,3306,0,1,1}-{2980,3337,0,1,6}-{2977,3377,0,0,3}-{3208,3357,0,1,3}-{2962,3424,0,1,6}-{3240,3393,0,1,3}-{2715,3451,0,1,4}-{2715,3436,0,1,3}-{2733,3459,0,1,3}-{2732,3457,0,1,6}-{3239,3523,0,1,4}-{3262,3523,0,1,2}-{2806,3181,0,1,3}-{2788,3179,0,1,3}-{2753,3178,0,1,3}-{2759,3155,0,1,0}-{2544,3184,0,1,3}-{3068,3251,0,1,6}-{3031,3322,0,1,1}-{3010,3271,0,1,6}-{3011,3513,0,1,1}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "710",
|
"npc_id": "710",
|
||||||
|
|
@ -2799,10 +2795,6 @@
|
||||||
"npc_id": "1013",
|
"npc_id": "1013",
|
||||||
"loc_data": "{2593,2971,0,1,0}-{2594,2971,0,1,0}-{2596,2961,0,1,0}-{2598,2971,0,1,0}-{2599,2960,0,1,0}-{2598,2960,0,1,0}-{2603,2966,0,1,0}-{2603,2970,0,1,0}-{2598,2960,0,1,0}-{2596,2963,0,1,0}-{2595,2964,0,1,0}-{2594,2964,0,1,0}-{2601,2964,0,1,0}-{2598,2969,0,1,0}-{2604,2971,0,1,0}-{2601,2972,0,1,0}-{2392,3057,0,1,0}-{2395,3056,0,1,0}-{2395,3052,0,1,0}-{2397,3048,0,1,0}-{2400,3050,0,1,0}-{2400,3053,0,1,0}-{2391,3052,0,1,0}-{2393,3047,0,1,0}-{2399,3046,0,1,0}-{2402,3044,0,1,0}-{2399,3040,0,1,0}-{2395,3042,0,1,0}-{2391,3045,0,1,0}-{2464,2912,0,1,0}-{2544,2904,0,1,0}-{2544,2988,0,1,0}-{2532,2983,0,1,0}-{2549,2983,0,1,0}-{2545,2983,0,1,0}-{2528,2986,0,1,0}-{2550,2979,0,1,0}-{2522,2978,0,1,0}-{2523,2976,0,1,0}-{2526,2974,0,1,0}-{2548,2990,0,1,0}-{2552,2988,0,1,0}-{2548,2979,0,1,0}-{2547,2991,0,1,0}-{2525,2975,0,1,0}-"
|
"loc_data": "{2593,2971,0,1,0}-{2594,2971,0,1,0}-{2596,2961,0,1,0}-{2598,2971,0,1,0}-{2599,2960,0,1,0}-{2598,2960,0,1,0}-{2603,2966,0,1,0}-{2603,2970,0,1,0}-{2598,2960,0,1,0}-{2596,2963,0,1,0}-{2595,2964,0,1,0}-{2594,2964,0,1,0}-{2601,2964,0,1,0}-{2598,2969,0,1,0}-{2604,2971,0,1,0}-{2601,2972,0,1,0}-{2392,3057,0,1,0}-{2395,3056,0,1,0}-{2395,3052,0,1,0}-{2397,3048,0,1,0}-{2400,3050,0,1,0}-{2400,3053,0,1,0}-{2391,3052,0,1,0}-{2393,3047,0,1,0}-{2399,3046,0,1,0}-{2402,3044,0,1,0}-{2399,3040,0,1,0}-{2395,3042,0,1,0}-{2391,3045,0,1,0}-{2464,2912,0,1,0}-{2544,2904,0,1,0}-{2544,2988,0,1,0}-{2532,2983,0,1,0}-{2549,2983,0,1,0}-{2545,2983,0,1,0}-{2528,2986,0,1,0}-{2550,2979,0,1,0}-{2522,2978,0,1,0}-{2523,2976,0,1,0}-{2526,2974,0,1,0}-{2548,2990,0,1,0}-{2552,2988,0,1,0}-{2548,2979,0,1,0}-{2547,2991,0,1,0}-{2525,2975,0,1,0}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "1015",
|
|
||||||
"loc_data": "{2716,4443,0,0,0}-{2719,4442,0,0,0}-{2724,4442,0,0,0}-{2729,4447,0,0,0}-{2728,4445,0,0,0}-{2735,4435,0,0,0}-{2738,4439,0,0,0}-{2713,4438,0,0,0}-{2792,4597,0,0,0}-{2785,4594,0,0,0}-{2783,4591,0,0,0}-{2774,4592,0,0,0}-{2770,4591,0,0,0}-{2769,4593,0,0,0}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "1017",
|
"npc_id": "1017",
|
||||||
"loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{3198,3355,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-"
|
"loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{3198,3355,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-"
|
||||||
|
|
@ -3409,7 +3401,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1223",
|
"npc_id": "1223",
|
||||||
"loc_data": "{3585,3478,0,1,0}-{3586,3480,0,1,0}-{3586,3496,0,1,0}-{3592,3477,0,1,0}-{3593,3458,0,1,0}-{3593,3508,0,1,0}-{3595,3491,0,1,0}-{3597,3479,0,1,0}-{3607,3466,0,1,0}-{3617,3477,0,1,0}-{3618,3514,0,1,0}-{3631,3471,0,1,0}-{3631,3499,0,1,0}-{3632,3459,0,1,0}-{3632,3475,0,1,0}-{3638,3472,0,1,0}-{3646,3467,0,1,0}-{3460,3241,0,1,0}-{3459,3237,0,1,0}-{3456,3234,0,1,0}-{3458,3230,0,1,0}-{3457,3227,0,1,0}-{3456,3223,0,1,0}-"
|
"loc_data": "{3585,3478,0,1,0}-{3586,3480,0,1,0}-{3586,3496,0,1,0}-{3592,3477,0,1,0}-{3593,3458,0,1,0}-{3593,3508,0,1,0}-{3595,3491,0,1,0}-{3597,3479,0,1,0}-{3607,3466,0,1,0}-{3617,3477,0,1,0}-{3618,3514,0,1,0}-{3631,3471,0,1,0}-{3631,3499,0,1,0}-{3632,3459,0,1,0}-{3632,3475,0,1,0}-{3638,3472,0,1,0}-{3646,3467,0,1,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1227",
|
"npc_id": "1227",
|
||||||
|
|
@ -3661,39 +3653,31 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1335",
|
"npc_id": "1335",
|
||||||
"loc_data": "{2518,4633,0,0,1}"
|
"loc_data": "{2518,4633,0,1,1}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1336",
|
"npc_id": "1336",
|
||||||
"loc_data": "{2508,3635,0,1,3}"
|
"loc_data": "{2508,3635,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1337",
|
"npc_id": "1337",
|
||||||
"loc_data": "{2445,4599,0,1,3}"
|
"loc_data": "{2445,4599,1,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1338",
|
"npc_id": "1338",
|
||||||
"loc_data": "{3151,5559,0,1,2}-{3157,5548,0,1,3}-{3155,5553,0,1,4}-{3145,5559,0,1,6}-{3152,5556,0,1,3}-{3149,5544,0,1,0}-{3145,5548,0,1,3}-{2514,10012,0,1,3}-{2515,10016,0,1,2}-{2519,10031,0,1,4}-{2527,10024,0,1,3}"
|
"loc_data": "{3151,5559,0,1,2}-{3157,5548,0,1,3}-{3155,5553,0,1,4}-{3145,5559,0,1,6}-{3152,5556,0,1,3}-{3149,5544,0,1,0}-{3145,5548,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1339",
|
"npc_id": "1339",
|
||||||
"loc_data": "{3153,5547,0,1,0}-{3150,5545,0,1,1}-{2521,10015,0,1,1}-{2523,10019,0,1,3}-{2514,10027,0,1,2}-{2534,10025,0,1,4}"
|
"loc_data": "{3153,5547,0,1,0}-{3150,5545,0,1,1}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1340",
|
"npc_id": "1340",
|
||||||
"loc_data": "{3147,5557,0,1,3}-{3154,5559,0,1,4}-{2511,10020,0,1,3}-{2526,10035,0,1,1}-{2522,10028,0,1,4}-"
|
"loc_data": "{3147,5557,0,1,3}-{3154,5559,0,1,4}-"
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1341",
|
|
||||||
"loc_data": "{2518,10013,0,1,6}-{2520,10018,0,1,4}-{2515,10030,0,1,3}-{2532,10023,0,1,2}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1342",
|
|
||||||
"loc_data": "{2524,10014,0,1,6}-{2527,10019,0,1,2}-{2518,10027,0,1,4}-{2535,10030,0,1,1}"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1343",
|
"npc_id": "1343",
|
||||||
"loc_data": "{3145,5548,0,1,6}-{2512,10018,0,1,4}-{2524,10033,0,1,2}-{2522,10023,0,1,3}-"
|
"loc_data": "{3145,5548,0,1,6}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1357",
|
"npc_id": "1357",
|
||||||
|
|
@ -3887,46 +3871,10 @@
|
||||||
"npc_id": "1526",
|
"npc_id": "1526",
|
||||||
"loc_data": "{2443,3089,0,0,0}-"
|
"loc_data": "{2443,3089,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "1528",
|
|
||||||
"loc_data": "{3443,3256,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1537",
|
|
||||||
"loc_data": "{2803,4595,0,0,0}-{2786,4571,0,1,0}-{2792,4567,0,1,0}-{2791,4560,0,1,0}-{2796,4587,0,1,0}-{2798,4592,0,1,0}-{2802,4591,0,1,0}-{2798,4597,0,1,0}-{2808,4598,0,1,0}-{2808,4601,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1538",
|
|
||||||
"loc_data": "{2804,4525,0,0,0}-{2772,4516,0,0,0}-{2773,4515,0,0,0}-{2801,4580,0,0,0}-{2802,4580,0,0,0}-{2800,4573,0,0,0}-{2807,4572,0,0,0}-{2810,4573,0,0,0}-{2813,4571,0,0,0}-{2811,4567,0,0,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1542",
|
|
||||||
"loc_data": "{2793,4458,0,0,7}-{2782,4458,0,0,2}-{2787,4451,0,0,1}-{2787,4446,0,0,2}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1543",
|
|
||||||
"loc_data": "{2788,4455,0,0,0}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "1544",
|
"npc_id": "1544",
|
||||||
"loc_data": "{2911,10175,0,0,4}-{2912,10175,0,0,4}-{2913,10175,0,0,4}-{2914,10175,0,0,4}-{2909,10173,0,0,4}-{2910,10173,0,0,4}-{2911,10173,0,0,4}-{2912,10173,0,0,4}-{2913,10173,0,0,4}-{2909,10171,0,0,4}-{2910,10171,0,0,4}-{2911,10169,0,0,4}-{2912,10169,0,0,4}-{2913,10169,0,0,4}-"
|
"loc_data": "{2911,10175,0,0,4}-{2912,10175,0,0,4}-{2913,10175,0,0,4}-{2914,10175,0,0,4}-{2909,10173,0,0,4}-{2910,10173,0,0,4}-{2911,10173,0,0,4}-{2912,10173,0,0,4}-{2913,10173,0,0,4}-{2909,10171,0,0,4}-{2910,10171,0,0,4}-{2911,10169,0,0,4}-{2912,10169,0,0,4}-{2913,10169,0,0,4}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "1545",
|
|
||||||
"loc_data": "{2727,4509,0,0,1}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1546",
|
|
||||||
"loc_data": "{2697,4498,0,0,4}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1547",
|
|
||||||
"loc_data": "{2715,4517,0,0,1}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1548",
|
|
||||||
"loc_data": "{2739,4528,0,0,1}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "1553",
|
"npc_id": "1553",
|
||||||
"loc_data": "{2828,10065,1,0,0}-"
|
"loc_data": "{2828,10065,1,0,0}-"
|
||||||
|
|
@ -3971,38 +3919,6 @@
|
||||||
"npc_id": "1566",
|
"npc_id": "1566",
|
||||||
"loc_data": "{2786,10199,0,1,0}-{2790,10222,0,1,0}-{2799,10214,0,1,0}-"
|
"loc_data": "{2786,10199,0,1,0}-{2790,10222,0,1,0}-{2799,10214,0,1,0}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "1567",
|
|
||||||
"loc_data": "{3521,3284,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1568",
|
|
||||||
"loc_data": "{3507,3437,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1569",
|
|
||||||
"loc_data": "{3506,9838,0,0,4}-{3506,9838,2,0,4}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1570",
|
|
||||||
"loc_data": "{3508,9837,2,0,3}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1571",
|
|
||||||
"loc_data": "{3504,9837,2,0,4}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1572",
|
|
||||||
"loc_data": "{3512,9834,0,1,0}-{3512,9834,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1573",
|
|
||||||
"loc_data": "{3513,9838,0,1,0}-{3513,9838,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1574",
|
|
||||||
"loc_data": "{3512,9842,0,1,0}-{3512,9842,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "1582",
|
"npc_id": "1582",
|
||||||
"loc_data": "{2568,9889,0,1,6}-{2578,9898,0,1,1}-{2657,9500,0,0,1}-{2632,9589,2,0,1}-{2628,9549,2,0,5}-{2629,9543,2,0,2}-{3249,5517,0,1,3}-"
|
"loc_data": "{2568,9889,0,1,6}-{2578,9898,0,1,1}-{2657,9500,0,0,1}-{2632,9589,2,0,1}-{2628,9549,2,0,5}-{2629,9543,2,0,2}-{3249,5517,0,1,3}-"
|
||||||
|
|
@ -4227,26 +4143,6 @@
|
||||||
"npc_id": "1658",
|
"npc_id": "1658",
|
||||||
"loc_data": "{2595,3087,1,1,1}-"
|
"loc_data": "{2595,3087,1,1,1}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "1660",
|
|
||||||
"loc_data": "{3549,9867,0,0,6}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1661",
|
|
||||||
"loc_data": "{3540,9873,0,0,1}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1662",
|
|
||||||
"loc_data": "{3554,9886,0,1,0}-{3560,9908,0,1,0}-{3565,9865,0,1,0}-{3572,9908,0,1,0}-{3573,9891,0,1,0}-{3577,9875,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1663",
|
|
||||||
"loc_data": "{3527,9909,0,1,0}-{3533,9912,0,1,0}-{3540,9892,0,1,0}-{3540,9902,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "1664",
|
|
||||||
"loc_data": "{3528,9865,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "1665",
|
"npc_id": "1665",
|
||||||
"loc_data": "{3544,3462,0,0,1}-"
|
"loc_data": "{3544,3462,0,0,1}-"
|
||||||
|
|
@ -4293,7 +4189,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1681",
|
"npc_id": "1681",
|
||||||
"loc_data": "{3202,5483,0,1,4}-{2544,9843,0,1,3}-{2528,9844,0,1,4}-{2543,9820,0,1,1}-"
|
"loc_data": "{3202,5483,0,1,4}-{2544,9843,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1683",
|
"npc_id": "1683",
|
||||||
|
|
@ -4433,7 +4329,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1770",
|
"npc_id": "1770",
|
||||||
"loc_data": "{2595,9826,0,1,1}-{3189,3246,0,1,0}-{3143,3231,0,1,0}-{3140,3263,0,1,0}-{2999,3212,0,1,1}-{3262,3253,0,1,6}-{3259,3254,0,1,3}-"
|
"loc_data": "{2595,9826,0,1,1}-{3189,3246,0,1,0}-{3143,3231,0,1,0}-{3140,3263,0,1,0}-{3262,3253,0,1,6}-{3259,3254,0,1,3}-{2999,3212,0,1,1}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1771",
|
"npc_id": "1771",
|
||||||
|
|
@ -4441,11 +4337,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1772",
|
"npc_id": "1772",
|
||||||
"loc_data": "{3194,3255,0,1,0}-{3143,3234,0,1,0}-{2993,3203,0,1,0}-{3251,3231,0,1,1}-{3260,3241,0,1,0}-{3259,3222,0,0,4}-"
|
"loc_data": "{3194,3255,0,1,0}-{3143,3234,0,1,0}-{3251,3231,0,1,1}-{3260,3241,0,1,0}-{3259,3222,0,0,4}-{2993,3203,0,1,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1773",
|
"npc_id": "1773",
|
||||||
"loc_data": "{2991,3219,0,1,1}-{3252,3227,0,1,1}-{3263,3219,0,1,0}-"
|
"loc_data": "{3252,3227,0,1,1}-{3263,3219,0,1,0}-{2991,3219,0,1,1}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1774",
|
"npc_id": "1774",
|
||||||
|
|
@ -4853,7 +4749,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1973",
|
"npc_id": "1973",
|
||||||
"loc_data": "{3166,4598,0,1,0}-{3167,4577,0,1,0}-{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-"
|
"loc_data": "{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "1976",
|
"npc_id": "1976",
|
||||||
|
|
@ -6055,14 +5951,6 @@
|
||||||
"npc_id": "2580",
|
"npc_id": "2580",
|
||||||
"loc_data": "{2918,3535,0,1,0}-"
|
"loc_data": "{2918,3535,0,1,0}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "2581",
|
|
||||||
"loc_data": "{3228,3477,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "2588",
|
|
||||||
"loc_data": "{3049,3505,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "2591",
|
"npc_id": "2591",
|
||||||
"loc_data": "{4786,5106,0,1,6}-{2474,5145,0,1,2}-"
|
"loc_data": "{4786,5106,0,1,6}-{2474,5145,0,1,2}-"
|
||||||
|
|
@ -6777,7 +6665,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "3108",
|
"npc_id": "3108",
|
||||||
"loc_data": "{2549,3100,0,1,4}-"
|
"loc_data": "{2549,3100,0,0,4}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "3109",
|
"npc_id": "3109",
|
||||||
|
|
@ -6785,11 +6673,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "3110",
|
"npc_id": "3110",
|
||||||
"loc_data": "{2788,3176,0,0,6}-"
|
"loc_data": "{2789,3175,0,0,4}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "3111",
|
"npc_id": "3111",
|
||||||
"loc_data": "{2788,3176,0,0,6}-"
|
"loc_data": "{2788,3176,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "3114",
|
"npc_id": "3114",
|
||||||
|
|
@ -9213,7 +9101,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "5383",
|
"npc_id": "5383",
|
||||||
"loc_data": "{3194,4569,0,1,0}-"
|
"loc_data": "{3194,4569,0,0,0}-"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"npc_id": "5384",
|
||||||
|
"loc_data": "{3165,4598,0,0,0}-{3167,4577,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "5385",
|
"npc_id": "5385",
|
||||||
|
|
@ -9317,19 +9209,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "5413",
|
"npc_id": "5413",
|
||||||
"loc_data": "{3187,5450,0,1,6}-{3177,5453,0,1,6}-{3423,9658,0,1,0}-"
|
"loc_data": "{3187,5450,0,1,6}-{3177,5453,0,1,6}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "5414",
|
"npc_id": "5414",
|
||||||
"loc_data": "{3176,5454,0,1,3}-{3182,5447,0,1,3}-{3429,9648,0,1,0}-{3420,9657,0,1,0}-"
|
"loc_data": "{3176,5454,0,1,3}-{3182,5447,0,1,3}-"
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "5417",
|
|
||||||
"loc_data": "{3146,4649,0,1,0}-{3148,4645,0,1,0}-{3152,4648,0,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "5418",
|
|
||||||
"loc_data": "{3140,4653,0,1,0}-{3140,4647,0,1,0}-{3158,4647,0,1,0}-{3158,4653,0,1,0}-{3147,4657,0,1,0}-{3150,4654,0,1,0}-"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "5423",
|
"npc_id": "5423",
|
||||||
|
|
@ -11481,7 +11365,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "6917",
|
"npc_id": "6917",
|
||||||
"loc_data": "{2916,3082,0,1,0}-{2917,3089,0,1,0}-{2912,3090,0,1,0}-"
|
"loc_data": "{2916,3082,0,0,0}-{2917,3089,0,0,0}-{2912,3090,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "6918",
|
"npc_id": "6918",
|
||||||
|
|
@ -11489,11 +11373,15 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "6921",
|
"npc_id": "6921",
|
||||||
"loc_data": "{2954,3273,0,1,6}-{2970,3300,0,1,0}-{2974,3448,0,1,4}-{2971,3442,0,1,6}-{2968,3451,0,1,1}-{2967,3439,0,1,4}-{2965,3451,0,1,5}-{3017,3402,0,1,0}-{3024,3405,0,1,0}-{3313,3440,0,1,0}-"
|
"loc_data": "{2954,3273,0,1,6}-{2974,3448,0,1,4}-{2971,3442,0,1,6}-{2968,3451,0,1,1}-{2967,3439,0,1,4}-{2965,3451,0,1,5}-"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"npc_id": "6942",
|
||||||
|
"loc_data": "{2890,3100,0,1,4}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "6944",
|
"npc_id": "6944",
|
||||||
"loc_data": "{2855,3028,0,1,0}-{2841,3039,0,1,0}-{2838,3031,0,1,0}-{2839,3022,0,1,0}-{2836,3014,0,1,0}-{2840,3008,0,1,0}-"
|
"loc_data": "{2855,3028,0,0,0}-{2841,3039,0,0,0}-{2838,3031,0,0,0}-{2836,3014,0,0,0}-{2839,3022,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "6962",
|
"npc_id": "6962",
|
||||||
|
|
@ -11565,7 +11453,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "6997",
|
"npc_id": "6997",
|
||||||
"loc_data": "{2927,3382,0,1,0}-{2931,3378,0,1,0}-{3007,3261,0,1,0}-{3002,3257,0,1,0}-{3049,3429,0,1,0}-{3058,3429,0,1,0}-{3059,3425,0,1,0}-{3059,3420,0,1,0}-{3309,3420,0,1,0}-{3305,3423,0,1,0}-"
|
"loc_data": "{3002,3257,0,0,0}-{3007,3261,0,0,0}-{3058,3429,0,0,0}-{3059,3420,0,0,0}-{3059,3425,0,0,0}-{3049,3429,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7003",
|
"npc_id": "7003",
|
||||||
|
|
@ -12033,63 +11921,59 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7228",
|
"npc_id": "7228",
|
||||||
"loc_data": "{2862,3101,0,1,0}-{2874,3098,0,1,0}-{2879,3109,0,1,0}-{2882,3104,0,1,0}-{2882,3098,0,1,0}-{2890,3100,0,1,0}-"
|
"loc_data": "{2862,3101,0,0,0}-{2879,3109,0,0,0}-{2874,3098,0,0,0}-{2882,3104,0,0,0}-{2882,3098,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7229",
|
"npc_id": "7229",
|
||||||
"loc_data": "{2831,3086,0,1,0}-{2833,3089,0,1,0}-{2844,3089,0,1,0}-{2836,3085,0,1,0}-{2840,3076,0,1,0}-"
|
"loc_data": "{2833,3088,0,0,0}-{2830,3085,0,0,0}-{2844,3089,0,0,0}-{2837,3084,0,0,0}-{2840,3076,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7230",
|
"npc_id": "7230",
|
||||||
"loc_data": "{2887,3051,0,1,0}-{2890,3052,0,1,0}-{2894,3058,0,1,0}-{2897,3035,0,1,0}-"
|
"loc_data": "{2840,3008,0,0,0}-{2887,3051,0,0,0}-{2890,3052,0,0,0}-{2894,3058,0,0,0}-{2897,3035,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7231",
|
"npc_id": "7231",
|
||||||
"loc_data": "{2930,2961,0,1,0}-{2942,2964,0,1,0}-{2933,2964,0,1,0}-{2932,2967,0,1,0}-{2936,2973,0,1,0}-"
|
"loc_data": "{2930,2961,0,0,0}-{2942,2964,0,0,0}-{2933,2964,0,0,0}-{2932,2967,0,0,0}-{2936,2973,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7232",
|
"npc_id": "7232",
|
||||||
"loc_data": "{2802,3106,0,1,0}-{2806,3108,0,1,0}-{2808,3106,0,1,0}-{2807,3101,0,1,0}-{2814,3100,0,1,0}-"
|
"loc_data": "{2802,3106,0,0,0}-{2807,3101,0,0,0}-{2806,3108,0,0,0}-{2808,3105,0,0,0}-{2814,3100,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7233",
|
"npc_id": "7233",
|
||||||
"loc_data": "{2922,3070,0,1,0}-{2919,3080,0,1,0}-{2924,3080,0,1,0}-{2923,3081,0,1,0}-{2929,3075,0,1,0}-"
|
"loc_data": "{2922,3070,0,0,0}-{2929,3075,0,0,0}-{2919,3080,0,0,0}-{2924,3080,0,0,0}-{2923,3081,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7234",
|
"npc_id": "7234",
|
||||||
"loc_data": "{2900,3107,0,1,0}-{2904,3107,0,1,0}-{2905,3107,0,1,0}-{2908,3104,0,1,0}-{2902,3101,0,1,0}-{2903,3098,0,1,0}-"
|
"loc_data": "{2900,3107,0,0,0}-{2903,3098,0,0,0}-{2908,3104,0,0,0}-{2905,3107,0,0,0}-{2904,3107,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7235",
|
"npc_id": "7235",
|
||||||
"loc_data": "{2820,3065,0,1,0}-{2830,3059,0,1,0}-{2825,3057,0,1,0}-{2827,3050,0,1,0}-{2822,3053,0,1,0}-"
|
"loc_data": "{2820,3065,0,0,0}-{2830,3059,0,0,0}-{2825,3057,0,0,0}-{2827,3050,0,0,0}-{2822,3053,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7236",
|
"npc_id": "7236",
|
||||||
"loc_data": "{2801,2995,0,1,0}-{2804,3001,0,1,0}-{2803,2986,0,1,0}-{2811,2999,0,1,0}-{2800,3006,0,1,0}-"
|
"loc_data": "{2799,3005,0,0,0}-{2801,2995,0,0,0}-{2804,3001,0,0,0}-{2803,2986,0,0,0}-{2811,2999,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7275",
|
"npc_id": "7275",
|
||||||
"loc_data": "{2916,3382,0,1,0}-{2914,3373,0,1,0}-{2995,3252,0,1,0}-{2996,3259,0,1,0}-{2993,3250,0,1,0}-{3000,3258,0,1,0}-{3306,3424,0,1,0}-{3306,3419,0,1,0}-"
|
"loc_data": "{2995,3252,0,0,0}-{2996,3259,0,0,0}-{2993,3250,0,0,0}-{3000,3258,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7276",
|
"npc_id": "7276",
|
||||||
"loc_data": "{2909,3381,0,1,0}-{2994,3256,0,1,0}-{3002,3250,0,1,0}-{2992,3252,0,1,0}-{3000,3250,0,1,0}-{2728,3422,0,1,1}-{2718,3413,0,1,4}-{2729,3420,0,1,4}-{2727,3414,0,1,6}-{2714,3419,0,1,3}-{2719,3427,0,1,7}-{3311,3420,0,1,0}-{3306,3421,0,1,0}-"
|
"loc_data": "{2994,3256,0,0,0}-{3002,3250,0,0,0}-{2992,3252,0,0,0}-{3000,3250,0,0,0}-{2728,3422,0,1,1}-{2718,3413,0,1,4}-{2729,3420,0,1,4}-{2727,3414,0,1,6}-{2714,3419,0,1,3}-{2719,3427,0,1,7}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7285",
|
"npc_id": "7285",
|
||||||
"loc_data": "{2835,3107,0,1,0}-{2836,3101,0,1,0}-{2836,3110,0,1,0}-{2837,3112,0,1,0}-{2841,3107,0,1,0}-{2885,3019,0,1,0}-{2885,3018,0,1,0}-{2891,3018,0,1,0}-"
|
"loc_data": "{2835,3107,0,0,0}-{2836,3101,0,0,0}-{2836,3110,0,0,0}-{2837,3112,0,0,0}-{2841,3107,0,0,0}-{2885,3018,0,0,0}-{2885,3019,0,0,0}-{2891,3018,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7286",
|
"npc_id": "7286",
|
||||||
"loc_data": "{2924,3102,0,1,0}-{2925,3097,0,1,0}-{2933,3104,0,1,0}-{2936,3096,0,1,0}-{2931,3090,0,1,0}-"
|
"loc_data": "{2931,3090,0,0,0}-{2925,3097,0,0,0}-{2936,3096,0,0,0}-{2924,3102,0,0,0}-{2933,3104,0,0,0}-"
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "7287",
|
|
||||||
"loc_data": "{2833,3055,0,1,0}-{2838,3054,0,1,0}-{2839,3047,0,1,0}-{2832,3047,0,1,0}-{2839,3063,0,1,0}-"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7288",
|
"npc_id": "7288",
|
||||||
"loc_data": "{2834,3045,0,1,0}-{2826,3048,0,1,0}-{2824,3043,0,1,0}-{2822,3045,0,1,0}-{2822,3045,0,1,0}-"
|
"loc_data": "{2834,3045,0,0,0}-{2826,3048,0,0,0}-{2824,3043,0,0,0}-{2822,3045,0,0,0}-{2818,3049,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7289",
|
"npc_id": "7289",
|
||||||
|
|
@ -12105,19 +11989,19 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7309",
|
"npc_id": "7309",
|
||||||
"loc_data": "{2946,3280,0,1,0}-{2966,3295,0,1,0}-{3023,3410,0,1,0}-{3023,3410,0,1,0}-{3317,3445,0,1,0}-"
|
"loc_data": "{2946,3280,0,0,0}-{3023,3410,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7310",
|
"npc_id": "7310",
|
||||||
"loc_data": "{2947,3273,0,1,0}-{2972,3298,0,1,0}-{2729,3425,0,1,0}-{3015,3409,0,1,0}-{3018,3407,0,1,0}-{3312,3442,0,1,0}-"
|
"loc_data": "{2946,3272,0,0,0}-{3015,3409,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7311",
|
"npc_id": "7311",
|
||||||
"loc_data": "{2956,3273,0,1,0}-{2967,3305,0,1,0}-{2731,3420,0,1,0}-{2722,3424,0,1,0}-{3024,3402,0,1,0}-{3021,3405,0,1,0}-{3308,3445,0,1,0}-"
|
"loc_data": "{2956,3273,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7312",
|
"npc_id": "7312",
|
||||||
"loc_data": "{2951,3267,0,1,0}-{2964,3297,0,1,0}-{2722,3418,0,1,0}-{2716,3423,0,1,0}-{3017,3412,0,1,0}-{3026,3409,0,1,0}-{3308,3440,0,1,0}-"
|
"loc_data": "{2950,3268,0,0,0}-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npc_id": "7420",
|
"npc_id": "7420",
|
||||||
|
|
@ -12335,54 +12219,6 @@
|
||||||
"npc_id": "8000",
|
"npc_id": "8000",
|
||||||
"loc_data": "{2987,3691,0,1,3}-"
|
"loc_data": "{2987,3691,0,1,3}-"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"npc_id": "8029",
|
|
||||||
"loc_data": "{1697,5463,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8030",
|
|
||||||
"loc_data": "{1698,5462,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8031",
|
|
||||||
"loc_data": "{1694,5473,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8032",
|
|
||||||
"loc_data": "{1691,5469,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8033",
|
|
||||||
"loc_data": "{1700,5463,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8034",
|
|
||||||
"loc_data": "{1692,5465,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8035",
|
|
||||||
"loc_data": "{1692,5472,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8036",
|
|
||||||
"loc_data": "{1696,5473,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8037",
|
|
||||||
"loc_data": "{1701,5472,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8038",
|
|
||||||
"loc_data": "{1702,5470,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8039",
|
|
||||||
"loc_data": "{1702,5468,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"npc_id": "8040",
|
|
||||||
"loc_data": "{1694,5462,2,1,0}-"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"npc_id": "8041",
|
"npc_id": "8041",
|
||||||
"loc_data": "{2794,3100,0,1,0}-"
|
"loc_data": "{2794,3100,0,1,0}-"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,165 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "1814",
|
|
||||||
"location": "3090, 3475, 0",
|
|
||||||
"type": "4",
|
|
||||||
"direction": "nw"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "2646",
|
|
||||||
"location": "2445, 3413, 0",
|
|
||||||
"direction": "nw"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "2646",
|
|
||||||
"location": "2447, 3414, 0",
|
|
||||||
"direction": "e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "2646",
|
|
||||||
"location": "2447, 3421, 0",
|
|
||||||
"direction": "nw"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Prison Pete Random",
|
|
||||||
"mode": "add",
|
|
||||||
"id": "36788",
|
|
||||||
"location": "2094, 4465, 0",
|
|
||||||
"type": "10",
|
|
||||||
"direction": "e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Green Portal",
|
|
||||||
"mode": "remove",
|
|
||||||
"id": "11371",
|
|
||||||
"location": "2085, 4457, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Lever",
|
|
||||||
"mode": "remove",
|
|
||||||
"id": "10817",
|
|
||||||
"location": "2083, 4460, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Lever",
|
|
||||||
"mode": "add",
|
|
||||||
"id": "26191",
|
|
||||||
"location": "2083, 4460, 0",
|
|
||||||
"type": "10",
|
|
||||||
"direction": "e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Window",
|
|
||||||
"mode": "add",
|
|
||||||
"id": "26184",
|
|
||||||
"location": "2084, 4459, 0",
|
|
||||||
"type": "0",
|
|
||||||
"direction": "n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Door",
|
|
||||||
"mode": "add",
|
|
||||||
"id": "26186",
|
|
||||||
"location": "2085, 4459, 0",
|
|
||||||
"type": "0",
|
|
||||||
"direction": "n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Door",
|
|
||||||
"mode": "add",
|
|
||||||
"id": "26188",
|
|
||||||
"location": "2086, 4459, 0",
|
|
||||||
"type": "0",
|
|
||||||
"direction": "n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"comment": "Window",
|
|
||||||
"mode": "add",
|
|
||||||
"id": "26184",
|
|
||||||
"location": "2087, 4459, 0",
|
|
||||||
"type": "0",
|
|
||||||
"direction": "n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "remove",
|
|
||||||
"id": "37670",
|
|
||||||
"location": "3292, 3299, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "37304",
|
|
||||||
"location": "3292, 3299, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "20987",
|
|
||||||
"location": "3821, 2996, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "remove",
|
|
||||||
"id": "356",
|
|
||||||
"location": "2804, 3428, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "356",
|
|
||||||
"location": "2804, 3428, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "remove",
|
|
||||||
"id": "20228",
|
|
||||||
"location": "2537, 3573, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "27663",
|
|
||||||
"location": "2537, 3573, 0",
|
|
||||||
"direction": "w"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "39237",
|
|
||||||
"location": "2957, 3266, 0",
|
|
||||||
"direction": "n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "39245",
|
|
||||||
"location": "2956, 3270, 0",
|
|
||||||
"direction": "se"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "39242",
|
|
||||||
"location": "2955, 3273, 0",
|
|
||||||
"direction": "w"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "39241",
|
|
||||||
"location": "2955, 3274, 0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "20987",
|
|
||||||
"location": "2821, 2996, 0",
|
|
||||||
"direction": "s"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "21301",
|
|
||||||
"location": "2662, 3162, 0",
|
|
||||||
"direction": "e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"mode": "add",
|
|
||||||
"id": "4176",
|
|
||||||
"location": "2629, 3661, 2",
|
|
||||||
"type": "4",
|
|
||||||
"direction": "e"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -1546,41 +1546,5 @@
|
||||||
"animation": "426",
|
"animation": "426",
|
||||||
"drop_ammo": "true",
|
"drop_ammo": "true",
|
||||||
"ammunition": "14202,14203,14204,14205,14206"
|
"ammunition": "14202,14203,14204,14205,14206"
|
||||||
},
|
|
||||||
{
|
|
||||||
"itemId": "10149",
|
|
||||||
"name": "Swamp lizard",
|
|
||||||
"ammo_slot": "13",
|
|
||||||
"weapon_type": "0",
|
|
||||||
"animation": "5247",
|
|
||||||
"drop_ammo": "false",
|
|
||||||
"ammunition": "10142"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"itemId": "10146",
|
|
||||||
"name": "Orange salamander",
|
|
||||||
"ammo_slot": "13",
|
|
||||||
"weapon_type": "0",
|
|
||||||
"animation": "5247",
|
|
||||||
"drop_ammo": "false",
|
|
||||||
"ammunition": "10143"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"itemId": "10147",
|
|
||||||
"name": "Red salamander",
|
|
||||||
"ammo_slot": "13",
|
|
||||||
"weapon_type": "0",
|
|
||||||
"animation": "5247",
|
|
||||||
"drop_ammo": "false",
|
|
||||||
"ammunition": "10144"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"itemId": "10148",
|
|
||||||
"name": "Black salamander",
|
|
||||||
"ammo_slot": "13",
|
|
||||||
"weapon_type": "0",
|
|
||||||
"animation": "5247",
|
|
||||||
"drop_ammo": "false",
|
|
||||||
"ammunition": "10145"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@
|
||||||
"general_store": "true",
|
"general_store": "true",
|
||||||
"id": "22",
|
"id": "22",
|
||||||
"title": "The Lighthouse Store",
|
"title": "The Lighthouse Store",
|
||||||
"stock": "{954,10,200}-{2347,10,500}-{1755,10,500}-{946,10,500}-{952,10,500}-{590,5,500}-{36,10,500}-{273,10,200}-{233,10,500}-{1931,10,500}-{1925,5,500}-{1929,5,500}-{1935,5,200}-{1937,5,500}-{229,10,500}-{227,10,500}-{2019,5,500}-{2021,5,500}-{2015,5,2}-{1915,5,500}-{2017,5,500}-{1909,5,500}-{1913,5,500}-{1907,5,500}"
|
"stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"npcs": "2352",
|
"npcs": "2352",
|
||||||
|
|
@ -2195,14 +2195,5 @@
|
||||||
"id": "256",
|
"id": "256",
|
||||||
"title": "Uglug's Stuffsies",
|
"title": "Uglug's Stuffsies",
|
||||||
"stock": "{4844,100,10}-{10927,0,100}-{2862,100,100}-{1777,10,200}-{2876,0,500}-{2878,10,100}-{4850,0,100}-{946,5,100}-{4773,0,1000}-{4778,0,1000}-{4783,0,1000}-{4788,0,1500}-{4793,0,2000}-{4798,0,3000}-{4803,0,4000}-{4827,0,2000}"
|
"stock": "{4844,100,10}-{10927,0,100}-{2862,100,100}-{1777,10,200}-{2876,0,500}-{2878,10,100}-{4850,0,100}-{946,5,100}-{4773,0,1000}-{4778,0,1000}-{4783,0,1000}-{4788,0,1500}-{4793,0,2000}-{4798,0,3000}-{4803,0,4000}-{4827,0,2000}"
|
||||||
},
|
|
||||||
{
|
|
||||||
"npcs": "",
|
|
||||||
"high_alch": "0",
|
|
||||||
"currency": "995",
|
|
||||||
"general_store": "false",
|
|
||||||
"id": "257",
|
|
||||||
"title": "Magic Guild Store",
|
|
||||||
"stock": "{4089,1000,100}-{4091,1000,100}-{4093,1000,100}-{4095,1000,100}-{4097,1000,100}-{9762,1000,100}"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
<properties>
|
<properties>
|
||||||
<project.mainClassName>core.Server</project.mainClassName>
|
<project.mainClassName>core.Server</project.mainClassName>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
|
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
|
||||||
<kotlin.version>1.8.20</kotlin.version>
|
<kotlin.version>1.8.20</kotlin.version>
|
||||||
<kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget>
|
<kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget>
|
||||||
|
|
@ -91,11 +90,6 @@
|
||||||
<version>2.9.0</version>
|
<version>2.9.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.java-websocket</groupId>
|
|
||||||
<artifactId>Java-WebSocket</artifactId>
|
|
||||||
<version>1.5.7</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
@ -252,7 +246,6 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<useFile>false</useFile>
|
<useFile>false</useFile>
|
||||||
<trimStackTrace>false</trimStackTrace>
|
<trimStackTrace>false</trimStackTrace>
|
||||||
<argLine>-Xmx4g -Xms2g</argLine>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
<version>2.22.0</version>
|
<version>2.22.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
||||||
172
Server/src/main/content/data/BossKillCounter.java
Normal file
172
Server/src/main/content/data/BossKillCounter.java
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
package content.data;
|
||||||
|
|
||||||
|
import core.game.node.entity.player.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The BossKillcounter keeps track of the amount of bosses the player has slain.
|
||||||
|
* addtoKillcount(player, npcId) should be added in the finalizeDeath() method of the combat handler for the boss.
|
||||||
|
* @author Splinter
|
||||||
|
*/
|
||||||
|
public enum BossKillCounter {
|
||||||
|
|
||||||
|
|
||||||
|
/* ORDINAL BOUND */
|
||||||
|
KING_BLACK_DRAGON(new int[] { 50 }, "King Black Dragon", 14649),
|
||||||
|
BORK(new int[] { 7133, 7134 }, "Bork", -1),
|
||||||
|
DAGANNOTH_SUPREME(new int[] { 2881 }, "Dagannoth Supreme", 14639),
|
||||||
|
DAGANNOTH_PRIME(new int[] { 2882 }, "Dagannoth Prime", 14640),
|
||||||
|
DAGANNOTH_REX(new int[] { 2883 }, "Dagannoth Rex", 14641),
|
||||||
|
CHAOS_ELEMENTAL(new int[] { 3200 }, "Chaos Elemental", 14638),
|
||||||
|
GIANT_MOLE(new int[] { 3340 }, "Giant Mole", 14642),
|
||||||
|
SARADOMIN(new int[] { 6247 }, "Commander Zilyana", 14647),
|
||||||
|
ZAMORAK(new int[] { 6203 }, "K'ril Tsutsaroth", 14648),
|
||||||
|
BANDOS(new int[] { 6260 }, "General Graardor", 14646),
|
||||||
|
ARMADYL(new int[] { 6222 }, "Kree'arra", 14645),
|
||||||
|
JAD(new int[] { 2745 }, "Tz-Tok Jad", 14828),
|
||||||
|
KALPHITE_QUEEN(new int[] { 1160 }, "Kalphite Queen", 14650),
|
||||||
|
CORPOREAL_BEAST(new int[] { 8133 }, "Corporeal Beast", 14653),
|
||||||
|
TORMENTED_DEMONS(new int[] {
|
||||||
|
8349, 8350, 8351, 8352, 8353, 8354,
|
||||||
|
8355, 8356, 8357, 8358, 8359, 8360,
|
||||||
|
8361, 8362, 8363, 8364, 8365, 8366,
|
||||||
|
}, "Tormented demon", -1),
|
||||||
|
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The npcs that can increase the killcounter
|
||||||
|
*/
|
||||||
|
private final int[] npc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the NPC, to be displayed as a sendMessage
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The item ID of the pet relating to the boss.
|
||||||
|
*/
|
||||||
|
private final int petId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code BossKillCounter} {@code Object}.
|
||||||
|
* @param npc the npc.
|
||||||
|
* @param name the npc's string name
|
||||||
|
*/
|
||||||
|
BossKillCounter(final int[] npc, final String name, final int petId) {
|
||||||
|
this.npc = npc;
|
||||||
|
this.name = name;
|
||||||
|
this.petId = petId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the npc.
|
||||||
|
* @return The npc.
|
||||||
|
*/
|
||||||
|
public int[] getNpc() {
|
||||||
|
return npc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the NPC's name
|
||||||
|
* @return their name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the petId
|
||||||
|
* @return The petId
|
||||||
|
*/
|
||||||
|
public int getPetId() {
|
||||||
|
return petId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type for the npc.
|
||||||
|
* @param npc the npc.
|
||||||
|
* @return the BossKillcounter
|
||||||
|
*/
|
||||||
|
public static BossKillCounter forNPC(final int npc) {
|
||||||
|
for (BossKillCounter kc : BossKillCounter.values()) {
|
||||||
|
for (int i : kc.getNpc()) {
|
||||||
|
if (npc == i) {
|
||||||
|
return kc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds to the player's killcount for that particular boss.
|
||||||
|
* @param killer The player who killed the npc
|
||||||
|
* @param npcid the ID of the npc that just died
|
||||||
|
*/
|
||||||
|
public static void addtoKillcount(Player killer, int npcid) {
|
||||||
|
if (killer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BossKillCounter boss = BossKillCounter.forNPC(npcid);
|
||||||
|
if (boss == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()]++;
|
||||||
|
killer.getPacketDispatch().sendMessage("Your " + boss.getName() + " killcount is now: <col=ff0000>" + killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()] + "</col>.");
|
||||||
|
// addBossPet(killer, npcid, boss);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Gives the player the pet if they killed a certain boss.
|
||||||
|
// * The chance by default is 1/5000. This rate lowers to 1/2200 if the <GlobalEvents> for Boss Pets is active.
|
||||||
|
// * Note: Not all bosses have pet versions of themselves.
|
||||||
|
// */
|
||||||
|
// private static void addBossPet(Player killer, int npcid, BossKillCounter boss){
|
||||||
|
// if(boss.getPetId() == -1){ //The boss does not have a pet version.
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// int number = 5000;
|
||||||
|
// if (npcid == 2745) {
|
||||||
|
// number = 200;
|
||||||
|
// if (killer.getSlayer().getTask() == Tasks.JAD) {
|
||||||
|
// number = 100;
|
||||||
|
// }
|
||||||
|
// } else if (npcid == 3200) {
|
||||||
|
// number = 300;
|
||||||
|
// }
|
||||||
|
// int rand = number;
|
||||||
|
// if(rand == 10){
|
||||||
|
// for (int i = 0; i < killer.getFamiliarManager().getInsuredPets().size(); i++) {
|
||||||
|
// if (killer.getFamiliarManager().getInsuredPets().get(i).getBabyItemId() == boss.getPetId()) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if(killer.getFamiliarManager().hasFamiliar() && killer.getInventory().freeSlots() < 1){
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if(!killer.getFamiliarManager().hasFamiliar()){
|
||||||
|
// killer.getFamiliarManager().summon(new Item(boss.getPetId()), true);
|
||||||
|
// killer.sendNotificationMessage("You have a funny feeling like you're being followed.");
|
||||||
|
// } else if (killer.getInventory().freeSlots() > 0){
|
||||||
|
// killer.getInventory().add(new Item(boss.getPetId(), 1));
|
||||||
|
// killer.sendNotificationMessage("You feel something weird sneaking into your backpack.");
|
||||||
|
// }
|
||||||
|
// Repository.sendNews(killer.getUsername()+" now commands a miniature "+(boss.equals(CORPOREAL_BEAST) ? "Dark core" : boss.getName())+"!");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments the player's Barrows chest counter.
|
||||||
|
* @param player the player
|
||||||
|
*/
|
||||||
|
public static void addtoBarrowsCount(Player player) {
|
||||||
|
if (player == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
player.getSavedData().getGlobalData().setBarrowsLoots(player.getSavedData().getGlobalData().getBarrowsLoots() + 1);
|
||||||
|
player.getPacketDispatch().sendMessage("Your Barrows chest count is: <col=ff0000>" + player.getSavedData().getGlobalData().getBarrowsLoots() + "</col>.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
package content.data
|
|
||||||
|
|
||||||
import core.api.sendMessage
|
|
||||||
import core.game.node.entity.player.Player
|
|
||||||
import org.rs09.consts.NPCs
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enumerates the bosses that have their kill counts tracked in a player's statistics (::stats).
|
|
||||||
* addToBossKillCount(player, npcId) should be added in the finalizeDeath() method of the combat handler for the boss.
|
|
||||||
* ORDINAL BOUND
|
|
||||||
* @author Bishop
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum class BossKillCounter(val bossId: IntArray, val bossName: String) {
|
|
||||||
|
|
||||||
KING_BLACK_DRAGON(intArrayOf(NPCs.KING_BLACK_DRAGON_50), "King Black Dragon"),
|
|
||||||
BORK(intArrayOf(NPCs.BORK_7133, NPCs.BORK_7134), "Bork"),
|
|
||||||
DAGANNOTH_SUPREME(intArrayOf(NPCs.DAGANNOTH_SUPREME_2881), "Dagannoth Supreme"),
|
|
||||||
DAGANNOTH_PRIME(intArrayOf(NPCs.DAGANNOTH_PRIME_2882), "Dagannoth Prime"),
|
|
||||||
DAGANNOTH_REX(intArrayOf(NPCs.DAGANNOTH_REX_2883), "Dagannoth Rex"),
|
|
||||||
CHAOS_ELEMENTAL(intArrayOf(NPCs.CHAOS_ELEMENTAL_3200), "Chaos Elemental"),
|
|
||||||
GIANT_MOLE(intArrayOf(NPCs.GIANT_MOLE_3340), "Giant Mole"),
|
|
||||||
SARADOMIN(intArrayOf(NPCs.COMMANDER_ZILYANA_6247), "Commander Zilyana"),
|
|
||||||
ZAMORAK(intArrayOf(NPCs.KRIL_TSUTSAROTH_6203), "K'ril Tsutsaroth"),
|
|
||||||
BANDOS(intArrayOf(NPCs.GENERAL_GRAARDOR_6260), "General Graardor"),
|
|
||||||
ARMADYL(intArrayOf(NPCs.KREEARRA_6222), "Kree'arra"),
|
|
||||||
JAD(intArrayOf(NPCs.TZTOK_JAD_2745), "Tz-Tok Jad"),
|
|
||||||
KALPHITE_QUEEN(intArrayOf(NPCs.KALPHITE_QUEEN_1160), "Kalphite Queen"),
|
|
||||||
CORPOREAL_BEAST(intArrayOf(NPCs.CORPOREAL_BEAST_8133), "Corporeal Beast"),
|
|
||||||
TORMENTED_DEMONS(
|
|
||||||
intArrayOf(
|
|
||||||
NPCs.TORMENTED_DEMON_8349, NPCs.TORMENTED_DEMON_8350, NPCs.TORMENTED_DEMON_8351,
|
|
||||||
NPCs.TORMENTED_DEMON_8352, NPCs.TORMENTED_DEMON_8353, NPCs.TORMENTED_DEMON_8354,
|
|
||||||
NPCs.TORMENTED_DEMON_8355, NPCs.TORMENTED_DEMON_8356, NPCs.TORMENTED_DEMON_8357,
|
|
||||||
NPCs.TORMENTED_DEMON_8358, NPCs.TORMENTED_DEMON_8359, NPCs.TORMENTED_DEMON_8360,
|
|
||||||
NPCs.TORMENTED_DEMON_8361, NPCs.TORMENTED_DEMON_8362, NPCs.TORMENTED_DEMON_8363,
|
|
||||||
NPCs.TORMENTED_DEMON_8364, NPCs.TORMENTED_DEMON_8365, NPCs.TORMENTED_DEMON_8366),
|
|
||||||
"Tormented demon"
|
|
||||||
),
|
|
||||||
PENANCE_QUEEN(intArrayOf(NPCs.PENANCE_QUEEN_5247), "Penance Queen");
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private fun forBossId(npc: Int): BossKillCounter? {
|
|
||||||
for (kc in values()) {
|
|
||||||
for (i in kc.bossId) {
|
|
||||||
if (npc == i) {
|
|
||||||
return kc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun addToBossKillCount(killer: Player?, bossId: Int) {
|
|
||||||
if (killer == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val boss: BossKillCounter = forBossId(bossId) ?: return
|
|
||||||
killer.getSavedData().globalData.bossCounters[boss.ordinal]++
|
|
||||||
sendMessage(killer, "Your ${boss.bossName} killcount is now: <col=ff0000>${killer.getSavedData().globalData.bossCounters[boss.ordinal]}</col>.")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addToBarrowsChestCount(player: Player?) {
|
|
||||||
if (player == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
player.getSavedData().globalData.barrowsLoots++
|
|
||||||
sendMessage(player, "Your Barrows chest count is: <col=ff0000>${player.getSavedData().globalData.barrowsLoots}</col>.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,14 +9,15 @@ import core.game.event.TeleportEvent
|
||||||
import core.game.interaction.QueueStrength
|
import core.game.interaction.QueueStrength
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
import core.game.node.entity.player.link.TeleportManager
|
import core.game.node.entity.player.link.TeleportManager
|
||||||
import core.game.node.entity.player.link.diary.DiaryType
|
|
||||||
import core.game.node.item.Item
|
import core.game.node.item.Item
|
||||||
|
import core.game.system.task.Pulse
|
||||||
import core.game.world.GameWorld
|
import core.game.world.GameWorld
|
||||||
import core.game.world.map.Location
|
import core.game.world.map.Location
|
||||||
import core.game.world.update.flag.context.Animation
|
import core.game.world.update.flag.context.Animation
|
||||||
import core.game.world.update.flag.context.Graphics
|
import core.game.world.update.flag.context.Graphics
|
||||||
import core.tools.Log
|
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
|
import core.game.world.GameWorld.Pulser
|
||||||
|
import core.tools.Log
|
||||||
import org.rs09.consts.Sounds
|
import org.rs09.consts.Sounds
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
@ -33,14 +34,12 @@ enum class EnchantedJewellery(
|
||||||
"Sumona in Pollnivneach.",
|
"Sumona in Pollnivneach.",
|
||||||
"Morytania Slayer Tower.",
|
"Morytania Slayer Tower.",
|
||||||
"Rellekka Slayer Caves.",
|
"Rellekka Slayer Caves.",
|
||||||
"Tarn's Lair.",
|
|
||||||
"Nowhere. Give me a slayer update."
|
"Nowhere. Give me a slayer update."
|
||||||
),
|
),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Location.create(3361, 2994, 0),
|
Location.create(3361, 2994, 0),
|
||||||
Location.create(3428, 3535, 0),
|
Location.create(3428, 3535, 0),
|
||||||
Location.create(2792, 3615, 0),
|
Location.create(2792, 3615, 0),
|
||||||
Location.create(3187, 4601, 0),
|
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
Items.RING_OF_SLAYING8_13281,
|
Items.RING_OF_SLAYING8_13281,
|
||||||
|
|
@ -195,7 +194,7 @@ enum class EnchantedJewellery(
|
||||||
),
|
),
|
||||||
RING_OF_LIFE(arrayOf<String>(),
|
RING_OF_LIFE(arrayOf<String>(),
|
||||||
arrayOf(
|
arrayOf(
|
||||||
Location.create(ServerConstants.HOME_LOCATION!!)
|
Location.create(ServerConstants.HOME_LOCATION)
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
Items.RING_OF_LIFE_2570
|
Items.RING_OF_LIFE_2570
|
||||||
|
|
@ -242,26 +241,13 @@ enum class EnchantedJewellery(
|
||||||
if (!canTeleport(player, nextJewellery)) {
|
if (!canTeleport(player, nextJewellery)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Access to Tarn's Lair has a quest prereq.
|
|
||||||
if (this == RING_OF_SLAYING && buttonID == 3
|
|
||||||
&& !isQuestComplete(player, Quests.HAUNTED_MINE)
|
|
||||||
) {
|
|
||||||
sendMessage(player, "You must complete the Haunted Mine quest to access Tarn's Lair.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
val location = getLocation(buttonID)
|
val location = getLocation(buttonID)
|
||||||
player.scripts.delay = GameWorld.ticks + 4
|
player.scripts.delay = GameWorld.ticks + 4
|
||||||
queueScript(player, 0, QueueStrength.SOFT) { stage ->
|
queueScript(player, 0, QueueStrength.SOFT) { stage ->
|
||||||
when (stage) {
|
when (stage) {
|
||||||
0 -> {
|
0 -> {
|
||||||
lock(player, 4)
|
lock(player, 4)
|
||||||
// This is an intentional teleport animation & graphics difference as these two jewellery
|
|
||||||
// animations are authentic to 2009 while others are currently unknown.
|
|
||||||
if (this == RING_OF_DUELING || this == GAMES_NECKLACE) {
|
|
||||||
visualize(player, JEWELLERY_ANIMATION, JEWELLERY_GRAPHICS)
|
|
||||||
} else {
|
|
||||||
visualize(player, ANIMATION, GRAPHICS)
|
visualize(player, ANIMATION, GRAPHICS)
|
||||||
}
|
|
||||||
playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
|
playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
|
||||||
player.impactHandler.disabledTicks = 4
|
player.impactHandler.disabledTicks = 4
|
||||||
closeInterface(player)
|
closeInterface(player)
|
||||||
|
|
@ -270,16 +256,8 @@ enum class EnchantedJewellery(
|
||||||
1 -> {
|
1 -> {
|
||||||
teleport(player, location)
|
teleport(player, location)
|
||||||
resetAnimator(player)
|
resetAnimator(player)
|
||||||
if (this == RING_OF_DUELING || this == GAMES_NECKLACE) {
|
|
||||||
player.graphics(JEWELLERY_GRAPHICS)
|
|
||||||
}
|
|
||||||
unlock(player)
|
unlock(player)
|
||||||
player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location))
|
player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location))
|
||||||
|
|
||||||
if (DIGSITE_PENDANT.ids.contains(item.id)) {
|
|
||||||
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!replace) {
|
if (!replace) {
|
||||||
return@queueScript stopExecuting(player)
|
return@queueScript stopExecuting(player)
|
||||||
}
|
}
|
||||||
|
|
@ -388,8 +366,6 @@ enum class EnchantedJewellery(
|
||||||
companion object {
|
companion object {
|
||||||
private val ANIMATION = Animation(714)
|
private val ANIMATION = Animation(714)
|
||||||
private val GRAPHICS = Graphics(308, 100, 50)
|
private val GRAPHICS = Graphics(308, 100, 50)
|
||||||
private val JEWELLERY_ANIMATION = Animation(9603)
|
|
||||||
private val JEWELLERY_GRAPHICS = Graphics(1684)
|
|
||||||
val idMap = HashMap<Int, EnchantedJewellery>()
|
val idMap = HashMap<Int, EnchantedJewellery>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package content.data;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.node.item.Item;
|
import core.game.node.item.Item;
|
||||||
|
|
||||||
import static core.api.ContentAPIKt.isQuestComplete;
|
import static core.api.ContentAPIKt.hasRequirement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A god book.
|
* A god book.
|
||||||
|
|
@ -100,7 +100,7 @@ public enum GodBook {
|
||||||
* @param page the page.
|
* @param page the page.
|
||||||
*/
|
*/
|
||||||
public void insertPage(Player player, Item book, Item page) {
|
public void insertPage(Player player, Item book, Item page) {
|
||||||
if (!isQuestComplete(player, Quests.HORROR_FROM_THE_DEEP))
|
if (!hasRequirement(player, Quests.HORROR_FROM_THE_DEEP))
|
||||||
return;
|
return;
|
||||||
if (hasPage(player, book, page)) {
|
if (hasPage(player, book, page)) {
|
||||||
player.sendMessage("The book already has that page.");
|
player.sendMessage("The book already has that page.");
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ public enum LightSource {
|
||||||
CANDLE(1, new Item(CANDLE_36, 1), new Item(LIT_CANDLE_33, 1), true, Components.DARKNESS_MEDIUM_98),
|
CANDLE(1, new Item(CANDLE_36, 1), new Item(LIT_CANDLE_33, 1), true, Components.DARKNESS_MEDIUM_98),
|
||||||
BLACK_CANDLE(1, new Item(BLACK_CANDLE_38, 1), new Item(LIT_BLACK_CANDLE_32, 1), true, Components.DARKNESS_MEDIUM_98),
|
BLACK_CANDLE(1, new Item(BLACK_CANDLE_38, 1), new Item(LIT_BLACK_CANDLE_32, 1), true, Components.DARKNESS_MEDIUM_98),
|
||||||
TORCH(1, new Item(UNLIT_TORCH_596, 1), new Item(LIT_TORCH_594, 1), true, Components.DARKNESS_MEDIUM_98),
|
TORCH(1, new Item(UNLIT_TORCH_596, 1), new Item(LIT_TORCH_594, 1), true, Components.DARKNESS_MEDIUM_98),
|
||||||
CANDLE_LANTERN(4, new Item(CANDLE_LANTERN_4529, 1), new Item(CANDLE_LANTERN_4531, 1), false, Components.DARKNESS_MEDIUM_98),
|
CANDLE_LANTERN(4, new Item(CANDLE_LANTERN_4527, 1), new Item(CANDLE_LANTERN_4531, 1), false, Components.DARKNESS_MEDIUM_98),
|
||||||
OIL_LAMP(12, new Item(OIL_LAMP_4522, 1), new Item(OIL_LAMP_4524, 1), true, Components.DARKNESS_LIGHT_97),
|
OIL_LAMP(12, new Item(OIL_LAMP_4522, 1), new Item(OIL_LAMP_4524, 1), true, Components.DARKNESS_LIGHT_97),
|
||||||
OIL_LANTERN(26, new Item(OIL_LANTERN_4537, 1), new Item(OIL_LANTERN_4539, 1), false, Components.DARKNESS_LIGHT_97),
|
OIL_LANTERN(26, new Item(OIL_LANTERN_4535, 1), new Item(OIL_LANTERN_4539, 1), false, Components.DARKNESS_LIGHT_97),
|
||||||
BULLSEYE_LANTERN(49, new Item(BULLSEYE_LANTERN_4548, 1), new Item(BULLSEYE_LANTERN_4550, 1), false, -1),
|
BULLSEYE_LANTERN(49, new Item(BULLSEYE_LANTERN_4548, 1), new Item(BULLSEYE_LANTERN_4550, 1), false, -1),
|
||||||
SAPPHIRE_LANTERN(49, new Item(SAPPHIRE_LANTERN_4701, 1), new Item(SAPPHIRE_LANTERN_4702, 1), false, -1),
|
SAPPHIRE_LANTERN(49, new Item(SAPPHIRE_LANTERN_4701, 1), new Item(SAPPHIRE_LANTERN_4702, 1), false, -1),
|
||||||
EMERALD_LANTERN(49, new Item(EMERALD_LANTERN_9064, 1), new Item(EMERALD_LANTERN_9065, 1), false, -1),
|
EMERALD_LANTERN(49, new Item(EMERALD_LANTERN_9064, 1), new Item(EMERALD_LANTERN_9065, 1), false, -1),
|
||||||
|
|
|
||||||
|
|
@ -118,8 +118,6 @@ public enum Consumables {
|
||||||
EGG_AND_TOMATO(new Food(new int[] {7064, 1923}, new HealingEffect(8))),
|
EGG_AND_TOMATO(new Food(new int[] {7064, 1923}, new HealingEffect(8))),
|
||||||
SWEET_CORN(new Food(new int[] {5988}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))),
|
SWEET_CORN(new Food(new int[] {5988}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))),
|
||||||
SWEETCORN_BOWL(new Food(new int[] {7088, 1923}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))),
|
SWEETCORN_BOWL(new Food(new int[] {7088, 1923}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))),
|
||||||
CHOPPED_TUNA(new Food(new int[] {7086, 1923}, new HealingEffect(10))),
|
|
||||||
CHOPPED_ONION(new Food(new int[] {1871, 1923}, new HealingEffect(1))),
|
|
||||||
POTATO_WITH_BUTTER(new Food(new int[] {6703}, new HealingEffect(7))),
|
POTATO_WITH_BUTTER(new Food(new int[] {6703}, new HealingEffect(7))),
|
||||||
CHILLI_POTATO(new Food(new int[] {7054}, new HealingEffect(14))),
|
CHILLI_POTATO(new Food(new int[] {7054}, new HealingEffect(14))),
|
||||||
FRIED_ONIONS(new Food(new int[] {7084, 1923}, new HealingEffect(5))),
|
FRIED_ONIONS(new Food(new int[] {7084, 1923}, new HealingEffect(5))),
|
||||||
|
|
@ -319,7 +317,6 @@ public enum Consumables {
|
||||||
TCHIKI_MONKEY_PASTE(new Food(new int[] {7575}, new HealingEffect(5), "You eat the Tchiki monkey nut paste. It sticks to the roof of your mouth.")),
|
TCHIKI_MONKEY_PASTE(new Food(new int[] {7575}, new HealingEffect(5), "You eat the Tchiki monkey nut paste. It sticks to the roof of your mouth.")),
|
||||||
OOMLIE_WRAP(new Food(new int[] {Items.COOKED_OOMLIE_WRAP_2343}, new MultiEffect(new HealingEffect(14), new AchievementEffect(DiaryType.KARAMJA, 2, 2)))),
|
OOMLIE_WRAP(new Food(new int[] {Items.COOKED_OOMLIE_WRAP_2343}, new MultiEffect(new HealingEffect(14), new AchievementEffect(DiaryType.KARAMJA, 2, 2)))),
|
||||||
ROE(new Food(new int[]{11324}, new HealingEffect(3))),
|
ROE(new Food(new int[]{11324}, new HealingEffect(3))),
|
||||||
CAVIAR(new Food(new int[]{11326}, new HealingEffect(5))),
|
|
||||||
EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))),
|
EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))),
|
||||||
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))),
|
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))),
|
||||||
EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))),
|
EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))),
|
||||||
|
|
@ -346,14 +343,14 @@ public enum Consumables {
|
||||||
AGILITY(new Potion(new int[] {3032, 3034, 3036, 3038}, new SkillEffect(Skills.AGILITY, 3, 0))),
|
AGILITY(new Potion(new int[] {3032, 3034, 3036, 3038}, new SkillEffect(Skills.AGILITY, 3, 0))),
|
||||||
HUNTER(new Potion(new int[] {9998, 10000, 10002, 10004}, new SkillEffect(Skills.HUNTER, 3, 0))),
|
HUNTER(new Potion(new int[] {9998, 10000, 10002, 10004}, new SkillEffect(Skills.HUNTER, 3, 0))),
|
||||||
RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))),
|
RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))),
|
||||||
SARA_BREW(new Potion(new int[] {6685, 6687, 6689, 6691}, new MultiEffect(new PercentHeal(2, .15), new SkillEffect(Skills.ATTACK, 0, -0.10), new SkillEffect(Skills.STRENGTH, 0, -0.10), new SkillEffect(Skills.MAGIC, 0, -0.10), new SkillEffect(Skills.RANGE, 0, -0.10), new SkillEffect(Skills.DEFENCE, 2, 0.2)))),
|
SARA_BREW(new Potion(new int[] {6685, 6687, 6689, 6691}, new MultiEffect(new PercentHeal(0, .15), new SkillEffect(Skills.ATTACK, 0, -0.10), new SkillEffect(Skills.STRENGTH, 0, -0.10), new SkillEffect(Skills.MAGIC, 0, -0.10), new SkillEffect(Skills.RANGE, 0, -0.10), new SkillEffect(Skills.DEFENCE, 0, 0.25)))),
|
||||||
SUMMONING(new Potion(new int[] {12140, 12142, 12144, 12146}, new MultiEffect(new RestoreSummoningSpecial(), new SummoningEffect(7, 0.25)))),
|
SUMMONING(new Potion(new int[] {12140, 12142, 12144, 12146}, new MultiEffect(new RestoreSummoningSpecial(), new SummoningEffect(7, 0.25)))),
|
||||||
COMBAT(new Potion(new int[] {9739, 9741, 9743, 9745}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, .1), new SkillEffect(Skills.ATTACK, 3, .1)))),
|
COMBAT(new Potion(new int[] {9739, 9741, 9743, 9745}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, .1), new SkillEffect(Skills.ATTACK, 3, .1)))),
|
||||||
ENERGY(new Potion(new int[] {3008, 3010, 3012, 3014}, new EnergyEffect(10))),
|
ENERGY(new Potion(new int[] {3008, 3010, 3012, 3014}, new EnergyEffect(10))),
|
||||||
FISHING(new Potion(new int[] {2438, 151, 153, 155}, new SkillEffect(Skills.FISHING, 3, 0))),
|
FISHING(new Potion(new int[] {2438, 151, 153, 155}, new SkillEffect(Skills.FISHING, 3, 0))),
|
||||||
PRAYER(new Potion(new int[] {2434, 139, 141, 143}, new PrayerEffect(7, 0.25))),
|
PRAYER(new Potion(new int[] {2434, 139, 141, 143}, new PrayerEffect(7, 0.25))),
|
||||||
SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new RestoreEffect(8, 0.25, true))),
|
SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new RestoreEffect(8, 0.25, true))),
|
||||||
ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true, 2), new SkillEffect(Skills.ATTACK, 2, 0.20), new SkillEffect(Skills.STRENGTH, 2, 0.12), new SkillEffect(Skills.DEFENCE, -2, -0.10), new PrayerEffect(0.0, 0.10, true)))),
|
ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1)))),
|
||||||
ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))),
|
ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))),
|
||||||
GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))),
|
GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))),
|
||||||
MAGIC_ESS(new Potion(new int[] {9021, 9022, 9023, 9024}, new SkillEffect(Skills.MAGIC,3,0))),
|
MAGIC_ESS(new Potion(new int[] {9021, 9022, 9023, 9024}, new SkillEffect(Skills.MAGIC,3,0))),
|
||||||
|
|
@ -363,7 +360,7 @@ public enum Consumables {
|
||||||
|
|
||||||
/** Barbarian Mixes */
|
/** Barbarian Mixes */
|
||||||
PRAYERMIX(new BarbarianMix(new int[] {11465, 11467}, new MultiEffect(new PrayerEffect(7, 0.25), new HealingEffect(6)))),
|
PRAYERMIX(new BarbarianMix(new int[] {11465, 11467}, new MultiEffect(new PrayerEffect(7, 0.25), new HealingEffect(6)))),
|
||||||
ZAMMY_MIX(new BarbarianMix(new int[]{11521, 11523}, new MultiEffect(new ZamorakMixEffect(), new SkillEffect(Skills.ATTACK, 2, 0.20), new SkillEffect(Skills.STRENGTH, 2, 0.12), new SkillEffect(Skills.DEFENCE, -2, -0.10)))),
|
ZAMMY_MIX(new BarbarianMix(new int[] {11521, 11523}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1)))),
|
||||||
ATT_MIX(new BarbarianMix(new int[] {11429, 11431}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new HealingEffect(3)))),
|
ATT_MIX(new BarbarianMix(new int[] {11429, 11431}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new HealingEffect(3)))),
|
||||||
ANTIP_MIX(new BarbarianMix(new int[] {11433, 11435}, new MultiEffect(new AddTimerEffect("poison:immunity", secondsToTicks(90)), new HealingEffect(3)))),
|
ANTIP_MIX(new BarbarianMix(new int[] {11433, 11435}, new MultiEffect(new AddTimerEffect("poison:immunity", secondsToTicks(90)), new HealingEffect(3)))),
|
||||||
RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new CureDiseaseEffect(), new HealingEffect(3)))),
|
RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new CureDiseaseEffect(), new HealingEffect(3)))),
|
||||||
|
|
|
||||||
|
|
@ -7,21 +7,15 @@ import core.game.node.entity.player.Player;
|
||||||
public class DamageEffect extends ConsumableEffect {
|
public class DamageEffect extends ConsumableEffect {
|
||||||
final double amt;
|
final double amt;
|
||||||
final boolean isPercent;
|
final boolean isPercent;
|
||||||
final int baseAmount;
|
|
||||||
|
|
||||||
public DamageEffect(double amt, boolean isPercent) {
|
public DamageEffect(double amt,boolean isPercent){
|
||||||
this(amt, isPercent, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DamageEffect(double amt, boolean isPercent, int baseAmount) {
|
|
||||||
this.amt = amt;
|
this.amt = amt;
|
||||||
this.isPercent = isPercent;
|
this.isPercent = isPercent;
|
||||||
this.baseAmount = baseAmount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void activate(Player p) {
|
public void activate(Player p) {
|
||||||
p.getImpactHandler().manualHit(p, -getHealthEffectValue(p), ImpactHandler.HitsplatType.NORMAL);
|
p.getImpactHandler().manualHit(p,-getHealthEffectValue(p), ImpactHandler.HitsplatType.NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -29,8 +23,8 @@ public class DamageEffect extends ConsumableEffect {
|
||||||
double amount = amt;
|
double amount = amt;
|
||||||
if (isPercent) {
|
if (isPercent) {
|
||||||
amount /= 100;
|
amount /= 100;
|
||||||
return (int) -(amount * player.getSkills().getLifepoints() + baseAmount);
|
return (int) -(amount * player.getSkills().getLifepoints());
|
||||||
}
|
}
|
||||||
return (int) -(amt + baseAmount);
|
return (int) -amt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,16 @@ import core.game.consumable.ConsumableEffect
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
import core.game.node.entity.skill.Skills
|
import core.game.node.entity.skill.Skills
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
import kotlin.math.ceil
|
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
|
|
||||||
class PrayerEffect @JvmOverloads constructor(var base: Double, var bonus: Double, private val roundUp: Boolean = false) : ConsumableEffect() {
|
class PrayerEffect(var base: Double, var bonus: Double) : ConsumableEffect() {
|
||||||
override fun activate(player: Player?) {
|
override fun activate(player: Player?) {
|
||||||
if(player == null) return
|
if(player == null) return
|
||||||
val level = getStatLevel(player, Skills.PRAYER)
|
val level = getStatLevel(player, Skills.PRAYER)
|
||||||
var b = bonus
|
var b = bonus
|
||||||
if(inInventory(player, Items.HOLY_WRENCH_6714))
|
if(inInventory(player, Items.HOLY_WRENCH_6714))
|
||||||
b += 0.02 // Leaving this in for futureproofing. Current update is for properly rounding down.
|
b += 0.02 // Leaving this in for futureproofing. Current update is for properly rounding down.
|
||||||
val rawAmount = base + (level * b)
|
val amount = floor(base + (level * b))
|
||||||
val amount = if (roundUp) ceil(rawAmount) else floor(rawAmount)
|
|
||||||
modPrayerPoints(player, amount)
|
modPrayerPoints(player, amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package content.data.consumables.effects;
|
|
||||||
|
|
||||||
import core.game.consumable.ConsumableEffect;
|
|
||||||
import core.game.node.entity.combat.ImpactHandler;
|
|
||||||
import core.game.node.entity.player.Player;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Zamorak mix shows the regular Zamorak brew hitsplat (10% of pre-drink lifepoints + 2, rounded down)
|
|
||||||
* but also heals 6 lifepoints. The heal must be applied before the hit so the net change can never kill
|
|
||||||
* the player, while the hitsplat still reflects the pre-heal lifepoints.
|
|
||||||
*/
|
|
||||||
public class ZamorakMixEffect extends ConsumableEffect {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void activate(Player p) {
|
|
||||||
int damage = (int) (p.getSkills().getLifepoints() * 0.10 + 2);
|
|
||||||
p.getSkills().heal(6);
|
|
||||||
p.getImpactHandler().manualHit(p, damage, ImpactHandler.HitsplatType.NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getHealthEffectValue(Player player) {
|
|
||||||
return 6 - (int) (player.getSkills().getLifepoints() * 0.10 + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package content.global.activity.cchallange.npc
|
package content.global.activity.cchallange.npc
|
||||||
|
|
||||||
import core.api.*
|
import core.api.*
|
||||||
|
import core.game.container.impl.EquipmentContainer
|
||||||
|
import core.game.global.action.EquipHandler
|
||||||
import core.game.node.entity.Entity
|
import core.game.node.entity.Entity
|
||||||
import core.game.node.entity.combat.BattleState
|
import core.game.node.entity.combat.BattleState
|
||||||
import core.game.node.entity.npc.AbstractNPC
|
import core.game.node.entity.npc.AbstractNPC
|
||||||
|
|
@ -60,11 +62,12 @@ class LesserDemonChampionNPC(id: Int = 0, location: Location? = null) : Abstract
|
||||||
super.checkImpact(state)
|
super.checkImpact(state)
|
||||||
val player = state.attacker
|
val player = state.attacker
|
||||||
if (player is Player) {
|
if (player is Player) {
|
||||||
if (player.equipment.isEmpty) {
|
if (!player.equipment[3].hasItemPlugin()) {
|
||||||
state.neutralizeHits()
|
state.neutralizeHits()
|
||||||
state.estimatedHit = state.maximumHit
|
state.estimatedHit = state.maximumHit
|
||||||
} else {
|
} else {
|
||||||
sendMessage(player, "You cannot wear any equipment in this challenge.")
|
EquipHandler.unequip(player, EquipmentContainer.SLOT_WEAPON, id)
|
||||||
|
sendMessage(player, "You cannot use weapons in this challenge.")
|
||||||
if (state.estimatedHit > -1) {
|
if (state.estimatedHit > -1) {
|
||||||
state.estimatedHit = 0
|
state.estimatedHit = 0
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ class ZombieChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(i
|
||||||
val player = state.attacker
|
val player = state.attacker
|
||||||
if (player is Player) {
|
if (player is Player) {
|
||||||
if (state.style == CombatStyle.MELEE || state.style == CombatStyle.RANGE) {
|
if (state.style == CombatStyle.MELEE || state.style == CombatStyle.RANGE) {
|
||||||
state.neutralizeHits()
|
|
||||||
state.estimatedHit = state.maximumHit
|
state.estimatedHit = state.maximumHit
|
||||||
|
state.neutralizeHits()
|
||||||
}
|
}
|
||||||
if (state.style == CombatStyle.MAGIC) {
|
if (state.style == CombatStyle.MAGIC) {
|
||||||
sendMessage(player, "You cannot use spells in this challenge.")
|
sendMessage(player, "You cannot use spells in this challenge.")
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class PenguinManager{
|
||||||
return tagMapping[Penguin.forLocation(location)?.ordinal]?.contains(player.username.toLowerCase()) ?: false
|
return tagMapping[Penguin.forLocation(location)?.ordinal]?.contains(player.username.toLowerCase()) ?: false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateStoreFile(){
|
private fun updateStoreFile(){
|
||||||
val jsonTags = JSONArray()
|
val jsonTags = JSONArray()
|
||||||
tagMapping.filter { it.value.isNotEmpty() }.forEach { (ordinal,taggers) ->
|
tagMapping.filter { it.value.isNotEmpty() }.forEach { (ordinal,taggers) ->
|
||||||
log(this::class.java, Log.FINE, "$ordinal - ${taggers.first()}")
|
log(this::class.java, Log.FINE, "$ordinal - ${taggers.first()}")
|
||||||
|
|
|
||||||
|
|
@ -44,65 +44,18 @@ enum class Penguin(val id: Int, val hint: String, val location: Location){
|
||||||
BUSH_8(NPCs.BUSH_8105,"located in the kingdom of Asgarnia.",Location.create(2951, 3511, 0)),
|
BUSH_8(NPCs.BUSH_8105,"located in the kingdom of Asgarnia.",Location.create(2951, 3511, 0)),
|
||||||
BUSH_9(NPCs.BUSH_8105,"located in the northern desert.",Location.create(3350, 3311, 0)),
|
BUSH_9(NPCs.BUSH_8105,"located in the northern desert.",Location.create(3350, 3311, 0)),
|
||||||
BUSH_10(NPCs.BUSH_8105,"located somewhere in the kingdom of Kandarin.",Location.create(2633, 3501, 0)),
|
BUSH_10(NPCs.BUSH_8105,"located somewhere in the kingdom of Kandarin.",Location.create(2633, 3501, 0)),
|
||||||
BUSH_11(NPCs.BUSH_8105,"located where wizards study.",Location.create(3112, 3149, 0)),
|
BUSH_11(NPCs.BUSH_8105,"located south of Ardougne.",Location.create(2440, 3206, 0)),
|
||||||
|
BUSH_12(NPCs.BUSH_8105,"located where wizards study.",Location.create(3112, 3149, 0)),
|
||||||
ROCK_1(NPCs.ROCK_8109,"located where the Imperial Guard train.",Location.create(2852, 3578, 0)),
|
ROCK_1(NPCs.ROCK_8109,"located where the Imperial Guard train.",Location.create(2852, 3578, 0)),
|
||||||
ROCK_2(NPCs.ROCK_8109,"located in the kingdom of Misthalin.",Location.create(3356, 3416, 0)),
|
ROCK_2(NPCs.ROCK_8109,"located in the kingdom of Misthalin.",Location.create(3356, 3416, 0)),
|
||||||
ROCK_3(NPCs.ROCK_8109,"located near some ogres.",Location.create(2631, 2980, 0)), //potentially incorrect location
|
ROCK_3(NPCs.ROCK_8109,"located near some ogres.",Location.create(2631, 2980, 0)),
|
||||||
ROCK_4(NPCs.ROCK_8109,"located in the Kingdom of Asgarnia.",Location.create(3013, 3501, 0)),
|
ROCK_4(NPCs.ROCK_8109,"located in the Kingdom of Asgarnia.",Location.create(3013, 3501, 0)),
|
||||||
ROCK_5(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2532, 3630, 0)),
|
ROCK_5(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2532, 3630, 0)),
|
||||||
CRATE_1(NPCs.CRATE_8108,"located in the kingdom of Misthalin.",Location.create(3112, 3332, 0)),
|
CRATE_1(NPCs.CRATE_8108,"located in the kingdom of Misthalin.",Location.create(3112, 3332, 0)),
|
||||||
CRATE_2(NPCs.CRATE_8108,"located in the Kingdom of Misthalin.",Location.create(3305, 3508, 0)),
|
CRATE_2(NPCs.CRATE_8108,"located in the Kingdom of Misthalin.",Location.create(3305, 3508, 0)),
|
||||||
CRATE_3(NPCs.CRATE_8108,"located south of Ardougne.",Location.create(2440, 3206, 0)),
|
BARREL_1(NPCs.CRATE_8108,"located where no weapons may go.",Location.create(2806, 3383, 0)),
|
||||||
BARREL_1(NPCs.BARREL_8104,"located where no weapons may go.",Location.create(2806, 3383, 0)),
|
|
||||||
TOADSTOOL_1(NPCs.TOADSTOOL_8110,"located in the kingdom of Misthalin.",Location.create(3156, 3178, 0)),
|
TOADSTOOL_1(NPCs.TOADSTOOL_8110,"located in the kingdom of Misthalin.",Location.create(3156, 3178, 0)),
|
||||||
TOADSTOOL_2(NPCs.TOADSTOOL_8110,"located in the fairy realm.",Location.create(2409, 4462, 0)), //potentially a spawn from 2010
|
TOADSTOOL_2(NPCs.TOADSTOOL_8110,"located in the fairy realm.",Location.create(2409, 4462, 0));
|
||||||
|
|
||||||
BUSH_12(NPCs.BUSH_8105,"located on an island.",Location.create(2534, 3871, 0)),
|
|
||||||
BARREL_2(NPCs.BARREL_8104,"located near the ghost town.",Location.create(3654, 3491, 0)),
|
|
||||||
BUSH_13(NPCs.BUSH_8105,"located where bloodsuckers rule.",Location.create(3600, 3487, 0)),
|
|
||||||
BUSH_14(NPCs.BUSH_8105,"located on islands where brothers quarrel.",Location.create(2355, 3848, 0)),
|
|
||||||
ROCK_6(NPCs.ROCK_8109,"located on a large crescent island.",Location.create(2118, 3943, 0)),
|
|
||||||
ROCK_7(NPCs.ROCK_8109,"located on islands where brothers quarrel.",Location.create(2357, 3797, 0)),
|
|
||||||
ROCK_8(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3169, 3650, 0)),
|
|
||||||
BARREL_3(NPCs.BARREL_8104,"located where pirates feel mostly harmless.",Location.create(3738, 3001, 0)),
|
|
||||||
CACTUS_3(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3276, 2797, 0)),
|
|
||||||
TOADSTOOL_3(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2314, 3174, 0)),
|
|
||||||
BUSH_15(NPCs.BUSH_8105,"located deep in the jungle.",Location.create(2938, 2978, 0)),
|
|
||||||
TOADSTOOL_4(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2219, 3227, 0)),
|
|
||||||
BARREL_4(NPCs.BARREL_8104,"located south of Ardougne.",Location.create(2662, 3152, 0)),
|
|
||||||
//BARREL_5(NPCs.BARREL_8104,"located where monkeys rule.",Location.create(2751, 2700, 0)),
|
|
||||||
//currently not well accessible, will need to add when Ape Atoll is sorted.
|
|
||||||
//BUSH_16(NPCs.BUSH_8105,"located on islands where brothers quarrel.",Location.create(2353, 3834, 0)),
|
|
||||||
//currently not well accessible, will need to add when Neitiznot bridges are fixed.
|
|
||||||
ROCK_9(NPCs.ROCK_8109,"located near a mountain of wolves.",Location.create(2852, 3504, 0)),
|
|
||||||
ROCK_10(NPCs.ROCK_8109,"located on islands where brothers quarrel.",Location.create(2413, 3846, 0)),
|
|
||||||
|
|
||||||
BUSH_17(NPCs.BUSH_8105,"located near some ogres.",Location.create(2578, 2909, 0)),
|
|
||||||
CRATE_4(NPCs.CRATE_8108,"located where banana smugglers dwell.",Location.create(2869, 3157, 0)),
|
|
||||||
//CRATE_5(NPCs.CRATE_8108,"located near the island of Dragontooth.",Location.create(3824, 3562, 0)),
|
|
||||||
//current not accessible, will need to add when Dragontooth island is sorted.
|
|
||||||
ROCK_11(NPCs.ROCK_8109,"located where bloodsuckers rule.",Location.create(3550, 3439, 0)),
|
|
||||||
TOADSTOOL_5(NPCs.TOADSTOOL_8110,"located near the pointy-eared ones.",Location.create(2181, 3172, 0)),
|
|
||||||
BUSH_18(NPCs.BUSH_8105,"located where bloodsuckers rule.",Location.create(3472, 3392, 0)),
|
|
||||||
BUSH_19(NPCs.BUSH_8105,"located near Port Sarim.",Location.create(2989, 3121, 0)),
|
|
||||||
CRATE_6(NPCs.CRATE_8108,"located where fishers colonise.",Location.create(2322, 3658, 0)),
|
|
||||||
ROCK_12(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2675, 3717, 0)),
|
|
||||||
ROCK_13(NPCs.ROCK_8109,"located near the pointy-eared ones.",Location.create(2296, 3270, 0)),
|
|
||||||
CRATE_7(NPCs.CRATE_8108,"located where bloodsuckers rule.",Location.create(3637, 3486, 0)),
|
|
||||||
TOADSTOOL_6(NPCs.TOADSTOOL_8110,"located where bloodsuckers rule.",Location.create(3416, 3437, 0)),
|
|
||||||
BUSH_20(NPCs.BUSH_8105,"located where monkeys rule.",Location.create(2802, 2806, 0)),
|
|
||||||
|
|
||||||
ROCK_14(NPCs.ROCK_8109,"located near some ogres.",Location.create(2438, 3050, 0)),
|
|
||||||
CACTUS_4(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3252, 2963, 0)),
|
|
||||||
ROCK_15(NPCs.ROCK_8109,"located near some ogres.",Location.create(2340, 3064, 0)),
|
|
||||||
ROCK_16(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3108, 3837, 0)),
|
|
||||||
CACTUS_5(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3433, 3000, 0)),
|
|
||||||
CACTUS_6(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3274, 2813, 0)),
|
|
||||||
ROCK_17(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3019, 3866, 0)),
|
|
||||||
ROCK_18(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(2991, 3824, 0)),
|
|
||||||
BUSH_21(NPCs.BUSH_8105,"located north of Ardougne.",Location.create(2398, 3361, 0)),
|
|
||||||
ROCK_19(NPCs.ROCK_8109,"located near the coast.",Location.create(2733, 3283, 0)),
|
|
||||||
ROCK_20(NPCs.ROCK_8109,"located in the Wilderness.",Location.create(3236, 3927, 0));
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val locationMap = values().map { it.location.toString() to it }.toMap()
|
private val locationMap = values().map { it.location.toString() to it }.toMap()
|
||||||
|
|
|
||||||
|
|
@ -99,18 +99,12 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
||||||
return ShootingStarType.values()[level.ordinal - 1]
|
return ShootingStarType.values()[level.ordinal - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the current star object or sprite
|
|
||||||
*/
|
|
||||||
fun clear() {
|
|
||||||
SceneryBuilder.remove(starObject)
|
|
||||||
clearSprite()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires the shooting star (spawns a new one). Only used when spawning new shooting stars, not for downgrading existing ones.
|
* Fires the shooting star (spawns a new one). Only used when spawning new shooting stars, not for downgrading existing ones.
|
||||||
*/
|
*/
|
||||||
fun fire() {
|
fun fire() {
|
||||||
|
SceneryBuilder.remove(starObject)
|
||||||
|
clearSprite()
|
||||||
SceneryBuilder.add(starObject)
|
SceneryBuilder.add(starObject)
|
||||||
if(!isSpawned) {
|
if(!isSpawned) {
|
||||||
(0..2).forEach {
|
(0..2).forEach {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import core.game.world.GameWorld
|
||||||
import core.tools.Log
|
import core.tools.Log
|
||||||
import core.tools.secondsToTicks
|
import core.tools.secondsToTicks
|
||||||
import content.data.Quests
|
import content.data.Quests
|
||||||
import core.game.node.scenery.SceneryBuilder
|
|
||||||
|
|
||||||
class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener {
|
class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener {
|
||||||
override fun login(player: Player) {
|
override fun login(player: Player) {
|
||||||
|
|
@ -47,7 +46,6 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
||||||
|
|
||||||
// Check if it's time to fire a new one
|
// Check if it's time to fire a new one
|
||||||
if (star.ticks >= tickDelay && !star.spriteSpawned) {
|
if (star.ticks >= tickDelay && !star.spriteSpawned) {
|
||||||
star.clear()
|
|
||||||
star.rebuildVars()
|
star.rebuildVars()
|
||||||
star.fire()
|
star.fire()
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +138,6 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
||||||
}
|
}
|
||||||
|
|
||||||
define("submit", Privilege.ADMIN, description = "Rebuilds and fires the shooting star event immediately.") { _, _ ->
|
define("submit", Privilege.ADMIN, description = "Rebuilds and fires the shooting star event immediately.") { _, _ ->
|
||||||
star.clear()
|
|
||||||
star.rebuildVars()
|
star.rebuildVars()
|
||||||
star.fire()
|
star.fire()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
package content.global.ame
|
package content.global.ame
|
||||||
|
|
||||||
import content.global.ame.events.surpriseexam.MysteriousOldManNPC
|
import content.global.ame.events.surpriseexam.MysteriousOldManNPC
|
||||||
import core.api.getAttribute
|
|
||||||
import core.api.playGlobalAudio
|
import core.api.playGlobalAudio
|
||||||
import core.api.poofClear
|
import core.api.poofClear
|
||||||
import core.api.removeAttribute
|
|
||||||
import core.api.sendMessage
|
import core.api.sendMessage
|
||||||
import core.api.setAttribute
|
import core.api.setAttribute
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
|
|
@ -27,6 +25,8 @@ import core.tools.secondsToTicks
|
||||||
import core.tools.ticksToCycles
|
import core.tools.ticksToCycles
|
||||||
import org.rs09.consts.NPCs
|
import org.rs09.consts.NPCs
|
||||||
import org.rs09.consts.Sounds
|
import org.rs09.consts.Sounds
|
||||||
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.min
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.reflect.full.createInstance
|
import kotlin.reflect.full.createInstance
|
||||||
|
|
||||||
|
|
@ -37,8 +37,8 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
||||||
val SMOKE_GRAPHICS = Graphics(86)
|
val SMOKE_GRAPHICS = Graphics(86)
|
||||||
var initialized = false
|
var initialized = false
|
||||||
var finalized = false
|
var finalized = false
|
||||||
|
var timerPaused = false
|
||||||
var ticksLeft = secondsToTicks(180)
|
var ticksLeft = secondsToTicks(180)
|
||||||
private val combatBracket = intArrayOf(10, 20, 40, 60, 90)
|
|
||||||
|
|
||||||
open fun create(player: Player, loot: WeightBasedTable? = null, type: String = ""): RandomEventNPC {
|
open fun create(player: Player, loot: WeightBasedTable? = null, type: String = ""): RandomEventNPC {
|
||||||
val event = this::class.createInstance()
|
val event = this::class.createInstance()
|
||||||
|
|
@ -56,7 +56,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
||||||
poofClear(this)
|
poofClear(this)
|
||||||
playGlobalAudio(this.location, Sounds.SMOKEPUFF_1930, ticksToCycles(1))
|
playGlobalAudio(this.location, Sounds.SMOKEPUFF_1930, ticksToCycles(1))
|
||||||
}
|
}
|
||||||
removeAttribute(player, "random:pause")
|
|
||||||
finalized = true
|
finalized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,6 +92,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
||||||
override fun init() {
|
override fun init() {
|
||||||
initialized = true
|
initialized = true
|
||||||
finalized = false
|
finalized = false
|
||||||
|
timerPaused = false
|
||||||
spawnLocation ?: terminate()
|
spawnLocation ?: terminate()
|
||||||
location = spawnLocation
|
location = spawnLocation
|
||||||
player.setAttribute("re-npc", this)
|
player.setAttribute("re-npc", this)
|
||||||
|
|
@ -144,13 +144,12 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun idForCombatLevel(ids: List<Int>, player: Player): Int {
|
fun idForCombatLevel(ids: List<Int>, player: Player): Int {
|
||||||
val index = combatBracket.indexOfFirst { player.properties.currentCombatLevel <= it }.takeIf { it != -1 }?: ids.lastIndex
|
val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1
|
||||||
return ids[index]
|
return ids[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sayLine(npc: NPC, phrases: Array<String>, hasOpeningPhrase: Boolean, hasOverTimePhrase: Boolean) {
|
fun sayLine(npc: NPC, phrases: Array<String>, hasOpeningPhrase: Boolean, hasOverTimePhrase: Boolean) {
|
||||||
val inInteraction = getAttribute(player, "random:pause", false) //used by Certer
|
if (!timerPaused && (ticksLeft % 20 == 0 || ticksLeft <= 2)) { //unless the Certer interface is up, speak every 20 ticks, or in the 2nd-to-last tick before attack/note-&-teleport
|
||||||
if ((ticksLeft % 20 == 0 || ticksLeft <= 2) && !inInteraction) { //speak every 20 ticks, or in the 2nd-to-last tick before attack/note-&-teleport
|
|
||||||
var playDwarfWhistle = true
|
var playDwarfWhistle = true
|
||||||
if (ticksLeft == secondsToTicks(180) && hasOpeningPhrase) {
|
if (ticksLeft == secondsToTicks(180) && hasOpeningPhrase) {
|
||||||
sendChat(phrases[0])
|
sendChat(phrases[0])
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import org.rs09.consts.NPCs
|
||||||
import content.global.ame.RandomEventNPC
|
import content.global.ame.RandomEventNPC
|
||||||
import core.api.animate
|
import core.api.animate
|
||||||
import core.api.lock
|
import core.api.lock
|
||||||
import core.api.setAttribute
|
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
|
|
||||||
class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) {
|
class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) {
|
||||||
|
|
@ -34,7 +33,8 @@ class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NP
|
||||||
"It's really rude to ignore someone, ${player.username}!",
|
"It's really rude to ignore someone, ${player.username}!",
|
||||||
"No-one ignores me!"
|
"No-one ignores me!"
|
||||||
)
|
)
|
||||||
setAttribute(player, "certer:reward", false)
|
player.setAttribute("random:pause", false)
|
||||||
|
player.setAttribute("certer:reward", false)
|
||||||
animate(this, Emotes.BOW.animation, true)
|
animate(this, Emotes.BOW.animation, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,9 @@ object DrillDemonUtils {
|
||||||
|
|
||||||
fun reward(player: Player) {
|
fun reward(player: Player) {
|
||||||
queueScript(player, 2, QueueStrength.SOFT) {
|
queueScript(player, 2, QueueStrength.SOFT) {
|
||||||
val hasHat = hasAnItem(player, Items.CAMO_HELMET_6656, checkPOH = true).exists()
|
val hasHat = hasAnItem(player, Items.CAMO_HELMET_6656).container != null
|
||||||
val hasShirt = hasAnItem(player, Items.CAMO_TOP_6654, checkPOH = true).exists()
|
val hasShirt = hasAnItem(player, Items.CAMO_TOP_6654).container != null
|
||||||
val hasPants = hasAnItem(player, Items.CAMO_BOTTOMS_6655, checkPOH = true).exists()
|
val hasPants = hasAnItem(player, Items.CAMO_BOTTOMS_6655).container != null
|
||||||
when {
|
when {
|
||||||
!hasHat -> addItemOrDrop(player, Items.CAMO_HELMET_6656)
|
!hasHat -> addItemOrDrop(player, Items.CAMO_HELMET_6656)
|
||||||
!hasShirt -> addItemOrDrop(player, Items.CAMO_TOP_6654)
|
!hasShirt -> addItemOrDrop(player, Items.CAMO_TOP_6654)
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,12 @@ import core.game.node.item.Item
|
||||||
import core.tools.RandomFunction
|
import core.tools.RandomFunction
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
import content.global.ame.RandomEventNPC
|
import content.global.ame.RandomEventNPC
|
||||||
import core.api.sendMessage
|
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
|
|
||||||
val ids = (2463..2468).toList()
|
val ids = (2463..2468).toList()
|
||||||
|
|
||||||
class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) {
|
class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) {
|
||||||
val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!")
|
val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!")
|
||||||
var sentMessage = false
|
|
||||||
override fun talkTo(npc: NPC) {}
|
override fun talkTo(npc: NPC) {}
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
|
|
@ -33,16 +31,13 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (!sentMessage) {
|
if(!player.location.withinDistance(this.location,8)){
|
||||||
if (!player.location.withinDistance(this.location, 8)) {
|
this.terminate()
|
||||||
// https://www.youtube.com/watch?v=v9p_I_Tq3JE
|
|
||||||
sendMessage(player, "The Evil Chicken realises you're out of range and vanishes.")
|
|
||||||
sentMessage = true
|
|
||||||
terminate()
|
|
||||||
} else if (getWorldTicks() % 10 == 0) {
|
|
||||||
sendChat(phrases.random().replace("@name", player.username.capitalize()))
|
|
||||||
}
|
}
|
||||||
|
if(getWorldTicks() % 10 == 0){
|
||||||
|
sendChat(phrases.random().replace("@name",player.username.capitalize()))
|
||||||
}
|
}
|
||||||
super.tick()
|
super.tick()
|
||||||
|
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,9 @@ object FreakUtils{
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reward(player: Player){
|
fun reward(player: Player){
|
||||||
val hasHat = hasAnItem(player, Items.LEDERHOSEN_HAT_6182, checkPOH = true).exists()
|
val hasHat = hasAnItem(player, Items.LEDERHOSEN_HAT_6182).container != null
|
||||||
val hasTop = hasAnItem(player, Items.LEDERHOSEN_TOP_6180, checkPOH = true).exists()
|
val hasTop = hasAnItem(player, Items.LEDERHOSEN_TOP_6180).container != null
|
||||||
val hasShort = hasAnItem(player, Items.LEDERHOSEN_SHORTS_6181, checkPOH = true).exists()
|
val hasShort = hasAnItem(player, Items.LEDERHOSEN_SHORTS_6181).container != null
|
||||||
sendNPCDialogue(player, freakNpc, "You get a lederhosen item as a reward for your help, many thanks!")
|
sendNPCDialogue(player, freakNpc, "You get a lederhosen item as a reward for your help, many thanks!")
|
||||||
when{
|
when{
|
||||||
(!hasHat) -> addItemOrDrop(player, Items.LEDERHOSEN_HAT_6182, 1)
|
(!hasHat) -> addItemOrDrop(player, Items.LEDERHOSEN_HAT_6182, 1)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ import core.game.interaction.InteractionListener
|
||||||
import core.game.interaction.QueueStrength
|
import core.game.interaction.QueueStrength
|
||||||
import core.game.node.entity.Entity
|
import core.game.node.entity.Entity
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
|
import core.game.system.task.Pulse
|
||||||
|
import core.game.world.GameWorld.Pulser
|
||||||
import core.game.world.map.Location
|
import core.game.world.map.Location
|
||||||
import core.game.world.map.zone.ZoneBorders
|
import core.game.world.map.zone.ZoneBorders
|
||||||
import core.game.world.map.zone.ZoneRestriction
|
import core.game.world.map.zone.ZoneRestriction
|
||||||
|
|
@ -74,23 +76,9 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||||
WeightedItem(Items.DEFENCE_POTION2_135,1,1,1.0),
|
WeightedItem(Items.DEFENCE_POTION2_135,1,1,1.0),
|
||||||
)
|
)
|
||||||
|
|
||||||
private val ONE_WAY_WALL = mapOf(
|
|
||||||
Location.create(2904, 4573, 0) to setOf( // Diagonal entries
|
|
||||||
Location.create(2904, 4573, 0),
|
|
||||||
Location.create(2904, 4572, 0),
|
|
||||||
Location.create(2904, 4574, 0),
|
|
||||||
),
|
|
||||||
Location.create(2906, 4586, 0) to setOf( // Diagonal entries
|
|
||||||
Location.create(2906, 4586, 0),
|
|
||||||
Location.create(2907, 4586, 0),
|
|
||||||
),
|
|
||||||
Location.create(2902, 4575, 0) to setOf(Location.create(2903, 4575, 0)),
|
|
||||||
Location.create(2924, 4583, 0) to setOf(Location.create(2923, 4583, 0)),
|
|
||||||
)
|
|
||||||
|
|
||||||
fun initMaze(player: Player) {
|
fun initMaze(player: Player) {
|
||||||
setAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 500)
|
setAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 300)
|
||||||
setVarp(player, MAZE_TIMER_VARP, (getAttribute<Int>(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) + 4) / 5,false)
|
setVarp(player, MAZE_TIMER_VARP, (getAttribute<Int>(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) / 3),false)
|
||||||
openOverlay(player, MAZE_TIMER_INTERFACE)
|
openOverlay(player, MAZE_TIMER_INTERFACE)
|
||||||
sendMessage(player, "You need to reach the maze center, then you'll be returned to where you were.")
|
sendMessage(player, "You need to reach the maze center, then you'll be returned to where you were.")
|
||||||
sendNPCDialogue(player, NPCs.MYSTERIOUS_OLD_MAN_410, "You need to reach the maze center, then you'll be returned to where you were.")
|
sendNPCDialogue(player, NPCs.MYSTERIOUS_OLD_MAN_410, "You need to reach the maze center, then you'll be returned to where you were.")
|
||||||
|
|
@ -99,7 +87,7 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||||
fun calculateLoot(player: Player) {
|
fun calculateLoot(player: Player) {
|
||||||
val randomNumber = (0..8).random()
|
val randomNumber = (0..8).random()
|
||||||
val totalLevel = player.getSkills().totalLevel.toDouble()
|
val totalLevel = player.getSkills().totalLevel.toDouble()
|
||||||
val rewardPotential = getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0).toDouble() / 500.0
|
val rewardPotential = getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0).toDouble() / 300.0
|
||||||
val itemDivisor = ITEM_DIVISOR[randomNumber]
|
val itemDivisor = ITEM_DIVISOR[randomNumber]
|
||||||
val itemQuantity = (totalLevel * rewardPotential * 3.33) / itemDivisor
|
val itemQuantity = (totalLevel * rewardPotential * 3.33) / itemDivisor
|
||||||
// sendMessage(player, "Maze reward calculation: $totalLevel * $rewardPotential * 3.33 / $itemDivisor = $itemQuantity")
|
// sendMessage(player, "Maze reward calculation: $totalLevel * $rewardPotential * 3.33 / $itemDivisor = $itemQuantity")
|
||||||
|
|
@ -107,17 +95,73 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||||
addItemOrDrop(player, REWARD_ITEM[randomNumber], itemQuantity.toInt())
|
addItemOrDrop(player, REWARD_ITEM[randomNumber], itemQuantity.toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chest Location to rotation mapping.
|
||||||
|
* This is needed as it is impossible to obtain the underlying chest scenery for the rotation.
|
||||||
|
* 0: Facing North, 1: Facing East, 2: Facing South, 3: Facing West
|
||||||
|
*/
|
||||||
|
val chestLocationRotationMap = mapOf(
|
||||||
|
Location(2930, 4595, 0).toString() to 2,
|
||||||
|
Location(2924, 4572, 0).toString() to 2,
|
||||||
|
Location(2925, 4573, 0).toString() to 0,
|
||||||
|
Location(2900, 4578, 0).toString() to 2,
|
||||||
|
Location(2901, 4560, 0).toString() to 1,
|
||||||
|
Location(2890, 4599, 0).toString() to 2,
|
||||||
|
Location(2896, 4591, 0).toString() to 2,
|
||||||
|
Location(2895, 4592, 0).toString() to 1,
|
||||||
|
Location(2901, 4560, 0).toString() to 3,
|
||||||
|
Location(2918, 4590, 0).toString() to 1,
|
||||||
|
Location(2917, 4590, 0).toString() to 3,
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chest Interaction workaround
|
||||||
|
*
|
||||||
|
* The issue here is that the walls(3626) of the Maze are overlapping some(not all) chest sceneries.
|
||||||
|
*
|
||||||
|
* The types for the wallScenery:
|
||||||
|
* Type 0 - flat panel |
|
||||||
|
* Type 2 - right angle panel with rotation 0:r 1:7 2:> 3:L
|
||||||
|
* Type 3 - corner post . for angle edges of walls
|
||||||
|
*/
|
||||||
|
fun overrideScenery(wallScenery: core.game.node.scenery.Scenery, chestSceneryId: Int): core.game.node.scenery.Scenery {
|
||||||
|
if (wallScenery.id == chestSceneryId) {
|
||||||
|
replaceScenery(wallScenery, Scenery.CHEST_3636, 30)
|
||||||
|
wallScenery.isActive = true
|
||||||
|
return wallScenery // Return the chest scenery as the wallScenery isn't there.
|
||||||
|
}
|
||||||
|
|
||||||
|
addScenery(Scenery.CHEST_3636, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10)
|
||||||
|
addScenery(wallScenery)
|
||||||
|
// replaceScenery(newChestScenery, Scenery.CHEST_3636, 3) // didn't work for an underlying scenery
|
||||||
|
// I did a world pulse since everyone will get to see the chest open.
|
||||||
|
Pulser.submit(object : Pulse(30) {
|
||||||
|
override fun pulse(): Boolean {
|
||||||
|
addScenery(Scenery.CHEST_3635, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10)
|
||||||
|
addScenery(wallScenery)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Return the chest scenery to replace PacketProcessor so that MISMATCH will not happen.
|
||||||
|
return core.game.node.scenery.Scenery(
|
||||||
|
chestSceneryId,
|
||||||
|
wallScenery.location,
|
||||||
|
chestLocationRotationMap[wallScenery.location.toString()] ?: 0
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun defineListeners() {
|
override fun defineListeners() {
|
||||||
|
|
||||||
|
// This somehow doesn't trigger as the scenery.id != objId (3626 != 3635)
|
||||||
on(Scenery.CHEST_3635, IntType.SCENERY, "open") { player, node ->
|
on(Scenery.CHEST_3635, IntType.SCENERY, "open") { player, node ->
|
||||||
lock(player, 3)
|
|
||||||
animate(player, 536)
|
|
||||||
replaceScenery(node.asScenery(), Scenery.CHEST_3636, 3)
|
|
||||||
if (getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0 && getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0) < 10) {
|
if (getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0 && getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0) < 10) {
|
||||||
|
animate(player, 536)
|
||||||
|
// val actualScenery = RegionManager.getObject(node.location.z, node.location.x, node.location.y, 3626)
|
||||||
val tableRoll = CHEST_REWARDS.roll()
|
val tableRoll = CHEST_REWARDS.roll()
|
||||||
addItemOrBank(player, tableRoll[0].id, tableRoll[0].amount)
|
addItemOrBank(player, tableRoll[0].id, tableRoll[0].amount)
|
||||||
when (tableRoll[0].id) {
|
when (tableRoll[0].id){
|
||||||
Items.AIR_RUNE_556 -> sendItemDialogue(player, Items.AIR_RUNE_556, "You've found some air runes!")
|
Items.AIR_RUNE_556 -> sendItemDialogue(player, Items.AIR_RUNE_556, "You've found some air runes!")
|
||||||
Items.WATER_RUNE_555 -> sendItemDialogue(player, Items.WATER_RUNE_555, "You've found some water runes!")
|
Items.WATER_RUNE_555 -> sendItemDialogue(player, Items.WATER_RUNE_555, "You've found some water runes!")
|
||||||
Items.EARTH_RUNE_557 -> sendItemDialogue(player, Items.EARTH_RUNE_557, "You've found some earth runes!")
|
Items.EARTH_RUNE_557 -> sendItemDialogue(player, Items.EARTH_RUNE_557, "You've found some earth runes!")
|
||||||
|
|
@ -129,7 +173,7 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||||
Items.STRENGTH_POTION2_117 -> sendItemDialogue(player, Items.STRENGTH_POTION2_117, "You've found a strength potion!")
|
Items.STRENGTH_POTION2_117 -> sendItemDialogue(player, Items.STRENGTH_POTION2_117, "You've found a strength potion!")
|
||||||
Items.DEFENCE_POTION2_135 -> sendItemDialogue(player, Items.DEFENCE_POTION2_135, "You've found a defence potion!")
|
Items.DEFENCE_POTION2_135 -> sendItemDialogue(player, Items.DEFENCE_POTION2_135, "You've found a defence potion!")
|
||||||
}
|
}
|
||||||
setAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0) + 1)
|
setAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0))
|
||||||
} else {
|
} else {
|
||||||
sendMessage(player,"You find nothing of interest.")
|
sendMessage(player,"You find nothing of interest.")
|
||||||
}
|
}
|
||||||
|
|
@ -146,25 +190,10 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||||
return@on true
|
return@on true
|
||||||
}
|
}
|
||||||
|
|
||||||
on(
|
on(Scenery.WALL_3628, IntType.SCENERY, "open") { player, node ->
|
||||||
intArrayOf(
|
// Door opening workaround
|
||||||
Scenery.WALL_3628,
|
// Ignore 3629(WALL_3629) and 3630(WALL_3630) in handleAutowalkDoor ignoreSecondDoor
|
||||||
Scenery.WALL_3629,
|
DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery)
|
||||||
Scenery.WALL_3630,
|
|
||||||
Scenery.WALL_3631,
|
|
||||||
Scenery.WALL_3632,
|
|
||||||
),
|
|
||||||
IntType.SCENERY,
|
|
||||||
"open"
|
|
||||||
) { player, node ->
|
|
||||||
val scenery = node as core.game.node.scenery.Scenery
|
|
||||||
|
|
||||||
if (ONE_WAY_WALL[scenery.location]?.contains(player.location) == true) {
|
|
||||||
sendDialogue(player, "I don't think that's the right way.")
|
|
||||||
} else {
|
|
||||||
DoorActionHandler.handleAutowalkDoor(player, scenery)
|
|
||||||
}
|
|
||||||
|
|
||||||
return@on true
|
return@on true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +240,7 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||||
if (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0) {
|
if (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0) {
|
||||||
setAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) - 1)
|
setAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) - 1)
|
||||||
}
|
}
|
||||||
setVarp(entity, MAZE_TIMER_VARP, (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) + 4) / 5, false)
|
setVarp(entity, MAZE_TIMER_VARP, (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) / 3), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@ class QuizMasterDialogueFile : DialogueLabeller() {
|
||||||
|
|
||||||
override fun addConversation() {
|
override fun addConversation() {
|
||||||
assignToIds(NPCs.QUIZ_MASTER_2477)
|
assignToIds(NPCs.QUIZ_MASTER_2477)
|
||||||
|
afterClose { player ->
|
||||||
|
loadLabel(player, "question")
|
||||||
|
}
|
||||||
|
|
||||||
npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>", unclosable = true)
|
npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>", unclosable = true)
|
||||||
player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...", unclosable = true)
|
player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...", unclosable = true)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable?
|
||||||
super.init()
|
super.init()
|
||||||
sendChat("Hey ${player.username}! It's your lucky day!")
|
sendChat("Hey ${player.username}! It's your lucky day!")
|
||||||
face(player)
|
face(player)
|
||||||
kidnapPlayer(this, player, Location(1952, 4764, 1)) { player, _ ->
|
kidnapPlayer(this, player, Location(1952, 4764, 0)) { player, _ ->
|
||||||
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
|
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
|
||||||
sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.")
|
sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.")
|
||||||
sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case.
|
sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import core.game.node.entity.Entity
|
||||||
import core.game.node.entity.npc.NPC
|
import core.game.node.entity.npc.NPC
|
||||||
import content.global.ame.RandomEventNPC
|
import content.global.ame.RandomEventNPC
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
import core.game.world.map.MapDistance
|
|
||||||
|
|
||||||
val ids = (391..396).toList()
|
val ids = (391..396).toList()
|
||||||
|
|
||||||
|
|
@ -22,12 +21,10 @@ class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEvent
|
||||||
super.finalizeDeath(killer)
|
super.finalizeDeath(killer)
|
||||||
}
|
}
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (!player.location.withinDistance(this.location, 8)) {
|
if(!player.location.withinDistance(this.location,8)){
|
||||||
this.terminate()
|
this.terminate()
|
||||||
}
|
}
|
||||||
super.tick()
|
super.tick()
|
||||||
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
|
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
|
||||||
this.clear()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ import core.game.node.entity.Entity
|
||||||
import core.game.node.entity.npc.NPC
|
import core.game.node.entity.npc.NPC
|
||||||
import content.global.ame.RandomEventNPC
|
import content.global.ame.RandomEventNPC
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
import core.game.world.map.MapDistance
|
|
||||||
|
|
||||||
val ids = (413..418).toList()
|
val ids = (413..418).toList()
|
||||||
|
|
||||||
|
|
@ -22,12 +21,10 @@ class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventN
|
||||||
super.finalizeDeath(killer)
|
super.finalizeDeath(killer)
|
||||||
}
|
}
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (!player.location.withinDistance(this.location, 8)) {
|
if(!player.location.withinDistance(this.location,8)){
|
||||||
this.terminate()
|
this.terminate()
|
||||||
}
|
}
|
||||||
super.tick()
|
super.tick()
|
||||||
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
|
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
|
||||||
this.clear()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ import core.game.node.entity.Entity
|
||||||
import core.game.node.entity.npc.NPC
|
import core.game.node.entity.npc.NPC
|
||||||
import content.global.ame.RandomEventNPC
|
import content.global.ame.RandomEventNPC
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
import core.game.world.map.MapDistance
|
|
||||||
|
|
||||||
class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){
|
class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){
|
||||||
val ids = (425..430).toList()
|
val ids = (425..430).toList()
|
||||||
|
|
@ -21,12 +20,10 @@ class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(4
|
||||||
super.finalizeDeath(killer)
|
super.finalizeDeath(killer)
|
||||||
}
|
}
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (!player.location.withinDistance(this.location, 8)) {
|
if(!player.location.withinDistance(this.location,8)){
|
||||||
this.terminate()
|
this.terminate()
|
||||||
}
|
}
|
||||||
super.tick()
|
super.tick()
|
||||||
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
|
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
|
||||||
this.clear()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import core.game.node.entity.Entity
|
||||||
import core.game.node.entity.npc.NPC
|
import core.game.node.entity.npc.NPC
|
||||||
import content.global.ame.RandomEventNPC
|
import content.global.ame.RandomEventNPC
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
import core.game.world.map.MapDistance
|
|
||||||
|
|
||||||
val ids = (438..443).toList()
|
val ids = (438..443).toList()
|
||||||
|
|
||||||
|
|
@ -22,12 +21,10 @@ class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEvent
|
||||||
super.finalizeDeath(killer)
|
super.finalizeDeath(killer)
|
||||||
}
|
}
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (!player.location.withinDistance(this.location, 8)) {
|
if(!player.location.withinDistance(this.location,8)){
|
||||||
this.terminate()
|
this.terminate()
|
||||||
}
|
}
|
||||||
super.tick()
|
super.tick()
|
||||||
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
|
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
|
||||||
this.clear()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ import core.game.node.entity.Entity
|
||||||
import core.game.node.entity.npc.NPC
|
import core.game.node.entity.npc.NPC
|
||||||
import content.global.ame.RandomEventNPC
|
import content.global.ame.RandomEventNPC
|
||||||
import core.api.utils.WeightBasedTable
|
import core.api.utils.WeightBasedTable
|
||||||
import core.game.world.map.MapDistance
|
|
||||||
|
|
||||||
class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){
|
class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){
|
||||||
val ids = (419..424).toList()
|
val ids = (419..424).toList()
|
||||||
|
|
@ -21,12 +20,10 @@ class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(
|
||||||
super.finalizeDeath(killer)
|
super.finalizeDeath(killer)
|
||||||
}
|
}
|
||||||
override fun tick() {
|
override fun tick() {
|
||||||
if (!player.location.withinDistance(this.location, 8)) {
|
if(!player.location.withinDistance(this.location,8)){
|
||||||
this.terminate()
|
this.terminate()
|
||||||
}
|
}
|
||||||
super.tick()
|
super.tick()
|
||||||
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
|
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
|
||||||
this.clear()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,24 @@ import core.game.world.GameWorld
|
||||||
import core.game.world.map.Location
|
import core.game.world.map.Location
|
||||||
import core.game.world.map.RegionManager
|
import core.game.world.map.RegionManager
|
||||||
import core.game.world.map.zone.ZoneBorders
|
import core.game.world.map.zone.ZoneBorders
|
||||||
|
import core.game.world.update.flag.*
|
||||||
import org.json.simple.JSONArray
|
import org.json.simple.JSONArray
|
||||||
import org.json.simple.JSONObject
|
import org.json.simple.JSONObject
|
||||||
import core.ServerConstants
|
import core.ServerConstants
|
||||||
|
import core.api.log
|
||||||
import core.game.bots.AIRepository
|
import core.game.bots.AIRepository
|
||||||
import core.game.bots.CombatBotAssembler
|
import core.game.bots.CombatBotAssembler
|
||||||
import core.game.bots.Script
|
import core.game.bots.Script
|
||||||
import core.game.interaction.IntType
|
import core.game.interaction.IntType
|
||||||
import core.game.interaction.InteractionListeners
|
import core.game.interaction.InteractionListeners
|
||||||
|
import core.tools.Log
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileReader
|
import java.io.FileReader
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bot script for Adventurers who explore the world!
|
* A bot script for Adventurers who explore the world!
|
||||||
* @param counter used in the bots random idling function.
|
* @param counter used in the bots random idling function.
|
||||||
|
|
@ -110,7 +114,7 @@ class Adventurer(val style: CombatStyle): Script() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun otherPlayersNearby(): Boolean {
|
private fun otherPlayersNearby(): Boolean {
|
||||||
val localPlayers = RegionManager.getLocalPlayers(bot.location)
|
val localPlayers = RegionManager.getLocalPlayers(bot)
|
||||||
val otherPlayers = localPlayers.filter { it.name != bot.name }
|
val otherPlayers = localPlayers.filter { it.name != bot.name }
|
||||||
return otherPlayers.isNotEmpty()
|
return otherPlayers.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
@ -499,7 +503,7 @@ class Adventurer(val style: CombatStyle): Script() {
|
||||||
dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand()
|
dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand()
|
||||||
}
|
}
|
||||||
|
|
||||||
val localPlayers = RegionManager.getLocalPlayers(bot.location)
|
var localPlayers = RegionManager.getLocalPlayers(bot)
|
||||||
if (localPlayers.isNotEmpty()) {
|
if (localPlayers.isNotEmpty()) {
|
||||||
val localPlayer = localPlayers
|
val localPlayer = localPlayers
|
||||||
.filter { it.name != bot.name }
|
.filter { it.name != bot.name }
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class CannonballSmelter : Script() {
|
||||||
} else if(!coalMine.insideBorder(bot)){
|
} else if(!coalMine.insideBorder(bot)){
|
||||||
scriptAPI.walkTo(coalMine.randomLoc)
|
scriptAPI.walkTo(coalMine.randomLoc)
|
||||||
} else {
|
} else {
|
||||||
val rock = scriptAPI.getNearestObjectByPredicate { node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node.id)?.reward == Items.COAL_453 }
|
val rock = scriptAPI.getNearestObjectByPredicate({node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node?.id!!).reward == Items.COAL_453 })
|
||||||
if(rock != null) {
|
if(rock != null) {
|
||||||
scriptAPI.interact(bot, rock, "mine")
|
scriptAPI.interact(bot, rock, "mine")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -75,7 +75,7 @@ class CannonballSmelter : Script() {
|
||||||
var loc = ironMine.randomLoc
|
var loc = ironMine.randomLoc
|
||||||
scriptAPI.walkTo(loc)
|
scriptAPI.walkTo(loc)
|
||||||
} else {
|
} else {
|
||||||
val rock = scriptAPI.getNearestObjectByPredicate { node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node.id)?.reward == Items.IRON_ORE_440 }
|
val rock = scriptAPI.getNearestObjectByPredicate({node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node?.id!!).reward == Items.IRON_ORE_440 })
|
||||||
//rock?.let { InteractionListeners.run(rock.id, IntType.SCENERY,"mine",bot,rock) }
|
//rock?.let { InteractionListeners.run(rock.id, IntType.SCENERY,"mine",bot,rock) }
|
||||||
if(rock != null) {
|
if(rock != null) {
|
||||||
scriptAPI.interact(bot, rock, "mine")
|
scriptAPI.interact(bot, rock, "mine")
|
||||||
|
|
|
||||||
|
|
@ -262,12 +262,10 @@ class DoublingMoney : Script() {
|
||||||
minDist = min(minDist, loc.getDistance(bot.location))
|
minDist = min(minDist, loc.getDistance(bot.location))
|
||||||
}
|
}
|
||||||
if (minDist > 1) return 2
|
if (minDist > 1) return 2
|
||||||
val region = RegionManager.forId(bot.location.regionId)
|
RegionManager.forId(bot.location.regionId).planes[bot.location.z].players.forEach {
|
||||||
val players = region.assemblePlayerList(bot.location.z)
|
if (AIRepository.PulseRepository[it?.username?.lowercase()]?.botScript is DoublingMoney
|
||||||
for (player in players) {
|
&& it != bot
|
||||||
if (AIRepository.PulseRepository[player.username.lowercase()]?.botScript is DoublingMoney
|
&& it.location.getDistance(bot.location) <= 1) {
|
||||||
&& player != bot
|
|
||||||
&& player.location.getDistance(bot.location) <= 1) {
|
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import core.game.bots.SkillingBotAssembler
|
||||||
import core.game.bots.Script
|
import core.game.bots.Script
|
||||||
import core.game.interaction.IntType
|
import core.game.interaction.IntType
|
||||||
import core.game.interaction.InteractionListeners
|
import core.game.interaction.InteractionListeners
|
||||||
import core.game.node.entity.skill.Skills
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ManThiever : Script() {
|
class ManThiever : Script() {
|
||||||
|
|
@ -23,6 +22,6 @@ class ManThiever : Script() {
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
skills[Skills.THIEVING] = 20
|
equipment.addAll(Arrays.asList(Item(1103), Item(1139), Item(1265)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,6 @@ package content.global.dialogue;
|
||||||
|
|
||||||
import content.global.handlers.item.book.GeneralRuleBook;
|
import content.global.handlers.item.book.GeneralRuleBook;
|
||||||
import core.game.dialogue.DialoguePlugin;
|
import core.game.dialogue.DialoguePlugin;
|
||||||
import core.game.diary.DiaryLevel;
|
|
||||||
import core.game.node.entity.npc.NPC;
|
import core.game.node.entity.npc.NPC;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.node.entity.player.link.diary.DiaryType;
|
import core.game.node.entity.player.link.diary.DiaryType;
|
||||||
|
|
@ -11,10 +10,6 @@ import core.game.world.GameWorld;
|
||||||
import core.game.world.update.flag.context.Animation;
|
import core.game.world.update.flag.context.Animation;
|
||||||
import core.plugin.Initializable;
|
import core.plugin.Initializable;
|
||||||
import core.tools.RandomFunction;
|
import core.tools.RandomFunction;
|
||||||
import org.rs09.consts.NPCs;
|
|
||||||
|
|
||||||
import static content.region.misthalin.lumbridge.diary.LumbridgeAchivementDiary.Companion.BeginnerTasks.DRAYNOR_TALK_TO_TOWNCRIER_ABOUT_RULES;
|
|
||||||
import static core.api.ContentAPIKt.finishTask;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the town crier dialogue plugin.
|
* Represents the town crier dialogue plugin.
|
||||||
|
|
@ -132,8 +127,9 @@ public final class TownCrierDialogue extends DialoguePlugin {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (npc.getId() == NPCs.TOWN_CRIER_6136) {
|
// Find out about the Rules of Conduct from the Draynor<br><br>Town Crier
|
||||||
finishTask(player, DiaryType.LUMBRIDGE, DiaryLevel.BEGINNER, DRAYNOR_TALK_TO_TOWNCRIER_ABOUT_RULES);
|
if (npc.getId() == 6136) {
|
||||||
|
player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 10);
|
||||||
}
|
}
|
||||||
stage = 71;
|
stage = 71;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,267 +0,0 @@
|
||||||
package content.global.handlers.iface
|
|
||||||
|
|
||||||
import core.api.*
|
|
||||||
import core.game.global.action.EquipHandler.Companion.unequip
|
|
||||||
import org.rs09.consts.*
|
|
||||||
import core.game.interaction.InterfaceListener
|
|
||||||
import core.game.node.entity.player.Player
|
|
||||||
import core.game.node.item.Item
|
|
||||||
import core.tools.Log
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bolt Pouch Interface
|
|
||||||
* Uses 396.cs2
|
|
||||||
*/
|
|
||||||
|
|
||||||
class BoltPouchInterface: InterfaceListener {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* iface components, attributes, and varbits used to define this all
|
|
||||||
*
|
|
||||||
* The varbits 2469 and 2470 are packaged in varp 834 (size 16).
|
|
||||||
* The varbits 2471 and 2472 are packaged in varp 835 (size 16).
|
|
||||||
*/
|
|
||||||
companion object {
|
|
||||||
val REMOVE_SLOT_1 = 4 // interface button
|
|
||||||
val WIELD_SLOT_1 = 3 // interface button
|
|
||||||
val ICON_SLOT_1 = 2 // interface icon component
|
|
||||||
val TEXT_SLOT_1 = 25 // interface text component
|
|
||||||
val STORED_ID_SLOT_1 = "/save:boltpouch-slot1" // attribute, this is the stored item ID
|
|
||||||
val QTY_SLOT_1 = 2469 // varbit
|
|
||||||
|
|
||||||
val REMOVE_SLOT_2 = 8
|
|
||||||
val WIELD_SLOT_2 = 7
|
|
||||||
val ICON_SLOT_2 = 6
|
|
||||||
val TEXT_SLOT_2 = 26
|
|
||||||
val STORED_ID_SLOT_2 = "/save:boltpouch-slot2"
|
|
||||||
val QTY_SLOT_2 = 2470
|
|
||||||
|
|
||||||
val REMOVE_SLOT_3 = 12
|
|
||||||
val WIELD_SLOT_3 = 11
|
|
||||||
val ICON_SLOT_3 = 10
|
|
||||||
val TEXT_SLOT_3 = 27
|
|
||||||
val STORED_ID_SLOT_3 = "/save:boltpouch-slot3"
|
|
||||||
val QTY_SLOT_3 = 2471
|
|
||||||
|
|
||||||
val REMOVE_SLOT_4 = 16
|
|
||||||
val WIELD_SLOT_4 = 15
|
|
||||||
val ICON_SLOT_4 = 14
|
|
||||||
val TEXT_SLOT_4 = 28
|
|
||||||
val STORED_ID_SLOT_4 = "/save:boltpouch-slot4"
|
|
||||||
val QTY_SLOT_4 = 2472
|
|
||||||
|
|
||||||
val UNWIELD_EQUIP_SLOT = 19
|
|
||||||
val ICON_EQUIP_SLOT = 18
|
|
||||||
val TEXT_EQUIP_SLOT = 29
|
|
||||||
val QTY_EQUIP_SLOT = 24
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface interactions
|
|
||||||
*/
|
|
||||||
override fun defineInterfaceListeners() {
|
|
||||||
onOpen(Components.XBOWS_POUCH_433) { player, _ ->
|
|
||||||
updateBolts(player)
|
|
||||||
return@onOpen true
|
|
||||||
}
|
|
||||||
|
|
||||||
on(Components.XBOWS_POUCH_433) { player, _, _, buttonID, _, _ ->
|
|
||||||
when(buttonID) {
|
|
||||||
REMOVE_SLOT_1 -> removeBolts(player, STORED_ID_SLOT_1, QTY_SLOT_1)
|
|
||||||
REMOVE_SLOT_2 -> removeBolts(player, STORED_ID_SLOT_2, QTY_SLOT_2)
|
|
||||||
REMOVE_SLOT_3 -> removeBolts(player, STORED_ID_SLOT_3, QTY_SLOT_3)
|
|
||||||
REMOVE_SLOT_4 -> removeBolts(player, STORED_ID_SLOT_4, QTY_SLOT_4)
|
|
||||||
WIELD_SLOT_1 -> wieldBolts(player, STORED_ID_SLOT_1, QTY_SLOT_1)
|
|
||||||
WIELD_SLOT_2 -> wieldBolts(player, STORED_ID_SLOT_2, QTY_SLOT_2)
|
|
||||||
WIELD_SLOT_3 -> wieldBolts(player, STORED_ID_SLOT_3, QTY_SLOT_3)
|
|
||||||
WIELD_SLOT_4 -> wieldBolts(player, STORED_ID_SLOT_4, QTY_SLOT_4)
|
|
||||||
UNWIELD_EQUIP_SLOT -> unwieldBolts(player)
|
|
||||||
}
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper Functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
// removes the bolts from the pouch by changing the stored ID to 0 and setting the qty varbit to 0
|
|
||||||
fun removeBolts(player: Player, boltSlotId: String, boltSlotQty: Int) {
|
|
||||||
val boltId = getAttribute(player, boltSlotId, -1)
|
|
||||||
val boltQty = getVarbit(player, boltSlotQty)
|
|
||||||
|
|
||||||
// error check in case arios fucks up my varbits
|
|
||||||
if (boltId == -1 && boltQty != 0) {
|
|
||||||
// log error
|
|
||||||
log(this::class.java, Log.ERR, "Invalid bolt ID '$boltSlotId' for ${player.name}.")
|
|
||||||
sendMessage(player, "ERROR: Invalid bolt ID. Please report this.")
|
|
||||||
|
|
||||||
// reset slot values
|
|
||||||
setVarbit(player, boltSlotQty, 0, true)
|
|
||||||
removeAttribute(player, boltSlotId)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (boltQty == 0) {
|
|
||||||
sendMessage(player, "There's nothing to remove from that slot.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val slot = when(boltSlotQty) {
|
|
||||||
QTY_SLOT_1 -> "first"
|
|
||||||
QTY_SLOT_2 -> "second"
|
|
||||||
QTY_SLOT_3 -> "third"
|
|
||||||
else -> "fourth"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addItem(player, boltId, boltQty)) {
|
|
||||||
setVarbit(player, boltSlotQty, 0, true)
|
|
||||||
removeAttribute(player, boltSlotId)
|
|
||||||
sendMessage(player, "You remove all the bolts from the $slot slot of your bolt pouch.")
|
|
||||||
} else {
|
|
||||||
sendMessage(player, "You don't have enough space in your inventory to do that.")
|
|
||||||
}
|
|
||||||
|
|
||||||
updateBolts(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
// wields the bolts
|
|
||||||
fun wieldBolts(player: Player, boltSlotId: String, boltSlotQty: Int) {
|
|
||||||
// any equipped ammo
|
|
||||||
val ammo = getItemFromEquipment(player, EquipmentSlot.AMMO)
|
|
||||||
val ammoId = ammo?.id ?: -1
|
|
||||||
|
|
||||||
// bolts to equip
|
|
||||||
val boltId = getAttribute(player, boltSlotId, -1)
|
|
||||||
val boltQty = getVarbit(player, boltSlotQty)
|
|
||||||
val bolt = Item(boltId, boltQty)
|
|
||||||
|
|
||||||
// error check in case arios fucks up my varbits
|
|
||||||
if (boltId == -1 && boltQty != 0) {
|
|
||||||
// log error
|
|
||||||
log(this::class.java, Log.ERR, "Invalid bolt ID '$boltSlotId' for ${player.name}.")
|
|
||||||
sendMessage(player, "ERROR: Invalid bolt ID. Please report this.")
|
|
||||||
|
|
||||||
// reset slot values
|
|
||||||
setVarbit(player, boltSlotQty, 0, true)
|
|
||||||
removeAttribute(player, boltSlotId)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// pouch slot is empty
|
|
||||||
if (boltQty == 0) {
|
|
||||||
sendMessage(player, "There's nothing in that slot to wield.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// check requirements
|
|
||||||
if (!bolt.definition.hasRequirement(player, true, true)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// same bolt type already equipped, add to stack and return
|
|
||||||
if (ammoId == boltId) {
|
|
||||||
val newQty = (ammo!!.amount + boltQty).coerceAtMost(Int.MAX_VALUE)
|
|
||||||
replaceSlot(player, EquipmentSlot.AMMO.ordinal, Item(boltId, newQty), container=Container.EQUIPMENT)
|
|
||||||
setVarbit(player, boltSlotQty, 0, true)
|
|
||||||
removeAttribute(player, boltSlotId)
|
|
||||||
sendMessage(player, "You add the bolts to your equipped stack.")
|
|
||||||
updateBolts(player)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// different bolt type, unequip existing first
|
|
||||||
if (ammoId != -1) {
|
|
||||||
if (freeSlots(player) < 1) {
|
|
||||||
sendMessage(player, "You don't have enough space in your inventory to do that.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
unequip(player, EquipmentSlot.AMMO.ordinal, ammoId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// equip new bolts
|
|
||||||
if (player.equipment.add(Item(boltId, boltQty), true, EquipmentSlot.AMMO.ordinal)) {
|
|
||||||
setVarbit(player, boltSlotQty, 0, true)
|
|
||||||
removeAttribute(player, boltSlotId)
|
|
||||||
sendMessage(player, "You wield some bolts from your bolt pouch.")
|
|
||||||
}
|
|
||||||
|
|
||||||
updateBolts(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
// unwields the bolts
|
|
||||||
fun unwieldBolts(player: Player) {
|
|
||||||
val ammo = getItemFromEquipment(player, EquipmentSlot.AMMO)?.id ?: -1
|
|
||||||
|
|
||||||
if (ammo == -1) {
|
|
||||||
sendMessage(player, "You're not wielding anything.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
unequip(player, EquipmentSlot.AMMO.ordinal, ammo)
|
|
||||||
updateBolts(player)
|
|
||||||
}
|
|
||||||
|
|
||||||
// updates the bolt interface. Uses the stored ID (attribute) or equipped ID to get the icon and text needed for each slot. qty is updated automatically with 396.cs2 and the varbits
|
|
||||||
fun updateBolts(player: Player) {
|
|
||||||
|
|
||||||
// the equipment slot
|
|
||||||
val ammo = getItemFromEquipment(player, EquipmentSlot.AMMO)
|
|
||||||
val ammoQty = amountInEquipment(player, ammo?.id ?: 0)
|
|
||||||
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_EQUIP_SLOT, ammo?.id ?: -1, 90)
|
|
||||||
setInterfaceText(player, ammo?.name ?: "Nothing", Components.XBOWS_POUCH_433, TEXT_EQUIP_SLOT)
|
|
||||||
if (ammoQty == 0) {
|
|
||||||
// RED from 396.cs2: Color(255, 0, 51)
|
|
||||||
setInterfaceText(player, "<col=FF0033>0</col>", Components.XBOWS_POUCH_433, QTY_EQUIP_SLOT)
|
|
||||||
} else {
|
|
||||||
// GREEN from 396.cs2: Color(0, 192, 0)
|
|
||||||
setInterfaceText(player, "<col=00C000>$ammoQty</col>", Components.XBOWS_POUCH_433, QTY_EQUIP_SLOT)
|
|
||||||
}
|
|
||||||
|
|
||||||
// the pouch slots
|
|
||||||
|
|
||||||
// slot 1
|
|
||||||
val slot1 = Item(getAttribute(player, STORED_ID_SLOT_1, 0))
|
|
||||||
if (slot1.id == 0) {
|
|
||||||
setInterfaceText(player, "Nothing", Components.XBOWS_POUCH_433, TEXT_SLOT_1)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_1, -1)
|
|
||||||
} else {
|
|
||||||
setInterfaceText(player, slot1.name, Components.XBOWS_POUCH_433, TEXT_SLOT_1)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_1, slot1.id, 90)
|
|
||||||
}
|
|
||||||
|
|
||||||
// slot 2
|
|
||||||
val slot2 = Item(getAttribute(player, STORED_ID_SLOT_2, 0)).definition
|
|
||||||
if (slot2.id == 0) {
|
|
||||||
setInterfaceText(player, "Nothing", Components.XBOWS_POUCH_433, TEXT_SLOT_2)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_2, -1)
|
|
||||||
} else {
|
|
||||||
setInterfaceText(player, slot2.name, Components.XBOWS_POUCH_433, TEXT_SLOT_2)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_2, slot2.id, 90)
|
|
||||||
}
|
|
||||||
|
|
||||||
// slot 3
|
|
||||||
val slot3 = Item(getAttribute(player, STORED_ID_SLOT_3, 0)).definition
|
|
||||||
if (slot3.id == 0) {
|
|
||||||
setInterfaceText(player, "Nothing", Components.XBOWS_POUCH_433, TEXT_SLOT_3)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_3, -1)
|
|
||||||
} else {
|
|
||||||
setInterfaceText(player, slot3.name, Components.XBOWS_POUCH_433, TEXT_SLOT_3)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_3, slot3.id, 90)
|
|
||||||
}
|
|
||||||
|
|
||||||
// slot 4
|
|
||||||
val slot4 = Item(getAttribute(player, STORED_ID_SLOT_4, 0)).definition
|
|
||||||
if (slot4.id == 0) {
|
|
||||||
setInterfaceText(player, "Nothing", Components.XBOWS_POUCH_433, TEXT_SLOT_4)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_4, -1)
|
|
||||||
} else {
|
|
||||||
setInterfaceText(player, slot4.name, Components.XBOWS_POUCH_433, TEXT_SLOT_4)
|
|
||||||
sendItemOnInterface(player, Components.XBOWS_POUCH_433, ICON_SLOT_4, slot4.id, 90)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,7 +6,6 @@ import core.game.component.ComponentDefinition
|
||||||
import core.game.component.ComponentPlugin
|
import core.game.component.ComponentPlugin
|
||||||
import core.game.container.access.InterfaceContainer
|
import core.game.container.access.InterfaceContainer
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
import core.game.node.entity.player.link.diary.DiaryType
|
|
||||||
import core.game.node.item.Item
|
import core.game.node.item.Item
|
||||||
import core.plugin.Initializable
|
import core.plugin.Initializable
|
||||||
import core.plugin.Plugin
|
import core.plugin.Plugin
|
||||||
|
|
@ -166,10 +165,6 @@ class FurClothingInterface : ComponentPlugin(){
|
||||||
if (removeItem(player, requiredFur, Container.INVENTORY) &&
|
if (removeItem(player, requiredFur, Container.INVENTORY) &&
|
||||||
removeItem(player, coins, Container.INVENTORY)) {
|
removeItem(player, coins, Container.INVENTORY)) {
|
||||||
addItem(player, clothing.product.id, amount)
|
addItem(player, clothing.product.id, amount)
|
||||||
|
|
||||||
if (clothing == FUR_CLOTHING.DASH_CAPE) {
|
|
||||||
player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 2)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package content.global.handlers.iface;
|
||||||
|
|
||||||
|
import static core.api.ContentAPIKt.*;
|
||||||
|
import core.game.component.Component;
|
||||||
|
import core.game.component.ComponentDefinition;
|
||||||
|
import core.game.component.ComponentPlugin;
|
||||||
|
import content.global.travel.glider.GliderPulse;
|
||||||
|
import content.global.travel.glider.Gliders;
|
||||||
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.plugin.Initializable;
|
||||||
|
import core.plugin.Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the glider interface component.
|
||||||
|
* @author Emperor
|
||||||
|
* @author 'Vexia
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Initializable
|
||||||
|
public final class GliderInterface extends ComponentPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
|
ComponentDefinition.put(138, this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||||
|
final Gliders glider = Gliders.forId(button);
|
||||||
|
if (glider == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
submitWorldPulse(new GliderPulse(1, player, glider));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package content.global.handlers.iface
|
|
||||||
|
|
||||||
import core.api.submitWorldPulse
|
|
||||||
import content.global.travel.glider.GliderPulse
|
|
||||||
import content.global.travel.glider.Gliders
|
|
||||||
import core.game.interaction.InterfaceListener
|
|
||||||
import org.rs09.consts.Components
|
|
||||||
|
|
||||||
class GliderInterface : InterfaceListener {
|
|
||||||
override fun defineInterfaceListeners() {
|
|
||||||
on(Components.GLIDERMAP_138) { player, _, _, button, _, _ ->
|
|
||||||
val glider = Gliders.forId(button) ?: return@on true
|
|
||||||
submitWorldPulse(GliderPulse(1, player, glider))
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +1,17 @@
|
||||||
package content.global.handlers.iface
|
package content.global.handlers.iface
|
||||||
|
|
||||||
import content.data.Quests
|
|
||||||
import content.region.kandarin.yanille.quest.thehandinthesand.dialogue.BertNPCContactDialogueFile
|
|
||||||
import core.api.isQuestComplete
|
|
||||||
import core.api.removeAttribute
|
|
||||||
import core.game.node.entity.npc.NPC
|
import core.game.node.entity.npc.NPC
|
||||||
import core.game.world.map.Location
|
import core.game.world.map.Location
|
||||||
|
import core.tools.RandomFunction
|
||||||
import org.rs09.consts.NPCs
|
import org.rs09.consts.NPCs
|
||||||
import core.game.dialogue.DialogueFile
|
import core.game.dialogue.DialogueFile
|
||||||
import core.game.interaction.InterfaceListener
|
import core.game.interaction.InterfaceListener
|
||||||
import core.game.node.entity.player.Player
|
|
||||||
|
|
||||||
class NPCContactInterface : InterfaceListener {
|
class NPCContactInterface : InterfaceListener {
|
||||||
val contactNPCs = arrayOf(
|
val contactNPCs = arrayOf(NPCs.HONEST_JIMMY_4362, NPCs.BERT_3108, NPCs.ADVISOR_GHRIM_1375, NPCs.TURAEL_8273, NPCs.LANTHUS_1526, NPCs.SUMONA_7780, NPCs.MAZCHNA_8274, NPCs.DURADEL_8275, NPCs.VANNAKA_1597, NPCs.DARK_MAGE_2262, NPCs.CHAELDAR_1598, NPCs.CYRISUS_432, NPCs.LARRY_5424)
|
||||||
NPCs.HONEST_JIMMY_4362,
|
|
||||||
NPCs.BERT_3108,
|
|
||||||
NPCs.ADVISOR_GHRIM_1375,
|
|
||||||
NPCs.TURAEL_8273,
|
|
||||||
NPCs.LANTHUS_1526,
|
|
||||||
NPCs.SUMONA_7780,
|
|
||||||
NPCs.MAZCHNA_8274,
|
|
||||||
NPCs.DURADEL_8275,
|
|
||||||
NPCs.VANNAKA_1597,
|
|
||||||
NPCs.MURPHY_464,
|
|
||||||
NPCs.CHAELDAR_1598,
|
|
||||||
NPCs.CYRISUS_432,
|
|
||||||
NPCs.LARRY_5424
|
|
||||||
)
|
|
||||||
val DialogueFiles = arrayOf<DialogueFile?>(
|
val DialogueFiles = arrayOf<DialogueFile?>(
|
||||||
/*TODO("Honest Jimmy"),
|
/*TODO("Honest Jimmy"),
|
||||||
|
TODO("Bert"),
|
||||||
TODO("ADVISOR GHRIM"),
|
TODO("ADVISOR GHRIM"),
|
||||||
TODO("Turael"),
|
TODO("Turael"),
|
||||||
TODO("LANTHUS"),
|
TODO("LANTHUS"),
|
||||||
|
|
@ -41,51 +24,20 @@ class NPCContactInterface : InterfaceListener {
|
||||||
TODO("Cyrisus"),
|
TODO("Cyrisus"),
|
||||||
TODO("Larry")*/
|
TODO("Larry")*/
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun canContact(player: Player, index: Int): Boolean {
|
|
||||||
return when (contactNPCs[index]) {
|
|
||||||
// Hidden until their required content is implemented.
|
|
||||||
NPCs.HONEST_JIMMY_4362, // Trouble Brewing
|
|
||||||
NPCs.ADVISOR_GHRIM_1375, // Managing Miscellania
|
|
||||||
NPCs.LANTHUS_1526, // Castle Wars
|
|
||||||
NPCs.SUMONA_7780, // Smoking Kills
|
|
||||||
NPCs.MURPHY_464, // Hook up after !2361 is merged.
|
|
||||||
NPCs.CYRISUS_432 -> false // Dream Mentor
|
|
||||||
|
|
||||||
// Add NPC Contact unlock checks here.
|
|
||||||
NPCs.BERT_3108 -> BertNPCContactDialogueFile.canContact(player)
|
|
||||||
NPCs.CHAELDAR_1598 -> isQuestComplete(player, Quests.LOST_CITY)
|
|
||||||
|
|
||||||
// TODO: Gate Larry after Penguin Hide and Seek intro dialogue is implemented.
|
|
||||||
NPCs.LARRY_5424 -> true
|
|
||||||
|
|
||||||
else -> true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getContactDialogue(index: Int): DialogueFile? {
|
|
||||||
return when (contactNPCs[index]) {
|
|
||||||
// Add custom NPC Contact dialogue files here.
|
|
||||||
NPCs.BERT_3108 -> BertNPCContactDialogueFile()
|
|
||||||
else -> DialogueFiles.getOrNull(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val INTER = 429
|
val INTER = 429
|
||||||
override fun defineInterfaceListeners() {
|
override fun defineInterfaceListeners() {
|
||||||
|
|
||||||
//Remove a bunch of the buttons/heads so that people don't
|
//Remove a bunch of the buttons/heads so that people don't
|
||||||
//waste runes on spells that aren't implemented
|
//waste runes on spells that aren't implemented
|
||||||
//TODO: Re-enable NPCs as their respective content gets added
|
//TODO: Re-enable NPCs as their respective content gets added
|
||||||
onOpen(INTER){player, _ ->
|
onOpen(INTER){player, component ->
|
||||||
//Honest Jimmy: Trouble Brewing
|
//Honest Jimmy: Trouble Brewing
|
||||||
player.packetDispatch.sendInterfaceConfig(429,10,true)
|
player.packetDispatch.sendInterfaceConfig(429,10,true)
|
||||||
player.packetDispatch.sendInterfaceConfig(429,38,true)
|
player.packetDispatch.sendInterfaceConfig(429,38,true)
|
||||||
|
|
||||||
//Bert the Sandman: Hand in the Sand quest
|
//Bert the Sandman: Hand in the Sand quest
|
||||||
val showBert = BertNPCContactDialogueFile.canContact(player)
|
player.packetDispatch.sendInterfaceConfig(429,11,true)
|
||||||
player.packetDispatch.sendInterfaceConfig(429,11, !showBert)
|
player.packetDispatch.sendInterfaceConfig(429,39,true)
|
||||||
player.packetDispatch.sendInterfaceConfig(429,39, !showBert)
|
|
||||||
|
|
||||||
//Advisor Ghrim: Kingdoms of Miscellania
|
//Advisor Ghrim: Kingdoms of Miscellania
|
||||||
player.packetDispatch.sendInterfaceConfig(429,12,true)
|
player.packetDispatch.sendInterfaceConfig(429,12,true)
|
||||||
|
|
@ -99,29 +51,15 @@ class NPCContactInterface : InterfaceListener {
|
||||||
player.packetDispatch.sendInterfaceConfig(429,27,true)
|
player.packetDispatch.sendInterfaceConfig(429,27,true)
|
||||||
player.packetDispatch.sendInterfaceConfig(429,42,true)
|
player.packetDispatch.sendInterfaceConfig(429,42,true)
|
||||||
|
|
||||||
// Murphy: Fishing Trawler
|
// Replace Murphy's icon with the Abyss's Dark Mage
|
||||||
player.packetDispatch.sendInterfaceConfig(429, 30, true)
|
player.packetDispatch.sendNpcOnInterface(NPCs.DARK_MAGE_2262, 429, 30)
|
||||||
player.packetDispatch.sendInterfaceConfig(429, 47, true)
|
player.packetDispatch.sendString("Dark mage", 429, 47)
|
||||||
|
|
||||||
// Chaeldar has a duplicate/stale interface child 31
|
|
||||||
val showChaeldar = canContact(player, 10)
|
|
||||||
player.packetDispatch.sendInterfaceConfig(429, 29, !showChaeldar)
|
|
||||||
player.packetDispatch.sendInterfaceConfig(429, 48, !showChaeldar)
|
|
||||||
|
|
||||||
val showCyrisus = canContact(player, 11)
|
|
||||||
player.packetDispatch.sendInterfaceConfig(429, 32, !showCyrisus)
|
|
||||||
player.packetDispatch.sendInterfaceConfig(429, 33, !showCyrisus)
|
|
||||||
|
|
||||||
return@onOpen true
|
return@onOpen true
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose(INTER) { player, _ ->
|
|
||||||
removeAttribute(player, "contact-caller")
|
|
||||||
return@onClose true
|
|
||||||
}
|
|
||||||
|
|
||||||
on(INTER){player, _, _, buttonID, _, _ ->
|
on(INTER){player, _, _, buttonID, _, _ ->
|
||||||
val index = when(buttonID) {
|
var index = when(buttonID){
|
||||||
10,38 -> 0
|
10,38 -> 0
|
||||||
11,39 -> 1
|
11,39 -> 1
|
||||||
12,40 -> 2
|
12,40 -> 2
|
||||||
|
|
@ -137,30 +75,15 @@ class NPCContactInterface : InterfaceListener {
|
||||||
34,49 -> 12
|
34,49 -> 12
|
||||||
else -> -1
|
else -> -1
|
||||||
}
|
}
|
||||||
if (index == -1) {
|
if(index == -1) index = RandomFunction.random(contactNPCs.size)
|
||||||
// TODO: "Random will contact any of 26 other NPCs around RuneScape, and appears not to be "random" in that it cycles through 26 different NPCs.
|
val dialogueFile = DialogueFiles.getOrNull(index)
|
||||||
// The spell may start going in order randomly or just jump around. Using Random requires completion of Dream Mentor."
|
player.getAttribute<() -> Unit>("contact-caller")?.invoke()
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!canContact(player, index)) {
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
|
|
||||||
val npcId = contactNPCs[index]
|
|
||||||
val dialogueFile = getContactDialogue(index)
|
|
||||||
val contactCaller = player.getAttribute<() -> Unit>("contact-caller")
|
|
||||||
|
|
||||||
removeAttribute(player, "contact-caller")
|
|
||||||
contactCaller?.invoke()
|
|
||||||
player.interfaceManager.close()
|
player.interfaceManager.close()
|
||||||
|
if(dialogueFile != null){
|
||||||
if(dialogueFile != null) {
|
player.dialogueInterpreter.open(dialogueFile, NPC(contactNPCs[index]))
|
||||||
player.dialogueInterpreter.open(dialogueFile, NPC(npcId))
|
|
||||||
} else {
|
} else {
|
||||||
player.dialogueInterpreter.open(npcId, NPC(npcId, Location(0, 0)))
|
player.dialogueInterpreter.open(contactNPCs[index], NPC(contactNPCs[index], Location(0, 0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return@on true
|
return@on true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
package content.global.handlers.iface;
|
||||||
|
|
||||||
|
import static core.api.ContentAPIKt.*;
|
||||||
|
import core.game.component.Component;
|
||||||
|
import core.game.component.ComponentDefinition;
|
||||||
|
import core.game.component.ComponentPlugin;
|
||||||
|
import content.global.skill.crafting.TanningProduct;
|
||||||
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.node.item.Item;
|
||||||
|
import core.plugin.Initializable;
|
||||||
|
import core.plugin.Plugin;
|
||||||
|
import kotlin.Unit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vexia
|
||||||
|
* @version 1.2
|
||||||
|
*/
|
||||||
|
@Initializable
|
||||||
|
public class TanningInterface extends ComponentPlugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used to create a new instance.
|
||||||
|
* @param arg
|
||||||
|
* @return
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
|
ComponentDefinition.put(324, this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||||
|
TanningProduct def = null;
|
||||||
|
switch (button) {
|
||||||
|
case 1:
|
||||||
|
def = TanningProduct.SOFT_LEATHER;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
def = TanningProduct.HARD_LEATHER;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
def = TanningProduct.SNAKESKIN;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
def = TanningProduct.SNAKESKIN2;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
def = TanningProduct.GREEN_DHIDE;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
def = TanningProduct.BLUEDHIDE;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
def = TanningProduct.REDDHIDE;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
def = TanningProduct.BLACKDHIDE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (def == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int amount = 0;
|
||||||
|
final TanningProduct deff = def;
|
||||||
|
switch (opcode){
|
||||||
|
case 155:
|
||||||
|
amount = 1;
|
||||||
|
break;
|
||||||
|
case 196:
|
||||||
|
amount = 5;
|
||||||
|
break;
|
||||||
|
case 124:
|
||||||
|
amount = 10;
|
||||||
|
case 199:
|
||||||
|
sendInputDialogue(player, true, "Enter the amount:", (value) -> {
|
||||||
|
TanningProduct.tan(player, (int) value, deff);
|
||||||
|
return Unit.INSTANCE;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 234:
|
||||||
|
amount = player.getInventory().getAmount(new Item(def.getItem(), 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TanningProduct.tan(player, amount, def);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package content.global.handlers.iface
|
|
||||||
|
|
||||||
import content.global.skill.crafting.TanningProduct
|
|
||||||
import core.api.amountInInventory
|
|
||||||
import core.api.sendInputDialogue
|
|
||||||
import core.game.interaction.InterfaceListener
|
|
||||||
|
|
||||||
class TanningInterface : InterfaceListener {
|
|
||||||
override fun defineInterfaceListeners() {
|
|
||||||
on(324) { player, _, opcode, buttonID, _, _ ->
|
|
||||||
val product = TanningProduct.forId(buttonID)
|
|
||||||
|
|
||||||
when (opcode) {
|
|
||||||
155 -> TanningProduct.tan(player, 1, product)
|
|
||||||
196 -> TanningProduct.tan(player, 5, product)
|
|
||||||
124 -> TanningProduct.tan(player, 10, product)
|
|
||||||
199 -> sendInputDialogue(player, true, "Enter the amount:") { value ->
|
|
||||||
TanningProduct.tan(player, value as Int, product)
|
|
||||||
}
|
|
||||||
234 -> TanningProduct.tan(player, amountInInventory(player, product.item), product)
|
|
||||||
}
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -127,7 +127,7 @@ private const val F_FLARES = 72
|
||||||
private const val F_PLAIN_TROUSERS = 70
|
private const val F_PLAIN_TROUSERS = 70
|
||||||
private const val F_SHORTS = 77
|
private const val F_SHORTS = 77
|
||||||
|
|
||||||
private val femaleLegIDs = intArrayOf(F_FINE_SKIRT, F_FRILLED_SKIRT, F_LAYERED_SKIRT, F_LONG_NARROW_SKIRT, F_RAGGED_SKIRT, F_TATTERED_SKIRT, F_SHORT_SKIRT, F_SASHED_SKIRT, F_FITTED_SKIRT, F_TORN_TROUSERS, F_LONG_SKIRT, F_TURN_UPS, F_FLARES, F_PLAIN_TROUSERS, F_SHORTS)
|
private val femaleLegIDs = intArrayOf(F_FINE_SKIRT, F_FRILLED_SKIRT, F_LAYERED_SKIRT, F_LONG_NARROW_SKIRT, F_RAGGED_SKIRT, F_TATTERED_SKIRT, F_SHORT_SKIRT, F_SASHED_SKIRT, F_FITTED_SKIRT, F_TORN_TROUSERS, F_LONG_SKIRT, F_TURN_UPS, F_FLARES, F_FLARES, F_PLAIN_TROUSERS, F_SHORTS)
|
||||||
|
|
||||||
private val COINS = Item(995,1000)
|
private val COINS = Item(995,1000)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package content.global.handlers.iface;
|
||||||
|
|
||||||
|
import core.game.component.Component;
|
||||||
|
import core.game.component.ComponentDefinition;
|
||||||
|
import core.game.component.ComponentPlugin;
|
||||||
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.plugin.Initializable;
|
||||||
|
import core.plugin.Plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the world map interface.
|
||||||
|
* @author Emperor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Initializable
|
||||||
|
public final class WorldMapInterface extends ComponentPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
|
ComponentDefinition.forId(755).setPlugin(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Thanks snicker!
|
||||||
|
@Override
|
||||||
|
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||||
|
switch (button) {
|
||||||
|
case 3:
|
||||||
|
player.getInterfaceManager().openWindowsPane(new Component(player.getInterfaceManager().isResizable() ? 746 : 548), 2);
|
||||||
|
player.getPacketDispatch().sendRunScript(1187, "ii", 0, 0);
|
||||||
|
player.updateSceneGraph(true);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
//log(this.getClass(), Log.ERR, "World map: buttonid: " + button + ", opcode: " + opcode + ", slot: " + slot);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package content.global.handlers.iface
|
|
||||||
|
|
||||||
import core.game.component.Component
|
|
||||||
import core.game.interaction.InterfaceListener
|
|
||||||
import org.rs09.consts.Components
|
|
||||||
|
|
||||||
class WorldMapInterface : InterfaceListener {
|
|
||||||
override fun defineInterfaceListeners() {
|
|
||||||
on(Components.WORLDMAP_755) { player, _, _, button, _, _ ->
|
|
||||||
if (button == 3) {
|
|
||||||
val paneId = if (player.interfaceManager.isResizable) {
|
|
||||||
Components.TOPLEVEL_FULLSCREEN_746
|
|
||||||
} else {
|
|
||||||
Components.TOPLEVEL_548
|
|
||||||
}
|
|
||||||
player.interfaceManager.openWindowsPane(Component(paneId), 2)
|
|
||||||
player.packetDispatch.sendRunScript(1187, "ii", 0, 0)
|
|
||||||
player.updateSceneGraph(true)
|
|
||||||
}
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
package content.global.handlers.item
|
|
||||||
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.QTY_SLOT_1
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.QTY_SLOT_2
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.QTY_SLOT_3
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.QTY_SLOT_4
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.STORED_ID_SLOT_1
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.STORED_ID_SLOT_2
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.STORED_ID_SLOT_3
|
|
||||||
import content.global.handlers.iface.BoltPouchInterface.Companion.STORED_ID_SLOT_4
|
|
||||||
import core.api.*
|
|
||||||
import core.game.interaction.IntType
|
|
||||||
import core.game.interaction.InteractionListener
|
|
||||||
import core.game.node.entity.player.Player
|
|
||||||
import core.game.node.item.Item
|
|
||||||
import org.rs09.consts.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener for the bolt pouch.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class BoltPouchListener: InteractionListener {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val BOLT_POUCH_ALLOWED_ITEMS = intArrayOf(
|
|
||||||
// metal bolts and their poisoned variants
|
|
||||||
Items.BRONZE_BOLTS_877, Items.BRONZE_BOLTSP_878, Items.BRONZE_BOLTSP_PLUS_6061, Items.BRONZE_BOLTSP_PLUS_PLUS_6062,
|
|
||||||
Items.IRON_BOLTS_9140, Items.IRON_BOLTS_P_9287, Items.IRON_BOLTSP_PLUS_9294, Items.IRON_BOLTSP_PLUS_PLUS_9301,
|
|
||||||
Items.BLURITE_BOLTS_9139, Items.BLURITE_BOLTSP_9286, Items.BLURITE_BOLTSP_PLUS_9293, Items.BLURITE_BOLTSP_PLUS_PLUS_9300,
|
|
||||||
Items.SILVER_BOLTS_9145, Items.SILVER_BOLTS_P_9292, Items.SILVER_BOLTSP_PLUS_9299, Items.SILVER_BOLTSP_PLUS_PLUS_9306,
|
|
||||||
Items.BLACK_BOLTS_13083, Items.BLACK_BOLTSP_13084, Items.BLACK_BOLTSP_PLUS_13085, Items.BLACK_BOLTSP_PLUS_PLUS_13086,
|
|
||||||
Items.STEEL_BOLTS_9141, Items.STEEL_BOLTS_P_9288, Items.STEEL_BOLTSP_PLUS_9295, Items.STEEL_BOLTSP_PLUS_PLUS_9302,
|
|
||||||
Items.MITHRIL_BOLTS_9142, Items.MITHRIL_BOLTS_P_9289, Items.MITHRIL_BOLTSP_PLUS_9296, Items.MITHRIL_BOLTSP_PLUS_PLUS_9303,
|
|
||||||
Items.ADAMANT_BOLTS_9143, Items.ADAMANT_BOLTS_P_9290, Items.ADAMANT_BOLTSP_PLUS_9297, Items.ADAMANT_BOLTSP_PLUS_PLUS_9304,
|
|
||||||
Items.RUNE_BOLTS_9144, Items.RUNITE_BOLTS_P_9291, Items.RUNITE_BOLTSP_PLUS_9298, Items.RUNITE_BOLTSP_PLUS_PLUS_9305,
|
|
||||||
|
|
||||||
// gem and enchanted gem bolts
|
|
||||||
Items.OPAL_BOLTS_879, Items.OPAL_BOLTS_E_9236,
|
|
||||||
Items.PEARL_BOLTS_880, Items.PEARL_BOLTS_E_9238,
|
|
||||||
Items.JADE_BOLTS_9335, Items.JADE_BOLTS_E_9237,
|
|
||||||
Items.TOPAZ_BOLTS_9336, Items.TOPAZ_BOLTS_E_9239,
|
|
||||||
Items.SAPPHIRE_BOLTS_9337, Items.SAPPHIRE_BOLTS_E_9240,
|
|
||||||
Items.EMERALD_BOLTS_9338, Items.EMERALD_BOLTS_E_9241,
|
|
||||||
Items.RUBY_BOLTS_9339, Items.RUBY_BOLTS_E_9242,
|
|
||||||
Items.DIAMOND_BOLTS_9340, Items.DIAMOND_BOLTS_E_9243,
|
|
||||||
Items.DRAGON_BOLTS_9341, Items.DRAGON_BOLTS_E_9244,
|
|
||||||
Items.ONYX_BOLTS_9342,Items.ONYX_BOLTS_E_9245,
|
|
||||||
|
|
||||||
// special bolts
|
|
||||||
Items.KEBBIT_BOLTS_10158, Items.LONG_KEBBIT_BOLTS_10159,
|
|
||||||
Items.BARBED_BOLTS_881,
|
|
||||||
Items.BROAD_TIPPED_BOLTS_13280,
|
|
||||||
Items.BONE_BOLTS_8882,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper function to drop the bolts
|
|
||||||
private fun dropBolts(player: Player, boltSlotId: String, boltSlotQty: Int) {
|
|
||||||
val boltId = getAttribute(player, boltSlotId, -1)
|
|
||||||
val boltQty = getVarbit(player, boltSlotQty)
|
|
||||||
|
|
||||||
if (boltQty == 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// drops bolts, changes the stored ID to 0, and sets the qty varbit to 0
|
|
||||||
produceGroundItem(player, boltId, boltQty, player.location)
|
|
||||||
setVarbit(player, boltSlotQty, 0, true)
|
|
||||||
removeAttribute(player, boltSlotId)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun defineListeners() {
|
|
||||||
// open pouch interface
|
|
||||||
on(Items.BOLT_POUCH_9433, IntType.ITEM, "open") { player, _ ->
|
|
||||||
openInterface(player, Components.XBOWS_POUCH_433)
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
|
|
||||||
// destroy pouch - drops bolts
|
|
||||||
on(Items.BOLT_POUCH_9433, IntType.ITEM, "destroy") { player, node ->
|
|
||||||
val item = node as Item
|
|
||||||
player.dialogueInterpreter.sendDestroyItem(item.id, "You can get another pouch from Hirko in Keldagrim.")
|
|
||||||
addDialogueAction(player) { _, button ->
|
|
||||||
if (button == 3) {
|
|
||||||
if (removeItem(player, item)) {
|
|
||||||
playAudio(player, Sounds.DESTROY_OBJECT_2381)
|
|
||||||
|
|
||||||
dropBolts(player, STORED_ID_SLOT_1, QTY_SLOT_1)
|
|
||||||
dropBolts(player, STORED_ID_SLOT_2, QTY_SLOT_2)
|
|
||||||
dropBolts(player, STORED_ID_SLOT_3, QTY_SLOT_3)
|
|
||||||
dropBolts(player, STORED_ID_SLOT_4, QTY_SLOT_4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
|
|
||||||
// bolts used on pouch: add to pouch
|
|
||||||
onUseWith(IntType.ITEM, Items.BOLT_POUCH_9433, *BOLT_POUCH_ALLOWED_ITEMS) { player, _, with ->
|
|
||||||
val id = with.id
|
|
||||||
val qtyUsed = amountInInventory(player, id)
|
|
||||||
|
|
||||||
// get either the first empty slot by querying the varbits, or a slot that already has the used bolts in it and at least one free space
|
|
||||||
var targetQtySlot = -1
|
|
||||||
var targetIdSlot = ""
|
|
||||||
|
|
||||||
// slot 1
|
|
||||||
if (getVarbit(player, QTY_SLOT_1) == 0 || (id == getAttribute(player, STORED_ID_SLOT_1, 0) && getVarbit(player, QTY_SLOT_1) < 255)) {
|
|
||||||
targetQtySlot = QTY_SLOT_1
|
|
||||||
targetIdSlot = STORED_ID_SLOT_1
|
|
||||||
|
|
||||||
// slot 2
|
|
||||||
} else if (getVarbit(player, QTY_SLOT_2) == 0 || (id == getAttribute(player, STORED_ID_SLOT_2, 0) && getVarbit(player, QTY_SLOT_2) < 255)) {
|
|
||||||
targetQtySlot = QTY_SLOT_2
|
|
||||||
targetIdSlot = STORED_ID_SLOT_2
|
|
||||||
|
|
||||||
// slot 3
|
|
||||||
} else if (getVarbit(player, QTY_SLOT_3) == 0 || (id == getAttribute(player, STORED_ID_SLOT_3, 0) && getVarbit(player, QTY_SLOT_3) < 255)) {
|
|
||||||
targetQtySlot = QTY_SLOT_3
|
|
||||||
targetIdSlot = STORED_ID_SLOT_3
|
|
||||||
|
|
||||||
// slot 4
|
|
||||||
} else if (getVarbit(player, QTY_SLOT_4) == 0 || (id == getAttribute(player, STORED_ID_SLOT_4, 0) && getVarbit(player, QTY_SLOT_4) < 255)) {
|
|
||||||
targetQtySlot = QTY_SLOT_4
|
|
||||||
targetIdSlot = STORED_ID_SLOT_4
|
|
||||||
}
|
|
||||||
|
|
||||||
// based on target values set earlier, add the bolts
|
|
||||||
if (targetQtySlot != -1) {
|
|
||||||
val currentQty = getVarbit(player, targetQtySlot)
|
|
||||||
val spaceLeft = 255 - currentQty
|
|
||||||
val toAdd = minOf(qtyUsed, spaceLeft)
|
|
||||||
|
|
||||||
if (removeItem(player, Item(id, toAdd))) {
|
|
||||||
setVarbit(player, targetQtySlot, toAdd + currentQty, true)
|
|
||||||
setAttribute(player, targetIdSlot, id)
|
|
||||||
sendMessage(player, "You store some bolts in your pouch.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// all slots are full
|
|
||||||
} else {
|
|
||||||
sendMessage(player, "You don't have enough space in your bolt pouch to do that.")
|
|
||||||
}
|
|
||||||
return@onUseWith true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
package content.global.handlers.item
|
package content.global.handlers.item
|
||||||
|
|
||||||
import content.global.skill.herblore.FinishedPotion
|
|
||||||
import content.global.skill.herblore.UnfinishedPotion
|
|
||||||
import core.api.*
|
import core.api.*
|
||||||
import core.cache.def.impl.ItemDefinition
|
import core.cache.def.impl.ItemDefinition
|
||||||
import core.game.interaction.IntType
|
import core.game.interaction.IntType
|
||||||
|
|
@ -82,9 +80,7 @@ class EmptyOptionListener : InteractionListener {
|
||||||
BURNT_GNOMEBOWL(Items.BURNT_GNOMEBOWL_2175, Items.GNOMEBOWL_MOULD_2166, "You empty the contents of the gnomebowl onto the floor."),
|
BURNT_GNOMEBOWL(Items.BURNT_GNOMEBOWL_2175, Items.GNOMEBOWL_MOULD_2166, "You empty the contents of the gnomebowl onto the floor."),
|
||||||
BURNT_EGG(Items.BURNT_EGG_7090, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."),
|
BURNT_EGG(Items.BURNT_EGG_7090, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."),
|
||||||
BURNT_ONION(Items.BURNT_ONION_7092, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."),
|
BURNT_ONION(Items.BURNT_ONION_7092, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."),
|
||||||
BURNT_MUSHROOM(Items.BURNT_MUSHROOM_7094, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."),
|
BURNT_MUSHROOM(Items.BURNT_MUSHROOM_7094, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.");
|
||||||
COCONUT_MILK(Items.COCONUT_MILK_5935, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401),
|
|
||||||
IMP_REPEL(Items.IMP_REPELLENT_11262, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401);
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var emptyItemMap = HashMap<Int, Int?>()
|
var emptyItemMap = HashMap<Int, Int?>()
|
||||||
|
|
@ -93,49 +89,17 @@ class EmptyOptionListener : InteractionListener {
|
||||||
var emptyItemList = ArrayList<Int>()
|
var emptyItemList = ArrayList<Int>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// add all the above manually-defined items
|
|
||||||
for (item in values()) {
|
for (item in values()) {
|
||||||
emptyItemMap.putIfAbsent(item.fullId, item.emptyId)
|
emptyItemMap.putIfAbsent(item.fullId, item.emptyId)
|
||||||
emptyMessageMap.putIfAbsent(item.fullId, item.emptyMessage)
|
emptyMessageMap.putIfAbsent(item.fullId, item.emptyMessage)
|
||||||
emptyAudioMap.putIfAbsent(item.fullId, item.audioId)
|
emptyAudioMap.putIfAbsent(item.fullId, item.audioId)
|
||||||
emptyItemList.add(item.fullId)
|
emptyItemList.add(item.fullId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add finished potion products
|
|
||||||
for (finishedPotion in FinishedPotion.values()) {
|
|
||||||
val potionId = finishedPotion.potion.id
|
|
||||||
|
|
||||||
emptyItemMap.putIfAbsent(potionId, Items.VIAL_229)
|
|
||||||
emptyMessageMap.putIfAbsent(potionId, "You empty the vial.")
|
|
||||||
emptyAudioMap.putIfAbsent(potionId, Sounds.LIQUID_2401)
|
|
||||||
|
|
||||||
if (!emptyItemList.contains(potionId)) {
|
|
||||||
emptyItemList.add(potionId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add unfinished potion products
|
|
||||||
for (unfinishedPotion in UnfinishedPotion.values()) {
|
|
||||||
val potionId = unfinishedPotion.potion.id
|
|
||||||
|
|
||||||
emptyItemMap.putIfAbsent(potionId, Items.VIAL_229)
|
|
||||||
emptyMessageMap.putIfAbsent(potionId, "You empty the vial.")
|
|
||||||
emptyAudioMap.putIfAbsent(potionId, Sounds.LIQUID_2401)
|
|
||||||
|
|
||||||
if (!emptyItemList.contains(potionId)) {
|
|
||||||
emptyItemList.add(potionId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo this legacy line loads a bunch of random shit that may or may not have empty options. It'd be better to define these all in the future in a controlled manner (e.g. this pulls items like Items.SUPER_KEBAB_4608 and Items.VOICE_OF_DOOM_POTION_11788)
|
|
||||||
// add some strings that might catch anything else
|
|
||||||
for (item in ItemDefinition.getDefinitions().values)
|
for (item in ItemDefinition.getDefinitions().values)
|
||||||
if (item.name.contains("potion") || item.name.contains("brew") || item.name.contains("poison") || item.name.lowercase(Locale.getDefault()).contains("serum") || item.name.contains("cure") || item.name.contains("mix") || item.name.contains("balm") || item.name.contains("Super ")) {
|
if (item.name.contains("potion") || item.name.contains("brew") || item.name.contains("poison") || item.name.lowercase(Locale.getDefault()).contains("serum") || item.name.contains("cure") || item.name.contains("mix") || item.name.contains("balm") || item.name.contains("Super ")) {
|
||||||
if (!emptyItemList.contains(item.id)) {
|
|
||||||
emptyItemList.add(item.id)
|
emptyItemList.add(item.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun getEmpty(id: Int): Int? {
|
fun getEmpty(id: Int): Int? {
|
||||||
return emptyItemMap[id]
|
return emptyItemMap[id]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package content.global.handlers.item
|
||||||
|
|
||||||
import content.global.skill.slayer.SlayerUtils
|
import content.global.skill.slayer.SlayerUtils
|
||||||
import core.api.*
|
import core.api.*
|
||||||
|
import content.global.skill.slayer.Tasks
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
import core.game.dialogue.DialogueFile
|
import core.game.dialogue.DialogueFile
|
||||||
import core.game.dialogue.IfTopic
|
import core.game.dialogue.IfTopic
|
||||||
|
|
@ -38,7 +39,12 @@ class EnchantedGemDialogue() : DialogueFile() {
|
||||||
if(!hasSlayerTask(player!!)) {
|
if(!hasSlayerTask(player!!)) {
|
||||||
npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "You need something new to hunt. Come and see me when you can and I'll give you a new task.").also { stage = 1 }
|
npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "You need something new to hunt. Come and see me when you can and I'll give you a new task.").also { stage = 1 }
|
||||||
} else {
|
} else {
|
||||||
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player!!))}; only ${getSlayerTaskKillsRemaining(player!!)} more to go.")
|
if(getSlayerTask(player!!) == Tasks.JAD) {
|
||||||
|
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill TzTok-Jad!")
|
||||||
|
} else {
|
||||||
|
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${SlayerUtils.pluralise(
|
||||||
|
getSlayerTaskName(player!!))}; only ${getSlayerTaskKillsRemaining(player!!)} more to go.")
|
||||||
|
}
|
||||||
setVarp(player!!, 2502, getSlayerTaskFlags(player!!) shr 4)
|
setVarp(player!!, 2502, getSlayerTaskFlags(player!!) shr 4)
|
||||||
stage = 1
|
stage = 1
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,11 +92,7 @@ class ItemQuestRequirementListener : InteractionListener {
|
||||||
|
|
||||||
private val godBooks = intArrayOf (
|
private val godBooks = intArrayOf (
|
||||||
Items.HOLY_BOOK_3840,
|
Items.HOLY_BOOK_3840,
|
||||||
Items.UNHOLY_BOOK_3842,
|
Items.UNHOLY_BOOK_3842
|
||||||
Items.BOOK_OF_BALANCE_3844,
|
|
||||||
Items.DAMAGED_BOOK_3839,
|
|
||||||
Items.DAMAGED_BOOK_3841,
|
|
||||||
Items.DAMAGED_BOOK_3843
|
|
||||||
)
|
)
|
||||||
|
|
||||||
private val pharaohScepters = (9044..9051).toIntArray()
|
private val pharaohScepters = (9044..9051).toIntArray()
|
||||||
|
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
package content.global.handlers.item
|
|
||||||
|
|
||||||
import core.api.*
|
|
||||||
import core.game.interaction.InteractionListener
|
|
||||||
import core.game.interaction.InterfaceListener
|
|
||||||
import core.game.node.entity.player.Player
|
|
||||||
import org.rs09.consts.Items
|
|
||||||
import org.rs09.consts.NPCs
|
|
||||||
import org.rs09.consts.Sounds
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles morphing with the Ring of Stone and Easter Ring.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class MorphItemListener : InteractionListener, InterfaceListener {
|
|
||||||
|
|
||||||
// the morphing items
|
|
||||||
private val morphItems = intArrayOf(Items.RING_OF_STONE_6583, Items.EASTER_RING_7927)
|
|
||||||
|
|
||||||
// the NPCs to morph into
|
|
||||||
private val easterEggs = intArrayOf(
|
|
||||||
NPCs.EGG_3689,
|
|
||||||
NPCs.EGG_3690,
|
|
||||||
NPCs.EGG_3691,
|
|
||||||
NPCs.EGG_3692,
|
|
||||||
NPCs.EGG_3693,
|
|
||||||
NPCs.EGG_3694
|
|
||||||
)
|
|
||||||
private val stone = intArrayOf(NPCs.ROCKS_2626)
|
|
||||||
|
|
||||||
// the "unmorph" interface
|
|
||||||
private val morphIface = 375
|
|
||||||
|
|
||||||
// equipping the morph items
|
|
||||||
override fun defineListeners() {
|
|
||||||
onEquip(morphItems) { player, item ->
|
|
||||||
morph(player, item.id)
|
|
||||||
return@onEquip false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the interface that appears when you morph
|
|
||||||
override fun defineInterfaceListeners() {
|
|
||||||
|
|
||||||
// hitting the 'unmorph' button
|
|
||||||
on(morphIface){ player, _, _, buttonID, _, _ ->
|
|
||||||
when(buttonID) {
|
|
||||||
3 -> closeAllInterfaces(player)
|
|
||||||
}
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
|
|
||||||
// after the interface closes
|
|
||||||
onClose(morphIface) { player, _ ->
|
|
||||||
unmorph(player)
|
|
||||||
return@onClose true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// morphs the player
|
|
||||||
private fun morph(player: Player, item: Int) {
|
|
||||||
val morphId = when (item) {
|
|
||||||
Items.RING_OF_STONE_6583 -> stone.random()
|
|
||||||
else -> easterEggs.random()
|
|
||||||
}
|
|
||||||
playAudio(player, Sounds.EASTER06_HUMAN_INTO_EGG_1520)
|
|
||||||
stopWalk(player)
|
|
||||||
closeAllInterfaces(player)
|
|
||||||
player.appearance.transformNPC(morphId)
|
|
||||||
openInterface(player, morphIface)
|
|
||||||
}
|
|
||||||
|
|
||||||
// unmorphs the player
|
|
||||||
private fun unmorph(player: Player) {
|
|
||||||
player.appearance.transformNPC(-1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
package content.global.handlers.item;
|
||||||
|
|
||||||
|
import core.cache.def.impl.ItemDefinition;
|
||||||
|
import core.game.component.CloseEvent;
|
||||||
|
import core.game.component.Component;
|
||||||
|
import core.game.component.ComponentDefinition;
|
||||||
|
import core.game.component.ComponentPlugin;
|
||||||
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.node.item.Item;
|
||||||
|
import core.game.world.GameWorld;
|
||||||
|
import core.plugin.Initializable;
|
||||||
|
import core.plugin.Plugin;
|
||||||
|
import core.plugin.ClassScanner;
|
||||||
|
import core.tools.RandomFunction;
|
||||||
|
import org.rs09.consts.Sounds;
|
||||||
|
|
||||||
|
import static core.api.ContentAPIKt.playAudio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a morph item.
|
||||||
|
* @author Vexia
|
||||||
|
*/
|
||||||
|
@Initializable
|
||||||
|
public class MorphItemPlugin implements Plugin<Object> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The easter egg ids.
|
||||||
|
*/
|
||||||
|
protected static final int[] EASTER_EGG_IDS = new int[] { 3689, 3690, 3691, 3692, 3693, 3694 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The morph component.
|
||||||
|
*/
|
||||||
|
private static final Component COMPONENT = new Component(375).setCloseEvent(new CloseEvent() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean close(Player player, Component c) {
|
||||||
|
unmorph(player);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
|
ItemDefinition.forId(7927).getHandlers().put("equipment", this);
|
||||||
|
ItemDefinition.forId(6583).getHandlers().put("equipment", this);
|
||||||
|
ClassScanner.definePlugin(new MorphInterfacePlugin());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object fireEvent(String identifier, Object... args) {
|
||||||
|
final Player player = (Player) args[0];
|
||||||
|
final Item item = (Item) args[1];
|
||||||
|
switch (identifier) {
|
||||||
|
case "equip":
|
||||||
|
morph(player, item);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Morphs the player.
|
||||||
|
* @param player the player.
|
||||||
|
* @param item the item.
|
||||||
|
*/
|
||||||
|
private void morph(Player player, Item item) {
|
||||||
|
int morphId = item.getId() == 6583 ? 2626 : EASTER_EGG_IDS[RandomFunction.random(EASTER_EGG_IDS.length)];
|
||||||
|
playAudio(player, 1520);
|
||||||
|
player.getInterfaceManager().close();
|
||||||
|
player.getAppearance().transformNPC(morphId);
|
||||||
|
player.getInterfaceManager().removeTabs(0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
|
||||||
|
player.getLocks().lockMovement(GameWorld.getTicks() + 900000000);
|
||||||
|
player.getLocks().lockInteractions(GameWorld.getTicks() + 90000000);
|
||||||
|
player.getLocks().lockTeleport(GameWorld.getTicks() + 900000000);
|
||||||
|
player.getInterfaceManager().openSingleTab(COMPONENT);
|
||||||
|
player.getAppearance().sync();
|
||||||
|
player.getWalkingQueue().reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmorphs the player.
|
||||||
|
* @param player the player.
|
||||||
|
*/
|
||||||
|
private static void unmorph(Player player) {
|
||||||
|
player.getAppearance().transformNPC(-1);
|
||||||
|
player.unlock();
|
||||||
|
player.getInterfaceManager().restoreTabs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the morph interface plugin.
|
||||||
|
* @author Vexia
|
||||||
|
*/
|
||||||
|
public class MorphInterfacePlugin extends ComponentPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
|
ComponentDefinition.forId(375).setPlugin(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||||
|
player.getInterfaceManager().closeSingleTab();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package content.global.handlers.item.equipment
|
|
||||||
|
|
||||||
import content.region.kandarin.quest.barbariantraining.BarbarianTraining
|
|
||||||
import core.api.*
|
|
||||||
import core.cache.def.impl.ItemDefinition
|
|
||||||
import core.game.interaction.InteractionListener
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents players from equipping hastas without the required barbarian training.
|
|
||||||
* @author Bishop
|
|
||||||
*/
|
|
||||||
|
|
||||||
class HastaEquipListener : InteractionListener {
|
|
||||||
override fun defineListeners() {
|
|
||||||
val hastaIds = ItemDefinition.getDefinitions().values
|
|
||||||
.filter { it.name.lowercase().contains("hasta") }
|
|
||||||
.map { it.id }
|
|
||||||
.toIntArray()
|
|
||||||
|
|
||||||
onEquip(hastaIds) { player, _ ->
|
|
||||||
if (getAttribute(player, BarbarianTraining.attributeHasta, 0) < 2) {
|
|
||||||
sendDialogue(player, "You must begin the relevant section of Otto Godblessed's barbarian training.")
|
|
||||||
return@onEquip false
|
|
||||||
}
|
|
||||||
return@onEquip true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -186,9 +186,9 @@ public final class ChainhitSpecialHandler extends RangeSwingHandler implements P
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
int distance = 5;
|
int distance = 5;
|
||||||
if (victim instanceof NPC) {
|
if (victim instanceof NPC) {
|
||||||
e.setAttribute("chain-hit_v", list = RegionManager.getLocalNPCs(e.getLocation(), distance));
|
e.setAttribute("chain-hit_v", list = RegionManager.getLocalNpcs(e, distance));
|
||||||
} else {
|
} else {
|
||||||
e.setAttribute("chain-hit_v", list = RegionManager.getLocalPlayers(e.getLocation(), distance));
|
e.setAttribute("chain-hit_v", list = RegionManager.getLocalPlayers(e, distance));
|
||||||
}
|
}
|
||||||
list.remove(e);
|
list.remove(e);
|
||||||
list.remove(victim);
|
list.remove(victim);
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,16 @@ import core.game.node.entity.combat.equipment.Ammunition;
|
||||||
import core.game.node.entity.combat.equipment.RangeWeapon;
|
import core.game.node.entity.combat.equipment.RangeWeapon;
|
||||||
import core.game.node.entity.combat.equipment.Weapon;
|
import core.game.node.entity.combat.equipment.Weapon;
|
||||||
import core.game.node.entity.combat.equipment.WeaponInterface;
|
import core.game.node.entity.combat.equipment.WeaponInterface;
|
||||||
|
import core.game.node.entity.npc.NPC;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.node.entity.skill.Skills;
|
import core.game.node.entity.skill.Skills;
|
||||||
|
import core.game.world.map.RegionManager;
|
||||||
import core.game.world.update.flag.context.Graphics;
|
import core.game.world.update.flag.context.Graphics;
|
||||||
import core.tools.RandomFunction;
|
import core.tools.RandomFunction;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargetsForChinchompa;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a combat swing using red chinchompas.
|
* Handles a combat swing using red chinchompas.
|
||||||
* @author Emperor
|
* @author Emperor
|
||||||
|
|
@ -55,19 +56,23 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean accurate = isAccurateImpact(entity, victim, CombatStyle.RANGE);
|
// ! Initial capacity of 14, but has dynamic size? i.e. we are not restricting to a max of 14 targets hit here now
|
||||||
List<Entity> targetCandidates = findMultihitTargetsForChinchompa(victim, entity);
|
List<Entity> targetCandidates = new ArrayList<>(14);
|
||||||
|
targetCandidates.addAll(RegionManager.getSurroundingNPCs(victim, 14, entity));
|
||||||
|
targetCandidates.addAll(RegionManager.getSurroundingPlayers(victim, 14, entity));
|
||||||
BattleState[] targets = new BattleState[targetCandidates.size()];
|
BattleState[] targets = new BattleState[targetCandidates.size()];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Entity e : targetCandidates) {
|
for (Entity e : targetCandidates) {
|
||||||
|
if (canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
|
||||||
BattleState s = targets[count++] = new BattleState(entity, e);
|
BattleState s = targets[count++] = new BattleState(entity, e);
|
||||||
s.setStyle(CombatStyle.RANGE);
|
s.setStyle(CombatStyle.RANGE);
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
if (accurate) {
|
if (isAccurateImpact(entity, e, CombatStyle.RANGE)) {
|
||||||
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
|
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
|
||||||
}
|
}
|
||||||
s.setEstimatedHit(hit);
|
s.setEstimatedHit(hit);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
state.setTargets(targets);
|
state.setTargets(targets);
|
||||||
Companion.useAmmo(entity, state, null);
|
Companion.useAmmo(entity, state, null);
|
||||||
return 2 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3);
|
return 2 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3);
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,12 @@ import java.util.List;
|
||||||
import core.game.node.entity.Entity;
|
import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.combat.BattleState;
|
import core.game.node.entity.combat.BattleState;
|
||||||
import core.game.node.entity.combat.CombatStyle;
|
import core.game.node.entity.combat.CombatStyle;
|
||||||
|
import core.game.node.entity.combat.InteractionType;
|
||||||
import core.game.node.entity.combat.MeleeSwingHandler;
|
import core.game.node.entity.combat.MeleeSwingHandler;
|
||||||
import core.game.node.entity.impl.Animator.Priority;
|
import core.game.node.entity.impl.Animator.Priority;
|
||||||
|
import core.game.node.entity.npc.NPC;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.world.map.RegionManager;
|
||||||
import core.game.world.update.flag.context.Animation;
|
import core.game.world.update.flag.context.Animation;
|
||||||
import core.game.world.update.flag.context.Graphics;
|
import core.game.world.update.flag.context.Graphics;
|
||||||
import core.plugin.Plugin;
|
import core.plugin.Plugin;
|
||||||
|
|
@ -16,7 +19,6 @@ import core.tools.RandomFunction;
|
||||||
import org.rs09.consts.Sounds;
|
import org.rs09.consts.Sounds;
|
||||||
|
|
||||||
import static core.api.ContentAPIKt.playGlobalAudio;
|
import static core.api.ContentAPIKt.playGlobalAudio;
|
||||||
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargetsForD2h;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the Powerstab special attack.
|
* Handles the Powerstab special attack.
|
||||||
|
|
@ -73,10 +75,13 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements
|
||||||
if (!multi) {
|
if (!multi) {
|
||||||
return super.swing(entity, victim, state);
|
return super.swing(entity, victim, state);
|
||||||
}
|
}
|
||||||
List<Entity> list = findMultihitTargetsForD2h(victim, entity, CombatStyle.MELEE);
|
@SuppressWarnings("rawtypes")
|
||||||
|
List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(entity, 9, entity) : RegionManager.getSurroundingPlayers(entity, 9, entity);
|
||||||
BattleState[] targets = new BattleState[list.size()];
|
BattleState[] targets = new BattleState[list.size()];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Entity e : list) {
|
for (Object o : list) {
|
||||||
|
Entity e = (Entity) o;
|
||||||
|
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
|
||||||
BattleState s = targets[count++] = new BattleState(entity, e);
|
BattleState s = targets[count++] = new BattleState(entity, e);
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
if (isAccurateImpact(entity, e)) {
|
if (isAccurateImpact(entity, e)) {
|
||||||
|
|
@ -85,6 +90,7 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements
|
||||||
s.setStyle(CombatStyle.MELEE);
|
s.setStyle(CombatStyle.MELEE);
|
||||||
s.setEstimatedHit(hit);
|
s.setEstimatedHit(hit);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
state.setTargets(targets);
|
state.setTargets(targets);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,25 +52,20 @@ public final class QuickSmashSpecialHandler extends MeleeSwingHandler implements
|
||||||
@Override
|
@Override
|
||||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
CombatStyle.MELEE.getSwingHandler().register(4153, this);
|
CombatStyle.MELEE.getSwingHandler().register(4153, this);
|
||||||
|
CombatStyle.MELEE.getSwingHandler().register(14792, this);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int swing(Entity entity, Entity victim, BattleState state) {
|
public int swing(Entity entity, Entity victim, BattleState state) {
|
||||||
Player p = (Player) entity;
|
Player p = (Player) entity;
|
||||||
boolean canMelee = MeleeSwingHandler.Companion.canMelee(p, victim, 1);
|
|
||||||
if (victim == null) {
|
if (victim == null) {
|
||||||
victim = p.getProperties().getCombatPulse().getLastVictim();
|
victim = p.getProperties().getCombatPulse().getLastVictim();
|
||||||
if (victim == null || GameWorld.getTicks() - p.getAttribute("combat-stop", -1) > 2 || !canMelee) {
|
if (victim == null || GameWorld.getTicks() - p.getAttribute("combat-stop", -1) > 2 || !MeleeSwingHandler.Companion.canMelee(p, victim, 1)) {
|
||||||
p.getPacketDispatch().sendMessage("Warning: Since the maul's special is an instant attack, it will be wasted when used ");
|
p.getPacketDispatch().sendMessage("Warning: Since the maul's special is an instant attack, it will be wasted when used ");
|
||||||
p.getPacketDispatch().sendMessage("on a first strike.");
|
p.getPacketDispatch().sendMessage("on a first strike.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
canMelee = canMelee && p.continueAttack(victim, CombatStyle.MELEE, true); //this is what checks wildy rules, e.g. "The level difference between you and your opponent is too great."
|
|
||||||
}
|
|
||||||
if (!canMelee) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
if (DeathTask.isDead(victim)) {
|
if (DeathTask.isDead(victim)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,12 @@ import java.util.List;
|
||||||
import core.game.node.entity.Entity;
|
import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.combat.BattleState;
|
import core.game.node.entity.combat.BattleState;
|
||||||
import core.game.node.entity.combat.CombatStyle;
|
import core.game.node.entity.combat.CombatStyle;
|
||||||
|
import core.game.node.entity.combat.InteractionType;
|
||||||
import core.game.node.entity.combat.MeleeSwingHandler;
|
import core.game.node.entity.combat.MeleeSwingHandler;
|
||||||
import core.game.node.entity.impl.Animator.Priority;
|
import core.game.node.entity.impl.Animator.Priority;
|
||||||
|
import core.game.node.entity.npc.NPC;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.world.map.RegionManager;
|
||||||
import core.game.world.update.flag.context.Animation;
|
import core.game.world.update.flag.context.Animation;
|
||||||
import core.game.world.update.flag.context.Graphics;
|
import core.game.world.update.flag.context.Graphics;
|
||||||
import core.plugin.Plugin;
|
import core.plugin.Plugin;
|
||||||
|
|
@ -16,7 +19,6 @@ import core.tools.RandomFunction;
|
||||||
import org.rs09.consts.Sounds;
|
import org.rs09.consts.Sounds;
|
||||||
|
|
||||||
import static core.api.ContentAPIKt.playGlobalAudio;
|
import static core.api.ContentAPIKt.playGlobalAudio;
|
||||||
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles Vesta's Spear special attack - Spear Wall.
|
* Handles Vesta's Spear special attack - Spear Wall.
|
||||||
|
|
@ -74,15 +76,20 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements
|
||||||
if (!multi) {
|
if (!multi) {
|
||||||
return super.swing(entity, victim, state);
|
return super.swing(entity, victim, state);
|
||||||
}
|
}
|
||||||
List<Entity> list = findMultihitTargets(victim, entity, CombatStyle.MELEE);
|
@SuppressWarnings("rawtypes")
|
||||||
|
List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(entity, 9, entity) : RegionManager.getSurroundingPlayers(entity, 9, entity);
|
||||||
BattleState[] targets = new BattleState[list.size()];
|
BattleState[] targets = new BattleState[list.size()];
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Entity e : list) {
|
for (Object o : list) {
|
||||||
|
Entity e = (Entity) o;
|
||||||
|
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
|
||||||
BattleState s = targets[count++] = new BattleState(entity, e);
|
BattleState s = targets[count++] = new BattleState(entity, e);
|
||||||
int hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
|
int hit = 0;
|
||||||
|
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
|
||||||
s.setStyle(CombatStyle.MELEE);
|
s.setStyle(CombatStyle.MELEE);
|
||||||
s.setEstimatedHit(hit);
|
s.setEstimatedHit(hit);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
state.setTargets(targets);
|
state.setTargets(targets);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,17 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import core.plugin.Initializable;
|
import core.plugin.Initializable;
|
||||||
|
import content.global.skill.summoning.familiar.Familiar;
|
||||||
import core.game.node.entity.Entity;
|
import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.combat.BattleState;
|
import core.game.node.entity.combat.BattleState;
|
||||||
import core.game.node.entity.combat.CombatStyle;
|
import core.game.node.entity.combat.CombatStyle;
|
||||||
import core.game.node.entity.combat.MeleeSwingHandler;
|
import core.game.node.entity.combat.MeleeSwingHandler;
|
||||||
import core.game.node.entity.impl.Animator.Priority;
|
import core.game.node.entity.impl.Animator.Priority;
|
||||||
|
import core.game.node.entity.npc.NPC;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.world.map.Direction;
|
||||||
|
import core.game.world.map.Location;
|
||||||
|
import core.game.world.map.RegionManager;
|
||||||
import core.game.world.update.flag.context.Animation;
|
import core.game.world.update.flag.context.Animation;
|
||||||
import core.game.world.update.flag.context.Graphics;
|
import core.game.world.update.flag.context.Graphics;
|
||||||
import core.plugin.Plugin;
|
import core.plugin.Plugin;
|
||||||
|
|
@ -17,7 +22,6 @@ import core.tools.RandomFunction;
|
||||||
import org.rs09.consts.Sounds;
|
import org.rs09.consts.Sounds;
|
||||||
|
|
||||||
import static core.api.ContentAPIKt.playGlobalAudio;
|
import static core.api.ContentAPIKt.playGlobalAudio;
|
||||||
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargetsForDragonHalberd;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the Dragon halberd special attack.
|
* Handles the Dragon halberd special attack.
|
||||||
|
|
@ -88,11 +92,25 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug
|
||||||
if (!entity.getProperties().isMultiZone() || !victim.getProperties().isMultiZone()) {
|
if (!entity.getProperties().isMultiZone() || !victim.getProperties().isMultiZone()) {
|
||||||
return new BattleState[]{state};
|
return new BattleState[]{state};
|
||||||
}
|
}
|
||||||
|
Location vl = victim.getLocation();
|
||||||
|
int x = vl.getX();
|
||||||
|
int y = vl.getY();
|
||||||
|
Direction dir = Direction.getDirection(x - entity.getLocation().getX(), y - entity.getLocation().getY());
|
||||||
List<BattleState> l = new ArrayList<>(20);
|
List<BattleState> l = new ArrayList<>(20);
|
||||||
l.add(new BattleState(entity, victim));
|
l.add(new BattleState(entity, victim));
|
||||||
List<Entity> list = findMultihitTargetsForDragonHalberd(victim, entity);
|
for (Entity n : victim instanceof NPC ? RegionManager.getSurroundingNPCs(victim, 9, entity, victim) : RegionManager.getSurroundingPlayers(victim, 9, entity, victim)) {
|
||||||
for (Entity n : list) {
|
if (n instanceof Familiar) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!n.isAttackable(entity, CombatStyle.MELEE, false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (n.getLocation().equals(vl.transform(dir.getStepY(), dir.getStepX(), 0)) || n.getLocation().equals(vl.transform(-dir.getStepY(), -dir.getStepX(), 0))) {
|
||||||
l.add(new BattleState(entity, n));
|
l.add(new BattleState(entity, n));
|
||||||
|
if (l.size() >= 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return l.toArray(new BattleState[l.size()]);
|
return l.toArray(new BattleState[l.size()]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package content.global.handlers.item.withitem
|
||||||
import content.data.Dyes
|
import content.data.Dyes
|
||||||
import core.game.interaction.NodeUsageEvent
|
import core.game.interaction.NodeUsageEvent
|
||||||
import core.game.interaction.UseWithHandler
|
import core.game.interaction.UseWithHandler
|
||||||
import core.game.node.entity.player.link.diary.DiaryType
|
|
||||||
import core.game.node.item.Item
|
import core.game.node.item.Item
|
||||||
import core.plugin.Initializable
|
import core.plugin.Initializable
|
||||||
import core.plugin.Plugin
|
import core.plugin.Plugin
|
||||||
|
|
@ -47,10 +46,6 @@ class CapeDyer : UseWithHandler(*CAPES.copyOfRange(0,CAPES.size - 1).toIntArray(
|
||||||
player.inventory.add(product.product)
|
player.inventory.add(product.product)
|
||||||
player.inventory.add(Item(Items.VIAL_229))
|
player.inventory.add(Item(Items.VIAL_229))
|
||||||
player.sendMessage("You dye the cape.")
|
player.sendMessage("You dye the cape.")
|
||||||
|
|
||||||
if (product == Cape.PINK) {
|
|
||||||
player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 2, 5)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
package content.global.handlers.item.withitem;
|
||||||
|
|
||||||
|
import core.cache.def.impl.ItemDefinition;
|
||||||
|
import core.plugin.Initializable;
|
||||||
|
import core.game.dialogue.DialogueAction;
|
||||||
|
import core.game.interaction.NodeUsageEvent;
|
||||||
|
import core.game.interaction.OptionHandler;
|
||||||
|
import core.game.interaction.UseWithHandler;
|
||||||
|
import core.game.node.Node;
|
||||||
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.node.item.Item;
|
||||||
|
import core.plugin.Plugin;
|
||||||
|
import core.plugin.ClassScanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin used to make the granite maul into the ornamental version.
|
||||||
|
* @author Splinter
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Initializable
|
||||||
|
public final class GraniteMaulPlugin extends UseWithHandler {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@code GraniteMaulPlugin} {@code Object}.
|
||||||
|
*/
|
||||||
|
public GraniteMaulPlugin() {
|
||||||
|
super(4153);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
|
ClassScanner.definePlugin(new GraniteMaulRevertHandler());
|
||||||
|
addHandler(14793, ITEM_TYPE, this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(final NodeUsageEvent event) {
|
||||||
|
final Player player = event.getPlayer();
|
||||||
|
player.getDialogueInterpreter().sendOptions("Attach the clamp?", "Yes", "No");
|
||||||
|
player.getDialogueInterpreter().addAction(new DialogueAction() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Player player, int buttonId) {
|
||||||
|
switch (buttonId) {
|
||||||
|
case 2:
|
||||||
|
if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) {
|
||||||
|
player.getInventory().add(new Item(14792, 1));
|
||||||
|
player.sendMessage("You attach the clamp to the granite maul, making it slightly more fashionable.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the removal of the ornamental kit.
|
||||||
|
* @author Splinter
|
||||||
|
*/
|
||||||
|
public final class GraniteMaulRevertHandler extends OptionHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
|
ItemDefinition.forId(14792).getHandlers().put("option:revert", this);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(Player player, Node node, String option) {
|
||||||
|
final Item item = (Item) node;
|
||||||
|
player.getDialogueInterpreter().sendOptions("Remove the clamp?", "Yes", "No");
|
||||||
|
player.getDialogueInterpreter().addAction(new DialogueAction() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Player player, int buttonId) {
|
||||||
|
switch (buttonId) {
|
||||||
|
case 2:
|
||||||
|
if(player.getInventory().remove(item)){
|
||||||
|
player.getInventory().add(new Item(4153, 1));
|
||||||
|
player.sendMessage("You remove the clamp from your maul, and in the process, it is destroyed.");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWalk() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ public final class ImpJarCreatePlugin extends UseWithHandler {
|
||||||
/**
|
/**
|
||||||
* The flower ids.
|
* The flower ids.
|
||||||
*/
|
*/
|
||||||
private static final int[] FLOWERS = new int[] { 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 6010, 6012 };
|
private static final int[] FLOWERS = new int[] { 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@code ImpJarCreatePlugin} {@code Object}.
|
* Constructs a new {@code ImpJarCreatePlugin} {@code Object}.
|
||||||
|
|
|
||||||
|
|
@ -97,14 +97,7 @@ class PoisonedWeaponListeners : InteractionListener {
|
||||||
ADAMANT_SPEAR(1245, 1259, 5712, 5726),
|
ADAMANT_SPEAR(1245, 1259, 5712, 5726),
|
||||||
RUNE_SPEAR(1247, 1261, 5714, 5728),
|
RUNE_SPEAR(1247, 1261, 5714, 5728),
|
||||||
DRAGON_SPEAR(1249, 1263, 5716, 5730),
|
DRAGON_SPEAR(1249, 1263, 5716, 5730),
|
||||||
BLACK_SPEAR(4580, 4582, 5734, 5736),
|
BLACK_SPEAR(4580, 4582, 5734, 5736);
|
||||||
|
|
||||||
BRONZE_HASTA(Items.BRONZE_HASTA_11367, Items.BRONZE_HASTAP_11379, Items.BRONZE_HASTAP_PLUS_11382, Items.BRONZE_HASTAP_PLUS_PLUS_11384),
|
|
||||||
IRON_HASTA(Items.IRON_HASTA_11369, Items.IRON_HASTAP_11386, Items.IRON_HASTAP_PLUS_11389, Items.IRON_HASTAP_PLUS_PLUS_11391),
|
|
||||||
STEEL_HASTA(Items.STEEL_HASTA_11371, Items.STEEL_HASTAP_11393, Items.STEEL_HASTAP_PLUS_11396, Items.STEEL_HASTAP_PLUS_PLUS_11398),
|
|
||||||
MITHRIL_HASTA(Items.MITHRIL_HASTA_11373, Items.MITHRIL_HASTAP_11400, Items.MITHRIL_HASTAP_PLUS_11403, Items.MITHRIL_HASTAP_PLUS_PLUS_11405),
|
|
||||||
ADAMANT_HASTA(Items.ADAMANT_HASTA_11375, Items.ADAMANT_HASTAP_11407, Items.ADAMANT_HASTAP_PLUS_11410, Items.ADAMANT_HASTAP_PLUS_PLUS_11412),
|
|
||||||
RUNE_HASTA(Items.RUNE_HASTA_11377, Items.RUNE_HASTAP_11414, Items.RUNE_HASTAP_PLUS_11417, Items.RUNE_HASTAP_PLUS_PLUS_11419);
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val itemMap = values().map { it.base to intArrayOf(it.p,it.pp,it.ppp) }.toMap()
|
val itemMap = values().map { it.base to intArrayOf(it.p,it.pp,it.ppp) }.toMap()
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ public final class SoftclayPlugin extends UseWithHandler {
|
||||||
player.getPacketDispatch().sendMessage("You mix the clay and water. You now have some soft, workable clay.");
|
player.getPacketDispatch().sendMessage("You mix the clay and water. You now have some soft, workable clay.");
|
||||||
player.getInventory().add(SOFT_CLAY);
|
player.getInventory().add(SOFT_CLAY);
|
||||||
player.getInventory().add(returnItem);
|
player.getInventory().add(returnItem);
|
||||||
if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.LUMBRIDGE, 0, 6) && player.getLocation().getRegionId() == 12341) {
|
if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.LUMBRIDGE, 0, 6) && player.getViewport().getRegion().getId() == 12341) {
|
||||||
player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 6);
|
player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 6);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package content.global.handlers.item.withobject
|
package content.global.handlers.item.withobject
|
||||||
|
|
||||||
import content.region.kandarin.seers.diary.SeersVillageAchievementDiary
|
|
||||||
import core.api.*
|
import core.api.*
|
||||||
import core.game.node.item.Item
|
import core.game.node.item.Item
|
||||||
import org.rs09.consts.Items
|
import org.rs09.consts.Items
|
||||||
|
|
@ -27,8 +26,6 @@ class CoalTruckListener : InteractionListener {
|
||||||
return@on true
|
return@on true
|
||||||
}
|
}
|
||||||
|
|
||||||
val coalTruckFull = coalInTruck == 120
|
|
||||||
|
|
||||||
var toRemove = freeSlots(player)
|
var toRemove = freeSlots(player)
|
||||||
|
|
||||||
if (toRemove > coalInTruck) {
|
if (toRemove > coalInTruck) {
|
||||||
|
|
@ -38,10 +35,6 @@ class CoalTruckListener : InteractionListener {
|
||||||
if (addItem(player, Items.COAL_453, toRemove)) {
|
if (addItem(player, Items.COAL_453, toRemove)) {
|
||||||
coalInTruck -= toRemove
|
coalInTruck -= toRemove
|
||||||
setAttribute(player, "/save:$ATTRIBUTE_COAL_TRUCK_INVENTORY", coalInTruck)
|
setAttribute(player, "/save:$ATTRIBUTE_COAL_TRUCK_INVENTORY", coalInTruck)
|
||||||
|
|
||||||
if (toRemove > 0) {
|
|
||||||
SeersVillageAchievementDiary().onCoalRemovedFromSeersTruck(player, node, coalTruckFull)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return@on true
|
return@on true
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,30 @@ import org.rs09.consts.Sounds
|
||||||
* @author Ceikry
|
* @author Ceikry
|
||||||
*/
|
*/
|
||||||
class WaterSourceListener : InteractionListener {
|
class WaterSourceListener : InteractionListener {
|
||||||
private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 14918, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089)
|
// NOTE '9695' should be removed from the array below once the sink object can be used directly, this is a temporary
|
||||||
|
// solution.
|
||||||
|
// this is ugly!
|
||||||
|
private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 9695, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 14918, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089)
|
||||||
|
|
||||||
private val nonWellableMsg = "If I drop my @ down there, I don't think I'm likely to get it back."
|
private val nonWellableMsg = "If I drop my @ down there, I don't think I'm likely to get it back."
|
||||||
private val animation = Animation(832)
|
private val animation = Animation(832)
|
||||||
|
|
||||||
override fun defineListeners() {
|
override fun defineListeners()
|
||||||
|
{
|
||||||
onUseWith(IntType.SCENERY, WaterVessel.getInputs(), *waterSources){ player, used, with ->
|
onUseWith(IntType.SCENERY, WaterVessel.getInputs(), *waterSources){ player, used, with ->
|
||||||
val vessel = WaterVessel.forId(used.id) ?: return@onUseWith false
|
val vessel = WaterVessel.forId(used.id) ?: return@onUseWith false
|
||||||
|
|
||||||
if(with.name.contains("well", ignoreCase = true) && !vessel.wellable)
|
if(with.name.contains("well", ignoreCase = true) && !vessel.wellable)
|
||||||
{
|
{
|
||||||
sendMessage(player, formatMsgText(used.name, nonWellableMsg))
|
sendMessage(player, formatMsgText(used.name, nonWellableMsg))
|
||||||
return@onUseWith true
|
return@onUseWith true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(with.id == 9695 && player.location.regionId != 11571)
|
||||||
|
{
|
||||||
|
return@onUseWith false
|
||||||
|
}
|
||||||
|
|
||||||
//ugly achievement code, achievement system sux
|
//ugly achievement code, achievement system sux
|
||||||
if(vessel == WaterVessel.BUCKET && with.id == 11661)
|
if(vessel == WaterVessel.BUCKET && with.id == 11661)
|
||||||
{
|
{
|
||||||
|
|
@ -56,6 +67,15 @@ class WaterSourceListener : InteractionListener {
|
||||||
|
|
||||||
return@onUseWith true
|
return@onUseWith true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is needed to make the crafting guild sink work, but technically it's wrong as it is the noticeboard and
|
||||||
|
// not the sink being used. This is a temporary solution until the sink object can be used directly.
|
||||||
|
setDest(IntType.SCENERY, intArrayOf(9695), "use") { player, node ->
|
||||||
|
if (player.location.regionId == 11571){
|
||||||
|
return@setDest Location.create(2934, 3280, 0)
|
||||||
|
}
|
||||||
|
return@setDest node.location
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatMsgText(name: String, template: String): String
|
private fun formatMsgText(name: String, template: String): String
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,9 @@ import core.game.node.entity.npc.AbstractNPC
|
||||||
import core.game.node.entity.npc.NPC
|
import core.game.node.entity.npc.NPC
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
import core.game.node.entity.player.link.IronmanMode
|
import core.game.node.entity.player.link.IronmanMode
|
||||||
import core.game.node.item.Item
|
|
||||||
import core.game.world.map.Direction
|
import core.game.world.map.Direction
|
||||||
import core.game.world.map.Location
|
import core.game.world.map.Location
|
||||||
import core.plugin.Initializable
|
import core.plugin.Initializable
|
||||||
import org.rs09.consts.Items
|
|
||||||
import org.rs09.consts.NPCs
|
import org.rs09.consts.NPCs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -41,7 +39,7 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
||||||
NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046, NPCs.MAGNUS_GRAM_5488, NPCs.TZHAAR_KET_ZUH_2619,
|
NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046, NPCs.MAGNUS_GRAM_5488, NPCs.TZHAAR_KET_ZUH_2619,
|
||||||
NPCs.SIRSAL_BANKER_4519, NPCs.FADLI_958, NPCs.BANK_TUTOR_4907, NPCs.JADE_4296,
|
NPCs.SIRSAL_BANKER_4519, NPCs.FADLI_958, NPCs.BANK_TUTOR_4907, NPCs.JADE_4296,
|
||||||
NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050,
|
NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050,
|
||||||
NPCs.BANKER_6538, NPCs.ODOVACAR_5383
|
NPCs.BANKER_6538
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
@ -63,25 +61,6 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val ODOVACAR_FEE = 100
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles special access requirements for bankers that charge a fee.
|
|
||||||
* @return true if banking may proceed, false if it should be blocked.
|
|
||||||
*/
|
|
||||||
fun canAccessBank(player: Player, npc: NPC): Boolean {
|
|
||||||
if (npc.id != NPCs.ODOVACAR_5383) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeItem(player, Item(Items.COINS_995, ODOVACAR_FEE))) {
|
|
||||||
sendMessage(player, "You pay 100 coins to use the travelling bank.")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun attemptBank(player: Player, node: Node): Boolean {
|
fun attemptBank(player: Player, node: Node): Boolean {
|
||||||
val npc = node as NPC
|
val npc = node as NPC
|
||||||
|
|
||||||
|
|
@ -90,11 +69,6 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canAccessBank(player, node)) {
|
|
||||||
sendMessage(player, "You need 100 coins to use the travelling bank.")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
npc.faceLocation(null)
|
npc.faceLocation(null)
|
||||||
openBankAccount(player)
|
openBankAccount(player)
|
||||||
|
|
||||||
|
|
@ -184,7 +158,7 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
class BankerDialogueLabellerFile : DialogueLabeller() {
|
class BankerDialogueLabellerFile : DialogueLabeller() {
|
||||||
val BANKERS_WITH_EXTRA_OPTION = intArrayOf(NPCs.BANK_TUTOR_4907, NPCs.JADE_4296, NPCs.BANKER_6538, NPCs.ODOVACAR_5383)
|
val BANKERS_WITH_EXTRA_OPTION = intArrayOf(NPCs.BANK_TUTOR_4907, NPCs.JADE_4296, NPCs.BANKER_6538)
|
||||||
|
|
||||||
override fun addConversation() {
|
override fun addConversation() {
|
||||||
exec { player, npc ->
|
exec { player, npc ->
|
||||||
|
|
@ -224,7 +198,6 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
||||||
options(
|
options(
|
||||||
DialogueOption("how to use", "How do I use the bank?") { _, npc -> return@DialogueOption npc.id == NPCs.BANK_TUTOR_4907 },
|
DialogueOption("how to use", "How do I use the bank?") { _, npc -> return@DialogueOption npc.id == NPCs.BANK_TUTOR_4907 },
|
||||||
DialogueOption("who is the bounty hunter banker", "Who are you?") { _, npc -> return@DialogueOption npc.id == NPCs.BANKER_6538 },
|
DialogueOption("who is the bounty hunter banker", "Who are you?") { _, npc -> return@DialogueOption npc.id == NPCs.BANKER_6538 },
|
||||||
DialogueOption("who is odovacar", "Who are you?") { _, npc -> return@DialogueOption npc.id == NPCs.ODOVACAR_5383 },
|
|
||||||
DialogueOption("access", "I'd like to access my bank account please.", expression = ChatAnim.ASKING),
|
DialogueOption("access", "I'd like to access my bank account please.", expression = ChatAnim.ASKING),
|
||||||
DialogueOption("buy second bank", "I'd like to open a secondary bank account.") { player, _ -> return@DialogueOption ServerConstants.SECOND_BANK && !hasActivatedSecondaryBankAccount(player) },
|
DialogueOption("buy second bank", "I'd like to open a secondary bank account.") { player, _ -> return@DialogueOption ServerConstants.SECOND_BANK && !hasActivatedSecondaryBankAccount(player) },
|
||||||
DialogueOption("switch second bank", "I'd like to switch to my primary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && isUsingSecondaryBankAccount(player) },
|
DialogueOption("switch second bank", "I'd like to switch to my primary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && isUsingSecondaryBankAccount(player) },
|
||||||
|
|
@ -269,43 +242,9 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
||||||
npc(ChatAnim.NEUTRAL, "How inconsiderate of me, dear @g[sir,madam]. My name is Maximillian Sackville and I conduct operations here on behalf of The Bank of Gielinor.")
|
npc(ChatAnim.NEUTRAL, "How inconsiderate of me, dear @g[sir,madam]. My name is Maximillian Sackville and I conduct operations here on behalf of The Bank of Gielinor.")
|
||||||
goto("main options")
|
goto("main options")
|
||||||
|
|
||||||
label("who is odovacar")
|
|
||||||
npc("How frightfully rude of me, my dear @g[chap,lady]. My name is Odovacar and I work for that excellent enterprise, the Bank of Gielinor.")
|
|
||||||
player("If you work for the bank, what are you doing here?")
|
|
||||||
npc("As part of our ongoing service to provide you, the customer, with an absolutely world-class banking experience, we are investigating the option of opening a chain of travelling banks.")
|
|
||||||
npc("These will provide you, our esteemed customer, with the convenience of having banking facilities where they will be of optimum use to you. Such as here!")
|
|
||||||
player("Huh?")
|
|
||||||
npc("I am the first of a new generation of travelling bankers that will wander the perilous areas of the world to provide you, the valued customer, with a bank when you need it most!")
|
|
||||||
player("So I can access my bank account simply by talking to you?")
|
|
||||||
npc("Absolutely correct, dear @g[sir,lady].")
|
|
||||||
npc("I must warn you, however, that due to the significantly increased overheads of an enterprise such as this, there is a small bank charge of 100gp every time you want to access your account.")
|
|
||||||
options(
|
|
||||||
DialogueOption("access", "Sounds fair; here's the money. Can I access my account now?"),
|
|
||||||
DialogueOption("payafterbank", "Let me open my account and then I'll pay you."),
|
|
||||||
DialogueOption("nopay2bank", "That's preposterous! I'm not paying to withdraw my own money!")
|
|
||||||
)
|
|
||||||
|
|
||||||
label("payafterbank")
|
|
||||||
npc("It's not that I don't trust you, old @g[chap,girl], but as the old adage goes, 'money comes before friends'.")
|
|
||||||
goto("nowhere")
|
|
||||||
|
|
||||||
label("nopay2bank")
|
|
||||||
npc("I'm sorry to hear that, @g[sir,madam]. If you should reconsider, because I believe this service offers excellent value for money, do not hesitate to contact me.")
|
|
||||||
goto("nowhere")
|
|
||||||
|
|
||||||
label("nomoney")
|
|
||||||
npc("I'm afraid you don't have the necessary funds with you at this time so I can't allow you to access your account. Please come again, when you have 100 gold to cover the fee.")
|
|
||||||
goto("nowhere")
|
|
||||||
|
|
||||||
label("access")
|
label("access")
|
||||||
exec { player, npc ->
|
exec { player, _ -> openBankAccount(player) }
|
||||||
if (!canAccessBank(player, npc)) {
|
|
||||||
goto("nomoney")
|
|
||||||
} else {
|
|
||||||
openBankAccount(player)
|
|
||||||
goto("nowhere")
|
goto("nowhere")
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
label("buy second bank")
|
label("buy second bank")
|
||||||
npc("Certainly. We offer secondary accounts to all our customers.")
|
npc("Certainly. We offer secondary accounts to all our customers.")
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package content.global.handlers.npc
|
||||||
|
|
||||||
import content.data.consumables.Consumables
|
import content.data.consumables.Consumables
|
||||||
import content.global.skill.cooking.fermenting.CalquatDecant
|
import content.global.skill.cooking.fermenting.CalquatDecant
|
||||||
import content.region.kandarin.quest.barbariantraining.BarbarianTraining
|
|
||||||
import core.api.*
|
import core.api.*
|
||||||
import core.game.consumable.Potion
|
import core.game.consumable.Potion
|
||||||
import core.game.dialogue.DialogueFile
|
import core.game.dialogue.DialogueFile
|
||||||
|
|
@ -119,7 +118,7 @@ class DecantListener : InteractionListener {
|
||||||
// Barbarian decanting: use a 4-dose potion and an empty vial together to make two 2-dose potions
|
// Barbarian decanting: use a 4-dose potion and an empty vial together to make two 2-dose potions
|
||||||
onUseWith(IntType.ITEM, potions, Items.VIAL_229) { player, used, with ->
|
onUseWith(IntType.ITEM, potions, Items.VIAL_229) { player, used, with ->
|
||||||
// Check if player has started barbarian herblore training
|
// Check if player has started barbarian herblore training
|
||||||
if (getAttribute(player, BarbarianTraining.attributeHerblore, 0) == 0) {
|
if (getAttribute(player, "/save:barbtraining:herblore", 0) == 0) {
|
||||||
return@onUseWith false
|
return@onUseWith false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,9 +129,9 @@ class SheepBehavior : NPCBehavior(*sheepIds), InteractionListener {
|
||||||
val sheepDirection = Direction.getDirection(sheepLocation, playerLocation) // Get direction sheep is facing, from the player's location
|
val sheepDirection = Direction.getDirection(sheepLocation, playerLocation) // Get direction sheep is facing, from the player's location
|
||||||
val sheepOppositeDirection = sheepDirection.getOpposite() // Switch to opposite direction
|
val sheepOppositeDirection = sheepDirection.getOpposite() // Switch to opposite direction
|
||||||
|
|
||||||
val xWalkLocation = sheepLocation.x + (sheepOppositeDirection.getStepX() * 3) // Gets x location, if set, 3 steps away from player
|
val xWalkLocation = sheepLocation.getX() + (sheepOppositeDirection.getStepX() * 3) // Gets x location, if set, 3 steps away from player
|
||||||
val yWalkLocation = sheepLocation.y + (sheepOppositeDirection.getStepY() * 3) // Gets y location, if set, 3 steps away from player
|
val yWalkLocation = sheepLocation.getY() + (sheepOppositeDirection.getStepY() * 3) // Gets y location, if set, 3 steps away from player
|
||||||
val sheepWalkToLocation = Location(xWalkLocation, yWalkLocation, sheepLocation.z); // New location for pathfinding
|
val sheepWalkToLocation = Location(xWalkLocation, yWalkLocation, sheepLocation.getZ()); // New location for pathfinding
|
||||||
|
|
||||||
sendMessage(player, messagePlayer)
|
sendMessage(player, messagePlayer)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,10 @@ import core.tools.RandomFunction;
|
||||||
import org.rs09.consts.Sounds;
|
import org.rs09.consts.Sounds;
|
||||||
|
|
||||||
import static core.api.ContentAPIKt.playAudio;
|
import static core.api.ContentAPIKt.playAudio;
|
||||||
import static core.api.ContentAPIKt.sendMessage;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the pick option of interactive scenery (non-farming cabbages,
|
* Handles the pick option of interactive scenery (non-farming cabbages,
|
||||||
* potatoes, bananas, etc)
|
* potatoes, bananas, etc)
|
||||||
*
|
|
||||||
* @author Emperor
|
* @author Emperor
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
|
@ -39,10 +37,10 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||||
for (PickingPlant p : PickingPlant.values()) {
|
for(PickingPlant p : PickingPlant.values()){
|
||||||
SceneryDefinition.forId(p.objectId).getHandlers().put("option:pick", this);
|
SceneryDefinition.forId(p.objectId).getHandlers().put("option:pick",this);
|
||||||
}
|
}
|
||||||
SceneryDefinition.forId(3511).getHandlers().put("option:take-cutting", this);
|
SceneryDefinition.forId(3511).getHandlers().put("option:take-cutting",this);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,12 +105,10 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
if (!isBloomPlant) {
|
if (!isBloomPlant) {
|
||||||
SceneryBuilder.replace(plant == PickingPlant.BANANA_TREE_4 ? full : object, object.transform(banana ? plant.respawn : 0), banana ? 300 : plant.respawn);
|
SceneryBuilder.replace(plant == PickingPlant.BANANA_TREE_4 ? full : object, object.transform(banana ? plant.respawn : 0), banana ? 300 : plant.respawn);
|
||||||
}
|
}
|
||||||
if (plant.name().startsWith("NETTLES")) {
|
if (!plant.name().startsWith("NETTLES")) {
|
||||||
sendMessage(player, "You pick a handful of nettles.");
|
player.getPacketDispatch().sendMessage("You pick a " + reward.getName().toLowerCase() + ".");
|
||||||
} else if (plant.name().startsWith("GLOWING")) {
|
|
||||||
sendMessage(player, "You pull the fungus from the water, it is very cold to the touch.");
|
|
||||||
} else {
|
} else {
|
||||||
sendMessage(player, "You pick a " + reward.getName().toLowerCase() + ".");
|
player.getPacketDispatch().sendMessage("You pick a handful of nettles.");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +118,6 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method used to handle the flax picking.
|
* Method used to handle the flax picking.
|
||||||
*
|
|
||||||
* @param player the player.
|
* @param player the player.
|
||||||
* @param object the object.
|
* @param object the object.
|
||||||
* @param plant the plank.
|
* @param plant the plank.
|
||||||
|
|
@ -143,7 +138,6 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a plant to be picked.
|
* Represents a plant to be picked.
|
||||||
*
|
|
||||||
* @author Emperor
|
* @author Emperor
|
||||||
*/
|
*/
|
||||||
private static enum PickingPlant {
|
private static enum PickingPlant {
|
||||||
|
|
@ -192,6 +186,7 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
GOLDEN_PEAR_BUSH(3513, 2974, -1),
|
GOLDEN_PEAR_BUSH(3513, 2974, -1),
|
||||||
GLOWING_FUNGUS_0(4932, 4075, 30),
|
GLOWING_FUNGUS_0(4932, 4075, 30),
|
||||||
GLOWING_FUNGUS_1(4933, 4075, 30),
|
GLOWING_FUNGUS_1(4933, 4075, 30),
|
||||||
|
RARE_FLOWERS(5006, 2460, 30),
|
||||||
BLACK_MUSHROOMS(6311, 4620, 30),
|
BLACK_MUSHROOMS(6311, 4620, 30),
|
||||||
KELP(12478, 7516, 30),
|
KELP(12478, 7516, 30),
|
||||||
RED_BANANA_TREE(12609, 7572, 30),
|
RED_BANANA_TREE(12609, 7572, 30),
|
||||||
|
|
@ -208,7 +203,7 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
TANSYMUM(29115, 12576, 30),
|
TANSYMUM(29115, 12576, 30),
|
||||||
PRIMWEED(29116, 12588, 30),
|
PRIMWEED(29116, 12588, 30),
|
||||||
STINKBLOOM(29117, 12590, 30),
|
STINKBLOOM(29117, 12590, 30),
|
||||||
TROLLWEISS_FLOWERS(5006, 4086, 30),
|
TROLLWEISS_FLOWERS(37328, 4086, 30),
|
||||||
HOLLOW_LOG(37830, 10968, 30);
|
HOLLOW_LOG(37830, 10968, 30);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -228,7 +223,6 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@code FieldPickingPlugin {@code Object}.
|
* Constructs a new {@code FieldPickingPlugin {@code Object}.
|
||||||
*
|
|
||||||
* @param objectId the object id.
|
* @param objectId the object id.
|
||||||
* @param reward the reward.
|
* @param reward the reward.
|
||||||
* @param respawn the resapwn.
|
* @param respawn the resapwn.
|
||||||
|
|
@ -241,7 +235,6 @@ public final class FieldPickingPlugin extends OptionHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the picking plant by the id.
|
* Gets the picking plant by the id.
|
||||||
*
|
|
||||||
* @param objectId the id.
|
* @param objectId the id.
|
||||||
* @return the picking plant.
|
* @return the picking plant.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -413,7 +413,7 @@ class TableListener : InteractionListener {
|
||||||
}
|
}
|
||||||
val droppedItem = used.dropItem
|
val droppedItem = used.dropItem
|
||||||
if (droppedItem.id == Items.COINS_995) playAudio(player, DROP_COINS_SOUND) else playAudio(player, DROP_ITEM_SOUND)
|
if (droppedItem.id == Items.COINS_995) playAudio(player, DROP_COINS_SOUND) else playAudio(player, DROP_ITEM_SOUND)
|
||||||
GroundItemManager.create(droppedItem, Location(nearestX, nearestY, player.location.z), player)
|
GroundItemManager.create(droppedItem, Location(nearestX, nearestY), player)
|
||||||
|
|
||||||
setAttribute(player, "droppedItem:${droppedItem.id}", getWorldTicks() + 2)
|
setAttribute(player, "droppedItem:${droppedItem.id}", getWorldTicks() + 2)
|
||||||
PlayerParser.save(player)
|
PlayerParser.save(player)
|
||||||
|
|
|
||||||
|
|
@ -139,13 +139,6 @@ public final class AgilityHandler {
|
||||||
* @return The force movement instance, if force movement is used.
|
* @return The force movement instance, if force movement is used.
|
||||||
*/
|
*/
|
||||||
public static ForceMovement forceWalk(final Player player, final int courseIndex, Location start, Location end, Animation animation, int speed, final double experience, final String message) {
|
public static ForceMovement forceWalk(final Player player, final int courseIndex, Location start, Location end, Animation animation, int speed, final double experience, final String message) {
|
||||||
return forceWalk(player, courseIndex, start, end, animation, speed, experience, message, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Walks across an obstacle while using an explicit force-movement facing direction.
|
|
||||||
*/
|
|
||||||
public static ForceMovement forceWalk(final Player player, final int courseIndex, Location start, Location end, Animation animation, int speed, final double experience, final String message, Direction direction) {
|
|
||||||
player.logoutListeners.put("forcewalk", p -> {
|
player.logoutListeners.put("forcewalk", p -> {
|
||||||
p.setLocation(player.getLocation().transform(0,0,0));
|
p.setLocation(player.getLocation().transform(0,0,0));
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
|
|
@ -165,9 +158,6 @@ public final class AgilityHandler {
|
||||||
player.logoutListeners.remove("forcewalk");
|
player.logoutListeners.remove("forcewalk");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (direction != null) {
|
|
||||||
movement.setDirection(direction);
|
|
||||||
}
|
|
||||||
movement.start();
|
movement.start();
|
||||||
GameWorld.getPulser().submit(movement);
|
GameWorld.getPulser().submit(movement);
|
||||||
return movement;
|
return movement;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package content.global.skill.agility
|
||||||
|
|
||||||
import core.api.*
|
import core.api.*
|
||||||
import core.cache.def.impl.SceneryDefinition
|
import core.cache.def.impl.SceneryDefinition
|
||||||
import core.game.interaction.QueueStrength
|
|
||||||
import core.game.node.Node
|
import core.game.node.Node
|
||||||
import core.game.node.scenery.Scenery
|
import core.game.node.scenery.Scenery
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
|
|
@ -169,27 +168,25 @@ class WildernessCourse
|
||||||
private fun handleSteppingStones(player: Player, `object`: Scenery) {
|
private fun handleSteppingStones(player: Player, `object`: Scenery) {
|
||||||
lock(player, 50)
|
lock(player, 50)
|
||||||
val fail = AgilityHandler.hasFailed(player, 1, 0.3)
|
val fail = AgilityHandler.hasFailed(player, 1, 0.3)
|
||||||
queueScript(player, 0, QueueStrength.SOFT) { stage ->
|
val origLoc = player.location
|
||||||
val courseIndex = if (stage == 5) 2 else -1
|
registerLogoutListener(player, "steppingstone"){p ->
|
||||||
val start = player.location
|
player.location = origLoc
|
||||||
val end = player.location.transform(-1, 0, 0)
|
|
||||||
val anim = Animation(741)
|
|
||||||
val xp = if (stage == 5) 20.0 else 0.0
|
|
||||||
val message = if (stage == 0) "You carefully start crossing the stepping stones..." else null
|
|
||||||
AgilityHandler.forceWalk(player, courseIndex, start, end, anim, 10, xp, message)
|
|
||||||
if (stage == 2 && fail) {
|
|
||||||
val dest = Location(3001, 3963, 0)
|
|
||||||
val failanim = Animation(771)
|
|
||||||
val hit = (player.skills.lifepoints * 0.26).toInt()
|
|
||||||
AgilityHandler.fail(player, -1, dest, failanim, hit, "... You lose your footing and fall into the lava.")
|
|
||||||
return@queueScript stopExecuting(player)
|
|
||||||
}
|
}
|
||||||
if (stage == 5) {
|
submitWorldPulse(object : Pulse(2, player){
|
||||||
|
var counter = 0
|
||||||
|
override fun pulse(): Boolean {
|
||||||
|
if (counter == 3 && fail) {
|
||||||
|
AgilityHandler.fail(player, -1, Location.create(3001, 3963, 0), Animation.create(771), (player.skills.lifepoints * 0.26).toInt(), "...You lose your footing and fall into the lava.")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
AgilityHandler.forceWalk(player, if (counter == 5) 2 else -1, player.location, player.location.transform(-1, 0, 0), Animation.create(741), 10, if (counter == 5) 20.0 else 0.0, if (counter != 0) null else "You carefully start crossing the stepping stones...")
|
||||||
|
if(++counter == 6){
|
||||||
unlock(player)
|
unlock(player)
|
||||||
return@queueScript stopExecuting(player)
|
clearLogoutListener(player, "steppingstone")
|
||||||
}
|
}
|
||||||
return@queueScript delayScript(player, 2)
|
return counter == 6
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,6 @@ import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.system.task.MovementHook;
|
import core.game.system.task.MovementHook;
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import core.net.packet.PacketRepository;
|
|
||||||
import core.net.packet.context.PlayerContext;
|
|
||||||
import core.net.packet.out.ClearMinimapFlag;
|
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import core.game.world.GameWorld;
|
import core.game.world.GameWorld;
|
||||||
import core.game.world.map.Direction;
|
import core.game.world.map.Direction;
|
||||||
|
|
@ -27,10 +24,6 @@ public final class BladeTrap implements MovementHook {
|
||||||
final Direction dir = e.getDirection();
|
final Direction dir = e.getDirection();
|
||||||
final Player player = (Player) e;
|
final Player player = (Player) e;
|
||||||
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
||||||
player.getPulseManager().clear();
|
|
||||||
player.getWalkingQueue().reset();
|
|
||||||
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player));
|
|
||||||
|
|
||||||
e.lock(5);
|
e.lock(5);
|
||||||
if(e.isPlayer())
|
if(e.isPlayer())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -237,32 +237,30 @@ public final class BrimhavenArena extends MapZone implements Plugin<Object> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (GameWorld.getTicks() % 100 == 0) {
|
if (GameWorld.getTicks() % 100 == 0) {
|
||||||
for (int z = 0; z < 4; z++) {
|
for (RegionPlane plane : r.getPlanes()) {
|
||||||
for (Player player : r.assemblePlayerList(z)) {
|
for (Player player : plane.getPlayers()) {
|
||||||
if (player != null) {
|
|
||||||
setDispenser(player);
|
setDispenser(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
handlePlankSwitching();
|
handlePlankSwitching();
|
||||||
}
|
}
|
||||||
int ticks = 3;
|
int ticks = 3;
|
||||||
if (GameWorld.getTicks() % ticks == 0) {
|
if (GameWorld.getTicks() % ticks == 0) {
|
||||||
sawBladeActive = !sawBladeActive;
|
sawBladeActive = !sawBladeActive;
|
||||||
if (sawBladeActive) {
|
if (sawBladeActive) {
|
||||||
Scenery object = RegionManager.getObject(2788, 9579, 3);
|
Scenery object = RegionManager.getObject(3, 2788, 9579);
|
||||||
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
|
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
|
||||||
object = RegionManager.getObject(2789, 9579, 3);
|
object = RegionManager.getObject(3, 2789, 9579);
|
||||||
SceneryBuilder.replace(object, object.transform(0), ticks);
|
SceneryBuilder.replace(object, object.transform(0), ticks);
|
||||||
|
|
||||||
object = RegionManager.getObject(2783, 9551, 3);
|
object = RegionManager.getObject(3, 2783, 9551);
|
||||||
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
|
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
|
||||||
object = RegionManager.getObject(2783, 9552, 3);
|
object = RegionManager.getObject(3, 2783, 9552);
|
||||||
SceneryBuilder.replace(object, object.transform(0), ticks);
|
SceneryBuilder.replace(object, object.transform(0), ticks);
|
||||||
|
|
||||||
object = RegionManager.getObject(2761, 9584, 3);
|
object = RegionManager.getObject(3, 2761, 9584);
|
||||||
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
|
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
|
||||||
object = RegionManager.getObject(2761, 9585, 3);
|
object = RegionManager.getObject(3, 2761, 9585);
|
||||||
SceneryBuilder.replace(object, object.transform(0), ticks);
|
SceneryBuilder.replace(object, object.transform(0), ticks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,8 +119,6 @@ public final class BrimhavenCourse extends OptionHandler {
|
||||||
final Direction dir = direction;
|
final Direction dir = direction;
|
||||||
final Direction faceDirection = Direction.get(object.getDirection().toInteger() - 1 & 3);
|
final Direction faceDirection = Direction.get(object.getDirection().toInteger() - 1 & 3);
|
||||||
final Location start = player.getLocation();
|
final Location start = player.getLocation();
|
||||||
player.setDirection(faceDirection);
|
|
||||||
player.faceLocation(start.transform(faceDirection));
|
|
||||||
player.getAppearance().setAnimations(Animation.create(1118 + m));
|
player.getAppearance().setAnimations(Animation.create(1118 + m));
|
||||||
player.getAppearance().sync();
|
player.getAppearance().sync();
|
||||||
AgilityHandler.climb(player, -1, new Animation(1117 + m), start.transform(dir), 0.0, null);
|
AgilityHandler.climb(player, -1, new Animation(1117 + m), start.transform(dir), 0.0, null);
|
||||||
|
|
@ -145,12 +143,12 @@ public final class BrimhavenCourse extends OptionHandler {
|
||||||
} else if (count == 6) {
|
} else if (count == 6) {
|
||||||
player.getAppearance().setAnimations();
|
player.getAppearance().setAnimations();
|
||||||
player.getAppearance().sync();
|
player.getAppearance().sync();
|
||||||
AgilityHandler.forceWalk(player, -1, last, last.transform(dir), Animation.create(1120 + m), 5, getExp(player, 22.0), null, faceDirection);
|
AgilityHandler.forceWalk(player, -1, last, last.transform(dir), Animation.create(1120 + m), 5, getExp(player, 22.0), null).setDirection(faceDirection);
|
||||||
player.logoutListeners.remove("brimcourse");
|
player.logoutListeners.remove("brimcourse");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
player.logoutListeners.remove("brimcourse");
|
player.logoutListeners.remove("brimcourse");
|
||||||
AgilityHandler.forceWalk(player, -1, last, last = last.transform(dir), Animation.create(1118 + m), 5, 0.0, null, faceDirection);
|
AgilityHandler.forceWalk(player, -1, last, last = last.transform(dir), Animation.create(1118 + m), 5, 0.0, null).setDirection(faceDirection);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -274,7 +272,7 @@ public final class BrimhavenCourse extends OptionHandler {
|
||||||
public boolean pulse() {
|
public boolean pulse() {
|
||||||
if (!finish) {
|
if (!finish) {
|
||||||
setDelay(2);
|
setDelay(2);
|
||||||
AgilityHandler.fail(player, 1, player.getLocation().transform(0, 0, -3), Animation.create(768), getHitAmount(player), "You stepped on a broken piece of plank!");
|
AgilityHandler.fail(player, 1, player.getLocation().transform(0, 0, -3), Animation.create(189), getHitAmount(player), "You stepped on a broken piece of plank!");
|
||||||
finish = true;
|
finish = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -284,7 +282,7 @@ public final class BrimhavenCourse extends OptionHandler {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AgilityHandler.walk(player, -1, start, end, Animation.create(1426), getExp(player, 6.0), null);
|
AgilityHandler.walk(player, -1, start, end, ForceMovement.WALK_ANIMATION, getExp(player, 6.0), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -391,7 +389,6 @@ public final class BrimhavenCourse extends OptionHandler {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3551:
|
case 3551:
|
||||||
case 3583:
|
|
||||||
return n.getLocation();
|
return n.getLocation();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import core.game.node.entity.impl.Projectile;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.system.task.MovementHook;
|
import core.game.system.task.MovementHook;
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import core.net.packet.context.PlayerContext;
|
|
||||||
import core.net.packet.out.ClearMinimapFlag;
|
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import core.game.world.GameWorld;
|
import core.game.world.GameWorld;
|
||||||
import core.game.world.map.Direction;
|
import core.game.world.map.Direction;
|
||||||
|
|
@ -31,9 +29,6 @@ public final class DartTrap implements MovementHook {
|
||||||
final Direction dir = e.getDirection();
|
final Direction dir = e.getDirection();
|
||||||
final Player player = (Player) e;
|
final Player player = (Player) e;
|
||||||
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
||||||
player.getPulseManager().clear();
|
|
||||||
player.getWalkingQueue().reset();
|
|
||||||
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player));
|
|
||||||
e.lock(6);
|
e.lock(6);
|
||||||
if(e.isPlayer())
|
if(e.isPlayer())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@ import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.system.task.MovementHook;
|
import core.game.system.task.MovementHook;
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import core.net.packet.PacketRepository;
|
|
||||||
import core.net.packet.context.PlayerContext;
|
|
||||||
import core.net.packet.out.ClearMinimapFlag;
|
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import core.game.world.GameWorld;
|
import core.game.world.GameWorld;
|
||||||
import core.game.world.map.Direction;
|
import core.game.world.map.Direction;
|
||||||
|
|
@ -27,9 +24,6 @@ public final class FloorSpikes implements MovementHook {
|
||||||
final Direction dir = e.getDirection();
|
final Direction dir = e.getDirection();
|
||||||
final Player player = (Player) e;
|
final Player player = (Player) e;
|
||||||
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
||||||
player.getPulseManager().clear();
|
|
||||||
player.getWalkingQueue().reset();
|
|
||||||
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player));
|
|
||||||
e.lock(5);
|
e.lock(5);
|
||||||
if(e.isPlayer())
|
if(e.isPlayer())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@ import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.system.task.MovementHook;
|
import core.game.system.task.MovementHook;
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import core.net.packet.PacketRepository;
|
|
||||||
import core.net.packet.context.PlayerContext;
|
|
||||||
import core.net.packet.out.ClearMinimapFlag;
|
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import core.game.world.GameWorld;
|
import core.game.world.GameWorld;
|
||||||
import core.game.world.map.Direction;
|
import core.game.world.map.Direction;
|
||||||
|
|
@ -27,10 +24,6 @@ public final class PressurePad implements MovementHook {
|
||||||
final Direction dir = e.getDirection();
|
final Direction dir = e.getDirection();
|
||||||
final Player player = (Player) e;
|
final Player player = (Player) e;
|
||||||
final Location start = dest.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
final Location start = dest.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
||||||
player.getPulseManager().clear();
|
|
||||||
player.getWalkingQueue().reset();
|
|
||||||
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player));
|
|
||||||
|
|
||||||
e.lock(5);
|
e.lock(5);
|
||||||
if(e.isPlayer())
|
if(e.isPlayer())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@ import core.game.node.entity.Entity;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.system.task.MovementHook;
|
import core.game.system.task.MovementHook;
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import core.net.packet.PacketRepository;
|
|
||||||
import core.net.packet.context.PlayerContext;
|
|
||||||
import core.net.packet.out.ClearMinimapFlag;
|
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import core.game.world.GameWorld;
|
import core.game.world.GameWorld;
|
||||||
import core.game.world.map.Direction;
|
import core.game.world.map.Direction;
|
||||||
|
|
@ -27,9 +24,6 @@ public final class SpinningBlades implements MovementHook {
|
||||||
final Direction dir = e.getDirection();
|
final Direction dir = e.getDirection();
|
||||||
final Player player = (Player) e;
|
final Player player = (Player) e;
|
||||||
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0);
|
||||||
player.getPulseManager().clear();
|
|
||||||
player.getWalkingQueue().reset();
|
|
||||||
PacketRepository.send(ClearMinimapFlag.class, new PlayerContext(player));
|
|
||||||
e.lock(5);
|
e.lock(5);
|
||||||
if(e.isPlayer())
|
if(e.isPlayer())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -65,16 +65,14 @@ public enum BuildHotspot {
|
||||||
* Low-level Work shop hotspots.
|
* Low-level Work shop hotspots.
|
||||||
*/
|
*/
|
||||||
REPAIR(15448, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.REPAIR_BENCH, Decoration.WHETSTONE, Decoration.ARMOUR_STAND),
|
REPAIR(15448, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.REPAIR_BENCH, Decoration.WHETSTONE, Decoration.ARMOUR_STAND),
|
||||||
WORKBENCH(15439, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE, Decoration.WORKBENCH_WITH_LATHE),
|
WORKBENCH(15439, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE,Decoration.WORKBENCH_WITH_LATHE),
|
||||||
CRAFTING(15441, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.CRAFTING_TABLE_1, Decoration.CRAFTING_TABLE_2,Decoration.CRAFTING_TABLE_3, Decoration.CRAFTING_TABLE_4),
|
CRAFTING(15441, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRAFTING_TABLE_1, Decoration.CRAFTING_TABLE_2,Decoration.CRAFTING_TABLE_3, Decoration.CRAFTING_TABLE_4),
|
||||||
TOOL1(15443, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5),
|
TOOL1(15443, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5),
|
||||||
TOOL2(15444, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
TOOL2(15444, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||||
TOOL3(15445, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
TOOL3(15445, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||||
TOOL4(15446, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
TOOL4(15446, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||||
TOOL5(15447, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
TOOL5(15447, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
|
||||||
HERALDRY(15450, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PLUMING_STAND, Decoration.SHIELD_EASEL,Decoration.BANNER_EASEL),
|
HERALDRY(15450, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PLUMING_STAND, Decoration.SHIELD_EASEL,Decoration.BANNER_EASEL),
|
||||||
WORKBENCH_STOOL(15440, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKSHOP_STOOL, Decoration.WORKSHOP_STOOL,Decoration.WORKSHOP_STOOL_OAK, Decoration.WORKSHOP_STOOL_OAK,Decoration.WORKSHOP_STOOL_OAK),
|
|
||||||
CRAFTING_STOOL(15442, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKSHOP_STOOL, Decoration.WORKSHOP_STOOL,Decoration.WORKSHOP_STOOL, Decoration.WORKSHOP_STOOL),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bedroom hotspots.
|
* Bedroom hotspots.
|
||||||
|
|
@ -388,8 +386,6 @@ public enum BuildHotspot {
|
||||||
linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT2, DUNGEON_DOOR_RIGHT2 });
|
linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT2, DUNGEON_DOOR_RIGHT2 });
|
||||||
linkedHotspots.add(new BuildHotspot[] { SMALL_PLANT_1, SMALL_PLANT1 });
|
linkedHotspots.add(new BuildHotspot[] { SMALL_PLANT_1, SMALL_PLANT1 });
|
||||||
linkedHotspots.add(new BuildHotspot[] { SHELVES, SHELVES_2 });
|
linkedHotspots.add(new BuildHotspot[] { SHELVES, SHELVES_2 });
|
||||||
linkedHotspots.add(new BuildHotspot[] { WORKBENCH, WORKBENCH_STOOL });
|
|
||||||
linkedHotspots.add(new BuildHotspot[] { CRAFTING, CRAFTING_STOOL });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,13 @@ import core.game.interaction.OptionHandler;
|
||||||
import core.game.node.Node;
|
import core.game.node.Node;
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.node.scenery.Scenery;
|
import core.game.node.scenery.Scenery;
|
||||||
import core.game.world.map.Location;
|
|
||||||
import core.game.world.map.RegionManager;
|
|
||||||
import core.plugin.Initializable;
|
import core.plugin.Initializable;
|
||||||
import core.plugin.Plugin;
|
import core.plugin.Plugin;
|
||||||
import core.tools.Log;
|
import core.tools.Log;
|
||||||
|
import core.tools.SystemLogger;
|
||||||
import core.plugin.ClassScanner;
|
import core.plugin.ClassScanner;
|
||||||
|
|
||||||
import static core.api.ContentAPIKt.log;
|
import static core.api.ContentAPIKt.log;
|
||||||
import static core.api.ContentAPIKt.setAttribute;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The build option handling plugin.
|
* The build option handling plugin.
|
||||||
|
|
@ -50,7 +48,7 @@ public final class BuildOptionPlugin extends OptionHandler {
|
||||||
player.getDialogueInterpreter().open("con:removedec", object);
|
player.getDialogueInterpreter().open("con:removedec", object);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
setAttribute(player, ConstructionInterface.ATTRIBUTE_HOTSPOT_OBJ, node);
|
player.setAttribute("con:hsobject", node);
|
||||||
if (BuildingUtils.isDoorHotspot(object)) {
|
if (BuildingUtils.isDoorHotspot(object)) {
|
||||||
int[] pos = BuildingUtils.roomExists(player, object);
|
int[] pos = BuildingUtils.roomExists(player, object);
|
||||||
if (pos != null) {
|
if (pos != null) {
|
||||||
|
|
@ -73,30 +71,8 @@ public final class BuildOptionPlugin extends OptionHandler {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildHotspot buildHotspot = hotspot.getHotspot();
|
player.setAttribute("con:hotspot", hotspot);
|
||||||
BuildHotspot[] linked = BuildHotspot.getLinkedHotspots(buildHotspot);
|
BuildingUtils.openBuildInterface(player, hotspot.getHotspot());
|
||||||
if (linked != null && linked[0] != buildHotspot) {
|
|
||||||
Location locObj = object.getLocation();
|
|
||||||
Room room = player.getHouseManager().getRoom(locObj);
|
|
||||||
if (room == null) return true;
|
|
||||||
for (Hotspot h : room.getHotspots()) {
|
|
||||||
if (h.getHotspot() == linked[0]) {
|
|
||||||
int dx = h.getCurrentX() - locObj.getChunkOffsetX();
|
|
||||||
int dy = h.getCurrentY() - locObj.getChunkOffsetY();
|
|
||||||
Scenery primaryObj = RegionManager.getObject(locObj.transform(dx, dy, 0));
|
|
||||||
if (primaryObj != null) {
|
|
||||||
setAttribute(player, ConstructionInterface.ATTRIBUTE_HOTSPOT_OBJ, primaryObj);
|
|
||||||
setAttribute(player, ConstructionInterface.ATTRIBUTE_HOTSPOT, h);
|
|
||||||
BuildingUtils.openBuildInterface(player, linked[0]);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttribute(player, ConstructionInterface.ATTRIBUTE_HOTSPOT, hotspot);
|
|
||||||
BuildingUtils.openBuildInterface(player, buildHotspot);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package content.global.skill.construction;
|
package content.global.skill.construction;
|
||||||
|
|
||||||
|
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
import core.game.node.item.Item;
|
import core.game.node.item.Item;
|
||||||
import core.game.node.scenery.Scenery;
|
import core.game.node.scenery.Scenery;
|
||||||
|
|
@ -17,9 +18,6 @@ import java.awt.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static core.api.ContentAPIKt.getAttribute;
|
|
||||||
import static core.game.world.map.RegionChunk.getRotatedPosition;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the building a room dialogue.
|
* Handles the building a room dialogue.
|
||||||
* @author Emperor
|
* @author Emperor
|
||||||
|
|
@ -27,6 +25,7 @@ import static core.game.world.map.RegionChunk.getRotatedPosition;
|
||||||
*/
|
*/
|
||||||
@Initializable
|
@Initializable
|
||||||
public final class BuildRoomDialogue extends DialoguePlugin {
|
public final class BuildRoomDialogue extends DialoguePlugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The door hotspot.
|
* The door hotspot.
|
||||||
*/
|
*/
|
||||||
|
|
@ -50,7 +49,7 @@ public final class BuildRoomDialogue extends DialoguePlugin {
|
||||||
/**
|
/**
|
||||||
* The boundaries of the room to build.
|
* The boundaries of the room to build.
|
||||||
*/
|
*/
|
||||||
private final List<Scenery> boundaries = new ArrayList<>(20);
|
private List<Scenery> boundaries = new ArrayList<>(20);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The room we're building.
|
* The room we're building.
|
||||||
|
|
@ -106,7 +105,7 @@ public final class BuildRoomDialogue extends DialoguePlugin {
|
||||||
stage = 2;
|
stage = 2;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
this.door = getAttribute(player, ConstructionInterface.ATTRIBUTE_HOTSPOT_OBJ, null);
|
this.door = (Scenery) player.getAttribute("con:hsobject");
|
||||||
int[] pos = BuildingUtils.getRoomPosition(player, door);
|
int[] pos = BuildingUtils.getRoomPosition(player, door);
|
||||||
roomX = pos[0];
|
roomX = pos[0];
|
||||||
roomY = pos[1];
|
roomY = pos[1];
|
||||||
|
|
@ -240,18 +239,15 @@ public final class BuildRoomDialogue extends DialoguePlugin {
|
||||||
for (Scenery object : boundaries) {
|
for (Scenery object : boundaries) {
|
||||||
SceneryBuilder.remove(object);
|
SceneryBuilder.remove(object);
|
||||||
}
|
}
|
||||||
boundaries.clear();
|
|
||||||
int rotation = directions[index].toInteger();
|
int rotation = directions[index].toInteger();
|
||||||
Location base = player.getLocation().getRegion().getBaseLocation().transform(roomX << 3, roomY << 3, player.getLocation().getZ());
|
boundaries.clear();
|
||||||
for (int x = 0; x < RegionChunk.SIZE; x++) {
|
Location base = player.getViewport().getRegion().getBaseLocation().transform(roomX << 3, roomY << 3, player.getLocation().getZ());
|
||||||
for (int y = 0; y < RegionChunk.SIZE; y++) {
|
for (int x = 0; x < 8; x++) {
|
||||||
for (int i = 0; i < RegionChunk.ARRAY_SIZE; i++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
Scenery object = room.getChunk().getObjects(x, y)[i];
|
Scenery[] objects = room.getChunk().getObjects(x, y);
|
||||||
|
for (Scenery object : objects) {
|
||||||
if (object != null && object.getDefinition().hasAction("build")) {
|
if (object != null && object.getDefinition().hasAction("build")) {
|
||||||
if (object.getLayer() == Scenery.Layer.WALL && !BuildingUtils.isDoorHotspot(object)) {
|
int[] pos = RegionChunk.getRotatedPosition(x, y, object.getDefinition().getSizeX(), object.getDefinition().getSizeY(), object.getRotation(), rotation);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int[] pos = getRotatedPosition(x, y, object.getDefinition().getSizeX(), object.getDefinition().getSizeY(), object.getRotation(), rotation);
|
|
||||||
Scenery obj = object.transform(object.getId(), (object.getRotation() + rotation) % 4, base.transform(pos[0], pos[1], 0));
|
Scenery obj = object.transform(object.getId(), (object.getRotation() + rotation) % 4, base.transform(pos[0], pos[1], 0));
|
||||||
boundaries.add(SceneryBuilder.add(obj));
|
boundaries.add(SceneryBuilder.add(obj));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,10 @@ import core.game.node.item.Item;
|
||||||
import core.game.node.scenery.Scenery;
|
import core.game.node.scenery.Scenery;
|
||||||
import core.game.node.scenery.SceneryBuilder;
|
import core.game.node.scenery.SceneryBuilder;
|
||||||
import core.game.system.task.Pulse;
|
import core.game.system.task.Pulse;
|
||||||
import core.game.world.map.*;
|
import core.game.world.map.BuildRegionChunk;
|
||||||
|
import core.game.world.map.Direction;
|
||||||
|
import core.game.world.map.Location;
|
||||||
|
import core.game.world.map.Region;
|
||||||
import core.game.world.update.flag.context.Animation;
|
import core.game.world.update.flag.context.Animation;
|
||||||
import core.net.packet.PacketRepository;
|
import core.net.packet.PacketRepository;
|
||||||
import core.net.packet.context.ContainerContext;
|
import core.net.packet.context.ContainerContext;
|
||||||
|
|
@ -136,13 +139,9 @@ public final class BuildingUtils {
|
||||||
* @param object The object.
|
* @param object The object.
|
||||||
*/
|
*/
|
||||||
public static void buildDecoration(final Player player, final Hotspot hotspot, final Decoration deco, final Scenery object) {
|
public static void buildDecoration(final Player player, final Hotspot hotspot, final Decoration deco, final Scenery object) {
|
||||||
buildDecoration(player, hotspot, deco, object, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void buildDecoration(final Player player, final Hotspot hotspot, final Decoration deco, final Scenery object, final boolean bypassCost, final boolean bypassXp) {
|
|
||||||
final int nailAmount = deco.getNailAmount();
|
final int nailAmount = deco.getNailAmount();
|
||||||
final NailType type = nailAmount > 0 ? NailType.get(player, nailAmount) : null;
|
final NailType type = nailAmount > 0 ? NailType.get(player, nailAmount) : null;
|
||||||
if (nailAmount > 0 && type == null && !bypassCost) {
|
if (nailAmount > 0 && type == null) {
|
||||||
player.getPacketDispatch().sendMessage("You don't have the right materials.");
|
player.getPacketDispatch().sendMessage("You don't have the right materials.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +165,7 @@ public final class BuildingUtils {
|
||||||
NailType nail = type;
|
NailType nail = type;
|
||||||
@Override
|
@Override
|
||||||
public boolean pulse() {
|
public boolean pulse() {
|
||||||
if (nails > 0 && !bypassCost) {
|
if (nails > 0) {
|
||||||
if (!type.isBend()) {
|
if (!type.isBend()) {
|
||||||
player.getPacketDispatch().sendMessage("You use a nail.");
|
player.getPacketDispatch().sendMessage("You use a nail.");
|
||||||
nails--;
|
nails--;
|
||||||
|
|
@ -190,15 +189,13 @@ public final class BuildingUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bypassCost || player.isAdmin() || player.getInventory().remove(deco.getItems())) {
|
if (player.getInventory().remove(deco.getItems()) || player.isAdmin()) {
|
||||||
setDecoration(player, r, room, hotspot, object, deco);
|
setDecoration(player, r, room, hotspot, object, deco);
|
||||||
if (!bypassXp) {
|
|
||||||
player.getSkills().addExperience(Skills.CONSTRUCTION, deco.getExperience(), true);
|
player.getSkills().addExperience(Skills.CONSTRUCTION, deco.getExperience(), true);
|
||||||
|
|
||||||
if (getObjectIdsThatGiveFarmingExperience().contains(deco.getObjectId())) {
|
if (getObjectIdsThatGiveFarmingExperience().contains(deco.getObjectId())) {
|
||||||
player.getSkills().addExperience(Skills.FARMING, deco.getExperience(), true);
|
player.getSkills().addExperience(Skills.FARMING, deco.getExperience(), true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
player.unlock();
|
player.unlock();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -253,7 +250,7 @@ public final class BuildingUtils {
|
||||||
if (reg == null) {
|
if (reg == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RegionChunk chunk = reg.getChunks()[l.getChunkX()][l.getChunkY()][plane % 3];
|
BuildRegionChunk chunk = (BuildRegionChunk) reg.getPlanes()[plane % 3].getChunks()[l.getChunkX()][l.getChunkY()];
|
||||||
Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY());
|
Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY());
|
||||||
for (Scenery o : objects) {
|
for (Scenery o : objects) {
|
||||||
if (o != null && o.getType() == object.getType()) {
|
if (o != null && o.getType() == object.getType()) {
|
||||||
|
|
@ -287,27 +284,24 @@ public final class BuildingUtils {
|
||||||
hotspot.setDecorationIndex(decIndex);
|
hotspot.setDecorationIndex(decIndex);
|
||||||
break;
|
break;
|
||||||
case RECURSIVE:
|
case RECURSIVE:
|
||||||
RegionChunk chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
|
BuildRegionChunk chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
|
||||||
for (int x = 0; x < 8; x++) {
|
for (int x = 0; x < 8; x++) {
|
||||||
for (int y = 0; y < 8; y++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y);
|
Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y);
|
||||||
if (h != null) {
|
if (h != null) {
|
||||||
h.setDecorationIndex(decIndex);
|
h.setDecorationIndex(decIndex);
|
||||||
int objectId = hotspot.getHotspot().getObjectId(style);
|
int objectId = hotspot.getHotspot().getObjectId(style);
|
||||||
int index = chunk.getIndex(x, y, objectId, -1);
|
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
|
||||||
if (index != -1) {
|
if (o != null && objectId == o.getId()) {
|
||||||
Scenery o = chunk.getObjects()[x][y][index];
|
|
||||||
if (objectId == o.getId()) {
|
|
||||||
SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getDecorations()[decIndex].getObjectId(style)));
|
SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getDecorations()[decIndex].getObjectId(style)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case LINKED:
|
case LINKED:
|
||||||
BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot());
|
BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot());
|
||||||
chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
|
chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
|
||||||
for (int x = 0; x < 8; x++) {
|
for (int x = 0; x < 8; x++) {
|
||||||
for (int y = 0; y < 8; y++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
for (BuildHotspot bh : linkedHotspots) {
|
for (BuildHotspot bh : linkedHotspots) {
|
||||||
|
|
@ -315,17 +309,14 @@ public final class BuildingUtils {
|
||||||
if (h != null) {
|
if (h != null) {
|
||||||
h.setDecorationIndex(decIndex);
|
h.setDecorationIndex(decIndex);
|
||||||
int objectId = bh.getObjectId(style);
|
int objectId = bh.getObjectId(style);
|
||||||
int index = chunk.getIndex(x, y, objectId, -1);
|
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
|
||||||
if (index != -1) {
|
if (o != null && objectId == o.getId()) {
|
||||||
Scenery o = chunk.getObjects()[x][y][index];
|
|
||||||
if (objectId == o.getId()) {
|
|
||||||
SceneryBuilder.replace(o, o.transform(bh.getDecorations()[decIndex].getObjectId(style)));
|
SceneryBuilder.replace(o, o.transform(bh.getDecorations()[decIndex].getObjectId(style)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -394,7 +385,7 @@ public final class BuildingUtils {
|
||||||
if (reg == null) {
|
if (reg == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RegionChunk chunk = reg.getChunks()[l.getChunkX()][l.getChunkY()][plane % 3];
|
BuildRegionChunk chunk = (BuildRegionChunk) reg.getPlanes()[plane % 3].getChunks()[l.getChunkX()][l.getChunkY()];
|
||||||
Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY());
|
Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY());
|
||||||
for (Scenery o : objects) {
|
for (Scenery o : objects) {
|
||||||
if (o != null && o.getType() == object.getType()) {
|
if (o != null && o.getType() == object.getType()) {
|
||||||
|
|
@ -426,18 +417,14 @@ public final class BuildingUtils {
|
||||||
hotspot.setDecorationIndex(-1);
|
hotspot.setDecorationIndex(-1);
|
||||||
break;
|
break;
|
||||||
case RECURSIVE:
|
case RECURSIVE:
|
||||||
RegionChunk chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
|
BuildRegionChunk chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
|
||||||
for (int x = 0; x < 8; x++) {
|
for (int x = 0; x < 8; x++) {
|
||||||
for (int y = 0; y < 8; y++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y);
|
Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y);
|
||||||
if (h != null) {
|
if (h != null) {
|
||||||
int objectId = hotspot.getHotspot().getDecorations()[h.getDecorationIndex()].getObjectId(style);
|
int objectId = hotspot.getHotspot().getDecorations()[h.getDecorationIndex()].getObjectId(style);
|
||||||
int index = chunk.getIndex(x, y, objectId, -1);
|
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
|
||||||
h.setDecorationIndex(-1);
|
h.setDecorationIndex(-1);
|
||||||
if (index == -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Scenery o = chunk.getObjects()[x][y][index];
|
|
||||||
if (o != null && objectId == o.getId()) {
|
if (o != null && objectId == o.getId()) {
|
||||||
SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getObjectId(style)));
|
SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getObjectId(style)));
|
||||||
}
|
}
|
||||||
|
|
@ -447,19 +434,15 @@ public final class BuildingUtils {
|
||||||
break;
|
break;
|
||||||
case LINKED:
|
case LINKED:
|
||||||
BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot());
|
BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot());
|
||||||
chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
|
chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
|
||||||
for (int x = 0; x < 8; x++) {
|
for (int x = 0; x < 8; x++) {
|
||||||
for (int y = 0; y < 8; y++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
for (BuildHotspot bh : linkedHotspots) {
|
for (BuildHotspot bh : linkedHotspots) {
|
||||||
Hotspot h = room.getHotspot(bh, x, y);
|
Hotspot h = room.getHotspot(bh, x, y);
|
||||||
if (h != null && h.getDecorationIndex() >= 0) {
|
if (h != null) {
|
||||||
int objectId = bh.getDecorations()[h.getDecorationIndex()].getObjectId(style);
|
int objectId = bh.getDecorations()[h.getDecorationIndex()].getObjectId(style);
|
||||||
|
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
|
||||||
h.setDecorationIndex(-1);
|
h.setDecorationIndex(-1);
|
||||||
int index = chunk.getIndex(x, y, objectId, -1);
|
|
||||||
if (index == -1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Scenery o = chunk.getObjects()[x][y][index];
|
|
||||||
if (o != null && objectId == o.getId()) {
|
if (o != null && objectId == o.getId()) {
|
||||||
SceneryBuilder.replace(o, o.transform(bh.getObjectId(style)));
|
SceneryBuilder.replace(o, o.transform(bh.getObjectId(style)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
package content.global.skill.construction;
|
||||||
|
|
||||||
|
|
||||||
|
import core.cache.def.impl.ItemDefinition;
|
||||||
|
import core.game.component.Component;
|
||||||
|
import core.game.component.ComponentDefinition;
|
||||||
|
import core.game.component.ComponentPlugin;
|
||||||
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.node.entity.skill.Skills;
|
||||||
|
import core.game.node.scenery.Scenery;
|
||||||
|
import core.plugin.Initializable;
|
||||||
|
import core.plugin.Plugin;
|
||||||
|
import core.tools.Log;
|
||||||
|
import core.tools.SystemLogger;
|
||||||
|
|
||||||
|
import static core.api.ContentAPIKt.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the creating of a decoration object.
|
||||||
|
* @author Emperor
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Initializable
|
||||||
|
public final class ConstructionInterface extends ComponentPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Plugin<Object> newInstance(Object arg) {
|
||||||
|
ComponentDefinition.put(396, this);
|
||||||
|
ComponentDefinition.put(398, this);
|
||||||
|
ComponentDefinition.put(402, this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||||
|
switch (component.getId()) {
|
||||||
|
case 396:
|
||||||
|
switch (button) {
|
||||||
|
case 132:
|
||||||
|
player.getInterfaceManager().close();
|
||||||
|
Hotspot hotspot = player.getAttribute("con:hotspot");
|
||||||
|
Scenery object = player.getAttribute("con:hsobject");
|
||||||
|
if (hotspot == null || object == null) {
|
||||||
|
log(this.getClass(), Log.ERR, "Failed building decoration " + hotspot + " : " + object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
slot = ((slot % 2 != 0) ? 4 : 0) + (slot >> 1);
|
||||||
|
if (slot >= hotspot.getHotspot().getDecorations().length) {
|
||||||
|
log(this.getClass(), Log.ERR, "Failed building decoration " + slot + "/" + hotspot.getHotspot().getDecorations().length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
boolean debug = player.isStaff();
|
||||||
|
Decoration deco = hotspot.getHotspot().getDecorations()[slot];
|
||||||
|
if (!debug) {
|
||||||
|
if (player.getSkills().getLevel(Skills.CONSTRUCTION) < deco.getLevel()) {
|
||||||
|
player.sendMessage("You need to have a Construction level of " + deco.getLevel() + " to build that.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!player.getInventory().containsItems(deco.getItems())) {
|
||||||
|
player.sendMessage("You don't have the right materials.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (int tool : deco.getTools()) {
|
||||||
|
if (tool == BuildingUtils.WATERING_CAN) {
|
||||||
|
boolean hasWateringCan = false;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
if (player.getInventory().contains(tool - i, 1)) {
|
||||||
|
hasWateringCan = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasWateringCan) {
|
||||||
|
player.sendMessage("You need a watering can to plant this.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!player.getInventory().contains(tool, 1)) {
|
||||||
|
player.sendMessage("You need a " + ItemDefinition.forId(tool).getName() + " to build this.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuildingUtils.buildDecoration(player, hotspot, deco, object);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 398:
|
||||||
|
switch (button) {
|
||||||
|
case 14:
|
||||||
|
player.getHouseManager().toggleBuildingMode(player, true);
|
||||||
|
return true;
|
||||||
|
case 1:
|
||||||
|
player.getHouseManager().toggleBuildingMode(player, false);
|
||||||
|
return true;
|
||||||
|
case 15:
|
||||||
|
player.getHouseManager().expelGuests(player);
|
||||||
|
return true;
|
||||||
|
case 13:
|
||||||
|
if (!player.getHouseManager().isInHouse(player)) {
|
||||||
|
player.sendMessage("You can't do this outside of your house.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
HouseManager.leave(player);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 402:
|
||||||
|
int index = button - 160;
|
||||||
|
log(this.getClass(), Log.FINE, "BuildRoom Interface Index: " + index);
|
||||||
|
if (index > -1 && index < RoomProperties.values().length) {
|
||||||
|
player.getDialogueInterpreter().open("con:room", RoomProperties.values()[index]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
package content.global.skill.construction
|
|
||||||
|
|
||||||
import content.global.skill.construction.decoration.workshop.WorkbenchListeners
|
|
||||||
import core.api.*
|
|
||||||
import core.cache.def.impl.ItemDefinition
|
|
||||||
import core.game.interaction.InterfaceListener
|
|
||||||
import core.game.node.entity.skill.Skills
|
|
||||||
import core.game.node.scenery.Scenery
|
|
||||||
import core.tools.Log
|
|
||||||
import org.rs09.consts.Components
|
|
||||||
import org.rs09.consts.Scenery as SceneryObj
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles three interfaces related to the Construction skill, namely those which allow a player to build decorations,
|
|
||||||
* toggle building mode/expel guests, and select a room to add to the POH.
|
|
||||||
* @author Bishop
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ConstructionInterface : InterfaceListener {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val ATTRIBUTE_HOTSPOT = "con:hotspot"
|
|
||||||
const val ATTRIBUTE_HOTSPOT_OBJ = "con:hsobject"
|
|
||||||
private const val DECO_BUTTON_BUILD = 132
|
|
||||||
private const val HOUSE_BUTTON_BUILDMODE_ON = 14
|
|
||||||
private const val HOUSE_BUTTON_BUILDMODE_OFF = 1
|
|
||||||
private const val HOUSE_BUTTON_EXPEL_GUESTS = 15
|
|
||||||
private const val HOUSE_BUTTON_LEAVE_HOUSE = 13
|
|
||||||
|
|
||||||
// Register furniture here when it is only obtainable by upgrading, to send the correct rejection message.
|
|
||||||
private val upgradeOnly = arrayOf(
|
|
||||||
Decoration.WORKBENCH_WITH_VICE,
|
|
||||||
Decoration.WORKBENCH_WITH_LATHE,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun defineInterfaceListeners() {
|
|
||||||
/**
|
|
||||||
* Handles the interface for selecting a decoration to build.
|
|
||||||
*/
|
|
||||||
on(Components.POH_DECORATION_396) { player, _, _, buttonID, slot, _ ->
|
|
||||||
when (buttonID) {
|
|
||||||
DECO_BUTTON_BUILD -> {
|
|
||||||
val hotspot = getAttribute<Hotspot?>(player, ATTRIBUTE_HOTSPOT, null)
|
|
||||||
val hotspotObj = getAttribute<Scenery?>(player, ATTRIBUTE_HOTSPOT_OBJ, null)
|
|
||||||
val flatpackMode = getAttribute(player, WorkbenchListeners.ATTRIBUTE_FLATPACK_MODE, false)
|
|
||||||
if (!flatpackMode) {
|
|
||||||
closeInterface(player)
|
|
||||||
}
|
|
||||||
if ((hotspot == null || hotspotObj == null) && !flatpackMode) {
|
|
||||||
log(this.javaClass, Log.ERR, "Failed building decoration $hotspot : $hotspotObj")
|
|
||||||
return@on false
|
|
||||||
}
|
|
||||||
// Translates slot data to index data, as slots are not in order of level requirement in the interface, but decoration data is organized that way
|
|
||||||
val decoIndex = (if (slot % 2 != 0) 4 else 0) + (slot shr 1)
|
|
||||||
val buildHotspot = if (flatpackMode) {
|
|
||||||
getAttribute<BuildHotspot?>(player, WorkbenchListeners.ATTRIBUTE_WORKBENCH_SELECTION, null)?: return@on false
|
|
||||||
} else {
|
|
||||||
hotspot!!.hotspot
|
|
||||||
}
|
|
||||||
if (decoIndex >= buildHotspot.decorations.size) {
|
|
||||||
return@on false
|
|
||||||
}
|
|
||||||
val deco = buildHotspot.decorations[decoIndex]
|
|
||||||
if (!player.isAdmin) {
|
|
||||||
if (getDynLevel(player, Skills.CONSTRUCTION) < deco.level) {
|
|
||||||
closeInterface(player)
|
|
||||||
sendMessage(player, "You need to have a Construction level of ${deco.level} to build that.")
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
if (deco in upgradeOnly) {
|
|
||||||
closeInterface(player)
|
|
||||||
sendMessage(player, "That can only be built by upgrading the previous piece of furniture.")
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
if (!player.inventory.containsItems(*deco.items)) { // No clean ContentAPI substitute for this
|
|
||||||
closeInterface(player)
|
|
||||||
sendMessage(player, "You don't have the right materials.")
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
for (tool in deco.tools) {
|
|
||||||
if (tool == BuildingUtils.WATERING_CAN) {
|
|
||||||
var hasWaterInCan = false
|
|
||||||
for (i in 0..8) {
|
|
||||||
if (inInventory(player, tool - i)) {
|
|
||||||
hasWaterInCan = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasWaterInCan) {
|
|
||||||
sendMessage(player, "You need a watering can to plant this.")
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (!inInventory(player, tool)) {
|
|
||||||
closeInterface(player)
|
|
||||||
sendMessage(player, "You need a ${ItemDefinition.forId(tool).name} to build this.")
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flatpackMode && WorkbenchListeners.getBenchLevel(getAttribute(player, WorkbenchListeners.ATTRIBUTE_WORKBENCH_ID, SceneryObj.WORKBENCH_13704)) < deco.level) {
|
|
||||||
closeInterface(player)
|
|
||||||
sendMessage(player, "You cannot make this with this workbench.") // TODO: Find authentic text
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flatpackMode) {
|
|
||||||
WorkbenchListeners.produceFlatpack(player, deco)
|
|
||||||
} else {
|
|
||||||
BuildingUtils.buildDecoration(player, hotspot, deco, hotspotObj)
|
|
||||||
}
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
else -> return@on false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the interface for managing building mode and POH guests.
|
|
||||||
*/
|
|
||||||
on(Components.POH_HOUSE_OPTIONS_398) { player, _, _, buttonID, _, _ ->
|
|
||||||
when (buttonID) {
|
|
||||||
HOUSE_BUTTON_BUILDMODE_ON -> {
|
|
||||||
player.houseManager.toggleBuildingMode(player, true)
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
HOUSE_BUTTON_BUILDMODE_OFF -> {
|
|
||||||
player.houseManager.toggleBuildingMode(player, false)
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
HOUSE_BUTTON_EXPEL_GUESTS -> {
|
|
||||||
player.houseManager.expelGuests(player)
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
HOUSE_BUTTON_LEAVE_HOUSE -> {
|
|
||||||
if (!player.houseManager.isInHouse(player)) {
|
|
||||||
sendMessage(player, "You can't do this outside of your house.")
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
HouseManager.leave(player)
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
else -> return@on false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the interface for selecting a new room to add to a POH.
|
|
||||||
*/
|
|
||||||
on(Components.POH_ROOMS_402) { player, _, _, buttonID, _, _ ->
|
|
||||||
val index = buttonID - 160
|
|
||||||
if (index > -1 && index < RoomProperties.values().size) {
|
|
||||||
player.dialogueInterpreter.open("con:room", RoomProperties.values()[index]) // ContentAPI impl won't work for this
|
|
||||||
}
|
|
||||||
return@on true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -74,13 +74,13 @@ public enum Decoration {
|
||||||
/**
|
/**
|
||||||
* Parlour chair spot
|
* Parlour chair spot
|
||||||
*/
|
*/
|
||||||
CRUDE_CHAIR (13581, 8309, 1, 58, new Item[] { new Item(Items.PLANK_960, 2) }, Items.CRUDE_WOODEN_CHAIR_8496),
|
CRUDE_CHAIR (13581, 8309, 1, 58, new Item[] { new Item(Items.PLANK_960, 2) }),
|
||||||
WOODEN_CHAIR (13582, 8310, 8, 87, new Item[] { new Item(Items.PLANK_960, 3) }, Items.WOODEN_CHAIR_8498),
|
WOODEN_CHAIR (13582, 8310, 8, 87, new Item[] { new Item(Items.PLANK_960, 3) }),
|
||||||
ROCKING_CHAIR (13583, 8311, 14, 87, new Item[] { new Item(Items.PLANK_960, 3) }, Items.ROCKING_CHAIR_8500),
|
ROCKING_CHAIR (13583, 8311, 14, 87, new Item[] { new Item(Items.PLANK_960, 3) }),
|
||||||
OAK_CHAIR (13584, 8312, 19, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }, Items.OAK_CHAIR_8502),
|
OAK_CHAIR (13584, 8312, 19, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }),
|
||||||
OAK_ARMCHAIR (13585, 8313, 26, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }, Items.OAK_ARMCHAIR_8504),
|
OAK_ARMCHAIR (13585, 8313, 26, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }),
|
||||||
TEAK_ARMCHAIR (13586, 8314, 35, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }, Items.TEAK_ARMCHAIR_8506),
|
TEAK_ARMCHAIR (13586, 8314, 35, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }),
|
||||||
MAHOGANY_ARMCHAIR(13587, 8315, 50, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }, Items.MAHOGANY_ARMCHAIR_8508),
|
MAHOGANY_ARMCHAIR(13587, 8315, 50, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rugs rugs rugs
|
* Rugs rugs rugs
|
||||||
|
|
@ -112,26 +112,29 @@ public enum Decoration {
|
||||||
/**
|
/**
|
||||||
* Bookcases
|
* Bookcases
|
||||||
*/
|
*/
|
||||||
WOODEN_BOOKCASE (13597, 8319, 4, 115, new Item[] { new Item(Items.PLANK_960, 4) }, Items.WOODEN_BOOKCASE_8510),
|
WOODEN_BOOKCASE (13597, 8319, 4, 115, new Item[] { new Item(Items.PLANK_960, 4) }),
|
||||||
OAK_BOOKCASE (13598, 8320, 29, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }, Items.OAK_BOOKCASE_8512),
|
OAK_BOOKCASE (13598, 8320, 29, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }),
|
||||||
MAHOGANY_BOOKCASE(13599, 8321, 40, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }, Items.MAHOGANY_BKCASE_8514),
|
MAHOGANY_BOOKCASE(13599, 8321, 40, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kitchen Beer Barrels
|
* Kitchen Beer Barrels
|
||||||
|
* TODO: These also require cooking levels!
|
||||||
|
* Basic: 1, Cider: 14, Asgarnian: 24, Greenman's: 29, D.Bitter: 39, Chef's: 54
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
BASIC_BEER_BARREL (13568, 8239, 7, 87, new Item[] { new Item(Items.PLANK_960, 3) }, Items.BEER_BARREL_8516),
|
BASIC_BEER_BARREL (13568, 8239, 7, 87, new Item[] { new Item(Items.PLANK_960, 3) }),
|
||||||
CIDER_BARREL (13569, 8240, 12, 91, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.CIDER_5763, 8) }, Items.CIDER_BARREL_8518),
|
CIDER_BARREL (13569, 8240, 12, 91, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.CIDER_5763, 8) }),
|
||||||
ASGARNIAN_ALE_BARREL(13570, 8241, 18, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.ASGARNIAN_ALE_1905, 8) }, Items.ASGARNIAN_ALE_8520),
|
ASGARNIAN_ALE_BARREL(13570, 8241, 18, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.ASGARNIAN_ALE_1905, 8) }),
|
||||||
GREENMANS_ALE_BARREL(13571, 8242, 26, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.GREENMANS_ALE_1909, 8) }, Items.GREENMANS_ALE_8522),
|
GREENMANS_ALE_BARREL(13571, 8242, 26, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.GREENMANS_ALE_1909, 8) }),
|
||||||
DRAGON_BITTER_BARREL(13572, 8243, 36, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.DRAGON_BITTER_1911, 8), new Item(Items.STEEL_BAR_2353, 2) }, Items.DRAGON_BITTER_8524),
|
DRAGON_BITTER_BARREL(13572, 8243, 36, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.DRAGON_BITTER_1911, 8), new Item(Items.STEEL_BAR_2353, 2) }),
|
||||||
CHEFS_DELIGHT_BARREL(13573, 8244, 48, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.CHEFS_DELIGHT_5755, 8), new Item(Items.STEEL_BAR_2353, 2) }, Items.CHEFS_DELIGHT_8526),
|
CHEFS_DELIGHT_BARREL(13573, 8244, 48, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.CHEFS_DELIGHT_5755, 8), new Item(Items.STEEL_BAR_2353, 2) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kitchen Tables!
|
* Kitchen Tables!
|
||||||
*/
|
*/
|
||||||
KITCHEN_WOODEN_TABLE(13577, 8246, 12, 87, new Item[] { new Item(Items.PLANK_960, 3) }, Items.WOOD_KITCHEN_TABLE_8528),
|
KITCHEN_WOODEN_TABLE(13577, 8246, 12, 87, new Item[] { new Item(Items.PLANK_960, 3) }),
|
||||||
KITCHEN_OAK_TABLE (13578, 8247, 32, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }, Items.OAK_KITCHEN_TABLE_8530),
|
KITCHEN_OAK_TABLE (13578, 8247, 32, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }),
|
||||||
KITCHEN_TEAK_TABLE (13579, 8248, 52, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }, Items.TEAK_KITCHEN_TABLE_8532),
|
KITCHEN_TEAK_TABLE (13579, 8248, 52, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kitchen Stoves
|
* Kitchen Stoves
|
||||||
|
|
@ -179,24 +182,24 @@ public enum Decoration {
|
||||||
/**
|
/**
|
||||||
* Dining room tables
|
* Dining room tables
|
||||||
*/
|
*/
|
||||||
DINING_TABLE_WOOD (13293, 8246, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }, Items.WOOD_DINING_TABLE_8548),
|
DINING_TABLE_WOOD (13293, 8246, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }),
|
||||||
DINING_TABLE_OAK (13294, 8247, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }, Items.OAK_DINING_TABLE_8550),
|
DINING_TABLE_OAK (13294, 8247, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }),
|
||||||
DINING_TABLE_CARVED_OAK (13295, 8247, 31, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }, Items.CARVED_OAK_TABLE_8552),
|
DINING_TABLE_CARVED_OAK (13295, 8247, 31, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }),
|
||||||
DINING_TABLE_TEAK (13296, 8248, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }, Items.TEAK_TABLE_8554),
|
DINING_TABLE_TEAK (13296, 8248, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }),
|
||||||
DINING_TABLE_CARVED_TEAK(13297, 8248, 45, 600, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }, Items.CARVED_TEAK_TABLE_8556),
|
DINING_TABLE_CARVED_TEAK(13297, 8248, 45, 600, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }),
|
||||||
DINING_TABLE_MAHOGANY (13298, 8120, 52, 840, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }, Items.MAHOGANY_TABLE_8558),
|
DINING_TABLE_MAHOGANY (13298, 8120, 52, 840, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }),
|
||||||
DINING_TABLE_OPULENT (13299, 8121, 72, 3100, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784, 4), new Item(Items.MARBLE_BLOCK_8786, 2) }, Items.OPULENT_TABLE_8560),
|
DINING_TABLE_OPULENT (13299, 8121, 72, 3100, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784, 4), new Item(Items.MARBLE_BLOCK_8786, 2) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dining room benches
|
* Dining room benches
|
||||||
*/
|
*/
|
||||||
BENCH_WOODEN (13300, 8108, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }, Items.WOODEN_BENCH_8562),
|
BENCH_WOODEN (13300, 8108, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }),
|
||||||
BENCH_OAK (13301, 8109, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }, Items.OAK_BENCH_8564),
|
BENCH_OAK (13301, 8109, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }),
|
||||||
BENCH_CARVED_OAK (13302, 8110, 31, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }, Items.CARVED_OAK_BENCH_8566),
|
BENCH_CARVED_OAK (13302, 8110, 31, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }),
|
||||||
BENCH_TEAK (13303, 8111, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }, Items.TEAK_DINING_BENCH_8568),
|
BENCH_TEAK (13303, 8111, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }),
|
||||||
BENCH_CARVED_TEAK(13304, 8112, 44, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }, Items.CARVED_TEAK_BENCH_8570),
|
BENCH_CARVED_TEAK(13304, 8112, 44, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }),
|
||||||
BENCH_MAHOGANY (13305, 8113, 52, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }, Items.MAHOGANY_BENCH_8572),
|
BENCH_MAHOGANY (13305, 8113, 52, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }),
|
||||||
BENCH_GILDED (13306, 8114, 61, 1760, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4) }, Items.GILDED_BENCH_8574),
|
BENCH_GILDED (13306, 8114, 61, 1760, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dining room bell-pulls
|
* Dining room bell-pulls
|
||||||
|
|
@ -206,7 +209,7 @@ public enum Decoration {
|
||||||
FANCY_BELL_PULL(13309, 8101, 33, 58, new Item[] { new Item(Items.TEAK_PLANK_8780), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784) }),
|
FANCY_BELL_PULL(13309, 8101, 33, 58, new Item[] { new Item(Items.TEAK_PLANK_8780), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workshop workbenches
|
* Workshop workbench
|
||||||
*/
|
*/
|
||||||
WORKBENCH_WOODEN (13704, 8375, 17, 143, new Item[] { new Item(Items.PLANK_960, 5) }),
|
WORKBENCH_WOODEN (13704, 8375, 17, 143, new Item[] { new Item(Items.PLANK_960, 5) }),
|
||||||
WORKBENCH_OAK (13705, 8376, 32, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }),
|
WORKBENCH_OAK (13705, 8376, 32, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }),
|
||||||
|
|
@ -214,12 +217,6 @@ public enum Decoration {
|
||||||
WORKBENCH_WITH_VICE (13707, 8378, 62, 750, new Item[] { new Item(Items.STEEL_FRAMED_BENCH_8377), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }),
|
WORKBENCH_WITH_VICE (13707, 8378, 62, 750, new Item[] { new Item(Items.STEEL_FRAMED_BENCH_8377), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }),
|
||||||
WORKBENCH_WITH_LATHE (13708, 8379, 77, 1000, new Item[] { new Item(Items.OAK_WORKBENCH_8376), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }),
|
WORKBENCH_WITH_LATHE (13708, 8379, 77, 1000, new Item[] { new Item(Items.OAK_WORKBENCH_8376), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }),
|
||||||
|
|
||||||
/**
|
|
||||||
* Workshop stools (linked to workbench/crafting table hotspots)
|
|
||||||
*/
|
|
||||||
WORKSHOP_STOOL (13719, -1, 1, 0),
|
|
||||||
WORKSHOP_STOOL_OAK(13720, -1, 1, 0),
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workshop repair benches/stands
|
* Workshop repair benches/stands
|
||||||
*/
|
*/
|
||||||
|
|
@ -428,30 +425,30 @@ public enum Decoration {
|
||||||
/**
|
/**
|
||||||
* Bedroom decorations.
|
* Bedroom decorations.
|
||||||
*/
|
*/
|
||||||
WOODEN_BED (13148, 8031, 20, 117, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }, Items.WOODEN_BED_8576),
|
WOODEN_BED (13148, 8031, 20, 117, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }),
|
||||||
OAK_BED (13149, 8032, 30, 210, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }, Items.OAK_BED_8578),
|
OAK_BED (13149, 8032, 30, 210, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }),
|
||||||
LARGE_OAK_BED (13150, 8033, 34, 330, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }, Items.LARGE_OAK_BED_8580),
|
LARGE_OAK_BED (13150, 8033, 34, 330, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }),
|
||||||
TEAK_BED (13151, 8034, 40, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }, Items.TEAK_BED_8582),
|
TEAK_BED (13151, 8034, 40, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }),
|
||||||
LARGE_TEAK_BED (13152, 8035, 45, 480, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }, Items.LARGE_TEAK_BED_8584),
|
LARGE_TEAK_BED (13152, 8035, 45, 480, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }),
|
||||||
FOUR_POSTER (13153, 8036, 53, 450, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }, Items.FOUR_POSTER_8586),
|
FOUR_POSTER (13153, 8036, 53, 450, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }),
|
||||||
GILDED_FOUR_POSTER(13154, 8037, 60, 1330, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 2) }, Items.GILDED_4_POSTER_8588),
|
GILDED_FOUR_POSTER(13154, 8037, 60, 1330, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 2) }),
|
||||||
OAK_CLOCK (13169, 8052, 25, 142, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.CLOCKWORK_8792) }, Items.OAK_CLOCK_8590),
|
OAK_CLOCK (13169, 8052, 25, 142, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.CLOCKWORK_8792) }),
|
||||||
TEAK_CLOCK (13170, 8053, 55, 202, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CLOCKWORK_8792) }, Items.TEAK_CLOCK_8592),
|
TEAK_CLOCK (13170, 8053, 55, 202, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CLOCKWORK_8792) }),
|
||||||
GILDED_CLOCK (13171, 8054, 85, 602, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.CLOCKWORK_8792), new Item(Items.GOLD_LEAF_8784) }, Items.GILDED_CLOCK_8594),
|
GILDED_CLOCK (13171, 8054, 85, 602, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.CLOCKWORK_8792), new Item(Items.GOLD_LEAF_8784) }),
|
||||||
SHAVING_STAND (13162, 8045, 21, 30, new Item[] { new Item(Items.PLANK_960), new Item(Items.MOLTEN_GLASS_1775) }, Items.SHAVING_STAND_8596),
|
SHAVING_STAND (13162, 8045, 21, 30, new Item[] { new Item(Items.PLANK_960), new Item(Items.MOLTEN_GLASS_1775) }),
|
||||||
OAK_SHAVING_STAND (13163, 8046, 29, 61, new Item[] { new Item(Items.OAK_PLANK_8778), new Item(Items.MOLTEN_GLASS_1775) }, Items.OAK_SHAVING_STAND_8598),
|
OAK_SHAVING_STAND (13163, 8046, 29, 61, new Item[] { new Item(Items.OAK_PLANK_8778), new Item(Items.MOLTEN_GLASS_1775) }),
|
||||||
OAK_DRESSER (13164, 8047, 37, 121, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775) }, Items.OAK_DRESSER_8600),
|
OAK_DRESSER (13164, 8047, 37, 121, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775) }),
|
||||||
TEAK_DRESSER (13165, 8048, 46, 181, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775) }, Items.TEAK_DRESSER_8602),
|
TEAK_DRESSER (13165, 8048, 46, 181, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775) }),
|
||||||
FANCY_TEAK_DRESSER(13166, 8049, 56, 182, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2) }, Items.FANCY_TEAK_DRESSER_8604),
|
FANCY_TEAK_DRESSER(13166, 8049, 56, 182, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2) }),
|
||||||
MAHOGANY_DRESSER (13167, 8050, 64, 281, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775) }, Items.MAHOGANY_DRESSER_8606),
|
MAHOGANY_DRESSER (13167, 8050, 64, 281, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775) }),
|
||||||
GILDED_DRESSER (13168, 8051, 74, 582, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.GOLD_LEAF_8784) }, Items.GILDED_DRESSER_8608),
|
GILDED_DRESSER (13168, 8051, 74, 582, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.GOLD_LEAF_8784) }),
|
||||||
SHOE_BOX (13155, 8038, 20, 58, new Item[] { new Item(Items.PLANK_960, 2) }, Items.SHOE_BOX_8610),
|
SHOE_BOX (13155, 8038, 20, 58, new Item[] { new Item(Items.PLANK_960, 2) }),
|
||||||
OAK_DRAWERS (13156, 8039, 27, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }, Items.OAK_DRAWERS_8612),
|
OAK_DRAWERS (13156, 8039, 27, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }),
|
||||||
OAK_WARDROBE (13157, 8040, 39, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }, Items.OAK_WARDROBE_8614),
|
OAK_WARDROBE (13157, 8040, 39, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }),
|
||||||
TEAK_DRAWERS (13158, 8041, 51, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }, Items.TEAK_DRAWERS_8616),
|
TEAK_DRAWERS (13158, 8041, 51, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }),
|
||||||
TEAK_WARDROBE (13159, 8042, 63, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }, Items.TEAK_WARDROBE_8618),
|
TEAK_WARDROBE (13159, 8042, 63, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }),
|
||||||
MAHOGANY_WARDROBE (13160, 8043, 75, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }, Items.MAHOGANY_DROBE_8620),
|
MAHOGANY_WARDROBE (13160, 8043, 75, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }),
|
||||||
GILDED_WARDROBE (13161, 8044, 87, 720, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }, Items.GILDED_WARDROBE_8622),
|
GILDED_WARDROBE (13161, 8044, 87, 720, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quest hall decorations.
|
* Quest hall decorations.
|
||||||
|
|
@ -505,31 +502,31 @@ public enum Decoration {
|
||||||
/**
|
/**
|
||||||
* Costume room decorations.
|
* Costume room decorations.
|
||||||
*/
|
*/
|
||||||
OAK_TREASURE_CHEST (18804, 9839, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }, Items.OAK_TREASURE_CHEST_9862),
|
OAK_TREASURE_CHEST (18804, 9839, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }),
|
||||||
TEAK_TREASURE_CHEST (18806, 9840, 66, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }, Items.TEAK_TREAS_CHEST_9863),
|
TEAK_TREASURE_CHEST (18806, 9840, 66, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }),
|
||||||
MAHOGANY_TREASURE_CHEST(18808, 9841, 84, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }, Items.MGANY_TREAS_CHEST_9864),
|
MAHOGANY_TREASURE_CHEST(18808, 9841, 84, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }),
|
||||||
OAK_ARMOUR_CASE (18778, 9826, 46, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }, Items.OAK_ARMOUR_CASE_9859),
|
OAK_ARMOUR_CASE (18778, 9826, 46, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }),
|
||||||
TEAK_ARMOUR_CASE (18780, 9827, 64, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }, Items.TEAK_ARMOUR_CASE_9860),
|
TEAK_ARMOUR_CASE (18780, 9827, 64, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }),
|
||||||
MGANY_ARMOUR_CASE (18782, 9828, 82, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }, Items.MGANY_ARMR_CASE_9861),
|
MGANY_ARMOUR_CASE (18782, 9828, 82, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }),
|
||||||
OAK_MAGIC_WARDROBE (18784, 9829, 42, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }, Items.OAK_MAGIC_WARDROBE_9852),
|
OAK_MAGIC_WARDROBE (18784, 9829, 42, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }),
|
||||||
C_OAK_MAGIC_WARDROBE (18786, 9830, 51, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }, Items.CARVED_OAK_MAGIC_WARDROBE_9853),
|
C_OAK_MAGIC_WARDROBE (18786, 9830, 51, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }),
|
||||||
TEAK_MAGIC_WARDROBE (18788, 9831, 60, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }, Items.TEAK_MAGIC_WARDROBE_9854),
|
TEAK_MAGIC_WARDROBE (18788, 9831, 60, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }),
|
||||||
C_TEAK_MAGIC_WARDROBE (18790, 9832, 69, 540, new Item[] { new Item(Items.TEAK_PLANK_8780, 6) }, Items.CARVED_TEAK_MAGIC_WARDROBE_9855),
|
C_TEAK_MAGIC_WARDROBE (18790, 9832, 69, 540, new Item[] { new Item(Items.TEAK_PLANK_8780, 6) }),
|
||||||
MGANY_MAGIC_WARDROBE (18792, 9833, 78, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }, Items.MAHOGANY_MAGIC_WARDROBE_9856),
|
MGANY_MAGIC_WARDROBE (18792, 9833, 78, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }),
|
||||||
GILDED_MAGIC_WARDROBE (18794, 9834, 87, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }, Items.GILDED_MAGIC_WARDROBE_9857),
|
GILDED_MAGIC_WARDROBE (18794, 9834, 87, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }),
|
||||||
MARBLE_MAGIC_WARDROBE (18796, 9835, 96, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }, Items.MARBLE_MAGIC_WARDROBE_9858),
|
MARBLE_MAGIC_WARDROBE (18796, 9835, 96, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }),
|
||||||
OAK_CAPE_RACK (18766, 9817, 54, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }, Items.OAK_CAPE_RACK_9843),
|
OAK_CAPE_RACK (18766, 9817, 54, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }),
|
||||||
TEAK_CAPE_RACK (18767, 9818, 63, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }, Items.TEAK_CAPE_RACK_9844),
|
TEAK_CAPE_RACK (18767, 9818, 63, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }),
|
||||||
MGANY_CAPE_RACK (18768, 9819, 72, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }, Items.MGANY_CAPE_RACK_9845),
|
MGANY_CAPE_RACK (18768, 9819, 72, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }),
|
||||||
GILDED_CAPE_RACK (18769, 9820, 81, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }, Items.GILDED_CAPE_RACK_9846),
|
GILDED_CAPE_RACK (18769, 9820, 81, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }),
|
||||||
MARBLE_CAPE_RACK (18770, 9821, 90, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }, Items.MARBLE_CAPE_RACK_9847),
|
MARBLE_CAPE_RACK (18770, 9821, 90, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }),
|
||||||
MAGIC_CAPE_RACK (18771, 9822, 99, 1000, new Item[] { new Item(Items.MAGIC_STONE_8788) }, Items.MAGICAL_CAPE_RACK_9848),
|
MAGIC_CAPE_RACK (18771, 9822, 99, 1000, new Item[] { new Item(Items.MAGIC_STONE_8788) }),
|
||||||
OAK_TOY_BOX (18798, 9836, 50, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }, Items.OAK_TOY_BOX_9849),
|
OAK_TOY_BOX (18798, 9836, 50, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }),
|
||||||
TEAK_TOY_BOX (18800, 9837, 68, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }, Items.TEAK_TOY_BOX_9850),
|
TEAK_TOY_BOX (18800, 9837, 68, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }),
|
||||||
MAHOGANY_TOY_BOX (18802, 9838, 86, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }, Items.MAHOGANY_TOY_BOX_9851),
|
MAHOGANY_TOY_BOX (18802, 9838, 86, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }),
|
||||||
OAK_COSTUME_BOX (18772, 9823, 44, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }, Items.OAK_COSTUME_BOX_9865),
|
OAK_COSTUME_BOX (18772, 9823, 44, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }),
|
||||||
TEAK_COSTUME_BOX (18774, 9824, 62, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }, Items.TEAK_COSTUME_BOX_9866),
|
TEAK_COSTUME_BOX (18774, 9824, 62, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }),
|
||||||
MAHOGANY_COSTUME_BOX (18776, 9825, 80, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }, Items.MAHOGANY_COS_BOX_9867),
|
MAHOGANY_COSTUME_BOX (18776, 9825, 80, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chapel decorations.
|
* Chapel decorations.
|
||||||
|
|
@ -687,7 +684,6 @@ public enum Decoration {
|
||||||
FREMENNIK_WINDOW (13112, -1, 1, 0),
|
FREMENNIK_WINDOW (13112, -1, 1, 0),
|
||||||
TROPICAL_WOOD_WINDOW (10816, -1, 1, 0),
|
TROPICAL_WOOD_WINDOW (10816, -1, 1, 0),
|
||||||
FANCY_STONE_WINDOW (13117, -1, 1, 0),
|
FANCY_STONE_WINDOW (13117, -1, 1, 0),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -720,11 +716,6 @@ public enum Decoration {
|
||||||
*/
|
*/
|
||||||
private final Item[] refundItems;
|
private final Item[] refundItems;
|
||||||
|
|
||||||
/**
|
|
||||||
* The item id of the flatpack.
|
|
||||||
*/
|
|
||||||
private final int flatpackItemId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tools required.
|
* The tools required.
|
||||||
*/
|
*/
|
||||||
|
|
@ -783,11 +774,6 @@ public enum Decoration {
|
||||||
this.reqsText = generateDefaultReqsText(items, getNailAmount());
|
this.reqsText = generateDefaultReqsText(items, getNailAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, int flatpackItemId) {
|
|
||||||
this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}, new String[] {}, flatpackItemId);
|
|
||||||
this.reqsText = generateDefaultReqsText(items, getNailAmount());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new object, default refund items, default requirements text.
|
* Constructs a new object, default refund items, default requirements text.
|
||||||
* @param objectId The object id.
|
* @param objectId The object id.
|
||||||
|
|
@ -841,10 +827,6 @@ public enum Decoration {
|
||||||
* @param reqsText The requirements text to be shown in the interface.
|
* @param reqsText The requirements text to be shown in the interface.
|
||||||
*/
|
*/
|
||||||
Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems, String[] reqsText) {
|
Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems, String[] reqsText) {
|
||||||
this(objectId, interfaceItem, level, experience, tools, items, refundItems, reqsText, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems, String[] reqsText, int flatpackItemId) {
|
|
||||||
this.objectId = objectId;
|
this.objectId = objectId;
|
||||||
this.objectIds = null;
|
this.objectIds = null;
|
||||||
this.interfaceItem = interfaceItem;
|
this.interfaceItem = interfaceItem;
|
||||||
|
|
@ -853,7 +835,6 @@ public enum Decoration {
|
||||||
this.tools = tools;
|
this.tools = tools;
|
||||||
this.items = items;
|
this.items = items;
|
||||||
this.refundItems = refundItems;
|
this.refundItems = refundItems;
|
||||||
this.flatpackItemId = flatpackItemId;
|
|
||||||
if (reqsText.length > 0) {
|
if (reqsText.length > 0) {
|
||||||
System.arraycopy(reqsText, 0, this.reqsText, 0, reqsText.length);
|
System.arraycopy(reqsText, 0, this.reqsText, 0, reqsText.length);
|
||||||
}
|
}
|
||||||
|
|
@ -900,7 +881,6 @@ public enum Decoration {
|
||||||
this.tools = tools;
|
this.tools = tools;
|
||||||
this.items = items;
|
this.items = items;
|
||||||
this.refundItems = refundItems;
|
this.refundItems = refundItems;
|
||||||
this.flatpackItemId = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -951,15 +931,6 @@ public enum Decoration {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Decoration forFlatpackItemId(int flatpackId) {
|
|
||||||
for (Decoration d : Decoration.values()) {
|
|
||||||
if (d.getFlatpackItemID() == flatpackId) {
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the amount of nails required for this hotspot.
|
* Gets the amount of nails required for this hotspot.
|
||||||
* @return The amount of nails.
|
* @return The amount of nails.
|
||||||
|
|
@ -1049,14 +1020,6 @@ public enum Decoration {
|
||||||
return objectIds;
|
return objectIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the flatpack item ID if it exists.
|
|
||||||
* @return the int ID.
|
|
||||||
*/
|
|
||||||
public int getFlatpackItemID() {
|
|
||||||
return flatpackItemId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this node should be invisible to user build options
|
* If this node should be invisible to user build options
|
||||||
* @return true if so.
|
* @return true if so.
|
||||||
|
|
|
||||||
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