mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-23 03:15:10 -06:00
Merge branch 2009scape:master into master
This commit is contained in:
commit
17a31969ac
283 changed files with 10362 additions and 9282 deletions
0
.gitlab/.gitkeep
Normal file
0
.gitlab/.gitkeep
Normal file
0
.gitlab/issue_templates/.gitkeep
Normal file
0
.gitlab/issue_templates/.gitkeep
Normal file
17
.gitlab/issue_templates/Default.md
Normal file
17
.gitlab/issue_templates/Default.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
What I did:
|
||||
|
||||
What I expected to happen:
|
||||
|
||||
What actually happened:
|
||||
|
||||
IDs of related NPCs/items:
|
||||
|
||||
2009-era source (if relevant):
|
||||
|
||||
Screenshots or video:
|
||||
|
||||
LIVE SERVER username affected by this issue:
|
||||
|
||||
**Bug reports are not accepted by SP users. SP is often out of date and results in invalid bug reports.**
|
||||
|
||||
**If the bug is exploitable make sure you tick the confidential checkbox below**
|
||||
|
|
@ -8021,16 +8021,9 @@
|
|||
}
|
||||
],
|
||||
"charm": [],
|
||||
"ids": "128,1479,1875,4343",
|
||||
"ids": "128,1479,1875",
|
||||
"description": "",
|
||||
"main": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "25.0",
|
||||
"id": "7862",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
]
|
||||
"main": []
|
||||
},
|
||||
{
|
||||
"default": [
|
||||
|
|
@ -36458,12 +36451,6 @@
|
|||
"weight": "100.0",
|
||||
"id": "532",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "3",
|
||||
"weight": "100.0",
|
||||
"id": "526",
|
||||
"maxAmount": "3"
|
||||
}
|
||||
],
|
||||
"charm": [],
|
||||
|
|
@ -58779,5 +58766,25 @@
|
|||
"ids": "8127",
|
||||
"description": "Dark energy core",
|
||||
"main": []
|
||||
},
|
||||
{
|
||||
"default": [
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "6287",
|
||||
"maxAmount": "1"
|
||||
},
|
||||
{
|
||||
"minAmount": "1",
|
||||
"weight": "1.0",
|
||||
"id": "526",
|
||||
"maxAmount": "1"
|
||||
}
|
||||
],
|
||||
"charm": [],
|
||||
"ids": "4343",
|
||||
"description": "",
|
||||
"main": []
|
||||
}
|
||||
]
|
||||
|
|
@ -207,6 +207,10 @@
|
|||
"item_id": "590",
|
||||
"loc_data": "{1,2368,3135,0,140}-{1,2431,3072,0,140}-{1,3112,3369,2,140}-{1,3209,3734,0,100}-"
|
||||
},
|
||||
{
|
||||
"item_id": "600",
|
||||
"loc_data": "{1,2438,3187,0,200}-"
|
||||
},
|
||||
{
|
||||
"item_id": "677",
|
||||
"loc_data": "{1,3369,3378,0,150}-"
|
||||
|
|
@ -233,7 +237,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,2700,3407,0,100}-{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,2700,3407,0,100}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,2653,9767,0,30}-{1,3218,9887,0,33}-"
|
||||
},
|
||||
{
|
||||
"item_id": "952",
|
||||
|
|
@ -417,11 +421,11 @@
|
|||
},
|
||||
{
|
||||
"item_id": "1812",
|
||||
"loc_data": "{1,2747,3579,0,100}"
|
||||
"loc_data": "{1,2747,3579,0,100}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1813",
|
||||
"loc_data": "{1,2746,3578,0,100}"
|
||||
"loc_data": "{1,2746,3578,0,100}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1856",
|
||||
|
|
@ -671,6 +675,10 @@
|
|||
"item_id": "11065",
|
||||
"loc_data": "{1,2928,3289,0,90}-"
|
||||
},
|
||||
{
|
||||
"item_id": "11656",
|
||||
"loc_data": "{1,2438,3185,0,200}-"
|
||||
},
|
||||
{
|
||||
"item_id": "12494",
|
||||
"loc_data": "{1,2762,2973,0,60}-"
|
||||
|
|
|
|||
|
|
@ -5575,7 +5575,7 @@
|
|||
"id": "601"
|
||||
},
|
||||
{
|
||||
"destroy_message": "You'll have to get another down in the Dungeon",
|
||||
"destroy_message": "You'll have to get another down in the dungeon.",
|
||||
"examine": "An unusual clay mould in the shape of a disc.",
|
||||
"durability": null,
|
||||
"name": "Lens mould",
|
||||
|
|
@ -39175,7 +39175,7 @@
|
|||
"id": "4237"
|
||||
},
|
||||
{
|
||||
"examine": "It's a bowl of (milky) nettle tea.",
|
||||
"examine": "It's a bowl of nettle tea.",
|
||||
"durability": null,
|
||||
"name": "Nettle tea",
|
||||
"weight": "0.9",
|
||||
|
|
@ -39183,7 +39183,7 @@
|
|||
"id": "4239"
|
||||
},
|
||||
{
|
||||
"examine": "It's a bowl of (milky) nettle tea.",
|
||||
"examine": "It's a bowl of milky nettle tea.",
|
||||
"durability": null,
|
||||
"name": "Nettle tea",
|
||||
"weight": "0.9",
|
||||
|
|
@ -39191,7 +39191,7 @@
|
|||
"id": "4240"
|
||||
},
|
||||
{
|
||||
"examine": "(In inventory) A handful of nettles (In ground) I better not get stung/I wouldn't like to get stung/I wish I could sting other people/Dock leaves at the ready/These may hurt/nettles sting my leggies(Draynor Village nettles)",
|
||||
"examine": "A handful of nettles.",
|
||||
"durability": null,
|
||||
"name": "Nettles",
|
||||
"archery_ticket_price": "0",
|
||||
|
|
@ -39199,22 +39199,22 @@
|
|||
},
|
||||
{
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "A nice cup of nettle tea.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "4242"
|
||||
},
|
||||
{
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "A milky cup of nettle tea.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "4243"
|
||||
|
|
@ -39228,22 +39228,22 @@
|
|||
},
|
||||
{
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "Some nettle tea in a porcelain cup.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "4245"
|
||||
},
|
||||
{
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "Some milky nettle tea in a porcelain cup.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "4246"
|
||||
|
|
@ -70083,517 +70083,584 @@
|
|||
"id": "7687"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "The kettle is empty.",
|
||||
"durability": null,
|
||||
"name": "Kettle",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7688"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Kettle",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7689"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "It's full of cold water.",
|
||||
"durability": null,
|
||||
"name": "Full kettle",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7690"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "It's full of boiling water.",
|
||||
"durability": null,
|
||||
"name": "Hot kettle",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7691"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (4)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7692"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (4)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7693"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (3)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7694"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (3)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7695"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (2)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7696"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (2)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7697"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (1)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7698"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (1)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7699"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "Add boiling water to make a tea.",
|
||||
"durability": null,
|
||||
"name": "Teapot with leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7700"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Teapot with leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7701"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "This teapot is empty.",
|
||||
"durability": null,
|
||||
"name": "Teapot",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.4",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7702"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Teapot",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7703"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (4)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7704"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (4)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7705"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (3)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7706"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (3)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7707"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (2)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7708"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (2)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7709"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (1)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7710"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (1)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7711"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "Add boiling water to make a tea.",
|
||||
"durability": null,
|
||||
"name": "Teapot with leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7712"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Teapot with leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7713"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "This teapot is empty.",
|
||||
"durability": null,
|
||||
"name": "Teapot",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.4",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7714"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Teapot",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7715"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (4)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7716"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (4)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7717"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (3)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7718"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (3)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7719"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (2)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7720"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (2)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7721"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "I'd really like a nice cup of tea.",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (1)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7722"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Pot of tea (1)",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7723"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "Add boiling water to make a tea.",
|
||||
"durability": null,
|
||||
"name": "Teapot with leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1.5",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7724"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Teapot with leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7725"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "This teapot is empty.",
|
||||
"durability": null,
|
||||
"name": "Teapot",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.4",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7726"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Teapot",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7727"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "1",
|
||||
"examine": "An empty cup.",
|
||||
"grand_exchange_price": "7",
|
||||
"durability": null,
|
||||
"name": "Empty cup",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7728"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Empty cup",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7729"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "A nice cup of nettle tea.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7730"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "A milky cup of nettle tea.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7731"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "A porcelain cup.",
|
||||
"durability": null,
|
||||
"name": "Porcelain cup",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7732"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "Some nettle tea in a porcelain cup.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7733"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "Some milky nettle tea in a porcelain cup.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7734"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "A porcelain cup.",
|
||||
"durability": null,
|
||||
"name": "Porcelain cup",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7735"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "Some nettle tea in a porcelain cup.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7736"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "10",
|
||||
"examine": "A nice cup of tea.",
|
||||
"examine": "Some milky nettle tea in a porcelain cup.",
|
||||
"grand_exchange_price": "30",
|
||||
"durability": null,
|
||||
"name": "Cup of tea",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7737"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "Mmm, how about a nice cup of tea?",
|
||||
"durability": null,
|
||||
"name": "Tea leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7738"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Tea leaves",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7739"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "A glass of frothy ale.",
|
||||
"grand_exchange_price": "151",
|
||||
"durability": null,
|
||||
"name": "Beer",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7740"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Beer",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7741"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "1",
|
||||
"examine": "I need to fill this with beer.",
|
||||
"grand_exchange_price": "25",
|
||||
"durability": null,
|
||||
"name": "Beer glass",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "0.05",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7742"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Beer glass",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7743"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "3",
|
||||
"examine": "Probably the finest readily-available ale in Asgarnia.",
|
||||
"grand_exchange_price": "131",
|
||||
"durability": null,
|
||||
"name": "Asgarnian ale",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7744"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Asgarnian ale",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7745"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "2",
|
||||
"examine": "A glass of frothy ale.",
|
||||
"grand_exchange_price": "569",
|
||||
"durability": null,
|
||||
"name": "Greenman's ale",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7746"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Greenman's ale",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7747"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "2",
|
||||
"examine": "A glass of bitter.",
|
||||
"grand_exchange_price": "523",
|
||||
"durability": null,
|
||||
"name": "Dragon bitter",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7748"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Dragon bitter",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7749"
|
||||
},
|
||||
|
|
@ -70615,36 +70682,40 @@
|
|||
"id": "7751"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"shop_price": "2",
|
||||
"examine": "A glass of Cider",
|
||||
"grand_exchange_price": "1539",
|
||||
"durability": null,
|
||||
"name": "Cider",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"weight": "1",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7752"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Cider",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7753"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"examine": "A fruity, full-bodied ale.",
|
||||
"grand_exchange_price": "2371",
|
||||
"durability": null,
|
||||
"name": "Chef's delight",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7754"
|
||||
},
|
||||
{
|
||||
"bankable": "false",
|
||||
"durability": null,
|
||||
"name": "Chef's delight",
|
||||
"tradeable": "true",
|
||||
"tradeable": "false",
|
||||
"archery_ticket_price": "0",
|
||||
"id": "7755"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1175,7 +1175,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "A barely visible deadly jungle spider.",
|
||||
"examine": "A barely visible deadly spider.",
|
||||
"melee_animation": "5327",
|
||||
"range_animation": "5327",
|
||||
"combat_audio": "537,539,538",
|
||||
|
|
@ -2949,7 +2949,7 @@
|
|||
"attack_level": "30"
|
||||
},
|
||||
{
|
||||
"examine": "One of Gielinor's many citizens",
|
||||
"examine": "One of Gielinor's many citizens.",
|
||||
"melee_animation": "422",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "511,513,512",
|
||||
|
|
@ -3177,6 +3177,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "This one's had too much to drink!",
|
||||
"melee_animation": "422",
|
||||
"combat_audio": "703,705,704",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -6227,6 +6228,22 @@
|
|||
"range_level": "1",
|
||||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "A man, learned in the ways of the stars.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"defence_animation": "0",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "0",
|
||||
"name": "Observatory professor",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
"lifepoints": "10",
|
||||
"strength_level": "1",
|
||||
"id": "488",
|
||||
"range_level": "1",
|
||||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "He doesn't look like he'd trust his own mother.",
|
||||
"melee_animation": "6199",
|
||||
|
|
@ -6237,13 +6254,13 @@
|
|||
"magic_animation": "0",
|
||||
"death_animation": "6190",
|
||||
"name": "Goblin guard",
|
||||
"defence_level": "20",
|
||||
"defence_level": "37",
|
||||
"safespot": null,
|
||||
"lifepoints": "28",
|
||||
"strength_level": "20",
|
||||
"lifepoints": "43",
|
||||
"strength_level": "37",
|
||||
"id": "489",
|
||||
"range_level": "1",
|
||||
"attack_level": "20"
|
||||
"attack_level": "32"
|
||||
},
|
||||
{
|
||||
"examine": "If the mummy is at school",
|
||||
|
|
@ -8565,7 +8582,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "Smartly dressed",
|
||||
"examine": "Smartly dressed, and ready to deliver food.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"defence_animation": "0",
|
||||
|
|
@ -9414,7 +9431,7 @@
|
|||
"attack_level": "15"
|
||||
},
|
||||
{
|
||||
"examine": "Children are just like real people...just smaller.",
|
||||
"examine": "A sad looking child.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"defence_animation": "0",
|
||||
|
|
@ -10518,13 +10535,13 @@
|
|||
"death_animation": "5329",
|
||||
"name": "Poison spider",
|
||||
"safespot": null,
|
||||
"defence_level": "52",
|
||||
"lifepoints": "64",
|
||||
"strength_level": "65",
|
||||
"defence_level": "28",
|
||||
"lifepoints": "25",
|
||||
"strength_level": "28",
|
||||
"id": "1009",
|
||||
"aggressive": "true",
|
||||
"range_level": "1",
|
||||
"attack_level": "50"
|
||||
"attack_level": "28"
|
||||
},
|
||||
{
|
||||
"examine": "A green skinned croaker",
|
||||
|
|
@ -16891,7 +16908,7 @@
|
|||
"lifepoints": "120",
|
||||
"strength_level": "45",
|
||||
"id": "1618",
|
||||
"aggressive": "true",
|
||||
"aggressive": "false",
|
||||
"clue_level": "2",
|
||||
"range_level": "1",
|
||||
"attack_level": "75"
|
||||
|
|
@ -25079,42 +25096,52 @@
|
|||
"melee_animation": "275",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "3609,3608,3610",
|
||||
"attack_speed": "7",
|
||||
"poisonous": "true",
|
||||
"magic_level": "1",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"defence_animation": "276",
|
||||
"weakness": "1",
|
||||
"poison_amount": "55",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "278",
|
||||
"name": "Bush snake",
|
||||
"defence_level": "61",
|
||||
"defence_level": "50",
|
||||
"safespot": null,
|
||||
"lifepoints": "87",
|
||||
"strength_level": "1",
|
||||
"lifepoints": "25",
|
||||
"strength_level": "25",
|
||||
"id": "2489",
|
||||
"aggressive": "true",
|
||||
"range_level": "61",
|
||||
"attack_level": "1"
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "1",
|
||||
"attack_level": "25"
|
||||
},
|
||||
{
|
||||
"examine": "A slithering serpent that likes to hide in the bush.",
|
||||
"melee_animation": "275",
|
||||
"combat_audio": "3609,3608,3610",
|
||||
"range_animation": "0",
|
||||
"attack_speed": "7",
|
||||
"poisonous": "true",
|
||||
"magic_level": "1",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "276",
|
||||
"poison_amount": "55",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "278",
|
||||
"name": "Bush snake",
|
||||
"defence_level": "1",
|
||||
"defence_level": "50",
|
||||
"safespot": null,
|
||||
"lifepoints": "25",
|
||||
"strength_level": "1",
|
||||
"strength_level": "25",
|
||||
"id": "2490",
|
||||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "1",
|
||||
"attack_level": "1"
|
||||
"attack_level": "25"
|
||||
},
|
||||
{
|
||||
"examine": "",
|
||||
"melee_animation": "5327",
|
||||
"combat_audio": "537,539,538",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -30854,6 +30881,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "One of Gielinor's many citizens.",
|
||||
"name": "Woman",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
|
|
@ -36003,7 +36031,7 @@
|
|||
"name": "Tortoise",
|
||||
"defence_level": "36",
|
||||
"safespot": null,
|
||||
"lifepoints": "51",
|
||||
"lifepoints": "121",
|
||||
"strength_level": "36",
|
||||
"id": "3808",
|
||||
"range_level": "1",
|
||||
|
|
@ -36077,61 +36105,68 @@
|
|||
"examine": "A Gnome Arrow-chucker",
|
||||
"combat_style": "1",
|
||||
"melee_animation": "190",
|
||||
"range_animation": "0",
|
||||
"range_animation": "190",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"defence_animation": "193",
|
||||
"weakness": "2",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "196",
|
||||
"name": "Gnome Archer",
|
||||
"defence_level": "30",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
"lifepoints": "42",
|
||||
"lifepoints": "10",
|
||||
"strength_level": "1",
|
||||
"id": "3814",
|
||||
"aggressive": "true",
|
||||
"range_level": "30",
|
||||
"attack_level": "1"
|
||||
"range_level": "5",
|
||||
"projectile": "10",
|
||||
"attack_level": "1",
|
||||
"prj_height": "30"
|
||||
},
|
||||
{
|
||||
"examine": "Yee haa!",
|
||||
"melee_animation": "3969",
|
||||
"range_animation": "0",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"defence_animation": "193",
|
||||
"weakness": "9",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "196",
|
||||
"name": "Gnome Driver",
|
||||
"defence_level": "33",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
"lifepoints": "47",
|
||||
"strength_level": "33",
|
||||
"lifepoints": "10",
|
||||
"strength_level": "1",
|
||||
"id": "3815",
|
||||
"aggressive": "true",
|
||||
"range_level": "1",
|
||||
"attack_level": "33"
|
||||
"attack_level": "5"
|
||||
},
|
||||
{
|
||||
"examine": "A battle mage of the gnomish variety.",
|
||||
"combat_style": "2",
|
||||
"start_gfx": "93",
|
||||
"start_height": "80",
|
||||
"melee_animation": "3968",
|
||||
"range_animation": "0",
|
||||
"magic_level": "34",
|
||||
"magic_level": "5",
|
||||
"spell_id": "",
|
||||
"respawn_delay": "60",
|
||||
"defence_animation": "0",
|
||||
"defence_animation": "193",
|
||||
"weakness": "5",
|
||||
"magic_animation": "0",
|
||||
"magic_animation": "200",
|
||||
"death_animation": "196",
|
||||
"name": "Gnome Mage",
|
||||
"defence_level": "34",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
"lifepoints": "48",
|
||||
"lifepoints": "10",
|
||||
"strength_level": "1",
|
||||
"id": "3816",
|
||||
"aggressive": "true",
|
||||
"range_level": "1",
|
||||
"attack_level": "1"
|
||||
"projectile": "94",
|
||||
"attack_level": "1",
|
||||
"prj_height": "30"
|
||||
},
|
||||
{
|
||||
"examine": "The cruel tortoise trainer. Boo!",
|
||||
|
|
@ -36160,7 +36195,7 @@
|
|||
"name": "Tortoise",
|
||||
"defence_level": "36",
|
||||
"safespot": null,
|
||||
"lifepoints": "51",
|
||||
"lifepoints": "101",
|
||||
"strength_level": "36",
|
||||
"id": "3819",
|
||||
"range_level": "1",
|
||||
|
|
@ -37498,15 +37533,30 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"name": "Snake",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
"lifepoints": "10",
|
||||
"examine": "Snake! Snaaaaake! ",
|
||||
"combat_audio": "3609,3608,3610",
|
||||
"strength_level": "1",
|
||||
"range_animation": "0",
|
||||
"melee_animation": "275",
|
||||
"attack_speed": "3",
|
||||
"poisonous": "true",
|
||||
"magic_level": "1",
|
||||
"end_gfx": "",
|
||||
"respawn_delay": "30",
|
||||
"defence_animation": "276",
|
||||
"poison_amount": "15",
|
||||
"end_height": "",
|
||||
"magic_animation": "0",
|
||||
"death_animation": "278",
|
||||
"name": "Snake",
|
||||
"defence_level": "50",
|
||||
"safespot": null,
|
||||
"lifepoints": "25",
|
||||
"strength_level": "25",
|
||||
"id": "4343",
|
||||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "1",
|
||||
"attack_level": "1"
|
||||
"attack_level": "25"
|
||||
},
|
||||
{
|
||||
"melee_animation": "220",
|
||||
|
|
@ -53269,6 +53319,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "An ugly green creature.",
|
||||
"name": "Goblin",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
|
|
@ -56220,6 +56271,7 @@
|
|||
"attack_level": "48"
|
||||
},
|
||||
{
|
||||
"examine": "This one's had too much to drink!",
|
||||
"melee_animation": "390",
|
||||
"combat_audio": "703,705,704",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -56236,6 +56288,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "This one's had too much to drink!",
|
||||
"melee_animation": "390",
|
||||
"combat_audio": "703,705,704",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -56252,6 +56305,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "This one's had too much to drink!",
|
||||
"melee_animation": "390",
|
||||
"combat_audio": "703,705,704",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -56268,6 +56322,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "This one's had too much to drink!",
|
||||
"melee_animation": "390",
|
||||
"combat_audio": "703,705,704",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -56284,6 +56339,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "This one's had too much to drink!",
|
||||
"melee_animation": "390",
|
||||
"combat_audio": "703,705,704",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -56610,6 +56666,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "A barely visible deadly spider.",
|
||||
"melee_animation": "5327",
|
||||
"combat_audio": "537,539,538",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -56626,6 +56683,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "A barely visible deadly spider.",
|
||||
"melee_animation": "5327",
|
||||
"combat_audio": "537,539,538",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -56737,6 +56795,7 @@
|
|||
"attack_level": "45"
|
||||
},
|
||||
{
|
||||
"examine": "That stinger has to hurt...",
|
||||
"melee_animation": "7242",
|
||||
"attack_speed": "5",
|
||||
"respawn_delay": "60",
|
||||
|
|
@ -63370,7 +63429,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny",
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "629,631,630",
|
||||
|
|
@ -65394,7 +65453,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny",
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "629,631,630",
|
||||
|
|
@ -65411,7 +65470,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny",
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "629,631,630",
|
||||
|
|
@ -65428,7 +65487,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny",
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "629,631,630",
|
||||
|
|
@ -65445,7 +65504,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny",
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "629,631,630",
|
||||
|
|
@ -65462,7 +65521,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny",
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "629,631,630",
|
||||
|
|
@ -65479,7 +65538,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny",
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"melee_animation": "0",
|
||||
"range_animation": "0",
|
||||
"combat_audio": "629,631,630",
|
||||
|
|
@ -65496,6 +65555,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"name": "Baby monkey",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
|
|
@ -65507,6 +65567,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"name": "Baby monkey",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
|
|
@ -65518,6 +65579,7 @@
|
|||
"attack_level": "1"
|
||||
},
|
||||
{
|
||||
"examine": "It's a tiny, cheeky monkey.",
|
||||
"name": "Baby monkey",
|
||||
"defence_level": "1",
|
||||
"safespot": null,
|
||||
|
|
@ -72684,9 +72746,10 @@
|
|||
{
|
||||
"examine": "Rock with attitude.",
|
||||
"combat_style": "1",
|
||||
"range_animation": "0",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "8",
|
||||
"range_animation": "5347",
|
||||
"attack_speed": "6",
|
||||
"defence_animation": "154",
|
||||
"death_animation": "156",
|
||||
"name": "Rock Golem",
|
||||
"lifepoints": "25",
|
||||
"strength_level": "8",
|
||||
|
|
@ -72694,14 +72757,16 @@
|
|||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "15",
|
||||
"projectile": "968",
|
||||
"attack_level": "8"
|
||||
},
|
||||
{
|
||||
"examine": "Rock with attitude.",
|
||||
"combat_style": "1",
|
||||
"range_animation": "0",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "17",
|
||||
"range_animation": "5347",
|
||||
"attack_speed": "6",
|
||||
"defence_animation": "154",
|
||||
"death_animation": "156",
|
||||
"name": "Rock Golem",
|
||||
"lifepoints": "40",
|
||||
"strength_level": "17",
|
||||
|
|
@ -72709,14 +72774,16 @@
|
|||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "30",
|
||||
"projectile": "968",
|
||||
"attack_level": "17"
|
||||
},
|
||||
{
|
||||
"examine": "Rock with attitude.",
|
||||
"combat_style": "1",
|
||||
"range_animation": "0",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "36",
|
||||
"range_animation": "5347",
|
||||
"attack_speed": "6",
|
||||
"defence_animation": "154",
|
||||
"death_animation": "156",
|
||||
"name": "Rock Golem",
|
||||
"lifepoints": "60",
|
||||
"strength_level": "36",
|
||||
|
|
@ -72724,14 +72791,16 @@
|
|||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "40",
|
||||
"projectile": "968",
|
||||
"attack_level": "38"
|
||||
},
|
||||
{
|
||||
"examine": "Rock with attitude.",
|
||||
"combat_style": "1",
|
||||
"range_animation": "0",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "64",
|
||||
"range_animation": "5347",
|
||||
"attack_speed": "6",
|
||||
"defence_animation": "154",
|
||||
"death_animation": "156",
|
||||
"name": "Rock Golem",
|
||||
"lifepoints": "86",
|
||||
"strength_level": "64",
|
||||
|
|
@ -72739,14 +72808,16 @@
|
|||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "60",
|
||||
"projectile": "968",
|
||||
"attack_level": "64"
|
||||
},
|
||||
{
|
||||
"examine": "Rock with attitude.",
|
||||
"combat_style": "1",
|
||||
"range_animation": "0",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "100",
|
||||
"range_animation": "5347",
|
||||
"attack_speed": "6",
|
||||
"defence_animation": "154",
|
||||
"death_animation": "156",
|
||||
"name": "Rock Golem",
|
||||
"lifepoints": "120",
|
||||
"strength_level": "100",
|
||||
|
|
@ -72754,14 +72825,16 @@
|
|||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "75",
|
||||
"projectile": "968",
|
||||
"attack_level": "100"
|
||||
},
|
||||
{
|
||||
"examine": "Rock with attitude.",
|
||||
"combat_style": "1",
|
||||
"range_animation": "0",
|
||||
"attack_speed": "4",
|
||||
"defence_animation": "130",
|
||||
"range_animation": "5347",
|
||||
"attack_speed": "6",
|
||||
"defence_animation": "154",
|
||||
"death_animation": "156",
|
||||
"name": "Rock Golem",
|
||||
"lifepoints": "166",
|
||||
"strength_level": "130",
|
||||
|
|
@ -72769,6 +72842,7 @@
|
|||
"aggressive": "true",
|
||||
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
|
||||
"range_level": "80",
|
||||
"projectile": "968",
|
||||
"attack_level": "130"
|
||||
},
|
||||
{
|
||||
|
|
@ -73422,6 +73496,7 @@
|
|||
"id": "366"
|
||||
},
|
||||
{
|
||||
"examine": "Owner of the banana plantation.",
|
||||
"name": "Luthas",
|
||||
"id": "379"
|
||||
},
|
||||
|
|
@ -73530,22 +73605,22 @@
|
|||
"id": "486"
|
||||
},
|
||||
{
|
||||
"name": "Observatory professor",
|
||||
"id": "488"
|
||||
},
|
||||
{
|
||||
"examine": "A cart driver; it looks like he's quite experienced.",
|
||||
"name": "Hajedy",
|
||||
"id": "510"
|
||||
},
|
||||
{
|
||||
"examine": "A cart driver; it looks like he's quite experienced.",
|
||||
"name": "Vigroy",
|
||||
"id": "511"
|
||||
},
|
||||
{
|
||||
"examine": "This is Yohnus - he runs the local blacksmiths.",
|
||||
"name": "Yohnus",
|
||||
"id": "513"
|
||||
},
|
||||
{
|
||||
"examine": "This is Seravel. He sells tickets for the 'Lady of the Waves.'",
|
||||
"name": "Seravel",
|
||||
"id": "514"
|
||||
},
|
||||
|
|
@ -73562,6 +73637,7 @@
|
|||
"id": "553"
|
||||
},
|
||||
{
|
||||
"examine": "Goods for sale and trade.",
|
||||
"name": "Jiminua",
|
||||
"id": "560"
|
||||
},
|
||||
|
|
@ -73574,6 +73650,7 @@
|
|||
"id": "565"
|
||||
},
|
||||
{
|
||||
"examine": "Appears slightly drunk.",
|
||||
"name": "Zambo",
|
||||
"id": "568"
|
||||
},
|
||||
|
|
@ -73598,6 +73675,7 @@
|
|||
"id": "585"
|
||||
},
|
||||
{
|
||||
"examine": "An amulet trader.",
|
||||
"name": "Davon",
|
||||
"id": "588"
|
||||
},
|
||||
|
|
@ -73766,6 +73844,7 @@
|
|||
"id": "673"
|
||||
},
|
||||
{
|
||||
"examine": "Builds ships for a living.",
|
||||
"name": "Shipyard worker",
|
||||
"id": "675"
|
||||
},
|
||||
|
|
@ -73854,6 +73933,7 @@
|
|||
"id": "725"
|
||||
},
|
||||
{
|
||||
"examine": "A wise old witch doctor.",
|
||||
"name": "Trufitus",
|
||||
"id": "740"
|
||||
},
|
||||
|
|
@ -73954,10 +74034,12 @@
|
|||
"id": "784"
|
||||
},
|
||||
{
|
||||
"examine": "A diligent guard.",
|
||||
"name": "Garv",
|
||||
"id": "788"
|
||||
},
|
||||
{
|
||||
"examine": "A rough looking thief.",
|
||||
"name": "Grubor",
|
||||
"id": "789"
|
||||
},
|
||||
|
|
@ -73966,6 +74048,7 @@
|
|||
"id": "791"
|
||||
},
|
||||
{
|
||||
"examine": "Looks like he's been in the wars.",
|
||||
"name": "Grip",
|
||||
"id": "792"
|
||||
},
|
||||
|
|
@ -74061,6 +74144,7 @@
|
|||
"id": "844"
|
||||
},
|
||||
{
|
||||
"examine": "A happening kind of guy!",
|
||||
"name": "Kangai Mau",
|
||||
"id": "846"
|
||||
},
|
||||
|
|
@ -74337,14 +74421,17 @@
|
|||
"id": "1159"
|
||||
},
|
||||
{
|
||||
"examine": "The imposing Chief of Tai Bwo Wannai.",
|
||||
"name": "Timfraku",
|
||||
"id": "1162"
|
||||
},
|
||||
{
|
||||
"examine": "A rather depressed looking fisherman.",
|
||||
"name": "Tiadeche",
|
||||
"id": "1163"
|
||||
},
|
||||
{
|
||||
"examine": "A rather depressed looking fisherman.",
|
||||
"name": "Tiadeche",
|
||||
"id": "1164"
|
||||
},
|
||||
|
|
@ -74357,6 +74444,7 @@
|
|||
"id": "1166"
|
||||
},
|
||||
{
|
||||
"examine": "A hunter who long ago succumbed to blood lust.",
|
||||
"name": "Tamayu",
|
||||
"id": "1167"
|
||||
},
|
||||
|
|
@ -74373,6 +74461,7 @@
|
|||
"id": "1170"
|
||||
},
|
||||
{
|
||||
"examine": "A crotchety old fisherman who doesn't like young whippersnappers.",
|
||||
"name": "Lubufu",
|
||||
"id": "1171"
|
||||
},
|
||||
|
|
@ -74397,10 +74486,12 @@
|
|||
"id": "1178"
|
||||
},
|
||||
{
|
||||
"examine": "A sea bird.",
|
||||
"name": "Cormorant",
|
||||
"id": "1180"
|
||||
},
|
||||
{
|
||||
"examine": "A sea bird.",
|
||||
"name": "Pelican",
|
||||
"id": "1181"
|
||||
},
|
||||
|
|
@ -74766,6 +74857,7 @@
|
|||
},
|
||||
{
|
||||
"name": "Solihib",
|
||||
"movement_radius": "1",
|
||||
"id": "1433"
|
||||
},
|
||||
{
|
||||
|
|
@ -75069,6 +75161,7 @@
|
|||
"id": "1581"
|
||||
},
|
||||
{
|
||||
"examine": "Looks like he wants money.",
|
||||
"name": "Saniboch",
|
||||
"id": "1595"
|
||||
},
|
||||
|
|
@ -75413,6 +75506,7 @@
|
|||
"id": "1883"
|
||||
},
|
||||
{
|
||||
"examine": "A well dressed thief.",
|
||||
"name": "Trobert",
|
||||
"id": "1884"
|
||||
},
|
||||
|
|
@ -76569,26 +76663,32 @@
|
|||
"id": "2590"
|
||||
},
|
||||
{
|
||||
"examine": "Another one of those mystic-types.",
|
||||
"name": "TzHaar-Mej-Jal",
|
||||
"id": "2617"
|
||||
},
|
||||
{
|
||||
"examine": "Another one of those mystic-types.",
|
||||
"name": "TzHaar-Mej-Kah",
|
||||
"id": "2618"
|
||||
},
|
||||
{
|
||||
"examine": "Maybe it'll guard my possessions.",
|
||||
"name": "TzHaar-Ket-Zuh",
|
||||
"id": "2619"
|
||||
},
|
||||
{
|
||||
"examine": "Wonder what it's making.",
|
||||
"name": "TzHaar-Hur-Tel",
|
||||
"id": "2620"
|
||||
},
|
||||
{
|
||||
"examine": "Wonder what it's making.",
|
||||
"name": "TzHaar-Hur-Lek",
|
||||
"id": "2622"
|
||||
},
|
||||
{
|
||||
"examine": "Another one of those mystic-types.",
|
||||
"name": "TzHaar-Mej-Roh",
|
||||
"id": "2623"
|
||||
},
|
||||
|
|
@ -80464,6 +80564,7 @@
|
|||
"id": "4577"
|
||||
},
|
||||
{
|
||||
"examine": "He looks like he's a long way from home.",
|
||||
"name": "Penwie",
|
||||
"id": "4578"
|
||||
},
|
||||
|
|
@ -82834,6 +82935,7 @@
|
|||
"id": "6114"
|
||||
},
|
||||
{
|
||||
"examine": "A man, learned in the ways of the stars.",
|
||||
"name": "Observatory professor",
|
||||
"id": "6119"
|
||||
},
|
||||
|
|
@ -83534,10 +83636,12 @@
|
|||
"id": "6915"
|
||||
},
|
||||
{
|
||||
"examine": "",
|
||||
"name": "Gecko",
|
||||
"id": "6916"
|
||||
},
|
||||
{
|
||||
"examine": "How cute!",
|
||||
"name": "Gecko",
|
||||
"id": "6918"
|
||||
},
|
||||
|
|
@ -84126,6 +84230,7 @@
|
|||
"id": "7280"
|
||||
},
|
||||
{
|
||||
"examine": "",
|
||||
"name": "Gecko",
|
||||
"id": "7281"
|
||||
},
|
||||
|
|
@ -84142,14 +84247,17 @@
|
|||
"id": "7284"
|
||||
},
|
||||
{
|
||||
"examine": "It's so adorably tiny!",
|
||||
"name": "Baby gecko",
|
||||
"id": "7286"
|
||||
},
|
||||
{
|
||||
"examine": "",
|
||||
"name": "Baby gecko",
|
||||
"id": "7287"
|
||||
},
|
||||
{
|
||||
"examine": "It's so adorably tiny!",
|
||||
"name": "Baby gecko",
|
||||
"id": "7288"
|
||||
},
|
||||
|
|
@ -84158,6 +84266,7 @@
|
|||
"id": "7289"
|
||||
},
|
||||
{
|
||||
"examine": "How cute!",
|
||||
"name": "Gecko",
|
||||
"id": "7290"
|
||||
},
|
||||
|
|
@ -84166,6 +84275,7 @@
|
|||
"id": "7291"
|
||||
},
|
||||
{
|
||||
"examine": "How cute!",
|
||||
"name": "Gecko",
|
||||
"id": "7292"
|
||||
},
|
||||
|
|
@ -86918,6 +87028,7 @@
|
|||
"id": "8274"
|
||||
},
|
||||
{
|
||||
"examine": "He looks dangerous!",
|
||||
"name": "Duradel",
|
||||
"id": "8275"
|
||||
},
|
||||
|
|
@ -88072,5 +88183,10 @@
|
|||
"examine": "He looks angry and smells drunk.",
|
||||
"name": "Skippy",
|
||||
"id": "2796"
|
||||
},
|
||||
{
|
||||
"examine": "Angry and stressed, he doesn't seem to have time for anything other than sand.",
|
||||
"name": "Sandy",
|
||||
"id": "3112"
|
||||
}
|
||||
]
|
||||
|
|
@ -133,7 +133,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "41",
|
||||
"loc_data": "{2851,3370,0,1,3}-{2846,3374,0,1,3}-{2853,3372,0,1,3}-{2847,3373,0,1,3}-{2850,3371,0,1,1}-{2851,3373,0,1,4}-{2852,3370,0,1,4}-{2819,3561,0,1,4}-{2818,3559,0,1,6}-{3110,9573,0,1,6}-{3140,3096,0,1,3}-{3140,3093,0,1,0}-{3138,3094,0,1,1}-{3140,3093,0,1,3}-{3138,3093,0,1,1}-{3138,3094,0,1,0}-{3140,3093,0,1,1}-{3187,3276,0,1,5}-{3188,3278,0,1,4}-{3197,3356,0,1,4}-{2655,3441,0,1,6}-{2649,3438,0,1,7}-{2649,3446,0,1,6}-{2653,3444,0,1,6}-{2647,3441,0,1,1}-{2674,3652,0,1,3}-{2672,3655,0,1,6}-{2677,3655,0,1,6}-{3234,3297,0,1,3}-{3230,3296,0,1,5}-{3236,3288,0,1,6}-{3236,3300,0,1,2}-{3234,3293,0,1,4}-{3229,3298,0,1,1}-{3228,3296,0,1,4}-{2694,3274,0,1,6}-{2695,3275,0,1,3}-{2965,3336,0,1,4}-{2784,3062,0,1,4}-{2789,3063,0,1,4}-{2815,3560,0,1,7}-"
|
||||
"loc_data": "{2851,3370,0,1,3}-{2846,3374,0,1,3}-{2853,3372,0,1,3}-{2847,3373,0,1,3}-{2850,3371,0,1,1}-{2851,3373,0,1,4}-{2852,3370,0,1,4}-{2819,3561,0,1,4}-{2818,3559,0,1,6}-{3110,9573,0,1,6}-{3140,3096,0,1,3}-{3140,3093,0,1,0}-{3138,3094,0,1,1}-{3140,3093,0,1,3}-{3138,3093,0,1,1}-{3138,3094,0,1,0}-{3140,3093,0,1,1}-{3187,3276,0,1,5}-{3188,3278,0,1,4}-{3197,3356,0,1,4}-{3197,3353,0,1,0}-{3196,3358,0,1,0}-{2655,3441,0,1,6}-{2649,3438,0,1,7}-{2649,3446,0,1,6}-{2653,3444,0,1,6}-{2647,3441,0,1,1}-{2674,3652,0,1,3}-{2672,3655,0,1,6}-{2677,3655,0,1,6}-{3234,3297,0,1,3}-{3230,3296,0,1,5}-{3236,3288,0,1,6}-{3236,3300,0,1,2}-{3234,3293,0,1,4}-{3229,3298,0,1,1}-{3228,3296,0,1,4}-{2694,3274,0,1,6}-{2695,3275,0,1,3}-{2965,3336,0,1,4}-{2784,3062,0,1,4}-{2789,3063,0,1,4}-{2815,3560,0,1,7}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "42",
|
||||
|
|
@ -157,7 +157,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "47",
|
||||
"loc_data": "{2821,3170,0,1,1}-{3341,3267,0,1,5}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2801,3158,0,1,2}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-"
|
||||
"loc_data": "{2821,3170,0,1,1}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3341,3267,0,1,5}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2339,9356,0,1,0}-{2354,9390,0,1,0}-{2361,9403,0,1,0}-{2362,9347,0,1,0}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2801,3158,0,1,2}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "48",
|
||||
|
|
@ -193,7 +193,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "59",
|
||||
"loc_data": "{3082,3362,0,1,4}-{2602,9640,0,1,0}-{2603,9635,0,1,0}-{2603,9638,0,1,0}-{2605,9637,0,1,0}-{2605,9639,0,1,0}-{2606,9635,0,1,0}-{2606,9646,0,1,0}-{2607,9637,0,1,0}-{2607,9641,0,1,0}-{2607,9644,0,1,0}-{2607,9648,0,1,0}-{2608,9635,0,1,0}-{2608,9642,0,1,0}-{2609,9639,0,1,0}-{2609,9643,0,1,0}-{3102,9881,0,1,3}-{3095,9883,0,1,2}-{3182,3244,0,1,1}-{3162,3223,0,1,7}-{3164,3242,0,1,0}-{3169,3246,0,1,0}-{3170,3250,0,1,0}-{3166,3247,0,1,0}-{3164,3249,0,1,0}-{3157,3226,0,1,0}-{3163,3227,0,1,0}-{3165,3223,0,1,0}-{3194,3236,0,1,0}-{3146,3347,0,1,3}-{2648,9766,0,1,4}-{2653,9761,0,1,3}-{2483,2877,0,1,3}-{2481,2876,0,1,4}-{2457,2867,0,1,4}-{2481,2847,0,1,0}-{2475,2854,0,1,3}-{2482,2873,0,1,3}-{2485,2876,0,1,2}-{2449,2865,0,1,1}-{2461,2880,0,1,5}-{2489,2935,0,1,7}-{2492,2907,0,1,1}-{2487,2894,0,1,2}-{2487,2888,0,1,7}-{2478,2916,0,1,5}-{2485,2902,0,1,3}-{2487,2902,0,1,2}-{2489,2894,0,1,2}-{2490,2905,0,1,7}-{2490,2917,0,1,5}-{2484,2890,0,1,1}-{2491,2927,0,1,1}-{3250,3239,0,1,1}-{3241,3241,0,1,1}-{3249,3249,0,1,1}-{3218,9890,0,1,3}-{3220,9887,0,1,0}-{3218,9887,0,1,1}-{3218,9889,0,1,5}-{3213,9890,0,1,1}-{2496,2890,0,1,4}-{2503,2889,0,1,1}-{2497,2939,0,1,2}-{2369,3374,0,1,0}-{2372,3379,0,1,0}-{2378,3366,0,1,0}-{2379,3378,0,1,0}-{2387,3370,0,1,0}-{2394,3365,0,1,0}-{2402,3386,0,1,0}-{2405,3381,0,1,0}-{2407,3387,0,1,0}-{2412,3384,0,1,0}-"
|
||||
"loc_data": "{3082,3362,0,1,4}-{2602,9640,0,1,0}-{2603,9635,0,1,0}-{2603,9638,0,1,0}-{2605,9637,0,1,0}-{2605,9639,0,1,0}-{2606,9635,0,1,0}-{2606,9646,0,1,0}-{2607,9637,0,1,0}-{2607,9641,0,1,0}-{2607,9644,0,1,0}-{2607,9648,0,1,0}-{2608,9635,0,1,0}-{2608,9642,0,1,0}-{2609,9639,0,1,0}-{2609,9643,0,1,0}-{3102,9881,0,1,3}-{3095,9883,0,1,2}-{3182,3244,0,1,1}-{3162,3223,0,1,7}-{3164,3242,0,1,0}-{3169,3246,0,1,0}-{3170,3250,0,1,0}-{3166,3247,0,1,0}-{3164,3249,0,1,0}-{3157,3226,0,1,0}-{3163,3227,0,1,0}-{3165,3223,0,1,0}-{3194,3236,0,1,0}-{3146,3347,0,1,3}-{2369,3374,0,1,0}-{2372,3379,0,1,0}-{2378,3366,0,1,0}-{2379,3378,0,1,0}-{2387,3370,0,1,0}-{2394,3365,0,1,0}-{2402,3386,0,1,0}-{2405,3381,0,1,0}-{2407,3387,0,1,0}-{2412,3384,0,1,0}-{2648,9766,0,1,4}-{2653,9761,0,1,3}-{2483,2877,0,1,3}-{2481,2876,0,1,4}-{2457,2867,0,1,4}-{2481,2847,0,1,0}-{2475,2854,0,1,3}-{2482,2873,0,1,3}-{2485,2876,0,1,2}-{2449,2865,0,1,1}-{2461,2880,0,1,5}-{2489,2935,0,1,7}-{2492,2907,0,1,1}-{2487,2894,0,1,2}-{2487,2888,0,1,7}-{2478,2916,0,1,5}-{2485,2902,0,1,3}-{2487,2902,0,1,2}-{2489,2894,0,1,2}-{2490,2905,0,1,7}-{2490,2917,0,1,5}-{2484,2890,0,1,1}-{2491,2927,0,1,1}-{3250,3239,0,1,1}-{3241,3241,0,1,1}-{3249,3249,0,1,1}-{3218,9890,0,1,3}-{3220,9887,0,1,0}-{3218,9887,0,1,1}-{3218,9889,0,1,5}-{3213,9890,0,1,1}-{2496,2890,0,1,4}-{2503,2889,0,1,1}-{2497,2939,0,1,2}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "60",
|
||||
|
|
@ -217,15 +217,15 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "66",
|
||||
"loc_data": "{2417,3493,1,1,0}-{2418,3495,1,1,0}-{2383,3452,0,1,0}-{2401,3417,0,1,0}-{2402,3422,0,1,0}-{2402,3441,0,1,0}-{2403,3430,0,1,0}-{2408,3441,0,1,0}-{2409,3430,0,1,0}-{2423,3426,0,1,0}-{2427,3428,0,1,0}-{2427,3440,0,1,0}-{2526,3168,0,1,0}-{2529,3163,0,1,0}-{2530,3172,0,1,0}-{2536,3169,0,1,0}-{2435,3460,0,1,0}-{2440,3470,0,1,0}-{2447,3502,0,1,0}-{2457,3462,0,1,0}-{2478,3502,0,1,0}-{2449,3492,1,1,0}-{2450,3490,1,1,0}-{2474,3490,1,1,0}-{2482,3492,1,1,0}-{2482,3498,1,1,0}-{2399,3356,0,1,0}-"
|
||||
"loc_data": "{2399,3356,0,1,0}-{2383,3452,0,1,0}-{2401,3417,0,1,0}-{2402,3422,0,1,0}-{2402,3441,0,1,0}-{2403,3430,0,1,0}-{2408,3441,0,1,0}-{2409,3430,0,1,0}-{2423,3426,0,1,0}-{2427,3428,0,1,0}-{2427,3440,0,1,0}-{2417,3493,1,1,0}-{2418,3495,1,1,0}-{2435,3460,0,1,0}-{2440,3470,0,1,0}-{2447,3502,0,1,0}-{2457,3462,0,1,0}-{2478,3502,0,1,0}-{2449,3492,1,1,0}-{2450,3490,1,1,0}-{2474,3490,1,1,0}-{2482,3492,1,1,0}-{2482,3498,1,1,0}-{2526,3168,0,1,0}-{2529,3163,0,1,0}-{2530,3172,0,1,0}-{2536,3169,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "67",
|
||||
"loc_data": "{2556,3226,0,1,0}-{2456,3425,0,1,0}-{2459,3421,0,1,0}-{2462,3431,0,1,0}-{2394,3500,1,1,0}-{2417,3483,1,1,0}-{2377,3442,0,1,0}-{2380,3425,0,1,0}-{2383,3433,0,1,0}-{2405,3447,0,1,0}-{2406,3440,0,1,0}-{2393,3451,1,1,0}-{2408,3437,1,1,0}-{2521,3169,0,1,0}-{2521,3171,0,1,0}-{2033,5530,1,1,0}-{2437,3478,0,1,0}-{2442,3465,0,1,0}-{2456,3467,0,1,0}-{2471,3496,0,1,0}-{2474,3508,0,1,0}-{2475,3471,0,1,0}-{2479,3468,0,1,0}-{2486,3470,0,1,0}-{2492,3474,0,1,0}-{2443,3464,1,1,0}-{2443,3502,1,1,0}-{2448,3496,1,1,0}-{2449,3506,1,1,0}-{2457,3498,1,1,0}-{2474,3498,1,1,0}-{2480,3502,1,1,0}-{2481,3482,1,1,0}-{2490,3503,1,1,0}-{2400,3356,0,1,0}-"
|
||||
"loc_data": "{2400,3356,0,1,0}-{2377,3442,0,1,0}-{2380,3425,0,1,0}-{2383,3433,0,1,0}-{2405,3447,0,1,0}-{2406,3440,0,1,0}-{2393,3451,1,1,0}-{2408,3437,1,1,0}-{2394,3500,1,1,0}-{2417,3483,1,1,0}-{2456,3425,0,1,0}-{2459,3421,0,1,0}-{2462,3431,0,1,0}-{2437,3478,0,1,0}-{2442,3465,0,1,0}-{2456,3467,0,1,0}-{2471,3496,0,1,0}-{2474,3508,0,1,0}-{2475,3471,0,1,0}-{2479,3468,0,1,0}-{2486,3470,0,1,0}-{2492,3474,0,1,0}-{2443,3464,1,1,0}-{2443,3502,1,1,0}-{2448,3496,1,1,0}-{2449,3506,1,1,0}-{2457,3498,1,1,0}-{2474,3498,1,1,0}-{2480,3502,1,1,0}-{2481,3482,1,1,0}-{2490,3503,1,1,0}-{2521,3169,0,1,0}-{2521,3171,0,1,0}-{2556,3226,0,1,0}-{2033,5530,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "68",
|
||||
"loc_data": "{2400,3514,1,1,0}-{2418,3485,1,1,0}-{2378,3423,0,1,0}-{2393,3435,0,1,0}-{2394,3425,0,1,0}-{2395,3449,0,1,0}-{2403,3433,0,1,0}-{2420,3429,0,1,0}-{2420,3438,0,1,0}-{2522,3172,0,1,0}-{2433,3474,0,1,0}-{2433,3492,0,1,0}-{2458,3497,0,1,0}-{2464,3505,0,1,0}-{2476,3458,0,1,0}-{2445,3502,1,1,0}-{2453,3488,1,1,0}-{2475,3502,1,1,0}-{2465,3490,2,1,0}-{2401,3357,0,1,0}-"
|
||||
"loc_data": "{2401,3357,0,1,0}-{2378,3423,0,1,0}-{2393,3435,0,1,0}-{2394,3425,0,1,0}-{2395,3449,0,1,0}-{2403,3433,0,1,0}-{2420,3429,0,1,0}-{2420,3438,0,1,0}-{2400,3514,1,1,0}-{2418,3485,1,1,0}-{2433,3474,0,1,0}-{2433,3492,0,1,0}-{2458,3497,0,1,0}-{2464,3505,0,1,0}-{2476,3458,0,1,0}-{2445,3502,1,1,0}-{2453,3488,1,1,0}-{2475,3502,1,1,0}-{2465,3490,2,1,0}-{2522,3172,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "73",
|
||||
|
|
@ -325,11 +325,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "100",
|
||||
"loc_data": "{2567,3440,0,1,3}-{2564,9653,0,1,0}-{2565,9655,0,1,0}-{2566,9626,0,1,0}-{2567,9653,0,1,0}-{2569,9633,0,1,0}-{2607,9621,0,1,0}-{2551,3408,0,1,6}-{2553,3405,0,1,3}-{2559,3452,0,1,3}-"
|
||||
"loc_data": "{2567,3440,0,1,3}-{2316,9392,0,1,0}-{2319,9367,0,1,0}-{2321,9402,0,1,0}-{2322,9387,0,1,0}-{2325,9360,0,1,0}-{2333,9346,0,1,0}-{2335,9382,0,1,0}-{2337,9387,0,1,0}-{2343,9360,0,1,0}-{2344,9369,0,1,0}-{2348,9390,0,1,0}-{2349,9380,0,1,0}-{2349,9402,0,1,0}-{2359,9345,0,1,0}-{2359,9359,0,1,0}-{2359,9374,0,1,0}-{2359,9382,0,1,0}-{2363,9403,0,1,0}-{2564,9653,0,1,0}-{2565,9655,0,1,0}-{2566,9626,0,1,0}-{2567,9653,0,1,0}-{2569,9633,0,1,0}-{2607,9621,0,1,0}-{2551,3408,0,1,6}-{2553,3405,0,1,3}-{2559,3452,0,1,3}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "101",
|
||||
"loc_data": "{2622,3389,0,1,4}-{2619,3390,0,1,4}-{2573,3437,0,1,3}-{2562,9659,0,1,0}-{2563,9661,0,1,0}-{2599,9626,0,1,0}-{2601,9627,0,1,0}-{2605,9621,0,1,0}-{2610,9620,0,1,0}-{2624,3391,0,1,1}-{2555,3407,0,1,3}-{2553,3457,0,1,3}-"
|
||||
"loc_data": "{2622,3389,0,1,4}-{2619,3390,0,1,4}-{2573,3437,0,1,3}-{2305,9385,0,1,0}-{2307,9359,0,1,0}-{2307,9403,0,1,0}-{2310,9396,0,1,0}-{2317,9371,0,1,0}-{2317,9383,0,1,0}-{2324,9404,0,1,0}-{2333,9366,0,1,0}-{2335,9393,0,1,0}-{2339,9403,0,1,0}-{2342,9347,0,1,0}-{2351,9359,0,1,0}-{2359,9392,0,1,0}-{2562,9659,0,1,0}-{2563,9661,0,1,0}-{2599,9626,0,1,0}-{2601,9627,0,1,0}-{2605,9621,0,1,0}-{2610,9620,0,1,0}-{2624,3391,0,1,1}-{2555,3407,0,1,3}-{2553,3457,0,1,3}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "102",
|
||||
|
|
@ -345,7 +345,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "105",
|
||||
"loc_data": "{3100,3594,0,1,6}-{3107,3608,0,1,2}-{3099,3602,0,1,0}-{2632,3280,0,1,1}-{2633,3274,0,1,3}-{2696,3329,0,1,4}-{2708,3336,0,1,4}-{3230,3500,0,1,5}-{2988,3671,0,1,0}-{3001,3674,0,1,0}-{2497,3164,0,1,2}-{2387,3376,0,1,0}-{2398,3366,0,1,0}-{2412,3378,0,1,0}-{2419,3372,0,1,0}-"
|
||||
"loc_data": "{3100,3594,0,1,6}-{3107,3608,0,1,2}-{3099,3602,0,1,0}-{2632,3280,0,1,1}-{2633,3274,0,1,3}-{2387,3376,0,1,0}-{2398,3366,0,1,0}-{2412,3378,0,1,0}-{2419,3372,0,1,0}-{2696,3329,0,1,4}-{2708,3336,0,1,4}-{3230,3500,0,1,5}-{2988,3671,0,1,0}-{3001,3674,0,1,0}-{2497,3164,0,1,2}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "106",
|
||||
|
|
@ -365,7 +365,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "110",
|
||||
"loc_data": "{2564,9887,0,1,4}-{2581,9897,0,1,1}-{2577,9888,0,1,1}-{3234,5497,0,1,1}-{3305,9400,0,1,1}-{3244,9356,0,1,1}-{3252,9370,0,1,1}-{3294,9375,0,1,3}-{3050,10337,0,1,4}-{3047,10340,0,1,4}-{3048,10346,0,1,4}-{3048,10346,0,1,3}-"
|
||||
"loc_data": "{2564,9887,0,1,4}-{2581,9897,0,1,1}-{2577,9888,0,1,1}-{3234,5497,0,1,1}-{3244,9356,0,1,1}-{3252,9370,0,1,1}-{3305,9400,0,1,1}-{3294,9375,0,1,3}-{3050,10337,0,1,4}-{3047,10340,0,1,4}-{3048,10346,0,1,4}-{3048,10346,0,1,3}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "111",
|
||||
|
|
@ -389,7 +389,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "117",
|
||||
"loc_data": "{2369,3404,0,1,0}-{3118,9845,0,1,4}-{3111,9844,0,1,6}-{3123,9845,0,1,3}-{3114,9833,0,1,3}-{3110,9841,0,1,1}-{3119,9839,0,1,1}-{3097,9832,0,1,0}-{3101,9832,0,1,1}-{3107,9829,0,1,3}-{3115,9831,0,1,4}-{3109,9835,0,1,4}-{2904,9734,0,1,0}-{2548,3146,0,1,1}-{2542,3145,0,1,4}-{2503,3150,0,1,4}-{3300,3649,0,1,0}-{3044,10321,0,1,2}-{3044,10316,0,1,4}-{3045,10308,0,1,4}-{3048,10317,0,1,2}-"
|
||||
"loc_data": "{3118,9845,0,1,4}-{3111,9844,0,1,6}-{3123,9845,0,1,3}-{3114,9833,0,1,3}-{3110,9841,0,1,1}-{3119,9839,0,1,1}-{3097,9832,0,1,0}-{3101,9832,0,1,1}-{3107,9829,0,1,3}-{3115,9831,0,1,4}-{3109,9835,0,1,4}-{2369,3404,0,1,0}-{2904,9734,0,1,0}-{2439,3214,0,1,0}-{2548,3146,0,1,1}-{2542,3145,0,1,4}-{2503,3150,0,1,4}-{3300,3649,0,1,0}-{3044,10321,0,1,2}-{3044,10316,0,1,4}-{3045,10308,0,1,4}-{3048,10317,0,1,2}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "118",
|
||||
|
|
@ -489,23 +489,23 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "153",
|
||||
"loc_data": "{2540,9820,0,1,0}-{2543,9813,0,1,0}-{2546,9817,0,1,0}-{2464,4421,0,1,0}-{2466,4423,0,1,0}-{2486,4464,0,1,0}-{2556,3444,0,1,0}-{3082,3077,0,1,0}-{3092,3082,0,1,0}-{3109,3090,0,1,0}-{3112,3093,0,1,0}-{2249,3260,0,1,0}-{2250,3257,0,1,0}-{2250,3259,0,1,0}-{2252,3261,0,1,0}-{2253,3256,0,1,0}-{2262,3226,0,1,0}-{2264,3225,0,1,0}-{2266,3229,0,1,0}-{2268,3227,0,1,0}-{2269,3222,0,1,0}-{2269,3224,0,1,0}-{2270,3223,0,1,0}-{2270,3226,0,1,0}-{3200,5954,0,1,0}-{3202,5958,0,1,0}-{3204,5955,0,1,0}-{3204,5959,0,1,0}-{3231,5967,0,1,0}-{3236,5974,0,1,0}-{3237,5968,0,1,0}-{3240,5992,0,1,0}-{3240,5994,0,1,0}-{3242,5990,0,1,0}-{3242,5993,0,1,0}-{3244,5994,0,1,0}-{3246,5989,0,1,0}-{2196,3191,0,1,0}-{2197,3189,0,1,0}-{2198,3181,0,1,0}-{2198,3187,0,1,0}-{2199,3183,0,1,0}-{2199,3187,0,1,0}-{2200,3185,0,1,0}-{2201,3185,0,1,0}-{2204,3180,0,1,0}-{2324,4599,0,1,0}-{2325,4597,0,1,0}-{2326,4589,0,1,0}-{2326,4595,0,1,0}-{2327,4591,0,1,0}-{2327,4595,0,1,0}-{2328,4593,0,1,0}-{2329,4593,0,1,0}-{2332,4588,0,1,0}-{2176,3202,0,1,0}-{2178,3206,0,1,0}-{2180,3203,0,1,0}-{2180,3207,0,1,0}-{2207,3215,0,1,0}-{2212,3222,0,1,0}-{2213,3216,0,1,0}-{2216,3240,0,1,0}-{2216,3242,0,1,0}-{2218,3238,0,1,0}-{2218,3241,0,1,0}-{2220,3242,0,1,0}-{2222,3237,0,1,0}-{2437,3425,0,1,0}-{2438,3422,0,1,0}-{2450,3419,0,1,0}-{2415,4466,0,1,0}-{2419,4427,0,1,0}-{2421,4468,0,1,0}-{2426,4431,0,1,0}-{3175,3226,0,1,0}-{3178,3228,0,1,0}-{3179,3226,0,1,0}-{3182,3251,0,1,0}-{3183,3254,0,1,0}-{2697,6204,0,1,0}-{2698,6201,0,1,0}-{2698,6203,0,1,0}-{2700,6205,0,1,0}-{2701,6200,0,1,0}-{2710,6170,0,1,0}-{2712,6169,0,1,0}-{2714,6173,0,1,0}-{2716,6171,0,1,0}-{2717,6166,0,1,0}-{2717,6168,0,1,0}-{2718,6167,0,1,0}-{2718,6170,0,1,0}-{2478,3373,0,1,0}-{2479,3381,0,1,0}-{2481,3384,0,1,0}-{2490,3371,0,1,0}-{2689,6083,0,1,0}-{2689,6088,0,1,0}-{2690,6094,0,1,0}-{2691,6084,0,1,0}-{2692,6081,0,1,0}-{2692,6090,0,1,0}-{2693,6083,0,1,0}-{2693,6085,0,1,0}-{2693,6090,0,1,0}-{2694,6083,0,1,0}-{2694,6086,0,1,0}-{2695,6082,0,1,0}-{2695,6085,0,1,0}-{2695,6088,0,1,0}-{2695,6091,0,1,0}-{2695,6121,0,1,0}-{2698,6121,0,1,0}-{2699,6082,0,1,0}-{2699,6085,0,1,0}-{2700,6084,0,1,0}-{2701,6085,0,1,0}-{2702,6081,0,1,0}-{2702,6083,0,1,0}-{2703,6119,0,1,0}-{2704,6117,0,1,0}-{2705,6121,0,1,0}-{2730,6091,0,1,0}-{2732,6095,0,1,0}-{2734,6090,0,1,0}-{2735,6094,0,1,0}-{2735,6097,0,1,0}-{2738,6098,0,1,0}-{2416,3404,0,1,0}-{2424,3410,0,1,0}-{2430,3405,0,1,0}-{1906,5223,0,1,0}-{1907,5221,0,1,0}-{3273,6012,0,1,0}-{3274,6009,0,1,0}-{3274,6011,0,1,0}-{3276,6013,0,1,0}-{3277,6008,0,1,0}-{3286,5978,0,1,0}-{3288,5977,0,1,0}-{3290,5981,0,1,0}-{3292,5979,0,1,0}-{3293,5974,0,1,0}-{3293,5976,0,1,0}-{3294,5975,0,1,0}-{3294,5978,0,1,0}-{2828,5091,0,1,0}-{2832,5108,0,1,0}-{2835,5079,0,1,0}-{2846,5067,0,1,0}-{2850,5111,0,1,0}-{2853,5086,0,1,0}-{2864,5071,0,1,0}-{2549,3139,0,1,0}-{2241,3139,0,1,0}-{2241,3144,0,1,0}-{2242,3150,0,1,0}-{2243,3140,0,1,0}-{2244,3137,0,1,0}-{2244,3146,0,1,0}-{2245,3139,0,1,0}-{2245,3141,0,1,0}-{2245,3146,0,1,0}-{2246,3139,0,1,0}-{2246,3142,0,1,0}-{2247,3138,0,1,0}-{2247,3141,0,1,0}-{2247,3144,0,1,0}-{2247,3147,0,1,0}-{2247,3177,0,1,0}-{2250,3177,0,1,0}-{2251,3138,0,1,0}-{2251,3141,0,1,0}-{2252,3140,0,1,0}-{2253,3141,0,1,0}-{2254,3137,0,1,0}-{2254,3139,0,1,0}-{2255,3175,0,1,0}-{2256,3173,0,1,0}-{2257,3177,0,1,0}-{2282,3147,0,1,0}-{2284,3151,0,1,0}-{2286,3146,0,1,0}-{2287,3150,0,1,0}-{2287,3153,0,1,0}-{2290,3154,0,1,0}-"
|
||||
"loc_data": "{3082,3077,0,1,0}-{3092,3082,0,1,0}-{3109,3090,0,1,0}-{3112,3093,0,1,0}-{2324,4599,0,1,0}-{2325,4597,0,1,0}-{2326,4589,0,1,0}-{2326,4595,0,1,0}-{2327,4591,0,1,0}-{2327,4595,0,1,0}-{2328,4593,0,1,0}-{2329,4593,0,1,0}-{2332,4588,0,1,0}-{2828,5091,0,1,0}-{2832,5108,0,1,0}-{2835,5079,0,1,0}-{2846,5067,0,1,0}-{2850,5111,0,1,0}-{2853,5086,0,1,0}-{2864,5071,0,1,0}-{3175,3226,0,1,0}-{3178,3228,0,1,0}-{3179,3226,0,1,0}-{3182,3251,0,1,0}-{3183,3254,0,1,0}-{2416,3404,0,1,0}-{2424,3410,0,1,0}-{2430,3405,0,1,0}-{2415,4466,0,1,0}-{2419,4427,0,1,0}-{2421,4468,0,1,0}-{2426,4431,0,1,0}-{1906,5223,0,1,0}-{1907,5221,0,1,0}-{2196,3191,0,1,0}-{2197,3189,0,1,0}-{2198,3181,0,1,0}-{2198,3187,0,1,0}-{2199,3183,0,1,0}-{2199,3187,0,1,0}-{2200,3185,0,1,0}-{2201,3185,0,1,0}-{2204,3180,0,1,0}-{2176,3202,0,1,0}-{2178,3206,0,1,0}-{2180,3203,0,1,0}-{2180,3207,0,1,0}-{2207,3215,0,1,0}-{2212,3222,0,1,0}-{2213,3216,0,1,0}-{2216,3240,0,1,0}-{2216,3242,0,1,0}-{2218,3238,0,1,0}-{2218,3241,0,1,0}-{2220,3242,0,1,0}-{2222,3237,0,1,0}-{2478,3373,0,1,0}-{2479,3381,0,1,0}-{2481,3384,0,1,0}-{2490,3371,0,1,0}-{2437,3425,0,1,0}-{2438,3422,0,1,0}-{2450,3419,0,1,0}-{2464,4421,0,1,0}-{2466,4423,0,1,0}-{2486,4464,0,1,0}-{3200,5954,0,1,0}-{3202,5958,0,1,0}-{3204,5955,0,1,0}-{3204,5959,0,1,0}-{3231,5967,0,1,0}-{3236,5974,0,1,0}-{3237,5968,0,1,0}-{3240,5992,0,1,0}-{3240,5994,0,1,0}-{3242,5990,0,1,0}-{3242,5993,0,1,0}-{3244,5994,0,1,0}-{3246,5989,0,1,0}-{2689,6083,0,1,0}-{2689,6088,0,1,0}-{2690,6094,0,1,0}-{2691,6084,0,1,0}-{2692,6081,0,1,0}-{2692,6090,0,1,0}-{2693,6083,0,1,0}-{2693,6085,0,1,0}-{2693,6090,0,1,0}-{2694,6083,0,1,0}-{2694,6086,0,1,0}-{2695,6082,0,1,0}-{2695,6085,0,1,0}-{2695,6088,0,1,0}-{2695,6091,0,1,0}-{2695,6121,0,1,0}-{2698,6121,0,1,0}-{2699,6082,0,1,0}-{2699,6085,0,1,0}-{2700,6084,0,1,0}-{2701,6085,0,1,0}-{2702,6081,0,1,0}-{2702,6083,0,1,0}-{2703,6119,0,1,0}-{2704,6117,0,1,0}-{2705,6121,0,1,0}-{2730,6091,0,1,0}-{2732,6095,0,1,0}-{2734,6090,0,1,0}-{2735,6094,0,1,0}-{2735,6097,0,1,0}-{2738,6098,0,1,0}-{2697,6204,0,1,0}-{2698,6201,0,1,0}-{2698,6203,0,1,0}-{2700,6205,0,1,0}-{2701,6200,0,1,0}-{2710,6170,0,1,0}-{2712,6169,0,1,0}-{2714,6173,0,1,0}-{2716,6171,0,1,0}-{2717,6166,0,1,0}-{2717,6168,0,1,0}-{2718,6167,0,1,0}-{2718,6170,0,1,0}-{2549,3139,0,1,0}-{2241,3139,0,1,0}-{2241,3144,0,1,0}-{2242,3150,0,1,0}-{2243,3140,0,1,0}-{2244,3137,0,1,0}-{2244,3146,0,1,0}-{2245,3139,0,1,0}-{2245,3141,0,1,0}-{2245,3146,0,1,0}-{2246,3139,0,1,0}-{2246,3142,0,1,0}-{2247,3138,0,1,0}-{2247,3141,0,1,0}-{2247,3144,0,1,0}-{2247,3147,0,1,0}-{2247,3177,0,1,0}-{2250,3177,0,1,0}-{2251,3138,0,1,0}-{2251,3141,0,1,0}-{2252,3140,0,1,0}-{2253,3141,0,1,0}-{2254,3137,0,1,0}-{2254,3139,0,1,0}-{2255,3175,0,1,0}-{2256,3173,0,1,0}-{2257,3177,0,1,0}-{2282,3147,0,1,0}-{2284,3151,0,1,0}-{2286,3146,0,1,0}-{2287,3150,0,1,0}-{2287,3153,0,1,0}-{2290,3154,0,1,0}-{2249,3260,0,1,0}-{2250,3257,0,1,0}-{2250,3259,0,1,0}-{2252,3261,0,1,0}-{2253,3256,0,1,0}-{2262,3226,0,1,0}-{2264,3225,0,1,0}-{2266,3229,0,1,0}-{2268,3227,0,1,0}-{2269,3222,0,1,0}-{2269,3224,0,1,0}-{2270,3223,0,1,0}-{2270,3226,0,1,0}-{2556,3444,0,1,0}-{3273,6012,0,1,0}-{3274,6009,0,1,0}-{3274,6011,0,1,0}-{3276,6013,0,1,0}-{3277,6008,0,1,0}-{3286,5978,0,1,0}-{3288,5977,0,1,0}-{3290,5981,0,1,0}-{3292,5979,0,1,0}-{3293,5974,0,1,0}-{3293,5976,0,1,0}-{3294,5975,0,1,0}-{3294,5978,0,1,0}-{2540,9820,0,1,0}-{2543,9813,0,1,0}-{2546,9817,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "154",
|
||||
"loc_data": "{2475,4459,0,1,0}-{2480,4458,0,1,0}-{2481,4454,0,1,0}-{2488,4465,0,1,0}-{3125,3084,0,1,0}-{2268,3228,0,1,0}-{3202,5955,0,1,0}-{3206,5953,0,1,0}-{3231,5976,0,1,0}-{3233,5974,0,1,0}-{3235,5970,0,1,0}-{3241,5996,0,1,0}-{3242,5988,0,1,0}-{3244,5992,0,1,0}-{2180,3173,0,1,0}-{2193,3187,0,1,0}-{2196,3184,0,1,0}-{2200,3181,0,1,0}-{2200,3188,0,1,0}-{2203,3189,0,1,0}-{2308,4581,0,1,0}-{2321,4595,0,1,0}-{2324,4592,0,1,0}-{2328,4589,0,1,0}-{2328,4596,0,1,0}-{2331,4597,0,1,0}-{2178,3203,0,1,0}-{2182,3201,0,1,0}-{2207,3224,0,1,0}-{2209,3222,0,1,0}-{2211,3218,0,1,0}-{2217,3244,0,1,0}-{2218,3236,0,1,0}-{2220,3240,0,1,0}-{2446,3396,0,1,0}-{2470,3397,0,1,0}-{2394,4453,0,1,0}-{2394,4457,0,1,0}-{2406,4447,0,1,0}-{2422,3489,0,1,0}-{2716,6172,0,1,0}-{2688,6092,0,1,0}-{2690,6087,0,1,0}-{2690,6095,0,1,0}-{2692,6082,0,1,0}-{2692,6088,0,1,0}-{2692,6123,0,1,0}-{2693,6081,0,1,0}-{2694,6125,0,1,0}-{2695,6087,0,1,0}-{2697,6086,0,1,0}-{2697,6087,0,1,0}-{2698,6081,0,1,0}-{2698,6124,0,1,0}-{2700,6083,0,1,0}-{2702,6084,0,1,0}-{2726,6085,0,1,0}-{2727,6081,0,1,0}-{2729,6083,0,1,0}-{2732,6084,0,1,0}-{2378,3418,0,1,0}-{2380,3422,0,1,0}-{2393,3442,0,1,0}-{2397,3440,0,1,0}-{2423,3399,0,1,0}-{2425,3406,0,1,0}-{2427,3402,0,1,0}-{1908,5222,0,1,0}-{3292,5980,0,1,0}-{2831,5070,0,1,0}-{2843,5106,0,1,0}-{2844,5080,0,1,0}-{2860,5079,0,1,0}-{2866,5104,0,1,0}-{2868,5096,0,1,0}-{2240,3148,0,1,0}-{2242,3143,0,1,0}-{2242,3151,0,1,0}-{2244,3138,0,1,0}-{2244,3144,0,1,0}-{2244,3179,0,1,0}-{2245,3137,0,1,0}-{2246,3181,0,1,0}-{2247,3143,0,1,0}-{2249,3142,0,1,0}-{2249,3143,0,1,0}-{2250,3137,0,1,0}-{2250,3180,0,1,0}-{2252,3139,0,1,0}-{2254,3140,0,1,0}-{2278,3141,0,1,0}-{2279,3137,0,1,0}-{2281,3139,0,1,0}-{2284,3140,0,1,0}-"
|
||||
"loc_data": "{3125,3084,0,1,0}-{2308,4581,0,1,0}-{2321,4595,0,1,0}-{2324,4592,0,1,0}-{2328,4589,0,1,0}-{2328,4596,0,1,0}-{2331,4597,0,1,0}-{2831,5070,0,1,0}-{2843,5106,0,1,0}-{2844,5080,0,1,0}-{2860,5079,0,1,0}-{2866,5104,0,1,0}-{2868,5096,0,1,0}-{2378,3418,0,1,0}-{2380,3422,0,1,0}-{2393,3442,0,1,0}-{2397,3440,0,1,0}-{2423,3399,0,1,0}-{2425,3406,0,1,0}-{2427,3402,0,1,0}-{2422,3489,0,1,0}-{2394,4453,0,1,0}-{2394,4457,0,1,0}-{2406,4447,0,1,0}-{1908,5222,0,1,0}-{2180,3173,0,1,0}-{2193,3187,0,1,0}-{2196,3184,0,1,0}-{2200,3181,0,1,0}-{2200,3188,0,1,0}-{2203,3189,0,1,0}-{2178,3203,0,1,0}-{2182,3201,0,1,0}-{2207,3224,0,1,0}-{2209,3222,0,1,0}-{2211,3218,0,1,0}-{2217,3244,0,1,0}-{2218,3236,0,1,0}-{2220,3240,0,1,0}-{2446,3396,0,1,0}-{2470,3397,0,1,0}-{2475,4459,0,1,0}-{2480,4458,0,1,0}-{2481,4454,0,1,0}-{2488,4465,0,1,0}-{3202,5955,0,1,0}-{3206,5953,0,1,0}-{3231,5976,0,1,0}-{3233,5974,0,1,0}-{3235,5970,0,1,0}-{3241,5996,0,1,0}-{3242,5988,0,1,0}-{3244,5992,0,1,0}-{2688,6092,0,1,0}-{2690,6087,0,1,0}-{2690,6095,0,1,0}-{2692,6082,0,1,0}-{2692,6088,0,1,0}-{2692,6123,0,1,0}-{2693,6081,0,1,0}-{2694,6125,0,1,0}-{2695,6087,0,1,0}-{2697,6086,0,1,0}-{2697,6087,0,1,0}-{2698,6081,0,1,0}-{2698,6124,0,1,0}-{2700,6083,0,1,0}-{2702,6084,0,1,0}-{2726,6085,0,1,0}-{2727,6081,0,1,0}-{2729,6083,0,1,0}-{2732,6084,0,1,0}-{2716,6172,0,1,0}-{2240,3148,0,1,0}-{2242,3143,0,1,0}-{2242,3151,0,1,0}-{2244,3138,0,1,0}-{2244,3144,0,1,0}-{2244,3179,0,1,0}-{2245,3137,0,1,0}-{2246,3181,0,1,0}-{2247,3143,0,1,0}-{2249,3142,0,1,0}-{2249,3143,0,1,0}-{2250,3137,0,1,0}-{2250,3180,0,1,0}-{2252,3139,0,1,0}-{2254,3140,0,1,0}-{2278,3141,0,1,0}-{2279,3137,0,1,0}-{2281,3139,0,1,0}-{2284,3140,0,1,0}-{2268,3228,0,1,0}-{3292,5980,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "155",
|
||||
"loc_data": "{3093,3086,0,1,0}-{3097,3085,0,1,0}-{3129,3091,0,1,0}-{3135,3084,0,1,0}-{2190,3180,0,1,0}-{2318,4588,0,1,0}-{2374,3469,0,1,0}-{2376,3466,0,1,0}-{3254,3230,0,1,0}-{1986,5564,0,1,0}-{2434,3516,0,1,0}-{2479,3501,0,1,0}-"
|
||||
"loc_data": "{3093,3086,0,1,0}-{3097,3085,0,1,0}-{3129,3091,0,1,0}-{3135,3084,0,1,0}-{2318,4588,0,1,0}-{2374,3469,0,1,0}-{2376,3466,0,1,0}-{2190,3180,0,1,0}-{3254,3230,0,1,0}-{2434,3516,0,1,0}-{2479,3501,0,1,0}-{1986,5564,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "156",
|
||||
"loc_data": "{2371,3460,0,1,0}-{2372,3456,0,1,0}-{2422,3467,0,1,0}-{2725,6127,0,1,0}-{2444,3491,0,1,0}-{2277,3183,0,1,0}-"
|
||||
"loc_data": "{2371,3460,0,1,0}-{2372,3456,0,1,0}-{2422,3467,0,1,0}-{2444,3491,0,1,0}-{2725,6127,0,1,0}-{2277,3183,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "157",
|
||||
"loc_data": "{2180,2798,0,1,0}-{2209,2812,0,1,0}-{2217,2780,0,1,0}-{1921,5931,0,1,0}-{1947,5908,0,1,0}-{1955,5949,0,1,0}-{1973,5888,0,1,0}-{1975,5918,0,1,0}-{1988,5870,0,1,0}-{2017,5884,0,1,0}-{2025,5852,0,1,0}-{2182,2979,0,1,0}-{2211,2963,0,1,0}-{1931,6038,0,1,0}-{1983,6037,0,1,0}-{2153,2810,0,1,0}-{2172,2806,0,1,0}-{1961,5882,0,1,0}-{1980,5878,0,1,0}-{2242,2788,0,1,0}-{2248,2858,0,1,0}-{2256,2828,0,1,0}-{2284,2874,0,1,0}-{2255,3216,0,1,0}-{2262,3210,0,1,0}-{2271,3204,0,1,0}-{2294,3219,0,1,0}-{2296,3206,0,1,0}-{2298,3201,0,1,0}-{2056,5930,0,1,0}-{2064,5900,0,1,0}-{2092,5946,0,1,0}-{2050,5860,0,1,0}-{3201,5986,0,1,0}-{3254,5972,0,1,0}-{3255,5986,0,1,0}-{3256,6008,0,1,0}-{3257,5973,0,1,0}-{3257,5975,0,1,0}-{3260,5974,0,1,0}-{3261,5977,0,1,0}-{3262,5957,0,1,0}-{2194,3158,0,1,0}-{2216,3188,0,1,0}-{2217,3190,0,1,0}-{2220,3158,0,1,0}-{2222,3141,0,1,0}-{2229,3138,0,1,0}-{2231,3181,0,1,0}-{2236,3155,0,1,0}-{2278,2956,0,1,0}-{2322,4566,0,1,0}-{2344,4596,0,1,0}-{2345,4598,0,1,0}-{2348,4566,0,1,0}-{2350,4549,0,1,0}-{2357,4546,0,1,0}-{2359,4589,0,1,0}-{2364,4563,0,1,0}-{2177,3234,0,1,0}-{2230,3220,0,1,0}-{2231,3234,0,1,0}-{2232,3256,0,1,0}-{2233,3221,0,1,0}-{2233,3223,0,1,0}-{2236,3222,0,1,0}-{2237,3225,0,1,0}-{2238,3205,0,1,0}-{2479,3396,0,1,0}-{2102,2942,0,1,0}-{2108,2919,0,1,0}-{2104,2873,0,1,0}-{2122,6032,0,1,0}-{1912,5945,0,1,0}-{3143,3210,0,1,0}-{3155,3253,0,1,0}-{3163,3261,0,1,0}-{3168,3258,0,1,0}-{2086,6028,0,1,0}-{2703,6160,0,1,0}-{2710,6154,0,1,0}-{2719,6148,0,1,0}-{2742,6163,0,1,0}-{2744,6150,0,1,0}-{2746,6145,0,1,0}-{2314,2960,0,1,0}-{2723,6105,0,1,0}-{2739,6123,0,1,0}-{2744,6108,0,1,0}-{2326,2894,0,1,0}-{2333,2920,0,1,0}-{3279,5968,0,1,0}-{3286,5962,0,1,0}-{3295,5956,0,1,0}-{3318,5971,0,1,0}-{3320,5958,0,1,0}-{3322,5953,0,1,0}-{2134,5966,0,1,0}-{2141,5992,0,1,0}-{2123,2966,0,1,0}-{2175,2965,0,1,0}-{1910,6014,0,1,0}-{1916,5991,0,1,0}-{2540,3167,0,1,0}-{2110,2955,0,1,0}-{1990,6051,0,1,0}-{2019,6035,0,1,0}-{2447,3467,0,1,0}-{2448,3469,0,1,0}-{1918,6027,0,1,0}-{2275,3161,0,1,0}-{2291,3179,0,1,0}-{2296,3164,0,1,0}-{2113,2859,0,1,0}-{2139,2836,0,1,0}-{2147,2877,0,1,0}-{2165,2816,0,1,0}-{2167,2846,0,1,0}-"
|
||||
"loc_data": "{2104,2873,0,1,0}-{2102,2942,0,1,0}-{2108,2919,0,1,0}-{2326,2894,0,1,0}-{2333,2920,0,1,0}-{2314,2960,0,1,0}-{2110,2955,0,1,0}-{2322,4566,0,1,0}-{2344,4596,0,1,0}-{2345,4598,0,1,0}-{2348,4566,0,1,0}-{2350,4549,0,1,0}-{2357,4546,0,1,0}-{2359,4589,0,1,0}-{2364,4563,0,1,0}-{2050,5860,0,1,0}-{2056,5930,0,1,0}-{2064,5900,0,1,0}-{2092,5946,0,1,0}-{2086,6028,0,1,0}-{2153,2810,0,1,0}-{2172,2806,0,1,0}-{2113,2859,0,1,0}-{2139,2836,0,1,0}-{2147,2877,0,1,0}-{2165,2816,0,1,0}-{2167,2846,0,1,0}-{2123,2966,0,1,0}-{2175,2965,0,1,0}-{3143,3210,0,1,0}-{3155,3253,0,1,0}-{3163,3261,0,1,0}-{3168,3258,0,1,0}-{1912,5945,0,1,0}-{2134,5966,0,1,0}-{2141,5992,0,1,0}-{1910,6014,0,1,0}-{1916,5991,0,1,0}-{2122,6032,0,1,0}-{1918,6027,0,1,0}-{2180,2798,0,1,0}-{2209,2812,0,1,0}-{2217,2780,0,1,0}-{2182,2979,0,1,0}-{2211,2963,0,1,0}-{2194,3158,0,1,0}-{2216,3188,0,1,0}-{2217,3190,0,1,0}-{2220,3158,0,1,0}-{2222,3141,0,1,0}-{2229,3138,0,1,0}-{2231,3181,0,1,0}-{2236,3155,0,1,0}-{2177,3234,0,1,0}-{2230,3220,0,1,0}-{2231,3234,0,1,0}-{2232,3256,0,1,0}-{2233,3221,0,1,0}-{2233,3223,0,1,0}-{2236,3222,0,1,0}-{2237,3225,0,1,0}-{2238,3205,0,1,0}-{2479,3396,0,1,0}-{2447,3467,0,1,0}-{2448,3469,0,1,0}-{1961,5882,0,1,0}-{1980,5878,0,1,0}-{1921,5931,0,1,0}-{1947,5908,0,1,0}-{1955,5949,0,1,0}-{1973,5888,0,1,0}-{1975,5918,0,1,0}-{3201,5986,0,1,0}-{3254,5972,0,1,0}-{3255,5986,0,1,0}-{3256,6008,0,1,0}-{3257,5973,0,1,0}-{3257,5975,0,1,0}-{3260,5974,0,1,0}-{3261,5977,0,1,0}-{3262,5957,0,1,0}-{1931,6038,0,1,0}-{1983,6037,0,1,0}-{2723,6105,0,1,0}-{2739,6123,0,1,0}-{2744,6108,0,1,0}-{2703,6160,0,1,0}-{2710,6154,0,1,0}-{2719,6148,0,1,0}-{2742,6163,0,1,0}-{2744,6150,0,1,0}-{2746,6145,0,1,0}-{2242,2788,0,1,0}-{2248,2858,0,1,0}-{2256,2828,0,1,0}-{2284,2874,0,1,0}-{2278,2956,0,1,0}-{2540,3167,0,1,0}-{2275,3161,0,1,0}-{2291,3179,0,1,0}-{2296,3164,0,1,0}-{2255,3216,0,1,0}-{2262,3210,0,1,0}-{2271,3204,0,1,0}-{2294,3219,0,1,0}-{2296,3206,0,1,0}-{2298,3201,0,1,0}-{1988,5870,0,1,0}-{2017,5884,0,1,0}-{2025,5852,0,1,0}-{3279,5968,0,1,0}-{3286,5962,0,1,0}-{3295,5956,0,1,0}-{3318,5971,0,1,0}-{3320,5958,0,1,0}-{3322,5953,0,1,0}-{1990,6051,0,1,0}-{2019,6035,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "158",
|
||||
|
|
@ -513,7 +513,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "159",
|
||||
"loc_data": "{2392,3475,0,1,0}-{2394,3506,0,1,0}-{2396,3471,0,1,0}-{2405,3499,0,1,0}-{2416,3487,0,1,0}-{2413,3445,1,1,0}-{2415,3435,1,1,0}-{2416,3416,1,1,0}-{2424,3434,1,1,0}-{2483,3500,1,1,0}-"
|
||||
"loc_data": "{2413,3445,1,1,0}-{2415,3435,1,1,0}-{2416,3416,1,1,0}-{2424,3434,1,1,0}-{2392,3475,0,1,0}-{2394,3506,0,1,0}-{2396,3471,0,1,0}-{2405,3499,0,1,0}-{2416,3487,0,1,0}-{2483,3500,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "160",
|
||||
|
|
@ -529,11 +529,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "163",
|
||||
"loc_data": "{2451,3414,0,1,0}-{2459,3395,0,1,0}-{2459,3438,0,1,0}-{2462,3395,0,1,0}-{2445,3429,1,1,0}-{2409,3470,1,1,0}-{2416,3466,1,1,0}-{2420,3466,1,1,0}-{2461,9895,0,1,0}-{2465,9894,0,1,0}-{2465,9899,0,1,0}-{2459,3385,0,1,0}-{2463,3385,0,1,0}-{2392,3454,0,1,0}-{2394,3436,0,1,0}-{2408,3452,0,1,0}-{2421,3413,0,1,0}-{2442,3489,0,1,0}-{2450,3485,0,1,0}-{2451,3507,0,1,0}-{2453,3490,0,1,0}-{2459,3503,0,1,0}-{2461,3509,0,1,0}-{2464,3465,0,1,0}-{2464,3468,0,1,0}-{2468,3465,0,1,0}-{2468,3468,0,1,0}-{2468,3506,0,1,0}-{2472,3484,0,1,0}-{2475,3490,0,1,0}-{2475,3502,0,1,0}-{2477,3512,0,1,0}-{2481,3485,0,1,0}-{2482,3501,0,1,0}-{2467,3495,1,1,0}-{2473,3495,1,1,0}-{2448,3497,2,1,0}-{2463,3480,2,1,0}-{2465,3497,2,1,0}-{2465,3510,2,1,0}-{2466,3480,2,1,0}-"
|
||||
"loc_data": "{2392,3454,0,1,0}-{2394,3436,0,1,0}-{2408,3452,0,1,0}-{2421,3413,0,1,0}-{2409,3470,1,1,0}-{2416,3466,1,1,0}-{2420,3466,1,1,0}-{2459,3385,0,1,0}-{2463,3385,0,1,0}-{2451,3414,0,1,0}-{2459,3395,0,1,0}-{2459,3438,0,1,0}-{2462,3395,0,1,0}-{2445,3429,1,1,0}-{2442,3489,0,1,0}-{2450,3485,0,1,0}-{2451,3507,0,1,0}-{2453,3490,0,1,0}-{2459,3503,0,1,0}-{2461,3509,0,1,0}-{2464,3465,0,1,0}-{2464,3468,0,1,0}-{2468,3465,0,1,0}-{2468,3468,0,1,0}-{2468,3506,0,1,0}-{2472,3484,0,1,0}-{2475,3490,0,1,0}-{2475,3502,0,1,0}-{2477,3512,0,1,0}-{2481,3485,0,1,0}-{2482,3501,0,1,0}-{2467,3495,1,1,0}-{2473,3495,1,1,0}-{2448,3497,2,1,0}-{2463,3480,2,1,0}-{2465,3497,2,1,0}-{2465,3510,2,1,0}-{2466,3480,2,1,0}-{2461,9895,0,1,0}-{2465,9894,0,1,0}-{2465,9899,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "164",
|
||||
"loc_data": "{2459,3392,0,1,0}-{2461,3422,0,1,0}-{2462,3392,0,1,0}-{2460,3382,0,1,0}-{2462,3382,0,1,0}-{2410,3416,0,1,0}-{2420,3435,0,1,0}-{2420,3447,0,1,0}-{2427,3410,0,1,0}-{2012,5535,2,1,0}-{2023,5544,2,1,0}-{2441,3497,0,1,0}-{2447,3510,0,1,0}-{2461,3487,0,1,0}-{2464,3472,0,1,0}-{2464,3489,0,1,0}-{2467,3489,0,1,0}-{2468,3472,0,1,0}-{2473,3503,0,1,0}-{2478,3497,0,1,0}-{2464,3496,1,1,0}-{2448,3495,2,1,0}-{2460,3487,2,1,0}-{2467,3494,2,1,0}-{2467,3510,2,1,0}-{2471,3496,2,1,0}-{2483,3495,2,1,0}-{2483,3497,2,1,0}-"
|
||||
"loc_data": "{2410,3416,0,1,0}-{2420,3435,0,1,0}-{2420,3447,0,1,0}-{2427,3410,0,1,0}-{2460,3382,0,1,0}-{2462,3382,0,1,0}-{2459,3392,0,1,0}-{2461,3422,0,1,0}-{2462,3392,0,1,0}-{2441,3497,0,1,0}-{2447,3510,0,1,0}-{2461,3487,0,1,0}-{2464,3472,0,1,0}-{2464,3489,0,1,0}-{2467,3489,0,1,0}-{2468,3472,0,1,0}-{2473,3503,0,1,0}-{2478,3497,0,1,0}-{2464,3496,1,1,0}-{2448,3495,2,1,0}-{2460,3487,2,1,0}-{2467,3494,2,1,0}-{2467,3510,2,1,0}-{2471,3496,2,1,0}-{2483,3495,2,1,0}-{2483,3497,2,1,0}-{2012,5535,2,1,0}-{2023,5544,2,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "166",
|
||||
|
|
@ -541,11 +541,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "168",
|
||||
"loc_data": "{2434,3436,0,1,0}-{2437,3451,0,1,0}-{2438,3427,0,1,0}-{2441,3411,0,1,0}-{2466,3449,0,1,0}-{2470,3399,0,1,0}-{2472,3400,0,1,0}-{2473,3412,0,1,0}-{2476,3454,0,1,0}-{2482,3397,0,1,0}-{2489,3401,0,1,0}-{2479,3407,1,1,0}-{2379,3482,0,1,0}-{2381,3496,0,1,0}-{2384,3497,0,1,0}-{2391,3476,0,1,0}-{2410,3496,0,1,0}-{2421,3481,0,1,0}-{2397,3514,1,1,0}-{2398,3451,1,1,0}-{2414,3447,1,1,0}-{2438,3465,0,1,0}-{2442,3505,0,1,0}-{2448,3486,0,1,0}-{2449,3487,0,1,0}-{2450,3489,0,1,0}-{2450,3505,0,1,0}-{2454,3465,0,1,0}-{2449,3486,1,1,0}-{2457,3488,1,1,0}-{2476,3488,1,1,0}-{2450,3496,2,1,0}-{2467,3488,2,1,0}-{2470,3503,2,1,0}-{2481,3498,2,1,0}-"
|
||||
"loc_data": "{2398,3451,1,1,0}-{2414,3447,1,1,0}-{2379,3482,0,1,0}-{2381,3496,0,1,0}-{2384,3497,0,1,0}-{2391,3476,0,1,0}-{2410,3496,0,1,0}-{2421,3481,0,1,0}-{2397,3514,1,1,0}-{2434,3436,0,1,0}-{2437,3451,0,1,0}-{2438,3427,0,1,0}-{2441,3411,0,1,0}-{2466,3449,0,1,0}-{2470,3399,0,1,0}-{2472,3400,0,1,0}-{2473,3412,0,1,0}-{2476,3454,0,1,0}-{2482,3397,0,1,0}-{2489,3401,0,1,0}-{2479,3407,1,1,0}-{2438,3465,0,1,0}-{2442,3505,0,1,0}-{2448,3486,0,1,0}-{2449,3487,0,1,0}-{2450,3489,0,1,0}-{2450,3505,0,1,0}-{2454,3465,0,1,0}-{2449,3486,1,1,0}-{2457,3488,1,1,0}-{2476,3488,1,1,0}-{2450,3496,2,1,0}-{2467,3488,2,1,0}-{2470,3503,2,1,0}-{2481,3498,2,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "169",
|
||||
"loc_data": "{2439,3433,0,1,0}-{2441,3449,0,1,0}-{2442,3428,0,1,0}-{2446,3403,0,1,0}-{2450,3416,0,1,0}-{2468,3441,0,1,0}-{2480,3408,0,1,0}-{2480,3406,1,1,0}-{2486,3400,1,1,0}-{2378,3482,0,1,0}-{2383,3496,0,1,0}-{2402,3507,0,1,0}-{2406,3476,0,1,0}-{2422,3485,0,1,0}-{2382,3506,1,1,0}-{2418,3472,1,1,0}-{2392,3450,1,1,0}-{2415,3415,1,1,0}-{2416,3434,1,1,0}-{2423,3425,1,1,0}-{2424,3442,1,1,0}-{2448,3489,0,1,0}-{2450,3488,0,1,0}-{2463,3508,0,1,0}-{2473,3489,0,1,0}-{2474,3457,0,1,0}-{2479,3503,0,1,0}-{2486,3467,0,1,0}-{2437,3463,1,1,0}-{2448,3489,1,1,0}-{2482,3508,1,1,0}-"
|
||||
"loc_data": "{2392,3450,1,1,0}-{2415,3415,1,1,0}-{2416,3434,1,1,0}-{2423,3425,1,1,0}-{2424,3442,1,1,0}-{2378,3482,0,1,0}-{2383,3496,0,1,0}-{2402,3507,0,1,0}-{2406,3476,0,1,0}-{2422,3485,0,1,0}-{2382,3506,1,1,0}-{2418,3472,1,1,0}-{2439,3433,0,1,0}-{2441,3449,0,1,0}-{2442,3428,0,1,0}-{2446,3403,0,1,0}-{2450,3416,0,1,0}-{2468,3441,0,1,0}-{2480,3408,0,1,0}-{2480,3406,1,1,0}-{2486,3400,1,1,0}-{2448,3489,0,1,0}-{2450,3488,0,1,0}-{2463,3508,0,1,0}-{2473,3489,0,1,0}-{2474,3457,0,1,0}-{2479,3503,0,1,0}-{2486,3467,0,1,0}-{2437,3463,1,1,0}-{2448,3489,1,1,0}-{2482,3508,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "170",
|
||||
|
|
@ -849,7 +849,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "278",
|
||||
"loc_data": "{3209,3215,0,0,0}-"
|
||||
"loc_data": "{3209,3215,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "279",
|
||||
|
|
@ -1357,11 +1357,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "479",
|
||||
"loc_data": "{1970,5522,3,1,0}-{2384,3481,0,1,0}-{2388,3473,0,1,0}-{2418,3474,3,1,0}-{2415,3433,3,1,0}-{2466,3500,2,1,0}-"
|
||||
"loc_data": "{2415,3433,3,1,0}-{2384,3481,0,1,0}-{2388,3473,0,1,0}-{2418,3474,3,1,0}-{2466,3500,2,1,0}-{1970,5522,3,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "480",
|
||||
"loc_data": "{1964,5522,3,1,0}-{2458,3417,1,1,0}-{2460,3417,1,1,0}-{2409,3507,0,1,0}-{2412,3474,3,1,0}-{2463,3504,2,1,0}-"
|
||||
"loc_data": "{2409,3507,0,1,0}-{2412,3474,3,1,0}-{2458,3417,1,1,0}-{2460,3417,1,1,0}-{2463,3504,2,1,0}-{1964,5522,3,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "481",
|
||||
|
|
@ -1387,6 +1387,10 @@
|
|||
"npc_id": "490",
|
||||
"loc_data": "{1887,5026,0,0,6}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "492",
|
||||
"loc_data": "{2464,3227,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "494",
|
||||
"loc_data": "{2615,3094,0,0,3}-{2615,3092,0,0,3}-{2615,3092,0,0,3}-{2615,3094,0,0,3}-{3122,3125,0,0,6}-{3120,3125,0,0,6}-{3090,3242,0,0,4}-{3090,3245,0,0,4}-{3090,3243,0,0,4}-{2618,3330,0,0,0}-{2619,3330,0,0,0}-{2584,3422,0,0,4}-{2584,3419,0,0,4}-{2584,3418,0,0,4}-{2657,3283,0,0,3}-{2657,3286,0,0,3}-{2807,3443,0,0,6}-{2810,3443,0,0,6}-"
|
||||
|
|
@ -2433,11 +2437,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "839",
|
||||
"loc_data": "{3265,3066,0,1,0}-{3267,3066,0,1,0}-{3310,3068,0,1,0}-{3322,3011,0,1,0}-{3322,3052,0,1,0}-{3324,3030,0,1,0}-{3150,3044,0,1,0}-{3172,3009,0,1,0}-{3197,3012,0,1,0}-{3198,3040,0,1,0}-{3217,3092,0,1,0}-{3235,3074,0,1,0}-{3252,3125,0,1,0}-{3258,3078,0,1,0}-{3237,2968,0,1,0}-{3224,3013,0,1,0}-{3225,3034,0,1,0}-{3226,3060,0,1,0}-{3250,3057,0,1,0}-{3283,3108,0,1,0}-{3323,3094,0,1,0}-"
|
||||
"loc_data": "{3150,3044,0,1,0}-{3172,3009,0,1,0}-{3197,3012,0,1,0}-{3198,3040,0,1,0}-{3237,2968,0,1,0}-{3224,3013,0,1,0}-{3225,3034,0,1,0}-{3226,3060,0,1,0}-{3250,3057,0,1,0}-{3217,3092,0,1,0}-{3235,3074,0,1,0}-{3252,3125,0,1,0}-{3258,3078,0,1,0}-{3265,3066,0,1,0}-{3267,3066,0,1,0}-{3310,3068,0,1,0}-{3322,3011,0,1,0}-{3322,3052,0,1,0}-{3324,3030,0,1,0}-{3283,3108,0,1,0}-{3323,3094,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "840",
|
||||
"loc_data": "{3268,3052,0,1,0}-{3281,3056,0,1,0}-{3307,3055,0,1,0}-{3318,3020,0,1,0}-{3318,3040,0,1,0}-{3190,3054,0,1,0}-{3192,3016,0,1,0}-{3217,3111,0,1,0}-{3222,3086,0,1,0}-{3238,3101,0,1,0}-{3244,3080,0,1,0}-{3253,3116,0,1,0}-{3255,3095,0,1,0}-{3237,3000,0,1,0}-{3245,2960,0,1,0}-{3208,3032,0,1,0}-{3217,3064,0,1,0}-{3238,3015,0,1,0}-{3258,3063,0,1,0}-{3267,3077,0,1,0}-{3269,3110,0,1,0}-{3275,3094,0,1,0}-{3291,3078,0,1,0}-{3291,3100,0,1,0}-{3305,3089,0,1,0}-{3318,3078,0,1,0}-{3321,3104,0,1,0}-"
|
||||
"loc_data": "{3190,3054,0,1,0}-{3192,3016,0,1,0}-{3237,3000,0,1,0}-{3245,2960,0,1,0}-{3208,3032,0,1,0}-{3217,3064,0,1,0}-{3238,3015,0,1,0}-{3258,3063,0,1,0}-{3217,3111,0,1,0}-{3222,3086,0,1,0}-{3238,3101,0,1,0}-{3244,3080,0,1,0}-{3253,3116,0,1,0}-{3255,3095,0,1,0}-{3268,3052,0,1,0}-{3281,3056,0,1,0}-{3307,3055,0,1,0}-{3318,3020,0,1,0}-{3318,3040,0,1,0}-{3267,3077,0,1,0}-{3269,3110,0,1,0}-{3275,3094,0,1,0}-{3291,3078,0,1,0}-{3291,3100,0,1,0}-{3305,3089,0,1,0}-{3318,3078,0,1,0}-{3321,3104,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "841",
|
||||
|
|
@ -2777,11 +2781,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1017",
|
||||
"loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-"
|
||||
"loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{3198,3355,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1019",
|
||||
"loc_data": "{3187,5555,0,1,4}-{3190,5563,0,1,1}-{3193,5555,0,1,3} -{3213,9377,0,1,3}-{3209,9397,0,1,4}-{3245,9401,0,1,6}- {3237,9402,0,1,2}-{3207,9349,0,1,3}-{3220,9347,0,1,6} -{3233,9359,0,1,4}-{3235,9354,0,0,6}-{3259,9370,0,1,1}- {3258,9387,0,1,6}-{2707,9880,0,1,0}-{2711,9876,0,1,0}- {2712,9871,0,1,0}-{2715,9874,0,1,0}-{2720,9871,0,1,0} -{2717,9880,0,1,0}-{2722,9879,0,1,0}-{2723,9875,0,1,0}- {3278,9368,0,1,5}-{3271,9359,0,1,3}-{3287,9359,0,1,5}- {3301,9394,0,1,5}-{3318,9352,0,1,5}-"
|
||||
"loc_data": "{3187,5555,0,1,4}-{3190,5563,0,1,1}-{3193,5555,0,1,3}-{3213,9377,0,1,3}-{3209,9397,0,1,4}-{3245,9401,0,1,6}-{3237,9402,0,1,2}-{3207,9349,0,1,3}-{3220,9347,0,1,6}-{3233,9359,0,1,4}-{3235,9354,0,0,6}-{3259,9370,0,1,1}-{3258,9387,0,1,6}-{2707,9880,0,1,0}-{2711,9876,0,1,0}-{2712,9871,0,1,0}-{2715,9874,0,1,0}-{2720,9871,0,1,0}-{2717,9880,0,1,0}-{2722,9879,0,1,0}-{2723,9875,0,1,0}-{3278,9368,0,1,5}-{3271,9359,0,1,3}-{3287,9359,0,1,5}-{3301,9394,0,1,5}-{3318,9352,0,1,5}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1020",
|
||||
|
|
@ -2809,11 +2813,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1038",
|
||||
"loc_data": "{3507,3496,1,1,1}-{3508,3494,0,1,1}-"
|
||||
"loc_data": "{3508,3494,0,1,1}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1039",
|
||||
"loc_data": "{3499,3506,1,1,5}-{3500,3505,0,1,5}-"
|
||||
"loc_data": "{3500,3505,0,1,5}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1040",
|
||||
|
|
@ -2821,7 +2825,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1041",
|
||||
"loc_data": "{3490,3503,1,0,0}-{3490,3500,0,1,4}-"
|
||||
"loc_data": "{3490,3500,0,1,4}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1042",
|
||||
|
|
@ -2829,7 +2833,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1043",
|
||||
"loc_data": "{3726,3381,0,0,0}-{3745,3359,0,0,0}-{3749,3365,0,0,0}-{3750,3354,0,0,0}-{3757,3363,0,0,0}-{3763,3337,0,0,0}-{3459,3457,0,0,0}-{3460,3462,0,0,0}-{3462,3459,0,0,0}-{3463,3490,0,0,0}-{3464,3511,0,0,0}-{3465,3466,0,0,0}-{3466,3495,0,0,0}-{3466,3497,0,0,0}-{3467,3485,0,0,0}-{3467,3497,0,0,0}-{3467,3509,0,0,0}-{3469,3470,0,0,0}-{3470,3469,0,0,0}-{3471,3477,0,0,0}-{3474,3505,0,0,0}-{3476,3507,0,0,0}-{3479,3511,0,0,0}-{3480,3468,0,0,0}-{3480,3470,0,0,0}-{3482,3469,0,0,0}-{3483,3511,0,0,0}-{3484,3464,0,0,0}-{3485,3509,0,0,0}-{3490,3461,0,0,0}-{3491,3460,0,0,0}-{3494,3461,0,0,0}-{3494,3512,0,0,0}-{3498,3461,0,0,0}-{3499,3513,0,0,0}-{3501,3513,0,0,0}-{3502,3464,0,0,0}-{3504,3463,0,0,0}-{3506,3512,0,0,0}-{3506,3515,0,0,0}-{3507,3515,0,0,0}-{3509,3512,0,0,0}-{3511,3488,0,0,0}-{3513,3467,0,0,0}-{3513,3487,0,0,0}-{3513,3489,0,0,0}-{3513,3503,0,0,0}-{3514,3490,0,0,0}-{3515,3495,0,0,0}-{3515,3499,0,0,0}-{3516,3469,0,0,0}-{3409,3369,0,0,0}-{3420,3349,0,0,0}-{3430,3340,0,0,0}-{3435,3330,0,0,0}-{3435,3359,0,0,0}-{3437,3374,0,0,0}-{3446,3385,0,0,0}-{3447,3388,0,0,0}-{3450,3370,0,0,0}-{3450,3387,0,0,0}-{3451,3336,0,0,0}-{3452,3355,0,0,0}-{3726,3289,0,0,0}-{3732,3291,0,0,0}-{3737,3280,0,0,0}-{3745,3285,0,0,0}-{3418,3420,0,0,0}-{3424,3452,0,0,0}-{3428,3409,0,0,0}-{3433,3416,0,0,0}-{3434,3394,0,0,0}-{3436,3407,0,0,0}-{3438,3414,0,0,0}-{3439,3449,0,0,0}-{3446,3439,0,0,0}-{3454,3410,0,0,0}-{3454,3423,0,0,0}-{2852,4561,0,0,0}-{2853,4566,0,0,0}-{2856,4568,0,0,0}-{2864,4561,0,0,0}-{2864,4563,0,0,0}-"
|
||||
"loc_data": "{2852,4561,0,0,0}-{2853,4566,0,0,0}-{2856,4568,0,0,0}-{2864,4561,0,0,0}-{2864,4563,0,0,0}-{3409,3369,0,0,0}-{3420,3349,0,0,0}-{3430,3340,0,0,0}-{3435,3330,0,0,0}-{3435,3359,0,0,0}-{3437,3374,0,0,0}-{3446,3385,0,0,0}-{3447,3388,0,0,0}-{3450,3370,0,0,0}-{3450,3387,0,0,0}-{3451,3336,0,0,0}-{3452,3355,0,0,0}-{3418,3420,0,0,0}-{3424,3452,0,0,0}-{3428,3409,0,0,0}-{3433,3416,0,0,0}-{3434,3394,0,0,0}-{3436,3407,0,0,0}-{3438,3414,0,0,0}-{3439,3449,0,0,0}-{3446,3439,0,0,0}-{3454,3410,0,0,0}-{3454,3423,0,0,0}-{3726,3289,0,0,0}-{3732,3291,0,0,0}-{3737,3280,0,0,0}-{3745,3285,0,0,0}-{3726,3381,0,0,0}-{3745,3359,0,0,0}-{3749,3365,0,0,0}-{3750,3354,0,0,0}-{3757,3363,0,0,0}-{3763,3337,0,0,0}-{3459,3457,0,0,0}-{3460,3462,0,0,0}-{3462,3459,0,0,0}-{3463,3490,0,0,0}-{3464,3511,0,0,0}-{3465,3466,0,0,0}-{3466,3495,0,0,0}-{3466,3497,0,0,0}-{3467,3485,0,0,0}-{3467,3497,0,0,0}-{3467,3509,0,0,0}-{3469,3470,0,0,0}-{3470,3469,0,0,0}-{3471,3477,0,0,0}-{3474,3505,0,0,0}-{3476,3507,0,0,0}-{3479,3511,0,0,0}-{3480,3468,0,0,0}-{3480,3470,0,0,0}-{3482,3469,0,0,0}-{3483,3511,0,0,0}-{3484,3464,0,0,0}-{3485,3509,0,0,0}-{3490,3461,0,0,0}-{3491,3460,0,0,0}-{3494,3461,0,0,0}-{3494,3512,0,0,0}-{3498,3461,0,0,0}-{3499,3513,0,0,0}-{3501,3513,0,0,0}-{3502,3464,0,0,0}-{3504,3463,0,0,0}-{3506,3512,0,0,0}-{3506,3515,0,0,0}-{3507,3515,0,0,0}-{3509,3512,0,0,0}-{3511,3488,0,0,0}-{3513,3467,0,0,0}-{3513,3487,0,0,0}-{3513,3489,0,0,0}-{3513,3503,0,0,0}-{3514,3490,0,0,0}-{3515,3495,0,0,0}-{3515,3499,0,0,0}-{3516,3469,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1044",
|
||||
|
|
@ -3345,11 +3349,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1212",
|
||||
"loc_data": "{2247,3226,0,0,0}-{2249,3227,0,0,0}-{2249,3258,0,0,0}-{2251,3260,0,0,0}-{2259,3211,0,0,0}-{2267,3223,0,0,0}-{2267,3225,0,0,0}-{2298,3262,0,0,0}-{3202,5990,0,0,0}-{3232,5977,0,0,0}-{3234,5969,0,0,0}-{3237,5995,0,0,0}-{3242,5997,0,0,0}-{3244,5995,0,0,0}-{3245,5995,0,0,0}-{2194,3189,0,0,0}-{2196,3187,0,0,0}-{2196,3189,0,0,0}-{2206,3164,0,0,0}-{2209,3164,0,0,0}-{2216,3142,0,0,0}-{2218,3139,0,0,0}-{2178,3238,0,0,0}-{2208,3225,0,0,0}-{2210,3217,0,0,0}-{2213,3243,0,0,0}-{2218,3245,0,0,0}-{2220,3243,0,0,0}-{2221,3243,0,0,0}-{2695,6170,0,0,0}-{2697,6171,0,0,0}-{2697,6202,0,0,0}-{2699,6204,0,0,0}-{2707,6155,0,0,0}-{2715,6167,0,0,0}-{2715,6169,0,0,0}-{2746,6206,0,0,0}-{2729,6086,0,0,0}-{2731,6080,0,0,0}-{2731,6089,0,0,0}-{2744,6139,0,0,0}-{3271,5978,0,0,0}-{3273,5979,0,0,0}-{3273,6010,0,0,0}-{3275,6012,0,0,0}-{3283,5963,0,0,0}-{3291,5975,0,0,0}-{3291,5977,0,0,0}-{3322,6014,0,0,0}-{2281,3142,0,0,0}-{2283,3136,0,0,0}-{2283,3145,0,0,0}-{2296,3195,0,0,0}-"
|
||||
"loc_data": "{2194,3189,0,0,0}-{2196,3187,0,0,0}-{2196,3189,0,0,0}-{2206,3164,0,0,0}-{2209,3164,0,0,0}-{2216,3142,0,0,0}-{2218,3139,0,0,0}-{2178,3238,0,0,0}-{2208,3225,0,0,0}-{2210,3217,0,0,0}-{2213,3243,0,0,0}-{2218,3245,0,0,0}-{2220,3243,0,0,0}-{2221,3243,0,0,0}-{3202,5990,0,0,0}-{3232,5977,0,0,0}-{3234,5969,0,0,0}-{3237,5995,0,0,0}-{3242,5997,0,0,0}-{3244,5995,0,0,0}-{3245,5995,0,0,0}-{2729,6086,0,0,0}-{2731,6080,0,0,0}-{2731,6089,0,0,0}-{2744,6139,0,0,0}-{2695,6170,0,0,0}-{2697,6171,0,0,0}-{2697,6202,0,0,0}-{2699,6204,0,0,0}-{2707,6155,0,0,0}-{2715,6167,0,0,0}-{2715,6169,0,0,0}-{2746,6206,0,0,0}-{2281,3142,0,0,0}-{2283,3136,0,0,0}-{2283,3145,0,0,0}-{2296,3195,0,0,0}-{2247,3226,0,0,0}-{2249,3227,0,0,0}-{2249,3258,0,0,0}-{2251,3260,0,0,0}-{2259,3211,0,0,0}-{2267,3223,0,0,0}-{2267,3225,0,0,0}-{2298,3262,0,0,0}-{3271,5978,0,0,0}-{3273,5979,0,0,0}-{3273,6010,0,0,0}-{3275,6012,0,0,0}-{3283,5963,0,0,0}-{3291,5975,0,0,0}-{3291,5977,0,0,0}-{3322,6014,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1213",
|
||||
"loc_data": "{2248,3225,0,0,0}-{2248,3227,0,0,0}-{2251,3257,0,0,0}-{2253,3259,0,0,0}-{2268,3224,0,0,0}-{2291,3262,0,0,0}-{3204,5988,0,0,0}-{3232,5979,0,0,0}-{3234,5967,0,0,0}-{3234,5976,0,0,0}-{3238,5996,0,0,0}-{3239,5997,0,0,0}-{3243,5996,0,0,0}-{2192,3188,0,0,0}-{2192,3191,0,0,0}-{2194,3190,0,0,0}-{2208,3163,0,0,0}-{2209,3163,0,0,0}-{2216,3136,0,0,0}-{2216,3140,0,0,0}-{2180,3236,0,0,0}-{2208,3227,0,0,0}-{2210,3215,0,0,0}-{2210,3224,0,0,0}-{2214,3244,0,0,0}-{2215,3245,0,0,0}-{2219,3244,0,0,0}-{2696,6169,0,0,0}-{2696,6171,0,0,0}-{2699,6201,0,0,0}-{2701,6203,0,0,0}-{2716,6168,0,0,0}-{2739,6206,0,0,0}-{2730,6084,0,0,0}-{3272,5977,0,0,0}-{3272,5979,0,0,0}-{3275,6009,0,0,0}-{3277,6011,0,0,0}-{3292,5976,0,0,0}-{3315,6014,0,0,0}-{2282,3140,0,0,0}-"
|
||||
"loc_data": "{2192,3188,0,0,0}-{2192,3191,0,0,0}-{2194,3190,0,0,0}-{2208,3163,0,0,0}-{2209,3163,0,0,0}-{2216,3136,0,0,0}-{2216,3140,0,0,0}-{2180,3236,0,0,0}-{2208,3227,0,0,0}-{2210,3215,0,0,0}-{2210,3224,0,0,0}-{2214,3244,0,0,0}-{2215,3245,0,0,0}-{2219,3244,0,0,0}-{3204,5988,0,0,0}-{3232,5979,0,0,0}-{3234,5967,0,0,0}-{3234,5976,0,0,0}-{3238,5996,0,0,0}-{3239,5997,0,0,0}-{3243,5996,0,0,0}-{2730,6084,0,0,0}-{2696,6169,0,0,0}-{2696,6171,0,0,0}-{2699,6201,0,0,0}-{2701,6203,0,0,0}-{2716,6168,0,0,0}-{2739,6206,0,0,0}-{2282,3140,0,0,0}-{2248,3225,0,0,0}-{2248,3227,0,0,0}-{2251,3257,0,0,0}-{2253,3259,0,0,0}-{2268,3224,0,0,0}-{2291,3262,0,0,0}-{3272,5977,0,0,0}-{3272,5979,0,0,0}-{3275,6009,0,0,0}-{3277,6011,0,0,0}-{3292,5976,0,0,0}-{3315,6014,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1214",
|
||||
|
|
@ -3771,6 +3775,10 @@
|
|||
"npc_id": "1427",
|
||||
"loc_data": "{2957,3025,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1433",
|
||||
"loc_data": "{2770,2789,0,1,6}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1434",
|
||||
"loc_data": "{2753,2770,0,1,6}-"
|
||||
|
|
@ -4057,7 +4065,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1633",
|
||||
"loc_data": "{1837,3244,0,1,0}-{1836,3250,0,1,0}-{1845,3251,0,1,0}-{1845,3247,0,1,0}-{1849,3241,0,1,0}-{1853,3247,0,1,0}-{1848,3254,0,1,0}-{1858,3251,0,1,0}-{1935,3217,0,1,0}-{1933,3209,0,1,0}-{1930,3208,0,1,0}-{1929,3217,0,1,0}-{1927,3219,0,1,0}-{1924,3211,0,1,0}-{1920,3216,0,1,0}-{1925,3213,0,1,0}-{3263,9399,0,1,3}-{3274,9397,0,1,1}-{3275,9393,0,1,6}-{3271,9384,0,1,0}-{3270,9380,0,1,2}-{3283,9378,0,1,6}-{3285,9386,0,1,5}-{3284,9401,0,1,4}-{3278,9353,0,1,1}-{3299,9380,0,1,1}-{3319,9402,0,1,1}-{3305,9350,0,1,4}-{3248,9374,0,1,3}-{3253,9363,0,1,3}-{3249,9355,0,1,3}-{2761,10007,0,1,0}-{2757,10010,0,1,3}-{2763,10000,0,1,5}-{2760,10011,0,1,0}-{2761,9997,0,1,4}-"
|
||||
"loc_data": "{1837,3244,0,1,0}-{1836,3250,0,1,0}-{1845,3251,0,1,0}-{1845,3247,0,1,0}-{1849,3241,0,1,0}-{1853,3247,0,1,0}-{1848,3254,0,1,0}-{1858,3251,0,1,0}-{1935,3217,0,1,0}-{1933,3209,0,1,0}-{1930,3208,0,1,0}-{1929,3217,0,1,0}-{1927,3219,0,1,0}-{1924,3211,0,1,0}-{1920,3216,0,1,0}-{1925,3213,0,1,0}-{3263,9399,0,1,3}-{3248,9374,0,1,3}-{3253,9363,0,1,3}-{3249,9355,0,1,3}-{3274,9397,0,1,1}-{3275,9393,0,1,6}-{3271,9384,0,1,0}-{3270,9380,0,1,2}-{3283,9378,0,1,6}-{3285,9386,0,1,5}-{3284,9401,0,1,4}-{3278,9353,0,1,1}-{3299,9380,0,1,1}-{3319,9402,0,1,1}-{3305,9350,0,1,4}-{2761,10007,0,1,0}-{2757,10010,0,1,3}-{2763,10000,0,1,5}-{2760,10011,0,1,0}-{2761,9997,0,1,4}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1634",
|
||||
|
|
@ -4257,7 +4265,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1752",
|
||||
"loc_data": "{2437,3442,0,1,0}-{2449,3421,0,1,0}-{2457,3394,0,1,0}-{2464,3394,0,1,0}-{2480,3406,0,1,0}-{2432,3387,0,1,0}-{2442,3388,0,1,0}-{2453,3363,0,1,0}-{2463,3375,0,1,0}-{2381,3428,0,1,0}-{2392,3405,0,1,0}-{2413,3397,0,1,0}-{2415,3408,0,1,0}-{2463,3456,0,1,0}-{2468,3456,0,1,0}-"
|
||||
"loc_data": "{2381,3428,0,1,0}-{2392,3405,0,1,0}-{2413,3397,0,1,0}-{2415,3408,0,1,0}-{2432,3387,0,1,0}-{2442,3388,0,1,0}-{2453,3363,0,1,0}-{2463,3375,0,1,0}-{2437,3442,0,1,0}-{2449,3421,0,1,0}-{2457,3394,0,1,0}-{2464,3394,0,1,0}-{2480,3406,0,1,0}-{2463,3456,0,1,0}-{2468,3456,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1754",
|
||||
|
|
@ -4541,7 +4549,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1874",
|
||||
"loc_data": "{3371,9301,0,1,0}-{3371,9303,0,1,0}-{3371,9305,0,1,0}-{3371,9307,0,1,0}-{3371,9309,0,1,0}-{3373,9301,0,1,0}-{3373,9303,0,1,0}-{3373,9306,0,1,0}-{3373,9308,0,1,0}-{3375,9301,0,1,0}-{3375,9303,0,1,0}-{3375,9305,0,1,0}-{3375,9307,0,1,0}-{3375,9309,0,1,0}-{3403,2963,0,1,0}-{3429,2976,0,1,0}-{3328,2952,0,1,0}-{3328,2957,0,1,0}-{3331,2955,0,1,0}-{3331,2961,0,1,0}-{3266,2955,0,1,0}-{3271,2967,0,1,0}-{3279,2957,0,1,0}-{3280,2975,0,1,0}-{3284,2959,0,1,0}-{3294,2964,0,1,0}-{3295,2978,0,1,0}-{3305,2966,0,1,0}-{3307,2959,0,1,0}-{3309,2973,0,1,0}-{3396,3029,0,1,0}-{3397,3044,0,1,0}-{3398,3038,0,1,0}-"
|
||||
"loc_data": "{3328,2952,0,1,0}-{3328,2957,0,1,0}-{3331,2955,0,1,0}-{3331,2961,0,1,0}-{3371,9301,0,1,0}-{3371,9303,0,1,0}-{3371,9305,0,1,0}-{3371,9307,0,1,0}-{3371,9309,0,1,0}-{3373,9301,0,1,0}-{3373,9303,0,1,0}-{3373,9306,0,1,0}-{3373,9308,0,1,0}-{3375,9301,0,1,0}-{3375,9303,0,1,0}-{3375,9305,0,1,0}-{3375,9307,0,1,0}-{3375,9309,0,1,0}-{3403,2963,0,1,0}-{3429,2976,0,1,0}-{3396,3029,0,1,0}-{3397,3044,0,1,0}-{3398,3038,0,1,0}-{3266,2955,0,1,0}-{3271,2967,0,1,0}-{3279,2957,0,1,0}-{3280,2975,0,1,0}-{3284,2959,0,1,0}-{3294,2964,0,1,0}-{3295,2978,0,1,0}-{3305,2966,0,1,0}-{3307,2959,0,1,0}-{3309,2973,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1875",
|
||||
|
|
@ -4701,19 +4709,19 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1961",
|
||||
"loc_data": "{3156,5477,0,1,5}-{3162,5479,0,1,4}-{3159,5477,0,1,6}-{3150,5474,0,1,3}-{3147,5480,0,1,1}-{3159,5484,0,1,3}-{2764,4944,1,1,0}-{2796,4976,1,1,0}-{2798,4950,1,1,0}-{2806,4939,1,1,0}-{2832,4959,2,1,0}-{3201,9293,0,1,0}-{3205,9303,0,1,0}-{3206,9328,0,1,0}-{3207,9310,0,1,0}-{3211,9284,0,1,0}-{3220,9289,0,1,0}-{3224,9334,0,1,0}-{3249,9286,0,1,0}-{3251,9303,0,1,0}-{3252,9327,0,1,0}-{3252,9332,0,1,0}-{3255,9315,0,1,0}-{3261,9296,0,1,0}-{3261,9306,0,1,0}-"
|
||||
"loc_data": "{2832,4959,2,1,0}-{3156,5477,0,1,5}-{3162,5479,0,1,4}-{3159,5477,0,1,6}-{3150,5474,0,1,3}-{3147,5480,0,1,1}-{3159,5484,0,1,3}-{3201,9293,0,1,0}-{3205,9303,0,1,0}-{3206,9328,0,1,0}-{3207,9310,0,1,0}-{3211,9284,0,1,0}-{3220,9289,0,1,0}-{3224,9334,0,1,0}-{3249,9286,0,1,0}-{3251,9303,0,1,0}-{3252,9327,0,1,0}-{3252,9332,0,1,0}-{3255,9315,0,1,0}-{3261,9296,0,1,0}-{3261,9306,0,1,0}-{2764,4944,1,1,0}-{2796,4976,1,1,0}-{2798,4950,1,1,0}-{2806,4939,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1962",
|
||||
"loc_data": "{3168,5458,0,1,2}-{2900,4948,3,1,0}-{2762,4962,1,1,0}-{2763,4973,1,1,0}-{2780,4977,1,1,0}-{2787,4967,1,1,0}-{2796,4959,1,1,0}-{2838,4948,2,1,0}-{3205,9329,0,1,0}-{3210,9292,0,1,0}-{3221,9310,0,1,0}-{3225,9323,0,1,0}-{3243,9310,0,1,0}-{3246,9290,0,1,0}-{3255,9301,0,1,0}-{3255,9321,0,1,0}-{3261,9331,0,1,0}-"
|
||||
"loc_data": "{2838,4948,2,1,0}-{2900,4948,3,1,0}-{3168,5458,0,1,2}-{3205,9329,0,1,0}-{3210,9292,0,1,0}-{3221,9310,0,1,0}-{3225,9323,0,1,0}-{3243,9310,0,1,0}-{3246,9290,0,1,0}-{3255,9301,0,1,0}-{3255,9321,0,1,0}-{3261,9331,0,1,0}-{2762,4962,1,1,0}-{2763,4973,1,1,0}-{2780,4977,1,1,0}-{2787,4967,1,1,0}-{2796,4959,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1963",
|
||||
"loc_data": "{3166,5465,0,1,7}-{3168,5462,0,1,0}-{3167,5467,0,1,1}-{3167,5467,0,1,7}-{2926,4965,3,1,0}-{2771,4947,1,1,0}-{2775,4963,1,1,0}-{2781,4948,1,1,0}-{2792,4942,1,1,0}-{2798,4954,1,1,0}-{2858,4964,2,1,0}-{3204,9309,0,1,0}-{3214,9333,0,1,0}-{3219,9297,0,1,0}-{3239,9300,0,1,0}-{3240,9286,0,1,0}-{3240,9330,0,1,0}-{3245,9306,0,1,0}-{3250,9316,0,1,0}-{3250,9317,0,1,0}-{3257,9290,0,1,0}-"
|
||||
"loc_data": "{2858,4964,2,1,0}-{2926,4965,3,1,0}-{3166,5465,0,1,7}-{3168,5462,0,1,0}-{3167,5467,0,1,1}-{3167,5467,0,1,7}-{3204,9309,0,1,0}-{3214,9333,0,1,0}-{3219,9297,0,1,0}-{3239,9300,0,1,0}-{3240,9286,0,1,0}-{3240,9330,0,1,0}-{3245,9306,0,1,0}-{3250,9316,0,1,0}-{3250,9317,0,1,0}-{3257,9290,0,1,0}-{2771,4947,1,1,0}-{2775,4963,1,1,0}-{2781,4948,1,1,0}-{2792,4942,1,1,0}-{2798,4954,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1964",
|
||||
"loc_data": "{2761,4950,1,1,0}-{2765,4938,1,1,0}-{2770,4955,1,1,0}-{2772,4940,1,1,0}-{2777,4943,1,1,0}-{2782,4967,1,1,0}-{2797,4965,1,1,0}-{2799,4937,1,1,0}-{2799,4941,1,1,0}-{2807,4968,1,1,0}-{2808,4975,1,1,0}-{2809,4953,1,1,0}-{2864,4946,2,1,0}-{3202,9283,0,1,0}-{3206,9333,0,1,0}-{3209,9299,0,1,0}-{3219,9301,0,1,0}-{3226,9285,0,1,0}-{3227,9303,0,1,0}-{3228,9293,0,1,0}-{3229,9333,0,1,0}-{3237,9293,0,1,0}-{3246,9321,0,1,0}-{3256,9296,0,1,0}-{3260,9285,0,1,0}-{3262,9317,0,1,0}-"
|
||||
"loc_data": "{2864,4946,2,1,0}-{3202,9283,0,1,0}-{3206,9333,0,1,0}-{3209,9299,0,1,0}-{3219,9301,0,1,0}-{3226,9285,0,1,0}-{3227,9303,0,1,0}-{3228,9293,0,1,0}-{3229,9333,0,1,0}-{3237,9293,0,1,0}-{3246,9321,0,1,0}-{3256,9296,0,1,0}-{3260,9285,0,1,0}-{3262,9317,0,1,0}-{2761,4950,1,1,0}-{2765,4938,1,1,0}-{2770,4955,1,1,0}-{2772,4940,1,1,0}-{2777,4943,1,1,0}-{2782,4967,1,1,0}-{2797,4965,1,1,0}-{2799,4937,1,1,0}-{2799,4941,1,1,0}-{2807,4968,1,1,0}-{2808,4975,1,1,0}-{2809,4953,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1970",
|
||||
|
|
@ -4725,7 +4733,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1973",
|
||||
"loc_data": "{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-"
|
||||
"loc_data": "{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1976",
|
||||
|
|
@ -4737,11 +4745,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "1993",
|
||||
"loc_data": "{3264,2886,0,1,0}-{3267,2891,0,1,0}-{3268,2881,0,1,0}-{3269,2885,0,1,0}-{3296,2912,0,1,0}-{3297,2919,0,1,0}-{3301,2920,0,1,0}-{3308,2916,0,1,0}-{3258,2868,0,1,0}-{3259,2823,0,1,0}-{3259,2845,0,1,0}-{3260,2830,0,1,0}-{3260,2859,0,1,0}-{3261,2819,0,1,0}-{3261,2851,0,1,0}-{3337,2922,0,1,0}-{3343,2931,0,1,0}-{3349,2922,0,1,0}-{3351,2927,0,1,0}-{3357,2922,0,1,0}-{3359,2927,0,1,0}-{3364,2937,0,1,0}-{3268,2854,0,1,0}-{3269,2827,0,1,0}-{3269,2866,0,1,0}-{3269,2875,0,1,0}-{3270,2818,0,1,0}-{3272,2841,0,1,0}-{3276,2842,0,1,0}-{3282,2839,0,1,0}-{3290,2847,0,1,0}-"
|
||||
"loc_data": "{3337,2922,0,1,0}-{3343,2931,0,1,0}-{3349,2922,0,1,0}-{3351,2927,0,1,0}-{3357,2922,0,1,0}-{3359,2927,0,1,0}-{3364,2937,0,1,0}-{3258,2868,0,1,0}-{3259,2823,0,1,0}-{3259,2845,0,1,0}-{3260,2830,0,1,0}-{3260,2859,0,1,0}-{3261,2819,0,1,0}-{3261,2851,0,1,0}-{3268,2854,0,1,0}-{3269,2827,0,1,0}-{3269,2866,0,1,0}-{3269,2875,0,1,0}-{3270,2818,0,1,0}-{3272,2841,0,1,0}-{3276,2842,0,1,0}-{3282,2839,0,1,0}-{3290,2847,0,1,0}-{3264,2886,0,1,0}-{3267,2891,0,1,0}-{3268,2881,0,1,0}-{3269,2885,0,1,0}-{3296,2912,0,1,0}-{3297,2919,0,1,0}-{3301,2920,0,1,0}-{3308,2916,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1994",
|
||||
"loc_data": "{3265,2931,0,1,0}-{3265,2935,0,1,0}-{3268,2932,0,1,0}-{3268,2935,0,1,0}-{3316,2900,0,1,0}-{3319,2897,0,1,0}-{3320,2901,0,1,0}-{3321,2899,0,1,0}-{3212,2863,0,1,0}-{3213,2866,0,1,0}-{3215,2863,0,1,0}-{3216,2865,0,1,0}-{3216,2868,0,1,0}-{3218,2831,0,1,0}-{3220,2830,0,1,0}-{3220,2833,0,1,0}-{3221,2831,0,1,0}-{3238,2845,0,1,0}-{3240,2845,0,1,0}-{3241,2843,0,1,0}-{3241,2847,0,1,0}-{3400,2997,0,1,0}-{3402,2999,0,1,0}-{3403,2997,0,1,0}-{3445,2993,0,1,0}-{3446,2992,0,1,0}-{3448,2991,0,1,0}-{3448,2994,0,1,0}-{3329,2933,0,1,0}-{3330,2931,0,1,0}-{3331,2933,0,1,0}-{3343,2895,0,1,0}-{3345,2896,0,1,0}-{3346,2894,0,1,0}-{3348,2894,0,1,0}-{3376,2934,0,1,0}-{3378,2933,0,1,0}-{3378,2935,0,1,0}-{3381,2907,0,1,0}-{3383,2905,0,1,0}-{3383,2908,0,1,0}-{3384,2907,0,1,0}-{3306,2817,0,1,0}-{3308,2818,0,1,0}-{3309,2816,0,1,0}-{3312,2817,0,1,0}-{3314,2861,0,1,0}-{3319,2873,0,1,0}-{3321,2871,0,1,0}-{3324,2870,0,1,0}-{3327,2858,0,1,0}-{3406,3014,0,1,0}-{3408,3013,0,1,0}-{3408,3016,0,1,0}-{3410,3015,0,1,0}-"
|
||||
"loc_data": "{3329,2933,0,1,0}-{3330,2931,0,1,0}-{3331,2933,0,1,0}-{3343,2895,0,1,0}-{3345,2896,0,1,0}-{3346,2894,0,1,0}-{3348,2894,0,1,0}-{3376,2934,0,1,0}-{3378,2933,0,1,0}-{3378,2935,0,1,0}-{3381,2907,0,1,0}-{3383,2905,0,1,0}-{3383,2908,0,1,0}-{3384,2907,0,1,0}-{3400,2997,0,1,0}-{3402,2999,0,1,0}-{3403,2997,0,1,0}-{3445,2993,0,1,0}-{3446,2992,0,1,0}-{3448,2991,0,1,0}-{3448,2994,0,1,0}-{3406,3014,0,1,0}-{3408,3013,0,1,0}-{3408,3016,0,1,0}-{3410,3015,0,1,0}-{3212,2863,0,1,0}-{3213,2866,0,1,0}-{3215,2863,0,1,0}-{3216,2865,0,1,0}-{3216,2868,0,1,0}-{3218,2831,0,1,0}-{3220,2830,0,1,0}-{3220,2833,0,1,0}-{3221,2831,0,1,0}-{3238,2845,0,1,0}-{3240,2845,0,1,0}-{3241,2843,0,1,0}-{3241,2847,0,1,0}-{3306,2817,0,1,0}-{3308,2818,0,1,0}-{3309,2816,0,1,0}-{3312,2817,0,1,0}-{3314,2861,0,1,0}-{3319,2873,0,1,0}-{3321,2871,0,1,0}-{3324,2870,0,1,0}-{3327,2858,0,1,0}-{3265,2931,0,1,0}-{3265,2935,0,1,0}-{3268,2932,0,1,0}-{3268,2935,0,1,0}-{3316,2900,0,1,0}-{3319,2897,0,1,0}-{3320,2901,0,1,0}-{3321,2899,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "1995",
|
||||
|
|
@ -4893,7 +4901,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "2057",
|
||||
"loc_data": "{2442,9436,2,1,0}-{2458,9413,2,1,0}-{2470,9435,2,1,0}-{2472,9460,2,1,0}-{2483,9413,2,1,0}-{2485,9447,2,1,0}-{2480,3046,0,1,0}-{2453,9393,2,1,0}-{2461,9403,2,1,0}-{2464,9380,2,1,0}-"
|
||||
"loc_data": "{2480,3046,0,1,0}-{2453,9393,2,1,0}-{2461,9403,2,1,0}-{2464,9380,2,1,0}-{2442,9436,2,1,0}-{2458,9413,2,1,0}-{2470,9435,2,1,0}-{2472,9460,2,1,0}-{2483,9413,2,1,0}-{2485,9447,2,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "2058",
|
||||
|
|
@ -5365,7 +5373,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "2265",
|
||||
"loc_data": "{3038,4809,0,1,6}-{3024,4850,0,1,3}-{3052,4808,0,1,5}-{3021,4847,0,1,3}-{3058,4811,0,1,4}-{3055,4848,0,1,0}-{3062,4822,0,1,6}-{3017,4837,0,1,3}-{3017,4817,0,1,7}-{3025,4812,0,1,1}-{3060,4825,0,1,3}-{3062,4838,0,1,3}-{3054,4850,0,1,6}-{3020,4914,0,1,2}-{3059,4890,0,1,3}-{3031,4901,0,1,7}-{3044,4915,0,1,6}-{3044,4883,0,1,4}-{3039,4885,0,1,1}-{3048,4917,0,1,5}-{3059,4888,0,1,5}-{3047,4874,0,1,2}-{3055,4908,0,1,5}-{3016,4876,0,1,1}-{3029,4890,0,1,5}-{3059,4906,0,1,1}-{3021,4875,0,1,3}-{3032,4903,0,1,3}-{3026,4914,0,1,6}-"
|
||||
"loc_data": "{3038,4809,0,1,6}-{3024,4850,0,1,3}-{3052,4808,0,1,5}-{3021,4847,0,1,3}-{3058,4811,0,1,4}-{3055,4848,0,1,0}-{3062,4822,0,1,6}-{3017,4837,0,1,3}-{3017,4817,0,1,7}-{3025,4812,0,1,1}-{3060,4825,0,1,3}-{3062,4838,0,1,3}-{3054,4850,0,1,6}-{3020,4914,0,1,2}-{3059,4890,0,1,3}-{3031,4901,0,1,7}-{3044,4915,0,1,6}-{3044,4883,0,1,4}-{3039,4885,0,1,1}-{3048,4917,0,1,5}-{3059,4888,0,1,5}-{3047,4874,0,1,2}-{3055,4908,0,1,5}-{3017,4876,0,1,1}-{3029,4890,0,1,5}-{3059,4906,0,1,1}-{3021,4875,0,1,3}-{3032,4903,0,1,3}-{3026,4914,0,1,6}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "2266",
|
||||
|
|
@ -5581,7 +5589,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "2335",
|
||||
"loc_data": "{3181,3359,0,0,0}-"
|
||||
"loc_data": "{3181,3359,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "2336",
|
||||
|
|
@ -5835,14 +5843,6 @@
|
|||
"npc_id": "2488",
|
||||
"loc_data": "{2799,3058,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "2489",
|
||||
"loc_data": "{3703,3040,0,1,3}-{3706,3051,0,1,1}-{3664,3013,0,1,7}-{3749,3000,0,1,6}-{3723,2998,0,1,2}-{3731,2991,0,1,1}-{3775,3033,0,1,4}-{3766,3010,0,1,4}-{3764,3020,0,1,1}-{3738,3010,0,1,3}-{3720,3040,0,1,6}-{3719,3045,0,1,6}-{3781,3031,0,1,5}-{3780,3022,0,1,1}-{3788,3011,0,1,2}-{3793,3019,0,1,5}-{3779,3045,0,1,1}-{3784,3040,0,1,3}-{3802,3037,0,1,2}-{3808,3026,0,1,3}-{3799,3024,0,1,4}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "2490",
|
||||
"loc_data": "{3782,3016,0,1,7}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "2491",
|
||||
"loc_data": "{2679,3080,0,1,6}-{2684,3084,0,1,4}-{2682,3093,0,1,4}-{2678,3095,0,1,3}-{2679,3102,0,1,1}-{2681,3110,0,1,4}-{2683,3115,0,1,6}-{2675,3108,0,1,3}-{2671,3109,0,1,3}-{2671,3113,0,1,4}-{2676,3090,0,1,4}-{2670,3088,0,1,6}-{2671,3086,0,1,6}-{2664,3088,0,1,7}-{2660,3086,0,1,6}-{2662,3088,0,1,6}-{2670,3082,0,1,7}-{2674,3081,0,1,3}-{2663,3086,0,1,6}-{2679,3082,0,1,1}-{2682,3093,0,1,3}-"
|
||||
|
|
@ -6313,7 +6313,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "2803",
|
||||
"loc_data": "{3387,3068,0,1,0}-{3387,3017,0,1,0}-{3404,3062,0,1,0}-{3441,3061,0,1,0}-{3445,3034,0,1,0}-{3338,2804,0,1,0}-{3339,2815,0,1,0}-{3342,2809,0,1,0}-{3344,2800,0,1,0}-{3348,2809,0,1,0}-{3349,2814,0,1,0}-{3357,2813,0,1,0}-{3357,2806,0,1,0}-{3365,2815,0,1,0}-"
|
||||
"loc_data": "{3338,2804,0,1,0}-{3339,2815,0,1,0}-{3342,2809,0,1,0}-{3344,2800,0,1,0}-{3348,2809,0,1,0}-{3349,2814,0,1,0}-{3357,2813,0,1,0}-{3357,2806,0,1,0}-{3365,2815,0,1,0}-{3387,3068,0,1,0}-{3387,3017,0,1,0}-{3404,3062,0,1,0}-{3441,3061,0,1,0}-{3445,3034,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "2804",
|
||||
|
|
@ -7233,7 +7233,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "3675",
|
||||
"loc_data": "{3333,2864,0,1,1}-{3335,2860,0,1,2}-{3338,2864,0,1,4}-{3215,2841,0,1,0}-{3217,2845,0,1,0}-{3220,2841,0,1,0}-{3295,2866,0,1,0}-{3297,2863,0,1,0}-{3301,2864,0,1,0}-{3336,2778,0,1,0}-{3343,2793,0,1,0}-{3367,2791,0,1,0}-"
|
||||
"loc_data": "{3336,2778,0,1,0}-{3343,2793,0,1,0}-{3367,2791,0,1,0}-{3333,2864,0,1,1}-{3335,2860,0,1,2}-{3338,2864,0,1,4}-{3215,2841,0,1,0}-{3217,2845,0,1,0}-{3220,2841,0,1,0}-{3295,2866,0,1,0}-{3297,2863,0,1,0}-{3301,2864,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "3677",
|
||||
|
|
@ -7461,7 +7461,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "4246",
|
||||
"loc_data": "{3480,3484,1,0,0}-{3479,3484,0,1,3}-"
|
||||
"loc_data": "{3479,3484,0,1,3}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4247",
|
||||
|
|
@ -7595,6 +7595,10 @@
|
|||
"npc_id": "4317",
|
||||
"loc_data": "{3230,3285,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4343",
|
||||
"loc_data": "{3706,3051,0,1,6}-{3703,3040,0,1,3}-{3664,3013,0,1,7}-{3731,2991,0,1,1}-{3723,2998,0,1,2}-{3749,3000,0,1,6}-{3775,3033,0,1,4}-{3766,3010,0,1,4}-{3764,3020,0,1,1}-{3738,3010,0,1,3}-{3720,3040,0,1,6}-{3719,3045,0,1,6}-{3781,3031,0,1,5}-{3780,3022,0,1,1}-{3788,3011,0,1,2}-{3793,3019,0,1,5}-{3779,3045,0,1,1}-{3784,3040,0,1,3}-{3802,3037,0,1,2}-{3808,3026,0,1,3}-{3799,3024,0,1,4}-{3782,3016,0,1,7}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4344",
|
||||
"loc_data": "{3733,2972,0,1,4}-{3747,3013,0,1,4}-{3766,3034,0,1,6}-"
|
||||
|
|
@ -8237,23 +8241,23 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "4689",
|
||||
"loc_data": "{2369,3401,0,1,0}-{2902,9736,0,1,0}-"
|
||||
"loc_data": "{2369,3401,0,1,0}-{2902,9736,0,1,0}-{2440,3213,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4690",
|
||||
"loc_data": "{2372,3401,0,1,0}-{3104,3875,0,1,2}-{2912,9731,0,1,0}-{3256,3624,0,1,5}-{3308,3661,0,1,2}-"
|
||||
"loc_data": "{3104,3875,0,1,2}-{2372,3401,0,1,0}-{2912,9731,0,1,0}-{2439,3211,0,1,0}-{3256,3624,0,1,5}-{3308,3661,0,1,2}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4691",
|
||||
"loc_data": "{2371,3398,0,1,0}-{3110,3854,0,1,0}-"
|
||||
"loc_data": "{3110,3854,0,1,0}-{2371,3398,0,1,0}-{2439,3208,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4692",
|
||||
"loc_data": "{2372,3395,0,1,0}-{3116,3858,0,1,0}-"
|
||||
"loc_data": "{3116,3858,0,1,0}-{2372,3395,0,1,0}-{2442,3210,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4693",
|
||||
"loc_data": "{2369,3394,0,1,0}-{3094,3849,0,1,0}-{2912,9741,0,1,0}-{2906,9736,0,1,0}-"
|
||||
"loc_data": "{3094,3849,0,1,0}-{2369,3394,0,1,0}-{2912,9741,0,1,0}-{2906,9736,0,1,0}-{2444,3208,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "4694",
|
||||
|
|
@ -9005,7 +9009,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "5359",
|
||||
"loc_data": "{2693,5065,0,1,0}-{2693,5089,0,1,0}-{2704,5091,0,1,0}-{2710,5095,0,1,0}-{2712,5076,0,1,0}-{2714,5108,0,1,0}-{2716,5092,0,1,0}-{2719,5071,0,1,0}-{2722,5061,0,1,0}-{2732,5087,0,1,0}-{2739,5078,0,1,0}-{2740,5104,0,1,0}-{2747,5083,0,1,0}-{2627,5093,0,1,0}-{2629,5061,0,1,0}-{2638,5090,0,1,0}-{2651,5105,0,1,0}-{2654,5079,0,1,0}-{2663,5116,0,1,0}-{2683,5059,0,1,0}-{2685,5111,0,1,0}-"
|
||||
"loc_data": "{2627,5093,0,1,0}-{2629,5061,0,1,0}-{2638,5090,0,1,0}-{2651,5105,0,1,0}-{2654,5079,0,1,0}-{2663,5116,0,1,0}-{2683,5059,0,1,0}-{2685,5111,0,1,0}-{2693,5065,0,1,0}-{2693,5089,0,1,0}-{2704,5091,0,1,0}-{2710,5095,0,1,0}-{2712,5076,0,1,0}-{2714,5108,0,1,0}-{2716,5092,0,1,0}-{2719,5071,0,1,0}-{2722,5061,0,1,0}-{2732,5087,0,1,0}-{2739,5078,0,1,0}-{2740,5104,0,1,0}-{2747,5083,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "5361",
|
||||
|
|
@ -9665,7 +9669,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "5748",
|
||||
"loc_data": "{3429,3276,0,0,0}-{3440,3281,0,0,0}-{3437,3272,0,0,0}-{3440,3271,0,0,0}-{3443,3272,0,0,0}-{3445,3279,0,0,0}-{3445,3274,0,0,0}-{3434,3417,0,0,0}-{3431,3415,0,0,0}-{3440,3410,0,0,0}-{3424,3409,0,0,0}-{3425,3410,0,0,0}-{3425,3407,0,0,0}-{3483,3449,0,0,0}-{3490,3444,0,0,0}-{3479,3434,0,0,0}-{3479,3430,0,0,0}-{3481,3473,0,0,0}-"
|
||||
"loc_data": "{3429,3276,0,0,0}-{3440,3281,0,0,0}-{3437,3272,0,0,0}-{3440,3271,0,0,0}-{3443,3272,0,0,0}-{3445,3279,0,0,0}-{3445,3274,0,0,0}-{3434,3417,0,0,0}-{3431,3415,0,0,0}-{3440,3410,0,0,0}-{3424,3409,0,0,0}-{3425,3410,0,0,0}-{3425,3407,0,0,0}-{3483,3449,0,0,0}-{3490,3444,0,0,0}-{3479,3434,0,0,0}-{3479,3430,0,0,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "5750",
|
||||
|
|
@ -10219,13 +10223,17 @@
|
|||
"npc_id": "6028",
|
||||
"loc_data": "{3497,3497,0,1,2}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6029",
|
||||
"loc_data": "{3474,3475,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6030",
|
||||
"loc_data": "{3496,3476,0,1,2}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6031",
|
||||
"loc_data": "{3511,3482,1,0,0}-"
|
||||
"loc_data": "{3511,3482,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6032",
|
||||
|
|
@ -10245,7 +10253,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "6036",
|
||||
"loc_data": "{3499,3474,1,0,0}-"
|
||||
"loc_data": "{3499,3474,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6037",
|
||||
|
|
@ -10253,7 +10261,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "6038",
|
||||
"loc_data": "{3490,3472,1,0,0}-"
|
||||
"loc_data": "{3490,3472,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6039",
|
||||
|
|
@ -10261,7 +10269,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "6040",
|
||||
"loc_data": "{3498,3472,1,0,0}-"
|
||||
"loc_data": "{3498,3472,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6041",
|
||||
|
|
@ -10269,15 +10277,19 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "6042",
|
||||
"loc_data": "{3479,3498,0,1,4}-"
|
||||
"loc_data": "{3480,3499,0,1,4}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6043",
|
||||
"loc_data": "{3490,3473,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6044",
|
||||
"loc_data": "{3505,3491,1,0,0}-"
|
||||
"loc_data": "{3505,3491,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6045",
|
||||
"loc_data": "{3479,3498,1,0,0}-"
|
||||
"loc_data": "{3479,3498,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6046",
|
||||
|
|
@ -10289,11 +10301,11 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "6050",
|
||||
"loc_data": "{3264,3008,0,1,0}-{3266,3008,0,1,0}-{3285,3066,0,1,0}-{3322,3032,0,1,0}-{3323,3055,0,1,0}-{3325,3010,0,1,0}-{3174,3010,0,1,0}-{3198,3061,0,1,0}-{3199,3016,0,1,0}-{3219,3125,0,1,0}-{3233,3075,0,1,0}-{3250,3126,0,1,0}-{3223,3011,0,1,0}-{3228,3060,0,1,0}-{3251,3059,0,1,0}-{3310,3076,0,1,0}-"
|
||||
"loc_data": "{3174,3010,0,1,0}-{3198,3061,0,1,0}-{3199,3016,0,1,0}-{3223,3011,0,1,0}-{3228,3060,0,1,0}-{3251,3059,0,1,0}-{3219,3125,0,1,0}-{3233,3075,0,1,0}-{3250,3126,0,1,0}-{3264,3008,0,1,0}-{3266,3008,0,1,0}-{3285,3066,0,1,0}-{3322,3032,0,1,0}-{3323,3055,0,1,0}-{3325,3010,0,1,0}-{3310,3076,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6051",
|
||||
"loc_data": "{3266,3010,0,1,0}-{3267,3068,0,1,0}-{3287,3065,0,1,0}-{3287,3067,0,1,0}-{3310,3070,0,1,0}-{3312,3068,0,1,0}-{3320,3054,0,1,0}-{3324,3013,0,1,0}-{3325,3033,0,1,0}-{3153,3047,0,1,0}-{3196,3063,0,1,0}-{3199,3036,0,1,0}-{3215,3092,0,1,0}-{3217,3124,0,1,0}-{3260,3077,0,1,0}-{3223,3035,0,1,0}-{3225,3011,0,1,0}-{3283,3084,0,1,0}-"
|
||||
"loc_data": "{3153,3047,0,1,0}-{3196,3063,0,1,0}-{3199,3036,0,1,0}-{3223,3035,0,1,0}-{3225,3011,0,1,0}-{3215,3092,0,1,0}-{3217,3124,0,1,0}-{3260,3077,0,1,0}-{3266,3010,0,1,0}-{3267,3068,0,1,0}-{3287,3065,0,1,0}-{3287,3067,0,1,0}-{3310,3070,0,1,0}-{3312,3068,0,1,0}-{3320,3054,0,1,0}-{3324,3013,0,1,0}-{3325,3033,0,1,0}-{3283,3084,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6052",
|
||||
|
|
@ -10419,6 +10431,38 @@
|
|||
"npc_id": "6117",
|
||||
"loc_data": "{1884,5020,0,0,6}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6118",
|
||||
"loc_data": "{2443,3190,0,0,6}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6119",
|
||||
"loc_data": "{2439,3186,0,1,4}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6120",
|
||||
"loc_data": "{2437,3160,1,1,4}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6122",
|
||||
"loc_data": "{2327,9394,0,0,1}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6123",
|
||||
"loc_data": "{2364,9399,0,0,1}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6124",
|
||||
"loc_data": "{2364,9398,0,0,1}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6125",
|
||||
"loc_data": "{2323,9377,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6126",
|
||||
"loc_data": "{2351,9358,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "6127",
|
||||
"loc_data": "{2467,3183,0,0,3}-"
|
||||
|
|
@ -12135,10 +12179,6 @@
|
|||
"npc_id": "7804",
|
||||
"loc_data": "{3279,4350,0,1,0}-{3294,4353,0,1,0}-{3294,4366,0,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "7823",
|
||||
"loc_data": ""
|
||||
},
|
||||
{
|
||||
"npc_id": "7891",
|
||||
"loc_data": "{3207,3250,0,0,0}-{3208,3250,0,0,0}-{3209,3250,0,0,0}-"
|
||||
|
|
@ -12301,7 +12341,7 @@
|
|||
},
|
||||
{
|
||||
"npc_id": "8324",
|
||||
"loc_data": "{2911,3811,0,1,0}-{2911,3812,0,1,0}-{2911,3813,0,1,0}-{2925,3821,0,1,0}-{2925,3822,0,1,0}-{2925,3823,0,1,0}-{2929,3798,0,1,0}-{2936,3790,0,1,0}-{2936,3810,0,1,0}-{2939,3823,0,1,0}-{2949,3819,1,1,0}-{2949,3822,1,1,0}-{2955,3822,1,1,0}-{2957,3822,1,1,0}-{3016,9977,1,1,0}-{3021,9939,1,1,0}-{3024,9954,1,1,0}-{3025,9943,1,1,0}-{3025,9954,1,1,0}-{3026,9966,1,1,0}-{3032,9952,1,1,0}-{3039,9954,1,1,0}-{3044,9967,1,1,0}-{3044,9971,1,1,0}-{3057,9936,1,1,0}-{3059,9953,1,1,0}-{3041,9975,2,1,0}-{3043,9975,2,1,0}-{3045,9975,2,1,0}-{3016,10022,2,1,0}-{3017,10039,2,1,0}-{3027,10028,2,1,0}-{3029,10013,2,1,0}-{3036,10038,2,1,0}-{3037,10006,2,1,0}-{3041,10024,2,1,0}-{3043,10032,2,1,0}-{3057,10002,2,1,0}-{3058,10021,2,1,0}-{3065,10006,2,1,0}-{3027,10092,1,1,0}-{3035,10097,1,1,0}-{3051,10099,1,1,0}-{3427,5102,0,1,0}-{3428,5099,0,1,0}-{3428,5102,0,1,0}-{3430,5099,0,1,0}-"
|
||||
"loc_data": "{2911,3811,0,1,0}-{2911,3812,0,1,0}-{2911,3813,0,1,0}-{2925,3821,0,1,0}-{2925,3822,0,1,0}-{2925,3823,0,1,0}-{2929,3798,0,1,0}-{2936,3790,0,1,0}-{2936,3810,0,1,0}-{2939,3823,0,1,0}-{3427,5102,0,1,0}-{3428,5099,0,1,0}-{3428,5102,0,1,0}-{3430,5099,0,1,0}-{2949,3819,1,1,0}-{2949,3822,1,1,0}-{2955,3822,1,1,0}-{2957,3822,1,1,0}-{3016,9977,1,1,0}-{3021,9939,1,1,0}-{3024,9954,1,1,0}-{3025,9943,1,1,0}-{3025,9954,1,1,0}-{3026,9966,1,1,0}-{3032,9952,1,1,0}-{3039,9954,1,1,0}-{3044,9967,1,1,0}-{3044,9971,1,1,0}-{3057,9936,1,1,0}-{3059,9953,1,1,0}-{3041,9975,2,1,0}-{3043,9975,2,1,0}-{3045,9975,2,1,0}-{3016,10022,2,1,0}-{3017,10039,2,1,0}-{3027,10028,2,1,0}-{3029,10013,2,1,0}-{3036,10038,2,1,0}-{3037,10006,2,1,0}-{3041,10024,2,1,0}-{3043,10032,2,1,0}-{3057,10002,2,1,0}-{3058,10021,2,1,0}-{3065,10006,2,1,0}-{3027,10092,1,1,0}-{3035,10097,1,1,0}-{3051,10099,1,1,0}-"
|
||||
},
|
||||
{
|
||||
"npc_id": "8328",
|
||||
|
|
|
|||
|
|
@ -20055,6 +20055,10 @@
|
|||
"examine": "Home sweet home?",
|
||||
"ids": "15480"
|
||||
},
|
||||
{
|
||||
"examine": "Baby bread.",
|
||||
"ids": "15506,15507"
|
||||
},
|
||||
{
|
||||
"examine": "Home sweet home?",
|
||||
"ids": "15748"
|
||||
|
|
@ -20183,6 +20187,18 @@
|
|||
"examine": "A short longboat!",
|
||||
"ids": "21834"
|
||||
},
|
||||
{
|
||||
"examine": "A place to sit and watch furniture grow.",
|
||||
"ids": "28627"
|
||||
},
|
||||
{
|
||||
"examine": "It's not rolling, but it seems to have gathered some moss.",
|
||||
"ids": "28635"
|
||||
},
|
||||
{
|
||||
"examine": "A thick metal gate.",
|
||||
"ids": "28690,28691,28692,28693"
|
||||
},
|
||||
{
|
||||
"examine": "Contains traces of summoning energy.",
|
||||
"ids": "29939,29943,29944,29945,29947,29951,29952,29953,29954"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import org.rs09.consts.Sounds
|
|||
import java.util.*
|
||||
|
||||
/**
|
||||
* Represents an enchanted jewellery.
|
||||
* Represents a piece of enchanted jewellery.
|
||||
* @author Vexia, downthecrop, Player Name
|
||||
*/
|
||||
enum class EnchantedJewellery(
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
package content.data;
|
||||
|
||||
import core.game.node.item.Item;
|
||||
|
||||
/**
|
||||
* Represents the repair item type.
|
||||
* @author Vexia
|
||||
*/
|
||||
public enum RepairItem {
|
||||
BRONZE_HATCHET(new Item(494, 1), new Item(1351, 1), 0),
|
||||
BRONZE_PICKAXE(new Item(468, 1), new Item(1265, 1), 0),
|
||||
IRON_HATCHET(new Item(496, 1), new Item(1349, 1), 0),
|
||||
IRON_PICKAXE(new Item(470, 1), new Item(1267, 1), 0),
|
||||
STEEL_HATCHET(new Item(498, 1), new Item(1353, 1), 0),
|
||||
STEEL_PICKAXE(new Item(472, 1), new Item(1269, 1), 14),
|
||||
BLACK_HATCHET(new Item(500, 1), new Item(1361, 1), 10),
|
||||
MITHRIL_HATCHET(new Item(502, 1), new Item(1355, 1), 18),
|
||||
MITHRIL_PICKAXE(new Item(474, 1), new Item(1273, 1), 43),
|
||||
ADAMANT_HATCHET(new Item(504, 1), new Item(1357, 1), 43),
|
||||
ADAMANT_PICKAXE(new Item(476, 1), new Item(1271, 1), 107),
|
||||
RUNE_HATCHET(new Item(506, 1), new Item(1359, 1), 427),
|
||||
RUNE_PICKAXE(new Item(478, 1), new Item(1275, 1), 1100),
|
||||
DRAGON_HATCHET(new Item(6741, 1), new Item(6739, 1), 1800);
|
||||
|
||||
/**
|
||||
* The item id.
|
||||
*/
|
||||
private final Item item;
|
||||
|
||||
/**
|
||||
* The product item.
|
||||
*/
|
||||
private final Item product;
|
||||
|
||||
/**
|
||||
* The cost of the money to repair.
|
||||
*/
|
||||
private final int cost;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BobRepairItem} {@code Object}.
|
||||
* @param item the item.
|
||||
* @param product the product.
|
||||
* @param cost the cost.
|
||||
*/
|
||||
RepairItem(Item item, Item product, int cost) {
|
||||
this.item = item;
|
||||
this.product = product;
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
* @return The item.
|
||||
*/
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product.
|
||||
* @return The product.
|
||||
*/
|
||||
public Item getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the cost.
|
||||
* @return The cost.
|
||||
*/
|
||||
public int getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reapir item by the id.
|
||||
* @param id the id.
|
||||
* @return the repair item.
|
||||
*/
|
||||
public static RepairItem forId(int id) {
|
||||
for (RepairItem item : RepairItem.values())
|
||||
if (item.item.getId() == id)
|
||||
return item;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
43
Server/src/main/content/data/RepairItem.kt
Normal file
43
Server/src/main/content/data/RepairItem.kt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package content.data
|
||||
|
||||
import core.game.node.item.Item
|
||||
|
||||
/**
|
||||
* Represents the repair item type.
|
||||
* @author Vexia
|
||||
* @author Damighty - Kotlin conversion
|
||||
*/
|
||||
enum class RepairItem(
|
||||
val item: Item,
|
||||
val product: Item,
|
||||
val cost: Int
|
||||
) {
|
||||
BRONZE_HATCHET(Item(494, 1), Item(1351, 1), 0),
|
||||
BRONZE_PICKAXE(Item(468, 1), Item(1265, 1), 0),
|
||||
IRON_HATCHET(Item(496, 1), Item(1349, 1), 0),
|
||||
IRON_PICKAXE(Item(470, 1), Item(1267, 1), 0),
|
||||
STEEL_HATCHET(Item(498, 1), Item(1353, 1), 0),
|
||||
STEEL_PICKAXE(Item(472, 1), Item(1269, 1), 14),
|
||||
BLACK_HATCHET(Item(500, 1), Item(1361, 1), 10),
|
||||
MITHRIL_HATCHET(Item(502, 1), Item(1355, 1), 18),
|
||||
MITHRIL_PICKAXE(Item(474, 1), Item(1273, 1), 43),
|
||||
ADAMANT_HATCHET(Item(504, 1), Item(1357, 1), 43),
|
||||
ADAMANT_PICKAXE(Item(476, 1), Item(1271, 1), 107),
|
||||
RUNE_HATCHET(Item(506, 1), Item(1359, 1), 427),
|
||||
RUNE_PICKAXE(Item(478, 1), Item(1275, 1), 1100),
|
||||
DRAGON_HATCHET(Item(6741, 1), Item(6739, 1), 1800);
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* List of all repairable item IDs.
|
||||
*/
|
||||
@JvmStatic
|
||||
val repairableItemIds: List<Int> = values().map { it.item.id }
|
||||
|
||||
/**
|
||||
* Gets the repair item by the broken items ID.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun forId(id: Int): RepairItem? = values().firstOrNull { it.item.id == id }
|
||||
}
|
||||
}
|
||||
|
|
@ -201,6 +201,7 @@ public enum Consumables {
|
|||
/** Ales */
|
||||
ASGOLDIAN_ALE(new FakeConsumable(7508, new String[] {"I don't think I'd like gold in beer thanks. Leave it for the dwarves."})),
|
||||
ASGARNIAN_ALE(new Drink(new int[] {1905, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
|
||||
ASGARNIAN_ALE_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))),
|
||||
|
|
@ -210,17 +211,21 @@ public enum Consumables {
|
|||
AXEMANS_FOLLY_M_KEG(new Drink(new int[] {5905, 5903, 5901, 5899, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))),
|
||||
BANDITS_BREW(new Drink(new int[] {4627, 1919}, new MultiEffect(new SkillEffect(Skills.THIEVING, 1, 0), new SkillEffect(Skills.ATTACK, 1, 0), new SkillEffect(Skills.STRENGTH, -1, 0), new SkillEffect(Skills.DEFENCE, -6, 0), new HealingEffect(1)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
|
||||
BEER(new Drink(new int[] {1917, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
|
||||
BEER_POH(new Drink(new int[] {7740, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")),
|
||||
BEER_TANKARD(new Drink(new int[] {3803, 3805}, new MultiEffect(new SkillEffect(Skills.ATTACK, -9, 0), new SkillEffect(Skills.STRENGTH, 4, 0)), "You quaff the beer. You feel slightly reinvigorated...", "...but very dizzy too.")),
|
||||
KEG_OF_BEER(new Drink(new int[] {3801}, new KegOfBeerEffect(), new Animation(1330), "You chug the keg. You feel reinvigorated...", "...but extremely drunk too.")),
|
||||
CHEFS_DELIGHT(new Drink(new int[] {5755, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
|
||||
CHEFS_DELIGHT_POH(new Drink(new int[] {7754, 7742}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))),
|
||||
CHEFS_DELIGHT_KEG(new Drink(new int[] {5833, 5831, 5829, 5827, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))),
|
||||
CHEFS_DELIGHT_M(new Drink(new int[] {5757, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)))),
|
||||
CHEFS_DELIGHT_M_KEG(new Drink(new int[] {5913, 5911, 5909, 5907, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)), new Animation(2289))),
|
||||
CIDER(new Drink(new int[] {5763, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))),
|
||||
CIDER_POH(new Drink(new int[] {7752, 7742}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))),
|
||||
CIDER_KEG(new Drink(new int[] {5849, 5847, 5845, 5843, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))), new Animation(2289))),
|
||||
MATURE_CIDER(new Drink(new int[] {5765, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))))),
|
||||
CIDER_M_KEG(new Drink(new int[] {5929, 5927, 5925, 5923, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))), new Animation(2289))),
|
||||
DRAGON_BITTER(new Drink(new int[] {1911, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))),
|
||||
DRAGON_BITTER_POH(new Drink(new int[] {7748, 7742}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))),
|
||||
DRAGON_BITTER_KEG(new Drink(new int[] {5809, 5807, 5805, 5803, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))),
|
||||
DRAGON_BITTER_M(new Drink(new int[] {5745, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))),
|
||||
DRAGON_BITTER_M_KEG(new Drink(new int[] {5889, 5887, 5885, 5883, 5769}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))),
|
||||
|
|
@ -229,6 +234,7 @@ public enum Consumables {
|
|||
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))),
|
||||
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))),
|
||||
|
|
@ -285,16 +291,19 @@ public enum Consumables {
|
|||
|
||||
/** Tea */
|
||||
CUP_OF_TEA(new Drink(new int[] {712, 1980}, new MultiEffect(new HealingEffect(3), new SkillEffect(Skills.ATTACK, 3, 0)), "Aaah, nothing like a nice cuppa tea!")),
|
||||
CUP_OF_TEA_NETTLE(new Drink(new int[] {4242, 1980}, new EnergyEffect(10))),
|
||||
CUP_OF_TEA_MILKY_NETTLE(new Drink(new int[] {4243, 1980}, new EnergyEffect(10))),
|
||||
NETTLE_TEA(new Drink(new int[] {4239, 1923}, new NettleTeaEffect())),
|
||||
NETTLE_TEA_MILKY(new Drink(new int[] {4240, 1980}, new NettleTeaEffect())),
|
||||
NETTLE_WATER(new Drink(new int[] {Items.NETTLE_WATER_4237, Items.BOWL_1923}, new HealingEffect((1)))),
|
||||
CUP_OF_TEA_NETTLE(new Drink(new int[] {4242, 1980}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
|
||||
CUP_OF_TEA_MILKY_NETTLE(new Drink(new int[] {4243, 1980}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
|
||||
CUP_OF_TEA_NETTLE_PORCELAIN(new Drink(new int[] {4245, 4244}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
|
||||
CUP_OF_TEA_MILKY_NETTLE_PORCELAIN(new Drink(new int[] {4246, 4244}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
|
||||
NETTLE_TEA(new Drink(new int[] {4239, 1923}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
|
||||
NETTLE_TEA_MILKY(new Drink(new int[] {4240, 1923}, new MultiEffect(new HealingEffect(3), new EnergyEffect(10)))),
|
||||
CUP_OF_TEA_CLAY(new Drink(new int[] {7730, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")),
|
||||
CUP_OF_TEA_CLAY_MILKY(new Drink(new int[] {7731, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0))),
|
||||
CUP_OF_TEA_CLAY_MILKY(new Drink(new int[] {7731, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")),
|
||||
CUP_OF_TEA_WHITE(new Drink(new int[] {7733, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")),
|
||||
CUP_OF_TEA_WHITE_MILKY(new Drink(new int[] {7734, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0))),
|
||||
CUP_OF_TEA_WHITE_MILKY(new Drink(new int[] {7734, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")),
|
||||
CUP_OF_TEA_GOLD(new Drink(new int[] {7736, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")),
|
||||
CUP_OF_TEA_GOLD_MILKY(new Drink(new int[] {7737, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0))),
|
||||
CUP_OF_TEA_GOLD_MILKY(new Drink(new int[] {7737, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")),
|
||||
|
||||
/** Miscellaneous */
|
||||
CHOCOLATE_BAR(new Food(new int[] {1973}, new HealingEffect(3))),
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
package content.data.consumables.effects;
|
||||
|
||||
import core.game.consumable.ConsumableEffect;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
public class NettleTeaEffect extends ConsumableEffect {
|
||||
|
||||
private final static int healing = 3;
|
||||
|
||||
@Override
|
||||
public void activate(Player p) {
|
||||
final ConsumableEffect effect = p.getSkills().getLifepoints() < p.getSkills().getMaximumLifepoints() ? new MultiEffect(new HealingEffect(3), new EnergyEffect(5)) : new HealingEffect(3);
|
||||
effect.activate(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHealthEffectValue(Player player) {
|
||||
return healing;
|
||||
}
|
||||
}
|
||||
|
|
@ -45,35 +45,35 @@ class ChampionChallengeListener : InteractionListener, MapArea {
|
|||
|
||||
private val IMP_SCROLL_TEXT = arrayOf(
|
||||
"How about picking on someone your own size? I'll",
|
||||
"see you at the Champion's Guild.",
|
||||
"see you at the Champions' Guild.",
|
||||
"",
|
||||
"Champion of Imps"
|
||||
)
|
||||
|
||||
private val GOBLIN_SCROLL_TEXT = arrayOf(
|
||||
"Fight me if you think you can human, I'll wait",
|
||||
"for you in the Champion's Guild.",
|
||||
"for you in the Champions' Guild.",
|
||||
"",
|
||||
"Champion of Goblins"
|
||||
)
|
||||
|
||||
private val SKELETON_SCROLL_TEXT = arrayOf(
|
||||
"I'll be waiting at the Champions' Guild to",
|
||||
"collect your bones.",
|
||||
"I'll be waiting at the Champions' Guild to collect",
|
||||
"your bones.",
|
||||
"",
|
||||
"Champion of Skeletons"
|
||||
)
|
||||
|
||||
private val ZOMBIE_SCROLL_TEXT = arrayOf(
|
||||
"You come to Champions' Guild, you fight me,",
|
||||
"I squish you, I get brains!",
|
||||
"You come to Champions' Guild, you fight me, I",
|
||||
"squish you, I get brains!",
|
||||
"",
|
||||
"Champion of Zombies"
|
||||
)
|
||||
|
||||
private val GIANT_SCROLL_TEXT = arrayOf(
|
||||
"Get yourself to the Champions' Guild, if you",
|
||||
"dare to face me puny human.",
|
||||
"Get yourself to the Champions' Guild, if you dare",
|
||||
"to face me puny human.",
|
||||
"",
|
||||
"Champion of Giants"
|
||||
)
|
||||
|
|
@ -93,21 +93,22 @@ class ChampionChallengeListener : InteractionListener, MapArea {
|
|||
)
|
||||
|
||||
private val EARTH_WARRIOR_TEXT = arrayOf(
|
||||
"I challenge you to a duel, come to the arena beneath",
|
||||
"the Champion's Guild and fight me if you dare.",
|
||||
"I challenge you to a duel, come to the arena",
|
||||
"beneath the Champions' Guild and fight me if you",
|
||||
"dare.",
|
||||
"",
|
||||
"Champion of Earth Warriors"
|
||||
)
|
||||
|
||||
private val JOGRE_SCROLL_TEXT = arrayOf(
|
||||
"You think you can defeat me? Come to the",
|
||||
"Champion's Guild and prove it!",
|
||||
"Champions' Guild and prove it!",
|
||||
"",
|
||||
"Champion of Jogres"
|
||||
)
|
||||
|
||||
private val LESSER_DEMON_SCROLL_TEXT = arrayOf(
|
||||
"Come to the Champion's Guild so I can banish",
|
||||
"Come to the Champions' Guild so I can banish",
|
||||
"you mortal!",
|
||||
"",
|
||||
"Champion of Lesser Demons"
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class ChampionScrollsDropHandler : ChampionScrollsEventHookBase() {
|
|||
|
||||
NPCs.CAVE_GOBLIN_GUARD_2073, NPCs.CAVE_GOBLIN_GUARD_2074,
|
||||
|
||||
NPCs.GOBLIN_GUARD_489, NPCs.GOBLIN_GUARD_6496, NPCs.GOBLIN_GUARD_6497,
|
||||
NPCs.GOBLIN_GUARD_6496, NPCs.GOBLIN_GUARD_6497,
|
||||
NPCs.SERGEANT_GRIMSPIKE_6265,
|
||||
NPCs.SERGEANT_STEELWILL_6263,
|
||||
NPCs.SERGEANT_STRONGSTACK_6261
|
||||
|
|
|
|||
|
|
@ -27,24 +27,24 @@ class LarxusDialogue(val ChallengeStart: Boolean = false) : DialogueFile() {
|
|||
0 -> {
|
||||
face(findNPC(NPCs.LARXUS_3050)!!, player!!, 1)
|
||||
for (i in scrolls)when{
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6798) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use prayer's. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6799) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only weapons. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6800) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only melee combat skill. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6801) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only magic skill. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6802) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use melee combat skills. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6803) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use weapons with special attack. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6804) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use ranged skill. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6805) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only equipment. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6806) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only ranged skill. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6807) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use magic skill. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6798) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Prayers. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6799) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to take Weapons, no other items are allowed. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6800) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Melee attacks, no Ranged or Magic. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6801) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Magic attacks, no Melee or Ranged. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6802) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Melee attacks. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6803) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Special Attacks. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6804) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Ranged attacks. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6805) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed any Weapons or Armour. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6806) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're only allowed to use Ranged attacks, no Melee or Magic. Do you still want to proceed?").also { stage = 1 }
|
||||
inInventory(player!!,Items.CHAMPION_SCROLL_6807) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use any Magic attacks. Do you still want to proceed?").also { stage = 1 }
|
||||
else -> {
|
||||
sendMessage(player!!, "Nothing interesting happens.").also { stage = END_DIALOGUE } }
|
||||
}
|
||||
}
|
||||
1 -> options("Yes, let me at him!", "No, thanks I'll pass.").also { stage = 2 }
|
||||
1 -> options("Yes, let me at him!", "No thanks, I'll pass.").also { stage = 2 }
|
||||
2 -> when (buttonID) {
|
||||
1 -> playerl("Yes, let me at him!").also { stage = 3 }
|
||||
2 -> playerl("No, thanks I'll pass.").also { stage = END_DIALOGUE }
|
||||
2 -> playerl("No thanks, I'll pass.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
3 -> npcl("Your challenger is ready, please go down through the trapdoor when you're ready.").also { stage = 4 }
|
||||
4 -> {
|
||||
|
|
@ -65,7 +65,7 @@ class LarxusDialogue(val ChallengeStart: Boolean = false) : DialogueFile() {
|
|||
3 -> playerl("Nothing thanks.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
3 -> npcl("Well pass it here and we'll get you started.").also { stage = END_DIALOGUE }
|
||||
4 -> npcl("This is the champions' arena, the champions of various, races use it to duel those they deem worthy of the, honour.").also { stage = END_DIALOGUE }
|
||||
4 -> npcl("This is the champions' arena. The champions of various races use it to duel those they deem worthy of the honour. If you find a challenge scroll in your travels, bring it here to face your challenger.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ package content.global.activity.cchallange.npc
|
|||
import core.api.*
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.BattleState
|
||||
import core.game.node.entity.combat.CombatStyle
|
||||
import core.game.node.entity.combat.equipment.WeaponInterface
|
||||
import core.game.node.entity.npc.AbstractNPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
|
|
@ -63,21 +61,11 @@ class ImpChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,
|
|||
super.checkImpact(state)
|
||||
val player = state.attacker
|
||||
if (player is Player) {
|
||||
val w = player.getExtension<WeaponInterface>(WeaponInterface::class.java)
|
||||
if (state.style == CombatStyle.MELEE || state.style == CombatStyle.MAGIC || state.style == CombatStyle.RANGE) {
|
||||
|
||||
//somehow the maximumHit is determined to be zero by this point if you're using a melee special attack.
|
||||
if (state.maximumHit == 0) {
|
||||
state.neutralizeHits()
|
||||
state.estimatedHit = state.maximumHit
|
||||
}
|
||||
if (w.weaponInterface.interfaceId == 10) {
|
||||
sendMessage(player, "You cannot use special attack in this challenge.")
|
||||
if (state.estimatedHit > -1) {
|
||||
state.estimatedHit = 0
|
||||
return
|
||||
}
|
||||
if (state.secondaryHit > -1) {
|
||||
state.secondaryHit = 0
|
||||
return
|
||||
}
|
||||
sendMessage(player, "Larxus said you couldn't use special attacks in this duel.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import core.game.node.entity.player.Player
|
|||
import core.game.node.entity.skill.SkillPulse
|
||||
import core.game.node.entity.skill.Skills
|
||||
import content.data.skill.SkillingTool
|
||||
import core.ServerConstants
|
||||
import core.game.node.item.Item
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.Items
|
||||
|
|
@ -13,6 +14,9 @@ import core.game.world.GameWorld
|
|||
import core.game.world.repository.Repository
|
||||
import core.tools.colorize
|
||||
|
||||
// TODO: Shooting stars should roll for bonus gems while mining
|
||||
// See: https://youtu.be/6OqZ2TGc6fM?si=U8nB5IDQREhWXApD
|
||||
|
||||
/**
|
||||
* The pulse used to handle mining shooting stars.
|
||||
*/
|
||||
|
|
@ -53,7 +57,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
|
|||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered
|
||||
return player.skills.getLevel(Skills.MINING) >= star.miningLevel
|
||||
}
|
||||
|
||||
|
||||
if (player.skills.getLevel(Skills.MINING) < star.miningLevel) {
|
||||
player.dialogueInterpreter.sendDialogue("You need a Mining level of at least " + star.miningLevel + " in order to mine this layer.")
|
||||
return false
|
||||
|
|
@ -100,7 +104,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
|
|||
if (ShootingStarPlugin.getStarDust(player) < 200) {
|
||||
player.inventory.add(Item(ShootingStarPlugin.STAR_DUST, 1))
|
||||
}
|
||||
if(!inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && !inBank(player, Items.ANCIENT_BLUEPRINT_14651)){
|
||||
if (ServerConstants.SHOOTING_STAR_RING && hasAnItem(player, Items.ANCIENT_BLUEPRINT_14651).container == null) {
|
||||
rollBlueprint(player)
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +134,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
|
|||
|
||||
override fun message(type: Int) {
|
||||
when (type) {
|
||||
0 -> player.packetDispatch.sendMessage("You swing your pickaxe at the rock...")
|
||||
0 -> player.packetDispatch.sendMessage("You swing your pickaxe at the rock.")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,16 +133,16 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
}
|
||||
|
||||
override fun defineCommands() {
|
||||
define("tostar", Privilege.ADMIN) { player, _ ->
|
||||
define("tostar", Privilege.ADMIN, description = "Teleports you adjacent to the currently active star.") { player, _ ->
|
||||
teleport(player, star.starObject.location.transform(1,1,0))
|
||||
}
|
||||
|
||||
define("submit", Privilege.ADMIN) { _, _ ->
|
||||
define("submit", Privilege.ADMIN, description = "Rebuilds and fires the shooting star event immediately.") { _, _ ->
|
||||
star.rebuildVars()
|
||||
star.fire()
|
||||
}
|
||||
|
||||
define("resetsprite", Privilege.ADMIN) { player, _ ->
|
||||
define("resetsprite", Privilege.ADMIN, description = "Resets your star sprite reward cooldown.") { player, _ ->
|
||||
player.savedData.globalData.starSpriteDelay = 0L
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,57 @@ package content.global.ame
|
|||
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager.TeleportType
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
fun kidnapPlayer(player: Player, loc: Location, type: TeleportType) {
|
||||
setAttribute(player, "kidnapped-by-random", true) //only used in POH code when you leave the hut, so does not need /save. Do not rely on this outside of its intended POH use case.
|
||||
if (getAttribute(player, "/save:original-loc", null) == null) {
|
||||
setAttribute(player, "/save:original-loc", player.location)
|
||||
fun kidnapPlayer(npc: NPC, player: Player, dest: Location, playerLine: String? = null, callback: (player: Player, npc: NPC) -> Unit) {
|
||||
val lockDuration = if (playerLine != null) 4 else 6
|
||||
lock(player, lockDuration)
|
||||
queueScript(player, 1, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
if (playerLine != null) {
|
||||
sendChat(player, playerLine)
|
||||
return@queueScript delayScript(player, 2)
|
||||
}
|
||||
return@queueScript delayScript(player, 0)
|
||||
}
|
||||
1 -> {
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
2 -> {
|
||||
setAttribute(player, "kidnapped-by-random", true)
|
||||
if (getAttribute<Location?>(player, "/save:original-loc", null) == null) {
|
||||
setAttribute(player, "/save:original-loc", player.location)
|
||||
}
|
||||
teleport(player, dest, TeleportType.INSTANT)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player, 8941)
|
||||
resetAnimator(player)
|
||||
callback(player, npc)
|
||||
return@queueScript delayScript(player, 2)
|
||||
}
|
||||
3 -> {
|
||||
removeAttribute(player, "kidnapped-by-random") //this is not needed at this point anymore and will reenable the original-loc sanity check tick action
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
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)
|
||||
val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION)
|
||||
teleport(player, destination!!)
|
||||
unlock(player)
|
||||
removeAttributes(player, "/save:original-loc", "kidnapped-by-random")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import content.global.ame.events.surpriseexam.MysteriousOldManNPC
|
|||
import core.api.playGlobalAudio
|
||||
import core.api.poofClear
|
||||
import core.api.sendMessage
|
||||
import core.api.setAttribute
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.entity.Entity
|
||||
|
|
@ -19,8 +20,10 @@ import core.game.world.map.RegionManager
|
|||
import core.game.world.map.path.Pathfinder
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.integrations.discord.Discord
|
||||
import core.tools.RandomFunction
|
||||
import core.tools.secondsToTicks
|
||||
import core.tools.ticksToCycles
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.min
|
||||
|
|
@ -43,6 +46,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
event.loot = loot
|
||||
event.player = player
|
||||
event.spawnLocation = RegionManager.getSpawnLocation(player, this)
|
||||
setAttribute(event, "spawned-by-ame", true)
|
||||
return event
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +105,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
}
|
||||
|
||||
open fun onTimeUp() {
|
||||
noteAndTeleport()
|
||||
terminate()
|
||||
}
|
||||
|
||||
|
|
@ -144,4 +147,23 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1
|
||||
return ids[index]
|
||||
}
|
||||
|
||||
fun sayLine(npc: NPC, phrases: Array<String>, hasOpeningPhrase: Boolean, hasOverTimePhrase: Boolean) {
|
||||
if (!timerPaused && (ticksLeft % 20 == 0 || ticksLeft <= 2)) { //unless the Certer interface is up, speak every 20 ticks, or in the 2nd-to-last tick before attack/note-&-teleport
|
||||
var playDwarfWhistle = true
|
||||
if (ticksLeft == secondsToTicks(180) && hasOpeningPhrase) {
|
||||
sendChat(phrases[0])
|
||||
} else if (ticksLeft <= 2 && hasOverTimePhrase) {
|
||||
sendChat(phrases[phrases.size - 1])
|
||||
playDwarfWhistle = false
|
||||
} else {
|
||||
val start = if (hasOpeningPhrase) 0 else 1
|
||||
val end = if (hasOverTimePhrase) phrases.size - 2 else phrases.size - 1
|
||||
sendChat(phrases[RandomFunction.random(start, end + 1)])
|
||||
}
|
||||
if (npc.id == NPCs.DRUNKEN_DWARF_956 && playDwarfWhistle) {
|
||||
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,5 +97,4 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.ame.events
|
||||
|
||||
import core.api.getAttribute
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
|
|
@ -8,12 +9,12 @@ 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
|
||||
val xprate = super.getXpMultiplier(self, attacker)
|
||||
return if (getAttribute(self, "spawned-by-ame", false)) xprate / 16.0 else xprate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,42 +4,19 @@ 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.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
/** "::revent -p player_name -e candlelight" **/
|
||||
class PiousPeteNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PRIEST_3206) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
// Supposed to be "I'm sorry to drag you away from your tasks, but I need a little help with something." but it's too goddamn long.
|
||||
sendChat("${player.username.capitalize()}! I need a little help with something.")
|
||||
sendChat("${player.username}! I need a little help with something.")
|
||||
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 -> {
|
||||
CandlelightInterface.initCandlelight(player)
|
||||
kidnapPlayer(player, Location(1972, 5002, 0), TeleportManager.TeleportType.INSTANT)
|
||||
// AntiMacro.terminateEventNpc(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
openDialogue(player, PiousPeteStartingDialogueFile(), NPC(NPCs.PIOUS_PETE_3207))
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
kidnapPlayer(this, player, Location(1972, 5002, 0)) { player, _ ->
|
||||
CandlelightInterface.initCandlelight(player)
|
||||
openDialogue(player, PiousPeteStartingDialogueFile(), NPC(NPCs.PIOUS_PETE_3207))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,29 +2,19 @@ package content.global.ame.events.certer
|
|||
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.link.emote.Emotes
|
||||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.NPCs
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.animate
|
||||
import core.api.lock
|
||||
import core.api.utils.WeightBasedTable
|
||||
|
||||
class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) {
|
||||
lateinit var pName: String
|
||||
lateinit var phrases: Array<String>
|
||||
|
||||
override fun tick() {
|
||||
// Don't speak if we have the interface opened
|
||||
if (!timerPaused) {
|
||||
// Over allotted time phrase
|
||||
if (ticksLeft <= 2) {
|
||||
player.lock(2)
|
||||
sendChat(phrases[4])
|
||||
|
||||
// Say a phrase every 20 ticks starting at 280 ticks
|
||||
// as to not interfere with the init chat phrase
|
||||
} else if (ticksLeft <= 280 && ticksLeft % 20 == 0) {
|
||||
sendChat(phrases[RandomFunction.random(1, 3)])
|
||||
}
|
||||
sayLine(this, phrases, true, true)
|
||||
if (ticksLeft == 2) {
|
||||
lock(player, 2)
|
||||
}
|
||||
super.tick()
|
||||
}
|
||||
|
|
@ -36,15 +26,20 @@ class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NP
|
|||
|
||||
override fun init() {
|
||||
super.init()
|
||||
pName = player.username.capitalize()
|
||||
phrases = arrayOf("Greetings $pName, I need your help.",
|
||||
"ehem... Hello $pName, please talk to me!",
|
||||
"Hello, are you there $pName?",
|
||||
"It's really rude to ignore someone, $pName!",
|
||||
"No-one ignores me!")
|
||||
phrases = arrayOf(
|
||||
"Greetings ${player.username}, I need your help.",
|
||||
"ehem... Hello ${player.username}, please talk to me!",
|
||||
"Hello, are you there ${player.username}?",
|
||||
"It's really rude to ignore someone, ${player.username}!",
|
||||
"No-one ignores me!"
|
||||
)
|
||||
player.setAttribute("random:pause", false)
|
||||
player.setAttribute("certer:reward", false)
|
||||
sendChat(phrases[0])
|
||||
animate(this, Emotes.BOW.animation, true)
|
||||
}
|
||||
|
||||
override fun onTimeUp() {
|
||||
noteAndTeleport()
|
||||
terminate()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,9 @@
|
|||
package content.global.ame.events.drilldemon
|
||||
|
||||
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
|
||||
import org.rs09.consts.Items
|
||||
|
|
@ -24,13 +21,6 @@ object DrillDemonUtils {
|
|||
val DD_AREA = ZoneBorders(3158, 4817, 3168, 4823)
|
||||
val DD_NPC = NPCs.SERGEANT_DAMIEN_2790
|
||||
|
||||
fun teleport(player: Player) {
|
||||
kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT)
|
||||
player.interfaceManager.closeDefaultTabs()
|
||||
setComponentVisibility(player, 548, 69, true)
|
||||
setComponentVisibility(player, 746, 12, true)
|
||||
}
|
||||
|
||||
fun changeSignsAndAssignTask(player: Player) {
|
||||
setVarp(player, DD_SIGN_VARP, 0)
|
||||
val tempList = arrayListOf(DD_SIGN_JOG, DD_SIGN_JUMP, DD_SIGN_PUSHUP, DD_SIGN_SITUP).shuffled().toMutableList()
|
||||
|
|
@ -94,6 +84,5 @@ object DrillDemonUtils {
|
|||
}
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,32 +3,22 @@ package content.global.ame.events.drilldemon
|
|||
import core.game.node.entity.npc.NPC
|
||||
import org.rs09.consts.NPCs
|
||||
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.system.timer.impl.AntiMacro
|
||||
import core.tools.secondsToTicks
|
||||
import core.game.world.map.Location
|
||||
|
||||
class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat(player.username+ "! Drop and give me 20!")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, secondsToTicks(30))
|
||||
DrillDemonUtils.teleport(player)
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
return@queueScript delayScript(player, 2)
|
||||
}
|
||||
1 -> {
|
||||
openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
sendChat("${player.username}! Drop and give me 20!")
|
||||
face(player)
|
||||
kidnapPlayer(this, player, Location(3163, 4819, 0)) { player, _ ->
|
||||
player.interfaceManager.closeDefaultTabs()
|
||||
setComponentVisibility(player, 548, 69, true)
|
||||
setComponentVisibility(player, 746, 12, true)
|
||||
openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,35 +9,27 @@ import org.rs09.consts.NPCs
|
|||
import org.rs09.consts.Sounds
|
||||
|
||||
class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.DRUNKEN_DWARF_956) {
|
||||
private val phrases = arrayOf("Oi, are you der @name!","Dunt ignore your matey!","Aww comeon, talk to ikle me @name!")
|
||||
private var attackPhrase = false
|
||||
lateinit var phrases: Array<String>
|
||||
private var attackDelay = 0
|
||||
private var lastPhraseTime = 0
|
||||
|
||||
private fun sendPhrases() {
|
||||
if (getWorldTicks() > lastPhraseTime + 5) {
|
||||
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
|
||||
sendChat(this, phrases.random().replace("@name",player.username.capitalize()))
|
||||
this.face(player)
|
||||
lastPhraseTime = getWorldTicks()
|
||||
}
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297)
|
||||
sendChat(this, "'Ello der ${player.username.capitalize()}! *hic*")
|
||||
phrases = arrayOf(
|
||||
"'Ello der ${player.username}! *hic*",
|
||||
"Oi, are you der ${player.username}!",
|
||||
"Dunt ignore your matey!",
|
||||
"Aww comeon, talk to ikle me ${player.username}!",
|
||||
"I hates you, ${player.username}!"
|
||||
)
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
if (RandomFunction.roll(20) && !attackPhrase)
|
||||
sendPhrases()
|
||||
sayLine(this, phrases, true, true)
|
||||
if (ticksLeft <= 10) {
|
||||
ticksLeft = 10
|
||||
if (!attackPhrase)
|
||||
sendChat("I hates you, ${player.username.capitalize()}!").also { attackPhrase = true }
|
||||
if (attackDelay <= getWorldTicks())
|
||||
if (attackDelay <= getWorldTicks()) {
|
||||
this.attack(player)
|
||||
}
|
||||
}
|
||||
super.tick()
|
||||
}
|
||||
|
|
@ -47,4 +39,10 @@ class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEvent
|
|||
this.pulseManager.clear()
|
||||
openDialogue(player, DrunkenDwarfDialogue(), this.asNpc())
|
||||
}
|
||||
|
||||
override fun onTimeUp() {
|
||||
if (attackDelay <= getWorldTicks()) {
|
||||
this.attack(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +1,22 @@
|
|||
package content.global.ame.events.evilbob
|
||||
|
||||
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.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class EvilBobNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.EVIL_BOB_2478) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("meow")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendChat(player, "No... what? Nooooooooooooo!")
|
||||
animate(player, EvilBobUtils.teleAnim)
|
||||
player.graphics(EvilBobUtils.telegfx)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
EvilBobUtils.giveEventFishingSpot(player)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
sendMessage(player, "Welcome to Scape2009.")
|
||||
EvilBobUtils.teleport(player)
|
||||
resetAnimator(player)
|
||||
openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479)
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
face(player)
|
||||
kidnapPlayer(this, player, Location(3419, 4776, 0), "No... what? Nooooooooooooo!") { player, _ ->
|
||||
EvilBobUtils.giveEventFishingSpot(player)
|
||||
sendMessage(player, "Welcome to Scape2009.")
|
||||
openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
package content.global.ame.events.evilbob
|
||||
|
||||
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
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
|
|
@ -53,10 +49,6 @@ object EvilBobUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun teleport(player: Player) {
|
||||
kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
|
||||
removeAll(player, Items.FISHLIKE_THING_6202)
|
||||
|
|
|
|||
|
|
@ -3,38 +3,47 @@ package content.global.ame.events.evilbob
|
|||
import core.api.*
|
||||
import core.game.activity.Cutscene
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Direction
|
||||
|
||||
class ServantCutsceneN(player: Player) : Cutscene(player) {
|
||||
|
||||
override fun setup() {
|
||||
setExit(player.location.transform(0, 0, 0))
|
||||
loadRegion(13642)
|
||||
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
|
||||
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
|
||||
}
|
||||
|
||||
override fun runStage(stage: Int) {
|
||||
when (stage) {
|
||||
0 -> {
|
||||
fadeToBlack()
|
||||
timedUpdate(4)
|
||||
teleport(player, 30, 41)
|
||||
moveCamera(30, 37, 400, 255)
|
||||
rotateCamera(30, 50, 400, 255)
|
||||
openInterface(player, 186)
|
||||
timedUpdate(0)
|
||||
}
|
||||
1 -> {
|
||||
teleport(player, 29, 41)
|
||||
moveCamera(30, 43) // +7 from statue
|
||||
openInterface(player, 186)
|
||||
timedUpdate(0)
|
||||
}
|
||||
2 -> { // Slow start
|
||||
moveCamera(30, 49, 400, 2)
|
||||
timedUpdate(2)
|
||||
}
|
||||
2 -> {
|
||||
3 -> { // Fast middle
|
||||
moveCamera(30, 44, 380, 4)
|
||||
timedUpdate(6)
|
||||
}
|
||||
4 -> { // Slow end
|
||||
moveCamera(30, 45, 340, 2)
|
||||
timedUpdate(2)
|
||||
rotateCamera(30, 51, 300, 100) // the statue loc
|
||||
fadeFromBlack()
|
||||
}
|
||||
3 -> {
|
||||
timedUpdate(9)
|
||||
moveCamera(30, 46, 300, 2) // +4 from statue
|
||||
5 -> {
|
||||
timedUpdate(2)
|
||||
}
|
||||
4 -> {
|
||||
end{ player.locks.lockTeleport(1000000) }
|
||||
6 -> {
|
||||
closeInterface(player)
|
||||
end(fade = false) { player.locks.lockTeleport(1000000) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -45,32 +54,40 @@ class ServantCutsceneS(player: Player) : Cutscene(player) {
|
|||
override fun setup() {
|
||||
setExit(player.location.transform(0, 0, 0))
|
||||
loadRegion(13642)
|
||||
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
|
||||
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
|
||||
}
|
||||
|
||||
override fun runStage(stage: Int) {
|
||||
when (stage) {
|
||||
0 -> {
|
||||
fadeToBlack()
|
||||
timedUpdate(4)
|
||||
teleport(player, 30, 41)
|
||||
moveCamera(31, 46, 365, 255)
|
||||
rotateCamera(29, 30, 365, 255)
|
||||
openInterface(player, 186)
|
||||
timedUpdate(0)
|
||||
}
|
||||
1 -> {
|
||||
teleport(player, 29, 41)
|
||||
moveCamera(29, 38) // +7 from statue
|
||||
openInterface(player, 186)
|
||||
timedUpdate(2)
|
||||
timedUpdate(0)
|
||||
}
|
||||
2 -> {
|
||||
moveCamera(31, 43, 480, 2)
|
||||
timedUpdate(2)
|
||||
rotateCamera(29, 30, 300, 100) // the statue loc
|
||||
fadeFromBlack()
|
||||
}
|
||||
3 -> {
|
||||
timedUpdate(9)
|
||||
moveCamera(29, 35, 300, 2) // +4 from statue
|
||||
moveCamera(31, 37, 455, 4)
|
||||
timedUpdate(8)
|
||||
}
|
||||
4 -> {
|
||||
end{ player.locks.lockTeleport(1000000) }
|
||||
moveCamera(31, 36, 395, 2)
|
||||
timedUpdate(2)
|
||||
}
|
||||
5 -> {
|
||||
timedUpdate(3)
|
||||
}
|
||||
6 -> {
|
||||
closeInterface(player)
|
||||
end(fade = false) { player.locks.lockTeleport(1000000) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -81,32 +98,40 @@ class ServantCutsceneE(player: Player) : Cutscene(player) {
|
|||
override fun setup() {
|
||||
setExit(player.location.transform(0, 0, 0))
|
||||
loadRegion(13642)
|
||||
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
|
||||
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
|
||||
}
|
||||
|
||||
override fun runStage(stage: Int) {
|
||||
when (stage) {
|
||||
0 -> {
|
||||
fadeToBlack()
|
||||
timedUpdate(4)
|
||||
teleport(player, 30, 41)
|
||||
moveCamera(25, 41, 440, 255)
|
||||
rotateCamera(42, 41, 440, 255)
|
||||
openInterface(player, 186)
|
||||
timedUpdate(0)
|
||||
}
|
||||
1 -> {
|
||||
teleport(player, 29, 41)
|
||||
moveCamera(35, 41) // +7 from statue
|
||||
openInterface(player, 186)
|
||||
timedUpdate(0)
|
||||
}
|
||||
2 -> { // Slow start
|
||||
moveCamera(28, 41, 500, 3)
|
||||
timedUpdate(2)
|
||||
}
|
||||
2 -> {
|
||||
3 -> { // Fast middle
|
||||
moveCamera(34, 41, 390, 5)
|
||||
timedUpdate(6)
|
||||
}
|
||||
4 -> { // Slow end
|
||||
moveCamera(36, 41, 340, 2)
|
||||
timedUpdate(2)
|
||||
rotateCamera(43, 41, 300, 100) // the statue loc
|
||||
fadeFromBlack()
|
||||
}
|
||||
3 -> {
|
||||
timedUpdate(9)
|
||||
moveCamera(38, 41, 300, 2) // +4 from statue
|
||||
5 -> {
|
||||
timedUpdate(4)
|
||||
}
|
||||
4 -> {
|
||||
end{ player.locks.lockTeleport(1000000) }
|
||||
6 -> {
|
||||
closeInterface(player)
|
||||
end(fade = false) { player.locks.lockTeleport(1000000) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,34 +142,41 @@ class ServantCutsceneW(player: Player) : Cutscene(player) {
|
|||
override fun setup() {
|
||||
setExit(player.location.transform(0, 0, 0))
|
||||
loadRegion(13642)
|
||||
addNPC(2479, 28, 41, Direction.SOUTH) // Evil Bob
|
||||
addNPC(2481, 31, 41, Direction.SOUTH_WEST) // Servant
|
||||
}
|
||||
|
||||
override fun runStage(stage: Int) {
|
||||
when (stage) {
|
||||
0 -> {
|
||||
fadeToBlack()
|
||||
timedUpdate(4)
|
||||
teleport(player, 30, 41)
|
||||
moveCamera(34, 41, 325, 255)
|
||||
rotateCamera(16, 40, 300, 255)
|
||||
openInterface(player, 186)
|
||||
timedUpdate(0)
|
||||
}
|
||||
1 -> {
|
||||
teleport(player, 29, 41)
|
||||
moveCamera(25, 40) // +7 from statue
|
||||
openInterface(player, 186)
|
||||
timedUpdate(0)
|
||||
}
|
||||
2 -> { // Slow start
|
||||
moveCamera(31, 41, 440, 3)
|
||||
timedUpdate(2)
|
||||
}
|
||||
2 -> {
|
||||
3 -> { // Fast middle
|
||||
moveCamera(24, 41, 330, 5)
|
||||
timedUpdate(7)
|
||||
}
|
||||
4 -> { // Slow end
|
||||
moveCamera(23, 41, 300, 2)
|
||||
timedUpdate(2)
|
||||
rotateCamera(18, 40, 300, 100) // the statue loc
|
||||
fadeFromBlack()
|
||||
}
|
||||
3 -> {
|
||||
timedUpdate(9)
|
||||
moveCamera(22, 40, 300, 2) // +4 from statue
|
||||
5 -> {
|
||||
timedUpdate(3)
|
||||
}
|
||||
4 -> {
|
||||
end{ player.locks.lockTeleport(1000000) }
|
||||
6 -> {
|
||||
closeInterface(player)
|
||||
end(fade = false) { player.locks.lockTeleport(1000000) }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
package content.global.ame.events.freakyforester
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -28,10 +25,6 @@ object FreakUtils{
|
|||
player.dialogueInterpreter.open(FreakyForesterDialogue(), freakNpc)
|
||||
}
|
||||
|
||||
fun teleport(player: Player) {
|
||||
kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, freakTask, freakComplete, pheasantKilled)
|
||||
|
|
|
|||
|
|
@ -1,39 +1,21 @@
|
|||
package content.global.ame.events.freakyforester
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import content.global.ame.kidnapPlayer
|
||||
import core.api.*
|
||||
import org.rs09.consts.NPCs
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.Sounds
|
||||
import core.game.world.map.Location
|
||||
|
||||
class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.FREAKY_FORESTER_2458) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("Ah, ${player.username}, just the person I need!")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(308, 100, 50), player.location)
|
||||
animate(player,714)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
FreakUtils.teleport(player)
|
||||
FreakUtils.giveFreakTask(player)
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc)
|
||||
resetAnimator(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
face(player)
|
||||
kidnapPlayer(this, player, Location(2599, 4777, 0)) { player, _ ->
|
||||
FreakUtils.giveFreakTask(player)
|
||||
openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,27 +4,40 @@ import core.game.node.entity.npc.NPC
|
|||
import core.tools.RandomFunction
|
||||
import org.rs09.consts.NPCs
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.lock
|
||||
import core.api.playAudio
|
||||
import core.api.utils.WeightBasedTable
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GENIE_409) {
|
||||
val phrases = arrayOf("Greetings, @name!","Ehem... Master @name?","Are you there, Master @name?","No one ignores me!")
|
||||
lateinit var phrases: Array<String>
|
||||
|
||||
override fun tick() {
|
||||
if(RandomFunction.random(1,15) == 5){
|
||||
sendChat(phrases.random().replace("@name",player.username.capitalize()))
|
||||
sayLine(this, phrases, true, true)
|
||||
if (ticksLeft == 2) {
|
||||
lock(player, 2)
|
||||
}
|
||||
super.tick()
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
val honorific = if (player.isMale) "Master" else "Mistress"
|
||||
phrases = arrayOf(
|
||||
"Greetings, ${player.username}!",
|
||||
"Ehem... $honorific ${player.username}?",
|
||||
"Are you there, $honorific ${player.username}?",
|
||||
"No one ignores me!"
|
||||
)
|
||||
playAudio(player, Sounds.GENIE_APPEAR_2301)
|
||||
sendChat(phrases.random().replace("@name",player.username.capitalize()))
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
player.dialogueInterpreter.open(GenieDialogue(),npc)
|
||||
}
|
||||
|
||||
override fun onTimeUp() {
|
||||
noteAndTeleport()
|
||||
terminate()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,54 +4,29 @@ 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)
|
||||
}
|
||||
// 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(this, player, MazeInterface.STARTING_POINTS.random()) { player, _ ->
|
||||
MazeInterface.initMaze(player)
|
||||
removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
// Do nothing.
|
||||
sendMessage(player, "He isn't interested in talking to you.")
|
||||
}
|
||||
}
|
||||
|
|
@ -4,47 +4,22 @@ 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.component.Component.setUnclosable
|
||||
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
|
||||
|
||||
// "::revent [-p] <lt>player name<gt> [-e <lt>event name<gt>]"
|
||||
class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PILLORY_GUARD_2791) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("${player.username}, you're under arrest!")
|
||||
face(player)
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
PilloryInterface.initPillory(player)
|
||||
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)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
kidnapPlayer(this, player, PilloryInterface.LOCATIONS.random()) { player, _ ->
|
||||
PilloryInterface.initPillory(player)
|
||||
setUnclosable(player, player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from."))
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
//player.dialogueInterpreter.open(FreakyForesterDialogue(),npc)
|
||||
sendMessage(player, "He isn't interested in talking to you.")
|
||||
}
|
||||
}
|
||||
|
|
@ -5,15 +5,17 @@ import core.ServerConstants
|
|||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.api.utils.WeightedItem
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.component.Component
|
||||
import core.game.dialogue.DialogueLabeller
|
||||
import core.game.dialogue.DialogueOption
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class QuizMasterDialogueFile : DialogueFile() {
|
||||
class QuizMasterDialogueFile : DialogueLabeller() {
|
||||
companion object {
|
||||
const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191
|
||||
const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct"
|
||||
|
|
@ -74,56 +76,77 @@ class QuizMasterDialogueFile : DialogueFile() {
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
override fun addConversation() {
|
||||
assignToIds(NPCs.QUIZ_MASTER_2477)
|
||||
afterClose { player ->
|
||||
loadLabel(player, "question")
|
||||
}
|
||||
|
||||
npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>", unclosable = true)
|
||||
player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...", unclosable = true)
|
||||
npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "<col=FF0000>${player?.username}</col>!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!", unclosable = true)
|
||||
goto("question")
|
||||
|
||||
label("question")
|
||||
manual(unclosable = true) { player, _ ->
|
||||
setAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player))
|
||||
val comp = Component(QUIZMASTER_INTERFACE)
|
||||
player.interfaceManager.openChatbox(comp)
|
||||
return@manual comp
|
||||
}
|
||||
exec { player, _ ->
|
||||
if (buttonID == getAttribute(player, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) {
|
||||
// Correct Answer
|
||||
setAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1)
|
||||
if (getAttribute(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) {
|
||||
goto("winner")
|
||||
} else {
|
||||
// Wrong Answer
|
||||
npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!")
|
||||
stage = 3
|
||||
goto("right")
|
||||
}
|
||||
}
|
||||
// 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()
|
||||
} else {
|
||||
goto("wrong")
|
||||
}
|
||||
}
|
||||
|
||||
label("right")
|
||||
npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!", unclosable = true)
|
||||
goto("question")
|
||||
|
||||
label("wrong")
|
||||
npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!", unclosable = true)
|
||||
goto("question")
|
||||
|
||||
label("winner")
|
||||
npc(FacialExpression.FRIENDLY,"<col=08088A>CONGRATULATIONS!</col>", "You are a <col=8A0808>WINNER</col>!", "Please choose your <col=08088A>PRIZE</col>!", unclosable = true)
|
||||
options(
|
||||
DialogueOption("money", "1000 Coins", skipPlayer = true),
|
||||
DialogueOption("item", "Random Item", skipPlayer = true)
|
||||
)
|
||||
|
||||
label("money")
|
||||
exec { player, _ ->
|
||||
queueScript(player, 0, QueueStrength.SOFT) { _ ->
|
||||
addItemOrDrop(player, Items.COINS_995, 1000)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
goto("cleanup")
|
||||
|
||||
label("item")
|
||||
exec { player, _ ->
|
||||
queueScript(player, 0, QueueStrength.SOFT) { _ ->
|
||||
addItemOrDrop(player, tableRoll.roll()[0].id)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
goto("cleanup")
|
||||
|
||||
label("cleanup")
|
||||
exec { player, _ ->
|
||||
resetAnimator(player)
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
|
||||
}
|
||||
goto("nowhere")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,9 @@ 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:
|
||||
|
|
@ -27,35 +22,14 @@ class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable?
|
|||
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)
|
||||
}
|
||||
|
||||
face(player)
|
||||
kidnapPlayer(this, player, Location(1952, 4764, 0)) { player, _ ->
|
||||
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
|
||||
sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.")
|
||||
sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case.
|
||||
face(player, Location(1952, 4768, 1))
|
||||
animate(player,2378)
|
||||
// Quiz dialogue gets opened automatically on zone entry.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
package content.global.ame.events.rockgolem
|
||||
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.BattleState
|
||||
import core.game.node.entity.combat.CombatStyle
|
||||
import core.game.node.entity.combat.CombatSwingHandler
|
||||
import core.game.node.entity.combat.InteractionType
|
||||
import core.game.node.entity.impl.Projectile
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class RockGolemBehavior() : NPCBehavior(NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418) {
|
||||
private val swingHandler = RockGolemSwingHandler()
|
||||
|
||||
override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler {
|
||||
return swingHandler
|
||||
}
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return super.getXpMultiplier(self, attacker) / 16.0
|
||||
}
|
||||
}
|
||||
|
||||
private class RockGolemSwingHandler : CombatSwingHandler(CombatStyle.RANGE) {
|
||||
override fun canSwing(entity: Entity, victim: Entity): InteractionType? {
|
||||
return type?.swingHandler?.canSwing(entity, victim)
|
||||
}
|
||||
|
||||
override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int {
|
||||
if (entity == null || victim == null) return -1
|
||||
|
||||
val prayingRange = victim.hasProtectionPrayer(CombatStyle.RANGE)
|
||||
|
||||
type = if (prayingRange) {
|
||||
CombatStyle.MELEE
|
||||
} else {
|
||||
CombatStyle.RANGE
|
||||
}
|
||||
|
||||
if (type == CombatStyle.MELEE && entity.location.getDistance(victim.location) > 1) return -1
|
||||
|
||||
return type?.swingHandler?.swing(entity, victim, state) ?: 0
|
||||
}
|
||||
|
||||
override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) {
|
||||
type?.swingHandler?.impact(entity, victim, state)
|
||||
}
|
||||
|
||||
override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) {
|
||||
type?.swingHandler?.visualizeImpact(entity, victim, state)
|
||||
}
|
||||
|
||||
override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) {
|
||||
when (type) {
|
||||
CombatStyle.MELEE -> {
|
||||
entity.animate(Animation(153))
|
||||
}
|
||||
|
||||
CombatStyle.RANGE -> {
|
||||
val speed = (100 + (Projectile.getLocation(entity).getDistance(victim!!.getLocation()) * 5)).toInt()
|
||||
Projectile.create(entity, victim, 968, 48, 36, 80, speed, 5, entity.size() shl 5).send()
|
||||
entity.animate(Animation(5347))
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
override fun calculateAccuracy(entity: Entity?): Int {
|
||||
return type?.swingHandler?.calculateAccuracy(entity) ?: 0
|
||||
}
|
||||
|
||||
override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int {
|
||||
return type?.swingHandler?.calculateHit(entity, victim, modifier) ?: 0
|
||||
}
|
||||
|
||||
override fun calculateDefence(victim: Entity?, attacker: Entity?): Int {
|
||||
return type?.swingHandler?.calculateDefence(victim, attacker) ?: 0
|
||||
}
|
||||
|
||||
override fun getSetMultiplier(e: Entity?, skillId: Int): Double {
|
||||
return type?.swingHandler?.getSetMultiplier(e, skillId) ?: 0.0
|
||||
}
|
||||
}
|
||||
|
|
@ -5,32 +5,49 @@ import core.tools.RandomFunction
|
|||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.lock
|
||||
import core.api.utils.WeightBasedTable
|
||||
|
||||
class SandwichLadyRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SANDWICH_LADY_3117) {
|
||||
val phrases = arrayOf("Hello, @name, can you hear me?","Sandwiches, @name!","Are you ignoring me, @name??","Yoohoo! Sandwiches, @name!","Hello, @name?", "Come get your sandwiches, @name!", "How could you ignore me like this, @name?!", "Do you even want your sandwiches, @name?")
|
||||
lateinit var phrases: Array<String>
|
||||
var assigned_item = 0
|
||||
val items = arrayOf(Items.BAGUETTE_6961,Items.TRIANGLE_SANDWICH_6962,Items.SQUARE_SANDWICH_6965,Items.ROLL_6963,Items.MEAT_PIE_2327,Items.KEBAB_1971,Items.CHOCOLATE_BAR_1973)
|
||||
val items = arrayOf(Items.BAGUETTE_6961, Items.TRIANGLE_SANDWICH_6962, Items.SQUARE_SANDWICH_6965, Items.ROLL_6963, Items.MEAT_PIE_2327, Items.KEBAB_1971, Items.CHOCOLATE_BAR_1973)
|
||||
|
||||
override fun tick() {
|
||||
if(RandomFunction.random(1,15) == 5){
|
||||
sendChat(phrases.random().replace("@name",player.username.capitalize()))
|
||||
sayLine(this, phrases, true, true)
|
||||
if (ticksLeft == 2) {
|
||||
lock(player, 2)
|
||||
}
|
||||
super.tick()
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
phrases = arrayOf(
|
||||
// https://www.youtube.com/watch?v=ek8r3ZS929E
|
||||
// She always starts with "Sandwiches, ${player.username}!" but she ALSO picks that at random, hence duplicate it with hasOpeningPhrase = true
|
||||
"Sandwiches, ${player.username}!",
|
||||
"Sandwiches, ${player.username}!",
|
||||
"Come on ${player.username}, I made these specially!!",
|
||||
"All types of sandwiches, ${player.username}.",
|
||||
"Did you hear me ${player.username}?",
|
||||
"You think I made these just for fun?!!?",
|
||||
"How could you ignore me like this, ${player.username}?!" //unknown if authentic but it was already here
|
||||
)
|
||||
assignItem()
|
||||
sendChat(phrases.random().replace("@name",player.username.capitalize()))
|
||||
}
|
||||
|
||||
override fun onTimeUp() {
|
||||
noteAndTeleport()
|
||||
terminate()
|
||||
}
|
||||
|
||||
fun assignItem(){
|
||||
assigned_item = items.random()
|
||||
player.setAttribute("sandwich-lady:item",assigned_item)
|
||||
player.setAttribute("sandwich-lady:item", assigned_item)
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
player.dialogueInterpreter.open(SandwichLadyDialogue(false),npc)
|
||||
player.dialogueInterpreter.open(SandwichLadyDialogue(false), npc)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,32 +5,16 @@ import content.global.ame.kidnapPlayer
|
|||
import core.api.*
|
||||
import org.rs09.consts.NPCs
|
||||
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.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("Surprise exam, ${player.username}!")
|
||||
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(1886, 5025, 0), TeleportManager.TeleportType.INSTANT)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
face(player)
|
||||
kidnapPlayer(this, player, Location(1886, 5025, 0)) { _, _ ->
|
||||
/* nothing needed */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package content.global.ame.events.surpriseexam
|
|||
|
||||
import core.game.component.Component
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.NPCs
|
||||
|
|
@ -66,6 +65,6 @@ class SupriseExamListeners : InteractionListener, MapArea {
|
|||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
package content.global.ame.events.surpriseexam
|
||||
|
||||
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.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
|
||||
object SurpriseExamUtils {
|
||||
val SE_KEY_INDEX = "supexam:index"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package content.global.bots
|
||||
|
||||
import content.global.skill.fletching.log.LogCraftInfo
|
||||
import content.global.skill.fletching.log.CraftItemWithLogScript
|
||||
import core.game.bots.Script
|
||||
import core.game.bots.SkillingBotAssembler
|
||||
import core.game.node.entity.skill.Skills
|
||||
import content.global.skill.fletching.Fletching
|
||||
import content.global.skill.fletching.FletchingPulse
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
import core.game.bots.SkillingBotAssembler
|
||||
import core.game.bots.Script
|
||||
|
||||
class FletchingBankstander : Script(){
|
||||
var state = State.FLETCHING
|
||||
|
|
@ -17,7 +17,7 @@ class FletchingBankstander : Script(){
|
|||
State.FLETCHING -> {
|
||||
bot.inventory.add(Item(Items.KNIFE_946))
|
||||
bot.inventory.add(Item(Items.LOGS_1511,27))
|
||||
bot.pulseManager.run(FletchingPulse(bot, Item(Items.LOGS_1511),27, Fletching.FletchingItems.ARROW_SHAFT))
|
||||
CraftItemWithLogScript(bot, LogCraftInfo.ARROW_SHAFT, 27).invoke()
|
||||
State.BANKING
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,181 +0,0 @@
|
|||
package content.global.dialogue
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.IronmanMode
|
||||
import core.plugin.Initializable
|
||||
import core.game.dialogue.IfTopic
|
||||
import core.game.dialogue.Topic
|
||||
import content.global.handlers.npc.BankerNPC
|
||||
import core.tools.END_DIALOGUE
|
||||
import core.tools.START_DIALOGUE
|
||||
|
||||
@Initializable
|
||||
class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) {
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
when (stage) {
|
||||
START_DIALOGUE -> when {
|
||||
hasIronmanRestriction(player, IronmanMode.ULTIMATE) -> {
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.ANNOYED,
|
||||
"My apologies, dear ${if (player.isMale) "sir" else "madam"}, " +
|
||||
"our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}"
|
||||
).also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
else -> {
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"Good day, how may I help you?"
|
||||
).also {
|
||||
if (hasAwaitingGrandExchangeCollections(player)) {
|
||||
stage++
|
||||
} else {
|
||||
stage += 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1 -> npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"Before we go any further, I should inform you that you " +
|
||||
"have items ready for collection from the Grand Exchange."
|
||||
).also { stage++ }
|
||||
|
||||
2 -> showTopics(
|
||||
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to access my bank account, please.", 10),
|
||||
IfTopic(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"I'd like to switch to my ${getBankAccountName(player, true)} bank account.",
|
||||
13,
|
||||
hasActivatedSecondaryBankAccount(player)
|
||||
),
|
||||
IfTopic(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"I'd like to open a secondary bank account.",
|
||||
20,
|
||||
!hasActivatedSecondaryBankAccount(player)
|
||||
),
|
||||
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to check my PIN settings.", 11),
|
||||
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to collect items.", 12),
|
||||
Topic(core.game.dialogue.FacialExpression.ASKING, "What is this place?", 3),
|
||||
)
|
||||
|
||||
3 -> npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"This is a branch of the Bank of Gielinor. We have branches in many towns."
|
||||
).also { stage++ }
|
||||
|
||||
4 -> playerl(
|
||||
core.game.dialogue.FacialExpression.ASKING,
|
||||
"And what do you do?"
|
||||
).also { stage++ }
|
||||
|
||||
5 -> npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"We will look after your items and money for you. " +
|
||||
"Leave your valuables with us if you want to keep them safe."
|
||||
).also { stage = END_DIALOGUE }
|
||||
|
||||
10 -> {
|
||||
openBankAccount(player)
|
||||
end()
|
||||
}
|
||||
|
||||
11 -> {
|
||||
openBankPinSettings(player)
|
||||
end()
|
||||
}
|
||||
|
||||
12 -> {
|
||||
openGrandExchangeCollectionBox(player)
|
||||
end()
|
||||
}
|
||||
|
||||
13 -> {
|
||||
toggleBankAccount(player)
|
||||
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"Your active bank account has been switched. " +
|
||||
"You can now access your ${getBankAccountName(player)} account."
|
||||
).also { stage = 2 }
|
||||
}
|
||||
|
||||
20 -> npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"Certainly. We offer secondary accounts to all our customers."
|
||||
).also { stage++ }
|
||||
|
||||
21 -> npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable " +
|
||||
"and account activation is permanent."
|
||||
).also { stage++ }
|
||||
|
||||
22 -> npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"If your inventory does not contain enough money to cover the costs, we will complement " +
|
||||
"the amount with the money inside your primary bank account."
|
||||
).also { stage++ }
|
||||
|
||||
23 -> npcl(
|
||||
core.game.dialogue.FacialExpression.ASKING,
|
||||
"Knowing all this, would you like to proceed with opening your secondary bank account?"
|
||||
).also { stage++ }
|
||||
|
||||
24 -> showTopics(
|
||||
Topic(core.game.dialogue.FacialExpression.HAPPY, "Yes, I am still interested.", 25),
|
||||
Topic(core.game.dialogue.FacialExpression.ANNOYED, "Actually, I've changed my mind.", 26)
|
||||
)
|
||||
|
||||
25 -> {
|
||||
when (activateSecondaryBankAccount(player)) {
|
||||
SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> {
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"Your bank account was already activated, there is no need to pay twice."
|
||||
).also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> {
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.ANNOYED,
|
||||
"I must apologize, the transaction was not successful. Please check your " +
|
||||
"primary bank account and your inventory - if there's money missing, please " +
|
||||
"screenshot your chat box and contact the game developers."
|
||||
).also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> {
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.ANNOYED,
|
||||
"It appears that you do not have the money necessary to cover the costs " +
|
||||
"associated with opening a secondary bank account. I will be waiting here " +
|
||||
"until you do."
|
||||
).also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
SecondaryBankAccountActivationResult.SUCCESS -> {
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"Your secondary bank account has been opened and can be accessed through any " +
|
||||
"of the Bank of Gielinor's employees. Thank you for choosing our services."
|
||||
).also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26 -> npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"Very well. Should you decide a secondary bank account is needed, do not hesitate to " +
|
||||
"contact any of the Bank of Gielinor's stationary employees. We will be happy to help."
|
||||
).also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray = BankerNPC.NPC_IDS
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.handlers.iface
|
||||
|
||||
import content.global.handlers.iface.BookInterface.Companion.FANCY_BOOK_2_27
|
||||
import core.api.closeInterface
|
||||
import core.api.getAttribute
|
||||
import core.api.openInterface
|
||||
|
|
@ -158,9 +159,22 @@ class BookInterface : InterfaceListener {
|
|||
if (pageSet == getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0)) {
|
||||
player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false)
|
||||
player.packetDispatch.sendModelOnInterface(modelId, componentId, drawLineId, 0)
|
||||
player.packetDispatch.sendAngleOnInterface(componentId, drawLineId, zoom, pitch, yaw)
|
||||
} else {
|
||||
player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, true)
|
||||
player.packetDispatch.sendAngleOnInterface(componentId, drawLineId, zoom, pitch, yaw)
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets item on lineId of pageSet (0 index). Call this in the display function after pageSetup. */
|
||||
fun setItemOnPage(player: Player, pageSet: Int, itemId: Int, componentId: Int, enableLineId: Int, drawLineId: Int, zoom: Int, pitch: Int, yaw: Int) {
|
||||
if (pageSet == getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0)) {
|
||||
player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false)
|
||||
player.packetDispatch.sendItemOnInterface(itemId, 1, componentId, drawLineId)
|
||||
}
|
||||
}
|
||||
|
||||
/** Clears models(pictures) on lineId of pageSet (0 index). Call this in the display function after pageSetup. */
|
||||
fun clearModelsOnPage(player: Player, componentId: Int) {
|
||||
BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS.forEach { drawId ->
|
||||
player.packetDispatch.sendInterfaceConfig(componentId, drawId, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ class HairDresserInterface : ComponentPlugin(){
|
|||
when(button){
|
||||
199 -> player.setAttribute("beard-setting",false)
|
||||
200 -> player.setAttribute("beard-setting",true)
|
||||
196,274 -> pay(player)
|
||||
196,274,68,100 -> pay(player)
|
||||
else -> when(component?.id){
|
||||
592 -> { //Female
|
||||
if(femaleColorButtonRange.contains(button)){
|
||||
|
|
|
|||
|
|
@ -43,13 +43,39 @@ class EmptyOptionListener : InteractionListener {
|
|||
BUCKET_OF_SLIME(Items.BUCKET_OF_SLIME_4286, Items.BUCKET_1925, "You empty the contents of the bucket on the floor.", Sounds.LIQUID_2401),
|
||||
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),
|
||||
JUG_OF_WATER(Items.JUG_OF_WATER_1937, Items.JUG_1935, "You empty the contents of the jug onto the floor.", Sounds.LIQUID_2401),
|
||||
BURNT_PIE(Items.BURNT_PIE_2329, Items.PIE_DISH_2313, "You empty the pie dish."),
|
||||
POTION(Items.POTION_195, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401),
|
||||
BURNT_STEW(Items.BURNT_STEW_2005, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401),
|
||||
NETTLE_TEA(Items.NETTLE_TEA_4239, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401),
|
||||
CUP_OF_TEA(Items.CUP_OF_TEA_4242, Items.EMPTY_CUP_1980, "You empty the cup of tea.", Sounds.LIQUID_2401),
|
||||
NETTLE_WATER(Items.NETTLE_WATER_4237, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401),
|
||||
NETTLE_TEA_MILKY(Items.NETTLE_TEA_4240, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401),
|
||||
NETTLE_TEA_CUP(Items.CUP_OF_TEA_4242, Items.EMPTY_CUP_1980, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
NETTLE_TEA_CUP_MILKY(Items.CUP_OF_TEA_4243, Items.EMPTY_CUP_1980, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
TEA_CUP_WATER(Items.CUP_OF_WATER_4458, Items.EMPTY_CUP_1980, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
TEA_CUP_HOT_WATER(Items.CUP_OF_HOT_WATER_4460, Items.EMPTY_CUP_1980, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
NETTLE_TEA_PORCELAIN(Items.CUP_OF_TEA_4245, Items.PORCELAIN_CUP_4244, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
NETTLE_TEA_PORCELAIN_MILKY(Items.CUP_OF_TEA_4246, Items.PORCELAIN_CUP_4244, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
BUILDERS_TEA1(Items.CUP_OF_TEA_7730, Items.EMPTY_CUP_7728, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
BUILDERS_TEA1_MILKY(Items.CUP_OF_TEA_7731, Items.EMPTY_CUP_7728, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
BUILDERS_TEA2(Items.CUP_OF_TEA_7733, Items.PORCELAIN_CUP_7732, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
BUILDERS_TEA2_MILKY(Items.CUP_OF_TEA_7734, Items.PORCELAIN_CUP_7732, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
BUILDERS_TEA3(Items.CUP_OF_TEA_7736, Items.PORCELAIN_CUP_7735, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
BUILDERS_TEA3_MILKY(Items.CUP_OF_TEA_7737, Items.PORCELAIN_CUP_7735, "You empty the contents of the cup onto the floor.", Sounds.LIQUID_2401),
|
||||
CLAY_POT_OF_TEA4(Items.POT_OF_TEA_4_7692, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
CLAY_POT_OF_TEA3(Items.POT_OF_TEA_3_7694, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
CLAY_POT_OF_TEA2(Items.POT_OF_TEA_2_7696, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
CLAY_POT_OF_TEA1(Items.POT_OF_TEA_1_7698, Items.TEAPOT_7702, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
PORCELAIN_POT_OF_TEA4(Items.POT_OF_TEA_4_7704, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
PORCELAIN_POT_OF_TEA3(Items.POT_OF_TEA_3_7706, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
PORCELAIN_POT_OF_TEA2(Items.POT_OF_TEA_2_7708, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
PORCELAIN_POT_OF_TEA1(Items.POT_OF_TEA_1_7710, Items.TEAPOT_7714, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
GOLD_PORCELAIN_POT_OF_TEA4(Items.POT_OF_TEA_4_7716, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
GOLD_PORCELAIN_POT_OF_TEA3(Items.POT_OF_TEA_3_7718, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
GOLD_PORCELAIN_POT_OF_TEA2(Items.POT_OF_TEA_2_7720, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
GOLD_PORCELAIN_POT_OF_TEA1(Items.POT_OF_TEA_1_7722, Items.TEAPOT_7726, "You empty the contents of the pot onto the floor", Sounds.LIQUID_2401),
|
||||
BURNT_CURRY(Items.BURNT_CURRY_2013, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401),
|
||||
BURNT_GNOMEBOWL(Items.BURNT_GNOMEBOWL_2175, Items.GNOMEBOWL_MOULD_2166, "You empty the contents of the gnomebowl onto the floor."),
|
||||
BURNT_EGG(Items.BURNT_EGG_7090, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."),
|
||||
|
|
|
|||
|
|
@ -1,85 +1,94 @@
|
|||
package content.global.handlers.item
|
||||
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.info.LogType
|
||||
import core.game.node.entity.player.info.PlayerMonitor
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Animations
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class EnchantJewelleryTabListener : InteractionListener {
|
||||
|
||||
private val LVL_1_ENCHANT = mapOf(
|
||||
Items.SAPPHIRE_RING_1637 to Items.RING_OF_RECOIL_2550,
|
||||
Items.SAPPHIRE_NECKLACE_1656 to Items.GAMES_NECKLACE8_3853,
|
||||
Items.SAPPHIRE_AMULET_1694 to Items.AMULET_OF_MAGIC_1727,
|
||||
Items.SAPPHIRE_BRACELET_11072 to Items.BRACELET_OF_CLAY_11074
|
||||
Items.SAPPHIRE_RING_1637 to Items.RING_OF_RECOIL_2550,
|
||||
Items.SAPPHIRE_NECKLACE_1656 to Items.GAMES_NECKLACE8_3853,
|
||||
Items.SAPPHIRE_AMULET_1694 to Items.AMULET_OF_MAGIC_1727,
|
||||
Items.SAPPHIRE_BRACELET_11072 to Items.BRACELET_OF_CLAY_11074
|
||||
)
|
||||
private val LVL_2_ENCHANT = mapOf(
|
||||
Items.EMERALD_RING_1639 to Items.RING_OF_DUELLING8_2552,
|
||||
Items.EMERALD_NECKLACE_1658 to Items.BINDING_NECKLACE_5521,
|
||||
Items.EMERALD_AMULET_1696 to Items.AMULET_OF_DEFENCE_1729,
|
||||
Items.EMERALD_BRACELET_11076 to Items.CASTLEWAR_BRACE3_11079
|
||||
Items.EMERALD_RING_1639 to Items.RING_OF_DUELLING8_2552,
|
||||
Items.EMERALD_NECKLACE_1658 to Items.BINDING_NECKLACE_5521,
|
||||
Items.EMERALD_AMULET_1696 to Items.AMULET_OF_DEFENCE_1729,
|
||||
Items.EMERALD_BRACELET_11076 to Items.CASTLEWAR_BRACE3_11079
|
||||
)
|
||||
|
||||
private val LVL_3_ENCHANT = mapOf(
|
||||
Items.RUBY_RING_1641 to Items.RING_OF_FORGING_2568,
|
||||
Items.RUBY_NECKLACE_1660 to Items.DIGSITE_PENDANT_5_11194,
|
||||
Items.RUBY_AMULET_1698 to Items.AMULET_OF_STRENGTH_1725,
|
||||
Items.RUBY_BRACELET_11085 to Items.INOCULATION_BRACE_11088
|
||||
Items.RUBY_RING_1641 to Items.RING_OF_FORGING_2568,
|
||||
Items.RUBY_NECKLACE_1660 to Items.DIGSITE_PENDANT_5_11194,
|
||||
Items.RUBY_AMULET_1698 to Items.AMULET_OF_STRENGTH_1725,
|
||||
Items.RUBY_BRACELET_11085 to Items.INOCULATION_BRACE_11088
|
||||
)
|
||||
|
||||
private val LVL_4_ENCHANT = mapOf(
|
||||
Items.DIAMOND_RING_1643 to Items.RING_OF_LIFE_2570,
|
||||
Items.DIAMOND_NECKLACE_1662 to Items.PHOENIX_NECKLACE_11090,
|
||||
Items.DIAMOND_AMULET_1700 to Items.AMULET_OF_POWER_1731,
|
||||
Items.DIAMOND_BRACELET_11092 to Items.FORINTHRY_BRACE5_11095
|
||||
Items.DIAMOND_RING_1643 to Items.RING_OF_LIFE_2570,
|
||||
Items.DIAMOND_NECKLACE_1662 to Items.PHOENIX_NECKLACE_11090,
|
||||
Items.DIAMOND_AMULET_1700 to Items.AMULET_OF_POWER_1731,
|
||||
Items.DIAMOND_BRACELET_11092 to Items.FORINTHRY_BRACE5_11095
|
||||
)
|
||||
|
||||
private val LVL_5_ENCHANT = mapOf(
|
||||
Items.DRAGONSTONE_RING_1645 to Items.RING_OF_WEALTH4_14646,
|
||||
Items.DRAGON_NECKLACE_1664 to Items.SKILLS_NECKLACE4_11105,
|
||||
Items.DRAGONSTONE_AMMY_1702 to Items.AMULET_OF_GLORY4_1712,
|
||||
Items.DRAGON_BRACELET_11115 to Items.COMBAT_BRACELET4_11118
|
||||
Items.DRAGONSTONE_RING_1645 to Items.RING_OF_WEALTH_2572,
|
||||
Items.DRAGON_NECKLACE_1664 to Items.SKILLS_NECKLACE_11113,
|
||||
Items.DRAGONSTONE_AMMY_1702 to Items.AMULET_OF_GLORY_1704,
|
||||
Items.DRAGON_BRACELET_11115 to Items.COMBAT_BRACELET_11126
|
||||
)
|
||||
|
||||
private val LVL_6_ENCHANT = mapOf(
|
||||
Items.ONYX_RING_6575 to Items.RING_OF_STONE_6583,
|
||||
Items.ONYX_NECKLACE_6577 to Items.BERSERKER_NECKLACE_11128,
|
||||
Items.ONYX_AMULET_6581 to Items.AMULET_OF_FURY_6585,
|
||||
Items.ONYX_BRACELET_11130 to Items.REGEN_BRACELET_11133
|
||||
Items.ONYX_RING_6575 to Items.RING_OF_STONE_6583,
|
||||
Items.ONYX_NECKLACE_6577 to Items.BERSERKER_NECKLACE_11128,
|
||||
Items.ONYX_AMULET_6581 to Items.AMULET_OF_FURY_6585,
|
||||
Items.ONYX_BRACELET_11130 to Items.REGEN_BRACELET_11133
|
||||
)
|
||||
private val TAB_MAPPING = arrayOf(
|
||||
Pair(Items.ENCHANT_SAPPHIRE_8016, LVL_1_ENCHANT),
|
||||
Pair(Items.ENCHANT_EMERALD_8017, LVL_2_ENCHANT),
|
||||
Pair(Items.ENCHANT_RUBY_8018, LVL_3_ENCHANT),
|
||||
Pair(Items.ENCHANT_DIAMOND_8019, LVL_4_ENCHANT),
|
||||
Pair(Items.ENCHANT_DRAGONSTN_8020, LVL_5_ENCHANT),
|
||||
Pair(Items.ENCHANT_ONYX_8021, LVL_6_ENCHANT)
|
||||
)
|
||||
|
||||
override fun defineListeners() {
|
||||
on(IntType.ITEM, "break") {player, node ->
|
||||
closeAllInterfaces(player)
|
||||
delayEntity(player, 1)
|
||||
queueScript(player, strength = QueueStrength.SOFT) {
|
||||
|
||||
val items = when (node.id) {
|
||||
8016 -> LVL_1_ENCHANT //Sapphire
|
||||
8017 -> LVL_2_ENCHANT
|
||||
8018 -> LVL_3_ENCHANT
|
||||
8019 -> LVL_4_ENCHANT
|
||||
8020 -> LVL_5_ENCHANT
|
||||
8021 -> LVL_6_ENCHANT
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
if (inInventory(player, node.id)) {
|
||||
for (item in player.inventory.toArray()) {
|
||||
if (item == null) continue
|
||||
val product = items[item.id] ?: continue
|
||||
if (removeItem(player, node.id) && (removeItem(player, item.id)) && addItem(player, product)) {
|
||||
playAudio(player, Sounds.POH_TABLET_BREAK_979)
|
||||
animate(player, 4069, true)
|
||||
break
|
||||
for ((tablet, mapping) in TAB_MAPPING) {
|
||||
on(tablet, IntType.ITEM, "break") { player, _ ->
|
||||
sendMessage(player, "Try using the tablet on the item instead.") //TODO authentic message
|
||||
return@on true
|
||||
}
|
||||
for ((unenchanted, enchanted) in mapping) {
|
||||
onUseWith(IntType.ITEM, tablet, unenchanted) { player, tabItem, node ->
|
||||
var product = enchanted
|
||||
if (product == Items.RING_OF_WEALTH_2572 && ServerConstants.RING_OF_WEALTH_TELEPORT) {
|
||||
product = Items.RING_OF_WEALTH_14638
|
||||
}
|
||||
if (removeItem(player, Item(tabItem.id))) {
|
||||
closeAllInterfaces(player)
|
||||
playAudio(player, Sounds.POH_TABLET_BREAK_979)
|
||||
val anim = Animation(Animations.POH_TABLET_BREAK_4069)
|
||||
animate(player, anim, true)
|
||||
delayEntity(player, anim.duration)
|
||||
queueScript(player, anim.duration, QueueStrength.SOFT) {
|
||||
val item = node.asItem()
|
||||
val ret = replaceSlot(player, item.slot, Item(product), item)
|
||||
if (ret != item) {
|
||||
PlayerMonitor.log(player, LogType.DUPE_ALERT, "Unknown slot-replacement problem when enchanting jewellery (adding $product replaced $ret rather than $item)")
|
||||
}
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,244 @@
|
|||
package content.global.handlers.item.equipment
|
||||
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
|
||||
/**
|
||||
* Barrows equipment information and utilities.
|
||||
* @author 'Vexia - original code
|
||||
* @author Damighty - Kotlin conversion and refactor
|
||||
*/
|
||||
object BarrowsEquipment {
|
||||
// Barrows equipment lasts for 15 hours of combat. Each piece has 4 degradation tiers (100, 75, 50, 25).
|
||||
const val DEGRADATION_TICKS_PER_TIER = (15 * 6000) / 4 // 22500 ticks per tier
|
||||
private const val MAX_DURABILITY = DEGRADATION_TICKS_PER_TIER * 4
|
||||
|
||||
/**
|
||||
* A data class for each Barrows piece. Holds all information related to a specific piece of Barrows gear.
|
||||
*
|
||||
* @param brother The Barrows brother this item belongs to.
|
||||
* @param equipmentType The slot type ("weapon", "body", "legs", "helm").
|
||||
* @param itemName The formatted name of the item.
|
||||
* @param baseRepairCost The full repair cost in GP.
|
||||
* @param degradationStates A list of item IDs, from fully repaired (index 0) to broken (index 5).
|
||||
*/
|
||||
data class BarrowsItemDefinition(
|
||||
val brother: String,
|
||||
val equipmentType: String,
|
||||
val itemName: String,
|
||||
val baseRepairCost: Int,
|
||||
val degradationStates: List<Int>
|
||||
) {
|
||||
val repairedId: Int = degradationStates.first()
|
||||
val brokenId: Int = degradationStates.last()
|
||||
|
||||
/** Checks if a given item ID belongs to this specific equipment set. */
|
||||
fun contains(itemId: Int): Boolean = itemId in degradationStates
|
||||
|
||||
/** Gets the degradation index for a given item ID (0=repaired, 1=100, ..., 5=broken). */
|
||||
fun getDegradationIndex(itemId: Int): Int = degradationStates.indexOf(itemId)
|
||||
}
|
||||
|
||||
/** All Barrows equipment data. */
|
||||
private val barrowsItemDefinitions = listOf(
|
||||
// Dharok
|
||||
BarrowsItemDefinition("dharok", "helm", "Dharok's helm", 60_000,
|
||||
listOf(Items.DHAROKS_HELM_4716, Items.DHAROKS_HELM_100_4880,
|
||||
Items.DHAROKS_HELM_75_4881, Items.DHAROKS_HELM_50_4882,
|
||||
Items.DHAROKS_HELM_25_4883, Items.DHAROKS_HELM_0_4884)),
|
||||
BarrowsItemDefinition("dharok", "weapon", "Dharok's greataxe", 100_000,
|
||||
listOf(Items.DHAROKS_GREATAXE_4718, Items.DHAROKS_AXE_100_4886,
|
||||
Items.DHAROKS_AXE_75_4887, Items.DHAROKS_AXE_50_4888,
|
||||
Items.DHAROKS_AXE_25_4889, Items.DHAROKS_AXE_0_4890)),
|
||||
BarrowsItemDefinition("dharok", "body", "Dharok's platebody", 90_000,
|
||||
listOf(Items.DHAROKS_PLATEBODY_4720, Items.DHAROKS_BODY_100_4892,
|
||||
Items.DHAROKS_BODY_75_4893, Items.DHAROKS_BODY_50_4894,
|
||||
Items.DHAROKS_BODY_25_4895, Items.DHAROKS_BODY_0_4896)),
|
||||
BarrowsItemDefinition("dharok", "legs", "Dharok's platelegs", 80_000,
|
||||
listOf(Items.DHAROKS_PLATELEGS_4722, Items.DHAROKS_LEGS_100_4898,
|
||||
Items.DHAROKS_LEGS_75_4899, Items.DHAROKS_LEGS_50_4900,
|
||||
Items.DHAROKS_LEGS_25_4901, Items.DHAROKS_LEGS_0_4902)),
|
||||
// Guthan
|
||||
BarrowsItemDefinition("guthan", "helm", "Guthan's helm", 60_000,
|
||||
listOf(Items.GUTHANS_HELM_4724, Items.GUTHANS_HELM_100_4904,
|
||||
Items.GUTHANS_HELM_75_4905, Items.GUTHANS_HELM_50_4906,
|
||||
Items.GUTHANS_HELM_25_4907, Items.GUTHANS_HELM_0_4908)),
|
||||
BarrowsItemDefinition("guthan", "weapon", "Guthan's warspear", 100_000,
|
||||
listOf(Items.GUTHANS_WARSPEAR_4726, Items.GUTHANS_SPEAR_100_4910,
|
||||
Items.GUTHANS_SPEAR_75_4911, Items.GUTHANS_SPEAR_50_4912,
|
||||
Items.GUTHANS_SPEAR_25_4913, Items.GUTHANS_SPEAR_0_4914)),
|
||||
BarrowsItemDefinition("guthan", "body", "Guthan's platebody", 90_000,
|
||||
listOf(Items.GUTHANS_PLATEBODY_4728, Items.GUTHANS_BODY_100_4916,
|
||||
Items.GUTHANS_BODY_75_4917, Items.GUTHANS_BODY_50_4918,
|
||||
Items.GUTHANS_BODY_25_4919, Items.GUTHANS_BODY_0_4920)),
|
||||
BarrowsItemDefinition("guthan", "legs", "Guthan's chainskirt", 80_000,
|
||||
listOf(Items.GUTHANS_CHAINSKIRT_4730, Items.GUTHANS_SKIRT_100_4922,
|
||||
Items.GUTHANS_SKIRT_75_4923, Items.GUTHANS_SKIRT_50_4924,
|
||||
Items.GUTHANS_SKIRT_25_4925, Items.GUTHANS_SKIRT_0_4926)),
|
||||
// Torag
|
||||
BarrowsItemDefinition("torag", "helm", "Torag's helm", 60_000,
|
||||
listOf(Items.TORAGS_HELM_4745, Items.TORAGS_HELM_100_4952,
|
||||
Items.TORAGS_HELM_75_4953, Items.TORAGS_HELM_50_4954,
|
||||
Items.TORAGS_HELM_25_4955, Items.TORAGS_HELM_0_4956)),
|
||||
BarrowsItemDefinition("torag", "weapon", "Torag's hammers", 100_000,
|
||||
listOf(Items.TORAGS_HAMMERS_4747, Items.TORAGS_HAMMER_100_4958,
|
||||
Items.TORAGS_HAMMER_75_4959, Items.TORAGS_HAMMER_50_4960,
|
||||
Items.TORAGS_HAMMER_25_4961, Items.TORAGS_HAMMER_0_4962)),
|
||||
BarrowsItemDefinition("torag", "body", "Torag's platebody", 90_000,
|
||||
listOf(Items.TORAGS_PLATEBODY_4749, Items.TORAGS_BODY_100_4964,
|
||||
Items.TORAGS_BODY_75_4965, Items.TORAGS_BODY_50_4966,
|
||||
Items.TORAGS_BODY_25_4967, Items.TORAGS_BODY_0_4968)),
|
||||
BarrowsItemDefinition("torag", "legs", "Torag's platelegs", 80_000,
|
||||
listOf(Items.TORAGS_PLATELEGS_4751, Items.TORAGS_LEGS_100_4970,
|
||||
Items.TORAGS_LEGS_75_4971, Items.TORAGS_LEGS_50_4972,
|
||||
Items.TORAGS_LEGS_25_4973, Items.TORAGS_LEGS_0_4974)),
|
||||
// Verac
|
||||
BarrowsItemDefinition("verac", "helm", "Verac's helm", 60_000,
|
||||
listOf(Items.VERACS_HELM_4753, Items.VERACS_HELM_100_4976,
|
||||
Items.VERACS_HELM_75_4977, Items.VERACS_HELM_50_4978,
|
||||
Items.VERACS_HELM_25_4979, Items.VERACS_HELM_0_4980)),
|
||||
BarrowsItemDefinition("verac", "weapon", "Verac's flail", 100_000,
|
||||
listOf(Items.VERACS_FLAIL_4755, Items.VERACS_FLAIL_100_4982,
|
||||
Items.VERACS_FLAIL_75_4983, Items.VERACS_FLAIL_50_4984,
|
||||
Items.VERACS_FLAIL_25_4985, Items.VERACS_FLAIL_0_4986)),
|
||||
BarrowsItemDefinition("verac", "body", "Verac's brassard", 90_000,
|
||||
listOf(Items.VERACS_BRASSARD_4757, Items.VERACS_TOP_100_4988,
|
||||
Items.VERACS_TOP_75_4989, Items.VERACS_TOP_50_4990,
|
||||
Items.VERACS_TOP_25_4991, Items.VERACS_TOP_0_4992)),
|
||||
BarrowsItemDefinition("verac", "legs", "Verac's plateskirt", 80_000,
|
||||
listOf(Items.VERACS_PLATESKIRT_4759, Items.VERACS_SKIRT_100_4994,
|
||||
Items.VERACS_SKIRT_75_4995, Items.VERACS_SKIRT_50_4996,
|
||||
Items.VERACS_SKIRT_25_4997, Items.VERACS_SKIRT_0_4998)),
|
||||
// Ahrim
|
||||
BarrowsItemDefinition("ahrim", "helm", "Ahrim's hood", 60_000,
|
||||
listOf(Items.AHRIMS_HOOD_4708, Items.AHRIMS_HOOD_100_4856,
|
||||
Items.AHRIMS_HOOD_75_4857, Items.AHRIMS_HOOD_50_4858,
|
||||
Items.AHRIMS_HOOD_25_4859, Items.AHRIMS_HOOD_0_4860)),
|
||||
BarrowsItemDefinition("ahrim", "weapon", "Ahrim's staff", 100_000,
|
||||
listOf(Items.AHRIMS_STAFF_4710, Items.AHRIMS_STAFF_100_4862,
|
||||
Items.AHRIMS_STAFF_75_4863, Items.AHRIMS_STAFF_50_4864,
|
||||
Items.AHRIMS_STAFF_25_4865, Items.AHRIMS_STAFF_0_4866)),
|
||||
BarrowsItemDefinition("ahrim", "body", "Ahrim's robetop", 90_000,
|
||||
listOf(Items.AHRIMS_ROBETOP_4712, Items.AHRIMS_TOP_100_4868,
|
||||
Items.AHRIMS_TOP_75_4869, Items.AHRIMS_TOP_50_4870,
|
||||
Items.AHRIMS_TOP_25_4871, Items.AHRIMS_TOP_0_4872)),
|
||||
BarrowsItemDefinition("ahrim", "legs", "Ahrim's robeskirt", 80_000,
|
||||
listOf(Items.AHRIMS_ROBESKIRT_4714, Items.AHRIMS_SKIRT_100_4874,
|
||||
Items.AHRIMS_SKIRT_75_4875, Items.AHRIMS_SKIRT_50_4876,
|
||||
Items.AHRIMS_SKIRT_25_4877, Items.AHRIMS_SKIRT_0_4878)),
|
||||
// Karil
|
||||
BarrowsItemDefinition("karil", "helm", "Karil's coif", 60_000,
|
||||
listOf(Items.KARILS_COIF_4732, Items.KARILS_COIF_100_4928,
|
||||
Items.KARILS_COIF_75_4929, Items.KARILS_COIF_50_4930,
|
||||
Items.KARILS_COIF_25_4931, Items.KARILS_COIF_0_4932)),
|
||||
BarrowsItemDefinition("karil", "weapon", "Karil's crossbow", 100_000,
|
||||
listOf(Items.KARILS_CROSSBOW_4734, Items.KARILS_X_BOW_100_4934,
|
||||
Items.KARILS_X_BOW_75_4935, Items.KARILS_X_BOW_50_4936,
|
||||
Items.KARILS_X_BOW_25_4937, Items.KARILS_X_BOW_0_4938)),
|
||||
BarrowsItemDefinition("karil", "body", "Karil's leathertop", 90_000,
|
||||
listOf(Items.KARILS_LEATHERTOP_4736, Items.KARILS_TOP_100_4940,
|
||||
Items.KARILS_TOP_75_4941, Items.KARILS_TOP_50_4942,
|
||||
Items.KARILS_TOP_25_4943, Items.KARILS_TOP_0_4944)),
|
||||
BarrowsItemDefinition("karil", "legs", "Karil's leatherskirt", 80_000,
|
||||
listOf(Items.KARILS_LEATHERSKIRT_4738, Items.KARILS_SKIRT_100_4946,
|
||||
Items.KARILS_SKIRT_75_4947, Items.KARILS_SKIRT_50_4948,
|
||||
Items.KARILS_SKIRT_25_4949, Items.KARILS_SKIRT_0_4950))
|
||||
)
|
||||
|
||||
/** Cached access to an item's full definition from its ID */
|
||||
private val itemIdToDefinitionMap: Map<Int, BarrowsItemDefinition> by lazy {
|
||||
barrowsItemDefinitions.flatMap { def ->
|
||||
def.degradationStates.map { id -> id to def }
|
||||
}.toMap()
|
||||
}
|
||||
|
||||
/** Gets all degradation state arrays for degradation registration */
|
||||
fun getAllEquipmentSets(): Collection<IntArray> = barrowsItemDefinitions.map { it.degradationStates.toIntArray() }
|
||||
|
||||
/** Gets all repairable Barrows item IDs (anything not fully repaired) */
|
||||
fun getAllRepairableBarrowsIds(): List<Int> = itemIdToDefinitionMap.filter { !isFullyRepaired(it.key) }.keys.toList()
|
||||
|
||||
/** Gets the full definition for a Barrows item */
|
||||
@JvmStatic
|
||||
fun getDefinition(itemId: Int): BarrowsItemDefinition? = itemIdToDefinitionMap[itemId]
|
||||
|
||||
/** Checks if an item ID is any Barrows item */
|
||||
@JvmStatic
|
||||
fun isBarrowsItem(itemId: Int): Boolean = itemId in itemIdToDefinitionMap
|
||||
|
||||
/** Checks if a Barrows item is fully repaired */
|
||||
@JvmStatic
|
||||
fun isFullyRepaired(itemId: Int): Boolean = getDefinition(itemId)?.repairedId == itemId
|
||||
|
||||
/** Checks if a Barrows item is broken */
|
||||
@JvmStatic
|
||||
fun isBroken(itemId: Int): Boolean = getDefinition(itemId)?.brokenId == itemId
|
||||
|
||||
/**
|
||||
* Calculates the repair cost for a degraded Barrows item
|
||||
* @param item The degraded Barrows item
|
||||
* @return The repair cost in GP, or -1 if the item cannot be repaired
|
||||
*/
|
||||
fun getRepairCost(item: Item): Int {
|
||||
val def = getDefinition(item.id) ?: return -1
|
||||
if (isFullyRepaired(item.id)) return -1
|
||||
|
||||
val totalRemainingDurability = calculateTotalRemainingDurability(item, def)
|
||||
val durabilityLost = MAX_DURABILITY - totalRemainingDurability
|
||||
val cost = ((durabilityLost.toDouble() / MAX_DURABILITY) * def.baseRepairCost).toInt()
|
||||
|
||||
return cost
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the durability of a Barrows item by 20% of its total remaining durability
|
||||
* @param item The Barrows item
|
||||
* @return The item with reduced durability, or null if the item is not a valid Barrows piece
|
||||
*/
|
||||
@JvmStatic
|
||||
fun graveDeathDurabilityReduction(item: Item): Item? {
|
||||
val def = getDefinition(item.id) ?: return null
|
||||
if (isBroken(item.id)) return item
|
||||
|
||||
val totalRemainingDurability = calculateTotalRemainingDurability(item, def)
|
||||
val durabilityReduction = (totalRemainingDurability * 0.2).toInt()
|
||||
val newRemainingDurability = totalRemainingDurability - durabilityReduction
|
||||
|
||||
return createItemFromDurability(def, newRemainingDurability, item.amount)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total remaining durability ticks (charge) for a Barrows item
|
||||
*/
|
||||
private fun calculateTotalRemainingDurability(item: Item, def: BarrowsItemDefinition): Int {
|
||||
return when (val index = def.getDegradationIndex(item.id)) {
|
||||
-1 -> 0 // Invalid
|
||||
0 -> MAX_DURABILITY // Fully repaired
|
||||
5 -> 0 // Broken
|
||||
else -> {
|
||||
// For degraded items (100, 75, 50, 25), durability is the number of fully remaining tiers below it, plus the charge of the current tier.
|
||||
// Index 1 (100) has 3 tiers below it. Index 4 (25) has 0 tiers below it.
|
||||
val remainingTiers = 4 - index
|
||||
(remainingTiers * DEGRADATION_TICKS_PER_TIER) + item.charge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Item instance based on a total durability value
|
||||
*/
|
||||
private fun createItemFromDurability(def: BarrowsItemDefinition, durability: Int, amount: Int): Item {
|
||||
if (durability <= 0) {
|
||||
return Item(def.brokenId, amount)
|
||||
}
|
||||
// Tier is 1-indexed (1=25, 2=50, 3=75, 4=100)
|
||||
val tier = ((durability - 1) / DEGRADATION_TICKS_PER_TIER) + 1
|
||||
// Degradation index is 4-indexed (4=25, 3=50, 2=75, 1=100)
|
||||
val degradationIndex = 5 - tier
|
||||
|
||||
val newId = def.degradationStates[degradationIndex]
|
||||
val newCharge = (durability - 1) % DEGRADATION_TICKS_PER_TIER + 1
|
||||
|
||||
return Item(newId, amount, newCharge)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,73 +4,16 @@ import core.plugin.Initializable
|
|||
import core.plugin.Plugin
|
||||
|
||||
@Initializable
|
||||
class BarrowsEquipmentRegister : Plugin<Any>{
|
||||
public companion object {
|
||||
// Barrows equipment lasts for 15 hours of combat, and each piece has 4 stages of degredation
|
||||
@JvmField
|
||||
public val TICKS = (15 * 6000) / 4
|
||||
}
|
||||
|
||||
val DHAROK_HELM = arrayOf(4716,4880,4881,4882,4883,4884)
|
||||
val DHAROK_AXE = arrayOf(4718,4886,4887,4888,4889,4890)
|
||||
val DHAROK_BODY = arrayOf(4720,4892,4893,4894,4895,4896)
|
||||
val DHAROK_LEGS = arrayOf(4722,4898,4899,4900,4901,4902)
|
||||
|
||||
val GUTHAN_HELM = arrayOf(4724,4904,4905,4906,4907,4908)
|
||||
val GUTHAN_SPEAR = arrayOf(4726,4910,4911,4912,4913,4914)
|
||||
val GUTHAN_BODY = arrayOf(4728,4916,4917,4918,4919,4920)
|
||||
val GUTHAN_SKIRT = arrayOf(4730,4922,4923,4924,4925,4926)
|
||||
|
||||
val TORAG_HELM = arrayOf(4745,4952,4953,4954,4955,4956)
|
||||
val TORAG_HAMMER = arrayOf(4747,4958,4959,4960,4961,4962)
|
||||
val TORAG_BODY = arrayOf(4749,4964,4965,4966,4967,4968)
|
||||
val TORAG_LEGS = arrayOf(4751,4970,4971,4972,4973,4974)
|
||||
|
||||
val VERAC_HELM = arrayOf(4753,4976,4977,4978,4979,4980)
|
||||
val VERAC_FLAIL = arrayOf(4755,4982,4983,4984,4985,4986)
|
||||
val VERAC_BRASS = arrayOf(4757,4988,4989,4990,4991,4992)
|
||||
val VERAC_SKIRT = arrayOf(4759,4994,4995,4996,4997,4998)
|
||||
|
||||
val AHRIM_HOOD = arrayOf(4708,4856,4857,4858,4859,4860)
|
||||
val AHRIM_STAFF = arrayOf(4710,4862,4863,4864,4865,4866)
|
||||
val AHRIM_TOP = arrayOf(4712,4868,4869,4870,4871,4872)
|
||||
val AHRIM_SKIRT = arrayOf(4714,4874,4875,4876,4877,4878)
|
||||
|
||||
val KARIL_COIF = arrayOf(4732,4928,4929,4930,4931,4932)
|
||||
val KARIL_CBOW = arrayOf(4734,4934,4935,4936,4937,4938)
|
||||
val KARIL_TOP = arrayOf(4736,4940,4941,4942,4943,4944)
|
||||
val KARIL_SKIRT = arrayOf(4738,4946,4947,4948,4949,4950)
|
||||
|
||||
class BarrowsEquipmentRegister : Plugin<Any> {
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
EquipmentDegrader.registerSet(TICKS, AHRIM_HOOD)
|
||||
EquipmentDegrader.registerSet(TICKS, AHRIM_STAFF)
|
||||
EquipmentDegrader.registerSet(TICKS, AHRIM_TOP)
|
||||
EquipmentDegrader.registerSet(TICKS, AHRIM_SKIRT)
|
||||
EquipmentDegrader.registerSet(TICKS, KARIL_COIF)
|
||||
EquipmentDegrader.registerSet(TICKS, KARIL_CBOW)
|
||||
EquipmentDegrader.registerSet(TICKS, KARIL_TOP)
|
||||
EquipmentDegrader.registerSet(TICKS, KARIL_SKIRT)
|
||||
EquipmentDegrader.registerSet(TICKS, DHAROK_HELM)
|
||||
EquipmentDegrader.registerSet(TICKS, DHAROK_AXE)
|
||||
EquipmentDegrader.registerSet(TICKS, DHAROK_BODY)
|
||||
EquipmentDegrader.registerSet(TICKS, DHAROK_LEGS)
|
||||
EquipmentDegrader.registerSet(TICKS, GUTHAN_HELM)
|
||||
EquipmentDegrader.registerSet(TICKS, GUTHAN_SPEAR)
|
||||
EquipmentDegrader.registerSet(TICKS, GUTHAN_BODY)
|
||||
EquipmentDegrader.registerSet(TICKS, GUTHAN_SKIRT)
|
||||
EquipmentDegrader.registerSet(TICKS, TORAG_HELM)
|
||||
EquipmentDegrader.registerSet(TICKS, TORAG_HAMMER)
|
||||
EquipmentDegrader.registerSet(TICKS, TORAG_BODY)
|
||||
EquipmentDegrader.registerSet(TICKS, TORAG_LEGS)
|
||||
EquipmentDegrader.registerSet(TICKS, VERAC_HELM)
|
||||
EquipmentDegrader.registerSet(TICKS, VERAC_FLAIL)
|
||||
EquipmentDegrader.registerSet(TICKS, VERAC_BRASS)
|
||||
EquipmentDegrader.registerSet(TICKS, VERAC_SKIRT)
|
||||
BarrowsEquipment.getAllEquipmentSets().forEach {
|
||||
degradationSet ->
|
||||
EquipmentDegrader.registerSet(BarrowsEquipment.DEGRADATION_TICKS_PER_TIER, degradationSet.toTypedArray())
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun fireEvent(identifier: String?, vararg args: Any?): Any {
|
||||
return Unit
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import core.game.world.map.RegionManager;
|
|||
import core.game.world.update.flag.context.Graphics;
|
||||
import core.tools.RandomFunction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -54,13 +55,15 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler {
|
|||
entity.getProperties().getCombatPulse().stop();
|
||||
return -1;
|
||||
}
|
||||
@SuppressWarnings("rawtypes")
|
||||
List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(victim, 14, entity) : RegionManager.getSurroundingPlayers(victim, 14, entity);
|
||||
BattleState[] targets = new BattleState[list.size()];
|
||||
|
||||
// ! Initial capacity of 14, but has dynamic size? i.e. we are not restricting to a max of 14 targets hit here now
|
||||
List<Entity> targetCandidates = new ArrayList<>(14);
|
||||
targetCandidates.addAll(RegionManager.getSurroundingNPCs(victim, 14, entity));
|
||||
targetCandidates.addAll(RegionManager.getSurroundingPlayers(victim, 14, entity));
|
||||
BattleState[] targets = new BattleState[targetCandidates.size()];
|
||||
int count = 0;
|
||||
for (Object o : list) {
|
||||
Entity e = (Entity) o;
|
||||
if (canSwing(entity, e) != InteractionType.NO_INTERACT) {
|
||||
for (Entity e : targetCandidates) {
|
||||
if (canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
|
||||
BattleState s = targets[count++] = new BattleState(entity, e);
|
||||
s.setStyle(CombatStyle.RANGE);
|
||||
int hit = 0;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements
|
|||
|
||||
@Override
|
||||
public void impact(Entity entity, Entity victim, BattleState state) {
|
||||
if (state.getTargets() != null) {
|
||||
if (state != null && state.getTargets() != null) {
|
||||
for (BattleState s : state.getTargets()) {
|
||||
if (s != null) {
|
||||
s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s);
|
||||
|
|
@ -81,13 +81,13 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements
|
|||
int count = 0;
|
||||
for (Object o : list) {
|
||||
Entity e = (Entity) o;
|
||||
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) {
|
||||
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
|
||||
BattleState s = targets[count++] = new BattleState(entity, e);
|
||||
int hit = 0;
|
||||
if (isAccurateImpact(entity, e)) {
|
||||
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
|
||||
}
|
||||
s.setStyle(CombatStyle.MELEE);
|
||||
s.setStyle(CombatStyle.MELEE);
|
||||
s.setEstimatedHit(hit);
|
||||
}
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements
|
|||
|
||||
@Override
|
||||
public void visualizeImpact(Entity entity, Entity victim, BattleState state) {
|
||||
if (state.getTargets() != null) {
|
||||
if (state != null && state.getTargets() != null) {
|
||||
for (BattleState s : state.getTargets()) {
|
||||
if (s != null) {
|
||||
s.getVictim().animate(victim.getProperties().getDefenceAnimation());
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements
|
|||
|
||||
@Override
|
||||
public void impact(Entity entity, Entity victim, BattleState state) {
|
||||
if (state.getTargets() != null) {
|
||||
if (state != null && state.getTargets() != null) {
|
||||
for (BattleState s : state.getTargets()) {
|
||||
if (s != null) {
|
||||
s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s);
|
||||
|
|
@ -82,11 +82,11 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements
|
|||
int count = 0;
|
||||
for (Object o : list) {
|
||||
Entity e = (Entity) o;
|
||||
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) {
|
||||
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
|
||||
BattleState s = targets[count++] = new BattleState(entity, e);
|
||||
int hit = 0;
|
||||
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
|
||||
s.setStyle(CombatStyle.MELEE);
|
||||
s.setStyle(CombatStyle.MELEE);
|
||||
s.setEstimatedHit(hit);
|
||||
}
|
||||
}
|
||||
|
|
@ -96,13 +96,13 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements
|
|||
|
||||
@Override
|
||||
public void visualize(Entity entity, Entity victim, BattleState state) {
|
||||
playGlobalAudio(entity.getLocation(), Sounds.CLEAVE_2529);
|
||||
entity.visualize(ANIMATION, GRAPHIC);
|
||||
playGlobalAudio(entity.getLocation(), Sounds.CLEAVE_2529);
|
||||
entity.visualize(ANIMATION, GRAPHIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visualizeImpact(Entity entity, Entity victim, BattleState state) {
|
||||
if (state.getTargets() != null) {
|
||||
if (state != null && state.getTargets() != null) {
|
||||
for (BattleState s : state.getTargets()) {
|
||||
if (s != null) {
|
||||
s.getVictim().animate(victim.getProperties().getDefenceAnimation());
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug
|
|||
BattleState[] targets = getTargets(entity, victim, state);
|
||||
state.setTargets(targets);
|
||||
for (BattleState s : targets) {
|
||||
s.setStyle(CombatStyle.MELEE);
|
||||
s.setStyle(CombatStyle.MELEE);
|
||||
int hit = 0;
|
||||
if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE)) {
|
||||
hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1) + 1);
|
||||
|
|
@ -90,7 +90,7 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug
|
|||
*/
|
||||
private BattleState[] getTargets(Entity entity, Entity victim, BattleState state) {
|
||||
if (!entity.getProperties().isMultiZone() || !victim.getProperties().isMultiZone()) {
|
||||
return new BattleState[] { state };
|
||||
return new BattleState[]{state};
|
||||
}
|
||||
Location vl = victim.getLocation();
|
||||
int x = vl.getX();
|
||||
|
|
@ -102,6 +102,9 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug
|
|||
if (n instanceof Familiar) {
|
||||
continue;
|
||||
}
|
||||
if (!n.isAttackable(entity, CombatStyle.MELEE, false)) {
|
||||
continue;
|
||||
}
|
||||
if (n.getLocation().equals(vl.transform(dir.getStepY(), dir.getStepX(), 0)) || n.getLocation().equals(vl.transform(-dir.getStepY(), -dir.getStepX(), 0))) {
|
||||
l.add(new BattleState(entity, n));
|
||||
if (l.size() >= 3) {
|
||||
|
|
@ -127,7 +130,7 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug
|
|||
|
||||
@Override
|
||||
public void impact(Entity entity, Entity victim, BattleState state) {
|
||||
if (state.getTargets() != null) {
|
||||
if (state != null && state.getTargets() != null) {
|
||||
for (BattleState s : state.getTargets()) {
|
||||
if (s != null) {
|
||||
s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s);
|
||||
|
|
@ -146,7 +149,7 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug
|
|||
|
||||
@Override
|
||||
public void visualizeImpact(Entity entity, Entity victim, BattleState state) {
|
||||
if (state.getTargets() != null) {
|
||||
if (state != null && state.getTargets() != null) {
|
||||
for (BattleState s : state.getTargets()) {
|
||||
if (s != null) {
|
||||
s.getVictim().animate(victim.getProperties().getDefenceAnimation());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package content.global.handlers.item.withitem
|
||||
|
||||
import core.api.*
|
||||
import org.rs09.consts.Items
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.info.LogType
|
||||
import core.game.node.entity.player.info.PlayerMonitor
|
||||
import core.game.node.item.Item
|
||||
|
||||
class GrindToothListener : InteractionListener {
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.ITEM, Items.PESTLE_AND_MORTAR_233, Items.SUQAH_TOOTH_9079) { player, _, with ->
|
||||
val item = with as Item
|
||||
val res = replaceSlot(player, item.slot, Item(Items.GROUND_TOOTH_9082))
|
||||
if (res?.id == Items.SUQAH_TOOTH_9079) {
|
||||
sendMessage(player, "You grind the suqah tooth to dust.") //https://www.youtube.com/watch?v=RdIcNH50v7I
|
||||
} else {
|
||||
PlayerMonitor.log(player, LogType.DUPE_ALERT, "Player ground item ${res?.name} instead of a suqah tooth - potential slot-based manipulation attempt")
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -129,6 +129,14 @@ class WaterSourceListener : InteractionListener {
|
|||
FISHBOWL(
|
||||
inputs = intArrayOf(Items.FISHBOWL_6667),
|
||||
output = Items.FISHBOWL_6668
|
||||
),
|
||||
KETTLE(
|
||||
inputs = intArrayOf(Items.KETTLE_7688),
|
||||
output = Items.FULL_KETTLE_7690
|
||||
),
|
||||
CUP(
|
||||
inputs = intArrayOf(Items.EMPTY_CUP_1980),
|
||||
output = Items.CUP_OF_WATER_4458
|
||||
);
|
||||
|
||||
companion object
|
||||
|
|
|
|||
|
|
@ -1,62 +1,54 @@
|
|||
package content.global.handlers.npc
|
||||
|
||||
import content.global.handlers.scenery.BankBoothListener
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.dialogue.ChatAnim
|
||||
import core.game.dialogue.DialogueLabeller
|
||||
import core.game.dialogue.DialogueOption
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.AbstractNPC
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.IronmanMode
|
||||
import core.game.world.map.Direction
|
||||
import core.game.world.map.Location
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.NPCs
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import content.global.handlers.scenery.BankBoothListener
|
||||
|
||||
/**
|
||||
* Provides dialogue tree for all generic banker NPCs as well as
|
||||
* handles all the common interactions like 'bank' and 'collect'.
|
||||
*
|
||||
* @author vddCore
|
||||
* @author Player Name
|
||||
*/
|
||||
@Initializable
|
||||
class BankerNPC : AbstractNPC, InteractionListener {
|
||||
val NPC_IDS = intArrayOf(
|
||||
NPCs.BANKER_44, NPCs.BANKER_45, NPCs.BANKER_494, NPCs.BANKER_495, NPCs.BANKER_496, NPCs.BANKER_497,
|
||||
NPCs.BANKER_498, NPCs.BANKER_499, NPCs.BANKER_1036, NPCs.BANKER_1360, NPCs.BANKER_2163, NPCs.BANKER_2164,
|
||||
NPCs.BANKER_2354, NPCs.BANKER_2355, NPCs.BANKER_2568, NPCs.BANKER_2569, NPCs.BANKER_2570, NPCs.BANKER_3198,
|
||||
NPCs.BANKER_3199, NPCs.BANKER_5258, NPCs.BANKER_5259, NPCs.BANKER_5260, NPCs.BANKER_5261, NPCs.BANKER_5776,
|
||||
NPCs.BANKER_5777, NPCs.BANKER_5912, NPCs.BANKER_5913, NPCs.BANKER_6200, NPCs.BANKER_6532, NPCs.BANKER_6533,
|
||||
NPCs.BANKER_6534, NPCs.BANKER_6535, NPCs.BANKER_7445, NPCs.BANKER_7446, NPCs.BANKER_7605,
|
||||
NPCs.GUNDAI_902,
|
||||
NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046, NPCs.MAGNUS_GRAM_5488, NPCs.TZHAAR_KET_ZUH_2619,
|
||||
NPCs.SIRSAL_BANKER_4519, NPCs.FADLI_958, NPCs.BANK_TUTOR_4907, NPCs.JADE_4296,
|
||||
NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050,
|
||||
NPCs.BANKER_6538
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val LUNAR_ISLE_BANK_REGION = 8253
|
||||
|
||||
val SPECIAL_NPC_IDS = intArrayOf(
|
||||
NPCs.SIRSAL_BANKER_4519, NPCs.FADLI_958, NPCs.BANK_TUTOR_4907, NPCs.JADE_4296,
|
||||
NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050, NPCs.ARNOLD_LYDSPOR_3824,
|
||||
|
||||
/* Maximillian Sackville - Near Wilderness bounty-hunter area. */
|
||||
NPCs.BANKER_6538
|
||||
)
|
||||
|
||||
val NPC_IDS = intArrayOf(
|
||||
NPCs.BANKER_44, NPCs.BANKER_45, NPCs.BANKER_494, NPCs.BANKER_495, NPCs.BANKER_496, NPCs.BANKER_497,
|
||||
NPCs.BANKER_498, NPCs.BANKER_499, NPCs.BANKER_1036, NPCs.BANKER_1360, NPCs.BANKER_2163, NPCs.BANKER_2164,
|
||||
NPCs.BANKER_2354, NPCs.BANKER_2355, NPCs.BANKER_2568, NPCs.BANKER_2569, NPCs.BANKER_2570, NPCs.BANKER_3198,
|
||||
NPCs.BANKER_3199, NPCs.BANKER_5258, NPCs.BANKER_5259, NPCs.BANKER_5260, NPCs.BANKER_5261, NPCs.BANKER_5776,
|
||||
NPCs.BANKER_5777, NPCs.BANKER_5912, NPCs.BANKER_5913, NPCs.BANKER_6200, NPCs.BANKER_6532, NPCs.BANKER_6533,
|
||||
NPCs.BANKER_6534, NPCs.BANKER_6535, NPCs.BANKER_7445, NPCs.BANKER_7446, NPCs.BANKER_7605,
|
||||
NPCs.GUNDAI_902,
|
||||
|
||||
NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046, NPCs.MAGNUS_GRAM_5488, NPCs.TZHAAR_KET_ZUH_2619,
|
||||
)
|
||||
|
||||
private val ALL_BANKER_NPC_IDS = intArrayOf(
|
||||
*SPECIAL_NPC_IDS,
|
||||
*NPC_IDS
|
||||
)
|
||||
|
||||
/**
|
||||
* This is poorly named, but performs a few checks to see if the player
|
||||
* is trying to access the bank on the Lunar Isle and returns a boolean
|
||||
* controlling whether or not to pass the quick bank or collection use.
|
||||
*
|
||||
* TODO
|
||||
* The location of this method is shit too. Find a better place for it?
|
||||
*/
|
||||
fun checkLunarIsleRestriction(player: Player, node: Node): Boolean {
|
||||
if (node.location.regionId != LUNAR_ISLE_BANK_REGION)
|
||||
|
|
@ -121,37 +113,35 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
|||
|
||||
private fun provideDestinationOverride(entity: Entity, node: Node): Location {
|
||||
val npc = node as NPC
|
||||
|
||||
return when(npc.id) {
|
||||
/* Ogress bankers are 2x2 with their spawn being offset to south-western tile. */
|
||||
NPCs.OGRESS_BANKER_7049,
|
||||
NPCs.OGRESS_BANKER_7050 -> npc.location.transform(3, 1, 0)
|
||||
|
||||
NPCs.BANKER_6532, NPCs.BANKER_6533,
|
||||
NPCs.BANKER_6534, NPCs.BANKER_6535 -> npc.location.transform(npc.direction, 1)
|
||||
|
||||
NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050 -> npc.location.transform(3, 1, 0)
|
||||
/* Magnus has no bank booth nearby so we need to handle that edge case here. */
|
||||
NPCs.MAGNUS_GRAM_5488 -> npc.location.transform(Direction.NORTH, 2)
|
||||
|
||||
/* Special-cased NPCs, idk why */
|
||||
NPCs.BANKER_6532, NPCs.BANKER_6533, NPCs.BANKER_6534, NPCs.BANKER_6535 -> npc.location.transform(npc.direction, 1)
|
||||
else -> {
|
||||
if (npc is BankerNPC) {
|
||||
npc.findAdjacentBankBoothLocation()?.let {
|
||||
return it.second
|
||||
}
|
||||
}
|
||||
|
||||
return npc.location
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(ALL_BANKER_NPC_IDS, IntType.NPC, "bank", handler = Companion::attemptBank)
|
||||
on(ALL_BANKER_NPC_IDS, IntType.NPC, "collect", handler = Companion::attemptCollect)
|
||||
on(NPC_IDS, IntType.NPC, "bank", handler = Companion::attemptBank)
|
||||
on(NPC_IDS, IntType.NPC, "collect", handler = Companion::attemptCollect)
|
||||
on(NPC_IDS, IntType.NPC, "talk-to") { player, node ->
|
||||
DialogueLabeller.open(player, BankerDialogueLabellerFile(), node as NPC)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineDestinationOverrides() {
|
||||
setDest(IntType.NPC, ALL_BANKER_NPC_IDS, "bank", "collect", "talk-to", handler = ::provideDestinationOverride)
|
||||
setDest(IntType.NPC, NPC_IDS, "bank", "collect", "talk-to", handler = ::provideDestinationOverride)
|
||||
}
|
||||
|
||||
override fun init() {
|
||||
|
|
@ -167,5 +157,167 @@ class BankerNPC : AbstractNPC, InteractionListener {
|
|||
}
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray = ALL_BANKER_NPC_IDS
|
||||
class BankerDialogueLabellerFile : DialogueLabeller() {
|
||||
val BANKERS_WITH_EXTRA_OPTION = intArrayOf(NPCs.BANK_TUTOR_4907, NPCs.JADE_4296, NPCs.BANKER_6538)
|
||||
|
||||
override fun addConversation() {
|
||||
exec { player, npc ->
|
||||
if (npc.id == NPCs.SIRSAL_BANKER_4519 && !hasSealOfPassage(player)) {
|
||||
loadLabel(player, "no seal of passage")
|
||||
}
|
||||
if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) {
|
||||
if (npc.id == NPCs.JADE_4296) loadLabel(player, "uim for jade")
|
||||
loadLabel(player, "uim")
|
||||
}
|
||||
if (npc.id == NPCs.JADE_4296) loadLabel(player, "hello for jade")
|
||||
loadLabel(player, "hello")
|
||||
}
|
||||
label("no seal of passage")
|
||||
npc(ChatAnim.ANNOYED, "What are you doing here, Fremennik?!")
|
||||
player(ChatAnim.WORRIED, "I have a Seal of Pass...")
|
||||
npc(ChatAnim.ANGRY, "No you don't! Begone!")
|
||||
// todo: kick them out, but only one of the two banker types should do so (see historical wiki)
|
||||
goto("nowhere")
|
||||
label("uim for jade")
|
||||
npc(ChatAnim.ANNOYED, "Greetings, warrior. I wish I could help you, but our services are not available for Ultimate Iron@g[men,women].")
|
||||
goto("nowhere")
|
||||
label("uim")
|
||||
npc(ChatAnim.ANNOYED, "My apologies, dear @g[sir,madam], our services are not available for Ultimate Iron@g[men,women]")
|
||||
goto("nowhere")
|
||||
label("hello for jade")
|
||||
npc("Greetings warrior, how may I help you?")
|
||||
exec { player, _ -> loadLabel(player, if (hasAwaitingGrandExchangeCollections(player)) "ge collect" else "main options") }
|
||||
label("hello")
|
||||
npc("Good day, would you like to access your bank account?")
|
||||
exec { player, _ -> loadLabel(player, if (hasAwaitingGrandExchangeCollections(player)) "ge collect" else "main options") }
|
||||
label("ge collect")
|
||||
npc("Before we go any further, I should inform you that you have items ready for collection from the Grand Exchange.")
|
||||
goto("main options")
|
||||
|
||||
label("main options")
|
||||
options(
|
||||
DialogueOption("how to use", "How do I use the bank?") { _, npc -> return@DialogueOption npc.id == NPCs.BANK_TUTOR_4907 },
|
||||
DialogueOption("who is the bounty hunter banker", "Who are you?") { _, npc -> return@DialogueOption npc.id == NPCs.BANKER_6538 },
|
||||
DialogueOption("access", "I'd like to access my bank account please.", expression = ChatAnim.ASKING),
|
||||
DialogueOption("buy second bank", "I'd like to open a secondary bank account.") { player, _ -> return@DialogueOption ServerConstants.SECOND_BANK && !hasActivatedSecondaryBankAccount(player) },
|
||||
DialogueOption("switch second bank", "I'd like to switch to my primary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && isUsingSecondaryBankAccount(player) },
|
||||
DialogueOption("switch second bank", "I'd like to switch to my secondary bank account.") { player, _ -> return@DialogueOption hasActivatedSecondaryBankAccount(player) && !isUsingSecondaryBankAccount(player) },
|
||||
DialogueOption("pin", "I'd like to check my PIN settings."),
|
||||
DialogueOption("collect", "I'd like to collect items."),
|
||||
DialogueOption("what is this place", "What is this place?") { _, npc -> return@DialogueOption npc.id !in BANKERS_WITH_EXTRA_OPTION },
|
||||
DialogueOption("jade's employment history", "How long have you worked here?") { _, npc -> return@DialogueOption npc.id == NPCs.JADE_4296 },
|
||||
DialogueOption("is the bounty hunter banker afraid", "Aren't you afraid of working in the Wilderness?") { _, npc -> return@DialogueOption npc.id == NPCs.BANKER_6538 && !ServerConstants.SECOND_BANK }
|
||||
)
|
||||
|
||||
label("how to use")
|
||||
options(
|
||||
DialogueOption("using bank", "Using the bank itself.", "Using the bank itself. I'm not sure how....?"),
|
||||
DialogueOption("using deposit", "Using bank deposit boxes.", "Using Bank deposit boxes.... what are they?"),
|
||||
DialogueOption("using PIN", "What's this PIN thing that people keep talking about?", "What's this PIN thing that people keep talking about?"),
|
||||
DialogueOption("nowhere", "Goodbye.")
|
||||
)
|
||||
|
||||
label("using bank")
|
||||
npc("Speak to any banker and ask to see your bank", "account. If you have set a PIN you will be asked for", "it, then all the belongings you have placed in the bank", "will appear in the window. To withdraw one item, left-")
|
||||
npc("click on it once.")
|
||||
npc("To withdraw many, right-click on the item and select", "from the menu. The same for depositing, left-click on", "the item in your inventory to deposit it in the bank.", "Right-click on it to deposit many of the same items.")
|
||||
npc("To move things around in your bank: firstly select", "Swap or Insert as your default moving mode, you can", "find these buttons on the bank window itself. Then click", "and drag an item to where you want it to appear.")
|
||||
npc("You may withdraw 'notes' or 'certificates' when the", "items you are trying to withdraw do not stack in your", "inventory. This will only work for items which are", "tradeable.")
|
||||
npc("For instance, if you wanted to sell 100 logs to another", "player, they would not fit in one inventory and you", "would need to do multiple trades. Instead, click the", "Note button to withdraw the logs as 'certs' or 'notes'")
|
||||
npc("then withdraw the items you need.")
|
||||
goto("how to use")
|
||||
|
||||
label("using deposit")
|
||||
npc("They look like grey pillars, there's one just over there,", "near the desk. Bank deposit boxes save so much time.", "If you're simply wanting to deposit a single item, 'Use'", "it on the deposit box.")
|
||||
npc("Otherwise, simply click once on the box and it will give", "you a choice of what to deposit in an interface very", "similar to the bank itself. Very quick for when you're", "simply fishing or mining etc.")
|
||||
goto("how to use")
|
||||
|
||||
label("using PIN")
|
||||
npc("The PIN - Personal Identification Number - can be", "set on your bank account to protect the items there in", "case someone finds out your account password. It", "consists of four numbers that you remember and tell")
|
||||
npc("no one.")
|
||||
npc("So if someone did manage to get your password they", "couldn't steal your items if they were in the bank.")
|
||||
goto("how to use")
|
||||
|
||||
label("who is the bounty hunter banker")
|
||||
npc(ChatAnim.NEUTRAL, "How inconsiderate of me, dear @g[sir,madam]. My name is Maximillian Sackville and I conduct operations here on behalf of The Bank of Gielinor.")
|
||||
goto("main options")
|
||||
|
||||
label("access")
|
||||
exec { player, _ -> openBankAccount(player) }
|
||||
goto("nowhere")
|
||||
|
||||
label("buy second bank")
|
||||
npc("Certainly. We offer secondary accounts to all our customers.")
|
||||
npc("The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable and account activation is permanent.")
|
||||
npc("If your inventory does not contain enough money to cover the costs, we will complement the amount with the money inside your primary bank account.")
|
||||
npc("Knowing all this, would you like to proceed with opening your secondary bank account?")
|
||||
options(
|
||||
DialogueOption("buy second bank yes", "Yes, I am still interested.", expression = ChatAnim.HAPPY),
|
||||
DialogueOption("buy second bank no", "Actually, I've changed my mind.", expression = ChatAnim.ANNOYED)
|
||||
)
|
||||
|
||||
label("buy second bank yes")
|
||||
exec { player, _ -> loadLabel(player, when (activateSecondaryBankAccount(player)) {
|
||||
SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> "already"
|
||||
SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> "failure"
|
||||
SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> "not enough cash"
|
||||
SecondaryBankAccountActivationResult.SUCCESS -> "success"
|
||||
}) }
|
||||
label("already")
|
||||
npc(ChatAnim.FRIENDLY, "Your bank account was already activated, there is no need to pay twice.")
|
||||
goto("main options")
|
||||
label("failure")
|
||||
npc(ChatAnim.ANNOYED, "I must apologize, the transaction was not successful. Please check your primary bank account and your inventory - if there's money missing, please screenshot your chatbox and contact the game developers.")
|
||||
goto("main options")
|
||||
label("not enough cash")
|
||||
npc(ChatAnim.ANNOYED, "It appears that you do not have the money necessary to cover the costs associated with opening a secondary bank account. I will be waiting here until you do.")
|
||||
goto("main options")
|
||||
label("success")
|
||||
npc(ChatAnim.FRIENDLY, "Your secondary bank account has been opened and can be accessed through any of the Bank of Gielinor's employees. Thank you for choosing our services.")
|
||||
goto("main options")
|
||||
|
||||
label("buy second bank no")
|
||||
npc("Very well. Should you decide a secondary bank account is needed, do not hesitate to contact any of the Bank of Gielinor's stationary employees. We will be happy to help.")
|
||||
goto("main options")
|
||||
|
||||
label("switch second bank")
|
||||
exec { player, _ ->
|
||||
toggleBankAccount(player)
|
||||
loadLabel(player, if (isUsingSecondaryBankAccount(player)) "now secondary" else "now primary")
|
||||
}
|
||||
label("now primary")
|
||||
npc("Your active bank account has been switched. You can now access your primary account.")
|
||||
goto("main options")
|
||||
label("now secondary")
|
||||
npc("Your active bank account has been switched. You can now access your secondary account.")
|
||||
goto("main options")
|
||||
|
||||
label("pin")
|
||||
exec { player, _ -> openBankPinSettings(player) }
|
||||
goto("nowhere")
|
||||
|
||||
label("collect")
|
||||
exec { player, _ -> openGrandExchangeCollectionBox(player) }
|
||||
goto("nowhere")
|
||||
|
||||
label("what is this place")
|
||||
npc("This is a branch of the Bank of Gielinor. We have branches in many towns.")
|
||||
player("And what do you do?")
|
||||
npc("We will look after your items and money for you. Leave your valuables with us if you want to keep them safe.")
|
||||
goto("main options")
|
||||
|
||||
label("jade's employment history")
|
||||
npc(ChatAnim.FRIENDLY, "Oh, ever since the Guild opened. I like it here.")
|
||||
player(ChatAnim.ASKING, "Why's that?")
|
||||
npc(ChatAnim.FRIENDLY, "Well... what with all these warriors around, there's not much chance of my bank being robbed, is there?")
|
||||
goto("nowhere")
|
||||
|
||||
label("is the bounty hunter banker afraid")
|
||||
npc(ChatAnim.NEUTRAL, "While the Wilderness is quite a dangerous place, The Bank of Gielinor offers us - roving bankers - extraordinary benefits for our hard work in hazardous environments.")
|
||||
npc(ChatAnim.NEUTRAL, "This allows us to provide our services to customers regardless of their current whereabouts. Our desire to serve is stronger than our fear of the Wilderness.")
|
||||
goto("nowhere")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray = NPC_IDS
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public final class GuardNPC extends AbstractNPC {
|
|||
/**
|
||||
* The NPC ids of NPCs using this plugin.
|
||||
*/
|
||||
private static final int[] ID = { 9, 32, 163, 164, 196, 197, 206, 253, 254, 255, 256, 274, 275, 296, 298, 299, 447, 448, 449, 489, 609, 678, 799, 837, 842, 862, 870, 877, 917, 1200, 1203, 1204, 1317, 1710, 1711, 1712, 2073, 2074, 2134, 2135, 2136, 2236, 2571, 2699, 2700, 2701, 2702, 2703, 3228, 3229, 3230, 3231, 3232, 3233, 3241, 3407, 3408, 3715, 4257, 4258, 4259, 4260, 4307, 4308, 4309, 4310, 4311, 4336, 4375, 4603, 4604, 4605, 4606, 5800, 5801, 5919, 5920 };
|
||||
private static final int[] ID = { 9, 32, 163, 164, 196, 197, 206, 253, 254, 255, 256, 274, 275, 296, 298, 299, 447, 448, 449, 609, 678, 799, 837, 842, 862, 870, 877, 917, 1200, 1203, 1204, 1317, 1710, 1711, 1712, 2073, 2074, 2134, 2135, 2136, 2236, 2571, 2699, 2700, 2701, 2702, 2703, 3228, 3229, 3230, 3231, 3232, 3233, 3241, 3407, 3408, 3715, 4257, 4258, 4259, 4260, 4307, 4308, 4309, 4310, 4311, 4336, 4375, 4603, 4604, 4605, 4606, 5800, 5801, 5919, 5920 };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code GuardNPC} {@code Object}.
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import core.game.system.timer.impl.AntiMacro
|
|||
import core.game.worldevents.holiday.HolidayRandomEventNPC
|
||||
import core.game.worldevents.holiday.HolidayRandomEvents
|
||||
import core.game.worldevents.holiday.HolidayRandoms
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
/**
|
||||
* Handles the NPC talk-to option.
|
||||
|
|
@ -37,11 +38,18 @@ class NPCTalkListener : InteractionListener {
|
|||
val npc = node.asNpc()
|
||||
if(RandomEvents.randomIDs.contains(node.id)){
|
||||
if(AntiMacro.getEventNpc(player) == null || AntiMacro.getEventNpc(player) != node.asNpc() || AntiMacro.getEventNpc(player)?.finalized == true) {
|
||||
player.sendMessage("They aren't interested in talking to you.")
|
||||
// Why the fuck is this here of all places? Now look at what you've made me do:
|
||||
if (npc.id == NPCs.SANDWICH_LADY_3117) {
|
||||
// https://www.youtube.com/watch?v=ek8r3ZS929E
|
||||
player.dialogueInterpreter.sendDialogue("The sandwich lady doesn't seem interested in selling you any", "refreshments.")
|
||||
} else {
|
||||
sendMessage(player, "They aren't interested in talking to you.")
|
||||
}
|
||||
} else {
|
||||
AntiMacro.getEventNpc(player)?.talkTo(node.asNpc())
|
||||
}
|
||||
return@on true
|
||||
//TODO bring sanity here
|
||||
}
|
||||
if (HolidayRandomEvents.holidayRandomIDs.contains(node.id) && node is HolidayRandomEventNPC) {
|
||||
if(HolidayRandoms.getEventNpc(player) == null || HolidayRandoms.getEventNpc(player) != node.asNpc() || HolidayRandoms.getEventNpc(player)?.finalized == true) {
|
||||
|
|
@ -79,4 +87,4 @@ class NPCTalkListener : InteractionListener {
|
|||
return@on player.dialogueInterpreter.open(npc.id, npc)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ public final class HouseManager {
|
|||
Room room = rooms[0][4][3] = new Room(RoomProperties.GARDEN);
|
||||
room.configure(style);
|
||||
room.getHotspots()[0].setDecorationIndex(0);
|
||||
redecorate(HousingStyle.BASIC_WOOD);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package content.global.skill.construction;
|
||||
|
||||
|
||||
import core.api.Container;
|
||||
import org.rs09.consts.Items;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.world.map.zone.MapZone;
|
||||
|
|
@ -91,6 +93,7 @@ public final class HouseZone extends MapZone {
|
|||
public boolean leave(Entity e, boolean logout) {
|
||||
if (e instanceof Player) {
|
||||
Player p = (Player) e;
|
||||
remove_items(p);
|
||||
// The below tears down the house if the owner was the one who left
|
||||
if (house == p.getHouseManager()) {
|
||||
house.expelGuests(p);
|
||||
|
|
@ -121,4 +124,11 @@ public final class HouseZone extends MapZone {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void remove_items(Player p) {
|
||||
for (int item = Items.KETTLE_7688; item <= Items.CHEFS_DELIGHT_7755; item++) {//Removes all PoH versions of tea and beer barrel-related items
|
||||
removeAll(p, item, Container.INVENTORY);
|
||||
removeAll(p, item, Container.BoB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
package content.global.skill.construction.decoration;
|
||||
|
||||
import core.game.interaction.NodeUsageEvent;
|
||||
import core.game.interaction.UseWithHandler;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import org.rs09.consts.Items;
|
||||
|
||||
/**
|
||||
* Handles the Construction beer barrels.
|
||||
* @author Splinter
|
||||
*/
|
||||
@Initializable
|
||||
public class BeerBarrelPlugin extends UseWithHandler {
|
||||
|
||||
/**
|
||||
* The object ids
|
||||
*/
|
||||
private static final int[] OBJECTS = new int[] {
|
||||
13568, 13569, 13570, 13571, 13572, 13573
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new {@Code BeerBarrelPlugin} {@Code Object}
|
||||
*/
|
||||
public BeerBarrelPlugin() {
|
||||
super(1919);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (int id : OBJECTS) {
|
||||
addHandler(id, OBJECT_TYPE, this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
final Scenery object = (Scenery) event.getUsedWith();
|
||||
|
||||
if (player.getInventory().remove(new Item(Items.BEER_GLASS_1919))) {
|
||||
player.animate(Animation.create(833));
|
||||
player.sendMessage("You fill up your glass.");
|
||||
player.getInventory().add(new Item(getReward(object.getId()), 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the beer reward based on the interaced barrel.
|
||||
* @return the item to give.
|
||||
*/
|
||||
public int getReward(int barrelId) {
|
||||
switch (barrelId) {
|
||||
case 13568:
|
||||
return 1917;
|
||||
case 13569:
|
||||
return 5763;
|
||||
case 13570:
|
||||
return 1905;
|
||||
case 13571:
|
||||
return 1909;
|
||||
case 13572:
|
||||
return 1911;
|
||||
case 13573:
|
||||
return 5755;
|
||||
}
|
||||
return 1917;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package content.global.skill.construction.decoration.kitchen
|
||||
|
||||
import core.api.addItem
|
||||
import core.api.freeSlots
|
||||
import core.api.sendDialogue
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.dialogue.Topic
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.END_DIALOGUE
|
||||
|
||||
abstract class AbstractContainer(containerId: Int, containers: Map<Int,List<Pair<String, Int>>>, private val containerName: String) : DialogueFile() {
|
||||
|
||||
private val container = containers[containerId]!!
|
||||
private val containerItemsNames = container.map { it.first }
|
||||
private val containerItemsIds = container.map { it.second }
|
||||
private val size = container.size
|
||||
private val itemsPerPage = 4
|
||||
|
||||
private fun checkItem(player: Player, idx : Int){
|
||||
val item = containerItemsIds[idx]
|
||||
if (addItem(player, item)){
|
||||
end()
|
||||
}
|
||||
else{
|
||||
sendDialogue(player, "You need at least one free inventory space to take from the $containerName.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
}
|
||||
|
||||
private fun createTopics(page: Int): MutableList<Topic<Int>> {
|
||||
val startIndex = (page - 1) * itemsPerPage
|
||||
val endIndex = (startIndex + itemsPerPage).coerceAtMost(size)
|
||||
|
||||
val topics = containerItemsNames.subList(startIndex, endIndex)
|
||||
.mapIndexed { index, item -> Topic(item, startIndex + index + 1, skipPlayer = true) }
|
||||
.toMutableList()
|
||||
|
||||
// Add "More" button if there's another page or to loop back
|
||||
if (endIndex < size || page > 1) {
|
||||
topics.add(Topic("More", endIndex + 1, skipPlayer = true))
|
||||
}
|
||||
|
||||
return topics
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
if (freeSlots(player!!) == 0) {
|
||||
sendDialogue(player!!, "You need at least one free inventory space to take from the $containerName.").also { stage = END_DIALOGUE }
|
||||
return
|
||||
}
|
||||
val itemsPerPage = 4
|
||||
|
||||
when (stage) {
|
||||
0, size + 1 -> { // Initial stage or final more button clicked
|
||||
val topics = createTopics(1)
|
||||
showTopics(*topics.toTypedArray()).also { stage = 1 }
|
||||
}
|
||||
in 1..size -> {
|
||||
val currentPage = (stage-1) / itemsPerPage
|
||||
val startIndex = currentPage * itemsPerPage
|
||||
|
||||
if (buttonID == itemsPerPage + 1) { // "More" button clicked (but not the last one)
|
||||
val topics = createTopics(currentPage + 1)
|
||||
showTopics(*topics.toTypedArray()).also { stage = currentPage*itemsPerPage + 1 }
|
||||
} else { // Handle item selection
|
||||
val itemIndex = startIndex + (buttonID - 1)
|
||||
if (itemIndex < size) {
|
||||
checkItem(player!!, itemIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> end()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package content.global.skill.construction.decoration.kitchen
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class BeerBarrelInteraction : InteractionListener {
|
||||
|
||||
companion object{
|
||||
private val barrelMap = mapOf(
|
||||
org.rs09.consts.Scenery.BEER_BARREL_13568 to Items.BEER_7740,
|
||||
org.rs09.consts.Scenery.CIDER_BARREL_13569 to Items.CIDER_7752,
|
||||
org.rs09.consts.Scenery.ASGARNIAN_ALE_13570 to Items.ASGARNIAN_ALE_7744,
|
||||
org.rs09.consts.Scenery.GREENMAN_S_ALE_13571 to Items.GREENMANS_ALE_7746,
|
||||
org.rs09.consts.Scenery.DRAGON_BITTER_13572 to Items.DRAGON_BITTER_7748,
|
||||
org.rs09.consts.Scenery.CHEF_S_DELIGHT_13573 to Items.CHEFS_DELIGHT_7754,
|
||||
)
|
||||
}
|
||||
override fun defineListeners() {
|
||||
onUseWith(SCENERY, Items.BEER_GLASS_7742, *barrelMap.keys.toIntArray()){ player, used, with ->
|
||||
val drinkName = with.name.lowercase().replace("barrel", "").trim()+"."
|
||||
if (removeItem(player, used)){
|
||||
sendMessage(player, "You fill up your glass with $drinkName")
|
||||
addItem(player, barrelMap[with.id]!!)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
package content.global.skill.construction.decoration.kitchen;
|
||||
|
||||
|
||||
import core.game.interaction.NodeUsageEvent;
|
||||
import core.game.interaction.UseWithHandler;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.node.scenery.Scenery;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import org.rs09.consts.Items;
|
||||
|
||||
/**
|
||||
* Handles the Construction beer barrels.
|
||||
* @author Splinter
|
||||
*/
|
||||
@Initializable
|
||||
public class BeerBarrelPlugin extends UseWithHandler {
|
||||
|
||||
/**
|
||||
* The object ids
|
||||
*/
|
||||
private static final int[] OBJECTS = new int[] {
|
||||
13568, 13569, 13570, 13571, 13572, 13573
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a new {@Code BeerBarrelPlugin} {@Code Object}
|
||||
*/
|
||||
public BeerBarrelPlugin() {
|
||||
super(1919);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (int id : OBJECTS) {
|
||||
addHandler(id, OBJECT_TYPE, this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
final Scenery object = (Scenery) event.getUsedWith();
|
||||
|
||||
if (player.getInventory().remove(new Item(Items.BEER_GLASS_1919))) {
|
||||
player.animate(Animation.create(3661 + (object.getId() - 13569)));
|
||||
player.sendMessage("You fill up your glass with " + object.getName().toLowerCase().replace("barrel", "").trim() + ".");
|
||||
player.getInventory().add(new Item(getReward(object.getId()), 1));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the beer reward based on the interacted barrel.
|
||||
* @return the item to give.
|
||||
*/
|
||||
public int getReward(int barrelId) {
|
||||
switch (barrelId) {
|
||||
case 13568:
|
||||
return 1917;
|
||||
case 13569:
|
||||
return 5763;
|
||||
case 13570:
|
||||
return 1905;
|
||||
case 13571:
|
||||
return 1909;
|
||||
case 13572:
|
||||
return 1911;
|
||||
case 13573:
|
||||
return 5755;
|
||||
}
|
||||
return 1917;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package content.global.skill.construction.decoration.kitchen
|
||||
|
||||
import core.api.openDialogue
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
class LarderListener : InteractionListener {
|
||||
|
||||
companion object {
|
||||
private val wooden_larder_items = listOf(
|
||||
"Tea Leaves" to Items.TEA_LEAVES_7738,
|
||||
"Bucket of Milk" to Items.BUCKET_OF_MILK_1927
|
||||
)
|
||||
private val oak_larder_items = wooden_larder_items + listOf(
|
||||
"Eggs" to Items.EGG_1944,
|
||||
"Pot of Flour" to Items.POT_OF_FLOUR_1933
|
||||
)
|
||||
private val teak_larder_items = oak_larder_items + listOf(
|
||||
"Potatoes" to Items.POTATO_1942,
|
||||
"Garlic" to Items.GARLIC_1550,
|
||||
"Onions" to Items.ONION_1957,
|
||||
"Cheese" to Items.CHEESE_1985
|
||||
)
|
||||
|
||||
val larders = mapOf(
|
||||
Scenery.LARDER_13565 to wooden_larder_items,
|
||||
Scenery.LARDER_13566 to oak_larder_items,
|
||||
Scenery.LARDER_13567 to teak_larder_items
|
||||
)
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(larders.keys.toIntArray(), IntType.SCENERY, "Search") { player, node ->
|
||||
openDialogue(player, LarderDialogue(node.id))
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
class LarderDialogue(shelfId: Int) : AbstractContainer(shelfId, larders, "larder")
|
||||
}
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
package content.global.skill.construction.decoration.kitchen;
|
||||
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import org.rs09.consts.Items;
|
||||
|
||||
/**
|
||||
* Handles the interactions for the three Larders.
|
||||
* @author Splinter
|
||||
*/
|
||||
@Initializable
|
||||
public final class LarderPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ClassScanner.definePlugin(new LarderDialogue());
|
||||
SceneryDefinition.forId(13565).getHandlers().put("option:search", this);
|
||||
SceneryDefinition.forId(13566).getHandlers().put("option:search", this);
|
||||
SceneryDefinition.forId(13567).getHandlers().put("option:search", this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
player.getDialogueInterpreter().open(42048, node.getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialogue options for the Larders.
|
||||
* @author Splinter
|
||||
* @version 1.0
|
||||
*/
|
||||
public final class LarderDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LarderDialogue} {@code Object}.
|
||||
*/
|
||||
public LarderDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LarderDialogue} {@code Object}.
|
||||
*
|
||||
* @param player
|
||||
* the player.
|
||||
*/
|
||||
public LarderDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new LarderDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
int id = (int) args[0];
|
||||
switch (id) {
|
||||
case 13565:
|
||||
interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk");
|
||||
stage = 1;
|
||||
break;
|
||||
case 13566:
|
||||
interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk", "Eggs", "Pot of Flour");
|
||||
stage = 1;
|
||||
break;
|
||||
case 13567:
|
||||
interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk", "Eggs", "Pot of Flour", "More Options");
|
||||
stage = 1;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
if (player.getInventory().freeSlots() < 1) {
|
||||
player.sendMessage("You need at least one free inventory space to take from the larder.");
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
switch (stage) {
|
||||
case 1:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
player.getInventory().add(new Item(Items.TEA_LEAVES_7738, 1));
|
||||
end();
|
||||
break;
|
||||
case 2:
|
||||
player.getInventory().add(new Item(Items.BUCKET_OF_MILK_1927, 1));
|
||||
end();
|
||||
break;
|
||||
case 3:
|
||||
player.getInventory().add(new Item(Items.EGG_1944, 1));
|
||||
end();
|
||||
break;
|
||||
case 4:
|
||||
player.getInventory().add(new Item(Items.POT_OF_FLOUR_1933, 1));
|
||||
end();
|
||||
break;
|
||||
case 5:
|
||||
player.getDialogueInterpreter().sendOptions(
|
||||
"Select an Option", "Potatoes", "Garlic", "Onions", "Cheese");
|
||||
stage = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
player.getInventory().add(new Item(Items.POTATO_1942, 1));
|
||||
end();
|
||||
break;
|
||||
case 2:
|
||||
player.getInventory().add(new Item(Items.GARLIC_1550, 1));
|
||||
end();
|
||||
break;
|
||||
case 3:
|
||||
player.getInventory().add(new Item(Items.ONION_1957, 1));
|
||||
end();
|
||||
break;
|
||||
case 4:
|
||||
player.getInventory().add(new Item(Items.CHEESE_1985, 1));
|
||||
end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 42048 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
package content.global.skill.construction.decoration.kitchen
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
|
||||
|
||||
class ShelfListener : InteractionListener {
|
||||
companion object {
|
||||
// Source for text https://www.youtube.com/watch?v=SNuqelEft3Y
|
||||
|
||||
private val woodshelf_1_items = listOf(
|
||||
"Kettle" to Items.KETTLE_7688,
|
||||
"Teapot" to Items.TEAPOT_7702,
|
||||
"Cup" to Items.EMPTY_CUP_7728
|
||||
)
|
||||
|
||||
private val woodshelf_2_items = woodshelf_1_items + listOf(
|
||||
"Beer glass" to Items.BEER_GLASS_7742
|
||||
)
|
||||
|
||||
private val woodshelf_3_items = woodshelf_2_items.map { (name, itemId) ->
|
||||
when (name) {
|
||||
"Cup" -> {
|
||||
"Porcelain cup" to Items.PORCELAIN_CUP_7732
|
||||
}
|
||||
|
||||
"Teapot" -> {
|
||||
"Teapot" to Items.TEAPOT_7714
|
||||
}
|
||||
|
||||
else -> {
|
||||
name to itemId
|
||||
}
|
||||
}
|
||||
} + listOf("Cake tin" to Items.CAKE_TIN_1887)
|
||||
|
||||
private val oakshelf_1_items = woodshelf_2_items + listOf("Cake tin" to Items.CAKE_TIN_1887) + listOf("Bowl" to Items.BOWL_1923)
|
||||
|
||||
private val oakshelf_2_items = oakshelf_1_items.map { (name, itemId) ->
|
||||
when (name) {
|
||||
"Cup" -> {
|
||||
"Porcelain cup" to Items.PORCELAIN_CUP_7732
|
||||
}
|
||||
|
||||
"Teapot" -> {
|
||||
"Teapot" to Items.TEAPOT_7714
|
||||
}
|
||||
|
||||
else -> {
|
||||
name to itemId
|
||||
}
|
||||
}
|
||||
} + listOf("Pie dish" to Items.PIE_DISH_2313)
|
||||
|
||||
private val teakshelf_1_items = oakshelf_2_items + listOf(
|
||||
"Pot" to Items.EMPTY_POT_1931
|
||||
)
|
||||
|
||||
private val teakshelf_2_items = teakshelf_1_items.map { (name, itemId) ->
|
||||
when (name) {
|
||||
"Porcelain cup" -> {
|
||||
"Porcelain cup" to Items.PORCELAIN_CUP_7735
|
||||
}
|
||||
|
||||
"Teapot" -> {
|
||||
"Teapot" to Items.TEAPOT_7726
|
||||
}
|
||||
|
||||
else -> {
|
||||
name to itemId
|
||||
}
|
||||
}
|
||||
} + listOf("Chef's Hat" to Items.CHEFS_HAT_1949)
|
||||
|
||||
val shelves = mapOf(
|
||||
Scenery.SHELVES_13545 to woodshelf_1_items,
|
||||
Scenery.SHELVES_13546 to woodshelf_2_items,
|
||||
Scenery.SHELVES_13547 to woodshelf_3_items,
|
||||
Scenery.SHELVES_13548 to oakshelf_1_items,
|
||||
Scenery.SHELVES_13549 to oakshelf_2_items,
|
||||
Scenery.SHELVES_13550 to teakshelf_1_items,
|
||||
Scenery.SHELVES_13551 to teakshelf_2_items,
|
||||
)
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(shelves.keys.toIntArray(), IntType.SCENERY, "Search") { player, node ->
|
||||
openDialogue(player, ShelfDialogue(node.id))
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
class ShelfDialogue(shelfId: Int) : AbstractContainer(shelfId, shelves, "shelf")
|
||||
}
|
||||
|
|
@ -1,239 +0,0 @@
|
|||
package content.global.skill.construction.decoration.kitchen;
|
||||
|
||||
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import org.rs09.consts.Items;
|
||||
|
||||
/**
|
||||
* Handles the shelves in the kitchen room.
|
||||
* @author Splinter
|
||||
*/
|
||||
@Initializable
|
||||
public final class ShelfPlugin extends OptionHandler {
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ClassScanner.definePlugin(new ShelfDialogue());
|
||||
for (int i = 13545; i < 13552; i++) {
|
||||
SceneryDefinition.forId(i).getHandlers().put("option:search", this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
player.getDialogueInterpreter().open(778341, node.getId());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialogue options for the shelves, what a mess!
|
||||
* @author Splinter
|
||||
* @version 1.0
|
||||
*/
|
||||
public final class ShelfDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ShelfDialogue} {@code Object}.
|
||||
*/
|
||||
public ShelfDialogue() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ShelfDialogue} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public ShelfDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new ShelfDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
int id = (int) args[0];
|
||||
switch (id) {
|
||||
case 13545:// wood 1
|
||||
interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup");
|
||||
stage = 1;
|
||||
break;
|
||||
case 13546:// wood 2
|
||||
interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass");
|
||||
stage = 1;
|
||||
break;
|
||||
case 13547:// wood 3
|
||||
interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass", "Cake tin");
|
||||
stage = 1;
|
||||
break;
|
||||
case 13548:// oak 1
|
||||
interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass", "Bowl");
|
||||
stage = 2;
|
||||
break;
|
||||
case 13549:// oak 2
|
||||
interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Porcelain cup", "Empty beer glass", "More Options");
|
||||
stage = 3;
|
||||
break;
|
||||
case 13550:// teak 1
|
||||
case 13551:
|
||||
interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Porcelain cup", "Empty beer glass", "More Options");
|
||||
stage = 5;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
if (player.getInventory().freeSlots() < 1) {
|
||||
player.sendMessage("You need at least one free inventory space to take from the shelves.");
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
switch (stage) {
|
||||
case 1:// all wood shelves
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.KETTLE_7688, 1));
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.TEAPOT_7702, 1));
|
||||
break;
|
||||
case 3:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.EMPTY_CUP_7728, 1));
|
||||
break;
|
||||
case 4:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1));
|
||||
break;
|
||||
case 5:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.CAKE_TIN_1887, 1));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:// Oak shelf #1
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.KETTLE_7688, 1));
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.TEAPOT_7702, 1));
|
||||
break;
|
||||
case 3:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.EMPTY_CUP_7728, 1));
|
||||
break;
|
||||
case 4:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1));
|
||||
break;
|
||||
case 5:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.BOWL_1923, 1));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3:// Oak shelves #2 only
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.KETTLE_7688, 1));
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.TEAPOT_7702, 1));
|
||||
break;
|
||||
case 3:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.PORCELAIN_CUP_4244, 1));
|
||||
break;
|
||||
case 4:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1));
|
||||
break;
|
||||
case 5:
|
||||
interpreter.sendOptions("Select an Option", "Bowl", "Cake tin");
|
||||
stage = 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:// Oak shelves #2 only
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.BOWL_1923, 1));
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.CAKE_TIN_1887, 1));
|
||||
break;
|
||||
}
|
||||
case 5:// teak shelves
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.KETTLE_7688, 1));
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.TEAPOT_7702, 1));
|
||||
break;
|
||||
case 3:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.PORCELAIN_CUP_7735, 1));
|
||||
break;
|
||||
case 4:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1));
|
||||
break;
|
||||
case 5:
|
||||
interpreter.sendOptions("Select an Option", "Bowl", "Pie dish", "Empty pot");
|
||||
stage = 6;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 6:// teak shelves
|
||||
switch (buttonId) {
|
||||
case 1:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.BOWL_1923, 1));
|
||||
break;
|
||||
case 2:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.PIE_DISH_2313, 1));
|
||||
break;
|
||||
case 3:
|
||||
end();
|
||||
player.getInventory().add(new Item(Items.EMPTY_POT_1931, 1));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 778341 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package content.global.skill.construction.decoration.kitchen
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import org.rs09.consts.Scenery as SceneryConst
|
||||
import org.rs09.consts.Items
|
||||
import core.game.node.scenery.Scenery
|
||||
import core.tools.secondsToTicks
|
||||
|
||||
|
||||
class StoveInteraction : InteractionListener {
|
||||
|
||||
// Imagine if these indexes incremented logically...
|
||||
companion object{
|
||||
val valid_stoves = intArrayOf(
|
||||
SceneryConst.FIREPIT_WITH_HOOK_13529,
|
||||
SceneryConst.FIREPIT_WITH_POT_13531,
|
||||
SceneryConst.SMALL_OVEN_13533,
|
||||
SceneryConst.LARGE_OVEN_13536,
|
||||
SceneryConst.STEEL_RANGE_13539,
|
||||
SceneryConst.FANCY_RANGE_13542
|
||||
)
|
||||
val in_progress_stoves = intArrayOf(
|
||||
SceneryConst.FIREPIT_WITH_HOOK_13530,
|
||||
SceneryConst.FIREPIT_WITH_POT_13532,
|
||||
SceneryConst.SMALL_OVEN_13534,
|
||||
SceneryConst.LARGE_OVEN_13537,
|
||||
SceneryConst.STEEL_RANGE_13541,
|
||||
SceneryConst.FANCY_RANGE_13544
|
||||
|
||||
)
|
||||
val stoves_with_kettle = intArrayOf(
|
||||
SceneryConst.FIREPIT_WITH_HOOK_13530,
|
||||
SceneryConst.FIREPIT_WITH_POT_13532,
|
||||
SceneryConst.SMALL_OVEN_13535,
|
||||
SceneryConst.LARGE_OVEN_13538,
|
||||
SceneryConst.STEEL_RANGE_13540,
|
||||
SceneryConst.FANCY_RANGE_13543
|
||||
|
||||
)
|
||||
const val kettleBoiled = "kettle_boiled"
|
||||
}
|
||||
override fun defineListeners() {
|
||||
onUseWith(SCENERY, Items.FULL_KETTLE_7690, *valid_stoves){ player, used, with ->
|
||||
val idx = valid_stoves.indexOf(with.id)
|
||||
if (removeItem(player, used)){
|
||||
replaceScenery(with as Scenery, in_progress_stoves[idx], -1)
|
||||
sendMessage(player, "You place the kettle over the fire.")
|
||||
setAttribute(player, kettleBoiled, 1)
|
||||
queueScript(player, secondsToTicks(10), QueueStrength.SOFT){ _ ->
|
||||
sendMessage(player, "The kettle boils.")
|
||||
// Of course they changed how these items work so we need 2 different cases
|
||||
setAttribute(player, kettleBoiled, 2)
|
||||
if (with.id in intArrayOf(SceneryConst.FIREPIT_WITH_HOOK_13529, SceneryConst.FIREPIT_WITH_POT_13531))
|
||||
return@queueScript stopExecuting(player)
|
||||
else{
|
||||
getScenery(with.location)?.let { replaceScenery(it, stoves_with_kettle[idx], -1) }
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
|
||||
on(stoves_with_kettle, SCENERY, "take-kettle"){ player, node ->
|
||||
if (getAttribute(player, kettleBoiled, 0) == 0){
|
||||
sendMessage(player, "This is not your kettle.")
|
||||
return@on false
|
||||
}
|
||||
else if (getAttribute(player, kettleBoiled, 0) == 1){
|
||||
sendMessage(player, "The kettle has not boiled yet.")
|
||||
return@on false
|
||||
}
|
||||
if(addItem(player, Items.HOT_KETTLE_7691)){
|
||||
replaceScenery(node as Scenery, valid_stoves[stoves_with_kettle.indexOf(node.id)], -1)
|
||||
setAttribute(player, kettleBoiled, 0)
|
||||
return@on true
|
||||
}
|
||||
else {
|
||||
sendMessage(player, "You do not have space to do that.")
|
||||
return@on false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,8 +4,7 @@ import core.game.dialogue.DialoguePlugin
|
|||
import content.data.RepairItem
|
||||
import core.game.interaction.NodeUsageEvent
|
||||
import core.game.interaction.UseWithHandler
|
||||
import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment
|
||||
import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment.BarrowsFullEquipment
|
||||
import content.global.handlers.item.equipment.BarrowsEquipment
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
|
|
@ -14,8 +13,10 @@ import core.plugin.Plugin
|
|||
import kotlin.math.ceil
|
||||
import org.rs09.consts.Items
|
||||
|
||||
private val ALL_REPAIRABLE_ITEM_IDS = (RepairItem.repairableItemIds + BarrowsEquipment.getAllRepairableBarrowsIds()).toIntArray()
|
||||
|
||||
@Initializable
|
||||
class ArmourStand : UseWithHandler(494, 468, 496, 470, 498, 472, 500, 502, 474, 504, 476, 506, 478, 6741, 4856, 4857, 4858, 4859, 4860, 4862, 4863, 4864, 4865, 4866, 4868, 4869, 4870, 4871, 4872, 4874, 4875, 4876, 4877, 4878, 4880, 4881, 4882, 4883, 4884, 4886, 4887, 4888, 4889, 4890, 4892, 4893, 4894, 4895, 4896, 4898, 4899, 4900, 4901, 4902, 4904, 4905, 4906, 4907, 4908, 4910, 4911, 4912, 4913, 4914, 4916, 4917, 4918, 4919, 4920, 4922, 4923, 4924, 4925, 4926, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4937, 4938, 4940, 4941, 4942, 4943, 4944, 4946, 4947, 4948, 4949, 4950, 4952, 4953, 4954, 4955, 4956, 4958, 4959, 4960, 4961, 4962, 4964, 4965, 4966, 4967, 4968, 4970, 4971, 4972, 4973, 4974, 4976, 4977, 4978, 4979, 4980, 4982, 4983, 4984, 4985, 4986, 4988, 4989, 4990, 4991, 4992, 4994, 4995, 4996, 4997, 4998){
|
||||
class ArmourStand : UseWithHandler(*ALL_REPAIRABLE_ITEM_IDS) {
|
||||
override fun newInstance(arg: Any?): Plugin<Any> {
|
||||
addHandler(13715, OBJECT_TYPE, this)
|
||||
return this
|
||||
|
|
@ -24,76 +25,90 @@ class ArmourStand : UseWithHandler(494, 468, 496, 470, 498, 472, 500, 502, 474,
|
|||
override fun handle(event: NodeUsageEvent?): Boolean {
|
||||
event ?: return false
|
||||
val player = event.player
|
||||
val repairItem = RepairItem.forId(event.used.id)
|
||||
val usedItem = event.used.asItem()
|
||||
|
||||
var baseCost = 0.0
|
||||
var baseCost = 0
|
||||
var product: Item? = null
|
||||
|
||||
if(repairItem != null){
|
||||
baseCost = repairItem.cost * 1.0
|
||||
product = repairItem.product
|
||||
} else if(BarrowsEquipment.isBarrowsItem(event.used.id)){
|
||||
//Begin terrible code thanks to Vexia
|
||||
val type = BarrowsEquipment.formatedName(event.used.id)
|
||||
val single = BarrowsEquipment.getSingleName(type)
|
||||
val equipment = BarrowsEquipment.getEquipmentType(type)
|
||||
val newString = type.toLowerCase().replace(single, "").trim { it <= ' ' }.replace("'s", "")
|
||||
val newewString = StringBuilder()
|
||||
newewString.append(newString).append(" $equipment")
|
||||
val fullequip = BarrowsFullEquipment.forName(newewString.toString())
|
||||
baseCost = BarrowsEquipment.getFormatedCost(equipment,event.used.asItem()) * 1.0
|
||||
product = fullequip.full
|
||||
//End terrible code thanks to Vexia
|
||||
}
|
||||
val repairItem = RepairItem.forId(usedItem.id)
|
||||
val barrowsDef = BarrowsEquipment.getDefinition(usedItem.id)
|
||||
|
||||
if((repairItem == null && baseCost == 0.0)){
|
||||
if (repairItem != null) {
|
||||
baseCost = repairItem.cost
|
||||
product = repairItem.product
|
||||
} else if (barrowsDef != null) {
|
||||
if (BarrowsEquipment.isFullyRepaired(event.used.id)) {
|
||||
player.sendMessage("That item can't be repaired.")
|
||||
return true
|
||||
}
|
||||
baseCost = BarrowsEquipment.getRepairCost(usedItem)
|
||||
product = Item(barrowsDef.repairedId)
|
||||
} else {
|
||||
player.sendMessage("That item can't be repaired.")
|
||||
return true
|
||||
}
|
||||
|
||||
val cost: Int = ceil(((100.0 - (player.skills.getLevel(Skills.SMITHING) / 2.0) ) / 100.0) * baseCost).toInt()
|
||||
|
||||
player.dialogueInterpreter.open(58824213,event.used,cost,product)
|
||||
val discountMultiplier = (100.0 - (player.skills.getLevel(Skills.SMITHING) / 2.0)) / 100.0
|
||||
val cost = ceil(discountMultiplier * baseCost).toInt()
|
||||
|
||||
player.dialogueInterpreter.open(58824213,usedItem, cost, product)
|
||||
return true
|
||||
}
|
||||
@Initializable
|
||||
class RepairDialogue(player: Player? = null) : DialoguePlugin(player){
|
||||
override fun newInstance(player: Player?): DialoguePlugin {
|
||||
return RepairDialogue(player)
|
||||
}
|
||||
var item: Item? = null
|
||||
var cost: Int = 0
|
||||
var product: Item? = null
|
||||
class RepairDialogue(player: Player? = null) : DialoguePlugin(player) {
|
||||
|
||||
private var item: Item? = null
|
||||
private var cost: Int = 0
|
||||
private var product: Item? = null
|
||||
|
||||
override fun newInstance(player: Player?): DialoguePlugin = RepairDialogue(player)
|
||||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
item = args[0] as Item
|
||||
cost = args[1] as Int
|
||||
product = args[2] as Item
|
||||
player.dialogueInterpreter.sendDialogue("Would you like to repair your ${(item as Item).name.toLowerCase()}","for $cost gp?")
|
||||
|
||||
val itemName = item?.name?.lowercase() ?: "item"
|
||||
player.dialogueInterpreter.sendDialogue(
|
||||
"Would you like to repair your $itemName",
|
||||
"for $cost gp?"
|
||||
)
|
||||
stage = 0
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
item ?: return false
|
||||
product ?: return false
|
||||
when(stage){
|
||||
0 -> options("Yes, please","No, thanks").also{stage++}
|
||||
1 -> when(buttonId){
|
||||
1 -> exchangeItems(item as Item,cost,product as Item).also { end() }
|
||||
val currentItem = item ?: return false
|
||||
val currentProduct = product ?: return false
|
||||
|
||||
when (stage) {
|
||||
0 -> {
|
||||
options("Yes, please", "No, thanks")
|
||||
stage++
|
||||
}
|
||||
1 -> when (buttonId) {
|
||||
1 -> {
|
||||
exchangeItems(currentItem, cost, currentProduct)
|
||||
end()
|
||||
}
|
||||
2 -> end()
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun exchangeItems(item: Item, cost: Int, product: Item) {
|
||||
private fun exchangeItems(item: Item, cost: Int, product: Item) {
|
||||
val coins = Item(Items.COINS_995, cost)
|
||||
|
||||
if (player.inventory.containsItem(coins) && player.inventory.containsItem(item)) {
|
||||
player.inventory.remove(item, coins)
|
||||
player.inventory.add(product)
|
||||
player.sendMessage("You repair your ${product.name.toLowerCase()} for $cost.")
|
||||
if (player.inventory.remove(item, coins)) {
|
||||
if (player.inventory.add(product)) {
|
||||
val costText = if (cost > 0) "${cost}gp" else "free"
|
||||
player.sendMessage("You repair your ${product.name.lowercase()} for $costText.")
|
||||
return
|
||||
}
|
||||
}
|
||||
player.sendMessage("Report this to an administrator!")
|
||||
} else {
|
||||
player.sendMessage("You can't afford that.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,171 +0,0 @@
|
|||
package content.global.skill.construction.decoration.workshop;
|
||||
|
||||
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.cache.def.impl.SceneryDefinition;
|
||||
import core.plugin.Initializable;
|
||||
import core.game.dialogue.DialogueInterpreter;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.interaction.OptionHandler;
|
||||
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.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Handles the 5 types of tool stores
|
||||
* ToolsPlugin.java
|
||||
* @author Clayton Williams
|
||||
* @date Oct 29, 2015
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class ToolsPlugin extends OptionHandler {
|
||||
|
||||
/**
|
||||
* The different tool stores
|
||||
* @author Clayton Williams
|
||||
* @date Oct 29, 2015
|
||||
*/
|
||||
private enum ToolStore {
|
||||
|
||||
TOOLSTORE_1(13699, 8794, 1755, 2347, 1735),
|
||||
TOOLSTORE_2(13700, 1925, 952, 590),
|
||||
TOOLSTORE_3(13701, 1757, 1785, 1733),
|
||||
TOOLSTORE_4(13702, 1595, 1597, 1592, 1599, 5523),
|
||||
TOOLSTORE_5(13703, 5341, 952, 676, 5343, 5331);
|
||||
|
||||
/**
|
||||
* The object id of the tool store
|
||||
*/
|
||||
private int objectId;
|
||||
|
||||
/**
|
||||
* The tools included
|
||||
*/
|
||||
private int[] tools;
|
||||
|
||||
/**
|
||||
* ToolStore
|
||||
* @param objectId
|
||||
* @param tools
|
||||
*/
|
||||
ToolStore(int objectId, int... tools) {
|
||||
this.objectId = objectId;
|
||||
this.tools = tools;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the toolstore from an object id
|
||||
* @param objectId - the object id
|
||||
* @return
|
||||
*/
|
||||
private static ToolStore forId(int objectId) {
|
||||
for (ToolStore t : ToolStore.values()) {
|
||||
if (t.objectId == objectId) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (ToolStore t : ToolStore.values()) {
|
||||
SceneryDefinition.forId(t.objectId).getHandlers().put("option:search", this);
|
||||
}
|
||||
ClassScanner.definePlugin(new ToolDialogue());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
Scenery object = node.asScenery();
|
||||
ToolStore ts = ToolStore.forId(object.getId());
|
||||
if (ts != null) {
|
||||
player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("con:tools"), ts);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the tool dialogue
|
||||
* @author Clayton Williams
|
||||
* @date Oct 29, 2015
|
||||
*/
|
||||
private final class ToolDialogue extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* The tool store being used
|
||||
*/
|
||||
private ToolStore toolStore;
|
||||
|
||||
/**
|
||||
* ToolDialogue
|
||||
*/
|
||||
private ToolDialogue() {
|
||||
/**
|
||||
* Empty
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* ToolDialogue
|
||||
* @param player
|
||||
*/
|
||||
public ToolDialogue(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new ToolDialogue(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
toolStore = (ToolStore) args[0];
|
||||
List<String> itemNames = new ArrayList<String>();
|
||||
for(int itemId : toolStore.tools) {
|
||||
ItemDefinition n = ItemDefinition.forId(itemId);
|
||||
itemNames.add(n.getName());
|
||||
}
|
||||
interpreter.sendOptions("Select a Tool", itemNames.toArray(new String[itemNames.size()]));
|
||||
stage = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 1:
|
||||
Item item = new Item(toolStore.tools[buttonId - 1], 1);
|
||||
if (player.getInventory().freeSlots() <= 0) {
|
||||
interpreter.sendDialogue("You have no space in your inventory.");
|
||||
stage = 2;
|
||||
return true;
|
||||
}
|
||||
player.getInventory().add(item);
|
||||
end();
|
||||
return true;
|
||||
case 2:
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { DialogueInterpreter.getDialogueKey("con:tools") };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
package content.global.skill.construction.decoration.workshop
|
||||
|
||||
|
||||
|
||||
import core.api.*
|
||||
import core.cache.def.impl.SceneryDefinition
|
||||
import core.game.dialogue.DialogueInterpreter
|
||||
import core.game.dialogue.DialoguePlugin
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.plugin.ClassScanner.definePlugin
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
import org.rs09.consts.Items
|
||||
|
||||
/**
|
||||
* Handles the 5 types of tool stores
|
||||
* ToolsPlugin.java
|
||||
* @author Clayton Williams
|
||||
* @date Oct 29, 2015
|
||||
*/
|
||||
|
||||
|
||||
@Initializable
|
||||
class ToolsPlugin : OptionHandler() {
|
||||
val id =0
|
||||
@Throws(Throwable::class)
|
||||
override fun newInstance(arg: Any?): Plugin<Any?> {
|
||||
definePlugin(ToolDialogue())
|
||||
SceneryDefinition.forId(13699).getHandlers().put("option:search", this)
|
||||
SceneryDefinition.forId(13700).getHandlers().put("option:search", this)
|
||||
SceneryDefinition.forId(13701).getHandlers().put("option:search", this)
|
||||
SceneryDefinition.forId(13702).getHandlers().put("option:search", this)
|
||||
SceneryDefinition.forId(13703).getHandlers().put("option:search", this)
|
||||
return this
|
||||
}
|
||||
override fun handle(player: Player, node: Node, option: String?): Boolean {
|
||||
openDialogue(player,DialogueInterpreter.getDialogueKey("con:tools"), node.getId())
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the tool dialogue
|
||||
* @author Clayton Williams
|
||||
* @date Oct 29, 2015
|
||||
*/
|
||||
private inner class ToolDialogue : DialoguePlugin {
|
||||
private var id: Int? = null
|
||||
/**
|
||||
* Constructs a new `ToolDialogue` `Object`.
|
||||
*/
|
||||
constructor()
|
||||
|
||||
/**
|
||||
* Constructs a new `ToolDialogue` `Object`.
|
||||
*
|
||||
* @param player
|
||||
* the player.
|
||||
*/
|
||||
constructor(player: Player?) : super(player)
|
||||
|
||||
fun addItemMsg(player: Player, id: Int, amount: Int = 1) {
|
||||
|
||||
if (!addItem(player, id,amount)){
|
||||
sendDialogue(player, "You have no space in your inventory.")
|
||||
stage = 3 //Stage 3, player just needs to confirm they received the no inventory space dialogue
|
||||
} else {end()} //Player received their Item, close dialogue
|
||||
}
|
||||
|
||||
public override fun newInstance(player: Player?): DialoguePlugin {
|
||||
return ToolDialogue(player)
|
||||
}
|
||||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
id = args[0] as Int
|
||||
when (id) {
|
||||
13699 -> {
|
||||
sendDialogueOptions(player,"Select a Tool", "Saw", "Chisel", "Hammer", "Shears")
|
||||
}
|
||||
|
||||
13700 -> {
|
||||
sendDialogueOptions(player,"Select a Tool", "Bucket", "Knife", "Spade", "Tinderbox")
|
||||
}
|
||||
|
||||
13701 -> {
|
||||
sendDialogueOptions(player,"Select a Tool", "Brown apron", "Glassblowing pipe", "Needle")
|
||||
}
|
||||
|
||||
13702 -> {
|
||||
sendDialogueOptions(player,"Select a Tool","Amulet mould","Necklace mould","Ring mould","Holy mould","More Options"
|
||||
)
|
||||
stage = 1
|
||||
}
|
||||
|
||||
13703 -> {
|
||||
sendDialogueOptions(player,"Select a Tool", "Rake", "Spade", "Trowel", "Seed dibber", "Watering can")
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
if (stage == 3) {//If reply was on full inventory confirmation, close dialogue
|
||||
end()
|
||||
return true
|
||||
}
|
||||
when (id) {
|
||||
13699 -> {
|
||||
when (buttonId) {
|
||||
1 -> {
|
||||
addItemMsg(player, Items.SAW_8794)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
addItemMsg(player, Items.CHISEL_1755)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
addItemMsg(player, Items.HAMMER_2347)
|
||||
}
|
||||
|
||||
4 -> {
|
||||
addItemMsg(player, Items.SHEARS_1735)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13700 -> {
|
||||
when (buttonId) {
|
||||
1 -> {
|
||||
addItemMsg(player, Items.BUCKET_1925)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
addItemMsg(player, Items.KNIFE_946)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
addItemMsg(player, Items.SPADE_952)
|
||||
}
|
||||
|
||||
4 -> {
|
||||
addItemMsg(player, Items.TINDERBOX_590)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13701 -> {
|
||||
when (buttonId) {
|
||||
1 -> {
|
||||
addItemMsg(player, Items.BROWN_APRON_1757)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
addItemMsg(player, Items.GLASSBLOWING_PIPE_1785)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
addItemMsg(player, Items.NEEDLE_1733)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13702 -> {
|
||||
when (stage) {
|
||||
1 -> when (buttonId) {
|
||||
1 -> {
|
||||
addItemMsg(player, Items.AMULET_MOULD_1595)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
addItemMsg(player, Items.NECKLACE_MOULD_1597)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
addItemMsg(player, Items.RING_MOULD_1592)
|
||||
}
|
||||
|
||||
4 -> {
|
||||
addItemMsg(player, Items.HOLY_MOULD_1599)
|
||||
}
|
||||
|
||||
5 -> {
|
||||
sendDialogueOptions(player,
|
||||
"Select a Tool", "Bracelet mould", "Tiara mould"
|
||||
)
|
||||
stage = 2
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
when (buttonId) {
|
||||
1 -> {
|
||||
addItemMsg(player, Items.BRACELET_MOULD_11065)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
addItemMsg(player, Items.TIARA_MOULD_5523)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
13703 -> {
|
||||
when (buttonId) {
|
||||
1 -> {
|
||||
addItemMsg(player, Items.RAKE_5341)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
addItemMsg(player, Items.SPADE_952)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
addItemMsg(player, Items.TROWEL_676)
|
||||
}
|
||||
|
||||
4 -> {
|
||||
addItemMsg(player, Items.SEED_DIBBER_5343)
|
||||
}
|
||||
|
||||
5 -> {
|
||||
addItemMsg(player, Items.WATERING_CAN_5331)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(DialogueInterpreter.getDialogueKey("con:tools"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ public enum CookableItems {
|
|||
// bowl foods
|
||||
BOWL_STEW(2003, 2001, 2005, 25, 117, 68, 392, 68, 392),
|
||||
BOWL_CURRY(2011, 2009, 2013, 60, 280, 38, 332, 38, 332),
|
||||
BOWL_NETTLE(4239, 4237, 4239, 20, 52, 78, 412, 78, 412),
|
||||
BOWL_NETTLE(4239, 4237, 4239, 20, 53, 78, 412, 78, 412),
|
||||
BOWL_EGG(7078, 7076, 7090, 13, 50, 0, 0, 90, 438),
|
||||
BOWL_ONION(7084, 1871, 7092, 43, 60, 36, 322, 36, 322),
|
||||
BOWL_MUSHROOM(7082, 7080, 7094, 46, 60, 16, 282, 16, 282),
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
package content.global.skill.cooking
|
||||
|
||||
import core.api.amountInInventory
|
||||
import content.region.misc.tutisland.handlers.TutorialStage
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.impl.Animator
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.game.node.scenery.Scenery
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Items.BREAD_DOUGH_2307
|
||||
import org.rs09.consts.Items.RAW_BEAR_MEAT_2136
|
||||
import org.rs09.consts.Items.RAW_BEEF_2132
|
||||
import org.rs09.consts.Items.SEAWEED_401
|
||||
import org.rs09.consts.Items.UNCOOKED_CAKE_1889
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
/**
|
||||
* @author Ceikry
|
||||
|
|
@ -28,12 +33,41 @@ class CookingRewrite : InteractionListener {
|
|||
list.add(RAW_BEEF_2132)
|
||||
list.add(RAW_BEAR_MEAT_2136)
|
||||
list.add(SEAWEED_401)
|
||||
list.add(Items.BOWL_OF_WATER_1921)
|
||||
RAW_FOODS = list.toIntArray()
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
|
||||
onUseWith(IntType.SCENERY,RAW_FOODS, *COOKING_OBJs){ player, used, with ->
|
||||
if (!getAttribute(player, "/save:tutorial:complete", false)) {
|
||||
// On tutorial island, we don't want to show the cook-x menu and we always want to burn our first shrimp
|
||||
// This requirement of a simplified and predictable cooking system means that, for the second time, I have to reinvent the wheel of cooking
|
||||
// (We only need to care about shrimp here, the tutorial island range is special and has its own separate listener)
|
||||
queueScript(player, 0, QueueStrength.WEAK) { stage ->
|
||||
if (stage == 0) {
|
||||
val FIRE_ANIMATION = Animation(897, Animator.Priority.HIGH)
|
||||
lock(player, FIRE_ANIMATION.duration)
|
||||
lockInteractions(player, FIRE_ANIMATION.duration)
|
||||
animate(player, FIRE_ANIMATION)
|
||||
playAudio(player, Sounds.FRY_2577)
|
||||
return@queueScript delayScript(player, FIRE_ANIMATION.duration)
|
||||
}
|
||||
val tutStage = getAttribute(player, "/save:tutorial:stage", 0)
|
||||
if (tutStage < 15) {
|
||||
replaceSlot(player, used.asItem().slot, Item(Items.BURNT_SHRIMP_7954), used.asItem())
|
||||
setAttribute(player, "tutorial:stage", 15)
|
||||
TutorialStage.load(player, 15)
|
||||
} else {
|
||||
replaceSlot(player, used.asItem().slot, Item(Items.SHRIMPS_315), used.asItem())
|
||||
if (tutStage == 15) {
|
||||
setAttribute(player, "tutorial:stage", 16)
|
||||
TutorialStage.load(player, 16)
|
||||
}
|
||||
}
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
val item = used.asItem()
|
||||
val obj = with.asScenery()
|
||||
val range = obj.name.toLowerCase().contains("range")
|
||||
|
|
@ -46,6 +80,10 @@ class CookingRewrite : InteractionListener {
|
|||
player.packetDispatch.sendMessage("You need to cook this on a range.")
|
||||
return@onUseWith false
|
||||
}
|
||||
Items.BOWL_OF_WATER_1921 ->{
|
||||
cook(player, obj, Items.BOWL_OF_WATER_1921, Items.BOWL_OF_HOT_WATER_4456, 1)
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
|
||||
//cook a standard item
|
||||
|
|
@ -66,7 +104,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, 18170, 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, 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) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.skill.cooking
|
||||
|
||||
import content.region.misc.tutisland.handlers.TutorialStage
|
||||
import core.api.*
|
||||
import core.game.event.ResourceProducedEvent
|
||||
import core.game.node.entity.skill.Skills
|
||||
|
|
@ -24,7 +25,16 @@ class DoughMakingListener : InteractionListener {
|
|||
FULL_WATER_CONTAINERS_TO_EMPTY_CONTAINERS.keys.toIntArray(),
|
||||
Items.POT_OF_FLOUR_1933
|
||||
) { player, waterContainer, flourContainer ->
|
||||
openDialogue(player, DoughMakeDialogue(waterContainer.asItem(), flourContainer.asItem()))
|
||||
if (getAttribute(player, "/save:tutorial:complete", false)) {
|
||||
openDialogue(player, DoughMakeDialogue(waterContainer.asItem(), flourContainer.asItem()))
|
||||
return@onUseWith true
|
||||
}
|
||||
// Continue the tutorial
|
||||
replaceSlot(player, waterContainer.asItem().slot, Item(Items.BUCKET_1925), waterContainer.asItem())
|
||||
replaceSlot(player, flourContainer.asItem().slot, Item(Items.EMPTY_POT_1931), flourContainer.asItem())
|
||||
addItemOrDrop(player, Items.BREAD_DOUGH_2307)
|
||||
setAttribute(player, "tutorial:stage", 20)
|
||||
TutorialStage.load(player, 20)
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +83,7 @@ class DoughMakingListener : InteractionListener {
|
|||
|
||||
sendMessage(
|
||||
player!!,
|
||||
"You mix the flower and the water to make some ${selectedDoughProduct.itemName.toLowerCase()}."
|
||||
"You mix the flour and the water to make some ${selectedDoughProduct.itemName.toLowerCase()}."
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package content.global.skill.cooking
|
||||
|
||||
import org.rs09.consts.Items
|
||||
import core.api.replaceSlot
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.item.Item
|
||||
|
||||
class NettleTeaListener : InteractionListener {
|
||||
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.ITEM, Items.EMPTY_CUP_1980, Items.NETTLE_TEA_4239) { player, used, with ->
|
||||
replaceSlot(player, with.asItem().slot, Item(Items.BOWL_1923), with.asItem())
|
||||
replaceSlot(player, used.asItem().slot, Item(Items.CUP_OF_TEA_4242), used.asItem())
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
package content.global.skill.cooking;
|
||||
|
||||
import core.game.interaction.NodeUsageEvent;
|
||||
import core.game.interaction.UseWithHandler;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to create nettle tea in a cup.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class NettleTeaPlugin extends UseWithHandler {
|
||||
|
||||
/**
|
||||
* Represents the empty cup item.
|
||||
*/
|
||||
private static final Item EMPTY_CUP = new Item(1980, 1);
|
||||
|
||||
/**
|
||||
* Represents the nettle tea item.
|
||||
*/
|
||||
private static final Item NETTLE_TEA = new Item(4239, 1);
|
||||
|
||||
/**
|
||||
* Represents the bowl item.
|
||||
*/
|
||||
private static final Item BOWL = new Item(1923);
|
||||
|
||||
/**
|
||||
* Represents the cup of tea item.
|
||||
*/
|
||||
private static final Item CUP_OF_TEA = new Item(4242, 1);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code NettleTeaPlugin} {@code Object}.
|
||||
*/
|
||||
public NettleTeaPlugin() {
|
||||
super(1980);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
addHandler(4239, ITEM_TYPE, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
if (player.getInventory().remove(EMPTY_CUP) && player.getInventory().remove(NETTLE_TEA)) {
|
||||
player.getInventory().add(BOWL);
|
||||
player.getInventory().add(CUP_OF_TEA);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package content.global.skill.cooking
|
||||
|
||||
import org.rs09.consts.Items
|
||||
import core.api.replaceSlot
|
||||
import core.api.removeItem
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.item.Item
|
||||
|
||||
class NettleWaterListener : InteractionListener {
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.ITEM, Items.BOWL_OF_WATER_1921, Items.NETTLES_4241) { player, used, with ->
|
||||
replaceSlot(player, used.asItem().slot, Item(Items.NETTLE_WATER_4237), used.asItem())
|
||||
removeItem(player, with.asItem())
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package content.global.skill.cooking;
|
||||
|
||||
import core.game.interaction.NodeUsageEvent;
|
||||
import core.game.interaction.UseWithHandler;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* @author Adam
|
||||
*/
|
||||
@Initializable
|
||||
public class NettleWaterPlugin extends UseWithHandler {
|
||||
|
||||
public NettleWaterPlugin() {
|
||||
super(1921);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
player.getInventory().remove(new Item(1921, 1));
|
||||
player.getInventory().remove(new Item(4241, 1));
|
||||
player.getInventory().add(new Item(4237, 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
addHandler(4241, ITEM_TYPE, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
166
Server/src/main/content/global/skill/cooking/TeaInteraction.kt
Normal file
166
Server/src/main/content/global/skill/cooking/TeaInteraction.kt
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
package content.global.skill.cooking
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import org.rs09.consts.Items
|
||||
|
||||
/**
|
||||
* This deals with all tea mixtures
|
||||
* cup of tea
|
||||
* nettle tea
|
||||
* nettle water
|
||||
* nettle tea (cup)
|
||||
* poh tea
|
||||
* clay
|
||||
* porcelain
|
||||
* gold trim
|
||||
* Flask
|
||||
*/
|
||||
class TeaInteraction : InteractionListener {
|
||||
private val teaMilkMap = mapOf(
|
||||
Items.NETTLE_TEA_4239 to Items.NETTLE_TEA_4240,
|
||||
Items.CUP_OF_TEA_4242 to Items.CUP_OF_TEA_4243,
|
||||
Items.CUP_OF_TEA_4245 to Items.CUP_OF_TEA_4246,
|
||||
Items.CUP_OF_TEA_7730 to Items.CUP_OF_TEA_7731,
|
||||
Items.CUP_OF_TEA_7733 to Items.CUP_OF_TEA_7734,
|
||||
Items.CUP_OF_TEA_7736 to Items.CUP_OF_TEA_7737,
|
||||
)
|
||||
|
||||
private val teaCupMap = mapOf(
|
||||
Items.NETTLE_TEA_4239 to Items.CUP_OF_TEA_4242,
|
||||
Items.NETTLE_TEA_4240 to Items.CUP_OF_TEA_4243,
|
||||
Items.BOWL_OF_HOT_WATER_4456 to Items.CUP_OF_HOT_WATER_4460
|
||||
)
|
||||
|
||||
// This is specifically for the porcelain cup without a handle for Ghost Ahoy
|
||||
private val teaCupPorcelainMap = mapOf(
|
||||
Items.NETTLE_TEA_4239 to Items.CUP_OF_TEA_4245,
|
||||
Items.NETTLE_TEA_4240 to Items.CUP_OF_TEA_4246
|
||||
)
|
||||
|
||||
private val emptyTeaPot = intArrayOf(
|
||||
Items.TEAPOT_7702,
|
||||
Items.TEAPOT_7714,
|
||||
Items.TEAPOT_7726
|
||||
)
|
||||
|
||||
private val leafTeaPot = intArrayOf(
|
||||
Items.TEAPOT_WITH_LEAVES_7700,
|
||||
Items.TEAPOT_WITH_LEAVES_7712,
|
||||
Items.TEAPOT_WITH_LEAVES_7724
|
||||
)
|
||||
|
||||
private val filledTeaPot = intArrayOf(
|
||||
Items.POT_OF_TEA_4_7692,
|
||||
Items.POT_OF_TEA_3_7694,
|
||||
Items.POT_OF_TEA_2_7696,
|
||||
Items.POT_OF_TEA_1_7698,
|
||||
Items.POT_OF_TEA_4_7704,
|
||||
Items.POT_OF_TEA_3_7706,
|
||||
Items.POT_OF_TEA_2_7708,
|
||||
Items.POT_OF_TEA_1_7710,
|
||||
Items.POT_OF_TEA_4_7716,
|
||||
Items.POT_OF_TEA_3_7718,
|
||||
Items.POT_OF_TEA_2_7720,
|
||||
Items.POT_OF_TEA_1_7722,
|
||||
)
|
||||
|
||||
private val emptyBuilderCup = intArrayOf(
|
||||
Items.EMPTY_CUP_7728,
|
||||
Items.PORCELAIN_CUP_7732,
|
||||
Items.PORCELAIN_CUP_7735
|
||||
)
|
||||
|
||||
override fun defineListeners() {
|
||||
onUseWith(ITEM, teaMilkMap.keys.toIntArray(), Items.BUCKET_OF_MILK_1927){ player, used, with ->
|
||||
if (removeItem(player, used) && removeItem(player, with)){
|
||||
addItem(player, teaMilkMap[used.id]!!)
|
||||
addItem(player, Items.BUCKET_1925)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(ITEM, teaCupMap.keys.toIntArray(), Items.EMPTY_CUP_1980){ player, used, with ->
|
||||
if (used.id != Items.BOWL_OF_HOT_WATER_4456){
|
||||
if (getDynLevel(player, Skills.COOKING) < 20){
|
||||
sendDialogue(player, "You need a cooking level of 20 to make tea.")
|
||||
return@onUseWith false
|
||||
}
|
||||
}
|
||||
if (removeItem(player, used) && removeItem(player, with)) {
|
||||
addItem(player, teaCupMap[used.id]!!)
|
||||
addItem(player, Items.BOWL_1923)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(ITEM, Items.BOWL_OF_WATER_1921, Items.NETTLES_4241) { player, used, with ->
|
||||
if (removeItem(player, used) && removeItem(player, with)){
|
||||
addItem(player, Items.NETTLE_WATER_4237)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(ITEM, teaCupPorcelainMap.keys.toIntArray(), Items.PORCELAIN_CUP_4244){player, used, with ->
|
||||
if (getDynLevel(player, Skills.COOKING) < 20){
|
||||
sendDialogue(player, "You need a cooking level of 20 to make tea.")
|
||||
return@onUseWith false
|
||||
}
|
||||
|
||||
if(removeItem(player, used) && removeItem(player, with)){
|
||||
addItem(player, teaCupPorcelainMap[used.id]!!)
|
||||
addItem(player, Items.BOWL_1923)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(ITEM, emptyTeaPot, Items.TEA_LEAVES_7738) { player, used, with ->
|
||||
if (removeItem(player, used) && removeItem(player, with)){
|
||||
addItem(player, used.id - 2)
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(ITEM, leafTeaPot, Items.HOT_KETTLE_7691) { player, used, with ->
|
||||
if (getDynLevel(player, Skills.COOKING) < 20){
|
||||
sendDialogue(player,"You need to be level 20 to make tea.")
|
||||
return@onUseWith false
|
||||
}
|
||||
if (removeItem(player, used) && removeItem(player, with)){
|
||||
addItem(player, Items.KETTLE_7688)
|
||||
addItem(player, used.id - 8)
|
||||
rewardXP(player, Skills.COOKING, 53.0)
|
||||
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(ITEM, filledTeaPot, *emptyBuilderCup) { player, used, with ->
|
||||
return@onUseWith fillBuildersTea(player, used, with)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fillBuildersTea(player: Player, used: Node, with: Node) : Boolean {
|
||||
if (removeItem(player, used) && removeItem(player, with)){
|
||||
// Thanks tea pot with tea leaves
|
||||
if (used.id + 4 in emptyTeaPot){
|
||||
addItem(player, used.id + 4)
|
||||
}
|
||||
else{
|
||||
addItem(player, used.id + 2)
|
||||
}
|
||||
// Why do these cups have a noted form!
|
||||
if (with.id == Items.EMPTY_CUP_7728){
|
||||
addItem(player, with.id + 2)
|
||||
}
|
||||
else{
|
||||
addItem(player, with.id + 1)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ public final class PotteryPlugin extends UseWithHandler {
|
|||
@Override
|
||||
public boolean handle(final NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(false)) {
|
||||
new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getPottery(false)) {
|
||||
|
||||
@Override
|
||||
public void create(final int amount, int index) {
|
||||
|
|
@ -145,7 +145,7 @@ public final class PotteryPlugin extends UseWithHandler {
|
|||
* @return the dialogue handler.
|
||||
*/
|
||||
public SkillDialogueHandler getSkillHandler(final Player player) {
|
||||
return new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(true)) {
|
||||
return new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getPottery(true)) {
|
||||
|
||||
@Override
|
||||
public void create(final int amount, final int index) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public class SnakeSkinPlugin extends UseWithHandler {
|
|||
@Override
|
||||
public boolean handle(final NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getSkins()) {
|
||||
new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, getSkins()) {
|
||||
|
||||
@Override
|
||||
public void create(final int amount, int index) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
package content.global.skill.crafting.lightsources
|
||||
|
||||
import content.data.LightSource
|
||||
import core.api.log
|
||||
import core.api.*
|
||||
import core.cache.def.impl.ItemDefinition
|
||||
import core.game.container.Container
|
||||
import core.game.interaction.OptionHandler
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
import core.tools.SystemLogger
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
|
|
@ -32,6 +35,12 @@ class LightSourceExtinguisher : OptionHandler(){
|
|||
|
||||
lightSource ?: return false.also { log(this::class.java, Log.WARN, "UNHANDLED EXTINGUISH OPTION: ID = ${node.id}") }
|
||||
|
||||
// For Temple of Ikov - if you are in the dark basement, do not let light source extinguish.
|
||||
if(player.location.isInRegion(10648)) {
|
||||
sendMessage(player, "Extinguishing the " + LightSource.getActiveLightSource(player).product.name.lowercase() + " would leave you without a light source.")
|
||||
return true
|
||||
}
|
||||
|
||||
player.inventory.replace(node.asItem(), Item(lightSource.fullID))
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
package content.global.skill.crafting.lightsources
|
||||
|
||||
import core.api.*
|
||||
import core.api.teleport
|
||||
import core.game.container.Container
|
||||
import core.game.event.LitLightSourceEvent
|
||||
import core.game.interaction.NodeUsageEvent
|
||||
import core.game.interaction.UseWithHandler
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
import core.plugin.Initializable
|
||||
import core.plugin.Plugin
|
||||
|
||||
|
|
@ -72,6 +76,14 @@ class LightSourceLighter : UseWithHandler(590,36,38){
|
|||
return true
|
||||
}
|
||||
|
||||
// For Temple of Ikov - if you are in the dark basement and light a light source, switch to the light basement.
|
||||
// For the listener that covers the firemaking cape perk, see content.global.skill.skillcapeperks.SkillcapePerks.kt
|
||||
if(event.player.location.isInRegion(10648) && event.player.location.withinDistance(Location(2639,9738,0), 8)) {
|
||||
teleport(event.player, Location.create(event.player.getLocation().getX(), event.player.getLocation().getY() + 23, event.player.getLocation().getZ()))
|
||||
closeDialogue(event.player)
|
||||
// Dark basement is region 10648, min 2639 9738 0, max 2643 9744 0. Add 23 to the Y loc to tele to light basement
|
||||
}
|
||||
|
||||
if(!light(event.player,used,lightSource)){
|
||||
event.player.sendMessage("You need a Firemaking level of at least ${lightSource.levelRequired} to light this.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ enum class SilverProduct(
|
|||
val strungId: Int
|
||||
) {
|
||||
HOLY(BUTTON_UNBLESSED, Items.HOLY_MOULD_1599, Items.UNSTRUNG_SYMBOL_1714, 1, 16, 50.0, Items.UNBLESSED_SYMBOL_1716),
|
||||
UNHOLY(BUTTON_UNHOLY, Items.UNHOLY_MOULD_1594, Items.UNSTRUNG_EMBLEM_1720, 1, 17, 50.0, Items.UNHOLY_SYMBOL_1724),
|
||||
UNHOLY(BUTTON_UNHOLY, Items.UNHOLY_MOULD_1594, Items.UNSTRUNG_EMBLEM_1720, 1, 17, 50.0, Items.UNPOWERED_SYMBOL_1722),
|
||||
SICKLE(BUTTON_SICKLE, Items.SICKLE_MOULD_2976, Items.SILVER_SICKLE_2961, 1, 18, 50.0, -1),
|
||||
TIARA(BUTTON_TIARA, Items.TIARA_MOULD_5523, Items.TIARA_5525, 1, 23, 52.5, -1),
|
||||
SILVTHRIL_CHAIN(BUTTON_SILVTHRIL_CHAIN, Items.CHAIN_LINK_MOULD_13153, Items.SILVTHRIL_CHAIN_13154, 1, 47, 100.0, -1),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package content.global.skill.fletching
|
||||
|
||||
object AchievementDiaryAttributeKeys {
|
||||
/**
|
||||
* This attribute signifies that the fletch of the magic shortbow is complete which is the first stage of getting the achievement
|
||||
*/
|
||||
const val FLETCHED_UNSTRUNG_MAGIC_SHORTBOW = "diary:seers:fletch-magic-short-bow"
|
||||
}
|
||||
16
Server/src/main/content/global/skill/fletching/Feathers.kt
Normal file
16
Server/src/main/content/global/skill/fletching/Feathers.kt
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package content.global.skill.fletching
|
||||
|
||||
import org.rs09.consts.Items
|
||||
|
||||
object Feathers {
|
||||
val all = intArrayOf(
|
||||
Items.FEATHER_314,
|
||||
Items.STRIPY_FEATHER_10087,
|
||||
Items.RED_FEATHER_10088,
|
||||
Items.BLUE_FEATHER_10089,
|
||||
Items.YELLOW_FEATHER_10090,
|
||||
Items.ORANGE_FEATHER_10091
|
||||
)
|
||||
|
||||
const val STANDARD = Items.FEATHER_314
|
||||
}
|
||||
|
|
@ -1,355 +0,0 @@
|
|||
package content.global.skill.fletching;
|
||||
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
|
||||
import java.util.HashMap;
|
||||
public class Fletching {
|
||||
public static HashMap<Integer, FletchingItems[]>logMap = new HashMap<>();
|
||||
public static HashMap<Integer, Bolts> boltMap = new HashMap<>();
|
||||
public static HashMap<Integer, Darts> dartMap = new HashMap<>();
|
||||
public static HashMap<Integer, ArrowHeads> arrowHeadMap = new HashMap<>();
|
||||
public static HashMap<Integer, GemBolts> gemMap = new HashMap<>();
|
||||
public static HashMap<Integer, GemBolts> tipMap = new HashMap<>();
|
||||
public static HashMap<Integer, String> stringMap = new HashMap<>();
|
||||
public static HashMap<Integer, Limb> limbMap = new HashMap<>();
|
||||
static{
|
||||
Items[] itemsArray = Items.values();
|
||||
int thisLength = itemsArray.length;
|
||||
for(int x = 0; x < thisLength; x++){
|
||||
Items item = itemsArray[x];
|
||||
logMap.putIfAbsent(item.id, item.items);
|
||||
}
|
||||
Bolts[] boltArray = Bolts.values();
|
||||
thisLength = boltArray.length;
|
||||
for(int x = 0; x < thisLength; x++){
|
||||
Bolts bolt = boltArray[x];
|
||||
boltMap.putIfAbsent(bolt.unfinished,bolt);
|
||||
}
|
||||
Darts[] dartArray = Darts.values();
|
||||
thisLength = dartArray.length;
|
||||
for(int x = 0; x < thisLength; x++){
|
||||
Darts dart = dartArray[x];
|
||||
dartMap.putIfAbsent(dart.unfinished,dart);
|
||||
}
|
||||
ArrowHeads[] ahArray = ArrowHeads.values();
|
||||
thisLength = ahArray.length;
|
||||
for(int x = 0; x < thisLength; x++){
|
||||
ArrowHeads arrowhead = ahArray[x];
|
||||
arrowHeadMap.putIfAbsent(arrowhead.unfinished,arrowhead);
|
||||
}
|
||||
GemBolts[] gbArray = GemBolts.values();
|
||||
thisLength = gbArray.length;
|
||||
for(int x = 0; x < thisLength; x++){
|
||||
GemBolts gem = gbArray[x];
|
||||
gemMap.putIfAbsent(gem.gem,gem);
|
||||
tipMap.putIfAbsent(gem.tip,gem);
|
||||
}
|
||||
String[] stringArray = String.values();
|
||||
thisLength = stringArray.length;
|
||||
for(int x = 0; x < thisLength; x++){
|
||||
String bow = stringArray[x];
|
||||
stringMap.putIfAbsent(bow.unfinished,bow);
|
||||
}
|
||||
Limb[] limbsArray = Limb.values();
|
||||
thisLength = limbsArray.length;
|
||||
for(int x = 0; x < thisLength; x++){
|
||||
Limb limb = limbsArray[x];
|
||||
limbMap.putIfAbsent(limb.stock, limb);
|
||||
}
|
||||
}
|
||||
public static FletchingItems[] getEntries(int id){
|
||||
return logMap.get(id);
|
||||
}
|
||||
public static boolean isLog(int id){
|
||||
return logMap.get(id) != null;
|
||||
}
|
||||
public static boolean isBolt(int id){
|
||||
return boltMap.get(id) != null;
|
||||
}
|
||||
public static boolean isDart(int id){
|
||||
return dartMap.get(id) != null;
|
||||
}
|
||||
public static boolean isArrowHead(int id){
|
||||
return arrowHeadMap.get(id) != null;
|
||||
}
|
||||
public static boolean isGemTip(int id){
|
||||
return tipMap.get(id) != null;
|
||||
}
|
||||
public static Item[] getItems(int id){
|
||||
FletchingItems[] entry = getEntries(id);
|
||||
Item items[] = {};
|
||||
switch(entry.length){
|
||||
case 1:
|
||||
items = new Item[] {new Item(entry[0].id)};
|
||||
break;
|
||||
case 2:
|
||||
items = new Item[] {new Item(entry[0].id), new Item(entry[1].id)};
|
||||
break;
|
||||
case 3:
|
||||
items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id)};
|
||||
break;
|
||||
case 4:
|
||||
items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id), new Item(entry[3].id)};
|
||||
break;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
public enum Limb {
|
||||
WOODEN_STOCK(9440,9420,9454,9, 12, new Animation(4436)),
|
||||
OAK_STOCK(9442,9422,9456,24, 32, new Animation(4437)),
|
||||
WILLOW_STOCK(9444,9423,9457,39, 44, new Animation(4438)),
|
||||
TEAK_STOCK(9446,9425,9459,46, 54, new Animation(4439)),
|
||||
MAPLE_STOCK(9448,9427,9461,54, 64, new Animation(4440)),
|
||||
MAHOGANY_STOCK(9450,9429,9463,61, 82, new Animation(4441)),
|
||||
YEW_STOCK(9452,9431,9465,69, 100, new Animation(4442));
|
||||
|
||||
|
||||
public int stock, limb, product,level;
|
||||
public double experience;
|
||||
public Animation animation;
|
||||
|
||||
Limb(int stock, int limb, int product, int level, double experience, Animation animation) {
|
||||
this.stock = stock;
|
||||
this.limb = limb;
|
||||
this.product = product;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.animation = animation;
|
||||
}
|
||||
}
|
||||
public enum String{
|
||||
//Bows
|
||||
SHORT_BOW((byte) 1,50,841,5, 5, new Animation(6678)),
|
||||
LONG_BOW((byte) 1,48,839,10, 10, new Animation(6684)),
|
||||
OAK_SHORTBOW((byte) 1,54,843,20, 16.5, new Animation(6679)),
|
||||
OAK_LONGBOW((byte) 1,56,845,25, 25, new Animation(6685)),
|
||||
WILLOW_SHORTBOW((byte) 1,60,849,35, 33.3, new Animation(6680)),
|
||||
WILLOW_LONGBOW((byte) 1,58,847,40, 41.5, new Animation(6686)),
|
||||
MAPLE_SHORTBOW((byte) 1,64,853,50, 50, new Animation(6681)),
|
||||
MAPLE_LONGBOW((byte) 1,62,851,55, 58.3, new Animation(6687)),
|
||||
YEW_SHORTBOW((byte) 1,68,857,65, 67.5, new Animation(6682)),
|
||||
YEW_LONGBOW((byte) 1,66,855,70, 75, new Animation(6688)),
|
||||
MAGIC_SHORTBOW((byte) 1,72,861,80, 83.3, new Animation(6683)),
|
||||
MAGIC_LONGBOW((byte) 1,70,859,85, 91.5, new Animation(6689)),
|
||||
OGRE_COMP_BOW((byte) 1,4825,4827,30, 45, new Animation(-1)),
|
||||
|
||||
//crossbows
|
||||
BRONZE_CBOW((byte) 2,9454,9174,9, 6, new Animation(6671)),
|
||||
BLURITE_CBOW((byte) 2,9456,9176,24, 16, new Animation(6672)),
|
||||
IRON_CBOW((byte) 2,9457,9177,39, 22, new Animation(6673)),
|
||||
STEEL_CBOW((byte) 2,9459,9179,46, 27, new Animation(6674)),
|
||||
MITHIRIL_CBOW((byte) 2,9461,9181,54, 32, new Animation(6675)),
|
||||
ADAMANT_CBOW((byte) 2,9463,9183,61, 41, new Animation(6676)),
|
||||
RUNITE_CBOW((byte) 2,9465,9185,69, 50, new Animation(6677));
|
||||
|
||||
|
||||
public int unfinished,product,string,level;
|
||||
public final double experience;
|
||||
public final Animation animation;
|
||||
String(byte indicator, final int unfinished, final int product, final int level, final double experience, final Animation animation) {
|
||||
this.unfinished = unfinished;
|
||||
this.product = product;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
this.animation = animation;
|
||||
switch(indicator & 0xFF){
|
||||
case 1:
|
||||
this.string = org.rs09.consts.Items.BOW_STRING_1777;
|
||||
break;
|
||||
case 2:
|
||||
this.string = org.rs09.consts.Items.CROSSBOW_STRING_9438;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public enum GemBolts {
|
||||
OPAL(877, org.rs09.consts.Items.OPAL_1609, 45, 879, 11, 1.6),
|
||||
PEARL(9140, org.rs09.consts.Items.OYSTER_PEARL_411, 46, 880, 41, 3.2),
|
||||
PEARLS(9140, org.rs09.consts.Items.OYSTER_PEARLS_413, 46, 880, 41, 3.2),
|
||||
JADE(9139, org.rs09.consts.Items.JADE_1611, 9187, 9335, 26, 2.4),
|
||||
RED_TOPAZ(9141, org.rs09.consts.Items.RED_TOPAZ_1613, 9188, 9336, 48, 3.9),
|
||||
SAPPHIRE(9142, org.rs09.consts.Items.SAPPHIRE_1607, 9189, 9337, 56, 4.7),
|
||||
EMERALD(9142, org.rs09.consts.Items.EMERALD_1605, 9190, 9338, 58, 5.5),
|
||||
RUBY(9143, org.rs09.consts.Items.RUBY_1603, 9191, 9339, 63, 6.3),
|
||||
DIAMOND(9143, org.rs09.consts.Items.DIAMOND_1601, 9192, 9340, 65, 7),
|
||||
DRAGONSTONE(9144, org.rs09.consts.Items.DRAGONSTONE_1615, 9193, 9341, 71, 8.2),
|
||||
ONYX(9144, org.rs09.consts.Items.ONYX_6573, 9194, 9342, 73, 9.4);
|
||||
|
||||
public int gem,tip,base,product,level;
|
||||
public double experience;
|
||||
GemBolts(int base, int gem, int tip, int product, int level, double experience){
|
||||
this.gem = gem;
|
||||
this.tip = tip;
|
||||
this.base = base;
|
||||
this.product = product;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
}
|
||||
|
||||
}
|
||||
public enum ArrowHeads {
|
||||
BRONZE_ARROW(39, 882, 1, 1.3),
|
||||
IRON_ARROW(40, 884, 15, 2.5),
|
||||
STEEL_ARROW(41, 886, 30, 5),
|
||||
MITHRIL_ARROW(42, 888, 45, 7.5),
|
||||
ADAMANT_ARROW(43, 890, 60, 10),
|
||||
RUNE_ARROW(44, 892, 75, 12.5),
|
||||
DRAGON_ARROW(11237, 11212, 90, 15),
|
||||
BROAD_ARROW(13278, 4160, 52, 15);
|
||||
|
||||
public int unfinished,finished,level;
|
||||
public double experience;
|
||||
ArrowHeads(int unfinished, int finished, int level, double experience){
|
||||
this.unfinished = unfinished;
|
||||
this.finished = finished;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
}
|
||||
public Item getFinished(){
|
||||
return new Item(finished);
|
||||
}
|
||||
public Item getUnfinished(){
|
||||
return new Item(unfinished);
|
||||
}
|
||||
}
|
||||
public enum Darts{
|
||||
BRONZE_DART(819, 806, 1, 1.8),
|
||||
IRON_DART(820, 807, 22, 3.8),
|
||||
STEEL_DART(821, 808, 37, 7.5),
|
||||
MITHRIL_DART(822, 809, 52, 11.2),
|
||||
ADAMANT_DART(823, 810, 67, 15),
|
||||
RUNE_DART(824, 811, 81, 18.8),
|
||||
DRAGON_DART(11232, 11230, 95, 25);
|
||||
|
||||
public int unfinished, finished, level;
|
||||
public double experience;
|
||||
Darts(int unfinished, int finished, int level, double experience){
|
||||
this.unfinished = unfinished;
|
||||
this.finished = finished;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
}
|
||||
public Item getFinished(){
|
||||
return new Item(finished);
|
||||
}
|
||||
public Item getUnfinished(){
|
||||
return new Item(unfinished);
|
||||
}
|
||||
}
|
||||
public enum Bolts{
|
||||
BRONZE_BOLT(9375, 877, 9, 0.5),
|
||||
BLURITE_BOLT(9376, 9139, 24, 1),
|
||||
IRON_BOLT(9377, 9140, 39, 1.5),
|
||||
SILVER_BOLT(9382, 9145, 43, 2.5),
|
||||
STEEL_BOLT(9378, 9141, 46, 3.5),
|
||||
MITHRIL_BOLT(9379, 9142, 54, 5),
|
||||
ADAMANTITE_BOLT(9380, 9143, 61, 7),
|
||||
RUNITE_BOLT(9381, 9144, 69, 10),
|
||||
BROAD_BOLT(13279, 13280, 55, 3);
|
||||
|
||||
public int unfinished, finished, level;
|
||||
public double experience;
|
||||
Bolts(int unfinished, int finished, int level, double experience){
|
||||
this.unfinished = unfinished;
|
||||
this.finished = finished;
|
||||
this.level = level;
|
||||
this.experience = experience;
|
||||
}
|
||||
public Item getFinished(){
|
||||
return new Item(finished);
|
||||
}
|
||||
public Item getUnfinished(){
|
||||
return new Item(unfinished);
|
||||
}
|
||||
}
|
||||
private enum Items{
|
||||
STANDARD(1511,FletchingItems.ARROW_SHAFT, FletchingItems.SHORT_BOW, FletchingItems.LONG_BOW, FletchingItems.WOODEN_STOCK),
|
||||
ACHEY(2862, FletchingItems.OGRE_ARROW_SHAFT, FletchingItems.OGRE_COMP_BOW),
|
||||
OAK(1521, FletchingItems.OAK_SHORTBOW, FletchingItems.OAK_LONGBOW, FletchingItems.OAK_STOCK),
|
||||
WILLOW(1519, FletchingItems.WILLOW_SHORTBOW, FletchingItems.WILLOW_LONGBOW, FletchingItems.WILLOW_STOCK),
|
||||
MAPLE(1517, FletchingItems.MAPLE_SHORTOW, FletchingItems.MAPLE_LONGBOW, FletchingItems.MAPLE_STOCK),
|
||||
YEW(1515, FletchingItems.YEW_SHORTBOW, FletchingItems.YEW_LONGBOW, FletchingItems.YEW_STOCK),
|
||||
MAGIC(1513, FletchingItems.MAGIC_SHORTBOW, FletchingItems.MAGIC_LONGBOW),
|
||||
TEAK(6333, FletchingItems.TEAK_STOCK),
|
||||
MAHOGANY(6332, FletchingItems.MAHOGANY_STOCK);
|
||||
|
||||
|
||||
FletchingItems[] items;
|
||||
int id;
|
||||
Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3, FletchingItems item_4){
|
||||
items = new FletchingItems[] {item_1, item_2, item_3, item_4};
|
||||
this.id = id;
|
||||
}
|
||||
Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3){
|
||||
items = new FletchingItems[] {item_1, item_2, item_3};
|
||||
this.id = id;
|
||||
}
|
||||
Items(int id, FletchingItems item_1, FletchingItems item_2){
|
||||
items = new FletchingItems[] {item_1, item_2};
|
||||
this.id = id;
|
||||
}
|
||||
Items(int id, FletchingItems item_1){
|
||||
items = new FletchingItems[] {item_1};
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
public enum FletchingItems {
|
||||
//Standard logs
|
||||
ARROW_SHAFT(52, 5, 1, 15),
|
||||
SHORT_BOW(50, 5, 5, 1),
|
||||
LONG_BOW(48, 10, 10, 1),
|
||||
WOODEN_STOCK(9440, 6, 9, 1),
|
||||
|
||||
//Achey logs
|
||||
OGRE_ARROW_SHAFT(2864, 6.4, 5, 4),
|
||||
OGRE_COMP_BOW(4825, 45, 30, 1),
|
||||
|
||||
//Oak logs
|
||||
OAK_SHORTBOW(54, 16.5, 20, 1),
|
||||
OAK_LONGBOW(56,25,25,1),
|
||||
OAK_STOCK(9442, 16, 24, 1),
|
||||
|
||||
//Willow logs
|
||||
WILLOW_SHORTBOW(60, 33.3, 35, 1),
|
||||
WILLOW_LONGBOW(58, 41.5, 40, 1),
|
||||
WILLOW_STOCK(9444, 22, 39, 1),
|
||||
|
||||
//Maple logs
|
||||
MAPLE_SHORTOW(64, 50, 50, 1),
|
||||
MAPLE_LONGBOW(62, 58.3, 55, 1),
|
||||
MAPLE_STOCK(9448, 32, 54, 1),
|
||||
|
||||
//Yew logs
|
||||
YEW_SHORTBOW(68, 67.5, 65, 1),
|
||||
YEW_LONGBOW(66, 75, 70, 1),
|
||||
YEW_STOCK(9452, 50, 69, 1),
|
||||
|
||||
//Magic logs
|
||||
MAGIC_SHORTBOW(72, 83.3, 80,1),
|
||||
MAGIC_LONGBOW(70, 91.5, 85, 1),
|
||||
|
||||
//Teak
|
||||
TEAK_STOCK(9446, 27, 46,1),
|
||||
|
||||
//Mahogany
|
||||
MAHOGANY_STOCK(9450, 41.0, 61, 1);
|
||||
|
||||
|
||||
int id,level,amount,logId;
|
||||
double experience;
|
||||
FletchingItems(int id, double experience, int level, int amount){
|
||||
this.id = id;
|
||||
this.level = level;
|
||||
this.amount = amount;
|
||||
this.experience = experience;
|
||||
}
|
||||
|
||||
public Item getItem(){
|
||||
return new Item(id);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
package content.global.skill.fletching
|
||||
|
||||
import content.data.Quests
|
||||
import content.global.skill.fletching.items.arrow.ArrowHeadPulse
|
||||
import content.global.skill.fletching.items.arrow.HeadlessArrowPulse
|
||||
import content.global.skill.fletching.items.arrow.HeadlessOgreArrowPulse
|
||||
import content.global.skill.fletching.items.bow.StringPulse
|
||||
import content.global.skill.fletching.items.crossbow.LimbPulse
|
||||
import core.api.*
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.ChildPositionContext
|
||||
import core.net.packet.out.RepositionChild
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Items.BLUE_FEATHER_10089
|
||||
import org.rs09.consts.Items.FEATHER_314
|
||||
import org.rs09.consts.Items.ORANGE_FEATHER_10091
|
||||
import org.rs09.consts.Items.RED_FEATHER_10088
|
||||
import org.rs09.consts.Items.STRIPY_FEATHER_10087
|
||||
import org.rs09.consts.Items.YELLOW_FEATHER_10090
|
||||
import core.game.dialogue.SkillDialogueHandler
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.entity.player.Player
|
||||
|
||||
class FletchingListeners : InteractionListener {
|
||||
|
||||
val LIMBIDs = Fletching.Limb.values().map(Fletching.Limb::limb).toIntArray()
|
||||
val STOCKIDs = Fletching.Limb.values().map(Fletching.Limb::stock).toIntArray()
|
||||
val MITHRIL_BOLT = Items.MITHRIL_BOLTS_9142
|
||||
val MITH_GRAPPLE_TIP = Items.MITH_GRAPPLE_TIP_9416
|
||||
val ROPE = Items.ROPE_954
|
||||
val MITH_GRAPPLE = Items.MITH_GRAPPLE_9418
|
||||
val ROPE_GRAPPLE = Items.MITH_GRAPPLE_9419
|
||||
val ARROW_SHAFT = Items.ARROW_SHAFT_52
|
||||
val OGRE_ARROW_SHAFT = Items.OGRE_ARROW_SHAFT_2864
|
||||
val FLETCHED_SHAFT = Items.HEADLESS_ARROW_53
|
||||
val FLIGHTED_OGRE_ARROW = Items.FLIGHTED_OGRE_ARROW_2865
|
||||
val UNFINISHED_ARROWS = Fletching.ArrowHeads.values().map(Fletching.ArrowHeads::unfinished).toIntArray()
|
||||
val FEATHERS = intArrayOf(FEATHER_314,STRIPY_FEATHER_10087,RED_FEATHER_10088,BLUE_FEATHER_10089,YELLOW_FEATHER_10090,ORANGE_FEATHER_10091)
|
||||
val UNSTRUNG_BOWS = Fletching.String.values().map(Fletching.String::unfinished).toIntArray()
|
||||
val STRINGS = intArrayOf(Items.BOW_STRING_1777,Items.CROSSBOW_STRING_9438)
|
||||
|
||||
override fun defineListeners() {
|
||||
|
||||
onUseWith(IntType.ITEM,STRINGS,*UNSTRUNG_BOWS){ player, string, bow ->
|
||||
val enum = Fletching.stringMap[bow.id] ?: return@onUseWith false
|
||||
|
||||
if (bow.id == Items.UNSTRUNG_COMP_BOW_4825) {
|
||||
// You shouldn't be able to string a bow
|
||||
if (getQuestStage(player, Quests.ZOGRE_FLESH_EATERS) < 8) {
|
||||
player.packetDispatch.sendMessage("You must have started Zogre Flesh Eaters and asked Grish to string this.")
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
if(enum.string != string.id){
|
||||
player.sendMessage("That's not the right kind of string for this.")
|
||||
return@onUseWith true
|
||||
}
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(enum.product)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
player.pulseManager.run(StringPulse(player, string.asItem(), enum, amount))
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return player.inventory.getAmount(string.asItem())
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 215, 10))
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM,ARROW_SHAFT,*FEATHERS){ player, shaft, feather ->
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLETCHED_SHAFT)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
player.pulseManager.run(HeadlessArrowPulse(player, shaft.asItem(), Item(feather.id), amount))
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return player.inventory.getAmount(FLETCHED_SHAFT)
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM,OGRE_ARROW_SHAFT,*FEATHERS){ player, shaft, feather ->
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLIGHTED_OGRE_ARROW)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
player.pulseManager.run(HeadlessOgreArrowPulse(player, shaft.asItem(), Item(feather.id, 4), amount))
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return player.inventory.getAmount(FLIGHTED_OGRE_ARROW)
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM,FLETCHED_SHAFT,*UNFINISHED_ARROWS){ player, shaft, unfinished ->
|
||||
val head = Fletching.arrowHeadMap[unfinished.id] ?: return@onUseWith false
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, head.getFinished()) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
player.pulseManager.run(ArrowHeadPulse(player, shaft.asItem(), head, amount))
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return player.inventory.getAmount(head.getUnfinished())
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM,MITHRIL_BOLT,MITH_GRAPPLE_TIP){ player, bolt, tip ->
|
||||
if(player.skills.getLevel(Skills.FLETCHING) < 59){
|
||||
player.sendMessage("You need a fletching level of 59 to make this.")
|
||||
return@onUseWith true
|
||||
}
|
||||
if(player.inventory.remove(Item(MITHRIL_BOLT,1),tip.asItem())){
|
||||
player.inventory.add(Item(MITH_GRAPPLE))
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM,ROPE,MITH_GRAPPLE){ player, rope, grapple ->
|
||||
if(player.skills.getLevel(Skills.FLETCHING) < 59){
|
||||
player.sendMessage("You need a fletching level of 59 to make this.")
|
||||
return@onUseWith true
|
||||
}
|
||||
if(player.inventory.remove(rope.asItem(),grapple.asItem())){
|
||||
player.inventory.add(Item(ROPE_GRAPPLE))
|
||||
}
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM,LIMBIDs,*STOCKIDs){ player, limb, stock ->
|
||||
val limbEnum = Fletching.limbMap[stock.id] ?: return@onUseWith false
|
||||
if(limbEnum.limb != limb.id){
|
||||
player.sendMessage("That's not the right limb to attach to that stock.")
|
||||
return@onUseWith true
|
||||
}
|
||||
val handler: SkillDialogueHandler = object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(limbEnum.product)){
|
||||
override fun create(amount: Int, index: Int) {
|
||||
player.pulseManager.run(LimbPulse(player, stock.asItem(), limbEnum, amount))
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return player.inventory.getAmount(stock.asItem())
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10))
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
/**
|
||||
* (Long) Kebbit bolts don't need feathers and go 6 at a time so use their own interaction
|
||||
*/
|
||||
fun makeKebbitBolt(player : Player, ingredient : Item) : Boolean{
|
||||
val longBolts = when(ingredient.id){
|
||||
Items.KEBBIT_SPIKE_10105 -> false
|
||||
Items.LONG_KEBBIT_SPIKE_10107 -> true
|
||||
else -> return false
|
||||
}
|
||||
val level = if(longBolts) 42 else 26
|
||||
if (getDynLevel(player, Skills.FLETCHING) < level){
|
||||
sendMessage(player, "You need a fletching level of $level to create ${if (longBolts) "long " else ""}kebbit bolts.")
|
||||
return true
|
||||
}
|
||||
val finalProduct = if(longBolts) Items.LONG_KEBBIT_BOLTS_10159 else Items.KEBBIT_BOLTS_10158
|
||||
val xp = if(longBolts) 47.7 else 28.6 // source https://runescape.wiki/w/Fletching?oldid=1069981#Bolts_2
|
||||
if(removeItem(player, ingredient.id)){
|
||||
addItem(player, finalProduct, 6)
|
||||
player.skills.addExperience(Skills.FLETCHING, xp)
|
||||
animate(player, 885)
|
||||
}
|
||||
return true
|
||||
}
|
||||
onUseWith(IntType.ITEM, Items.CHISEL_1755, Items.KEBBIT_SPIKE_10105) { player, used, with ->
|
||||
return@onUseWith makeKebbitBolt(player, with as Item)
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM, Items.CHISEL_1755, Items.LONG_KEBBIT_SPIKE_10107) { player, used, with ->
|
||||
return@onUseWith makeKebbitBolt(player, with as Item)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
package content.global.skill.fletching;
|
||||
|
||||
import content.global.skill.fletching.items.bolts.BoltPulse;
|
||||
import content.global.skill.fletching.items.darts.DartPulse;
|
||||
import org.rs09.consts.Items;
|
||||
import core.game.dialogue.SkillDialogueHandler;
|
||||
import core.game.dialogue.SkillDialogueHandler.SkillDialogue;
|
||||
import core.game.interaction.NodeUsageEvent;
|
||||
import core.game.interaction.UseWithHandler;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.ChildPositionContext;
|
||||
import core.net.packet.out.RepositionChild;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to open the fletching dialogue.
|
||||
* @author Ceikry
|
||||
*/
|
||||
@Initializable
|
||||
public class FletchingPlugin extends UseWithHandler {
|
||||
|
||||
public FletchingPlugin() {
|
||||
super(819,820,821,822,823,824,11232,9375,9376,9377,9382,9378,9379,9380,9381,13279,1511,1521,1519,1517,1515,1513,2862,6332,6333, Items.MAHOGANY_LOGS_6332);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
// Knife
|
||||
addHandler(946, ITEM_TYPE, this);
|
||||
|
||||
// Feathers plus colored feathers
|
||||
addHandler(314, ITEM_TYPE,this);
|
||||
addHandler(10087, ITEM_TYPE, this);
|
||||
addHandler(10088, ITEM_TYPE, this);
|
||||
addHandler(10089, ITEM_TYPE, this);
|
||||
addHandler(10090, ITEM_TYPE, this);
|
||||
addHandler(10091, ITEM_TYPE, this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(final NodeUsageEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
//handle darts
|
||||
if(Fletching.isDart(event.getUsedItem().getId())){
|
||||
final Fletching.Darts dart = Fletching.dartMap.get(event.getUsedItem().getId());
|
||||
SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, dart.getFinished()) {
|
||||
@Override
|
||||
public void create(final int amount, int index) {
|
||||
player.getPulseManager().run(new DartPulse(player, event.getUsedItem(), dart, amount));
|
||||
}
|
||||
@Override
|
||||
public int getAll(int index) {
|
||||
return player.getInventory().getAmount(event.getUsedItem());
|
||||
}
|
||||
};
|
||||
handler.open();
|
||||
return true;
|
||||
}
|
||||
|
||||
//handle bolts
|
||||
if(Fletching.isBolt(event.getUsedItem().getId()) || Fletching.isBolt(event.getUsedWith().getId())){
|
||||
// figure out which of the used items is a bolt, and which is potentially a feather
|
||||
final Fletching.Bolts bolt
|
||||
= Fletching.isBolt(event.getUsedItem().getId())
|
||||
? Fletching.boltMap.get(event.getUsedItem().getId())
|
||||
: Fletching.boltMap.get(event.getUsedWith().getId());
|
||||
final int featherId
|
||||
= Fletching.isBolt(event.getUsedItem().getId())
|
||||
? event.getUsedWith().getId()
|
||||
: event.getUsedItem().getId();
|
||||
final boolean hasFeather = (featherId == 314 || (featherId >= 10087 && featherId <= 10091));
|
||||
|
||||
if (hasFeather) {
|
||||
SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, bolt.getFinished()) {
|
||||
@Override
|
||||
public void create(final int amount, int index) {
|
||||
player.getPulseManager().run(new BoltPulse(player, event.getUsedItem(), bolt, new Item(featherId), amount));
|
||||
}
|
||||
@Override
|
||||
public int getAll(int index) {
|
||||
return player.getInventory().getAmount(event.getUsedItem());
|
||||
}
|
||||
};
|
||||
handler.open();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//handle logs
|
||||
if(Fletching.isLog(event.getUsedItem().getId()) && event.getUsedWith().getId() == 946) {
|
||||
final Item log = event.getUsedItem();
|
||||
Item[] items = Fletching.getItems(log.getId());
|
||||
SkillDialogue dialLength = SkillDialogue.ONE_OPTION;
|
||||
switch (items.length) {
|
||||
case 2:
|
||||
dialLength = SkillDialogue.TWO_OPTION;
|
||||
break;
|
||||
case 3:
|
||||
dialLength = SkillDialogue.THREE_OPTION;
|
||||
break;
|
||||
case 4:
|
||||
dialLength = SkillDialogue.FOUR_OPTION;
|
||||
break;
|
||||
}
|
||||
SkillDialogueHandler handler = new SkillDialogueHandler(player, dialLength, items) {
|
||||
|
||||
@Override
|
||||
public void create(final int amount, int index) {
|
||||
final Fletching.FletchingItems item = Fletching.getEntries(log.getId())[index];
|
||||
player.getPulseManager().run(new FletchingPulse(player, log, amount, item));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAll(int index) {
|
||||
return player.getInventory().getAmount(log);
|
||||
}
|
||||
|
||||
};
|
||||
handler.open();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
package content.global.skill.fletching;
|
||||
|
||||
import core.tools.RandomFunction;
|
||||
import core.game.node.entity.player.link.diary.DiaryType;
|
||||
import core.game.world.map.zone.ZoneBorders;
|
||||
import core.game.node.entity.skill.SkillPulse;
|
||||
import core.game.node.entity.skill.Skills;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.game.world.update.flag.context.Animation;
|
||||
import core.tools.StringUtils;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* fletching skill pulse
|
||||
* @author ceik
|
||||
*/
|
||||
public final class FletchingPulse extends SkillPulse<Item> {
|
||||
|
||||
/**
|
||||
* Seers bank zone borders for the diary task
|
||||
*/
|
||||
private static final ZoneBorders bankZone = new ZoneBorders(2721,3493,2730,3487);
|
||||
|
||||
/**
|
||||
* Represents the animation used in this generic pulse.
|
||||
*/
|
||||
private static final Animation ANIMATION = new Animation(1248);
|
||||
|
||||
/**
|
||||
* Represents the item we are fletching.
|
||||
*/
|
||||
private Fletching.FletchingItems fletch;
|
||||
|
||||
/**
|
||||
* Represents the amount to fletch.
|
||||
*/
|
||||
private int amount = 0;
|
||||
|
||||
/**
|
||||
* Represents the amount to arrows fletched (for ogre arrow shafts which is a random number from 2-6).
|
||||
*/
|
||||
private int finalAmount = 0;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FletchingPulse.java} {@code Object}.
|
||||
* @param player
|
||||
* @param node
|
||||
*/
|
||||
public FletchingPulse(final Player player, final Item node, final int amount, final Fletching.FletchingItems fletch) {
|
||||
super(player, node);
|
||||
this.amount = amount;
|
||||
this.fletch = fletch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkRequirements() {
|
||||
if (player.getSkills().getLevel(Skills.FLETCHING) < fletch.level) {
|
||||
player.getDialogueInterpreter().sendDialogue("You need a Fletching skill of " + fletch.level + " or above to make " + (StringUtils.isPlusN(fletch.getItem().getName().replace("(u)", "").trim()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim());
|
||||
return false;
|
||||
}
|
||||
if (amount > player.getInventory().getAmount(node)) {
|
||||
amount = player.getInventory().getAmount(node);
|
||||
}
|
||||
if (fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT) {
|
||||
if (player.getQuestRepository().getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING).getStage(player) == 0) {
|
||||
player.getPacketDispatch().sendMessage("You must have started Big Chompy Bird Hunting to make those.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (fletch == Fletching.FletchingItems.OGRE_COMP_BOW) {
|
||||
// Technically, this isn't supposed to show up till you've asked Grish.
|
||||
if (player.getQuestRepository().getQuest(Quests.ZOGRE_FLESH_EATERS).getStage(player) < 8) {
|
||||
player.getPacketDispatch().sendMessage("You must have started Zogre Flesh Eaters and asked Grish to make this.");
|
||||
return false;
|
||||
}
|
||||
if (!player.getInventory().contains(2859, 1)) {
|
||||
player.getPacketDispatch().sendMessage("You need to have Wolf Bones in order to make this.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void animate() {
|
||||
player.animate(ANIMATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reward() {
|
||||
if(bankZone.insideBorder(player) && fletch == Fletching.FletchingItems.MAGIC_SHORTBOW) {
|
||||
player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2);
|
||||
}
|
||||
if (getDelay() == 1) {
|
||||
super.setDelay(4);
|
||||
return false;
|
||||
}
|
||||
if (player.getInventory().remove(node)) {
|
||||
final Item item = new Item(fletch.id,fletch.amount);
|
||||
if ( fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT ) {
|
||||
// The amount of shafts given is random; between two and six will be made.
|
||||
finalAmount = RandomFunction.random(2,6);
|
||||
item.setAmount(finalAmount);
|
||||
}
|
||||
if ( fletch == Fletching.FletchingItems.OGRE_COMP_BOW ) {
|
||||
if (!player.getInventory().contains(2859, 1)) {
|
||||
return false;
|
||||
} else {
|
||||
player.getInventory().remove(new Item(2859));
|
||||
}
|
||||
}
|
||||
player.getInventory().add(item);
|
||||
player.getSkills().addExperience(Skills.FLETCHING, fletch.experience, true);
|
||||
String message = getMessage();
|
||||
player.getPacketDispatch().sendMessage(message);
|
||||
|
||||
if (fletch.id == Fletching.FletchingItems.MAGIC_SHORTBOW.id
|
||||
&& (new ZoneBorders(2721, 3489, 2724, 3493, 0).insideBorder(player)
|
||||
|| new ZoneBorders(2727, 3487, 2730, 3490, 0).insideBorder(player))
|
||||
&& !player.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 2)) {
|
||||
player.setAttribute("/save:diary:seers:fletch-magic-short-bow", true);
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
amount--;
|
||||
return amount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to get the message of the fletch.
|
||||
* @return the message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
switch (fletch) {
|
||||
case ARROW_SHAFT:
|
||||
return "You carefully cut the wood into 15 arrow shafts.";
|
||||
case OGRE_ARROW_SHAFT:
|
||||
return "You carefully cut the wood into " + finalAmount + " arrow shafts.";
|
||||
default:
|
||||
return "You carefully cut the wood into " + (StringUtils.isPlusN(fletch.getItem().getName()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim() + ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
package content.global.skill.fletching
|
||||
|
||||
import content.global.skill.fletching.Fletching.GemBolts
|
||||
import content.global.skill.fletching.items.gem.GemBoltCutPulse
|
||||
import content.global.skill.fletching.items.gem.GemBoltPulse
|
||||
import core.api.amountInInventory
|
||||
import core.game.dialogue.SkillDialogueHandler
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.item.Item
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.ChildPositionContext
|
||||
import core.net.packet.out.RepositionChild
|
||||
import org.rs09.consts.Items
|
||||
import kotlin.math.min
|
||||
|
||||
class GemBoltListener : InteractionListener {
|
||||
val gems = intArrayOf(
|
||||
Items.OYSTER_PEARL_411,
|
||||
Items.OYSTER_PEARLS_413,
|
||||
Items.OPAL_1609,
|
||||
Items.JADE_1611,
|
||||
Items.RED_TOPAZ_1613,
|
||||
Items.SAPPHIRE_1607,
|
||||
Items.EMERALD_1605,
|
||||
Items.RUBY_1603,
|
||||
Items.DIAMOND_1601,
|
||||
Items.DRAGONSTONE_1615,
|
||||
Items.ONYX_6573
|
||||
)
|
||||
val boltBases = GemBolts.values().map { it.base }.toIntArray()
|
||||
val boltTips = GemBolts.values().map { it.tip }.toIntArray()
|
||||
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.ITEM, Items.CHISEL_1755, *gems) { player, used, with ->
|
||||
val gem = Fletching.gemMap[with.id] ?: return@onUseWith true
|
||||
|
||||
object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(gem.gem)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
player.pulseManager.run(GemBoltCutPulse(player, used as? Item, gem, amount))
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return player.inventory.getAmount(gem.gem)
|
||||
}
|
||||
}.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM, boltBases, *boltTips) {player, used, with ->
|
||||
val bolt = Fletching.tipMap[with.id] ?: return@onUseWith true
|
||||
if (used.id != bolt.base || with.id != bolt.tip) return@onUseWith true
|
||||
|
||||
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(bolt.product)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
player.pulseManager.run(GemBoltPulse(player, used as? Item, bolt, amount))
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return min(amountInInventory(player, used.id), amountInInventory(player, with.id))
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Server/src/main/content/global/skill/fletching/Zones.kt
Normal file
21
Server/src/main/content/global/skill/fletching/Zones.kt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package content.global.skill.fletching
|
||||
|
||||
import core.game.node.Node
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
|
||||
object Zones {
|
||||
val seersMagicShortbowAchievementZones = arrayOf(
|
||||
ZoneBorders(2721, 3489, 2724, 3493, 0),
|
||||
ZoneBorders(2727, 3487, 2730, 3490, 0),
|
||||
ZoneBorders(2721, 3493, 2730, 3487)
|
||||
)
|
||||
|
||||
fun inAnyZone(node: Node, zones: Array<ZoneBorders>): Boolean {
|
||||
for (zone in zones) {
|
||||
if (zone.insideBorder(node)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package content.global.skill.fletching.arrow
|
||||
|
||||
import org.rs09.consts.Items
|
||||
|
||||
enum class ArrowCraftInfo(val tipItemId: Int, val arrowItemId: Int, val level: Int, val experience: Double) {
|
||||
BRONZE_ARROW(Items.BRONZE_ARROWTIPS_39, Items.BRONZE_ARROW_882, 1, 1.3),
|
||||
IRON_ARROW(Items.IRON_ARROWTIPS_40, Items.IRON_ARROW_884, 15, 2.5),
|
||||
STEEL_ARROW(Items.STEEL_ARROWTIPS_41, Items.STEEL_ARROW_886, 30, 5.0),
|
||||
MITHRIL_ARROW(Items.MITHRIL_ARROWTIPS_42, Items.MITHRIL_ARROW_888, 45, 7.5),
|
||||
ADAMANT_ARROW(Items.ADAMANT_ARROWTIPS_43, Items.ADAMANT_ARROW_890, 60, 10.0),
|
||||
RUNE_ARROW(Items.RUNE_ARROWTIPS_44, Items.RUNE_ARROW_892, 75, 12.5),
|
||||
DRAGON_ARROW(Items.DRAGON_ARROWTIPS_11237,Items.DRAGON_ARROW_11212, 90, 15.0),
|
||||
BROAD_ARROW(Items.BROAD_ARROW_HEADS_13278, Items.BROAD_ARROW_4160, 52, 15.0);
|
||||
|
||||
companion object {
|
||||
private val arrowCraftInfoByTipId = values().associateBy { it.tipItemId }
|
||||
|
||||
val arrowTipIds: IntArray = values().map { arrowCraftInfo: ArrowCraftInfo -> arrowCraftInfo.tipItemId }.toIntArray()
|
||||
|
||||
fun fromTipId(tipId: Int) : ArrowCraftInfo? {
|
||||
return arrowCraftInfoByTipId[tipId]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package content.global.skill.fletching.arrow
|
||||
|
||||
import content.global.skill.fletching.Feathers
|
||||
import core.api.*
|
||||
import core.game.dialogue.SkillDialogueHandler
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
|
||||
@Suppress("unused") // Reflectively loaded
|
||||
class ArrowListeners : InteractionListener {
|
||||
private val arrowShaft = Items.ARROW_SHAFT_52
|
||||
val headlessArrow = Items.HEADLESS_ARROW_53
|
||||
|
||||
companion object {
|
||||
const val FLIGHTED_OGRE_ARROW_LEVEL = 5
|
||||
fun sendLevelCheckFailDialog(player: Player, level: Int) {
|
||||
sendDialogue(
|
||||
player,
|
||||
"You need a fletching level of $level to do this."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
onUseWith(IntType.ITEM, arrowShaft, *Feathers.all) { player, shaft, feather ->
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(headlessArrow)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
if (!hasSpaceFor(player, Item(headlessArrow))) {
|
||||
sendDialogue(player, "You do not have enough inventory space.")
|
||||
return
|
||||
}
|
||||
HeadlessArrowCraftScript(player, feather.id, amount).invoke()
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return amountInInventory(player, headlessArrow)
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM, headlessArrow, *ArrowCraftInfo.arrowTipIds) { player, headlessArrow, arrowTip ->
|
||||
val arrowCraftInfo = ArrowCraftInfo.fromTipId(arrowTip.id) ?: return@onUseWith false
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(arrowCraftInfo.arrowItemId)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
if (!playerMeetsInitialRequirements()) return
|
||||
TippedArrowCraftScript(player, arrowCraftInfo, amount).invoke()
|
||||
}
|
||||
|
||||
private fun playerMeetsInitialRequirements(): Boolean {
|
||||
if (arrowCraftInfo == ArrowCraftInfo.BROAD_ARROW && !getSlayerFlags(player).isBroadsUnlocked()) {
|
||||
sendDialogue(player, "You need to unlock the ability to create broad arrows.")
|
||||
return false
|
||||
}
|
||||
|
||||
if (getDynLevel(player, Skills.FLETCHING) < arrowCraftInfo.level) {
|
||||
sendLevelCheckFailDialog(player, arrowCraftInfo.level)
|
||||
return false
|
||||
}
|
||||
|
||||
if (!hasSpaceFor(player, Item(arrowCraftInfo.arrowItemId))) {
|
||||
sendDialogue(player, "You do not have enough inventory space.")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return amountInInventory(player, arrowTip.id)
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
onUseWith(IntType.ITEM, Items.OGRE_ARROW_SHAFT_2864, *Feathers.all) { player, ogreArrowShaft, feather ->
|
||||
val handler: SkillDialogueHandler =
|
||||
object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(Items.FLIGHTED_OGRE_ARROW_2865)) {
|
||||
override fun create(amount: Int, index: Int) {
|
||||
if (!playerMeetsInitialRequirements()) return
|
||||
FlightedOgreArrowCraftScript(player, feather.id, amount).invoke()
|
||||
}
|
||||
|
||||
private fun playerMeetsInitialRequirements(): Boolean {
|
||||
if (getDynLevel(player, Skills.FLETCHING) < FLIGHTED_OGRE_ARROW_LEVEL) {
|
||||
sendLevelCheckFailDialog(player, FLIGHTED_OGRE_ARROW_LEVEL)
|
||||
return false
|
||||
}
|
||||
|
||||
if (!hasSpaceFor(player, Item(Items.FLIGHTED_OGRE_ARROW_2865))) {
|
||||
sendDialogue(player, "You do not have enough inventory space.")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getAll(index: Int): Int {
|
||||
return amountInInventory(player, Items.OGRE_ARROW_SHAFT_2864)
|
||||
}
|
||||
}
|
||||
handler.open()
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package content.global.skill.fletching.arrow
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.Clocks
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Defines the queueScript for creating a flighted ogre arrow
|
||||
* @author 'Vexia
|
||||
* @param player the player.
|
||||
* @param idOfFeatherUsed the feather to attach to the shaft.
|
||||
* @param sets the amount of sets to complete.
|
||||
*/
|
||||
class FlightedOgreArrowCraftScript(
|
||||
private val player: Player,
|
||||
private val idOfFeatherUsed: Int,
|
||||
private val sets: Int
|
||||
) {
|
||||
|
||||
private val flightedOgreArrow = Items.FLIGHTED_OGRE_ARROW_2865
|
||||
private val ogreArrowShaft = Items.OGRE_ARROW_SHAFT_2864
|
||||
private val maximumFlightedOgreArrowsCraftableInOneStage = 6
|
||||
|
||||
private val feathersPerArrow = 4
|
||||
|
||||
private val initialDelay = 1
|
||||
private val subsequentDelay = 3
|
||||
|
||||
private fun getAmountToCraftForThisStage(shaftsInInventory: Int, feathersInInventory: Int): Int {
|
||||
val limitOfCraftableArrowsDueToFeathers = feathersInInventory / feathersPerArrow
|
||||
|
||||
val totalCraftableArrows = min(shaftsInInventory, limitOfCraftableArrowsDueToFeathers)
|
||||
return if (totalCraftableArrows > maximumFlightedOgreArrowsCraftableInOneStage) {
|
||||
maximumFlightedOgreArrowsCraftableInOneStage
|
||||
} else {
|
||||
totalCraftableArrows
|
||||
}
|
||||
}
|
||||
|
||||
fun invoke() {
|
||||
queueScript(player, initialDelay) { stage ->
|
||||
if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player)
|
||||
|
||||
if (getDynLevel(player, Skills.FLETCHING) < ArrowListeners.FLIGHTED_OGRE_ARROW_LEVEL) {
|
||||
ArrowListeners.sendLevelCheckFailDialog(player, ArrowListeners.FLIGHTED_OGRE_ARROW_LEVEL)
|
||||
return@queueScript stopExecuting(player) // Check each iteration since dynLevel can change (status effects ending, skill assist session end...)
|
||||
}
|
||||
|
||||
val featherAmount = amountInInventory(player, idOfFeatherUsed)
|
||||
val shaftAmount = amountInInventory(player, ogreArrowShaft)
|
||||
|
||||
val amountToCraft = getAmountToCraftForThisStage(shaftAmount, featherAmount)
|
||||
|
||||
if (
|
||||
removeItemsIfPlayerHasEnough(
|
||||
player,
|
||||
Item(ogreArrowShaft, amountToCraft),
|
||||
Item(idOfFeatherUsed, amountToCraft * feathersPerArrow)
|
||||
)
|
||||
) {
|
||||
when (amountToCraft) {
|
||||
1 -> sendMessage(player, "You attach $feathersPerArrow feathers to a shaft.")
|
||||
else -> {
|
||||
sendMessage(
|
||||
player,
|
||||
"You attach ${amountToCraft * feathersPerArrow} feathers to $amountToCraft arrow shafts."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
rewardXP(player, Skills.FLETCHING, amountToCraft.toDouble())
|
||||
addItem(player, flightedOgreArrow, amountToCraft)
|
||||
} else {
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
if (stage >= sets - 1) {
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
package content.global.skill.fletching.arrow
|
||||
|
||||
import core.api.*
|
||||
import core.game.interaction.Clocks
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import org.rs09.consts.Items
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Defines the queueScript for creating a headless arrow
|
||||
* @author 'Vexia
|
||||
* @param player the player.
|
||||
* @param idOfFeatherUsed the feather to attach to the shaft.
|
||||
* @param sets the amount of sets to complete.
|
||||
*/
|
||||
class HeadlessArrowCraftScript(
|
||||
private val player: Player,
|
||||
private val idOfFeatherUsed: Int,
|
||||
private val sets: Int
|
||||
) {
|
||||
|
||||
private val headlessArrow = Items.HEADLESS_ARROW_53
|
||||
private val arrowShaft = Items.ARROW_SHAFT_52
|
||||
private val maximumHeadlessArrowsCraftableInOneStage = 15
|
||||
|
||||
private val initialDelay = 1
|
||||
private val subsequentDelay = 3
|
||||
|
||||
private fun getAmountToCraftForThisStage(shaftsInInventory: Int, feathersInInventory: Int): Int {
|
||||
val smallerItemAmount = min(shaftsInInventory, feathersInInventory)
|
||||
return if (smallerItemAmount > maximumHeadlessArrowsCraftableInOneStage) {
|
||||
maximumHeadlessArrowsCraftableInOneStage
|
||||
} else {
|
||||
smallerItemAmount
|
||||
}
|
||||
}
|
||||
|
||||
fun invoke() {
|
||||
queueScript(player, initialDelay) { stage ->
|
||||
if (!clockReady(player, Clocks.SKILLING)) return@queueScript keepRunning(player)
|
||||
|
||||
val featherAmount = amountInInventory(player, idOfFeatherUsed)
|
||||
val shaftAmount = amountInInventory(player, arrowShaft)
|
||||
|
||||
val amountToCraft = getAmountToCraftForThisStage(shaftAmount, featherAmount)
|
||||
|
||||
if (
|
||||
removeItemsIfPlayerHasEnough(
|
||||
player,
|
||||
Item(arrowShaft, amountToCraft),
|
||||
Item(idOfFeatherUsed, amountToCraft)
|
||||
)
|
||||
) {
|
||||
when (amountToCraft) {
|
||||
1 -> sendMessage(player, "You attach a feather to a shaft.")
|
||||
else -> {
|
||||
sendMessage(player, "You attach feathers to $amountToCraft arrow shafts.")
|
||||
}
|
||||
}
|
||||
|
||||
rewardXP(player, Skills.FLETCHING, amountToCraft.toDouble())
|
||||
addItem(player, headlessArrow, amountToCraft)
|
||||
} else {
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
if (stage >= sets - 1) {
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
return@queueScript delayClock(player, Clocks.SKILLING, subsequentDelay, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
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