forked from 2009Scape/Server
Merge pull request 'Update master with 2009scape updates' (#16) from dev into master
Reviewed-on: #16
This commit is contained in:
commit
7592372dc4
875 changed files with 38214 additions and 9943 deletions
|
|
@ -149,4 +149,4 @@ These credits can be spent in the 2009Scape Reward Shop. It's important to be cl
|
|||
|
||||
Testers are not the only people who can gain credits - other ways of earning credits can be found on [the 2009Scape website](https://2009scape.org/site/game_guide/credits.html).
|
||||
|
||||
Please be patient! The Credit system is not fully complete yet, so it will take a long time for credits to be awarded.
|
||||
Please be patient! The Credit system is not fully complete yet, so it will take a long time for credits to be awarded.
|
||||
1
Server/.gitignore
vendored
1
Server/.gitignore
vendored
|
|
@ -2,6 +2,7 @@ bin/**
|
|||
out/**
|
||||
data/logs/**
|
||||
data/profile/**
|
||||
data/playerstats/**
|
||||
.idea/**
|
||||
/bin
|
||||
.DS_Store**
|
||||
|
|
|
|||
BIN
Server/data/cache/main_file_cache.dat2
(Stored with Git LFS)
vendored
BIN
Server/data/cache/main_file_cache.dat2
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Server/data/cache/main_file_cache.idx255
(Stored with Git LFS)
vendored
BIN
Server/data/cache/main_file_cache.idx255
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Server/data/cache/main_file_cache.idx5
(Stored with Git LFS)
vendored
BIN
Server/data/cache/main_file_cache.idx5
(Stored with Git LFS)
vendored
Binary file not shown.
|
|
@ -301,7 +301,7 @@
|
|||
},
|
||||
{
|
||||
"id": "2025",
|
||||
"replaceId": "1534",
|
||||
"replaceId": "2026",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -925,7 +925,7 @@
|
|||
},
|
||||
{
|
||||
"id": "3747",
|
||||
"replaceId": "1534",
|
||||
"replaceId": "3748",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -943,7 +943,7 @@
|
|||
},
|
||||
{
|
||||
"id": "4148",
|
||||
"replaceId": "4248",
|
||||
"replaceId": "4246",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -1759,7 +1759,7 @@
|
|||
},
|
||||
{
|
||||
"id": "14245",
|
||||
"replaceId": "14248",
|
||||
"replaceId": "14246",
|
||||
"fence": "true",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -1984,16 +1984,14 @@
|
|||
"replaceId": "28518",
|
||||
"fence": "false",
|
||||
"metal": "true",
|
||||
"autowalk": "true",
|
||||
"questRequirement": "Icthlarin's Little Helper"
|
||||
"autowalk": "true"
|
||||
},
|
||||
{
|
||||
"id": "28514",
|
||||
"replaceId": "28518",
|
||||
"fence": "false",
|
||||
"metal": "true",
|
||||
"autowalk": "true",
|
||||
"questRequirement": "Icthlarin's Little Helper"
|
||||
"autowalk": "true"
|
||||
},
|
||||
{
|
||||
"id": "21065",
|
||||
|
|
|
|||
|
|
@ -3262,7 +3262,7 @@
|
|||
}
|
||||
],
|
||||
"charm": [],
|
||||
"ids": "73,74,75,419,420,421,422,423,424,1826,2714,2863,2866,2869,2878,3622,4392,4393,4394,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5375,5376,5377,5378,5379,5380,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,6099,6100,6131",
|
||||
"ids": "73,74,75,419,420,421,422,423,424,2714,2863,2866,2869,2878,3622,4392,4393,4394,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5375,5376,5377,5378,5379,5380,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,6099,6100,6131",
|
||||
"description": "",
|
||||
"main": [
|
||||
{
|
||||
|
|
@ -5858,205 +5858,165 @@
|
|||
"charm": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "12158",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "12159",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "12160",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "12163",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5600.0",
|
||||
"weight": "1000.0",
|
||||
"id": "0",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"tertiary": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "4986.5",
|
||||
"id": "0",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "12.5",
|
||||
"id": "10976",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "10977",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"ids": "114",
|
||||
"description": "",
|
||||
"main": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "50.0",
|
||||
"id": "7844",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "10977",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "10976",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5323",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5298",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5281",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5301",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5280",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5294",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5297",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5104",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5100",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5106",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "12176",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5293",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5296",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5311",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5105",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "5292",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "5295",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "5303",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "5302",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "5321",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "5299",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "5.0",
|
||||
"id": "31",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "0",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "3.0",
|
||||
"weight": "39.0625",
|
||||
"id": "6666",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "3.0",
|
||||
"weight": "78.125",
|
||||
"id": "6665",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "13.0",
|
||||
"id": "14422",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "13.0",
|
||||
"id": "14430",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "156.25",
|
||||
"id": "345",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "156.25",
|
||||
"id": "327",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "156.25",
|
||||
"id": "371",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "2",
|
||||
"weight": "156.25",
|
||||
"id": "372",
|
||||
"maxAmount": "5"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "156.25",
|
||||
"id": "359",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "156.25",
|
||||
"id": "360",
|
||||
"maxAmount": "3"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "39.0625",
|
||||
"id": "383",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "39.0625",
|
||||
"id": "349",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "39.0625",
|
||||
"id": "331",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "5",
|
||||
"weight": "156.25",
|
||||
"id": "313",
|
||||
"maxAmount": "15"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "156.25",
|
||||
"id": "1511",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "39.0625",
|
||||
"id": "1383",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "78.125",
|
||||
"id": "407",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "4",
|
||||
"weight": "78.125",
|
||||
"id": "402",
|
||||
"maxAmount": "8"
|
||||
},
|
||||
{
|
||||
"minAmount": "5",
|
||||
"weight": "4.0",
|
||||
"id": "555",
|
||||
"maxAmount": "18"
|
||||
},
|
||||
{
|
||||
"minAmount": "3",
|
||||
"weight": "78.125",
|
||||
"id": "6664",
|
||||
"maxAmount": "6"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "39.0625",
|
||||
"id": "401",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "39.0625",
|
||||
"id": "6667",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -11426,47 +11386,11 @@
|
|||
"weight": "100.0",
|
||||
"id": "526",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "1506",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "6065",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "6067",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "6069",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "6068",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "100.0",
|
||||
"id": "6070",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"charm": [],
|
||||
"ids": "347,348,357,369,370,371,372,717,718,719,2349,2350,2351,2373,2374,2784,3216",
|
||||
"description": "",
|
||||
"ids": "370,357,348,369,347,371",
|
||||
"description": "all combat mourners",
|
||||
"main": []
|
||||
},
|
||||
{
|
||||
|
|
@ -18161,7 +18085,7 @@
|
|||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"ids": "1183,1184,1201,2359,2360,2361,2362,7438,7439,7440,7441",
|
||||
"ids": "1183,1184,1201,2359,2360,2361,2362,2373,7438,7439,7440,7441",
|
||||
"description": "",
|
||||
"main": [
|
||||
{
|
||||
|
|
@ -28545,60 +28469,10 @@
|
|||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"charm": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "85.8093",
|
||||
"id": "0",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "10.9113",
|
||||
"id": "12158",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.6775",
|
||||
"id": "12159",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.6019",
|
||||
"id": "12160",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "0.0",
|
||||
"id": "12163",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"ids": "2044,2045,2046,2047,2048,2049,2051,2052,2053,2054,2055",
|
||||
"charm": [],
|
||||
"ids": "2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057",
|
||||
"description": "",
|
||||
"main": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "1",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "124.0",
|
||||
"id": "0",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "3.0",
|
||||
"id": "7848",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
]
|
||||
"main": []
|
||||
},
|
||||
{
|
||||
"default": [
|
||||
|
|
@ -39929,7 +39803,20 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"default": [],
|
||||
"default": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "532",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "9080",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"charm": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
|
|
@ -58901,6 +58788,26 @@
|
|||
"description": "Ram",
|
||||
"main": []
|
||||
},
|
||||
{
|
||||
"default": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "526",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "1583",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"charm": [],
|
||||
"ids": "6108",
|
||||
"description": "",
|
||||
"main": []
|
||||
},
|
||||
{
|
||||
"default": [],
|
||||
"charm": [],
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@
|
|||
},
|
||||
{
|
||||
"item_id": "946",
|
||||
"loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,3218,9887,0,33}-"
|
||||
"loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,3218,9887,0,33}-{1,2700,3407,0,100}-"
|
||||
},
|
||||
{
|
||||
"item_id": "952",
|
||||
|
|
@ -241,7 +241,7 @@
|
|||
},
|
||||
{
|
||||
"item_id": "954",
|
||||
"loc_data": "{1,2094,3152,0,150}-"
|
||||
"loc_data": "{1,2094,3152,0,150}-{1,2785,3279,0,150}-{1,2786,3287,0,150}-{1,2786,3286,0,150}-"
|
||||
},
|
||||
{
|
||||
"item_id": "960",
|
||||
|
|
@ -339,6 +339,14 @@
|
|||
"item_id": "1422",
|
||||
"loc_data": "{1,3320,3137,0,150}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1467",
|
||||
"loc_data": "{1,2784,3289,0,0}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1469",
|
||||
"loc_data": "{1,2766,3277,0,100}-{1,2766,3289,0,100}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1510",
|
||||
"loc_data": "{1,2576,3334,0,100}-"
|
||||
|
|
@ -619,6 +627,10 @@
|
|||
"item_id": "4707",
|
||||
"loc_data": "{1,3571,3312,0,40}-"
|
||||
},
|
||||
{
|
||||
"item_id": "4838",
|
||||
"loc_data": "{1,2593,3103,1,40}-"
|
||||
},
|
||||
{
|
||||
"item_id": "5008",
|
||||
"loc_data": "{1,3230,9609,0,44}-"
|
||||
|
|
|
|||
|
|
@ -95,6 +95,30 @@
|
|||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "68",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "69",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "70",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "71",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "74",
|
||||
"interfaceType": "4",
|
||||
|
|
@ -365,6 +389,30 @@
|
|||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "245",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "246",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "247",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "248",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "256",
|
||||
"interfaceType": "8",
|
||||
|
|
|
|||
|
|
@ -5719,7 +5719,7 @@
|
|||
},
|
||||
{
|
||||
"shop_price": "35",
|
||||
"examine": "Allows you to rest in the luxurious Paramayer[sic] Inn.",
|
||||
"examine": "Allows you to rest in the luxurious Paramayer Inn.",
|
||||
"durability": null,
|
||||
"name": "Paramaya ticket",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -5727,7 +5727,7 @@
|
|||
},
|
||||
{
|
||||
"shop_price": "35",
|
||||
"examine": "Allows you to rest in the luxurious Paramayer[sic] Inn.",
|
||||
"examine": "Allows you to rest in the luxurious Paramayer Inn.",
|
||||
"durability": null,
|
||||
"name": "Paramaya ticket",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -16309,6 +16309,7 @@
|
|||
"examine": "Maybe I should read this...",
|
||||
"durability": null,
|
||||
"name": "A magic scroll",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "1505"
|
||||
},
|
||||
|
|
@ -16324,7 +16325,7 @@
|
|||
"equipment_slot": "0"
|
||||
},
|
||||
{
|
||||
"examine": "Quite a small key (Plague City).",
|
||||
"examine": "Quite a small key.",
|
||||
"durability": null,
|
||||
"name": "A small key",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -16869,7 +16870,7 @@
|
|||
"id": "1583"
|
||||
},
|
||||
{
|
||||
"examine": "Apparently my name is Hartigan",
|
||||
"examine": "Apparently my name is Hartigen.",
|
||||
"durability": null,
|
||||
"name": "Id papers",
|
||||
"tradeable": "false",
|
||||
|
|
@ -20559,7 +20560,7 @@
|
|||
},
|
||||
{
|
||||
"ge_buy_limit": "1000",
|
||||
"examine": "On ground: Cabbage... yuck!In inventory: Yuck, I don't like cabbage.",
|
||||
"examine": "Yuck, I don't like cabbage.",
|
||||
"grand_exchange_price": "41",
|
||||
"durability": null,
|
||||
"name": "Cabbage",
|
||||
|
|
@ -20578,7 +20579,7 @@
|
|||
"id": "1966"
|
||||
},
|
||||
{
|
||||
"examine": "On ground: Cabbage... yuck!In inventory: Yuck, I don't like cabbage.",
|
||||
"examine": "Yuck, a cabbage from Draynor Manor. I don't like cabbage.",
|
||||
"grand_exchange_price": "55",
|
||||
"durability": null,
|
||||
"name": "Cabbage",
|
||||
|
|
@ -33982,7 +33983,7 @@
|
|||
{
|
||||
"requirements": "{1,40}",
|
||||
"ge_buy_limit": "2",
|
||||
"examine": "Rune platebody with complete gold trim & plating.",
|
||||
"examine": "Rune platebody with complete gold trim & plating.",
|
||||
"durability": null,
|
||||
"weight": "10",
|
||||
"absorb": "3,0,6",
|
||||
|
|
@ -42660,7 +42661,7 @@
|
|||
"id": "4619"
|
||||
},
|
||||
{
|
||||
"examine": "It looks horrible.On ground: Not good for eating.",
|
||||
"examine": "It looks horrible.",
|
||||
"durability": null,
|
||||
"name": "Black mushroom",
|
||||
"weight": "1",
|
||||
|
|
@ -42749,7 +42750,7 @@
|
|||
"equipment_slot": "12"
|
||||
},
|
||||
{
|
||||
"examine": "Frank's shiny silver coated pot.",
|
||||
"examine": "A silver pot made by Ruantun.",
|
||||
"durability": null,
|
||||
"name": "Silver pot",
|
||||
"tradeable": "false",
|
||||
|
|
@ -42766,7 +42767,7 @@
|
|||
"id": "4659"
|
||||
},
|
||||
{
|
||||
"examine": "Frank's shiny silver coated pot.",
|
||||
"examine": "A silver pot made by Ruantun filled with your blood.",
|
||||
"durability": null,
|
||||
"name": "Silver pot",
|
||||
"tradeable": "false",
|
||||
|
|
@ -42775,7 +42776,7 @@
|
|||
"id": "4660"
|
||||
},
|
||||
{
|
||||
"examine": "A silver pot made by Ruantun and blessed on Entrana.",
|
||||
"examine": "A blessed silver pot made by Ruantun filled with your blood.",
|
||||
"durability": null,
|
||||
"name": "Blessed pot",
|
||||
"weight": "2",
|
||||
|
|
@ -42783,7 +42784,7 @@
|
|||
"id": "4661"
|
||||
},
|
||||
{
|
||||
"examine": "Frank's shiny silver coated pot.",
|
||||
"examine": "A silver pot made by Ruantun filled with blood and garlic.",
|
||||
"durability": null,
|
||||
"name": "Silver pot",
|
||||
"tradeable": "false",
|
||||
|
|
@ -42792,7 +42793,7 @@
|
|||
"id": "4662"
|
||||
},
|
||||
{
|
||||
"examine": "A silver pot made by Ruantun and blessed on Entrana.",
|
||||
"examine": "A blessed silver pot filled with blood and garlic.",
|
||||
"durability": null,
|
||||
"name": "Blessed pot",
|
||||
"weight": "2",
|
||||
|
|
@ -42800,7 +42801,7 @@
|
|||
"id": "4663"
|
||||
},
|
||||
{
|
||||
"examine": "Frank's shiny silver coated pot.",
|
||||
"examine": "A silver pot made by Ruantun filled with blood and spices.",
|
||||
"durability": null,
|
||||
"name": "Silver pot",
|
||||
"tradeable": "false",
|
||||
|
|
@ -42809,7 +42810,7 @@
|
|||
"id": "4664"
|
||||
},
|
||||
{
|
||||
"examine": "A silver pot made by Ruantun and blessed on Entrana.",
|
||||
"examine": "A blessed silver pot filled with blood and spices.",
|
||||
"durability": null,
|
||||
"name": "Blessed pot",
|
||||
"weight": "2",
|
||||
|
|
@ -42817,7 +42818,7 @@
|
|||
"id": "4665"
|
||||
},
|
||||
{
|
||||
"examine": "Frank's shiny silver coated pot.",
|
||||
"examine": "A silver pot made by Ruantun filled with blood, garlic and spices.",
|
||||
"durability": null,
|
||||
"name": "Silver pot",
|
||||
"tradeable": "false",
|
||||
|
|
@ -42826,7 +42827,7 @@
|
|||
"id": "4666"
|
||||
},
|
||||
{
|
||||
"examine": "A silver pot made by Ruantun and blessed on Entrana.",
|
||||
"examine": "A blessed silver pot filled with blood, garlic and spices.",
|
||||
"durability": null,
|
||||
"name": "Blessed pot",
|
||||
"weight": "2",
|
||||
|
|
@ -43126,13 +43127,13 @@
|
|||
"id": "4702"
|
||||
},
|
||||
{
|
||||
"shop_price": "975000",
|
||||
"examine": "A magic stone to make high-level furniture.",
|
||||
"grand_exchange_price": "977755",
|
||||
"shop_price": "1",
|
||||
"examine": "Doesn't look very special.",
|
||||
"grand_exchange_price": "0",
|
||||
"durability": null,
|
||||
"name": "Magic stone",
|
||||
"tradeable": "true",
|
||||
"weight": "1",
|
||||
"tradeable": "false",
|
||||
"weight": "2.267",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "4703"
|
||||
},
|
||||
|
|
@ -48987,7 +48988,7 @@
|
|||
"id": "5419"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There is one potato in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(1)",
|
||||
|
|
@ -49004,7 +49005,7 @@
|
|||
"id": "5421"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are two potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(2)",
|
||||
|
|
@ -49021,7 +49022,7 @@
|
|||
"id": "5423"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are three potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(3)",
|
||||
|
|
@ -49038,7 +49039,7 @@
|
|||
"id": "5425"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are four potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(4)",
|
||||
|
|
@ -49055,7 +49056,7 @@
|
|||
"id": "5427"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are five potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(5)",
|
||||
|
|
@ -49072,7 +49073,7 @@
|
|||
"id": "5429"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are six potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(6)",
|
||||
|
|
@ -49089,7 +49090,7 @@
|
|||
"id": "5431"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are seven potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(7)",
|
||||
|
|
@ -49106,7 +49107,7 @@
|
|||
"id": "5433"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are eight potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(8)",
|
||||
|
|
@ -49123,7 +49124,7 @@
|
|||
"id": "5435"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are nine potatoes in this sack.",
|
||||
"grand_exchange_price": "1276",
|
||||
"durability": null,
|
||||
"name": "Potatoes(9)",
|
||||
|
|
@ -49141,7 +49142,7 @@
|
|||
},
|
||||
{
|
||||
"ge_buy_limit": "1000",
|
||||
"examine": "There are <number of potatoes> in this sack.",
|
||||
"examine": "There are ten potatoes in this sack.",
|
||||
"grand_exchange_price": "1052",
|
||||
"durability": null,
|
||||
"name": "Potatoes(10)",
|
||||
|
|
@ -49333,7 +49334,7 @@
|
|||
"id": "5459"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There is one cabbage in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(1)",
|
||||
|
|
@ -49349,7 +49350,7 @@
|
|||
"id": "5461"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are two cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(2)",
|
||||
|
|
@ -49365,7 +49366,7 @@
|
|||
"id": "5463"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are three cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(3)",
|
||||
|
|
@ -49381,7 +49382,7 @@
|
|||
"id": "5465"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are four cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(4)",
|
||||
|
|
@ -49397,7 +49398,7 @@
|
|||
"id": "5467"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are five cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(5)",
|
||||
|
|
@ -49413,7 +49414,7 @@
|
|||
"id": "5469"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are six cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(6)",
|
||||
|
|
@ -49429,7 +49430,7 @@
|
|||
"id": "5471"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are seven cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(7)",
|
||||
|
|
@ -49445,7 +49446,7 @@
|
|||
"id": "5473"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are eight cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(8)",
|
||||
|
|
@ -49461,7 +49462,7 @@
|
|||
"id": "5475"
|
||||
},
|
||||
{
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are nine cabbages in this sack.",
|
||||
"grand_exchange_price": "1304",
|
||||
"durability": null,
|
||||
"name": "Cabbages(9)",
|
||||
|
|
@ -49478,7 +49479,7 @@
|
|||
},
|
||||
{
|
||||
"ge_buy_limit": "1000",
|
||||
"examine": "There are <number of cabbages> in this sack.",
|
||||
"examine": "There are ten cabbages in this sack.",
|
||||
"grand_exchange_price": "917",
|
||||
"durability": null,
|
||||
"name": "Cabbages(10)",
|
||||
|
|
@ -55738,7 +55739,7 @@
|
|||
"equipment_slot": "4"
|
||||
},
|
||||
{
|
||||
"examine": "Damaged: These are in need of a good tailor.Repaired: A pair of mourner trousers.",
|
||||
"examine": "These are in need of a good tailor.",
|
||||
"durability": null,
|
||||
"name": "Mourner trousers",
|
||||
"weight": "2.25",
|
||||
|
|
@ -55746,7 +55747,7 @@
|
|||
"id": "6066"
|
||||
},
|
||||
{
|
||||
"examine": "Damaged: These are in need of a good tailor.Repaired: A pair of mourner trousers.",
|
||||
"examine": "A pair of mourner trousers.",
|
||||
"durability": null,
|
||||
"name": "Mourner trousers",
|
||||
"weight": "2.25",
|
||||
|
|
@ -58309,7 +58310,7 @@
|
|||
{
|
||||
"shop_price": "150",
|
||||
"ge_buy_limit": "100",
|
||||
"examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"examine": "A brown armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"grand_exchange_price": "734",
|
||||
"durability": null,
|
||||
"name": "Villager armband",
|
||||
|
|
@ -58442,7 +58443,7 @@
|
|||
{
|
||||
"shop_price": "150",
|
||||
"ge_buy_limit": "100",
|
||||
"examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"examine": "A blue armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"grand_exchange_price": "672",
|
||||
"durability": null,
|
||||
"name": "Villager armband",
|
||||
|
|
@ -58553,7 +58554,7 @@
|
|||
{
|
||||
"shop_price": "150",
|
||||
"ge_buy_limit": "100",
|
||||
"examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"examine": "A yellow armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"grand_exchange_price": "823",
|
||||
"durability": null,
|
||||
"name": "Villager armband",
|
||||
|
|
@ -58664,7 +58665,7 @@
|
|||
{
|
||||
"shop_price": "150",
|
||||
"ge_buy_limit": "100",
|
||||
"examine": "A <colour> armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"examine": "A pink armband, as worn by the Tai Bwo Wannai locals.",
|
||||
"grand_exchange_price": "1697",
|
||||
"durability": null,
|
||||
"name": "Villager armband",
|
||||
|
|
@ -59764,7 +59765,7 @@
|
|||
},
|
||||
{
|
||||
"destroy_message": "You will not get a replacement for the present. Open it for your reward.",
|
||||
"examine": "Thanks for all your help! Love, Bob & Neite.",
|
||||
"examine": "Thanks for all your help! Love, Bob & Neite.",
|
||||
"durability": null,
|
||||
"name": "Present",
|
||||
"tradeable": "false",
|
||||
|
|
@ -70692,7 +70693,7 @@
|
|||
},
|
||||
{
|
||||
"ge_buy_limit": "100",
|
||||
"examine": "In inventory: Nice bit of crafting! When released: Nice bit of crafting that...",
|
||||
"examine": "Nice bit of crafting!",
|
||||
"grand_exchange_price": "3236",
|
||||
"durability": null,
|
||||
"name": "Toy doll",
|
||||
|
|
@ -70710,7 +70711,7 @@
|
|||
"id": "7764"
|
||||
},
|
||||
{
|
||||
"examine": "In inventory: Nice bit of crafting! When released: Nice bit of crafting that...",
|
||||
"examine": "Nice bit of crafting!",
|
||||
"grand_exchange_price": "3289",
|
||||
"durability": null,
|
||||
"name": "Toy doll (wound)",
|
||||
|
|
@ -93158,7 +93159,7 @@
|
|||
},
|
||||
{
|
||||
"requirements": "{1,40}",
|
||||
"examine": "Rune platebody with complete gold trim & plating.",
|
||||
"examine": "Rune platebody with complete gold trim & plating.",
|
||||
"durability": null,
|
||||
"weight": "10",
|
||||
"absorb": "3,0,6",
|
||||
|
|
@ -105245,28 +105246,28 @@
|
|||
"id": "12196"
|
||||
},
|
||||
{
|
||||
"examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.",
|
||||
"examine": "A hatchling green dragon.",
|
||||
"durability": null,
|
||||
"name": "Dragon hatchling",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12197"
|
||||
},
|
||||
{
|
||||
"examine": "Baby: Little NipperAdult: Bigger Nipper.",
|
||||
"examine": "Little Nipper.",
|
||||
"durability": null,
|
||||
"name": "Baby giant crab",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12198"
|
||||
},
|
||||
{
|
||||
"examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.",
|
||||
"examine": "A stripy little baby raccoon.",
|
||||
"durability": null,
|
||||
"name": "Baby raccoon",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12199"
|
||||
},
|
||||
{
|
||||
"examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.",
|
||||
"examine": "An experienced nut-thief.",
|
||||
"durability": null,
|
||||
"name": "Squirrel",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -106499,28 +106500,28 @@
|
|||
"id": "12468"
|
||||
},
|
||||
{
|
||||
"examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.",
|
||||
"examine": "A hatchling red dragon.",
|
||||
"durability": null,
|
||||
"name": "Hatchling dragon",
|
||||
"name": "Dragon hatchling",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12469"
|
||||
},
|
||||
{
|
||||
"examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.",
|
||||
"examine": "A hatchling blue dragon.",
|
||||
"durability": null,
|
||||
"name": "Hatchling dragon",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12471"
|
||||
},
|
||||
{
|
||||
"examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.",
|
||||
"examine": "A hatchling green dragon.",
|
||||
"durability": null,
|
||||
"name": "Hatchling dragon",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12473"
|
||||
},
|
||||
{
|
||||
"examine": "(hatchling) A hatchling <dragon colour> dragon.(baby) A bigger baby <colour> dragon.",
|
||||
"examine": "A hatchling black dragon.",
|
||||
"durability": null,
|
||||
"name": "Hatchling dragon",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -106567,16 +106568,17 @@
|
|||
"id": "12480"
|
||||
},
|
||||
{
|
||||
"examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.",
|
||||
"examine": "Can't fly and can barely walk, but adorable nonetheless.",
|
||||
"durability": null,
|
||||
"name": "Baby penguin",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12481"
|
||||
},
|
||||
{
|
||||
"examine": "I can hatch this in an Incubator.",
|
||||
"examine": "I can hatch this in an incubator.",
|
||||
"durability": null,
|
||||
"name": "Penguin egg",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12483"
|
||||
},
|
||||
|
|
@ -108972,14 +108974,14 @@
|
|||
"id": "12761"
|
||||
},
|
||||
{
|
||||
"examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.",
|
||||
"examine": "Can't fly and can barely walk, but adorable nonetheless.",
|
||||
"durability": null,
|
||||
"name": "Baby penguin",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "12763"
|
||||
},
|
||||
{
|
||||
"examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.",
|
||||
"examine": "Can't fly and can barely walk, but adorable nonetheless.",
|
||||
"durability": null,
|
||||
"name": "Baby penguin",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -122124,7 +122126,7 @@
|
|||
{
|
||||
"lendable": "true",
|
||||
"destroy_message": "Drop",
|
||||
"examine": "Rune platebody with complete gold trim & plating.",
|
||||
"examine": "Rune platebody with complete gold trim & plating.",
|
||||
"grand_exchange_price": "2034838",
|
||||
"durability": null,
|
||||
"name": "Gilded platebody",
|
||||
|
|
@ -132095,5 +132097,20 @@
|
|||
"archery_ticket_price": "0",
|
||||
"id": "14658",
|
||||
"equipment_slot": "0"
|
||||
},
|
||||
{
|
||||
"examine": "Emperor of all he surveys.",
|
||||
"name": "Penguin",
|
||||
"id": "12482"
|
||||
},
|
||||
{
|
||||
"examine": "Emperor of all he surveys.",
|
||||
"name": "Penguin",
|
||||
"id": "12762"
|
||||
},
|
||||
{
|
||||
"examine": "Emperor of all he surveys.",
|
||||
"name": "Penguin",
|
||||
"id": "12764"
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -16324,7 +16324,7 @@
|
|||
"ids": "11629"
|
||||
},
|
||||
{
|
||||
"examine": "South to Falador :: West to Taverley :: East to Varrock.",
|
||||
"examine": "This tells you which way is which.",
|
||||
"ids": "11630,11631,11632,11633"
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -564,7 +564,7 @@
|
|||
"general_store": "false",
|
||||
"id": "65",
|
||||
"title": "Dodgy Mikes Second-hand Clothing",
|
||||
"stock": "{7114,10,100}"
|
||||
"stock": "{7114,10,100}-{7122,10,100}-{7128,10,100}-{7134,10,100}-{7110,10,100}-{7126,10,100}-{7132,10,100}-{7138,10,100}-{7116,10,100}-{7124,10,100}-{7130,10,100}-{7112,10,100}-{7136,10,100}"
|
||||
},
|
||||
{
|
||||
"npcs": "2161",
|
||||
|
|
@ -2177,5 +2177,23 @@
|
|||
"id": "255",
|
||||
"title": "Castle Wars Ticket Exchange",
|
||||
"stock": "{4068,1,100}-{4069,1,100}-{4070,1,100}-{4071,1,100}-{4072,1,100}-{4503,1,100}-{4504,1,100}-{4505,1,100}-{4506,1,100}-{4507,1,100}-{4508,1,100}-{4509,1,100}-{4510,1,100}-{4511,1,100}-{4512,1,100}-{4513,1,100}-{4514,1,100}-{4515,1,100}-{4516,1,100}"
|
||||
},
|
||||
{
|
||||
"npcs": "5111",
|
||||
"high_alch": "0",
|
||||
"currency": "995",
|
||||
"general_store": "false",
|
||||
"id": "256",
|
||||
"title": "Leon's Prototype Crossbow",
|
||||
"stock": "{10156,2,100}"
|
||||
},
|
||||
{
|
||||
"npcs": "2039",
|
||||
"high_alch": "0",
|
||||
"currency": "995",
|
||||
"general_store": "false",
|
||||
"id": "256",
|
||||
"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}"
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,6 +2,7 @@ package content.data
|
|||
|
||||
import content.global.skill.magic.TeleportMethod
|
||||
import content.global.skill.slayer.SlayerManager.Companion.getInstance
|
||||
import content.global.skill.slayer.SlayerUtils
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.event.TeleportEvent
|
||||
|
|
@ -304,7 +305,7 @@ enum class EnchantedJewellery(
|
|||
return
|
||||
}
|
||||
sendNPCDialogue(player, slayerManager.master!!.npc, "You're currently " +
|
||||
"assigned to kill ${getSlayerTaskName(player).lowercase(Locale.getDefault())}'s; " +
|
||||
"assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player))} " +
|
||||
"only ${getSlayerTaskKillsRemaining(player)} more to go.", core.game.dialogue.FacialExpression.FRIENDLY)
|
||||
// Slayer tracker UI
|
||||
setVarp(player, 2502, slayerManager.flags.taskFlags shr 4)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public enum GodBook {
|
|||
* @param page the page.
|
||||
*/
|
||||
public void insertPage(Player player, Item book, Item page) {
|
||||
if (!hasRequirement(player, "Horror from the Deep"))
|
||||
if (!hasRequirement(player, Quests.HORROR_FROM_THE_DEEP))
|
||||
return;
|
||||
if (hasPage(player, book, page)) {
|
||||
player.sendMessage("The book already has that page.");
|
||||
|
|
|
|||
158
Server/src/main/content/data/Quests.kt
Normal file
158
Server/src/main/content/data/Quests.kt
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
package content.data
|
||||
|
||||
enum class Quests(val questName: String) {
|
||||
MYTHS_OF_THE_WHITE_LANDS("Myths of the White Lands"),
|
||||
BLACK_KNIGHTS_FORTRESS("Black Knights' Fortress"),
|
||||
COOKS_ASSISTANT("Cook's Assistant"),
|
||||
DEMON_SLAYER("Demon Slayer"),
|
||||
DORICS_QUEST("Doric's Quest"),
|
||||
DRAGON_SLAYER("Dragon Slayer"),
|
||||
ERNEST_THE_CHICKEN("Ernest the Chicken"),
|
||||
GOBLIN_DIPLOMACY("Goblin Diplomacy"),
|
||||
IMP_CATCHER("Imp Catcher"),
|
||||
THE_KNIGHTS_SWORD("The Knight's Sword"),
|
||||
PIRATES_TREASURE("Pirate's Treasure"),
|
||||
PRINCE_ALI_RESCUE("Prince Ali Rescue"),
|
||||
THE_RESTLESS_GHOST("The Restless Ghost"),
|
||||
ROMEO_JULIET("Romeo & Juliet"),
|
||||
RUNE_MYSTERIES("Rune Mysteries"),
|
||||
SHEEP_SHEARER("Sheep Shearer"),
|
||||
SHIELD_OF_ARRAV("Shield of Arrav"),
|
||||
VAMPIRE_SLAYER("Vampire Slayer"),
|
||||
WITCHS_POTION("Witch's Potion"),
|
||||
ANIMAL_MAGNETISM("Animal Magnetism"),
|
||||
BETWEEN_A_ROCK("Between a Rock..."),
|
||||
BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting"),
|
||||
BIOHAZARD("Biohazard"),
|
||||
CABIN_FEVER("Cabin Fever"),
|
||||
CLOCK_TOWER("Clock Tower"),
|
||||
CONTACT("Contact!"),
|
||||
ZOGRE_FLESH_EATERS("Zogre Flesh Eaters"),
|
||||
CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain"),
|
||||
DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale"),
|
||||
DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun"),
|
||||
DEATH_PLATEAU("Death Plateau"),
|
||||
DESERT_TREASURE("Desert Treasure"),
|
||||
DEVIOUS_MINDS("Devious Minds"),
|
||||
THE_DIG_SITE("The Dig Site"),
|
||||
DRUIDIC_RITUAL("Druidic Ritual"),
|
||||
DWARF_CANNON("Dwarf Cannon"),
|
||||
EADGARS_RUSE("Eadgar's Ruse"),
|
||||
EAGLES_PEAK("Eagles' Peak"),
|
||||
ELEMENTAL_WORKSHOP_I("Elemental Workshop I"),
|
||||
ELEMENTAL_WORKSHOP_II("Elemental Workshop II"),
|
||||
ENAKHRAS_LAMENT("Enakhra's Lament"),
|
||||
ENLIGHTENED_JOURNEY("Enlightened Journey"),
|
||||
THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie"),
|
||||
FAIRYTALE_I_GROWING_PAINS("Fairytale I - Growing Pains"),
|
||||
FAIRYTALE_II_CURE_A_QUEEN("Fairytale II - Cure a Queen"),
|
||||
FAMILY_CREST("Family Crest"),
|
||||
THE_FEUD("The Feud"),
|
||||
FIGHT_ARENA("Fight Arena"),
|
||||
FISHING_CONTEST("Fishing Contest"),
|
||||
FORGETTABLE_TALE("Forgettable Tale..."),
|
||||
THE_FREMENNIK_TRIALS("The Fremennik Trials"),
|
||||
WATERFALL_QUEST("Waterfall Quest"),
|
||||
GARDEN_OF_TRANQUILITY("Garden of Tranquility"),
|
||||
GERTRUDES_CAT("Gertrude's Cat"),
|
||||
GHOSTS_AHOY("Ghosts Ahoy"),
|
||||
THE_GIANT_DWARF("The Giant Dwarf"),
|
||||
THE_GOLEM("The Golem"),
|
||||
THE_GRAND_TREE("The Grand Tree"),
|
||||
THE_HAND_IN_THE_SAND("The Hand in the Sand"),
|
||||
HAUNTED_MINE("Haunted Mine"),
|
||||
HAZEEL_CULT("Hazeel Cult"),
|
||||
HEROES_QUEST("Heroes' Quest"),
|
||||
HOLY_GRAIL("Holy Grail"),
|
||||
HORROR_FROM_THE_DEEP("Horror from the Deep"),
|
||||
ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper"),
|
||||
IN_AID_OF_THE_MYREQUE("In Aid of the Myreque"),
|
||||
IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque"),
|
||||
JUNGLE_POTION("Jungle Potion"),
|
||||
LEGENDS_QUEST("Legend's Quest"),
|
||||
LOST_CITY("Lost City"),
|
||||
THE_LOST_TRIBE("The Lost Tribe"),
|
||||
LUNAR_DIPLOMACY("Lunar Diplomacy"),
|
||||
MAKING_HISTORY("Making History"),
|
||||
MERLINS_CRYSTAL("Merlin's Crystal"),
|
||||
MONKEY_MADNESS("Monkey Madness"),
|
||||
MONKS_FRIEND("Monk's Friend"),
|
||||
MOUNTAIN_DAUGHTER("Mountain Daughter"),
|
||||
MOURNINGS_END_PART_I("Mourning's End Part I"),
|
||||
MOURNINGS_END_PART_II("Mourning's End Part II"),
|
||||
MURDER_MYSTERY("Murder Mystery"),
|
||||
MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure"),
|
||||
NATURE_SPIRIT("Nature Spirit"),
|
||||
OBSERVATORY_QUEST("Observatory Quest"),
|
||||
ONE_SMALL_FAVOUR("One Small Favour"),
|
||||
PLAGUE_CITY("Plague City"),
|
||||
PRIEST_IN_PERIL("Priest in Peril"),
|
||||
RAG_AND_BONE_MAN("Rag and Bone Man"),
|
||||
RATCATCHERS("Ratcatchers"),
|
||||
RECIPE_FOR_DISASTER("Recipe for Disaster"),
|
||||
RECRUITMENT_DRIVE("Recruitment Drive"),
|
||||
REGICIDE("Regicide"),
|
||||
ROVING_ELVES("Roving Elves"),
|
||||
ROYAL_TROUBLE("Royal Trouble"),
|
||||
RUM_DEAL("Rum Deal"),
|
||||
SCORPION_CATCHER("Scorpion Catcher"),
|
||||
SEA_SLUG("Sea Slug"),
|
||||
THE_SLUG_MENACE("The Slug Menace"),
|
||||
SHADES_OF_MORTTON("Shades of Mort'ton"),
|
||||
SHADOW_OF_THE_STORM("Shadow of the Storm"),
|
||||
SHEEP_HERDER("Sheep Herder"),
|
||||
SHILO_VILLAGE("Shilo Village"),
|
||||
A_SOULS_BANE("A Soul's Bane"),
|
||||
SPIRITS_OF_THE_ELID("Spirits of the Elid"),
|
||||
SWAN_SONG("Swan Song"),
|
||||
TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio"),
|
||||
A_TAIL_OF_TWO_CATS("A Tail of Two Cats"),
|
||||
TEARS_OF_GUTHIX("Tears of Guthix"),
|
||||
TEMPLE_OF_IKOV("Temple of Ikov"),
|
||||
THRONE_OF_MISCELLANIA("Throne of Miscellania"),
|
||||
THE_TOURIST_TRAP("The Tourist Trap"),
|
||||
WITCHS_HOUSE("Witch's House"),
|
||||
TREE_GNOME_VILLAGE("Tree Gnome Village"),
|
||||
TRIBAL_TOTEM("Tribal Totem"),
|
||||
TROLL_ROMANCE("Troll Romance"),
|
||||
TROLL_STRONGHOLD("Troll Stronghold"),
|
||||
UNDERGROUND_PASS("Underground Pass"),
|
||||
WANTED("Wanted!"),
|
||||
WATCHTOWER("Watchtower"),
|
||||
COLD_WAR("Cold War"),
|
||||
THE_FREMENNIK_ISLES("The Fremennik Isles"),
|
||||
TOWER_OF_LIFE("Tower of Life"),
|
||||
THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery"),
|
||||
WHAT_LIES_BELOW("What Lies Below"),
|
||||
OLAFS_QUEST("Olaf's Quest"),
|
||||
ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M"),
|
||||
DREAM_MENTOR("Dream Mentor"),
|
||||
GRIM_TALES("Grim Tales"),
|
||||
KINGS_RANSOM("King's Ransom"),
|
||||
THE_PATH_OF_GLOUPHRIE("The Path of Glouphrie"),
|
||||
BACK_TO_MY_ROOTS("Back to my Roots"),
|
||||
LAND_OF_THE_GOBLINS("Land of the Goblins"),
|
||||
DEALING_WITH_SCABARAS("Dealing with Scabaras"),
|
||||
WOLF_WHISTLE("Wolf Whistle"),
|
||||
AS_A_FIRST_RESORT("As a First Resort..."),
|
||||
CATAPULT_CONSTRUCTION("Catapult Construction"),
|
||||
KENNITHS_CONCERNS("Kennith's Concerns"),
|
||||
LEGACY_OF_SEERGAZE("Legacy of Seergaze"),
|
||||
PERILS_OF_ICE_MOUNTAIN("Perils of Ice Mountain"),
|
||||
TOKTZ_KET_DILL("TokTz-Ket-Dill"),
|
||||
SMOKING_KILLS("Smoking Kills"),
|
||||
ROCKING_OUT("Rocking Out"),
|
||||
SPIRIT_OF_SUMMER("Spirit of Summer"),
|
||||
MEETING_HISTORY("Meeting History"),
|
||||
ALL_FIRED_UP("All Fired Up"),
|
||||
SUMMERS_END("Summer's End"),
|
||||
DEFENDER_OF_VARROCK("Defender of Varrock"),
|
||||
SWEPT_AWAY("Swept Away"),
|
||||
WHILE_GUTHIX_SLEEPS("While Guthix Sleeps"),
|
||||
IN_PYRE_NEED("In Pyre Need"),
|
||||
TEST_QUEST("Test Quest");
|
||||
|
||||
override fun toString(): String {
|
||||
return questName
|
||||
}
|
||||
}
|
||||
|
|
@ -30,36 +30,36 @@ public enum Consumables {
|
|||
HERRING(new Food(new int[] {347}, new HealingEffect(5))),
|
||||
MACKEREL(new Food(new int[] {355}, new HealingEffect(6))),
|
||||
ROAST_BIRD_MEAT(new Food(new int[] {9980}, new HealingEffect(6))),
|
||||
THIN_SNAIL(new Food(new int[] {3369}, new HealingEffect(5))),
|
||||
THIN_SNAIL(new Food(new int[] {3369}, new RandomHealthEffect(5, 7))),
|
||||
TROUT(new Food(new int[] {333}, new HealingEffect(7))),
|
||||
SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new HealingEffect(7))),
|
||||
SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new RandomHealthEffect(7, 11))),
|
||||
SPIDER_ON_SHAFT(new Food(new int[] {6299}, new HealingEffect(7))),
|
||||
ROAST_RABBIT(new Food(new int[] {7223}, new HealingEffect(7))),
|
||||
LEAN_SNAIL(new Food(new int[] {3371}, new HealingEffect(8))),
|
||||
LEAN_SNAIL(new Food(new int[] {3371}, new RandomHealthEffect(6, 8))),
|
||||
COD(new Food(new int[] {339}, new HealingEffect(7))),
|
||||
PIKE(new Food(new int[] {351}, new HealingEffect(8))),
|
||||
ROAST_BEAST_MEAT(new Food(new int[] {9988}, new HealingEffect(8))),
|
||||
COOKED_CRAB_MEAT(new Food(new int[] {7521, 7523, 7524, 7525, 7526}, new HealingEffect(2))),
|
||||
FAT_SNAIL(new Food(new int[] {3373}, new HealingEffect(9))),
|
||||
FAT_SNAIL(new Food(new int[] {3373}, new RandomHealthEffect(7, 9))),
|
||||
SALMON(new Food(new int[] {329}, new HealingEffect(9))),
|
||||
SLIMY_EEL(new Food(new int[] {3381}, new HealingEffect(6))),
|
||||
SLIMY_EEL(new Food(new int[] {3381}, new RandomHealthEffect(6, 10))),
|
||||
TUNA(new Food(new int[] {361}, new HealingEffect(10))),
|
||||
COOKED_KARAMBWAN(new Food(new int[] {3144}, new HealingEffect(18)), true),
|
||||
COOKED_CHOMPY(new Food(new int[] {2878}, new HealingEffect(10))),
|
||||
RAINBOW_FISH(new Food(new int[] {10136}, new HealingEffect(11))),
|
||||
CAVE_EEL(new Food(new int[] {5003}, new HealingEffect(7))),
|
||||
CAVE_EEL(new Food(new int[] {5003}, new RandomHealthEffect(8, 12))),
|
||||
LOBSTER(new Food(new int[] {379}, new HealingEffect(12))),
|
||||
COOKED_JUBBLY(new Food(new int[] {7568}, new HealingEffect(15))),
|
||||
BASS(new Food(new int[] {365}, new HealingEffect(13))),
|
||||
SWORDFISH(new Food(new int[] {373}, new HealingEffect(14))),
|
||||
LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(14))),
|
||||
LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(11))),
|
||||
MONKFISH(new Food(new int[] {7946}, new HealingEffect(16))),
|
||||
SHARK(new Food(new int[] {385}, new HealingEffect(20))),
|
||||
SEA_TURTLE(new Food(new int[] {397}, new HealingEffect(21))),
|
||||
MANTA_RAY(new Food(new int[] {391}, new HealingEffect(22))),
|
||||
KARAMBWANJI(new Food(new int[] {3151}, new HealingEffect(3))),
|
||||
STUFFED_SNAKE(new Food(new int[] {7579}, new HealingEffect(20), "You eat the stuffed snake-it's quite a meal! It tastes like chicken.")),
|
||||
CRAYFISH(new Food(new int[] {13433}, new HealingEffect(2))),
|
||||
CRAYFISH(new Food(new int[] {13433}, new HealingEffect(1))),
|
||||
GIANT_FROG_LEGS(new Food(new int [] {4517}, new HealingEffect(6))),
|
||||
|
||||
/** Breads */
|
||||
|
|
@ -111,7 +111,7 @@ public enum Consumables {
|
|||
|
||||
/** Vegetables */
|
||||
POTATO(new Food(new int[] {1942}, new HealingEffect(1), "You eat the potato. Yuck!")),
|
||||
BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(2))),
|
||||
BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(4))),
|
||||
SPICY_SAUCE(new Food(new int[] {7072, 1923}, new HealingEffect(2))),
|
||||
CHILLI_CON_CARNE(new Food(new int[] {7062, 1923}, new HealingEffect(5))),
|
||||
SCRAMBLED_EGG(new Food(new int[] {7078, 1923}, new HealingEffect(5))),
|
||||
|
|
@ -128,8 +128,8 @@ public enum Consumables {
|
|||
MUSHROOM_POTATO(new Food(new int[] {7058}, new HealingEffect(20))),
|
||||
TUNA_AND_CORN(new Food(new int[] {7068, 1923}, new HealingEffect(13))),
|
||||
TUNA_POTATO(new Food(new int[] {7060}, new HealingEffect(22))),
|
||||
ONION(new Food(new int[] {1957}, new HealingEffect(2), "It's always sad to see a grown man/woman cry.")),
|
||||
CABBAGE(new Food(new int[] {1965}, new HealingEffect(2), "You eat the cabbage. Yuck!")),
|
||||
ONION(new Food(new int[] {1957}, new HealingEffect(1), "It's always sad to see a grown man/woman cry.")),
|
||||
CABBAGE(new Food(new int[] {1965}, new HealingEffect(1), "You eat the cabbage. Yuck!")),
|
||||
DRAYNOR_CABBAGE(new Food(new int[] {1967}, new DraynorCabbageEffect(), "You eat the cabbage.", "It seems to taste nicer than normal.")),
|
||||
EVIL_TURNIP(new Food(new int[] {12134, 12136, 12138}, new HealingEffect(6))),
|
||||
SPINACH_ROLL(new Food(new int[] {1969}, new HealingEffect(2))),
|
||||
|
|
@ -147,7 +147,7 @@ public enum Consumables {
|
|||
ORANGE(new Food(new int[] {2108}, new HealingEffect(2))),
|
||||
ORANGE_CHUNKS(new Food(new int[] {2110}, new HealingEffect(2))),
|
||||
ORANGE_SLICES(new Food(new int[] {2112}, new HealingEffect(2))),
|
||||
PAPAYA_FRUIT(new Food(new int[] {5972}, new HealingEffect(2))),
|
||||
PAPAYA_FRUIT(new Food(new int[] {5972}, new MultiEffect(new EnergyEffect(5), new HealingEffect(8)))),
|
||||
TENTI_PINEAPPLE(new FakeConsumable(1851, new String[] {"Try using a knife to slice it into pieces."})),
|
||||
PINEAPPLE(new FakeConsumable(2114, new String[] {"Try using a knife to slice it into pieces."})),
|
||||
PINEAPPLE_CHUNKS(new Food(new int[] {2116}, new HealingEffect(2))),
|
||||
|
|
@ -169,8 +169,8 @@ public enum Consumables {
|
|||
STRANGE_FRUIT(new Food(new int[] {464}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(30)))),
|
||||
|
||||
/** Gnome Cooking */
|
||||
TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(12))),
|
||||
PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(12))),
|
||||
TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(8))),
|
||||
PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(8))),
|
||||
SPICY_CRUNCHIES(new Food(new int[] {2213}, new HealingEffect(7))),
|
||||
PREMADE_SY_CRUNCH(new Food(new int[] {2241}, new HealingEffect(7))),
|
||||
WORM_CRUNCHIES(new Food(new int[] {2205}, new HealingEffect(8))),
|
||||
|
|
@ -307,7 +307,7 @@ public enum Consumables {
|
|||
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))),
|
||||
EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))),
|
||||
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(6))),
|
||||
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))),
|
||||
EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))),
|
||||
FROG_SPAWN(new Food(new int[] {5004}, new RandomHealthEffect(3, 7), "You eat the frogspawn. Yuck.")),
|
||||
|
||||
|
|
@ -328,7 +328,7 @@ public enum Consumables {
|
|||
ANTIPOISON_(new Potion(new int[] {5943, 5945, 5947, 5949}, new AddTimerEffect("poison:immunity", minutesToTicks(9)))),
|
||||
ANTIPOISON__(new Potion(new int[] {5952, 5954, 5956, 5958}, new AddTimerEffect("poison:immunity", minutesToTicks(12)))),
|
||||
SUPER_ANTIP(new Potion(new int[] {2448, 181, 183, 185}, new AddTimerEffect("poison:immunity", minutesToTicks(6)))),
|
||||
RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new MultiEffect(new SetAttributeEffect("disease:immunity", 300), new RemoveTimerEffect("disease")))),
|
||||
RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new CureDiseaseEffect())),
|
||||
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))),
|
||||
RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))),
|
||||
|
|
@ -339,8 +339,8 @@ public enum Consumables {
|
|||
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))),
|
||||
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), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1), new RandomPrayerEffect(0, 10)))),
|
||||
ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new SetAttributeEffect("fire:immune", 600, 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))),
|
||||
GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))),
|
||||
MAGIC_ESS(new Potion(new int[] {11491, 11489}, new SkillEffect(Skills.MAGIC,3,0))),
|
||||
SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25, true), new AddTimerEffect("poison:immunity", secondsToTicks(90)), new RemoveTimerEffect("disease")))),
|
||||
|
|
@ -349,10 +349,10 @@ public enum Consumables {
|
|||
|
||||
/** Barbarian Mixes */
|
||||
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 DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1), new RandomPrayerEffect(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)))),
|
||||
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 RemoveTimerEffect("disease"), new SetAttributeEffect("disease:immunity", 300), new HealingEffect(3)))),
|
||||
RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new CureDiseaseEffect(), new HealingEffect(3)))),
|
||||
STR_MIX(new BarbarianMix(new int[] {11443, 11441}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0.1), new HealingEffect(3)))),
|
||||
RESTO_MIX(new BarbarianMix(new int[] {11449, 11451}, new MultiEffect(new RestoreEffect(10, 0.3), new HealingEffect(3)))),
|
||||
SUPER_RESTO_MIX(new BarbarianMix(new int [] {11493, 11495}, new MultiEffect(new RestoreEffect(8,0.25), new PrayerEffect(8, 0.25), new SummoningEffect(8, 0.25), new HealingEffect(6)))),
|
||||
|
|
@ -367,6 +367,7 @@ public enum Consumables {
|
|||
SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))),
|
||||
ANTIDOTE_PLUS_MIX(new BarbarianMix(new int[] {11501, 11503}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(9)), new RandomHealthEffect(3, 7)))),
|
||||
ANTIP_SUPERMIX(new BarbarianMix(new int[] {11473, 11475}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(6)), new RandomHealthEffect(3, 7)))),
|
||||
ANTIFIRE_MIX(new BarbarianMix(new int[] {11505, 11507}, new MultiEffect(new AddTimerEffect("dragonfire:immunity", 600, true), new RandomHealthEffect(3, 7)))),
|
||||
|
||||
/** Stealing creation potions */
|
||||
SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package content.data.consumables.effects
|
||||
|
||||
import core.api.*
|
||||
import core.game.consumable.ConsumableEffect
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.timer.impl.Disease
|
||||
|
||||
class CureDiseaseEffect () : ConsumableEffect() {
|
||||
override fun activate (p: Player) {
|
||||
val existingTimer = getTimer<Disease>(p)
|
||||
if (existingTimer != null) {
|
||||
existingTimer.hitsLeft -= 9
|
||||
if (existingTimer.hitsLeft <= 0) {
|
||||
sendMessage(p, "The disease has been cured.")
|
||||
removeTimer<Disease>(p)
|
||||
}else{
|
||||
sendMessage(p,"You feel slightly better.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -30,11 +30,13 @@ public class RestoreEffect extends ConsumableEffect {
|
|||
int[] skills = this.all_skills ? ALL_SKILLS : SKILLS;
|
||||
for(int skill : skills){
|
||||
int statL = sk.getStaticLevel(skill);
|
||||
int boost = (int) (base + (statL * bonus));
|
||||
int curL = sk.getLevel(skill);
|
||||
if(curL < statL){
|
||||
int boost = (int) (base + (statL * bonus));
|
||||
p.getSkills().updateLevel(skill, boost, statL);
|
||||
}
|
||||
if (skill == Skills.PRAYER)
|
||||
p.getSkills().incrementPrayerPoints(boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@ import core.ServerStore.Companion.getString
|
|||
|
||||
import content.global.bots.ShootingStarBot
|
||||
import core.game.world.repository.Repository
|
||||
import core.tools.RandomFunction
|
||||
|
||||
/**
|
||||
* Represents a shooting star object (Only ever initialized once) (ideally)
|
||||
* @author Ceikry
|
||||
*/
|
||||
class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()){
|
||||
class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()) {
|
||||
val crash_locations = mapOf(
|
||||
"East of Dark Wizards' Tower" to Location.create(2925, 3339, 0), // East of Dark Wizards' Tower
|
||||
"Crafting Guild" to Location.create(2940, 3280, 0), // Crafting Guild Mine
|
||||
|
|
@ -30,7 +31,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
"Relleka mining site" to Location.create(2682, 3700, 0), // Rellekka mining site
|
||||
"Jatizso mine" to Location.create(2393, 3815, 0), //Jatiszo mining site (requires Fremennik Isles prereqs)
|
||||
"Lunar Isle mine" to Location.create(2140, 3939, 0), // Lunar Isle mine (requires Lunar Diplomacy prereqs)
|
||||
"Miscellania coal mine" to Location.create(2529, 3887, 0), // Miscellania coal mine (requires Fremennik Trials)
|
||||
"Miscellania coal mine" to Location.create(2529, 3887, 0), // Miscellania coal mine (requires The Fremennik Trials)
|
||||
//"Neitiznot runite mine" to Location.create(2376, 3835, 0), // Near the Neitiznot runite mine (requires Fremennik Isles prereqs) currently inaccessible as bridge does not work
|
||||
"Ardougne mining site" to Location.create(2600, 3232, 0), // Ardougne mining site (Monastery)
|
||||
"Ardougne eastern mine" to Location.create(2706, 3334, 0), // Ardougne mining site (Legends Guild)
|
||||
|
|
@ -79,22 +80,15 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
* Degrades a ShootingStar (or removes the starObject and spawns a Star Sprite if it's the last star)
|
||||
*/
|
||||
fun degrade() {
|
||||
if(level.ordinal == 0){
|
||||
selfBots.filter { it.isMining() }.forEach { it.sleep() }
|
||||
SceneryBuilder.remove(starObject)
|
||||
isSpawned = false
|
||||
starSprite.location = starObject.location
|
||||
starSprite.init()
|
||||
spriteSpawned = true
|
||||
ShootingStarPlugin.getStoreFile().clear()
|
||||
if(level.ordinal == 0) {
|
||||
spawnSprite()
|
||||
return
|
||||
}
|
||||
level = getNextType()
|
||||
maxDust = level.totalStardust
|
||||
dustLeft = level.totalStardust
|
||||
|
||||
ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered
|
||||
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft
|
||||
|
||||
val newStar = Scenery(level.objectId, starObject.location)
|
||||
SceneryBuilder.replace(starObject, newStar)
|
||||
|
|
@ -110,7 +104,6 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
*/
|
||||
fun fire() {
|
||||
SceneryBuilder.remove(starObject)
|
||||
rebuildVars()
|
||||
clearSprite()
|
||||
SceneryBuilder.add(starObject)
|
||||
if(!isSpawned) {
|
||||
|
|
@ -123,37 +116,54 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
}
|
||||
isSpawned = true
|
||||
Repository.sendNews("A shooting star level ${level.ordinal + 1} just crashed near ${location}!")
|
||||
ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
|
||||
ShootingStarPlugin.getStoreFile()["location"] = location
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered
|
||||
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds some of the variables with new information.
|
||||
*/
|
||||
fun rebuildVars(){
|
||||
if(firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()){
|
||||
level = ShootingStarType.values()[ShootingStarPlugin.getStoreFile().getInt("level")]
|
||||
location = ShootingStarPlugin.getStoreFile().getString("location")
|
||||
isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered")
|
||||
} else {
|
||||
level = ShootingStarType.values().random()
|
||||
location = crash_locations.entries.random().key
|
||||
isDiscovered = false
|
||||
// Defaults
|
||||
var levelOrd = RandomFunction.random(9)
|
||||
level = ShootingStarType.values()[levelOrd]
|
||||
location = crash_locations.entries.random().key
|
||||
isDiscovered = false
|
||||
dustLeft = level.totalStardust
|
||||
ticks = 0
|
||||
spriteSpawned = false
|
||||
|
||||
if (firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()) {
|
||||
// Replace default with stored values, if any
|
||||
levelOrd = ShootingStarPlugin.getStoreFile().getInt("level", levelOrd)
|
||||
level = ShootingStarType.values()[levelOrd]
|
||||
location = ShootingStarPlugin.getStoreFile().getString("location", location)
|
||||
isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered", false)
|
||||
dustLeft = ShootingStarPlugin.getStoreFile().getInt("dustLeft", dustLeft)
|
||||
ticks = ShootingStarPlugin.getStoreFile().getInt("ticks", ticks)
|
||||
spriteSpawned = ShootingStarPlugin.getStoreFile().getBoolean("spriteSpawned", false)
|
||||
}
|
||||
|
||||
maxDust = level.totalStardust
|
||||
dustLeft = level.totalStardust
|
||||
starObject = Scenery(level.objectId, crash_locations.get(location))
|
||||
}
|
||||
|
||||
ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
|
||||
ShootingStarPlugin.getStoreFile()["location"] = location
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = false
|
||||
|
||||
ticks = 0
|
||||
firstStar = false
|
||||
fun spawnSprite() {
|
||||
selfBots.filter { it.isMining() }.forEach { it.sleep() }
|
||||
SceneryBuilder.remove(starObject)
|
||||
isSpawned = false
|
||||
starSprite.location = starObject.location
|
||||
starSprite.init()
|
||||
spriteSpawned = true
|
||||
ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned
|
||||
}
|
||||
|
||||
fun clearSprite() {
|
||||
starSprite.clear()
|
||||
spriteSpawned = false
|
||||
ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -161,6 +171,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
*/
|
||||
fun decDust() {
|
||||
if(--dustLeft <= 0) degrade()
|
||||
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
|
|||
player.sendMessage("You have ${player.skills.experienceMultiplier * player.getAttribute("shooting-star:bonus-xp", 0).toDouble()} bonus xp towards mining stardust.")
|
||||
ShootingStarPlugin.submitScoreBoard(player)
|
||||
star.isDiscovered = true
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered
|
||||
return player.skills.getLevel(Skills.MINING) >= star.miningLevel
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ import core.ServerStore.Companion.getBoolean
|
|||
import core.game.dialogue.DialogueFile
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.tools.SystemLogger
|
||||
import core.game.system.command.Privilege
|
||||
import core.game.world.GameWorld
|
||||
import core.tools.Log
|
||||
import core.tools.secondsToTicks
|
||||
import content.data.Quests
|
||||
|
||||
class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener {
|
||||
override fun login(player: Player) {
|
||||
|
|
@ -27,14 +27,30 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
override fun tick() {
|
||||
++star.ticks
|
||||
|
||||
// Check if the current star sprite should expire
|
||||
val maxDelay = tickDelay + (tickDelay / 3)
|
||||
if(star.ticks > maxDelay && star.spriteSpawned){
|
||||
star.clearSprite()
|
||||
}
|
||||
|
||||
if ((star.ticks >= tickDelay && !star.spriteSpawned) || (!star.isSpawned && !star.spriteSpawned)) {
|
||||
if (star.firstStar && !star.isSpawned && !star.spriteSpawned) {
|
||||
// Apparently, the server has only just booted
|
||||
star.rebuildVars()
|
||||
if (star.spriteSpawned) {
|
||||
star.spawnSprite()
|
||||
} else {
|
||||
star.fire()
|
||||
}
|
||||
star.firstStar = false
|
||||
}
|
||||
|
||||
// Check if it's time to fire a new one
|
||||
if (star.ticks >= tickDelay && !star.spriteSpawned) {
|
||||
star.rebuildVars()
|
||||
star.fire()
|
||||
}
|
||||
|
||||
getStoreFile()["ticks"] = star.ticks
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
|
|
@ -80,17 +96,17 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
fun teleportToStar(player: Player) {
|
||||
val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) {
|
||||
"canifis bank" -> {p -> requireQuest(p, "Priest in Peril", "to access this.") }
|
||||
//"burgh de rott bank" -> {p -> hasRequirement(p, "In Aid of the Myreque") } //disabled: crash
|
||||
"crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40) }
|
||||
"lletya bank" -> {p -> hasRequirement(p, "Mourning's End Part I") }
|
||||
"jatizso mine" -> {p -> hasRequirement(p, "The Fremennik Isles") }
|
||||
"south crandor mining site" -> {p -> hasRequirement(p, "Dragon Slayer") }
|
||||
"shilo village mining site" -> {p -> hasRequirement(p, "Shilo Village") }
|
||||
"mos le'harmless bank" -> {p -> hasRequirement(p, "Cabin Fever") } //needs to be updated to check for completion when the quest releases; https://runescape.wiki/w/Mos_Le%27Harmless?oldid=913025
|
||||
"lunar isle mine" -> {p -> hasRequirement(p, "Lunar Diplomacy") }
|
||||
"miscellania coal mine" -> {p -> requireQuest(p, "The Fremennik Trials", "to access this.") }
|
||||
//"neitiznot runite mine" -> {p -> hasRequirement(p, "The Fremennik Isles") } //disabled: currently not reachable
|
||||
"canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")}
|
||||
//"burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} //disabled: crash
|
||||
"crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)}
|
||||
"lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)}
|
||||
"jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)}
|
||||
"south crandor mining site" -> {p -> hasRequirement(p, Quests.DRAGON_SLAYER)}
|
||||
"shilo village mining site" -> {p -> hasRequirement(p, Quests.SHILO_VILLAGE)}
|
||||
"mos le'harmless bank" -> {p -> hasRequirement(p, Quests.CABIN_FEVER)} //needs to be updated to check for completion when the quest releases; https://runescape.wiki/w/Mos_Le%27Harmless?oldid=913025
|
||||
"lunar isle mine" -> {p -> hasRequirement(p, Quests.LUNAR_DIPLOMACY)}
|
||||
"miscellania coal mine" -> {p -> requireQuest(p, Quests.THE_FREMENNIK_TRIALS, "to access this.")}
|
||||
//"neitiznot runite mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} //disabled: currently not reachable
|
||||
else -> {_ -> true}
|
||||
}
|
||||
if (!condition.invoke(player)) {
|
||||
|
|
@ -122,6 +138,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
}
|
||||
|
||||
define("submit", Privilege.ADMIN) { _, _ ->
|
||||
star.rebuildVars()
|
||||
star.fire()
|
||||
}
|
||||
|
||||
|
|
|
|||
23
Server/src/main/content/global/ame/KidnapHelper.kt
Normal file
23
Server/src/main/content/global/ame/KidnapHelper.kt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package content.global.ame
|
||||
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager.TeleportType
|
||||
import core.game.world.map.Location
|
||||
|
||||
fun kidnapPlayer(player: Player, loc: Location, type: TeleportType) {
|
||||
setAttribute(player, "kidnapped-by-random", true)
|
||||
if (getAttribute(player, "/save:original-loc", null) == null) {
|
||||
setAttribute(player, "/save:original-loc", player.location)
|
||||
}
|
||||
teleport(player, loc, type)
|
||||
}
|
||||
|
||||
fun returnPlayer(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
|
||||
teleport(player, destination)
|
||||
unlock(player)
|
||||
removeAttributes(player, "/save:original-loc", "kidnapped-by-random")
|
||||
}
|
||||
|
|
@ -3,9 +3,15 @@ package content.global.ame
|
|||
import content.global.ame.events.MysteriousOldManNPC
|
||||
import core.api.playGlobalAudio
|
||||
import core.api.poofClear
|
||||
import core.api.sendMessage
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.CombatStyle
|
||||
import core.game.node.entity.impl.PulseType
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.agg.AggressiveBehavior
|
||||
import core.game.node.entity.npc.agg.AggressiveHandler
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
|
|
@ -13,10 +19,11 @@ import core.game.world.map.RegionManager
|
|||
import core.game.world.map.path.Pathfinder
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.integrations.discord.Discord
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.tools.secondsToTicks
|
||||
import core.tools.ticksToCycles
|
||||
import org.rs09.consts.Sounds
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.min
|
||||
import kotlin.random.Random
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
|
|
@ -66,7 +73,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
if (!player.getAttribute("random:pause", false)) {
|
||||
ticksLeft--
|
||||
}
|
||||
|
||||
if (!pulseManager.hasPulseRunning() && !finalized) {
|
||||
follow()
|
||||
}
|
||||
|
|
@ -87,6 +93,11 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
location = spawnLocation
|
||||
player.setAttribute("re-npc", this)
|
||||
super.init()
|
||||
super.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() {
|
||||
override fun canSelectTarget(entity: Entity, target: Entity): Boolean {
|
||||
return target == player
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
open fun onTimeUp() {
|
||||
|
|
@ -118,4 +129,19 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
}
|
||||
|
||||
abstract fun talkTo(npc: NPC)
|
||||
}
|
||||
|
||||
override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean {
|
||||
if (entity != player) {
|
||||
if (entity is Player) {
|
||||
sendMessage(entity, "It isn't interested in fighting you.") //TODO authentic message
|
||||
}
|
||||
return false
|
||||
}
|
||||
return super.isAttackable(entity, style, message)
|
||||
}
|
||||
|
||||
fun idForCombatLevel(ids: List<Int>, player: Player): Int {
|
||||
val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1
|
||||
return ids[index]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,16 +3,18 @@ package content.global.ame
|
|||
import org.rs09.consts.Items
|
||||
import content.global.ame.events.MysteriousOldManNPC
|
||||
import content.global.ame.events.certer.CerterNPC
|
||||
import content.global.ame.events.drilldemon.SeargentDamienNPC
|
||||
import content.global.ame.events.drilldemon.SergeantDamienNPC
|
||||
import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC
|
||||
import content.global.ame.events.evilbob.EvilBobNPC
|
||||
import content.global.ame.events.evilchicken.EvilChickenNPC
|
||||
import content.global.ame.events.freakyforester.FreakyForesterNPC
|
||||
import content.global.ame.events.maze.MazeNPC
|
||||
import content.global.ame.events.genie.GenieNPC
|
||||
import content.global.ame.events.pillory.PilloryNPC
|
||||
import content.global.ame.events.rickturpentine.RickTurpentineNPC
|
||||
import content.global.ame.events.rivertroll.RiverTrollRENPC
|
||||
import content.global.ame.events.rockgolem.RockGolemRENPC
|
||||
import content.global.ame.events.quizmaster.QuizMasterNPC
|
||||
import content.global.ame.events.sandwichlady.SandwichLadyRENPC
|
||||
import content.global.ame.events.shade.ShadeRENPC
|
||||
import content.global.ame.events.strangeplant.StrangePlantNPC
|
||||
|
|
@ -44,7 +46,8 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
|
|||
WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,0.1),
|
||||
WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1)
|
||||
)),
|
||||
DRILL_DEMON(npc = SeargentDamienNPC()),
|
||||
MAZE(npc = MazeNPC()),
|
||||
DRILL_DEMON(npc = SergeantDamienNPC()),
|
||||
EVIL_CHICKEN(npc = EvilChickenNPC()),
|
||||
STRANGE_PLANT(npc = StrangePlantNPC()),
|
||||
SWARM(npc = SwarmNPC()),
|
||||
|
|
@ -55,6 +58,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
|
|||
FREAKY_FORESTER(npc = FreakyForesterNPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
|
||||
PILLORY(npc = PilloryNPC(), skillIds = intArrayOf(Skills.THIEVING)),
|
||||
TREE_SPIRIT(npc = TreeSpiritRENPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
|
||||
QUIZ_MASTER(npc = QuizMasterNPC()),
|
||||
RIVER_TROLL(RiverTrollRENPC(), skillIds = intArrayOf(Skills.FISHING)),
|
||||
ROCK_GOLEM(RockGolemRENPC(), skillIds = intArrayOf(Skills.MINING)),
|
||||
SHADE(ShadeRENPC(), skillIds = intArrayOf(Skills.PRAYER)),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package content.global.ame.events
|
||||
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class HostileRandomEventBehavior : NPCBehavior(
|
||||
NPCs.EVIL_CHICKEN_2463, NPCs.EVIL_CHICKEN_2464, NPCs.EVIL_CHICKEN_2465, NPCs.EVIL_CHICKEN_2466, NPCs.EVIL_CHICKEN_2467, NPCs.EVIL_CHICKEN_2468,
|
||||
NPCs.RIVER_TROLL_391, NPCs.RIVER_TROLL_392, NPCs.RIVER_TROLL_393, NPCs.RIVER_TROLL_394, NPCs.RIVER_TROLL_395, NPCs.RIVER_TROLL_396,
|
||||
NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418,
|
||||
NPCs.SHADE_425, NPCs.SHADE_426, NPCs.SHADE_427, NPCs.SHADE_428, NPCs.SHADE_429, NPCs.SHADE_430, NPCs.SHADE_431,
|
||||
NPCs.TREE_SPIRIT_438, NPCs.TREE_SPIRIT_439, NPCs.TREE_SPIRIT_440, NPCs.TREE_SPIRIT_441, NPCs.TREE_SPIRIT_442, NPCs.TREE_SPIRIT_443,
|
||||
NPCs.ZOMBIE_419, NPCs.ZOMBIE_420, NPCs.ZOMBIE_421, NPCs.ZOMBIE_422, NPCs.ZOMBIE_423, NPCs.ZOMBIE_424
|
||||
) {
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return super.getXpMultiplier(self, attacker) / 16.0
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
package content.global.ame.events.drilldemon
|
||||
|
||||
import core.ServerConstants
|
||||
import content.global.ame.kidnapPlayer
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.update.flag.context.Animation
|
||||
|
|
@ -12,7 +14,6 @@ import org.rs09.consts.NPCs
|
|||
|
||||
object DrillDemonUtils {
|
||||
val DD_KEY_TASK = "/save:drilldemon:task"
|
||||
val DD_KEY_RETURN_LOC = "/save:original-loc"
|
||||
val DD_SIGN_VARP = 531
|
||||
val DD_SIGN_JOG = 0
|
||||
val DD_SIGN_SITUP = 1
|
||||
|
|
@ -24,10 +25,7 @@ object DrillDemonUtils {
|
|||
val DD_NPC = NPCs.SERGEANT_DAMIEN_2790
|
||||
|
||||
fun teleport(player: Player) {
|
||||
if (getAttribute(player, DD_KEY_RETURN_LOC, null) == null) {
|
||||
setAttribute(player, DD_KEY_RETURN_LOC, player.location)
|
||||
}
|
||||
teleport(player, Location.create(3163, 4819, 0))
|
||||
kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT)
|
||||
player.interfaceManager.closeDefaultTabs()
|
||||
setComponentVisibility(player, 548, 69, true)
|
||||
setComponentVisibility(player, 746, 12, true)
|
||||
|
|
@ -66,14 +64,8 @@ object DrillDemonUtils {
|
|||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
unlock(player)
|
||||
val destination = getAttribute(player, DD_KEY_RETURN_LOC, ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
|
||||
teleport(player, destination)
|
||||
removeAttribute(player, DD_KEY_RETURN_LOC)
|
||||
removeAttribute(player, DD_KEY_TASK)
|
||||
removeAttribute(player, DD_CORRECT_OFFSET)
|
||||
removeAttribute(player, DD_CORRECT_COUNTER)
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, DD_KEY_TASK, DD_CORRECT_OFFSET, DD_CORRECT_COUNTER)
|
||||
player.interfaceManager.openDefaultTabs()
|
||||
setComponentVisibility(player, 548, 69, false)
|
||||
setComponentVisibility(player, 746, 12, false)
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ import core.game.interaction.QueueStrength
|
|||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.tools.secondsToTicks
|
||||
|
||||
class SeargentDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
|
||||
class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat(player.username.capitalize() + "! Drop and give me 20!")
|
||||
sendChat(player.username+ "! Drop and give me 20!")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.ame.events.evilbob
|
||||
|
||||
import content.global.ame.returnPlayer
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.dialogue.FacialExpression
|
||||
|
|
@ -8,8 +9,6 @@ import core.game.interaction.InteractionListener
|
|||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.link.emote.Emotes
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
|
|
@ -121,8 +120,7 @@ class EvilBobListeners : InteractionListener, MapArea {
|
|||
}
|
||||
3 -> {
|
||||
sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.")
|
||||
val destination = getAttribute(player, EvilBobUtils.prevLocation, ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
|
||||
teleport(player, destination)
|
||||
returnPlayer(player)
|
||||
EvilBobUtils.reward(player)
|
||||
EvilBobUtils.cleanup(player)
|
||||
resetAnimator(player)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package content.global.ame.events.evilbob
|
||||
|
||||
import core.ServerConstants
|
||||
import content.global.ame.kidnapPlayer
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
|
|
@ -14,7 +16,6 @@ import org.rs09.consts.NPCs
|
|||
import org.rs09.consts.Scenery
|
||||
|
||||
object EvilBobUtils {
|
||||
const val prevLocation = "/save:original-loc"
|
||||
const val eventComplete = "/save:evilbob:eventcomplete"
|
||||
const val assignedFishingZone = "/save:evilbob:fishingzone"
|
||||
const val attentive = "/save:evilbob:attentive"
|
||||
|
|
@ -53,16 +54,11 @@ object EvilBobUtils {
|
|||
}
|
||||
|
||||
fun teleport(player: Player) {
|
||||
if (getAttribute(player, prevLocation, null) == null) {
|
||||
setAttribute(player, prevLocation, player.location)
|
||||
}
|
||||
player.properties.teleportLocation = Location.create(3419, 4776, 0)
|
||||
kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
player.properties.teleportLocation = getAttribute(player, prevLocation, ServerConstants.HOME_LOCATION)
|
||||
removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
|
||||
removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
|
||||
removeAll(player, Items.FISHLIKE_THING_6202)
|
||||
removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK)
|
||||
removeAll(player, Items.FISHLIKE_THING_6206)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ import core.tools.RandomFunction
|
|||
import org.rs09.consts.Items
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import java.lang.Integer.max
|
||||
|
||||
val ids = 2463..2468
|
||||
val ids = (2463..2468).toList()
|
||||
|
||||
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!")
|
||||
|
|
@ -19,8 +18,7 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN
|
|||
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, (player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat(phrases.random().replace("@name",player.username.capitalize()))
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
package content.global.ame.events.freakyforester
|
||||
|
||||
import core.ServerConstants
|
||||
import content.global.ame.kidnapPlayer
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.tools.RandomFunction
|
||||
|
||||
object FreakUtils{
|
||||
const val freakNpc = NPCs.FREAKY_FORESTER_2458
|
||||
const val freakPreviousLoc = "/save:original-loc"
|
||||
const val freakTask = "/save:freakyf:task"
|
||||
const val freakComplete = "/save:freakyf:complete"
|
||||
const val pheasantKilled = "freakyf:killed"
|
||||
|
|
@ -28,16 +29,12 @@ object FreakUtils{
|
|||
}
|
||||
|
||||
fun teleport(player: Player) {
|
||||
if (getAttribute(player, freakPreviousLoc,null) == null) {
|
||||
setAttribute(player, freakPreviousLoc, player.location)
|
||||
}
|
||||
teleport(player, Location.create(2599, 4777 ,0))
|
||||
kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
player.properties.teleportLocation = getAttribute(player,freakPreviousLoc, ServerConstants.HOME_LOCATION)
|
||||
removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled)
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, freakTask, freakComplete, pheasantKilled)
|
||||
removeAll(player, Items.RAW_PHEASANT_6178)
|
||||
removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK)
|
||||
removeAll(player, Items.RAW_PHEASANT_6179)
|
||||
|
|
|
|||
277
Server/src/main/content/global/ame/events/maze/MazeInterface.kt
Normal file
277
Server/src/main/content/global/ame/events/maze/MazeInterface.kt
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
package content.global.ame.events.maze
|
||||
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.api.utils.WeightedItem
|
||||
import core.game.event.EventHook
|
||||
import core.game.event.TickEvent
|
||||
import core.game.global.action.DoorActionHandler
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.Entity
|
||||
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.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.*
|
||||
|
||||
class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||
companion object {
|
||||
const val MAZE_TIMER_INTERFACE = Components.MAZETIMER_209
|
||||
const val MAZE_TIMER_VARP = 531 // Interface 209 child 2 config: [531, 0]
|
||||
const val MAZE_ATTRIBUTE_TICKS_LEFT = "maze:percent-ticks-left"
|
||||
const val MAZE_ATTRIBUTE_CHESTS_OPEN = "/save:maze:chests-opened"
|
||||
|
||||
val STARTING_POINTS = arrayOf(
|
||||
Location(2928, 4553, 0),
|
||||
Location(2917, 4553, 0),
|
||||
Location(2908, 4555, 0),
|
||||
Location(2891, 4589, 0),
|
||||
Location(2891, 4595, 0),
|
||||
Location(2891, 4595, 0),
|
||||
Location(2926, 4597, 0),
|
||||
Location(2931, 4597, 0),
|
||||
// There's 2 more, but there isn't a door for them...
|
||||
)
|
||||
|
||||
val REWARD_ITEM = intArrayOf(
|
||||
Items.COINS_995,
|
||||
Items.FEATHER_314,
|
||||
Items.IRON_ARROW_884,
|
||||
Items.CHAOS_RUNE_562,
|
||||
Items.STEEL_ARROW_886,
|
||||
Items.DEATH_RUNE_560,
|
||||
Items.COAL_454,
|
||||
Items.NATURE_RUNE_561,
|
||||
Items.MITHRIL_ORE_448
|
||||
)
|
||||
|
||||
val ITEM_DIVISOR = arrayOf(
|
||||
1.0,
|
||||
2.0,
|
||||
3.0,
|
||||
9.0,
|
||||
12.0,
|
||||
18.0,
|
||||
45.0,
|
||||
162.0,
|
||||
180.0,
|
||||
)
|
||||
|
||||
val CHEST_REWARDS = WeightBasedTable.create(
|
||||
WeightedItem(Items.AIR_RUNE_556,15,15,1.0),
|
||||
WeightedItem(Items.WATER_RUNE_555,10,10,1.0),
|
||||
WeightedItem(Items.EARTH_RUNE_557,10,10,1.0),
|
||||
WeightedItem(Items.FIRE_RUNE_554,10,10,1.0),
|
||||
WeightedItem(Items.BRONZE_ARROW_882,20,20,1.0),
|
||||
WeightedItem(Items.BRONZE_BOLTS_877,10,10,1.0),
|
||||
WeightedItem(Items.IRON_ARROW_884,15,15,1.0),
|
||||
WeightedItem(Items.ATTACK_POTION2_123,1,1,1.0),
|
||||
WeightedItem(Items.STRENGTH_POTION2_117,1,1,1.0),
|
||||
WeightedItem(Items.DEFENCE_POTION2_135,1,1,1.0),
|
||||
)
|
||||
|
||||
fun initMaze(player: Player) {
|
||||
setAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 300)
|
||||
setVarp(player, MAZE_TIMER_VARP, (getAttribute<Int>(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) / 3),false)
|
||||
openOverlay(player, MAZE_TIMER_INTERFACE)
|
||||
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.")
|
||||
}
|
||||
|
||||
fun calculateLoot(player: Player) {
|
||||
val randomNumber = (0..8).random()
|
||||
val totalLevel = player.getSkills().totalLevel.toDouble()
|
||||
val rewardPotential = getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0).toDouble() / 300.0
|
||||
val itemDivisor = ITEM_DIVISOR[randomNumber]
|
||||
val itemQuantity = (totalLevel * rewardPotential * 3.33) / itemDivisor
|
||||
// sendMessage(player, "Maze reward calculation: $totalLevel * $rewardPotential * 3.33 / $itemDivisor = $itemQuantity")
|
||||
if (itemQuantity.toInt() > 0) {
|
||||
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() {
|
||||
|
||||
// This somehow doesn't trigger as the scenery.id != objId (3626 != 3635)
|
||||
on(Scenery.CHEST_3635, IntType.SCENERY, "open") { player, node ->
|
||||
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()
|
||||
addItemOrBank(player, tableRoll[0].id)
|
||||
when (tableRoll[0].id){
|
||||
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.EARTH_RUNE_557 -> sendItemDialogue(player, Items.EARTH_RUNE_557, "You've found some earth runes!")
|
||||
Items.FIRE_RUNE_554 -> sendItemDialogue(player, Items.FIRE_RUNE_554, "You've found some fire runes!")
|
||||
Items.BRONZE_ARROW_882 -> sendItemDialogue(player, Items.BRONZE_ARROW_882, "You've found some bronze arrows!")
|
||||
Items.BRONZE_BOLTS_877 -> sendItemDialogue(player, Items.BRONZE_BOLTS_877, "You've found some bronze bolts!")
|
||||
Items.IRON_ARROW_884 -> sendItemDialogue(player, Items.IRON_ARROW_884, "You've found some iron arrows!")
|
||||
Items.ATTACK_POTION2_123 -> sendItemDialogue(player, Items.ATTACK_POTION2_123, "You've found an attack 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!")
|
||||
}
|
||||
setAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0))
|
||||
} else {
|
||||
sendMessage(player,"You find nothing of interest.")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.CHEST_3636, SCENERY, "search") { player, node ->
|
||||
sendMessage(player,"You find nothing of interest.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.WALL_3626, IntType.SCENERY, "open") { player, node ->
|
||||
sendMessage(player, "That bit doesn't open.") // 0xBrLo9woIY
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.WALL_3628, IntType.SCENERY, "open") { player, node ->
|
||||
// Door opening workaround
|
||||
// Ignore 3629(WALL_3629) and 3630(WALL_3630) in handleAutowalkDoor ignoreSecondDoor
|
||||
DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.STRANGE_SHRINE_3634, IntType.SCENERY, "touch") { player, node ->
|
||||
player.unhook(this)
|
||||
closeOverlay(player)
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(86, 0, 3), player.location)
|
||||
animate(player,862)
|
||||
return@queueScript delayScript(player, 6)
|
||||
}
|
||||
1 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
2 -> {
|
||||
returnPlayer(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
closeOverlay(player)
|
||||
return@queueScript delayScript(player, 1)
|
||||
}
|
||||
3 -> {
|
||||
calculateLoot(player)
|
||||
removeAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT)
|
||||
removeAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun process(entity: Entity, event: TickEvent) {
|
||||
if (entity is Player) {
|
||||
if (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0) {
|
||||
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) / 3), false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(getRegionBorders(11591))
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (entity is Player) {
|
||||
sendMessage(entity, "Head for the center of the maze.")
|
||||
entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12)
|
||||
openOverlay(entity, MAZE_TIMER_INTERFACE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.restoreTabs()
|
||||
closeOverlay(entity)
|
||||
entity.unhook(this)
|
||||
}
|
||||
}
|
||||
override fun entityStep(entity: Entity, location: Location, lastLocation: Location) {
|
||||
if (entity is Player) {
|
||||
entity.hook(Event.Tick, this)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
57
Server/src/main/content/global/ame/events/maze/MazeNPC.kt
Normal file
57
Server/src/main/content/global/ame/events/maze/MazeNPC.kt
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package content.global.ame.events.maze
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import content.global.ame.kidnapPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.build.DynamicRegion
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("Aha, you'll do ${player.username}!")
|
||||
face(player)
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
MazeInterface.initMaze(player)
|
||||
// Note: This event is NOT instanced:
|
||||
// Sources:
|
||||
// https://youtu.be/2gpzn9oNdy0 (2007)
|
||||
// https://youtu.be/Tni1HURgnxg (2008)
|
||||
// https://youtu.be/igdwDZOv9LU (2008)
|
||||
// https://youtu.be/0oBCkLArUmc (2011 - even with personal Mysterious Old Man) - "Sorry, this is not the old man you are looking for."
|
||||
// https://youtu.be/FMuKZm-Ikgs (2011)
|
||||
// val region = DynamicRegion.create(11591)
|
||||
kidnapPlayer(player, MazeInterface.STARTING_POINTS.random(), TeleportManager.TeleportType.INSTANT) // 10 random spots
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package content.global.ame.events.pillory
|
||||
|
||||
import content.global.ame.RandomEvents
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.IntType
|
||||
|
|
@ -42,11 +43,10 @@ import org.rs09.consts.Sounds
|
|||
class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
||||
companion object {
|
||||
const val PILLORY_LOCK_INTERFACE = 189
|
||||
const val PILLORY_ATRRIBUTE_RETURN_LOC = "/save:original-loc"
|
||||
const val PILLORY_ATTRIBUTE_EVENT_KEYS = "pillory:event-keys"
|
||||
const val PILLORY_ATTRIBUTE_EVENT_LOCK = "pillory:event-lock"
|
||||
const val PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct"
|
||||
const val PILLORY_ATRRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct"
|
||||
const val PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct"
|
||||
const val PILLORY_ATTRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct"
|
||||
|
||||
val LOCATIONS = arrayOf(
|
||||
// Varrock Cages
|
||||
|
|
@ -64,8 +64,8 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
|||
)
|
||||
|
||||
fun initPillory(player: Player) {
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")
|
||||
}
|
||||
|
||||
|
|
@ -82,8 +82,8 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
|||
player.packetDispatch.sendModelOnInterface(9749 + keys[2], PILLORY_LOCK_INTERFACE, 6, 0)
|
||||
player.packetDispatch.sendModelOnInterface(9749 + keys[3], PILLORY_LOCK_INTERFACE, 7, 0)
|
||||
|
||||
val numberToGetCorrect = getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
val correctCount = getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
|
||||
val numberToGetCorrect = getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
val correctCount = getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
|
||||
for (i in 1.. 6) {
|
||||
// Set if lock is red or green.
|
||||
if (i <= correctCount) {
|
||||
|
|
@ -101,12 +101,12 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
|||
val lock = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, -1)
|
||||
if (keys[buttonID] == lock) {
|
||||
// CORRECT ANSWER
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0) + 1)
|
||||
if (getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, -1)) {
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + 1)
|
||||
if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, -1)) {
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "You've escaped!")
|
||||
sendMessage(player, "You've escaped!")
|
||||
removeAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT)
|
||||
removeAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER)
|
||||
removeAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT)
|
||||
removeAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER)
|
||||
closeInterface(player)
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
|
|
@ -120,10 +120,9 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
|||
1 -> {
|
||||
val loot = RandomEvents.CERTER.loot!!.roll(player)[0]
|
||||
addItemOrDrop(player, loot.id, loot.amount)
|
||||
teleport(player, getAttribute(player, PILLORY_ATRRIBUTE_RETURN_LOC, Location.create(3222, 3218, 0)))
|
||||
returnPlayer(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
removeAttribute(player, PILLORY_ATRRIBUTE_RETURN_LOC)
|
||||
closeInterface(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
|
@ -137,19 +136,19 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
|||
true,
|
||||
"",
|
||||
"Correct!",
|
||||
"" + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0) + " down, " +
|
||||
(getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)) + " to go!")
|
||||
"" + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + " down, " +
|
||||
(getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)) + " to go!")
|
||||
// Animation for the star, but it doesn't work.
|
||||
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 1), false)
|
||||
sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 1))
|
||||
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1), false)
|
||||
sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1))
|
||||
} else {
|
||||
// WRONG ANSWER
|
||||
player.dialogueInterpreter.close()
|
||||
player.dialogueInterpreter.sendDialogues(NPCs.TRAMP_2794 , FacialExpression.OLD_ANGRY1, "Bah, that's not right.","Use the key that matches the hole", "in the spinning lock.")
|
||||
if (getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) {
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATRRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1)
|
||||
if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) {
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1)
|
||||
}
|
||||
setAttribute(player, PILLORY_ATRRIBUTE_CORRECT_COUNTER, 0)
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
|
||||
closeInterface(player)
|
||||
}
|
||||
}
|
||||
|
|
@ -201,7 +200,7 @@ class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
|||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT)
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package content.global.ame.events.pillory
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import content.global.ame.kidnapPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
|
|
@ -29,11 +31,9 @@ class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(N
|
|||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
if (getAttribute<Location?>(player, PilloryInterface.PILLORY_ATRRIBUTE_RETURN_LOC, null) == null) {
|
||||
setAttribute(player, PilloryInterface.PILLORY_ATRRIBUTE_RETURN_LOC, player.location)
|
||||
}
|
||||
PilloryInterface.initPillory(player)
|
||||
teleport(player, PilloryInterface.LOCATIONS.random()) // 9 random spots!
|
||||
val dest = PilloryInterface.LOCATIONS.random() //9 random spots!
|
||||
kidnapPlayer(player, dest, TeleportManager.TeleportType.INSTANT)
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package content.global.ame.events.quizmaster
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class QuizMasterBorders : MapArea {
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(getRegionBorders(7754))
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12)
|
||||
face(entity, Location(1952, 4768, 1))
|
||||
animate(entity,2378)
|
||||
openDialogue(entity, QuizMasterDialogueFile(), NPC(NPCs.QUIZ_MASTER_2477))
|
||||
}
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.restoreTabs()
|
||||
//closeOverlay(entity)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
package content.global.ame.events.quizmaster
|
||||
|
||||
import content.global.ame.returnPlayer
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.api.utils.WeightedItem
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class QuizMasterDialogueFile : DialogueFile() {
|
||||
companion object {
|
||||
const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191
|
||||
const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct"
|
||||
const val QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER = "quizmaster:random-answer"
|
||||
|
||||
/*
|
||||
// Golden Models:
|
||||
8828 ADAMANT_BATTLEAXE_1371
|
||||
8829 SALMON_329
|
||||
8830 TROUT_333
|
||||
8831 NECKLACE
|
||||
8832 WOODEN_SHIELD_1171
|
||||
8833 BRONZE_MED_HELM_1139
|
||||
8834 RING
|
||||
8835 SECATEURS_5329
|
||||
8836 BRONZE_SWORD_1277
|
||||
8837 GARDENING_TROWEL_5325
|
||||
*/
|
||||
val sets = arrayOf(
|
||||
intArrayOf(8828, 8829, 8829),
|
||||
intArrayOf(8831, 8837, 8835),
|
||||
intArrayOf(8830, 8832, 8833),
|
||||
intArrayOf(8835, 8834, 8831),
|
||||
intArrayOf(8837, 8836, 8828),
|
||||
)
|
||||
|
||||
fun randomQuestion(player: Player): Int {
|
||||
val randomSet = intArrayOf(*sets.random())
|
||||
val answer = intArrayOf(*randomSet)[0]
|
||||
randomSet.shuffle()
|
||||
val correctButton = randomSet.indexOf(answer) + 2 // buttons are 3,4,5
|
||||
|
||||
player.packetDispatch.sendModelOnInterface(randomSet[0], QUIZMASTER_INTERFACE, 6, 512)
|
||||
player.packetDispatch.sendModelOnInterface(randomSet[1], QUIZMASTER_INTERFACE, 7, 512)
|
||||
player.packetDispatch.sendModelOnInterface(randomSet[2], QUIZMASTER_INTERFACE, 8, 512)
|
||||
player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 6, 512,0,0)
|
||||
player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 7, 512,0,0)
|
||||
player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 8, 512,0,0)
|
||||
|
||||
return correctButton
|
||||
}
|
||||
|
||||
// Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas.
|
||||
val tableRoll = WeightBasedTable.create(
|
||||
WeightedItem(Items.LAMP_6796, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.CABBAGE_1965, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.DIAMOND_1601, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.BUCKET_1925, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.FLIER_956, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.OLD_BOOT_685, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.BODY_RUNE_559, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.ONION_1957, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.MITHRIL_SCIMITAR_1329, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.CASKET_405, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.STEEL_PLATEBODY_1119, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.NATURE_RUNE_561, 20, 20, 1.0, false),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (stage) {
|
||||
0 -> npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>").also { stage++ }
|
||||
1 -> player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...").also { stage++ }
|
||||
2 -> npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "<col=FF0000>${player?.username}</col>!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!").also { stage++ }
|
||||
3 -> {
|
||||
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player!!))
|
||||
player!!.interfaceManager.openChatbox(QUIZMASTER_INTERFACE)
|
||||
stage++
|
||||
}
|
||||
4-> {
|
||||
if (buttonID == getAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) {
|
||||
// Correct Answer
|
||||
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1)
|
||||
if (getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) {
|
||||
npc(FacialExpression.FRIENDLY,"<col=08088A>CONGRATULATIONS!</col>", "You are a <col=8A0808>WINNER</col>!", "Please choose your <col=08088A>PRIZE</col>!")
|
||||
stage = 5
|
||||
} else {
|
||||
npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!")
|
||||
stage = 3
|
||||
}
|
||||
} else {
|
||||
// Wrong Answer
|
||||
npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!")
|
||||
stage = 3
|
||||
}
|
||||
}
|
||||
// Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas.
|
||||
5 -> options("1000 Coins", "Random Item").also { stage++ }
|
||||
6 -> {
|
||||
resetAnimator(player!!)
|
||||
returnPlayer(player!!)
|
||||
when (buttonID) {
|
||||
1 -> {
|
||||
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
addItemOrDrop(player!!, Items.COINS_995, 1000)
|
||||
return@queueScript stopExecuting(player!!)
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
addItemOrDrop(player!!, tableRoll.roll()[0].id)
|
||||
return@queueScript stopExecuting(player!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAttributes(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
|
||||
stage = END_DIALOGUE
|
||||
end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package content.global.ame.events.quizmaster
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import content.global.ame.kidnapPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
/**
|
||||
* Quiz Master NPC:
|
||||
*
|
||||
* https://www.youtube.com/watch?v=EFAWSiPTfcM
|
||||
* https://www.youtube.com/watch?v=caWn7pE2mkE
|
||||
* https://www.youtube.com/watch?v=Bc1gAov2o4w
|
||||
* https://www.youtube.com/watch?v=oHU8-MUarxE
|
||||
* https://www.youtube.com/watch?v=wvjYiF4v9tI
|
||||
* https://www.youtube.com/watch?v=dC6rlSnXEfw
|
||||
*/
|
||||
class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.QUIZ_MASTER_2477) {
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("Hey ${player.username}! It's your lucky day!")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
kidnapPlayer(player, Location(1952, 4764, 1), TeleportManager.TeleportType.INSTANT)
|
||||
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.")
|
||||
sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case.
|
||||
return@queueScript delayScript(player, 6)
|
||||
}
|
||||
2 -> {
|
||||
face(player, Location(1952, 4768, 1))
|
||||
animate(player,2378)
|
||||
// This is not needed as when you enter the QuizMasterBorders, it should fire off the dialogue
|
||||
// openDialogue(player, QuizMasterDialogueFile(), this.asNpc())
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
openDialogue(player, QuizMasterDialogueFile(), this.asNpc())
|
||||
}
|
||||
}
|
||||
|
|
@ -4,17 +4,14 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import java.lang.Integer.max
|
||||
|
||||
|
||||
val ids = 391..396
|
||||
val ids = (391..396).toList()
|
||||
|
||||
class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(391){
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, (player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Fishies be mine, leave dem fishies!")
|
||||
|
|
|
|||
|
|
@ -4,17 +4,14 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.max
|
||||
|
||||
|
||||
val ids = 413..418
|
||||
val ids = (413..418).toList()
|
||||
|
||||
class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(413){
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0,(player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Raarrrgghh! Flee human!")
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.*
|
||||
|
||||
class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){
|
||||
val ids = (425..430).toList()
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1))
|
||||
val id = ids[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Leave this place!")
|
||||
|
|
|
|||
|
|
@ -32,4 +32,8 @@ class StrangePlantBehavior() : NPCBehavior(NPCs.STRANGE_PLANT_408) {
|
|||
override fun onDeathStarted(self: NPC, killer: Entity) {
|
||||
AntiMacro.terminateEventNpc(killer.asPlayer())
|
||||
}
|
||||
}
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return super.getXpMultiplier(self, attacker) / 16.0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.component.Component
|
||||
import core.game.dialogue.FacialExpression
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package content.global.ame.events
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
import content.global.ame.events.supriseexam.SurpriseExamUtils
|
||||
import content.global.ame.events.surpriseexam.SurpriseExamUtils
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.tools.END_DIALOGUE
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.node.entity.npc.NPC
|
||||
import org.rs09.consts.Components
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.component.Component
|
||||
import core.game.node.entity.player.Player
|
||||
|
|
@ -10,6 +10,7 @@ import core.game.interaction.InteractionListener
|
|||
import core.game.interaction.IntType
|
||||
import content.global.handlers.iface.ExperienceInterface
|
||||
import core.api.MapArea
|
||||
import core.api.removeItem
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ class SupriseExamListeners : InteractionListener, MapArea {
|
|||
return@on true
|
||||
}
|
||||
|
||||
on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open"){ player, node ->
|
||||
on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open") { player, node ->
|
||||
val correctDoor = player.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1)
|
||||
|
||||
if(correctDoor == -1){
|
||||
|
|
@ -42,7 +43,7 @@ class SupriseExamListeners : InteractionListener, MapArea {
|
|||
|
||||
on(Items.BOOK_OF_KNOWLEDGE_11640, IntType.ITEM, "read") { player, _ ->
|
||||
player.setAttribute("caller") { skill: Int, p: Player ->
|
||||
if (p.inventory.remove(Item(Items.BOOK_OF_KNOWLEDGE_11640))) {
|
||||
if (removeItem(p, Items.BOOK_OF_KNOWLEDGE_11640)) {
|
||||
val level = p.skills.getStaticLevel(skill)
|
||||
val experience = level * 15.0
|
||||
p.skills.addExperience(skill, experience)
|
||||
|
|
@ -1,22 +1,18 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.Server
|
||||
import content.global.ame.kidnapPlayer
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import core.game.node.entity.impl.PulseType
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.GroundItemManager
|
||||
import core.game.node.item.Item
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import core.ServerConstants
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
|
||||
object SurpriseExamUtils {
|
||||
|
||||
val SE_KEY_LOC = "/save:original-loc"
|
||||
val SE_KEY_INDEX = "supexam:index"
|
||||
val SE_LOGOUT_KEY = "suprise_exam"
|
||||
val SE_DOOR_KEY = "supexam:door"
|
||||
val INTER_PATTERN_CHILDS = intArrayOf(6,7,8)
|
||||
val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13)
|
||||
|
|
@ -30,20 +26,13 @@ object SurpriseExamUtils {
|
|||
intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311)
|
||||
)
|
||||
|
||||
fun teleport(player: Player){
|
||||
if (getAttribute(player, SE_KEY_LOC, null) == null) {
|
||||
player.setAttribute(SE_KEY_LOC, player.location)
|
||||
}
|
||||
registerLogoutListener(player, SE_LOGOUT_KEY){p ->
|
||||
p.location = getAttribute(p, SE_KEY_LOC, ServerConstants.HOME_LOCATION)
|
||||
}
|
||||
player.properties.teleportLocation = Location.create(1886, 5025, 0)
|
||||
fun teleport(player: Player) {
|
||||
kidnapPlayer(player, Location.create(1886, 5025, 0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player){
|
||||
player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC, ServerConstants.HOME_LOCATION)
|
||||
clearLogoutListener(player, SE_LOGOUT_KEY)
|
||||
removeAttributes(player, SE_KEY_LOC, SE_KEY_INDEX, SE_KEY_CORRECT)
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT)
|
||||
player.pulseManager.run(object : Pulse(2){
|
||||
override fun pulse(): Boolean {
|
||||
addItemOrDrop(player, Items.BOOK_OF_KNOWLEDGE_11640)
|
||||
|
|
@ -4,17 +4,14 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.max
|
||||
|
||||
|
||||
val ids = 438..443
|
||||
val ids = (438..443).toList()
|
||||
|
||||
class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(438){
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0,(player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Leave these woods and never return!")
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.*
|
||||
|
||||
class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){
|
||||
val ids = (419..424).toList()
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1))
|
||||
val id = ids[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Brainsssss!")
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import core.api.*
|
|||
import core.game.bots.*
|
||||
import core.game.ge.GrandExchange
|
||||
import core.game.interaction.DestinationFlag
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListeners
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.skill.Skills
|
||||
|
|
@ -16,6 +14,7 @@ import core.game.node.item.Item
|
|||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import org.rs09.consts.Items
|
||||
import content.data.Quests
|
||||
|
||||
@PlayerCompatible
|
||||
@ScriptName("Falador Cannonball Smelter")
|
||||
|
|
@ -273,6 +272,6 @@ class CannonballSmelter : Script() {
|
|||
skills.put(Skills.HITPOINTS,99)
|
||||
skills.put(Skills.DEFENCE,99)
|
||||
skills.put(Skills.SMITHING,35)
|
||||
quests.add("Dwarf Cannon")
|
||||
quests.add(Quests.DWARF_CANNON)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public class ManDialoguePlugin extends DialoguePlugin {
|
|||
/**
|
||||
* The NPC ids that use this dialogue plugin.
|
||||
*/
|
||||
private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 351, 352, 353, 354, 359, 360, 361, 362, 363, 726, 727, 728, 729, 730, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,};
|
||||
private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,};
|
||||
|
||||
public ManDialoguePlugin() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,17 +36,21 @@ public final class ClanInterfacePlugin extends ComponentPlugin {
|
|||
switch (component.getId()) {
|
||||
case 589:
|
||||
switch (button) {
|
||||
case 9:
|
||||
if (player.getInterfaceManager().getComponent(590) != null) {
|
||||
player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'");
|
||||
case 9:
|
||||
if (player.getInterfaceManager().getComponent(590) != null) {
|
||||
player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'");
|
||||
return true;
|
||||
}
|
||||
ClanRepository.openSettings(player);
|
||||
return true;
|
||||
}
|
||||
ClanRepository.openSettings(player);
|
||||
return true;
|
||||
case 14:
|
||||
player.getDetails().getCommunication().toggleLootshare(player);
|
||||
return true;
|
||||
case 14:
|
||||
if (player.getIronmanManager().checkRestriction()) {
|
||||
return false;
|
||||
}
|
||||
player.getDetails().getCommunication().toggleLootshare(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case 590:
|
||||
final ClanRepository clan = ClanRepository.get(player.getName(), true);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import core.plugin.Initializable
|
|||
import core.plugin.Plugin
|
||||
import core.tools.Log
|
||||
import org.rs09.consts.Sounds
|
||||
import content.data.Quests
|
||||
|
||||
/**
|
||||
* Represents the experience interface.
|
||||
|
|
@ -78,15 +79,15 @@ class ExperienceInterface() : ComponentPlugin() {
|
|||
}
|
||||
|
||||
private fun checkHerblore(player: Player): Boolean{
|
||||
return (player.questRepository.isComplete("Druidic Ritual"))
|
||||
return (player.questRepository.isComplete(Quests.DRUIDIC_RITUAL))
|
||||
}
|
||||
|
||||
private fun checkSummoning(player: Player): Boolean{
|
||||
return player.questRepository.isComplete("Wolf Whistle")
|
||||
return player.questRepository.isComplete(Quests.WOLF_WHISTLE)
|
||||
}
|
||||
|
||||
private fun checkRunecrafting(player: Player): Boolean{
|
||||
return player.questRepository.isComplete("Rune Mysteries")
|
||||
return player.questRepository.isComplete(Quests.RUNE_MYSTERIES)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import core.game.world.GameWorld
|
|||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.tools.RandomFunction
|
||||
|
||||
import content.data.Quests
|
||||
|
||||
/**
|
||||
* Handles the fairy ring interface
|
||||
|
|
@ -179,7 +179,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
AKS(Location.create(2571, 2956, 0), "Feldip Hills: Jungle Hunter area", 25),
|
||||
ALQ(Location.create(3597, 3495, 0), "Morytania: Haunted Woods east of Canifis", 27) {
|
||||
override fun checkAccess(player: Player) : Boolean {
|
||||
return requireQuest(player, "Priest in Peril", "to use this ring.")
|
||||
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.")
|
||||
}
|
||||
},
|
||||
ALS(Location.create(2644, 3495, 0), "Kandarin: McGrubor's Wood", 29),
|
||||
|
|
@ -191,7 +191,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
BKQ(Location.create(3041, 4532, 0), "Other realms: Enchanted Valley", 39),
|
||||
BKR(Location.create(3469, 3431, 0), "Morytania: Mort Myre, south of Canifis", 40) {
|
||||
override fun checkAccess(player: Player) : Boolean {
|
||||
return requireQuest(player, "Priest in Peril", "to use this ring.")
|
||||
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.")
|
||||
}
|
||||
},
|
||||
BLP(Location.create(2437, 5126, 0), "Dungeons: TzHaar area", 42),
|
||||
|
|
@ -199,7 +199,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
BLR(Location.create(2740, 3351, 0), "Kandarin: Legends' Guild", 44),
|
||||
CIP(Location.create(2513, 3884, 0), "Islands: Miscellania", 46) {
|
||||
override fun checkAccess(player: Player): Boolean {
|
||||
return requireQuest(player, "Fremennik Trials", "to use this ring.")
|
||||
return requireQuest(player, Quests.THE_FREMENNIK_TRIALS, "to use this ring.")
|
||||
}
|
||||
},
|
||||
CIQ(Location.create(2528, 3127, 0), "Kandarin: North-west of Yanille", 47),
|
||||
|
|
@ -208,7 +208,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
CKR(Location.create(2801, 3003, 0), "Karamja: South of Tai Bwo Wannai Village", 56),
|
||||
CKS(Location.create(3447, 3470, 0), "Morytania: Canifis", 57) {
|
||||
override fun checkAccess(player: Player) : Boolean {
|
||||
return requireQuest(player, "Priest in Peril", "to use this ring.")
|
||||
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.")
|
||||
}
|
||||
},
|
||||
CLP(Location.create(3082, 3206, 0), "Islands: South of Draynor Village", 58),
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import core.plugin.Initializable;
|
|||
import core.plugin.Plugin;
|
||||
|
||||
import static core.api.ContentAPIKt.hasRequirement;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Represents the prayer interface.
|
||||
|
|
@ -27,7 +28,7 @@ public final class PrayerTabInterface extends ComponentPlugin {
|
|||
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||
final PrayerType type = PrayerType.get(button);
|
||||
if (type == PrayerType.CHIVALRY || type == PrayerType.PIETY)
|
||||
if (!hasRequirement(player, "King's Ransom"))
|
||||
if (!hasRequirement(player, Quests.KINGS_RANSOM))
|
||||
return true;
|
||||
if (type == null) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ import kotlin.math.*
|
|||
import java.util.*
|
||||
|
||||
import org.rs09.consts.*
|
||||
import content.data.Quests
|
||||
|
||||
object QuestTabUtils {
|
||||
@JvmStatic
|
||||
fun showRequirementsInterface (player: Player, button: Int) {
|
||||
val questName = getNameForButton (button)
|
||||
val questReq = QuestRequirements.values().filter { it.questName.equals(questName, true) }.firstOrNull() ?: return
|
||||
fun showRequirementsInterface(player: Player, button: Int) {
|
||||
val questName = getNameForButton(button)
|
||||
val questReq = QuestRequirements.values().filter { it.quest.questName == questName }.firstOrNull() ?: return
|
||||
var (isMet, unmetReqs) = QuestReq(questReq).evaluate(player)
|
||||
|
||||
var messageList = ArrayList<String>()
|
||||
|
|
@ -27,7 +28,7 @@ object QuestTabUtils {
|
|||
closeInterface(player)
|
||||
for (req in unmetReqs) {
|
||||
if (req is QuestReq)
|
||||
questList.add(req.questReq.questName)
|
||||
questList.add(req.questReq.quest.questName)
|
||||
else if (req is SkillReq) {
|
||||
if (statMap[req.skillId] == null || (statMap[req.skillId] != null && statMap[req.skillId]!! < req.level))
|
||||
statMap[req.skillId] = req.level
|
||||
|
|
@ -82,163 +83,163 @@ object QuestTabUtils {
|
|||
openInterface(player, Components.QUESTJOURNAL_SCROLL_275)
|
||||
}
|
||||
|
||||
fun getNameForButton (button: Int) : String {
|
||||
val name = when (button) {
|
||||
10 -> "Myths of the White Lands"
|
||||
11 -> "Myths of the White Lands"
|
||||
private fun getNameForButton(button: Int) : String {
|
||||
val quest = when (button) {
|
||||
10 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName
|
||||
11 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName
|
||||
12 -> "Free Quests"
|
||||
13 -> "Black Knights' Fortress"
|
||||
14 -> "Cook's Assistant"
|
||||
15 -> "Demon Slayer"
|
||||
16 -> "Doric's Quest"
|
||||
17 -> "Dragon Slayer"
|
||||
18 -> "Ernest the Chicken"
|
||||
19 -> "Goblin Diplomacy"
|
||||
20 -> "Imp Catcher"
|
||||
21 -> "The Knight's Sword"
|
||||
22 -> "Pirate's Treasure"
|
||||
23 -> "Prince Ali Rescue"
|
||||
24 -> "The Restless Ghost"
|
||||
25 -> "Romeo & Juliet"
|
||||
26 -> "Rune Mysteries"
|
||||
27 -> "Sheep Shearer"
|
||||
28 -> "Shield of Arrav"
|
||||
29 -> "Vampire Slayer"
|
||||
30 -> "Witch's Potion"
|
||||
13 -> Quests.BLACK_KNIGHTS_FORTRESS.questName
|
||||
14 -> Quests.COOKS_ASSISTANT.questName
|
||||
15 -> Quests.DEMON_SLAYER.questName
|
||||
16 -> Quests.DORICS_QUEST.questName
|
||||
17 -> Quests.DRAGON_SLAYER.questName
|
||||
18 -> Quests.ERNEST_THE_CHICKEN.questName
|
||||
19 -> Quests.GOBLIN_DIPLOMACY.questName
|
||||
20 -> Quests.IMP_CATCHER.questName
|
||||
21 -> Quests.THE_KNIGHTS_SWORD.questName
|
||||
22 -> Quests.PIRATES_TREASURE.questName
|
||||
23 -> Quests.PRINCE_ALI_RESCUE.questName
|
||||
24 -> Quests.THE_RESTLESS_GHOST.questName
|
||||
25 -> Quests.ROMEO_JULIET.questName
|
||||
26 -> Quests.RUNE_MYSTERIES.questName
|
||||
27 -> Quests.SHEEP_SHEARER.questName
|
||||
28 -> Quests.SHIELD_OF_ARRAV.questName
|
||||
29 -> Quests.VAMPIRE_SLAYER.questName
|
||||
30 -> Quests.WITCHS_POTION.questName
|
||||
31 -> "Members' Quests"
|
||||
32 -> "Animal Magnetism"
|
||||
33 -> "Between a Rock..."
|
||||
34 -> "Big Chompy Bird Hunting"
|
||||
35 -> "Biohazard"
|
||||
36 -> "Cabin Fever"
|
||||
37 -> "Clock Tower"
|
||||
38 -> "Contact!"
|
||||
39 -> "Zogre Flesh Eaters"
|
||||
40 -> "Creature of Fenkenstrain"
|
||||
41 -> "Darkness of Hallowvale"
|
||||
42 -> "Death to the Dorgeshuun"
|
||||
43 -> "Death Plateau"
|
||||
44 -> "Desert Treasure"
|
||||
45 -> "Devious Minds"
|
||||
46 -> "The Dig Site"
|
||||
47 -> "Druidic Ritual"
|
||||
48 -> "Dwarf Cannon"
|
||||
49 -> "Eadgar's Ruse"
|
||||
50 -> "Eagles' Peak"
|
||||
51 -> "Elemental Workshop I"
|
||||
52 -> "Elemental Workshop II"
|
||||
53 -> "Enakhra's Lament"
|
||||
54 -> "Enlightened Journey"
|
||||
55 -> "The Eyes of Glouphrie"
|
||||
56 -> "Fairytale I - Growing Pains"
|
||||
57 -> "Fairytale II - Cure a Queen"
|
||||
58 -> "Family Crest"
|
||||
59 -> "The Feud"
|
||||
60 -> "Fight Arena"
|
||||
61 -> "Fishing Contest"
|
||||
62 -> "Forgettable Tale..."
|
||||
63 -> "The Fremennik Trials"
|
||||
64 -> "Waterfall Quest"
|
||||
65 -> "Garden of Tranquillity"
|
||||
66 -> "Gertrude's Cat"
|
||||
67 -> "Ghosts Ahoy"
|
||||
68 -> "The Giant Dwarf"
|
||||
69 -> "The Golem"
|
||||
70 -> "The Grand Tree"
|
||||
71 -> "The Hand in the Sand"
|
||||
72 -> "Haunted Mine"
|
||||
73 -> "Hazeel Cult"
|
||||
74 -> "Heroes' Quest"
|
||||
75 -> "Holy Grail"
|
||||
76 -> "Horror from the Deep"
|
||||
77 -> "Icthlarin's Little Helper"
|
||||
78 -> "In Aid of the Myreque"
|
||||
79 -> "In Search of the Myreque"
|
||||
80 -> "Jungle Potion"
|
||||
81 -> "Legend's Quest"
|
||||
82 -> "Lost City"
|
||||
83 -> "The Lost Tribe"
|
||||
84 -> "Lunar Diplomacy"
|
||||
85 -> "Making History"
|
||||
86 -> "Merlin's Crystal"
|
||||
87 -> "Monkey Madness"
|
||||
88 -> "Monk's Friend"
|
||||
89 -> "Mountain Daughter"
|
||||
90 -> "Mourning's End Part I"
|
||||
91 -> "Mourning's End Part II"
|
||||
92 -> "Murder Mystery"
|
||||
93 -> "My Arm's Big Adventure"
|
||||
94 -> "Nature Spirit"
|
||||
95 -> "Observatory Quest"
|
||||
96 -> "One Small Favour"
|
||||
97 -> "Plague City"
|
||||
98 -> "Priest in Peril"
|
||||
99 -> "Rag and Bone Man"
|
||||
100 -> "Ratcatchers"
|
||||
101 -> "Recipe for Disaster"
|
||||
102 -> "Recruitment Drive"
|
||||
103 -> "Regicide"
|
||||
104 -> "Roving Elves"
|
||||
105 -> "Royal Trouble"
|
||||
106 -> "Rum Deal"
|
||||
107 -> "Scorpion Catcher"
|
||||
108 -> "Sea Slug"
|
||||
109 -> "The Slug Menace"
|
||||
110 -> "Shades of Mort'ton"
|
||||
111 -> "Shadow of the Storm"
|
||||
112 -> "Sheep Herder"
|
||||
113 -> "Shilo Village"
|
||||
114 -> "A Soul's Bane"
|
||||
115 -> "Spirits of the Elid"
|
||||
116 -> "Swan Song"
|
||||
117 -> "Tai Bwo Wannai Trio"
|
||||
118 -> "A Tail of Two Cats"
|
||||
119 -> "Tears of Guthix"
|
||||
120 -> "Temple of Ikov"
|
||||
121 -> "Throne of Miscellania"
|
||||
122 -> "The Tourist Trap"
|
||||
123 -> "Witch's House"
|
||||
124 -> "Tree Gnome Village"
|
||||
125 -> "Tribal Totem"
|
||||
126 -> "Troll Romance"
|
||||
127 -> "Troll Stronghold"
|
||||
128 -> "Underground Pass"
|
||||
129 -> "Wanted!"
|
||||
130 -> "Watchtower"
|
||||
131 -> "Cold War"
|
||||
132 -> "The Fremennik Isles"
|
||||
133 -> "Tower of Life"
|
||||
134 -> "The Great Brain Robbery"
|
||||
135 -> "What Lies Below"
|
||||
136 -> "Olaf's Quest"
|
||||
137 -> "Another Slice of H.A.M"
|
||||
138 -> "Dream Mentor"
|
||||
139 -> "Grim Tales"
|
||||
140 -> "King's Ransom"
|
||||
141 -> "The Path of Glouphrie"
|
||||
142 -> "Back to my Roots"
|
||||
143 -> "Land of the Goblins"
|
||||
144 -> "Dealing with Scabaras"
|
||||
145 -> "Wolf Whistle"
|
||||
146 -> "As a First Resort..."
|
||||
147 -> "Catapult Construction"
|
||||
148 -> "Kennith's Concerns"
|
||||
149 -> "Legacy of Seergaze"
|
||||
150 -> "Perils of Ice Mountain"
|
||||
151 -> "TokTz-Ket-Dill"
|
||||
152 -> "Smoking Kills"
|
||||
153 -> "Rocking Out"
|
||||
154 -> "Spirit of Summer"
|
||||
155 -> "Meeting History"
|
||||
156 -> "All Fired Up"
|
||||
157 -> "Summer's End"
|
||||
158 -> "Defender of Varrock"
|
||||
159 -> "Swept Away"
|
||||
160 -> "While Guthix Sleeps"
|
||||
161 -> "In Pyre Need"
|
||||
162 -> "Myths of the White Lands"
|
||||
32 -> Quests.ANIMAL_MAGNETISM.questName
|
||||
33 -> Quests.BETWEEN_A_ROCK.questName
|
||||
34 -> Quests.BIG_CHOMPY_BIRD_HUNTING.questName
|
||||
35 -> Quests.BIOHAZARD.questName
|
||||
36 -> Quests.CABIN_FEVER.questName
|
||||
37 -> Quests.CLOCK_TOWER.questName
|
||||
38 -> Quests.CONTACT.questName
|
||||
39 -> Quests.ZOGRE_FLESH_EATERS.questName
|
||||
40 -> Quests.CREATURE_OF_FENKENSTRAIN.questName
|
||||
41 -> Quests.DARKNESS_OF_HALLOWVALE.questName
|
||||
42 -> Quests.DEATH_TO_THE_DORGESHUUN.questName
|
||||
43 -> Quests.DEATH_PLATEAU.questName
|
||||
44 -> Quests.DESERT_TREASURE.questName
|
||||
45 -> Quests.DEVIOUS_MINDS.questName
|
||||
46 -> Quests.THE_DIG_SITE.questName
|
||||
47 -> Quests.DRUIDIC_RITUAL.questName
|
||||
48 -> Quests.DWARF_CANNON.questName
|
||||
49 -> Quests.EADGARS_RUSE.questName
|
||||
50 -> Quests.EAGLES_PEAK.questName
|
||||
51 -> Quests.ELEMENTAL_WORKSHOP_I.questName
|
||||
52 -> Quests.ELEMENTAL_WORKSHOP_II.questName
|
||||
53 -> Quests.ENAKHRAS_LAMENT.questName
|
||||
54 -> Quests.ENLIGHTENED_JOURNEY.questName
|
||||
55 -> Quests.THE_EYES_OF_GLOUPHRIE.questName
|
||||
56 -> Quests.FAIRYTALE_I_GROWING_PAINS.questName
|
||||
57 -> Quests.FAIRYTALE_II_CURE_A_QUEEN.questName
|
||||
58 -> Quests.FAMILY_CREST.questName
|
||||
59 -> Quests.THE_FEUD.questName
|
||||
60 -> Quests.FIGHT_ARENA.questName
|
||||
61 -> Quests.FISHING_CONTEST.questName
|
||||
62 -> Quests.FORGETTABLE_TALE.questName
|
||||
63 -> Quests.THE_FREMENNIK_TRIALS.questName
|
||||
64 -> Quests.WATERFALL_QUEST.questName
|
||||
65 -> Quests.GARDEN_OF_TRANQUILITY.questName
|
||||
66 -> Quests.GERTRUDES_CAT.questName
|
||||
67 -> Quests.GHOSTS_AHOY.questName
|
||||
68 -> Quests.THE_GIANT_DWARF.questName
|
||||
69 -> Quests.THE_GOLEM.questName
|
||||
70 -> Quests.THE_GRAND_TREE.questName
|
||||
71 -> Quests.THE_HAND_IN_THE_SAND.questName
|
||||
72 -> Quests.HAUNTED_MINE.questName
|
||||
73 -> Quests.HAZEEL_CULT.questName
|
||||
74 -> Quests.HEROES_QUEST.questName
|
||||
75 -> Quests.HOLY_GRAIL.questName
|
||||
76 -> Quests.HORROR_FROM_THE_DEEP.questName
|
||||
77 -> Quests.ICTHLARINS_LITTLE_HELPER.questName
|
||||
78 -> Quests.IN_AID_OF_THE_MYREQUE.questName
|
||||
79 -> Quests.IN_SEARCH_OF_THE_MYREQUE.questName
|
||||
80 -> Quests.JUNGLE_POTION.questName
|
||||
81 -> Quests.LEGENDS_QUEST.questName
|
||||
82 -> Quests.LOST_CITY.questName
|
||||
83 -> Quests.THE_LOST_TRIBE.questName
|
||||
84 -> Quests.LUNAR_DIPLOMACY.questName
|
||||
85 -> Quests.MAKING_HISTORY.questName
|
||||
86 -> Quests.MERLINS_CRYSTAL.questName
|
||||
87 -> Quests.MONKEY_MADNESS.questName
|
||||
88 -> Quests.MONKS_FRIEND.questName
|
||||
89 -> Quests.MOUNTAIN_DAUGHTER.questName
|
||||
90 -> Quests.MOURNINGS_END_PART_I.questName
|
||||
91 -> Quests.MOURNINGS_END_PART_II.questName
|
||||
92 -> Quests.MURDER_MYSTERY.questName
|
||||
93 -> Quests.MY_ARMS_BIG_ADVENTURE.questName
|
||||
94 -> Quests.NATURE_SPIRIT.questName
|
||||
95 -> Quests.OBSERVATORY_QUEST.questName
|
||||
96 -> Quests.ONE_SMALL_FAVOUR.questName
|
||||
97 -> Quests.PLAGUE_CITY.questName
|
||||
98 -> Quests.PRIEST_IN_PERIL.questName
|
||||
99 -> Quests.RAG_AND_BONE_MAN.questName
|
||||
100 -> Quests.RATCATCHERS.questName
|
||||
101 -> Quests.RECIPE_FOR_DISASTER.questName
|
||||
102 -> Quests.RECRUITMENT_DRIVE.questName
|
||||
103 -> Quests.REGICIDE.questName
|
||||
104 -> Quests.ROVING_ELVES.questName
|
||||
105 -> Quests.ROYAL_TROUBLE.questName
|
||||
106 -> Quests.RUM_DEAL.questName
|
||||
107 -> Quests.SCORPION_CATCHER.questName
|
||||
108 -> Quests.SEA_SLUG.questName
|
||||
109 -> Quests.THE_SLUG_MENACE.questName
|
||||
110 -> Quests.SHADES_OF_MORTTON.questName
|
||||
111 -> Quests.SHADOW_OF_THE_STORM.questName
|
||||
112 -> Quests.SHEEP_HERDER.questName
|
||||
113 -> Quests.SHILO_VILLAGE.questName
|
||||
114 -> Quests.A_SOULS_BANE.questName
|
||||
115 -> Quests.SPIRITS_OF_THE_ELID.questName
|
||||
116 -> Quests.SWAN_SONG.questName
|
||||
117 -> Quests.TAI_BWO_WANNAI_TRIO.questName
|
||||
118 -> Quests.A_TAIL_OF_TWO_CATS.questName
|
||||
119 -> Quests.TEARS_OF_GUTHIX.questName
|
||||
120 -> Quests.TEMPLE_OF_IKOV.questName
|
||||
121 -> Quests.THRONE_OF_MISCELLANIA.questName
|
||||
122 -> Quests.THE_TOURIST_TRAP.questName
|
||||
123 -> Quests.WITCHS_HOUSE.questName
|
||||
124 -> Quests.TREE_GNOME_VILLAGE.questName
|
||||
125 -> Quests.TRIBAL_TOTEM.questName
|
||||
126 -> Quests.TROLL_ROMANCE.questName
|
||||
127 -> Quests.TROLL_STRONGHOLD.questName
|
||||
128 -> Quests.UNDERGROUND_PASS.questName
|
||||
129 -> Quests.WANTED.questName
|
||||
130 -> Quests.WATCHTOWER.questName
|
||||
131 -> Quests.COLD_WAR.questName
|
||||
132 -> Quests.THE_FREMENNIK_ISLES.questName
|
||||
133 -> Quests.TOWER_OF_LIFE.questName
|
||||
134 -> Quests.THE_GREAT_BRAIN_ROBBERY.questName
|
||||
135 -> Quests.WHAT_LIES_BELOW.questName
|
||||
136 -> Quests.OLAFS_QUEST.questName
|
||||
137 -> Quests.ANOTHER_SLICE_OF_HAM.questName
|
||||
138 -> Quests.DREAM_MENTOR.questName
|
||||
139 -> Quests.GRIM_TALES.questName
|
||||
140 -> Quests.KINGS_RANSOM.questName
|
||||
141 -> Quests.THE_PATH_OF_GLOUPHRIE.questName
|
||||
142 -> Quests.BACK_TO_MY_ROOTS.questName
|
||||
143 -> Quests.LAND_OF_THE_GOBLINS.questName
|
||||
144 -> Quests.DEALING_WITH_SCABARAS.questName
|
||||
145 -> Quests.WOLF_WHISTLE.questName
|
||||
146 -> Quests.AS_A_FIRST_RESORT.questName
|
||||
147 -> Quests.CATAPULT_CONSTRUCTION.questName
|
||||
148 -> Quests.KENNITHS_CONCERNS.questName
|
||||
149 -> Quests.LEGACY_OF_SEERGAZE.questName
|
||||
150 -> Quests.PERILS_OF_ICE_MOUNTAIN.questName
|
||||
151 -> Quests.TOKTZ_KET_DILL.questName
|
||||
152 -> Quests.SMOKING_KILLS.questName
|
||||
153 -> Quests.ROCKING_OUT.questName
|
||||
154 -> Quests.SPIRIT_OF_SUMMER.questName
|
||||
155 -> Quests.MEETING_HISTORY.questName
|
||||
156 -> Quests.ALL_FIRED_UP.questName
|
||||
157 -> Quests.SUMMERS_END.questName
|
||||
158 -> Quests.DEFENDER_OF_VARROCK.questName
|
||||
159 -> Quests.SWEPT_AWAY.questName
|
||||
160 -> Quests.WHILE_GUTHIX_SLEEPS.questName
|
||||
161 -> Quests.IN_PYRE_NEED.questName
|
||||
162 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName
|
||||
else -> ""
|
||||
}
|
||||
return name
|
||||
return quest as String
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import core.game.world.update.flag.context.Graphics
|
|||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
import org.rs09.consts.Sounds
|
||||
import content.data.Quests
|
||||
|
||||
@Suppress("unused")
|
||||
class EctophialListener : InteractionListener {
|
||||
|
|
@ -37,7 +38,7 @@ class EctophialListener : InteractionListener {
|
|||
}
|
||||
|
||||
on(Items.ECTOPHIAL_4251, IntType.ITEM, "empty") { player, node ->
|
||||
if (!hasRequirement(player, "Ghosts Ahoy"))
|
||||
if (!hasRequirement(player, Quests.GHOSTS_AHOY))
|
||||
return@on true
|
||||
|
||||
if (player.isTeleBlocked) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.handlers.item
|
||||
|
||||
import content.global.skill.slayer.SlayerUtils
|
||||
import core.api.*
|
||||
import content.global.skill.slayer.Tasks
|
||||
import org.rs09.consts.Items
|
||||
|
|
@ -41,7 +42,8 @@ class EnchantedGemDialogue() : DialogueFile() {
|
|||
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 ${getSlayerTaskName(player!!)}s; only ${getSlayerTaskKillsRemaining(player!!)} more to go.")
|
||||
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)
|
||||
stage = 1
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import core.api.*
|
|||
import core.game.node.entity.player.link.quest.QuestRepository
|
||||
import org.rs09.consts.Items
|
||||
import core.game.interaction.InteractionListener
|
||||
import content.data.Quests
|
||||
|
||||
class ItemQuestRequirementListener : InteractionListener {
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
|
||||
/*
|
||||
onEquip(fremennikIslesEquipment) { player, _ ->
|
||||
if (!isQuestComplete(player, "Fremennik Isles")) {
|
||||
if (!isQuestComplete(player, Quests.THE_FREMENNIK_ISLES)) {
|
||||
sendMessage(player, "You must have completed The Fremennik Isles to equip this.")
|
||||
return@onEquip false
|
||||
}
|
||||
|
|
@ -114,7 +115,7 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
}
|
||||
|
||||
onEquip(fremennikIslesDuringQuestEquipment){ player, _ ->
|
||||
if (questStage(player, "Fremennik Isles") > 0) {
|
||||
if (questStage(player, Quests.THE_FREMENNIK_ISLES) > 0) {
|
||||
sendMessage(player, "You must have started The Fremennik Isles to equip this.")
|
||||
return@onEquip false
|
||||
}
|
||||
|
|
@ -123,23 +124,23 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
*/
|
||||
|
||||
onEquip(fremennikTrialsEquipment) { player, _ ->
|
||||
return@onEquip hasRequirement(player, "Fremennik Trials")
|
||||
return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)
|
||||
}
|
||||
|
||||
onEquip(fremennikIslesEquipment) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "The Fremennik Isles")
|
||||
return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_ISLES)
|
||||
}
|
||||
|
||||
onEquip(avasBackpacks){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Animal Magnetism")
|
||||
return@onEquip hasRequirement(player, Quests.ANIMAL_MAGNETISM)
|
||||
}
|
||||
|
||||
onEquip(lostCityWeapons){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Lost City")
|
||||
return@onEquip hasRequirement(player, Quests.LOST_CITY)
|
||||
}
|
||||
|
||||
onEquip(Items.CAPE_OF_LEGENDS_1052) { player, _ ->
|
||||
return@onEquip hasRequirement(player, "Legend's Quest")
|
||||
return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST)
|
||||
}
|
||||
|
||||
onEquip(questCapes) { player, _ ->
|
||||
|
|
@ -152,84 +153,84 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
}
|
||||
|
||||
onEquip(Items.WOLFBANE_2952){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Priest in Peril")
|
||||
return@onEquip hasRequirement(player, Quests.PRIEST_IN_PERIL)
|
||||
}
|
||||
|
||||
onEquip(Items.ANCIENT_MACE_11061){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Another Slice of H.A.M")
|
||||
return@onEquip hasRequirement(player, Quests.ANOTHER_SLICE_OF_HAM)
|
||||
}
|
||||
|
||||
onEquip(Items.ANCIENT_STAFF_4675){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Desert Treasure")
|
||||
return@onEquip hasRequirement(player, Quests.DESERT_TREASURE)
|
||||
}
|
||||
|
||||
onEquip(Items.ELEMENTAL_SHIELD_2890) { player, _ ->
|
||||
return@onEquip hasRequirement(player, "Elemental Workshop I")
|
||||
return@onEquip hasRequirement(player, Quests.ELEMENTAL_WORKSHOP_I)
|
||||
}
|
||||
|
||||
onEquip(crystalEquipment){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Roving Elves")
|
||||
return@onEquip hasRequirement(player, Quests.ROVING_ELVES)
|
||||
}
|
||||
|
||||
onEquip(dragonSlayerEquipment) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Dragon Slayer")
|
||||
return@onEquip hasRequirement(player, Quests.DRAGON_SLAYER)
|
||||
}
|
||||
|
||||
onEquip(Items.DRAGON_SCIMITAR_4587) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Monkey Madness")
|
||||
return@onEquip hasRequirement(player, Quests.MONKEY_MADNESS)
|
||||
}
|
||||
|
||||
onEquip(Items.GLOVES_7462) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Recipe for Disaster")
|
||||
return@onEquip hasRequirement(player, Quests.RECIPE_FOR_DISASTER)
|
||||
}
|
||||
|
||||
onEquip(Items.SLAYER_HELMET_13263) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Smoking Kills")
|
||||
return@onEquip hasRequirement(player, Quests.SMOKING_KILLS)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_HALBERD_3204) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Regicide")
|
||||
return@onEquip hasRequirement(player, Quests.REGICIDE)
|
||||
}
|
||||
|
||||
onEquip (Items.CLIMBING_BOOTS_3105) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Death Plateau")
|
||||
return@onEquip hasRequirement(player, Quests.DEATH_PLATEAU)
|
||||
}
|
||||
|
||||
onEquip (godBooks) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Horror from the Deep")
|
||||
return@onEquip hasRequirement(player, Quests.HORROR_FROM_THE_DEEP)
|
||||
}
|
||||
|
||||
onEquip (pharaohScepters) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Icthlarin's Little Helper")
|
||||
return@onEquip hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_SQ_SHIELD_1187) {player, _ ->
|
||||
//because I know people won't believe it: https://runescape.wiki/w/Dragon_sq_shield?oldid=899636
|
||||
return@onEquip hasRequirement(player, "Legend's Quest")
|
||||
return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST)
|
||||
}
|
||||
|
||||
onEquip (initiateArmour) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Recruitment Drive")
|
||||
return@onEquip hasRequirement(player, Quests.RECRUITMENT_DRIVE)
|
||||
}
|
||||
|
||||
onEquip (proselyteArmour) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "The Slug Menace")
|
||||
return@onEquip hasRequirement(player, Quests.THE_SLUG_MENACE)
|
||||
}
|
||||
|
||||
onEquip (spiritShields) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Summer's End")
|
||||
return@onEquip hasRequirement(player, Quests.SUMMERS_END)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_MACE_1434) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Heroes' Quest")
|
||||
return@onEquip hasRequirement(player, Quests.HEROES_QUEST)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_BATTLEAXE_1377) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Heroes' Quest")
|
||||
return@onEquip hasRequirement(player, Quests.HEROES_QUEST)
|
||||
}
|
||||
|
||||
onEquip (Items.DARKLIGHT_6746) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Shadow of the Storm")
|
||||
return@onEquip hasRequirement(player, Quests.SHADOW_OF_THE_STORM)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import core.game.node.entity.player.Player;
|
|||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import content.region.morytania.quest.naturespirit.NSUtils;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Handles the Silver Sickle (b) to collect Mort Myre Fungus.
|
||||
|
|
@ -28,7 +29,7 @@ public final class SilverSicklePlugin extends OptionHandler {
|
|||
switch (option) {
|
||||
case "operate":
|
||||
case "cast bloom":
|
||||
if(player.getQuestRepository().getQuest("Nature Spirit").getStage(player) >= 75) {
|
||||
if(player.getQuestRepository().getQuest(Quests.NATURE_SPIRIT).getStage(player) >= 75) {
|
||||
player.getPacketDispatch().sendAnimation(9021);
|
||||
NSUtils.castBloom(player);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
package content.global.handlers.item
|
||||
|
||||
import core.api.inInventory
|
||||
import core.api.removeItem
|
||||
import core.api.teleport
|
||||
import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
import core.api.hasRequirement;
|
||||
import content.data.Quests
|
||||
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
|
||||
|
|
@ -17,23 +16,23 @@ class TeleTabsListener : InteractionListener {
|
|||
|
||||
enum class TeleTabs(val item: Int, val location: Location, val exp: Double, val requirementCheck: (Player) -> Boolean = { true }) {
|
||||
ADDOUGNE_TELEPORT(8011, Location.create(2662, 3307, 0), 61.0, {
|
||||
player -> hasRequirement(player, "Plague City");
|
||||
player -> getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)
|
||||
}),
|
||||
AIR_ALTAR_TELEPORT(13599, Location.create(2978, 3296, 0), 0.0),
|
||||
ASTRAL_ALTAR_TELEPORT(13611, Location.create(2156, 3862, 0), 0.0, {
|
||||
player -> hasRequirement(player, "Lunar Diplomacy");
|
||||
player -> hasRequirement(player, Quests.LUNAR_DIPLOMACY);
|
||||
}),
|
||||
BLOOD_ALTAR_TELEPORT(13610, Location.create(3559, 9778, 0), 0.0, {
|
||||
player -> hasRequirement(player, "Legacy of Seergaze");
|
||||
player -> hasRequirement(player, Quests.LEGACY_OF_SEERGAZE);
|
||||
}),
|
||||
BODY_ALTAR_TELEPORT(13604, Location.create(3055, 3443, 0), 0.0),
|
||||
CAMELOT_TELEPORT(8010, Location.create(2757, 3477, 0), 55.5),
|
||||
CHAOS_ALTAR_TELEPORT(13606, Location.create(3058, 3593, 0), 0.0),
|
||||
COSMIC_ALTAR_TELEPORT(13605, Location.create(2411, 4380, 0), 0.0, {
|
||||
player -> hasRequirement(player, "Lost City");
|
||||
player -> hasRequirement(player, Quests.LOST_CITY);
|
||||
}),
|
||||
DEATH_ALTAR_TELEPORT(13609, Location.create(1863, 4639, 0), 0.0, {
|
||||
player -> hasRequirement(player, "Mourning's End Part II");
|
||||
player -> hasRequirement(player, Quests.MOURNINGS_END_PART_II);
|
||||
}),
|
||||
EARTH_ALTAR_TELEPORT(13602, Location.create(3304, 3472, 0), 0.0),
|
||||
FALADOR_TELEPORT(8009, Location.create(2966, 3380, 0), 47.0),
|
||||
|
|
@ -45,11 +44,11 @@ class TeleTabsListener : InteractionListener {
|
|||
MIND_ALTAR_TELEPORT(13600, Location.create(2979, 3510, 0), 0.0),
|
||||
NATURE_ALTAR_TELEPORT(13607, Location.create(2868, 3013, 0), 0.0),
|
||||
TELEKINETIC_GRAB(8022, Location.create(2836, 3285, 0), 0.0, {
|
||||
player -> hasRequirement(player, "Dragon Slayer");
|
||||
player -> hasRequirement(player, Quests.DRAGON_SLAYER);
|
||||
}),
|
||||
VARROCK_TELEPORT(8007, Location.create(3212, 3423, 0), 35.00),
|
||||
WATCH_TOWER_TELEPORT(8012, Location.create(2548, 3114, 0), 68.00, {
|
||||
player -> hasRequirement(player, "Watchtower");
|
||||
player -> hasRequirement(player, Quests.WATCHTOWER);
|
||||
}),
|
||||
WATER_ALTAR_TELEPORT(13601, Location.create(3182, 3162, 0), 0.0);
|
||||
|
||||
|
|
@ -68,9 +67,17 @@ class TeleTabsListener : InteractionListener {
|
|||
val tabEnum = TeleTabs.forId(tab)
|
||||
if (tabEnum != null && inInventory(player,tab)) {
|
||||
val tabloc = tabEnum.location
|
||||
if (inInventory(player, tab) && tabEnum.requirementCheck(player)) {
|
||||
if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) {
|
||||
removeItem(player, Item(node.id, 1))
|
||||
if (inInventory(player, tab)) {
|
||||
if (tabEnum.requirementCheck(player)){
|
||||
if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) {
|
||||
removeItem(player, Item(node.id, 1))
|
||||
}
|
||||
}
|
||||
else {
|
||||
when (tabEnum){
|
||||
TeleTabs.ADDOUGNE_TELEPORT -> sendMessage(player, "You need to complete Plague City to use this tablet.")
|
||||
else -> sendMessage(player, "You do not have the requirements to use this tablet.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import core.game.world.map.zone.impl.WildernessZone;
|
|||
import core.plugin.Plugin;
|
||||
|
||||
import static core.api.ContentAPIKt.hasRequirement;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Represents the rotten potato plugin.
|
||||
|
|
@ -34,7 +35,7 @@ public final class TeleportCrystalPlugin extends OptionHandler {
|
|||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
if (!hasRequirement(player, "Mourning's End Part I"))
|
||||
if (!hasRequirement(player, Quests.MOURNINGS_END_PART_I))
|
||||
return true;
|
||||
if (!WildernessZone.checkTeleport(player, 20)) {
|
||||
player.getPacketDispatch().sendMessage("The crystal is unresponsive.");
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
package content.global.handlers.item.withnpc
|
||||
|
||||
import core.api.Container
|
||||
import core.api.*
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
|
||||
class CatOnArdougneCivilian: InteractionListener {
|
||||
|
||||
private val civilians = intArrayOf(
|
||||
NPCs.CIVILIAN_785,
|
||||
NPCs.CIVILIAN_786,
|
||||
NPCs.CIVILIAN_787
|
||||
)
|
||||
|
||||
private val cats = intArrayOf(
|
||||
Items.PET_CAT_1561,
|
||||
Items.PET_CAT_1562,
|
||||
Items.PET_CAT_1563,
|
||||
Items.PET_CAT_1564,
|
||||
Items.PET_CAT_1565,
|
||||
Items.PET_CAT_1566,
|
||||
Items.OVERGROWN_CAT_1567,
|
||||
Items.OVERGROWN_CAT_1568,
|
||||
Items.OVERGROWN_CAT_1569,
|
||||
Items.OVERGROWN_CAT_1570,
|
||||
Items.OVERGROWN_CAT_1571,
|
||||
Items.OVERGROWN_CAT_1572,
|
||||
Items.LAZY_CAT_6551,
|
||||
Items.LAZY_CAT_6552,
|
||||
Items.LAZY_CAT_6553,
|
||||
Items.LAZY_CAT_6554,
|
||||
Items.WILY_CAT_6555,
|
||||
Items.WILY_CAT_6556,
|
||||
Items.WILY_CAT_6557,
|
||||
Items.WILY_CAT_6558,
|
||||
Items.WILY_CAT_6559,
|
||||
Items.WILY_CAT_6560,
|
||||
Items.HELL_CAT_7582,
|
||||
Items.OVERGROWN_HELLCAT_7581,
|
||||
Items.LAZY_HELL_CAT_7584,
|
||||
Items.WILY_HELLCAT_7585,
|
||||
)
|
||||
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.NPC,cats,*civilians){ player, used, _ ->
|
||||
sendItemDialogue(player,Items.DEATH_RUNE_560,"You hand over the cat.<br>You are given 100 Death Runes.")
|
||||
player.familiarManager.removeDetails(used.id)
|
||||
removeItem(player,used,Container.INVENTORY)
|
||||
addItem(player,Items.DEATH_RUNE_560,100)
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,27 +10,27 @@ import org.rs09.consts.NPCs
|
|||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.world.GameWorld.Pulser
|
||||
import content.data.Quests
|
||||
|
||||
class GCItemOnCat : InteractionListener {
|
||||
override fun defineListeners() {
|
||||
val GERTCAT = "Gertrude's Cat"
|
||||
val BEND_DOWN = 827
|
||||
|
||||
onUseWith(IntType.NPC, Items.BUCKET_OF_MILK_1927, NPCs.GERTRUDES_CAT_2997) { player, used, with ->
|
||||
if(getQuestStage(player, GERTCAT) == 20 && removeItem(player, used.asItem())){
|
||||
if(getQuestStage(player, Quests.GERTRUDES_CAT) == 20 && removeItem(player, used.asItem())){
|
||||
addItem(player, Items.BUCKET_1925)
|
||||
animate(player, BEND_DOWN) //bend down
|
||||
sendChat(with.asNpc(), "Mew!")
|
||||
setQuestStage(player, GERTCAT, 30)
|
||||
setQuestStage(player, Quests.GERTRUDES_CAT, 30)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.NPC, Items.DOOGLE_SARDINE_1552, NPCs.GERTRUDES_CAT_2997){ player, used, with ->
|
||||
if(getQuestStage(player, GERTCAT) == 30 && removeItem(player, used.asItem())){
|
||||
if(getQuestStage(player, Quests.GERTRUDES_CAT) == 30 && removeItem(player, used.asItem())){
|
||||
animate(player, BEND_DOWN)
|
||||
sendChat(with.asNpc(), "Mew!")
|
||||
setQuestStage(player, GERTCAT, 40)
|
||||
setQuestStage(player, Quests.GERTRUDES_CAT, 40)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ class GCItemOnCat : InteractionListener {
|
|||
|
||||
onUseWith(IntType.NPC, Items.THREE_LITTLE_KITTENS_13236, NPCs.GERTRUDES_CAT_2997){ player, used, with ->
|
||||
if(removeItem(player, used.asItem())){
|
||||
setQuestStage(player, GERTCAT, 60)
|
||||
setQuestStage(player, Quests.GERTRUDES_CAT, 60)
|
||||
//below copied verbatim from original, I don't like it.
|
||||
Pulser.submit(object : Pulse(1) {
|
||||
var count = 0
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import core.game.world.map.path.Pathfinder;
|
|||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle the use with interactions.
|
||||
|
|
@ -50,7 +51,7 @@ public final class GertrudeCatUsePlugin extends UseWithHandler {
|
|||
public boolean handle(NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
final NPC npc = ((NPC) event.getUsedWith());
|
||||
final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat");
|
||||
final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT);
|
||||
if (event.getUsedItem().getId() == 1927 && quest.getStage(player) == 20) {
|
||||
if (player.getInventory().remove(event.getUsedItem())) {
|
||||
player.getInventory().add(EMPTY_BUCKET);
|
||||
|
|
|
|||
|
|
@ -5,20 +5,19 @@ import org.rs09.consts.Items
|
|||
import org.rs09.consts.NPCs
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import content.data.Quests
|
||||
|
||||
class RopeOnLadyKeli : InteractionListener {
|
||||
override fun defineListeners() {
|
||||
val PAR = "Prince Ali Rescue"
|
||||
|
||||
onUseWith(IntType.NPC, Items.ROPE_954, NPCs.LADY_KELI_919) { player, used, with ->
|
||||
if(getQuestStage(player, PAR) in 40..50 && getAttribute(player, "guard-drunk", false)){
|
||||
if(getQuestStage(player, Quests.PRINCE_ALI_RESCUE) in 40..50 && getAttribute(player, "guard-drunk", false)){
|
||||
if(removeItem(player, used.asItem())){
|
||||
sendDialogue(player, "You overpower Keli, tie her up, and put her in a cupboard.")
|
||||
setQuestStage(player, PAR, 50)
|
||||
setQuestStage(player, Quests.PRINCE_ALI_RESCUE, 50)
|
||||
setAttribute(player, "keli-gone", getWorldTicks() + 350)
|
||||
}
|
||||
} else {
|
||||
if (getQuestStage(player, PAR) == 40){
|
||||
if (getQuestStage(player, Quests.PRINCE_ALI_RESCUE) == 40){
|
||||
sendMessage(player, "You need to do something about the guard first.")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package content.global.handlers.item.withobject
|
||||
|
||||
import content.data.Quests
|
||||
import core.api.*
|
||||
import content.region.kandarin.quest.dwarfcannon.DwarfCannon
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
|
|
@ -19,8 +19,8 @@ class AmmoMouldOnFurnace : InteractionListener {
|
|||
private fun cannonBallOnUseWithHandler(player: Player, used: Node, with: Node): Boolean {
|
||||
face(player, with.centerLocation)
|
||||
|
||||
if(!isQuestComplete(player, DwarfCannon.NAME)) {
|
||||
sendDialogue(player, "You need to complete the ${DwarfCannon.NAME} quest in order to do this.")
|
||||
if(!isQuestComplete(player, Quests.DWARF_CANNON)) {
|
||||
sendDialogue(player, "You need to complete the ${Quests.DWARF_CANNON} quest in order to do this.")
|
||||
return true
|
||||
}
|
||||
if (getDynLevel(player, Skills.SMITHING) < levelRequirement) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import core.game.node.scenery.Scenery;
|
|||
import core.plugin.Plugin;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.ClassScanner;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Represents the option handler used for smithing.
|
||||
|
|
@ -68,7 +69,7 @@ public final class SmithingPlugin extends UseWithHandler {
|
|||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
if (((Scenery) event.getUsedWith()).getId() == 2782 && !player.getQuestRepository().isComplete("Doric's Quest")) {
|
||||
if (((Scenery) event.getUsedWith()).getId() == 2782 && !player.getQuestRepository().isComplete(Quests.DORICS_QUEST)) {
|
||||
player.getDialogueInterpreter().sendDialogue("Property of Doric the Dwarf.");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import core.game.node.item.GroundItemManager;
|
|||
import core.game.node.item.Item;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.world.map.Location;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Represents a rat npc.
|
||||
|
|
@ -51,7 +52,7 @@ public class RatNPC extends AbstractNPC {
|
|||
super.finalizeDeath(killer);
|
||||
if (killer instanceof Player) {
|
||||
final Player p = ((Player) killer);
|
||||
if (p.getQuestRepository().getQuest("Witch's Potion").isStarted(p)) {
|
||||
if (p.getQuestRepository().getQuest(Quests.WITCHS_POTION).isStarted(p)) {
|
||||
GroundItemManager.create(RAT_TAIL, getLocation(), p);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.rs09.consts.NPCs
|
|||
import org.rs09.consts.Sounds
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.Direction
|
||||
import content.data.Quests
|
||||
|
||||
private val sheepIds = intArrayOf(
|
||||
NPCs.SHEEP_42,
|
||||
|
|
@ -74,7 +75,7 @@ class SheepBehavior : NPCBehavior(*sheepIds), InteractionListener {
|
|||
val sheep = node as NPC
|
||||
sheep.faceTemporary(player, 1)
|
||||
if (sheep.id == NPCs.SHEEP_3579) {
|
||||
if (player.questRepository.getQuest("Sheep Shearer").isStarted(player)) {
|
||||
if (player.questRepository.getQuest(Quests.SHEEP_SHEARER).isStarted(player)) {
|
||||
setAttribute(player, ATTR_IS_PENGUIN_SHEEP_SHEARED, true)
|
||||
}
|
||||
animate(player, Animation(893))
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public final class FieldPickingPlugin extends OptionHandler {
|
|||
player.dispatch(new ResourceProducedEvent(reward.getId(), reward.getAmount(), node, -1));
|
||||
if (plant.name().startsWith("NETTLES") && (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) == null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null && !player.getEquipment().get(EquipmentContainer.SLOT_HANDS).getName().contains("glove"))) {
|
||||
player.getPacketDispatch().sendMessage("You have been stung by the nettles!");
|
||||
player.getImpactHandler().manualHit(player, 2, HitsplatType.POISON);
|
||||
player.getImpactHandler().manualHit(player, 6, HitsplatType.POISON);
|
||||
return true;
|
||||
}
|
||||
if (plant.respawn != -1 && plant != PickingPlant.FLAX) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import core.game.node.entity.player.Player;
|
|||
import core.game.node.item.Item;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import content.data.Quests;
|
||||
|
||||
import static core.api.ContentAPIKt.*;
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ public class SearchOptionPlugin extends OptionHandler {
|
|||
player.getInventory().add(new Item(946));
|
||||
return true;
|
||||
}
|
||||
if (node.getId() == 12799 && hasRequirement(player, "In Aid of the Myreque")) {
|
||||
if (node.getId() == 12799 && hasRequirement(player, Quests.IN_AID_OF_THE_MYREQUE)) {
|
||||
openBankAccount(player);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,18 +11,21 @@ class SignpostListener : InteractionListener {
|
|||
override fun defineListeners() {
|
||||
on(Scenery.SIGNPOST_18493, IntType.SCENERY, "read") { player, node ->
|
||||
if (node.asScenery().location.equals(Location(3235, 3228))) {
|
||||
// Authentic
|
||||
setInterfaceText(player, "Head north towards Fred's farm, and the windmill.", 135, 3) // North
|
||||
setInterfaceText(player, "South to the swamps of Lumbridge.", 135, 9) // South
|
||||
setInterfaceText(player, "Cross the bridge and head east to Al Kharid or north to Varrock.", 135, 8) // East
|
||||
setInterfaceText(player, "West to the Lumbridge Castle and Draynor Village. Beware the goblins!", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
} else if (node.asScenery().location.equals(Location(3261, 3230))) {
|
||||
// Authentic
|
||||
setInterfaceText(player, "North to farms and Varrock.", 135, 3) // North
|
||||
setInterfaceText(player, "The River Lum lies to the south.", 135, 9) // South
|
||||
setInterfaceText(player, "East to Al Kharid - toll gate; bring some money.", 135, 8) // East
|
||||
setInterfaceText(player, "West to Lumbridge.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
} else if (node.asScenery().location.equals(Location(2983, 3278))) {
|
||||
// Authentic
|
||||
setInterfaceText(player, "North to the glorious White Knights' city of Falador.", 135, 3) // North
|
||||
setInterfaceText(player, "South to Rimmington.", 135, 9) // South
|
||||
setInterfaceText(player, "East to Port Sarim and Draynor Village.", 135, 8) // East
|
||||
|
|
@ -45,12 +48,14 @@ class SignpostListener : InteractionListener {
|
|||
}
|
||||
on(Scenery.SIGNPOST_24263, IntType.SCENERY, "read") { player, node ->
|
||||
if (node.asScenery().location.equals(Location(3268, 3332))) {
|
||||
// Authentic
|
||||
setInterfaceText(player, "Sheep lay this way.", 135, 3) // North
|
||||
setInterfaceText(player, "South through farms to Al Kharid and Lumbridge.", 135, 9) // South
|
||||
setInterfaceText(player, "East to Al Kharid mine and follow the path north to Varrock east gate.", 135, 8) // East
|
||||
setInterfaceText(player, "West to Champion's Guild and Varrock south gate.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
} else if (node.asScenery().location.equals(Location(3283, 3333))) {
|
||||
// Authentic
|
||||
setInterfaceText(player, "North to Varrock mine and Varrock east gate.", 135, 3) // North
|
||||
setInterfaceText(player, "South to large Mining area and Al Kharid.", 135, 9) // South
|
||||
setInterfaceText(player, "Follow the path east to the Dig Site.", 135, 8) // East
|
||||
|
|
@ -66,7 +71,13 @@ class SignpostListener : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
on(Scenery.SIGNPOST_4132, IntType.SCENERY, "read") { player, node ->
|
||||
if (node.asScenery().location.equals(Location(3166, 3286))) {
|
||||
if (node.asScenery().location.equals(Location(3223, 3427))) {
|
||||
setInterfaceText(player, "North to Varrock Palace.", 135, 3) // North
|
||||
setInterfaceText(player, "South to the Champion's Guild.", 135, 9) // South
|
||||
setInterfaceText(player, "East to the Dig Site.", 135, 8) // East
|
||||
setInterfaceText(player, "West to Barbarian Village and Falador.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
} else if (node.asScenery().location.equals(Location(3166, 3286))) {
|
||||
setInterfaceText(player, "North to the windmill.", 135, 3) // North
|
||||
setInterfaceText(player, "South to a fishing pond next to Fred's farm.", 135, 9) // South
|
||||
setInterfaceText(player, "East to Lumbridge.", 135, 8) // East
|
||||
|
|
@ -133,6 +144,56 @@ class SignpostListener : InteractionListener {
|
|||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.SIGNPOST_4135, IntType.SCENERY, "read") { player, node ->
|
||||
if (node.asScenery().location.equals(Location(3448, 3486))) {
|
||||
setInterfaceText(player, "North to the Slayer Tower.", 135, 3) // North
|
||||
setInterfaceText(player, "South to Mort Myre Swamp.", 135, 9) // South
|
||||
setInterfaceText(player, "East to Canifis.", 135, 8) // East
|
||||
setInterfaceText(player, "West to Varrock.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
} else {
|
||||
setInterfaceText(player, "North to unknown.", 135, 3) // North
|
||||
setInterfaceText(player, "South to unknown.", 135, 9) // South
|
||||
setInterfaceText(player, "East to unknown.", 135, 8) // East
|
||||
setInterfaceText(player, "West to unknown.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.SIGNPOST_31296, IntType.SCENERY, "read") { player, node ->
|
||||
if (node.asScenery().location.equals(Location(3304, 3109))) {
|
||||
// Authentic
|
||||
setInterfaceText(player, "North to Al Kharid.", 135, 3) // North
|
||||
setInterfaceText(player, "South to the Desert Mining Camp and Pollnivneach.", 135, 9) // South
|
||||
setInterfaceText(player, "East and across the river to the Ruins of Uzer.", 135, 8) // East
|
||||
setInterfaceText(player, "West to the Kalphite Lair.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
} else {
|
||||
setInterfaceText(player, "North to unknown.", 135, 3) // North
|
||||
setInterfaceText(player, "South to unknown.", 135, 9) // South
|
||||
setInterfaceText(player, "East to unknown.", 135, 8) // East
|
||||
setInterfaceText(player, "West to unknown.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
on(Scenery.STONE_SIGNPOST_11630, IntType.SCENERY, "read") { player, node ->
|
||||
// Authentic // https://youtu.be/vvHXKTOh_g4
|
||||
if (node.asScenery().location.equals(Location(2967, 3412))) {
|
||||
setInterfaceText(player, "North to Goblin Village.", 135, 3) // North
|
||||
setInterfaceText(player, "South to Falador.", 135, 9) // South
|
||||
setInterfaceText(player, "East to Varrock.", 135, 8) // East
|
||||
setInterfaceText(player, "West to Taverley.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
} else {
|
||||
setInterfaceText(player, "North to unknown.", 135, 3) // North
|
||||
setInterfaceText(player, "South to unknown.", 135, 9) // South
|
||||
setInterfaceText(player, "East to unknown.", 135, 8) // East
|
||||
setInterfaceText(player, "West to unknown.", 135, 12) // West
|
||||
openInterface(player, Components.AIDE_COMPASS_135)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Old handlers of Signpost. Not all should be opening the AIDE_COMPASS.
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import core.game.world.map.Location;
|
|||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Handles the bar squeezing shortcut.
|
||||
|
|
@ -61,7 +62,7 @@ public class BarSqueezeShortcut extends AgilityShortcut {
|
|||
|
||||
@Override
|
||||
public boolean checkRequirements(Player player) {
|
||||
if (!player.getQuestRepository().isComplete("Priest in Peril") && !(player.getLocation().getY() >= 3159 && player.getLocation().getY() <= 3161)) {
|
||||
if (!player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL) && !(player.getLocation().getY() >= 3159 && player.getLocation().getY() <= 3161)) {
|
||||
player.getDialogueInterpreter().sendDialogue("You need to have completed Priest in Peril in order to do this.");
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import core.plugin.Initializable;
|
|||
import core.plugin.Plugin;
|
||||
|
||||
import static core.api.ContentAPIKt.hasRequirement;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Handles a tunnel shortcut.
|
||||
|
|
@ -73,7 +74,7 @@ public class TunnelShortcut extends AgilityShortcut {
|
|||
@Override
|
||||
public void run(final Player player, Scenery object, String option, boolean failed) {
|
||||
if (object.getId() == 14922) {
|
||||
if (!hasRequirement(player, "Swan Song"))
|
||||
if (!hasRequirement(player, Quests.SWAN_SONG))
|
||||
return;
|
||||
}
|
||||
player.lock(6);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package content.global.skill.construction;
|
|||
import core.game.node.entity.player.Player;
|
||||
import org.rs09.consts.Items;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Family crest types.
|
||||
|
|
@ -16,7 +17,7 @@ public enum CrestType implements CrestRequirement {
|
|||
|
||||
@Override
|
||||
public boolean eligible(Player player) {
|
||||
return player.getQuestRepository().isComplete("Shield of Arrav");
|
||||
return player.getQuestRepository().isComplete(Quests.SHIELD_OF_ARRAV);
|
||||
}
|
||||
},
|
||||
ASGARNIA("the symbol of Asgarnia"), // no requirements
|
||||
|
|
@ -24,21 +25,21 @@ public enum CrestType implements CrestRequirement {
|
|||
|
||||
@Override
|
||||
public boolean eligible(Player player) {
|
||||
return player.getQuestRepository().isComplete("The Lost Tribe");
|
||||
return player.getQuestRepository().isComplete(Quests.THE_LOST_TRIBE);
|
||||
}
|
||||
},
|
||||
DRAGON("a dragon") { // requires Dragon Slayer
|
||||
|
||||
@Override
|
||||
public boolean eligible(Player player) {
|
||||
return player.getQuestRepository().isComplete("Dragon Slayer");
|
||||
return player.getQuestRepository().isComplete(Quests.DRAGON_SLAYER);
|
||||
}
|
||||
},
|
||||
FAIRY("a fairy") { // requries Lost City
|
||||
|
||||
@Override
|
||||
public boolean eligible(Player player) {
|
||||
return player.getQuestRepository().isComplete("Lost City");
|
||||
return player.getQuestRepository().isComplete(Quests.LOST_CITY);
|
||||
}
|
||||
},
|
||||
GUTHIX("the symbol of Guthix") { // Requires 70+ Prayer
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import core.game.world.GameWorld;
|
|||
import org.rs09.consts.Sounds;
|
||||
|
||||
import java.awt.*;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static core.api.ContentAPIKt.*;
|
||||
import static core.api.regionspec.RegionSpecificationKt.fillWith;
|
||||
|
|
@ -99,36 +98,6 @@ public final class HouseManager {
|
|||
}
|
||||
|
||||
|
||||
public void save(ByteBuffer buffer) {
|
||||
buffer.put((byte) location.ordinal());
|
||||
buffer.put((byte) style.ordinal());
|
||||
if (hasServant()) {
|
||||
servant.save(buffer);
|
||||
} else {
|
||||
buffer.put((byte) -1);
|
||||
}
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
Room room = rooms[z][x][y];
|
||||
if (room != null) {
|
||||
buffer.put((byte) z).put((byte) x).put((byte) y);
|
||||
buffer.put((byte) room.getProperties().ordinal());
|
||||
buffer.put((byte) room.getRotation().toInteger());
|
||||
for (int i = 0; i < room.getHotspots().length; i++) {
|
||||
if (room.getHotspots()[i].getDecorationIndex() > -1) {
|
||||
buffer.put((byte) i);
|
||||
buffer.put((byte) room.getHotspots()[i].getDecorationIndex());
|
||||
}
|
||||
}
|
||||
buffer.put((byte) -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.put((byte) -1);//Eof
|
||||
}
|
||||
|
||||
public void parse(JSONObject data){
|
||||
location = HouseLocation.values()[Integer.parseInt( data.get("location").toString())];
|
||||
style = HousingStyle.values()[Integer.parseInt( data.get("style").toString())];
|
||||
|
|
@ -155,28 +124,6 @@ public final class HouseManager {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public void parse(ByteBuffer buffer) {
|
||||
location = HouseLocation.values()[buffer.get() & 0xFF];
|
||||
style = HousingStyle.values()[buffer.get() & 0xFF];
|
||||
servant = Servant.parse(buffer);
|
||||
int z = 0;
|
||||
while ((z = buffer.get()) != -1) {
|
||||
if (z == 3) {
|
||||
hasDungeon = true;
|
||||
}
|
||||
int x = buffer.get();
|
||||
int y = buffer.get();
|
||||
Room room = rooms[z][x][y] = new Room(RoomProperties.values()[buffer.get() & 0xFF]);
|
||||
room.configure(style);
|
||||
room.setRotation(Direction.get(buffer.get() & 0xFF));
|
||||
int spot = 0;
|
||||
while ((spot = buffer.get()) != -1) {
|
||||
room.getHotspots()[spot].setDecorationIndex(buffer.get() & 0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares for entering the player's house.
|
||||
* @param player
|
||||
|
|
@ -257,7 +204,7 @@ public final class HouseManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Leaves this house.
|
||||
* Leaves this house through the portal.
|
||||
* @param player The player leaving.
|
||||
*/
|
||||
public static void leave(Player player) {
|
||||
|
|
@ -268,7 +215,6 @@ public final class HouseManager {
|
|||
if (house.isInHouse(player)) {
|
||||
player.animate(Animation.RESET);
|
||||
player.getProperties().setTeleportLocation(house.location.getExitLocation());
|
||||
removeAttribute(player, "original-loc");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ package content.global.skill.construction;
|
|||
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.world.map.build.DynamicRegion;
|
||||
import core.game.world.map.zone.MapZone;
|
||||
import core.game.world.map.zone.ZoneRestriction;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.map.Region;
|
||||
import core.game.system.task.Pulse;
|
||||
import core.game.world.map.zone.ZoneRestriction;
|
||||
|
||||
import static core.api.ContentAPIKt.*;
|
||||
|
||||
|
|
@ -81,14 +82,16 @@ public final class HouseZone extends MapZone {
|
|||
if (e instanceof Player) {
|
||||
Player p = (Player) e;
|
||||
HouseManager.leave(p);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return super.death(e, killer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean leave(Entity e, boolean logout) {
|
||||
if (e instanceof Player) {
|
||||
Player p = (Player) e;
|
||||
// The below tears down the house if the owner was the one who left
|
||||
if (house == p.getHouseManager()) {
|
||||
house.expelGuests(p);
|
||||
int toRemove = previousRegion;
|
||||
|
|
@ -109,7 +112,11 @@ public final class HouseZone extends MapZone {
|
|||
}
|
||||
});
|
||||
}
|
||||
// Clear logout listener and original-loc (if appropriate)
|
||||
clearLogoutListener(p, "houselogout");
|
||||
if (!getAttribute(p, "kidnapped-by-random", false)) {
|
||||
removeAttribute(p, "/save:original-loc");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import core.game.node.entity.npc.NPC;
|
|||
import core.game.node.item.Item;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Represents a player's servant.
|
||||
* @author Emperor
|
||||
|
|
@ -44,26 +42,9 @@ public final class Servant extends NPC {
|
|||
}
|
||||
|
||||
/**
|
||||
* Saves the servant details.
|
||||
* @param buffer The buffer to write on.
|
||||
*/
|
||||
public void save(ByteBuffer buffer) {
|
||||
buffer.put((byte) type.ordinal());
|
||||
buffer.putShort((byte) uses);
|
||||
if (item == null) {
|
||||
buffer.putShort((short) -1);
|
||||
} else {
|
||||
buffer.putShort((short) item.getId());
|
||||
buffer.putInt(item.getAmount());
|
||||
}
|
||||
buffer.put((byte) (greet ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the servant from the buffer.
|
||||
* Parses the servant from the save file.
|
||||
* @return The servant.
|
||||
*/
|
||||
|
||||
public static Servant parse(JSONObject data){
|
||||
int type = Integer.parseInt( data.get("type").toString());
|
||||
Servant servant = new Servant(ServantType.values()[type]);
|
||||
|
|
@ -77,21 +58,6 @@ public final class Servant extends NPC {
|
|||
return servant;
|
||||
}
|
||||
|
||||
public static Servant parse(ByteBuffer buffer) {
|
||||
int type = buffer.get();
|
||||
if (type == -1) {
|
||||
return null;
|
||||
}
|
||||
Servant servant = new Servant(ServantType.values()[type]);
|
||||
servant.uses = buffer.getShort() & 0xFFFF;
|
||||
int itemId = buffer.getShort() & 0xFFFF;
|
||||
if ((short) itemId != -1) {
|
||||
servant.item = new Item(itemId, buffer.getInt());
|
||||
}
|
||||
servant.greet = buffer.get() == 1;
|
||||
return servant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item value.
|
||||
* @return The item.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import core.plugin.Initializable;
|
|||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
|
||||
import static content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
* PortalChamberPlugin
|
||||
* @author Clayton Williams
|
||||
|
|
@ -87,6 +89,12 @@ public class PortalChamberPlugin extends OptionHandler {
|
|||
}
|
||||
for (Locations l : Locations.values()) {
|
||||
if (l.name().contains(identifier)) {
|
||||
if (l == Locations.ARDOUGNE){
|
||||
if (player.getAttribute(ARDOUGNE_TELE_ATTRIBUTE, false)){
|
||||
player.sendMessage("You do not have the requirements to direct the portal there");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Item[] runes = l.runes;
|
||||
if (!player.getInventory().containsItems(runes)) {
|
||||
player.sendMessage("You do not have the required runes to build this portal");
|
||||
|
|
@ -130,6 +138,12 @@ public class PortalChamberPlugin extends OptionHandler {
|
|||
case "enter":
|
||||
String objectName = object.getName();
|
||||
for (Locations l : Locations.values()) {
|
||||
if (l == Locations.ARDOUGNE){
|
||||
if (player.getAttribute(ARDOUGNE_TELE_ATTRIBUTE, false)){
|
||||
player.sendMessage("You do not have the requirements to enter this portal.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (objectName.toLowerCase().contains(l.name().toLowerCase())) {
|
||||
player.teleport(l.location);
|
||||
if (player.getHouseManager().isInHouse(player) && node.getId() == 13635) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import core.game.node.entity.player.Player
|
|||
import core.game.node.entity.player.link.diary.DiaryType
|
||||
import core.game.node.entity.skill.Skills
|
||||
import content.global.skill.construction.Decoration
|
||||
import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE
|
||||
import core.game.node.entity.combat.spell.MagicStaff
|
||||
import core.game.node.item.Item
|
||||
import core.game.system.task.Pulse
|
||||
|
|
@ -84,6 +85,11 @@ class LecternPlugin : OptionHandler() {
|
|||
player.sendMessages("You need the Bones to Peaches ability purchased from MTA before making these.", "This requirement doesn't apply to actually using the tabs.")
|
||||
return false
|
||||
}
|
||||
if(this == ARDOUGNE && !getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)){
|
||||
sendMessage(player, "You need to unlock Ardougne teleport before you can make a tablet.")
|
||||
return false
|
||||
|
||||
}
|
||||
var found = false
|
||||
for (d in requiredDecorations) if (d.objectId == objectId) found = true
|
||||
if (!found) {
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ public class HouseServantDialogue extends DialoguePlugin {
|
|||
bankFetch(player, new Item(Items.MARBLE_BLOCK_8786));
|
||||
break;
|
||||
case 3: //magic stones
|
||||
bankFetch(player, new Item(Items.MAGIC_STONE_4703));
|
||||
bankFetch(player, new Item(Items.MAGIC_STONE_8788));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class CookingRewrite : InteractionListener {
|
|||
}
|
||||
|
||||
companion object {
|
||||
val COOKING_OBJs = intArrayOf(24313,21302, 13528, 13529, 13533, 13531, 13536, 13539, 13542, 2728, 2729, 2730, 2731, 2732, 2859, 3038, 3039, 3769, 3775, 4265, 4266, 5249, 5499, 5631, 5632, 5981, 9682, 10433, 11404, 11405, 11406, 12102, 12796, 13337, 13881, 14169, 14919, 15156, 20000, 20001, 21620, 21792, 22713, 22714, 23046, 24283, 24284, 25155, 25156, 25465, 25730, 27297, 29139, 30017, 32099, 33500, 34495, 34546, 36973, 37597, 37629, 37726, 114, 4172, 5275, 8750, 16893, 22154, 34410, 34565, 114, 9085, 9086, 9087, 12269, 15398, 25440, 25441, 2724, 2725, 2726, 4618, 4650, 5165, 6093, 6094, 6095, 6096, 8712, 9374, 9439, 9440, 9441, 10824, 17640, 17641, 17642, 17643, 18039, 21795, 24285, 24329, 27251, 33498, 35449, 36815, 36816, 37426, 40110, 10377)
|
||||
val COOKING_OBJs = intArrayOf(24313,21302, 13528, 13529, 13533, 13531, 13536, 13539, 13542, 2728, 2729, 2730, 2731, 2732, 2859, 3038, 3039, 3769, 3775, 4265, 4266, 5249, 5499, 5631, 5632, 5981, 9682, 10433, 11404, 11405, 11406, 12102, 12796, 13337, 13881, 14169, 14919, 15156, 20000, 20001, 21620, 21792, 22713, 22714, 23046, 24283, 24284, 25155, 25156, 25465, 25730, 27297, 29139, 30017, 32099, 33500, 34495, 34546, 36973, 37597, 37629, 37726, 114, 4172, 5275, 8750, 16893, 22154, 34410, 34565, 114, 9085, 9086, 9087, 12269, 15398, 25440, 25441, 2724, 2725, 2726, 4618, 4650, 5165, 6093, 6094, 6095, 6096, 8712, 9374, 9439, 9440, 9441, 10824, 17640, 17641, 17642, 17643, 18039, 18170, 21795, 24285, 24329, 27251, 33498, 35449, 36815, 36816, 37426, 40110, 10377)
|
||||
|
||||
@JvmStatic
|
||||
fun cook(player: Player, `object`: Scenery?, initial: Int, product: Int, amount: Int) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import content.global.skill.skillcapeperks.SkillcapePerks;
|
|||
import core.game.event.ResourceProducedEvent;
|
||||
import core.game.node.entity.impl.Animator;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.entity.player.info.LogType;
|
||||
import core.game.node.entity.player.info.PlayerMonitor;
|
||||
import core.game.node.entity.player.link.audio.Audio;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.item.GroundItemManager;
|
||||
|
|
@ -15,7 +17,8 @@ import core.tools.RandomFunction;
|
|||
import org.rs09.consts.Items;
|
||||
import org.rs09.consts.Sounds;
|
||||
|
||||
import static core.api.ContentAPIKt.playAudio;
|
||||
import static core.api.ContentAPIKt.*;
|
||||
import content.data.Quests;
|
||||
|
||||
public class StandardCookingPulse extends Pulse {
|
||||
//range animation
|
||||
|
|
@ -38,12 +41,17 @@ public class StandardCookingPulse extends Pulse {
|
|||
private boolean burned = false;
|
||||
public CookableItems properties;
|
||||
|
||||
private int initialAmount;
|
||||
private int processedAmount;
|
||||
|
||||
public StandardCookingPulse(Player player, Scenery object, int initial, int product, int amount) {
|
||||
this.player = player;
|
||||
this.object = object;
|
||||
this.initial = initial;
|
||||
this.product = product;
|
||||
this.amount = amount;
|
||||
this.initialAmount = amountInInventory(player, initial);
|
||||
this.processedAmount = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -72,7 +80,7 @@ public class StandardCookingPulse extends Pulse {
|
|||
this.experience = 0;
|
||||
if (properties != null) {
|
||||
// Handle Cook's Assistant range
|
||||
if (object.getId() == LUMBRIDGE_RANGE && !player.getQuestRepository().isComplete("Cook's Assistant")) {
|
||||
if (object.getId() == LUMBRIDGE_RANGE && !player.getQuestRepository().isComplete(Quests.COOKS_ASSISTANT)) {
|
||||
player.getPacketDispatch().sendMessage("You need to have completed the Cook's Assistant quest in order to use that range.");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -169,6 +177,11 @@ public class StandardCookingPulse extends Pulse {
|
|||
player.getInventory().add(productItem);
|
||||
player.dispatch(new ResourceProducedEvent(productItem.getId(), 1, object, initialItem.getId()));
|
||||
player.getSkills().addExperience(Skills.COOKING, experience, true);
|
||||
processedAmount++;
|
||||
if (processedAmount > initialAmount) {
|
||||
PlayerMonitor.log(player, LogType.DUPE_ALERT, "cooked item (" + player.getName() + ", " + initialItem.getName() + "): initialAmount " + initialAmount + ", processedAmount " + processedAmount);
|
||||
}
|
||||
player.incrementAttribute("/save:stats_manager:food_cooked", 1);
|
||||
} else {
|
||||
player.dispatch(new ResourceProducedEvent(CookableItems.getBurnt(initial).getId(), 1, object, initialItem.getId()));
|
||||
player.getInventory().add(CookableItems.getBurnt(initial));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
package content.global.skill.cooking.recipe
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.skill.Skills
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class HangoverRecipe : InteractionListener {
|
||||
|
||||
companion object{
|
||||
private const val SNAPE_GRASS = Items.SNAPE_GRASS_231
|
||||
private const val HANGOVER_CURE = Items.HANGOVER_CURE_1504
|
||||
private const val BUCKET_OF_MILK = Items.BUCKET_OF_MILK_1927
|
||||
private const val CHOCOLATE_DUST = Items.CHOCOLATE_DUST_1975
|
||||
private const val CHOCOLATE_MILK = Items.CHOCOLATEY_MILK_1977
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.ITEM, CHOCOLATE_DUST, BUCKET_OF_MILK) { player, _, _ ->
|
||||
if(hasLevelDyn(player, Skills.COOKING, 4)){
|
||||
if(removeItem(player, CHOCOLATE_DUST) and removeItem(player, BUCKET_OF_MILK)){
|
||||
addItem(player, CHOCOLATE_MILK)
|
||||
sendItemDialogue(player, CHOCOLATE_MILK, "You mix the chocolate into the bucket.")
|
||||
}
|
||||
}
|
||||
else {
|
||||
sendDialogue(player, "You need a Cooking level of at least 4 to make chocolate milk.")
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM, SNAPE_GRASS, CHOCOLATE_MILK) { player, _, _ ->
|
||||
if (removeItem(player, SNAPE_GRASS) && removeItem(player, CHOCOLATE_MILK))
|
||||
{
|
||||
sendItemDialogue(player, HANGOVER_CURE, "You mix the snape grass into the bucket.")
|
||||
addItem(player, HANGOVER_CURE)
|
||||
return@onUseWith true
|
||||
}
|
||||
return@onUseWith false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -66,6 +66,12 @@ class LightSourceLighter : UseWithHandler(590,36,38){
|
|||
|
||||
lightSource ?: return false
|
||||
|
||||
// For Sea Slug Quest - No lighting of any torch on the fishing platform.
|
||||
if(event.player.location.isInRegion(11059)) {
|
||||
event.player.sendMessage("Your tinderbox is damp from the sea crossing. It won't work here.")
|
||||
return true
|
||||
}
|
||||
|
||||
if(!light(event.player,used,lightSource)){
|
||||
event.player.sendMessage("You need a Firemaking level of at least ${lightSource.levelRequired} to light this.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ class CropHarvester : OptionHandler() {
|
|||
if (patch.patch.type in livesBased) {
|
||||
patch.rollLivesDecrement(
|
||||
getDynLevel(player, Skills.FARMING),
|
||||
requiredItem == Items.MAGIC_SECATEURS_7409
|
||||
inInventory(player, Items.MAGIC_SECATEURS_7409) //add ||inEquipment() check when Fairy Tale pt 1 has been implemented
|
||||
)
|
||||
} else {
|
||||
patch.harvestAmt--
|
||||
|
|
|
|||
|
|
@ -154,7 +154,8 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl
|
|||
PatchType.FRUIT_TREE_PATCH -> setVarbit(player, patch.varbit, plantable!!.value + plantable!!.stages + 20)
|
||||
PatchType.BUSH_PATCH -> setVarbit(player, patch.varbit, 250 + (plantable!!.ordinal - Plantable.REDBERRY_SEED.ordinal))
|
||||
PatchType.CACTUS_PATCH -> setVarbit(player, patch.varbit, 31)
|
||||
else -> log(this::class.java, Log.WARN, "Invalid setting of isCheckHealth for patch type: " + patch.type.name)
|
||||
PatchType.TREE_PATCH -> setVarbit(player, patch.varbit, plantable!!.value + plantable!!.stages)
|
||||
else -> log(this::class.java, Log.WARN, "Invalid setting of isCheckHealth for patch type: " + patch.type.name + "at" + patch.name)
|
||||
}
|
||||
} else {
|
||||
when(patch.type){
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class ToolLeprechaunInterface : InterfaceListener {
|
|||
player ?: return
|
||||
val hasAmount = amountInInventory(player, item)
|
||||
var finalAmount = amount
|
||||
val spaceLeft = (if (item == Items.BUCKET_1925) 31 else 255) - quantityCheckMethod.invoke(player)
|
||||
val spaceLeft = (if (item == Items.BUCKET_1925) 255 else 255) - quantityCheckMethod.invoke(player)
|
||||
|
||||
if (hasAmount == 0) {
|
||||
val itemName = if (item == Items.BUCKET_1925) "buckets" else getItemName(item).lowercase()
|
||||
|
|
@ -183,7 +183,7 @@ class ToolLeprechaunInterface : InterfaceListener {
|
|||
|
||||
private fun doStackedWithdrawal(player: Player?, item: Int, amount: Int, updateQuantityMethod: (Player?, Int) -> Unit, quantityCheckMethod: (Player?) -> Int) {
|
||||
player ?: return
|
||||
val hasAmount = quantityCheckMethod.invoke(player)
|
||||
val hasAmount = if (item == Items.BUCKET_1925) 31 else quantityCheckMethod.invoke(player)
|
||||
var finalAmount = amount
|
||||
|
||||
if (hasAmount == 0) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import core.game.interaction.QueueStrength
|
|||
import core.tools.StringUtils
|
||||
import core.tools.prependArticle
|
||||
import org.rs09.consts.Sounds
|
||||
import content.data.Quests
|
||||
|
||||
class UseWithPatchHandler : InteractionListener {
|
||||
val RAKE = Items.RAKE_5341
|
||||
|
|
@ -39,7 +40,7 @@ class UseWithPatchHandler : InteractionListener {
|
|||
val usedItem = used.asItem()
|
||||
|
||||
if (patch == FarmingPatch.TROLL_STRONGHOLD_HERB) {
|
||||
if (!hasRequirement(player, "My Arm's Big Adventure"))
|
||||
if (!hasRequirement(player, Quests.MY_ARMS_BIG_ADVENTURE))
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
|
|
@ -263,51 +264,53 @@ class UseWithPatchHandler : InteractionListener {
|
|||
sendMessage(player, "You need ${prependArticle(requiredItem.asItem().name.lowercase())} to plant that.")
|
||||
return@onUseWith true
|
||||
}
|
||||
player.lock()
|
||||
if (removeItem(player, plantItem)) {
|
||||
when (requiredItem) {
|
||||
Items.SPADE_952 -> {
|
||||
animate(player, spadeDigAnim)
|
||||
playAudio(player, Sounds.DIGSPADE_1470)
|
||||
|
||||
queueScript(player, 0, QueueStrength.WEAK) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
val (anim, sound) = when (requiredItem) {
|
||||
Items.SPADE_952 -> Pair(spadeDigAnim, Sounds.DIGSPADE_1470)
|
||||
else -> Pair(seedDibberAnim,Sounds.FARMING_DIBBING_2432)
|
||||
}
|
||||
animate(player, anim)
|
||||
playAudio(player, sound)
|
||||
val delay = if (patch.type == PatchType.TREE_PATCH || patch.type == PatchType.FRUIT_TREE_PATCH || plantable == Plantable.SCARECROW) 3 else 0
|
||||
return@queueScript delayScript(player,anim.duration + delay)
|
||||
}
|
||||
Items.SEED_DIBBER_5343 -> {
|
||||
animate(player, seedDibberAnim)
|
||||
playAudio(player, Sounds.FARMING_DIBBING_2432)
|
||||
1 -> {
|
||||
if (removeItem(player, plantItem)) {
|
||||
if (plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 0, 7)) {
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 0, 7)
|
||||
}
|
||||
p.plant(plantable)
|
||||
rewardXP(player, Skills.FARMING, plantable.plantingXP)
|
||||
p.setNewHarvestAmount()
|
||||
if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) {
|
||||
addItem(player, Items.PLANT_POT_5350)
|
||||
}
|
||||
|
||||
val itemAmount =
|
||||
if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) "the"
|
||||
else if (plantItem.amount == 1) "a"
|
||||
else plantItem.amount
|
||||
val itemName =
|
||||
if (plantItem.amount == 1) plantable.displayName else StringUtils.plusS(
|
||||
plantable.displayName
|
||||
)
|
||||
val patchName = p.patch.type.displayName()
|
||||
if (plantable == Plantable.SCARECROW) {
|
||||
sendMessage(player, "You place the scarecrow in the $patchName.")
|
||||
} else {
|
||||
sendMessage(player, "You plant $itemAmount $itemName in the $patchName.")
|
||||
}
|
||||
}
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
val delay = if (patch.type == PatchType.TREE_PATCH || patch.type == PatchType.FRUIT_TREE_PATCH || plantable == Plantable.SCARECROW) 0 else 3
|
||||
submitIndividualPulse(player, object : Pulse(delay) {
|
||||
override fun pulse(): Boolean {
|
||||
if (plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 0, 7)) {
|
||||
player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 0, 7)
|
||||
}
|
||||
p.plant(plantable)
|
||||
rewardXP(player, Skills.FARMING, plantable.plantingXP)
|
||||
p.setNewHarvestAmount()
|
||||
if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) {
|
||||
addItem(player, Items.PLANT_POT_5350)
|
||||
}
|
||||
|
||||
val itemAmount =
|
||||
if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) "the"
|
||||
else if (plantItem.amount == 1) "a"
|
||||
else plantItem.amount
|
||||
val itemName = if (plantItem.amount == 1) plantable.displayName else StringUtils.plusS(plantable.displayName)
|
||||
val patchName = p.patch.type.displayName()
|
||||
if (plantable == Plantable.SCARECROW) {
|
||||
sendMessage(player, "You place the scarecrow in the $patchName.")
|
||||
} else {
|
||||
sendMessage(player, "You plant $itemAmount $itemName in the $patchName.")
|
||||
}
|
||||
|
||||
player.unlock()
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ enum class Fish(val id: Int, val level: Int, val experience: Double, val lowChan
|
|||
LOBSTER(Items.RAW_LOBSTER_377, 40, 90.0, 0.16, 0.375),
|
||||
BASS(Items.RAW_BASS_363, 46, 100.0, 0.078, 0.16),
|
||||
SWORDFISH(Items.RAW_SWORDFISH_371, 50, 100.0, 0.105, 0.191),
|
||||
LAVA_EEL(Items.RAW_LAVA_EEL_2148, 53, 30.0, 0.227, 0.379),
|
||||
LAVA_EEL(Items.RAW_LAVA_EEL_2148, 53, 60.0, 0.227, 0.379),
|
||||
MONKFISH(Items.RAW_MONKFISH_7944, 62, 120.0, 0.293, 0.356),
|
||||
KARAMBWAN(Items.RAW_KARAMBWAN_3142, 65, 105.0, 0.414, 0.629),
|
||||
SHARK(Items.RAW_SHARK_383, 76, 110.0, 0.121, 0.16),
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
package core.game.node.entity.skill.fletching;
|
||||
|
||||
import core.game.dialogue.SkillDialogueHandler;
|
||||
import core.game.dialogue.SkillDialogueHandler.SkillDialogue;
|
||||
import core.game.node.entity.skill.fletching.items.bolts.Bolt;
|
||||
import core.game.node.entity.skill.fletching.items.bolts.BoltPulse;
|
||||
import org.crandor.game.interaction.NodeUsageEvent;
|
||||
import org.crandor.game.interaction.UseWithHandler;
|
||||
import org.crandor.game.node.entity.player.Player;
|
||||
import org.crandor.net.packet.PacketRepository;
|
||||
import org.crandor.net.packet.context.ChildPositionContext;
|
||||
import org.crandor.net.packet.out.RepositionChild;
|
||||
import org.crandor.plugin.InitializablePlugin;
|
||||
import org.crandor.plugin.Plugin;
|
||||
|
||||
*/
|
||||
/**
|
||||
* Represents the bolt creating plugin.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*//*
|
||||
|
||||
@InitializablePlugin
|
||||
public final class BoltCreatePlugin extends UseWithHandler {
|
||||
|
||||
*/
|
||||
/**
|
||||
* Constructs a new {@code BoltCreatePlugin} {@code Object}.
|
||||
*//*
|
||||
|
||||
public BoltCreatePlugin() {
|
||||
super(314);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (Bolt bolt : Bolt.values()) {
|
||||
addHandler(bolt.getItem().getId(), ITEM_TYPE, this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(final NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
//package core.game.node.entity.skill.fletching;
|
||||
//
|
||||
//import core.game.dialogue.SkillDialogueHandler;
|
||||
//import core.game.dialogue.SkillDialogueHandler.SkillDialogue;
|
||||
//import core.game.node.entity.skill.fletching.items.gem.GemBolt;
|
||||
//import core.game.node.entity.skill.fletching.items.gem.GemBoltPulse;
|
||||
//import org.crandor.game.interaction.NodeUsageEvent;
|
||||
//import org.crandor.game.interaction.UseWithHandler;
|
||||
//import org.crandor.game.node.entity.player.Player;
|
||||
//import org.crandor.net.packet.PacketRepository;
|
||||
//import org.crandor.net.packet.context.ChildPositionContext;
|
||||
//import org.crandor.net.packet.out.RepositionChild;
|
||||
//import org.crandor.plugin.InitializablePlugin;
|
||||
//import org.crandor.plugin.Plugin;
|
||||
//
|
||||
///**
|
||||
// * Represents the plugin used to handle gem bolt making.
|
||||
// * @author 'Vexia
|
||||
// * @version 1.0
|
||||
// */
|
||||
//@InitializablePlugin
|
||||
//public class BoltGemPlugin extends UseWithHandler {
|
||||
//
|
||||
// /**
|
||||
// * Constructs a new {@code BoltGemPlugin} {@code Object}.
|
||||
// */
|
||||
// public BoltGemPlugin() {
|
||||
// super(45, 46, 9187, 9188, 9189, 9190, 9191, 9192, 9193, 9194);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
// for (GemBolt bolt : GemBolt.values()) {
|
||||
// addHandler(bolt.getBase().getId(), ITEM_TYPE, this);
|
||||
// }
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public boolean handle(final NodeUsageEvent event) {
|
||||
// final Player player = event.getPlayer();
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
package core.game.node.entity.skill.fletching;
|
||||
|
||||
import core.game.node.entity.skill.fletching.items.darts.Dart;
|
||||
import org.crandor.game.interaction.NodeUsageEvent;
|
||||
import org.crandor.game.interaction.UseWithHandler;
|
||||
import org.crandor.plugin.InitializablePlugin;
|
||||
import org.crandor.plugin.Plugin;
|
||||
import core.game.content.quest.touristrap.TouristTrap;
|
||||
|
||||
*/
|
||||
/**
|
||||
* Represents the plugin used to create a dart.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*//*
|
||||
|
||||
@InitializablePlugin
|
||||
public final class DartCreatePlugin extends UseWithHandler {
|
||||
|
||||
*/
|
||||
/**
|
||||
* Constructs a new {@code DartCreatePlugin} {@code Object}.
|
||||
*//*
|
||||
|
||||
public DartCreatePlugin() {
|
||||
super(314);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (Dart dart : Dart.values()) {
|
||||
addHandler(dart.getItem().getId(), ITEM_TYPE, this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
if (event.getPlayer().getQuestRepository().getQuest(TouristTrap.NAME).getStage(event.getPlayer()) < 60) {
|
||||
event.getPlayer().getPacketDispatch().sendMessage("You need to start Tourist Trap in order to do this.");
|
||||
return true;
|
||||
}
|
||||
event.getPlayer().getDialogueInterpreter().open(328933, event.getUsedItem(), event.getBaseItem());
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
package core.game.node.entity.skill.fletching;
|
||||
|
||||
import org.crandor.game.node.item.Item;
|
||||
|
||||
*/
|
||||
/**
|
||||
* Represents a fletching item to make.
|
||||
* @author 'Vexia
|
||||
*//*
|
||||
|
||||
public enum FletchItem {
|
||||
ARROW_SHAFT(FletchType.LOG, new Item(52, 15), 1, 5), SHORTBOW(FletchType.LOG, new Item(50), 5, 5),
|
||||
LONGBOW(FletchType.LOG, new Item(48), 10, 10),
|
||||
OAK_SHORTBOW(FletchType.OAK, new Item(54), 20, 16.5),
|
||||
OAK_LONGBOW(FletchType.OAK, new Item(56), 25, 25),
|
||||
WILLOW_SHORTBOW(FletchType.WILLOW, new Item(60), 35, 33.3),
|
||||
WILLOW_LONGBOW(FletchType.WILLOW, new Item(58), 40, 41.5),
|
||||
MAPLE_SHORTBOW(FletchType.MAPLE, new Item(64), 50, 50),
|
||||
MAPLE_LONGBOW(FletchType.MAPLE, new Item(62), 55, 58.3),
|
||||
YEW_SHORTBOW(FletchType.YEW, new Item(68), 65, 55),
|
||||
YEW_LONGBOW(FletchType.YEW, new Item(66), 70, 75),
|
||||
MAGIC_SHORTBOW(FletchType.MAGIC, new Item(72), 80, 83.3),
|
||||
MAGIC_LONGBOW(FletchType.MAGIC, new Item(70), 85, 91.5),
|
||||
WOODEN_STOCK(FletchType.LOG, new Item(9440), 9, 6),
|
||||
OAK_STOCK(FletchType.OAK, new Item(9442), 24, 16),
|
||||
WILLOW_STOCK(FletchType.WILLOW, new Item(9444), 39, 22),
|
||||
TEAK_STOCK(FletchType.TEAK, new Item(9446), 46, 27),
|
||||
MAPLE_STOCK(FletchType.MAPLE, new Item(9448), 54, 32),
|
||||
MAHOGANY_STOCK(FletchType.MAHOGANY, new Item(9450), 61, 41),
|
||||
YEW_STOCK(FletchType.YEW, new Item(9452), 69, 50);
|
||||
|
||||
*/
|
||||
/**
|
||||
* Constructs a new {@code FletchItem.java} {@code Object}.
|
||||
* @param type the type.
|
||||
* @param product the product.
|
||||
* @param level the level.
|
||||
* @param experience the experience.
|
||||
*//*
|
||||
|
||||
FletchItem(final FletchType type, final Item product, final int level, final double experience) {
|
||||
this.type = type;
|
||||
this.product = product;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Represents the type this item pertaint o.
|
||||
*//*
|
||||
|
||||
private FletchType type;
|
||||
|
||||
*/
|
||||
/**
|
||||
* Represents the product of this item.
|
||||
*//*
|
||||
|
||||
private Item product;
|
||||
|
||||
*/
|
||||
/**
|
||||
* Represents the level.
|
||||
*//*
|
||||
|
||||
private final int level;
|
||||
|
||||
*/
|
||||
/**
|
||||
* Represents the experience.
|
||||
*//*
|
||||
|
||||
private final double experience;
|
||||
|
||||
*/
|
||||
/**
|
||||
* Gets the type.
|
||||
* @return The type.
|
||||
*//*
|
||||
|
||||
public FletchType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Sets the type.
|
||||
* @param type The type to set.
|
||||
*//*
|
||||
|
||||
public void setType(FletchType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Gets the product.
|
||||
* @return The product.
|
||||
*//*
|
||||
|
||||
public Item getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Sets the product.
|
||||
* @param product The product to set.
|
||||
*//*
|
||||
|
||||
public void setProduct(Item product) {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Gets the level.
|
||||
* @return The level.
|
||||
*//*
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Gets the experience.
|
||||
* @return The experience.
|
||||
*//*
|
||||
|
||||
public double getExperience() {
|
||||
return experience;
|
||||
}
|
||||
}
|
||||
*/
|
||||
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