diff --git a/Server/data/ObjectParser.xml b/Server/data/ObjectParser.xml
index b10a0d445..bfd1c5167 100644
--- a/Server/data/ObjectParser.xml
+++ b/Server/data/ObjectParser.xml
@@ -11,7 +11,6 @@
-
diff --git a/Server/data/configs/door_configs.json b/Server/data/configs/door_configs.json
index 4dd902862..f342b1856 100644
--- a/Server/data/configs/door_configs.json
+++ b/Server/data/configs/door_configs.json
@@ -343,7 +343,7 @@
},
{
"id": "2054",
- "replaceId": "24375",
+ "replaceId": "2055",
"fence": "false",
"metal": "false"
},
@@ -419,18 +419,6 @@
"fence": "false",
"metal": "false"
},
- {
- "id": "2391",
- "replaceId": "1561",
- "fence": "false",
- "metal": "true"
- },
- {
- "id": "2392",
- "replaceId": "1561",
- "fence": "false",
- "metal": "true"
- },
{
"id": "2397",
"replaceId": "24383",
@@ -2169,7 +2157,7 @@
},
{
"id": "24376",
- "replaceId": "24377",
+ "replaceId": "24375",
"fence": "false",
"metal": "false"
},
diff --git a/Server/data/configs/ground_spawns.json b/Server/data/configs/ground_spawns.json
index 4be6a19b0..727fe50bc 100644
--- a/Server/data/configs/ground_spawns.json
+++ b/Server/data/configs/ground_spawns.json
@@ -141,7 +141,7 @@
},
{
"item_id": "401",
- "loc_data": "{1,2959,2959,0,160}-{1,2943,2950,0,160}-{1,2866,2976,0,160}-{1,2854,2977,0,160}-{1,2839,2975,0,160}-{1,2757,2947,0,160}-{1,2755,2952,0,160}-{1,2786,2960,0,160}-{1,2782,2987,0,160}-{1,2771,2995,0,160}-{1,2761,3000,0,160}-{1,3829,3053,0,160}-{1,3813,3066,0,160}-{1,3814,3064,0,160}-{1,3808,3060,0,160}-{1,2945,3068,0,160}-{1,2975,3013,0,160}-{1,2955,3010,0,160}-{1,2755,3008,0,160}-{1,2754,3017,0,160}-{1,2756,3060,0,160}-{1,2755,3070,0,160}-{1,2896,3119,0,160}-{1,2914,3111,0,160}-{1,2926,3110,0,160}-{1,2939,3102,0,160}-{1,2938,3073,0,160}-{1,2756,3074,0,160}-{1,2806,3128,0,160}-{1,2764,3131,0,160}-{1,2753,3125,0,160}-{1,2757,3109,0,160}-{1,2864,3195,0,160}-{1,2810,3387,0,160}-{1,2809,3388,0,160}-{1,2809,3385,0,160}-{1,2807,3386,0,160}-{1,2804,3385,0,160}-{1,2807,3384,0,160}-{1,2805,3384,0,160}-{1,2802,3382,0,160}-{1,2805,3381,0,160}-{1,2804,3380,0,160}-{1,2693,3727,0,160}-{1,2698,3729,0,160}-{1,2700,3731,0,160}-{1,2708,3728,0,160}-{1,2725,3731,0,160}-{1,2721,3730,0,160}-{1,2719,3733,0,160}-{1,2714,3733,0,160}-{1,2712,3732,0,160}-"
+ "loc_data": "{1,2959,2959,0,160}-{1,2866,2976,0,160}-{1,2854,2977,0,160}-{1,2839,2975,0,160}-{1,2943,2950,0,160}-{1,2757,2947,0,160}-{1,2755,2952,0,160}-{1,2786,2960,0,160}-{1,2782,2987,0,160}-{1,2771,2995,0,160}-{1,2761,3000,0,160}-{1,2945,3068,0,160}-{1,2975,3013,0,160}-{1,2955,3010,0,160}-{1,3829,3053,0,160}-{1,3813,3066,0,160}-{1,3814,3064,0,160}-{1,3808,3060,0,160}-{1,2755,3008,0,160}-{1,2754,3017,0,160}-{1,2756,3060,0,160}-{1,2755,3070,0,160}-{1,2896,3119,0,160}-{1,2914,3111,0,160}-{1,2926,3110,0,160}-{1,2939,3102,0,160}-{1,2938,3073,0,160}-{1,2756,3074,0,160}-{1,2806,3128,0,160}-{1,2764,3131,0,160}-{1,2753,3125,0,160}-{1,2757,3109,0,160}-{1,2864,3195,0,160}-{1,2810,3387,0,160}-{1,2809,3388,0,160}-{1,2809,3385,0,160}-{1,2807,3386,0,160}-{1,2804,3385,0,160}-{1,2807,3384,0,160}-{1,2805,3384,0,160}-{1,2802,3382,0,160}-{1,2805,3381,0,160}-{1,2804,3380,0,160}-{1,2693,3727,0,160}-{1,2698,3729,0,160}-{1,2700,3731,0,160}-{1,2708,3728,0,160}-{1,2725,3731,0,160}-{1,2721,3730,0,160}-{1,2719,3733,0,160}-{1,2714,3733,0,160}-{1,2712,3732,0,160}-"
},
{
"item_id": "444",
@@ -369,7 +369,7 @@
},
{
"item_id": "1573",
- "loc_data": "{1,2559,2975,0,10}-{1,2560,2974,0,10}-{1,2561,2973,0,10}-{1,2561,2976,0,10}-{1,2740,3637,0,30}-{1,2736,3638,0,30}-{1,2735,3636,0,30}-{1,2743,3636,0,30}-{1,2739,3634,0,30}-{1,2743,3640,0,30}-{1,2741,3639,0,30}-{1,2736,3641,0,30}-{1,2738,3641,0,30}-{1,2734,3640,0,30}-{1,2738,3636,0,30}-"
+ "loc_data": "{1,2560,2974,0,10}-{1,2561,2973,0,10}-{1,2561,2976,0,10}-{1,2559,2975,0,10}-{1,2740,3637,0,30}-{1,2736,3638,0,30}-{1,2735,3636,0,30}-{1,2743,3636,0,30}-{1,2739,3634,0,30}-{1,2743,3640,0,30}-{1,2741,3639,0,30}-{1,2736,3641,0,30}-{1,2738,3641,0,30}-{1,2734,3640,0,30}-{1,2738,3636,0,30}-"
},
{
"item_id": "1590",
@@ -469,7 +469,7 @@
},
{
"item_id": "1931",
- "loc_data": "{1,3209,3214,0,80}-{1,3166,3310,0,90}-{1,3144,3449,2,90}-"
+ "loc_data": "{1,3209,3214,0,80}-{1,3166,3310,0,90}-{1,3144,3449,2,90}-{1,2918,10191,1,90}-"
},
{
"item_id": "1935",
diff --git a/Server/data/configs/item_configs.json b/Server/data/configs/item_configs.json
index 07c04813b..f66a72738 100644
--- a/Server/data/configs/item_configs.json
+++ b/Server/data/configs/item_configs.json
@@ -17702,7 +17702,7 @@
{
"shop_price": "350",
"ge_buy_limit": "5000",
- "examine": "A plain gold amulet.",
+ "examine": "It needs a string so I can wear it.",
"grand_exchange_price": "172",
"durability": null,
"name": "Gold amulet",
@@ -17722,7 +17722,7 @@
{
"shop_price": "810",
"ge_buy_limit": "5000",
- "examine": "I wonder if I can get this enchanted.",
+ "examine": "It needs a string so I can wear it.",
"grand_exchange_price": "473",
"durability": null,
"name": "Sapphire amulet",
@@ -17742,7 +17742,7 @@
{
"shop_price": "1147",
"ge_buy_limit": "5000",
- "examine": "I wonder if I can get this enchanted.",
+ "examine": "It needs a string so I can wear it.",
"grand_exchange_price": "695",
"durability": null,
"name": "Emerald amulet",
@@ -17762,7 +17762,7 @@
{
"shop_price": "2025",
"ge_buy_limit": "5000",
- "examine": "I wonder if I can get this enchanted.",
+ "examine": "It needs a string so I can wear it.",
"grand_exchange_price": "1268",
"durability": null,
"name": "Ruby amulet",
@@ -17783,7 +17783,7 @@
{
"shop_price": "3307",
"ge_buy_limit": "5000",
- "examine": "I wonder if I can get this enchanted.",
+ "examine": "It needs a string so I can wear it.",
"grand_exchange_price": "3359",
"durability": null,
"name": "Diamond amulet",
@@ -17802,7 +17802,7 @@
},
{
"ge_buy_limit": "100",
- "examine": "I wonder if I can get this enchanted.",
+ "examine": "It needs a string so I can wear it.",
"grand_exchange_price": "26900",
"durability": null,
"name": "Dragonstone ammy",
@@ -48457,14 +48457,14 @@
},
{
"shop_price": "200",
- "examine": "An acorn has been sown and watered in this plant pot.",
+ "examine": "An acorn has been sown in this plant pot.",
"durability": null,
"name": "Oak seedling",
"archery_ticket_price": "0",
"id": "5358"
},
{
- "examine": "A willow tree seed has been sown and watered in this plant pot",
+ "examine": "A willow tree seed has been sown in this plant pot.",
"durability": null,
"name": "Willow seedling",
"weight": "0.9",
@@ -48472,7 +48472,7 @@
"id": "5359"
},
{
- "examine": "A maple tree has been sown (and watered) in this plant pot.",
+ "examine": "A maple tree seed has been sown in this plant pot.",
"durability": null,
"name": "Maple seedling",
"weight": "0.9",
@@ -48480,7 +48480,7 @@
"id": "5360"
},
{
- "examine": "A yew seed has been sown in the plant pot",
+ "examine": "A yew tree seed has been sown in this plant pot.",
"durability": null,
"name": "Yew seedling",
"weight": "1",
@@ -48488,7 +48488,7 @@
"id": "5361"
},
{
- "examine": "A magic tree seed has been sown and watered in this plant pot.",
+ "examine": "A magic tree seed has been sown in this plant pot.",
"durability": null,
"name": "Magic seedling",
"weight": "0.9",
@@ -48496,7 +48496,7 @@
"id": "5362"
},
{
- "examine": "A spirit seedling is growing in this pot. It has been sown and watered.",
+ "examine": "A spirit tree seed has been sown in this plant pot.",
"durability": null,
"name": "Spirit seedling",
"archery_ticket_price": "0",
@@ -48511,7 +48511,7 @@
"id": "5364"
},
{
- "examine": "A willow tree seed has been sown and watered in this plant pot",
+ "examine": "A willow tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Willow seedling",
"weight": "0.9",
@@ -48519,7 +48519,7 @@
"id": "5365"
},
{
- "examine": "A maple tree has been sown (and watered) in this plant pot.",
+ "examine": "A maple tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Maple seedling",
"weight": "0.9",
@@ -48527,7 +48527,7 @@
"id": "5366"
},
{
- "examine": "A yew seed has been sown in the plant pot",
+ "examine": "A yew tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Yew seedling",
"weight": "1",
@@ -48543,7 +48543,7 @@
"id": "5368"
},
{
- "examine": "A spirit seedling is growing in this pot. It has been sown and watered.",
+ "examine": "A spirit tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Spirit seedling",
"archery_ticket_price": "0",
@@ -49497,7 +49497,7 @@
"id": "5479"
},
{
- "examine": "An apple tree has been sown (and watered) in this plant pot.",
+ "examine": "An apple tree seed has been sown in this plant pot.",
"durability": null,
"name": "Apple seedling",
"weight": "0.9",
@@ -49505,7 +49505,7 @@
"id": "5480"
},
{
- "examine": "A banana tree seed has been sown and watered in this plant pot.",
+ "examine": "A banana tree seed has been sown in this plant pot.",
"durability": null,
"name": "Banana seedling",
"weight": "0.9",
@@ -49513,14 +49513,14 @@
"id": "5481"
},
{
- "examine": "An orange tree seed has been sown (and watered)in this plant pot.",
+ "examine": "An orange tree seed has been sown in this plant pot.",
"durability": null,
"name": "Orange seedling",
"archery_ticket_price": "0",
"id": "5482"
},
{
- "examine": "A curry seed has been sown and watered in this plant pot.",
+ "examine": "A curry tree seed has been sown in this plant pot.",
"durability": null,
"name": "Curry seedling",
"weight": "0.9",
@@ -49528,7 +49528,7 @@
"id": "5483"
},
{
- "examine": "A pineapple tree has been sown (and watered) in this plant pot.",
+ "examine": "A pineapple plant seed has been sown in this plant pot.",
"durability": null,
"name": "Pineapple seedling",
"weight": "0.9",
@@ -49536,7 +49536,7 @@
"id": "5484"
},
{
- "examine": "This needs watering before it will grow.",
+ "examine": "A papaya tree seed has been sown in this plant pot.",
"durability": null,
"name": "Papaya seedling",
"weight": "0.9",
@@ -49544,7 +49544,7 @@
"id": "5485"
},
{
- "examine": "This sapling is ready to be replanted in a fruit tree patch.",
+ "examine": "A palm tree seed has been sown in this plant pot.",
"durability": null,
"name": "Palm seedling",
"weight": "0.66",
@@ -49552,7 +49552,7 @@
"id": "5486"
},
{
- "examine": "A calquat tree has been sown (and watered) in this plant pot.",
+ "examine": "A calquat tree seed has been sown in this plant pot.",
"durability": null,
"name": "Calquat seedling",
"weight": "0.9",
@@ -49560,7 +49560,7 @@
"id": "5487"
},
{
- "examine": "An apple tree has been sown (and watered) in this plant pot.",
+ "examine": "An apple tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Apple seedling",
"weight": "0.9",
@@ -49576,14 +49576,14 @@
"id": "5489"
},
{
- "examine": "An orange tree seed has been sown (and watered)in this plant pot.",
+ "examine": "An orange tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Orange seedling",
"archery_ticket_price": "0",
"id": "5490"
},
{
- "examine": "A curry seed has been sown and watered in this plant pot.",
+ "examine": "A curry tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Curry seedling",
"weight": "0.9",
@@ -49591,7 +49591,7 @@
"id": "5491"
},
{
- "examine": "A pineapple tree has been sown (and watered) in this plant pot.",
+ "examine": "A pineapple plant seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Pineapple seedling",
"weight": "0.9",
@@ -49599,7 +49599,7 @@
"id": "5492"
},
{
- "examine": "This needs watering before it will grow.",
+ "examine": "A papaya tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Papaya seedling",
"weight": "0.9",
@@ -49607,7 +49607,7 @@
"id": "5493"
},
{
- "examine": "This sapling is ready to be replanted in a fruit tree patch.",
+ "examine": "A palm tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Palm seedling",
"weight": "0.66",
@@ -49615,7 +49615,7 @@
"id": "5494"
},
{
- "examine": "A calquat tree has been sown (and watered) in this plant pot.",
+ "examine": "A calquat tree seed has been sown and watered in this plant pot.",
"durability": null,
"name": "Calquat seedling",
"weight": "0.9",
@@ -51571,9 +51571,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "483",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Iron dagger(p+)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51600,9 +51600,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "350",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Bronze dagger(p+)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51630,9 +51630,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "575",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Steel dagger(p+)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51660,9 +51660,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "538",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Mithril dagger(p+)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51686,9 +51686,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "800",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Adamant dagger(p+)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51783,9 +51783,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "664",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Black dagger(p+)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51831,9 +51831,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "4128",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Iron dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51860,9 +51860,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "5088",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Br'ze dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51890,9 +51890,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "4729",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Steel dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51920,9 +51920,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "3476",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Mithril dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51946,9 +51946,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "4612",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Adamant dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -51976,10 +51976,10 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"lendable": "true",
"grand_exchange_price": "5061",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Rune dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -52043,9 +52043,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "4921",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "Black dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -52751,7 +52751,7 @@
},
{
"ge_buy_limit": "100",
- "examine": "This looks a good deal stronger than normal dwarven stout.",
+ "examine": "This looks a good deal stronger than normal Dwarven Stout.",
"grand_exchange_price": "56400",
"durability": null,
"name": "Dwarven stout(m)",
@@ -53779,7 +53779,7 @@
},
{
"ge_buy_limit": "100",
- "examine": "This looks a good deal stronger than normal dwarven stout.",
+ "examine": "This looks a good deal stronger than normal Dwarven Stout.",
"grand_exchange_price": "44600",
"durability": null,
"name": "Dwarven stout(m1)",
@@ -53798,7 +53798,7 @@
},
{
"ge_buy_limit": "100",
- "examine": "This looks a good deal stronger than normal dwarven stout.",
+ "examine": "This looks a good deal stronger than normal Dwarven Stout.",
"grand_exchange_price": "68900",
"durability": null,
"name": "Dwarven stout(m2)",
@@ -53817,7 +53817,7 @@
},
{
"ge_buy_limit": "100",
- "examine": "This looks a good deal stronger than normal dwarven stout.",
+ "examine": "This looks a good deal stronger than normal Dwarven Stout.",
"grand_exchange_price": "98800",
"durability": null,
"name": "Dwarven stout(m3)",
@@ -53836,7 +53836,7 @@
},
{
"ge_buy_limit": "100",
- "examine": "This looks a good deal stronger than normal dwarven stout.",
+ "examine": "This looks a good deal stronger than normal Dwarven Stout.",
"grand_exchange_price": "237400",
"durability": null,
"name": "Dwarven stout(m4)",
@@ -60136,7 +60136,7 @@
"id": "6578"
},
{
- "examine": "I wonder if I can get this enchanted.",
+ "examine": "It needs a string so I can wear it.",
"grand_exchange_price": "9058124",
"durability": null,
"name": "Onyx amulet",
@@ -60318,9 +60318,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "497",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "White dagger(p)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -60348,9 +60348,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "982",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "White dagger(p+)",
"tradeable": "true",
"archery_ticket_price": "0",
@@ -60378,9 +60378,9 @@
"equip_audio": "2248",
"render_anim": "2584",
"equipment_slot": "3",
+ "attack_anims": "400,400,401,400",
"grand_exchange_price": "8422",
"attack_audios": "2517,2517,2500,2517",
- "attack_anims": "400,400,401,400",
"name": "White dagger(p++)",
"tradeable": "true",
"archery_ticket_price": "0",
diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json
index 0230de40c..fad58089b 100644
--- a/Server/data/configs/npc_configs.json
+++ b/Server/data/configs/npc_configs.json
@@ -44609,7 +44609,9 @@
"strength_level": "1",
"id": "5079",
"range_level": "1",
- "attack_level": "1"
+ "attack_level": "1",
+ "death_animation": "5183",
+ "examine": "Handle with care."
},
{
"examine": "It looks fluffy and cute; it's probably deadly.",
@@ -59144,7 +59146,7 @@
"magic_animation": "7515",
"death_animation": "7461",
"name": "Revenant hellhound",
- "defence_level": "1",
+ "defence_level": "50",
"safespot": null,
"lifepoints": "80",
"strength_level": "50",
@@ -59990,7 +59992,7 @@
"magic_animation": "7515",
"death_animation": "7461",
"name": "Revenant hellhound",
- "defence_level": "1",
+ "defence_level": "50",
"safespot": null,
"lifepoints": "80",
"strength_level": "50",
@@ -76113,6 +76115,7 @@
"id": "2308"
},
{
+ "examine": "In his former life an expert brewer.",
"name": "Metarialus",
"id": "2322"
},
diff --git a/Server/data/configs/npc_spawns.json b/Server/data/configs/npc_spawns.json
index 8e1f93407..2fda3c449 100644
--- a/Server/data/configs/npc_spawns.json
+++ b/Server/data/configs/npc_spawns.json
@@ -5547,6 +5547,10 @@
"npc_id": "2321",
"loc_data": "{2915,10194,1,1,0}-"
},
+ {
+ "npc_id": "2322",
+ "loc_data": "{3679,9957,0,1,1}-"
+ },
{
"npc_id": "2323",
"loc_data": "{3056,3306,0,1,1}-"
diff --git a/Server/data/configs/object_configs.json b/Server/data/configs/object_configs.json
index ae364fd37..1dffc0568 100644
--- a/Server/data/configs/object_configs.json
+++ b/Server/data/configs/object_configs.json
@@ -19168,87 +19168,87 @@
"ids": "13614"
},
{
- "examine": "A gateway to Varrock",
+ "examine": "A gateway to Varrock.",
"ids": "13615"
},
{
- "examine": "A gateway to Lumbridge",
+ "examine": "A gateway to Lumbridge.",
"ids": "13616"
},
{
- "examine": "A gateway to Falador",
+ "examine": "A gateway to Falador.",
"ids": "13617"
},
{
- "examine": "A gateway to Camelot",
+ "examine": "A gateway to Camelot.",
"ids": "13618"
},
{
- "examine": "A gateway to Ardougne",
+ "examine": "A gateway to Ardougne.",
"ids": "13619"
},
{
- "examine": "A gateway to the Yanille watchtower",
+ "examine": "A gateway to the Yanille watchtower.",
"ids": "13620"
},
{
- "examine": "A gateway to Trollheim",
+ "examine": "A gateway to Kharyrll.",
"ids": "13621"
},
{
- "examine": "A gateway to Varrock",
+ "examine": "A gateway to Varrock.",
"ids": "13622"
},
{
- "examine": "A gateway to Lumbridge",
+ "examine": "A gateway to Lumbridge.",
"ids": "13623"
},
{
- "examine": "A gateway to Falador",
+ "examine": "A gateway to Falador.",
"ids": "13624"
},
{
- "examine": "A gateway to Camelot",
+ "examine": "A gateway to Camelot.",
"ids": "13625"
},
{
- "examine": "A gateway to Ardougne",
+ "examine": "A gateway to Ardougne.",
"ids": "13626"
},
{
- "examine": "A gateway to the Yanille watchtower",
+ "examine": "A gateway to the Yanille watchtower.",
"ids": "13627"
},
{
- "examine": "A gateway to Trollheim",
+ "examine": "A gateway to Kharyrll.",
"ids": "13628"
},
{
- "examine": "A gateway to Varrock",
+ "examine": "A gateway to Varrock.",
"ids": "13629"
},
{
- "examine": "A gateway to Lumbridge",
+ "examine": "A gateway to Lumbridge.",
"ids": "13630"
},
{
- "examine": "A gateway to Falador",
+ "examine": "A gateway to Falador.",
"ids": "13631"
},
{
- "examine": "A gateway to Camelot",
+ "examine": "A gateway to Camelot.",
"ids": "13632"
},
{
- "examine": "A gateway to Ardougne",
+ "examine": "A gateway to Ardougne.",
"ids": "13633"
},
{
- "examine": "A gateway to the Yanille watchtower",
+ "examine": "A gateway to the Yanille watchtower.",
"ids": "13634"
},
{
- "examine": "A gateway to Trollheim",
+ "examine": "A gateway to Kharyrll.",
"ids": "13635"
},
{
diff --git a/Server/src/main/content/data/EnchantedJewellery.kt b/Server/src/main/content/data/EnchantedJewellery.kt
index cb94545e5..a0c53ad00 100644
--- a/Server/src/main/content/data/EnchantedJewellery.kt
+++ b/Server/src/main/content/data/EnchantedJewellery.kt
@@ -11,11 +11,13 @@ import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.node.item.Item
import core.game.system.task.Pulse
+import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Items
import core.game.world.GameWorld.Pulser
+import core.tools.Log
import org.rs09.consts.Sounds
import java.util.*
@@ -73,17 +75,17 @@ enum class EnchantedJewellery(
),
AMULET_OF_GLORY(
arrayOf(
- "Edgeville.",
- "Karamja.",
- "Draynor Village.",
- "Al-Kharid.",
- "Nowhere."
+ "Edgeville",
+ "Karamja",
+ "Draynor Village",
+ "Al Kharid",
+ "Nowhere"
),
arrayOf(
Location.create(3087, 3495, 0),
Location.create(2919, 3175, 0),
Location.create(3104, 3249, 0),
- Location.create(3304, 3124, 0)
+ Location.create(3292, 3175, 0)
),
Items.AMULET_OF_GLORY4_1712,
Items.AMULET_OF_GLORY3_1710,
@@ -209,7 +211,7 @@ enum class EnchantedJewellery(
constructor(options: Array, locations: Array, vararg ids: Int) : this(options, locations, false, *ids)
/**
- * Method used when the player "Use"s the jewellery piece.
+ * Method used when the player clicks one of the options in the jewellery piece's options dialog.
* @param player the player.
* @param item the used jewellery item.
* @param buttonID the button id.
@@ -222,7 +224,7 @@ enum class EnchantedJewellery(
}
return
}
- attemptTeleport(player, item, buttonID, isEquipped)
+ attemptTeleport(player, item, buttonID, true, isEquipped)
}
/**
@@ -230,43 +232,69 @@ enum class EnchantedJewellery(
* @param player the player.
* @param item the used jewellery item.
* @param buttonID the button id.
+ * @param replace Whether to attempt replacing the item with its lower-charge version. Always true unless you generated a fake item in code.
* @param isEquipped If the player is operating.
*/
- fun attemptTeleport(player: Player, item: Item, buttonID: Int, isEquipped: Boolean): Boolean {
+ fun attemptTeleport(player: Player, item: Item, buttonID: Int, replace: Boolean, isEquipped: Boolean): Boolean {
val itemIndex = getItemIndex(item)
val nextJewellery = Item(getNext(itemIndex))
if (!canTeleport(player, nextJewellery)) {
return false
}
- Pulser.submit(object : Pulse(0) {
- private var count = 0
- private var location = getLocation(buttonID)
- override fun pulse(): Boolean {
- when (count) {
- 0 -> {
- lock(player,4)
- visualize(player, ANIMATION, GRAPHICS)
- playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
- player.impactHandler.disabledTicks = 4
- closeInterface(player)
+ val location = getLocation(buttonID)
+ player.scripts.delay = GameWorld.ticks + 4
+ queueScript(player, 0, QueueStrength.SOFT) { stage ->
+ when (stage) {
+ 0 -> {
+ lock(player, 4)
+ visualize(player, ANIMATION, GRAPHICS)
+ playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
+ player.impactHandler.disabledTicks = 4
+ closeInterface(player)
+ return@queueScript delayScript(player, 3)
+ }
+ 1 -> {
+ teleport(player, location)
+ resetAnimator(player)
+ unlock(player)
+ player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location))
+ if (!replace) {
+ return@queueScript stopExecuting(player)
}
- 3 -> {
- teleport(player,location)
- resetAnimator(player)
- if (isLastItemIndex(itemIndex)) {
- if (isCrumble) crumbleJewellery(player, item, isEquipped)
- } else {
- replaceJewellery(player, item, nextJewellery, isEquipped)
+ if (isLastItemIndex(itemIndex)) {
+ if (isSlayerRing(item)) {
+ if (isEquipped) {
+ // Remove it now, but only addItemOrDrop the gem after the teleport has procced
+ if (removeItem(player, item, Container.EQUIPMENT)) {
+ return@queueScript delayScript(player, 1)
+ }
+ log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (removeItem from equipment)")
+ }
+ // Not equipped -> can replace fluently
+ if (replaceSlot(player, item.slot, Item(Items.ENCHANTED_GEM_4155), item) == item) {
+ return@queueScript stopExecuting(player)
+ }
+ log(this.javaClass, Log.ERR, "Error replacing slayer ring with enchanted gem (replaceSlot)")
}
- unlock(player)
- player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location))
- return true
+ // Not slayer ring
+ if (isCrumble) {
+ val removeFrom = if (isEquipped) Container.EQUIPMENT else Container.INVENTORY
+ if (removeItem(player, item, removeFrom)) {
+ return@queueScript stopExecuting(player)
+ }
+ log(this.javaClass, Log.ERR, "Error crumbling jewelry")
+ }
+ } else {
+ replaceJewellery(player, item, nextJewellery, isEquipped)
}
}
- count += 1
- return false
+ 2 -> {
+ addItemOrDrop(player, Items.ENCHANTED_GEM_4155)
+ sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.")
+ }
}
- })
+ return@queueScript stopExecuting(player)
+ }
return true
}
@@ -278,21 +306,6 @@ enum class EnchantedJewellery(
}
}
- private fun crumbleJewellery(player: Player, item: Item, isEquipped: Boolean) {
- if (isEquipped) {
- removeItem(player, item, Container.EQUIPMENT)
- } else {
- removeItem(player, item)
- }
- if (isSlayerRing(item)) {
- queueScript(player, 1, QueueStrength.SOFT) {
- addItemOrDrop(player, Items.ENCHANTED_GEM_4155)
- sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.")
- return@queueScript stopExecuting(player)
- }
- }
- }
-
private fun isSlayerRing(item: Item): Boolean {
return (item.id in RING_OF_SLAYING.ids)
}
diff --git a/Server/src/main/content/data/consumables/Consumables.java b/Server/src/main/content/data/consumables/Consumables.java
index e16b6aa23..2d3744679 100644
--- a/Server/src/main/content/data/consumables/Consumables.java
+++ b/Server/src/main/content/data/consumables/Consumables.java
@@ -203,8 +203,8 @@ public enum Consumables {
ASGARNIAN_ALE(new Drink(new int[] {1905, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
ASGARNIAN_ALE_POH(new Drink(new int[] {7744, 7742}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
ASGARNIAN_ALE_KEG(new Drink(new int[] {5785, 5783, 5781, 5779, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
- ASGARNIAN_ALE_M(new Drink(new int[] {5739, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))),
- ASGARNIAN_ALE_M_KEG(new Drink(new int[] {5865, 5863, 5861, 5859, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))),
+ ASGARNIAN_ALE_M(new Drink(new int[] {5739, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
+ ASGARNIAN_ALE_M_KEG(new Drink(new int[] {5865, 5863, 5861, 5859, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
AXEMANS_FOLLY(new Drink(new int[] {5751, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)))),
AXEMANS_FOLLY_KEG(new Drink(new int[] {5825, 5823, 5821, 5819, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)), new Animation(2289))),
AXEMANS_FOLLY_M(new Drink(new int[] {5753, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)))),
@@ -231,24 +231,26 @@ public enum Consumables {
DRAGON_BITTER_M_KEG(new Drink(new int[] {5889, 5887, 5885, 5883, 5769}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))),
DWARVEN_STOUT(new Drink(new int[] {1913, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
DWARVEN_STOUT_KEG(new Drink(new int[] {5777, 5775, 5773, 5771, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
- DWARVEN_STOUT_M(new Drink(new int[] {5747, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)))),
- DWARVEN_STOUT_M_KEG(new Drink(new int[] {5857, 5855, 5853, 5851, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), new Animation(2289))),
+ DWARVEN_STOUT_M(new Drink(new int[] {5747, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
+ DWARVEN_STOUT_M_KEG(new Drink(new int[] {5857, 5855, 5853, 5851, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")),
GREENMANS_ALE(new Drink(new int[] {1909, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))),
GREENMANS_ALE_POH(new Drink(new int[] {7746, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))),
GREENMANS_ALE_KEG(new Drink(new int[] {5793, 5791, 5789, 5787, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)), new Animation(2289))),
GREENMANS_ALE_M(new Drink(new int[] {5743, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
GREENMANS_ALE_M_KEG(new Drink(new int[] {5873, 5871, 5869, 5867, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
GROG(new Drink(new int[] {1915, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))),
- MOONLIGHT_MEAD(new Drink(new int[] {2955, 1919}, new HealingEffect(4), "It tastes like something just died in your mouth.")),
- MOONLIGHT_MEAD_KEG(new Drink(new int[] {5817, 5815, 5813, 5811, 5769}, new HealingEffect(4), new Animation(2289), "It tastes like something just died in your mouth.")),
- MOONLIGHT_MEAD_M(new Drink(new int[] {5749, 1919}, new HealingEffect(6))),
- MOONLIGHT_MEAD_M_KEG(new Drink(new int[] {5897, 5895, 5893, 5891, 5769}, new HealingEffect(6), new Animation(2289))),
+ MOONLIGHT_MEAD(new Drink(new int[] {2955, 1919}, new HealingEffect(5), "It tastes like something just died in your mouth.")),
+ MOONLIGHT_MEAD_KEG(new Drink(new int[] {5817, 5815, 5813, 5811, 5769}, new HealingEffect(5), new Animation(2289), "It tastes like something just died in your mouth.")),
+ MOONLIGHT_MEAD_M(new Drink(new int[] {5749, 1919}, new HealingEffect(4), "It tastes like something just died in your mouth.")),
+ MOONLIGHT_MEAD_M_KEG(new Drink(new int[] {5897, 5895, 5893, 5891, 5769}, new HealingEffect(4), new Animation(2289), "It tastes like something just died in your mouth.")),
SLAYERS_RESPITE(new Drink(new int[] {5759, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
SLAYERS_RESPITE_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
SLAYERS_RESPITE_M(new Drink(new int[] {5761, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
SLAYERS_RESPITE_M_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
WIZARDS_MIND_BOMB(new Drink(new int[] {1907, 1919}, new WizardsMindBombEffect(), "You drink the Wizard's Mind Bomb.", "You feel very strange.")),
- MATURE_WMB(new Drink(new int[] {5741, 1919}, new MatureWmbEffect())),
+ WIZARDS_MIND_BOMB_KEG(new Drink(new int[] {5801, 5799, 5797, 5795, 5769}, new WizardsMindBombEffect(), new Animation(2289), "You drink the Wizard's Mind Bomb.", "You feel very strange.")),
+ MATURE_WMB(new Drink(new int[] {5741, 1919}, new MatureWmbEffect(), "You drink the mature Wizard's Mind Bomb.", "You feel very strange.")),
+ MATURE_WMB_KEG(new Drink(new int[] {5881, 5879, 5877, 5875, 5769}, new MatureWmbEffect(), new Animation(2289), "You drink the mature Wizard's Mind Bomb.", "You feel very strange.")),
/** Cocktails */
FRUIT_BLAST(new Drink(new int[] {2084, 2026}, new HealingEffect(9))),
diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt
index 9432ea009..074ab27a6 100644
--- a/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt
+++ b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt
@@ -49,7 +49,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
"South-west Varrock mine" to Location.create(3176, 3362, 0), // South-west Varrock mine / Champion's Guild mine
"Varrock east bank" to Location.create(3259, 3407, 0), // Varrock east bank / Rune shop
"Lumbridge Swamp south-east mine" to Location.create(3227, 3150, 0), // Lumbridge Swamp south-east mine
- //"Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter)
+ "Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter)
"Canifis Bank" to Location.create(3504, 3487, 0), // Canifis bank
"Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires quest to enter but is currently accessible for Slayer)
"Gnome stronghold Bank" to Location.create(2460, 3432, 0), // Gnome stronghold bank
diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt
index 234c49c61..7368b7689 100644
--- a/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt
+++ b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt
@@ -97,7 +97,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
fun teleportToStar(player: Player) {
val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) {
"canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")}
- //"burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} //disabled: crash
+ "burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)}
"crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)}
"lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)}
"jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)}
@@ -120,7 +120,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ }
2 -> player.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ }
3 -> when (buttonID) {
- 1 -> end().also { teleportToStar(player) }
+ 1 -> teleportToStar(player)
2 -> end()
}
}
diff --git a/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt
index da4ddef6c..c58bf62ed 100644
--- a/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt
+++ b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt
@@ -41,6 +41,7 @@ class EmptyOptionListener : InteractionListener {
BUCKET_OF_COMPOST(Items.COMPOST_6032, Items.BUCKET_1925, "You empty the bucket of compost."),
BUCKET_OF_SUPERCOMPOST(Items.SUPERCOMPOST_6034, Items.BUCKET_1925, "You empty the bucket of supercompost."),
BUCKET_OF_SLIME(Items.BUCKET_OF_SLIME_4286, Items.BUCKET_1925, "You empty the contents of the bucket on the floor.", Sounds.LIQUID_2401),
+ APPLE_MUSH(Items.APPLE_MUSH_5992,Items.BUCKET_1925, "You empty the bucket of apple mush."),
VIAL_OF_WATER(Items.VIAL_OF_WATER_227, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401),
BOWL_OF_WATER(Items.BOWL_OF_WATER_1921, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401),
BOWL_OF_HOT_WATER(Items.BOWL_OF_HOT_WATER_4456, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401),
diff --git a/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt
index 2878628ac..549b69051 100644
--- a/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt
+++ b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt
@@ -50,15 +50,15 @@ class EnchantedJewelleryListener : InteractionListener {
jewellery.use(player, item, 0, isEquipped)
return
}
- openDialogue(player,EnchantedJewelleryDialogueFile(jewellery,item,isEquipped))
+ openDialogue(player,EnchantedJewelleryDialogueFile(jewellery, item, true, isEquipped))
}
}
- class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item, val isEquipped: Boolean) : DialogueFile() {
+ class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item, val replace: Boolean, val isEquipped: Boolean) : DialogueFile() {
override fun handle(componentID: Int, buttonID: Int) {
when (stage) {
START_DIALOGUE -> {
- interpreter!!.sendOptions("Where would you like to go?", *jewellery.options)
+ interpreter!!.sendOptions("Where would you like to teleport to?", *jewellery.options)
stage++
}
1 -> end().also { jewellery.use(player!!, item, buttonID - 1, isEquipped) }
diff --git a/Server/src/main/content/global/handlers/item/withitem/CalquatKeg.kt b/Server/src/main/content/global/handlers/item/withitem/CalquatKeg.kt
new file mode 100644
index 000000000..56b5cb77e
--- /dev/null
+++ b/Server/src/main/content/global/handlers/item/withitem/CalquatKeg.kt
@@ -0,0 +1,19 @@
+package content.global.handlers.item.withitem
+
+import core.api.addItem
+import core.api.animate
+import core.api.removeItem
+import core.game.interaction.InteractionListener
+import org.rs09.consts.Items
+
+class CalquatKeg : InteractionListener{
+ override fun defineListeners() {
+ onUseWith(ITEM, Items.CALQUAT_FRUIT_5980, Items.KNIFE_946) { player, _, _ ->
+ if (removeItem(player, Items.CALQUAT_FRUIT_5980)){
+ animate(player,2290)
+ addItem(player, Items.CALQUAT_KEG_5769)
+ }
+ return@onUseWith true
+ }
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/global/handlers/npc/ChinchompaDeathListener.kt b/Server/src/main/content/global/handlers/npc/ChinchompaDeathListener.kt
new file mode 100644
index 000000000..3a146eaf4
--- /dev/null
+++ b/Server/src/main/content/global/handlers/npc/ChinchompaDeathListener.kt
@@ -0,0 +1,52 @@
+package content.global.handlers.npc
+
+import core.api.*
+import core.api.playGlobalAudio
+import core.api.sendGraphics
+import core.game.node.entity.Entity
+import core.game.node.entity.npc.NPCBehavior
+import org.rs09.consts.NPCs
+import core.game.node.entity.npc.NPC
+import core.game.node.entity.player.Player
+import core.tools.RandomFunction
+import core.game.world.update.flag.context.Graphics
+import core.game.node.entity.combat.ImpactHandler.HitsplatType;
+
+private val chinchompaIDs = intArrayOf(
+ NPCs.CHINCHOMPA_5079,
+ NPCs.CARNIVOROUS_CHINCHOMPA_5080
+)
+
+/**
+ * Minimal evasive approach to the Chinchompas exploding on death cause by combat and not by trapping.
+ */
+class ChinchompaDeathListener: NPCBehavior(*chinchompaIDs) {
+ override fun onDeathFinished(self: NPC, killer: Entity) {
+
+ // If it 'died' from getting trapped an attribute is set of 'hunter'.
+ if (!self.attributes.containsKey("hunter") && killer is Player) {
+ val explosionLoc = self.location
+ val validExplosionDmgTiles = explosionLoc.surroundingTiles
+
+ val chinExplosionGFX = Graphics(157, 96)
+ sendGraphics(chinExplosionGFX, explosionLoc)
+ playGlobalAudio(explosionLoc, 158)
+
+ if (validExplosionDmgTiles.contains(killer.location)) {
+ //As weird this looks, it does allow to have a hit from 0 to 2
+ val hitAmount = RandomFunction.random(0, 3)
+ impact(killer, hitAmount, HitsplatType.NORMAL)
+ }
+ }
+ }
+
+ /**
+ * At content.global.skill.hunter.TrapSetting
+ * sets an attribute of 'hunter' during it's getCatchPulse for reward rolling, but it never cleans it up after.
+ * These NPCs is a member of NPC class although exists a HunterNPC class, but it's mainly used for imps.
+ * Logically you'd do this after death finishes, but it would interfere with the reward rolls and I fear it may affect other hunter NPCs.
+ */
+ override fun onRespawn(self: NPC) {
+ self.removeAttribute("hunter")
+ }
+}
\ No newline at end of file
diff --git a/Server/src/main/content/global/handlers/npc/DecantListener.kt b/Server/src/main/content/global/handlers/npc/DecantListener.kt
index 9a63c78c2..368835e32 100644
--- a/Server/src/main/content/global/handlers/npc/DecantListener.kt
+++ b/Server/src/main/content/global/handlers/npc/DecantListener.kt
@@ -1,6 +1,7 @@
package content.global.handlers.npc
import content.data.consumables.Consumables
+import content.global.skill.cooking.fermenting.CalquatDecant
import core.api.*
import core.game.consumable.Potion
import core.game.dialogue.DialogueFile
@@ -14,23 +15,39 @@ class DecantListener : InteractionListener {
companion object {
val potions = Consumables.potions.toIntArray()
+ val decantables = potions + CalquatDecant.allKegIds
}
override fun defineListeners() {
on(IntType.NPC,"decant"){ player, node ->
- val (toRemove, toAdd) = decantContainer(player.inventory)
- for (item in toRemove)
- removeItem(player, item)
- for (item in toAdd)
+ // Decant potions
+ val (potionRemove, potionAdd) = decantContainer(player.inventory)
+ for (item in potionRemove)
+ if (!removeItem(player, item)) { return@on false }
+ for (item in potionAdd)
addItem(player, item.id, item.amount)
+
+ // Decant kegs
+ val (kegRemove, kegAdd) = CalquatDecant.decantCalquat(player.inventory)
+ for (item in kegRemove)
+ if (!removeItem(player, item)) { return@on false }
+ for (item in kegAdd)
+ addItem(player, item.id, item.amount)
+
player.dialogueInterpreter.open(DecantingDialogue(),node.asNpc())
return@on true
}
- onUseWith(IntType.ITEM, potions, *potions) { player, used, with ->
+ onUseWith(IntType.ITEM, decantables, *decantables) { player, used, with ->
if (used !is Item) return@onUseWith false
if (with !is Item) return@onUseWith false
+ // Check if these are kegs - handle with CalquatDecant
+ if (CalquatDecant.isKeg(used.id) || CalquatDecant.isKeg(with.id)) {
+ return@onUseWith CalquatDecant.combineKegs(player, used, with)
+ }
+
+ // Otherwise handle as potions
// Verify these are both the same potion types
val potionUsed = Consumables.getConsumableById(used.id)?.consumable as? Potion ?: return@onUseWith false
val potionWith = Consumables.getConsumableById(with.id)?.consumable as? Potion ?: return@onUseWith false
@@ -83,6 +100,57 @@ class DecantListener : InteractionListener {
return@onUseWith true
}
+
+ // Decant keg into beer glass
+ onUseWith(IntType.ITEM, Items.BEER_GLASS_1919, *CalquatDecant.allKegIds) { player, used, with ->
+ if (used !is Item || with !is Item) return@onUseWith false
+
+ // Determine which is the glass and which is the keg
+ val (glass, keg) = if (used.id == Items.BEER_GLASS_1919) {
+ used to with
+ } else {
+ with to used
+ }
+
+ return@onUseWith CalquatDecant.pourIntoGlass(player, glass, keg)
+ }
+
+ // Barbarian decanting: use a 4-dose potion and an empty vial together to make two 2-dose potions
+ onUseWith(IntType.ITEM, potions, Items.VIAL_229) { player, used, with ->
+ // Check if player has started barbarian herblore training
+ if (getAttribute(player, "/save:barbtraining:herblore", 0) == 0) {
+ return@onUseWith false
+ }
+
+ if (used !is Item) return@onUseWith false
+ if (with !is Item) return@onUseWith false
+
+ // Determine which item is the potion and which is the vial
+ val (potionItem) = if (used.id == Items.VIAL_229) {
+ Pair(with, used)
+ } else {
+ Pair(used, with)
+ }
+
+ // Check if the potion is 4 doses
+ val potion = Consumables.getConsumableById(potionItem.id)?.consumable as? Potion ?: return@onUseWith false
+ val dose = potion.getDose(potionItem)
+
+ if (dose != 4) {
+ return@onUseWith false
+ }
+
+ // Get the 2-dose version of this potion by index
+ val twoDoseId = potion.ids[2]
+
+ // Replace ingredients with products
+ replaceSlot(player, with.slot, Item(twoDoseId))
+ replaceSlot(player, used.slot, Item(twoDoseId))
+
+ playAudio(player, 2401)
+
+ return@onUseWith true
+ }
}
internal class DecantingDialogue : DialogueFile(){
diff --git a/Server/src/main/content/global/skill/construction/BuildingUtils.java b/Server/src/main/content/global/skill/construction/BuildingUtils.java
index 02bfbd9c2..2ee636337 100644
--- a/Server/src/main/content/global/skill/construction/BuildingUtils.java
+++ b/Server/src/main/content/global/skill/construction/BuildingUtils.java
@@ -90,8 +90,6 @@ public final class BuildingUtils {
for (int menuIndex = 0; menuIndex < 7; menuIndex++) {
int itemsStringOffset = 97 + (menuIndex * 5);
-
- //97 +
if (menuIndex >= hotspot.getDecorations().length || (hotspot.getDecorations()[menuIndex] != null && hotspot.getDecorations()[menuIndex].isInvisibleNode())) {
for (int j = 0; j < 5; j++) {
player.getPacketDispatch().sendString("", 396, itemsStringOffset + j);
@@ -104,43 +102,24 @@ public final class BuildingUtils {
Decoration decoration = hotspot.getDecorations()[menuIndex];
items[BUILD_INDEXES[menuIndex]] = new Item(decoration.getInterfaceItem());
player.getPacketDispatch().sendString(ItemDefinition.forId(decoration.getInterfaceItem()).getName(), 396, itemsStringOffset);
- boolean hasRequirements = player.getSkills().getLevel(Skills.CONSTRUCTION) >= decoration.getLevel();
+ boolean hasRequirements = player.getSkills().getLevel(Skills.CONSTRUCTION) >= decoration.getLevel(); //nails are checked in buildDecoration
+ Item[] reqItems = decoration.getItems();
+ String[] reqsText = decoration.getReqsText();
for (int j = 0; j < 4; j++) {
- if (j >= decoration.getItems().length) {
- if (j == decoration.getItems().length && decoration.getNailAmount() > 0) {
- player.getPacketDispatch().sendString("Nails: " + decoration.getNailAmount(), 396, (itemsStringOffset + 1) + j);
- } else {
- player.getPacketDispatch().sendString("", 396, (itemsStringOffset + 1) + j);
- }
- } else {
- Item item = decoration.getItems()[j];
- if (!player.getInventory().containsItem(item)) {
- hasRequirements = false;
- }
- String s = item.getName() + ": " + item.getAmount();
- /*if (j > 1 && (decoration == Decoration.RUNE_CASE1 || decoration == Decoration.RUNE_CASE2)) {
- if (j == 3) {
- offset--;
- item = decoration.getItems()[++j];
- s = item.getName() + ": " + item.getAmount();
- }
- item = decoration.getItems()[j + 1];
- s += ", " + item.getName() + ": " + item.getAmount();
- player.getPacketDispatch().sendString(s, 396, 15 + offset + j);
- continue;
- }*/
- player.getPacketDispatch().sendString(s, 396, (itemsStringOffset + 1) + j);
+ if (j < reqItems.length && !player.getInventory().containsItem(reqItems[j])) {
+ hasRequirements = false;
}
+ player.getPacketDispatch().sendString(reqsText[j], 396, (itemsStringOffset + 1) + j);
}
if (hasRequirements) {
c261Value += (1 << (menuIndex + 1));
}
- setVarp(player, 1485 + menuIndex, hasRequirements || player.isStaff() ? 1 : 0);
+ setVarp(player, 1485 + menuIndex, hasRequirements || player.isStaff() ? 1 : 0);
player.getPacketDispatch().sendString("Level " + decoration.getLevel(), 396, 140 + menuIndex);
//player.getPacketDispatch().sendItemZoomOnInterface(items[i].protocol(), 50000, 396, 49 + i);
}
- setVarp(player, 261, c261Value);
+ setVarp(player, 261, c261Value);
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 396, 132, 8, items, false));
}
diff --git a/Server/src/main/content/global/skill/construction/Decoration.java b/Server/src/main/content/global/skill/construction/Decoration.java
index 6229dff82..4191cb1a9 100644
--- a/Server/src/main/content/global/skill/construction/Decoration.java
+++ b/Server/src/main/content/global/skill/construction/Decoration.java
@@ -454,7 +454,7 @@ public enum Decoration {
* Quest hall decorations.
*/
ANTIDRAGON_SHIELD(13522, 8282, 47, 280, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ANTI_DRAGON_SHIELD_1540) }, new Item[] { new Item(Items.ANTI_DRAGON_SHIELD_1540) }),
- AMULET_OF_GLORY (13523, 8283, 47, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.AMULET_OF_GLORY_1704) }, new Item[] { new Item(Items.AMULET_OF_GLORY_1704) }),
+ AMULET_OF_GLORY (13523, 8283, 47, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.AMULET_OF_GLORY_1704) }, new Item[] { new Item(Items.AMULET_OF_GLORY_1704) }, new String[] { "Teak plank: 3", "Amulet of Glory", "(uncharged): 1" }),
CAPE_OF_LEGENDS (13524, 8284, 47, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.CAPE_OF_LEGENDS_1052) }, new Item[] { new Item(Items.CAPE_OF_LEGENDS_1052) }),
KING_ARTHUR (13510, 8285, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ARTHUR_PORTRAIT_7995) }),
ELENA (13511, 8286, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ELENA_PORTRAIT_7996) }),
@@ -727,23 +727,42 @@ public enum Decoration {
private final int[] objectIds;
/**
- * If this node should be invisible to user build options
+ * If this node should be invisible to user build options.
*/
private boolean invisibleNode;
/**
- * Constructs a new object, no items, no tools, no refund items.
+ * The requirements text to show for this node.
+ */
+ private String[] reqsText = {"", "", "", ""};
+
+ private String[] generateDefaultReqsText(Item[] items, int nailAmount) {
+ String[] ret = {"", "", "", ""};
+ for (int i = 0; i < 4; i++) {
+ if (i >= items.length) {
+ if (i == items.length && nailAmount > 0) {
+ ret[i] = "Nails: " + nailAmount;
+ }
+ } else {
+ ret[i] = items[i].getName() + ": " + items[i].getAmount();
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * Constructs a new object, default items, default tools, default refund items, default requirements text.
* @param objectId The object id.
* @param interfaceItem The item id for the building interface.
* @param level The level required.
* @param experience The experience gained.
*/
Decoration(int objectId, int interfaceItem, int level, int experience) {
- this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, new Item[] {}, new Item[] {});
+ this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, new Item[] {}, new Item[] {}, new String[] {});
}
/**
- * Constructs a new object, no tools, no refund items.
+ * Constructs a new object, default tools, default refund items, default requirements text.
* @param objectId The object id.
* @param interfaceItem The item id for the building interface.
* @param level The level required.
@@ -751,11 +770,12 @@ public enum Decoration {
* @param items The items required.
*/
Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items) {
- this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {});
+ this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}, new String[] {});
+ this.reqsText = generateDefaultReqsText(items, getNailAmount());
}
/**
- * Constructs a new object, no refund items.
+ * Constructs a new object, default refund items, default requirements text.
* @param objectId The object id.
* @param interfaceItem The item id for the building interface.
* @param level The level required.
@@ -764,7 +784,8 @@ public enum Decoration {
* @param items The items required.
*/
Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items) {
- this(objectId, interfaceItem, level, experience, tools, items, new Item[] {});
+ this(objectId, interfaceItem, level, experience, tools, items, new Item[] {}, new String[] {});
+ this.reqsText = generateDefaultReqsText(items, getNailAmount());
}
/**
@@ -777,7 +798,21 @@ public enum Decoration {
* @param refundItems The items to be refunded when the item is removed.
*/
Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, Item[] refundItems) {
- this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems);
+ this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems, new String[] {});
+ this.reqsText = generateDefaultReqsText(items, getNailAmount());
+ }
+
+ /**
+ * Constructs a new object, default tools.
+ * @param objectId The object id.
+ * @param interfaceItem The item id for the building interface.
+ * @param level The level required.
+ * @param experience The experience gained.
+ * @param items The items required.
+ * @param refundItems The items to be refunded when the item is removed.
+ */
+ Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, Item[] refundItems, String[] reqsText) {
+ this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems, reqsText);
}
/**
@@ -789,8 +824,9 @@ public enum Decoration {
* @param tools The tools needed.
* @param items The items required.
* @param refundItems The items to be refunded when the item is removed.
+ * @param reqsText The requirements text to be shown in the interface.
*/
- Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems) {
+ Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems, String[] reqsText) {
this.objectId = objectId;
this.objectIds = null;
this.interfaceItem = interfaceItem;
@@ -799,6 +835,9 @@ public enum Decoration {
this.tools = tools;
this.items = items;
this.refundItems = refundItems;
+ if (reqsText.length > 0) {
+ System.arraycopy(reqsText, 0, this.reqsText, 0, reqsText.length);
+ }
}
/**
@@ -822,18 +861,6 @@ public enum Decoration {
Decoration(int[] objectIds, int interfaceItem, int level, int experience, Item[] items) {
this(objectIds, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {});
}
- /**
- * Constructs a new object no refund items.
- * @param objectIds The object id.
- * @param interfaceItem The item id for the building interface.
- * @param level The level required.
- * @param experience The experience gained.
- * @param tools The tools needed.
- * @param items The items required.
- */
- Decoration(int[] objectIds, int interfaceItem, int level, int experience, int[] tools, Item[] items) {
- this(objectIds, interfaceItem, level, experience, tools, items, new Item[] {});
- }
/**
* Constructs a new object.
@@ -1000,4 +1027,12 @@ public enum Decoration {
public boolean isInvisibleNode() {
return invisibleNode;
}
+
+ /**
+ * Gets the requirements text.
+ * @return The requirements text.
+ */
+ public String[] getReqsText() {
+ return reqsText;
+ }
}
diff --git a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java
index bf1f26c54..c154bef68 100644
--- a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java
+++ b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java
@@ -1,6 +1,7 @@
package content.global.skill.construction.decoration.portalchamber;
+import content.data.Quests;
import content.global.skill.construction.Hotspot;
import content.global.skill.runecrafting.Rune;
import core.cache.def.impl.SceneryDefinition;
@@ -18,6 +19,7 @@ import core.plugin.Plugin;
import core.plugin.ClassScanner;
import static content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE;
+import static core.api.ContentAPIKt.*;
/**
* PortalChamberPlugin
@@ -89,15 +91,14 @@ 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;
- }
+ if ((l == Locations.ARDOUGNE && !getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)) ||
+ (l == Locations.KHARYRLL && !isQuestComplete(player, Quests.DESERT_TREASURE))) {
+ sendMessage(player, "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");
+ sendMessage(player, "You do not have the required runes to build this portal.");
return;
}
player.getInventory().remove(runes);
diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt
index 47051e46f..b5196af4d 100644
--- a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt
+++ b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt
@@ -1,53 +1,53 @@
package content.global.skill.construction.decoration.questhall
+import content.data.EnchantedJewellery
+import content.global.handlers.item.EnchantedJewelleryListener.EnchantedJewelleryDialogueFile
+import core.api.delayScript
+import core.api.lock
+import core.api.openDialogue
import core.api.playGlobalAudio
+import core.api.queueScript
+import core.api.resetAnimator
+import core.api.stopExecuting
import core.api.teleport
+import core.api.visualize
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
+import core.game.interaction.QueueStrength
import core.game.node.Node
import core.game.node.entity.player.Player
import core.game.node.item.Item
import core.game.node.scenery.Scenery
-import core.game.system.task.Pulse
-import core.game.world.map.Location
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Items
import org.rs09.consts.Sounds
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
class MountedGlory : InteractionListener {
-
val MOUNTED_GLORY = 13523
-
- val TELEPORTS = arrayOf(
- Location.create(3087, 3495, 0),
- Location.create(2919, 3175, 0),
- Location.create(3104, 3249, 0),
- Location.create(3304, 3124, 0)
- )
+ val TELEPORTS = EnchantedJewellery.AMULET_OF_GLORY.locations
override fun defineListeners() {
on(MOUNTED_GLORY, IntType.SCENERY, "Edgeville") { player, `object` ->
mountedGloryAction(player, `object`, 0)
return@on true
}
-
on(MOUNTED_GLORY, IntType.SCENERY, "Karamja") { player, `object` ->
mountedGloryAction(player, `object`, 1)
return@on true
}
-
on(MOUNTED_GLORY, IntType.SCENERY, "Draynor Village") { player, `object` ->
mountedGloryAction(player, `object`, 2)
return@on true
}
-
on(MOUNTED_GLORY, IntType.SCENERY, "Al Kharid") { player, `object` ->
mountedGloryAction(player, `object`, 3)
return@on true
}
+ on(MOUNTED_GLORY, IntType.SCENERY, "Rub") { player, _ ->
+ openDialogue(player,EnchantedJewelleryDialogueFile(EnchantedJewellery.AMULET_OF_GLORY, Item(Items.AMULET_OF_GLORY4_1712), false, false))
+ return@on true
+ }
}
private fun mountedGloryAction(player : Player, `object` : Node, int : Int) {
if (player.houseManager.isBuildingMode) {
@@ -57,21 +57,16 @@ class MountedGlory : InteractionListener {
if (!player.zoneMonitor.teleport(1, Item(Items.AMULET_OF_GLORY_1704))) {
return
}
- Executors.newSingleThreadScheduledExecutor().schedule({
- player.pulseManager.run(object : Pulse() {
- var counter = 0
- override fun pulse(): Boolean {
- when (counter++) {
- 1 -> {
- player.lock(5)
- player.visualize(Animation(714), Graphics(308, 100, 50))
- playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
- }
- 4 -> player.animator.reset().also { teleport(player, TELEPORTS[int]) }
- }
- return false
+ queueScript(player, 0, QueueStrength.SOFT) { stage ->
+ if (stage == 0) {
+ lock(player, 4)
+ visualize(player, Animation(714), Graphics(308, 100, 50))
+ playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200)
+ return@queueScript delayScript(player, 3)
}
- })
- }, 0, TimeUnit.SECONDS)
+ resetAnimator(player)
+ teleport(player, TELEPORTS[int])
+ return@queueScript stopExecuting(player)
+ }
}
}
diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java
deleted file mode 100644
index 90d96eb80..000000000
--- a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package content.global.skill.construction.decoration.questhall;
-
-
-import core.cache.def.impl.SceneryDefinition;
-import core.game.dialogue.DialogueAction;
-import core.game.dialogue.DialogueInterpreter;
-import core.game.interaction.OptionHandler;
-import core.game.node.Node;
-import core.game.node.entity.player.Player;
-import core.game.system.task.Pulse;
-import core.game.world.GameWorld;
-import core.game.world.map.Location;
-import core.game.world.update.flag.context.Animation;
-import core.game.world.update.flag.context.Graphics;
-import core.plugin.Initializable;
-import core.plugin.Plugin;
-import org.rs09.consts.Sounds;
-
-import static core.api.ContentAPIKt.playGlobalAudio;
-
-/**
- * Handles the POH Mounted Glory.
- * @author Splinter
- */
-@Initializable
-public class MountedGloryPlugin extends OptionHandler {
-
- /**
- * Represents the teleport animation.
- */
- private static final Animation ANIMATION = new Animation(714);
-
- /**
- * Represents the graphics to use.
- */
- private static final Graphics GRAPHICS = new Graphics(308, 100, 50);
-
- @Override
- public Plugin