forked from 2009Scape/Server
Compare commits
366 commits
May-31-202
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cdf7767eb | |||
| e9085a8270 | |||
| bfa62864fa | |||
| b372d5e963 | |||
| 590e9fe44f | |||
| 59c55708a6 | |||
| 5a896cecb4 | |||
| e046f46ed2 | |||
| 2ecdde1011 | |||
| cd8cce30a0 | |||
| 06055c0ff8 | |||
| 6e91725d58 | |||
| a9065d763b | |||
| 2ad90e9ed8 | |||
| cecdb97b19 | |||
| 52185005aa | |||
| 7e8c2d8883 | |||
| af446a4c27 | |||
| 67990205b4 | |||
| fa429edc03 | |||
| 3f0c44b1c3 | |||
| b3196a282c | |||
| 4053fdf43c | |||
| 415aa512fb | |||
| 54055e36d0 | |||
| 269eb82850 | |||
| 4d7f26bb47 | |||
| 7538322006 | |||
| 08ffa6fee6 | |||
|
|
bfbfae8391 | ||
| 45ee87e64e | |||
|
|
bcc3bc069e | ||
|
|
48bc0ffb28 | ||
|
|
7b1ebd4608 | ||
|
|
1b0a7d5fca | ||
|
|
fc2247f457 | ||
|
|
47ac5e93d6 | ||
|
|
63f8ec3cbf | ||
|
|
0622aed00c | ||
| 4799069ebd | |||
| 4991b07ff8 | |||
| 7be39c73b9 | |||
| a5eb1ea929 | |||
| d02b16d970 | |||
| 07d8bb6a13 | |||
| 61f5120cfc | |||
| fb0dd3a27d | |||
| 81730af934 | |||
| 6458a6ef95 | |||
| b109b98247 | |||
| daf312ce6b | |||
|
|
dda80d535b | ||
| 9c8c2ada70 | |||
| 18d30a3e1e | |||
| 9926b5c244 | |||
| 40d5478b57 | |||
|
|
5eddd5e98a | ||
| fe117e6976 | |||
| c59e13f0aa | |||
| e88bdf94d3 | |||
| a411c7a5e2 | |||
| 16da0ed93e | |||
| 249c501184 | |||
|
|
448f970c10 | ||
|
|
83b8689b86 | ||
|
|
7592372dc4 | ||
|
|
9b8ba3b6dd | ||
| 680a08ea98 | |||
|
|
6362eee753 | ||
|
|
f0ee476e42 | ||
|
|
0e65f20223 | ||
|
|
af58fae1fc | ||
|
|
74ed5e1bee | ||
|
|
cf08e700fb | ||
|
|
d65a53b275 | ||
|
|
fb9d6307b3 | ||
|
|
45fb89ec73 | ||
|
|
50ba3682b5 | ||
|
|
df73f4a171 | ||
|
|
9eedfc2336 | ||
|
|
e25780a4c5 | ||
|
|
b6560c0e3f | ||
|
|
2d1a626df0 | ||
|
|
4f97dbef8c | ||
|
|
be76ca143b | ||
|
|
053254b504 | ||
|
|
486ca4bb19 | ||
|
|
104533c11d | ||
|
|
9886049429 | ||
|
|
f1131b7d00 | ||
|
|
be47c1d5c9 | ||
|
|
bb860b60e0 | ||
|
|
fed309a70b | ||
|
|
1afd4d5328 | ||
|
|
a6eb706358 | ||
|
|
957477b9b0 | ||
|
|
4387b346dc | ||
|
|
618d39d73c | ||
|
|
62a7dd4324 | ||
|
|
212ce57580 | ||
| 84951244f9 | |||
|
|
389c5858d0 | ||
|
|
5540febf6e | ||
|
|
8a4ea5d1f3 | ||
|
|
0f14639e9b | ||
|
|
e63c6f523a | ||
|
|
612ccc6776 | ||
|
|
b5784c5782 | ||
|
|
867c332466 | ||
|
|
8b1763c3ba | ||
|
|
d0fdf08d13 | ||
| 8e822234fb | |||
| 718d7e39e1 | |||
|
|
d91f77c294 | ||
| 7b5ac708dc | |||
| dd35e479c1 | |||
|
|
c03947e0b0 | ||
|
|
acc6c182a5 | ||
|
|
1b85808885 | ||
|
|
2cf8392691 | ||
|
|
4a016d45e5 | ||
|
|
cd43f8d269 | ||
|
|
0a26d5039a | ||
|
|
c3929cf06c | ||
|
|
fcbea5acdc | ||
|
|
3d7e93b6c2 | ||
|
|
6e9f3cb8b9 | ||
|
|
0c8efbac7a | ||
|
|
ccc60b1240 | ||
|
|
818ffc01e7 | ||
|
|
f37b30749e | ||
|
|
edc6f9cf07 | ||
|
|
064edfbbe4 | ||
|
|
b62f4e9525 | ||
|
|
57f5617fe8 | ||
|
|
6c386e6ed2 | ||
|
|
93890769e1 | ||
|
|
4039c0123b | ||
|
|
27f2d457ea | ||
|
|
c6b508b3ed | ||
|
|
67b6855370 | ||
|
|
4480618748 | ||
|
|
9fff4dbb5d | ||
|
|
6a68cf9d7c | ||
|
|
e34a81ec6c | ||
|
|
00b5a44c31 | ||
|
|
f75577d41d | ||
|
|
3838f01adf | ||
|
|
a932c309b3 | ||
|
|
9af776e3c6 | ||
|
|
39634b6caf | ||
|
|
eb3884180e | ||
|
|
d5c7d74767 | ||
|
|
d08656021c | ||
|
|
9beb7219ea | ||
|
|
deecf136bc | ||
|
|
b849de2dab | ||
|
|
b4950343ec | ||
| 6cf3e97985 | |||
| 579df71848 | |||
| bd8669f629 | |||
| 97053798ff | |||
| b1ca068e3f | |||
| 05c1ac1dc0 | |||
| b381d78362 | |||
| ed9a6fa118 | |||
| ecb3a66d58 | |||
| ffe1e11d11 | |||
| ff80ec3b51 | |||
| be7143be20 | |||
| a788b64e44 | |||
| 6cc6a4c69c | |||
| 30113613e0 | |||
| 40196333ad | |||
| f3c9dd2d9c | |||
| f258632fb5 | |||
|
|
7749e8263f | ||
| e19c89f441 | |||
| 3119a01e3f | |||
| fba2e413cf | |||
| 456925264b | |||
| 6ed0ead8a7 | |||
| 6cca2d1bed | |||
| 440f8ce3ac | |||
| ee11daa0be | |||
| b33ad22740 | |||
| 3f8828457b | |||
| 793acecf2e | |||
| eebcb25274 | |||
| 9ed560cca6 | |||
| a86b734e0d | |||
| 5319cabdae | |||
| ee6f83eb7e | |||
| 63c7fc3f70 | |||
| 8f55baa13e | |||
| 6845a3740f | |||
| 02a36f7bf7 | |||
|
|
79c69e3d43 | ||
|
|
7d79c9a82a | ||
|
|
e216a6366f | ||
|
|
9054e36288 | ||
|
|
1a67932351 | ||
|
|
7a6adda997 | ||
|
|
1da53c448d | ||
|
|
53dc169774 | ||
|
|
b0be48501b | ||
|
|
98c99e7550 | ||
|
|
ed41f3a228 | ||
|
|
a2eafa8bc0 | ||
|
|
2be5f9eac0 | ||
| 251934d3a9 | |||
| 964c95b572 | |||
| e7ed5b0d7a | |||
| a6ad4f8f3b | |||
| 0b05424690 | |||
| e45f8fa81b | |||
| 3035aaa7e6 | |||
| 9143cd5f47 | |||
| d92a3f3a8e | |||
| 65cb778a18 | |||
| 563fcc23bc | |||
| 2e68ac1522 | |||
| 62463576cf | |||
| ac14e7a22e | |||
| f2aad1c957 | |||
| ee3a71a5d0 | |||
|
|
a361915281 | ||
| e5e6006212 | |||
| fa808accd4 | |||
| df3fc6c973 | |||
| da071b795d | |||
| 48069e2234 | |||
| 2e65f0d186 | |||
| 7da14bd3b8 | |||
| de4f67832b | |||
| d21452a8bf | |||
| e8afa4e529 | |||
| 98e8cd4592 | |||
| 974c44a041 | |||
| 325b8f6f20 | |||
| 13e4a0b640 | |||
| f4c51dbafe | |||
| 81779f1fae | |||
| 7113ef393d | |||
| 3fd5f60d7f | |||
| acfd5c90b9 | |||
| 6195af3e7b | |||
| 4eebee34c4 | |||
| 8a72ac52db | |||
| 7779d03654 | |||
| 1f538d2976 | |||
| 4b5687b8ab | |||
| d4da75e6ab | |||
| 8094465579 | |||
| 6305e2a718 | |||
| bbaa4bbdbe | |||
| 4cd703097c | |||
| 1ef61d8c33 | |||
| 54d755b12d | |||
| 010cd58460 | |||
| 9295c91a7d | |||
| 86913bf75f | |||
| 90c80fbd8e | |||
| 4912b39831 | |||
| 17ac2ab4da | |||
| 845a00079b | |||
| 82681e8303 | |||
| d74d83b2ec | |||
| 2abf540515 | |||
| 78847c2415 | |||
| 540db8e15a | |||
| 020c10d961 | |||
| 0f00221cd9 | |||
| bbf8f3c348 | |||
| 0fddd2134b | |||
| b35159b5b7 | |||
| 490c6d42ec | |||
| bc5958b60d | |||
| cc6f33ab7e | |||
| 62dc8bc324 | |||
| ea980fe909 | |||
| ab78bce769 | |||
| af47ae42c1 | |||
| 661aa22e41 | |||
|
|
876b87b72a | ||
|
|
32cd17bfa2 | ||
|
|
393752d77b | ||
|
|
2b460b64f2 | ||
|
|
59075798ea | ||
|
|
034c05f512 | ||
|
|
01b5e59250 | ||
|
|
7d32e77860 | ||
|
|
f11149ebe2 | ||
|
|
ba1e190cdb | ||
|
|
1c9fbc79aa | ||
|
|
218a040f8b | ||
|
|
cc8dd4edb4 | ||
|
|
3982258500 | ||
|
|
2be422e7da | ||
|
|
5abe50430d | ||
|
|
97b8ed19a6 | ||
|
|
9d38357c4e | ||
|
|
64fa1d89c3 | ||
|
|
e31397b42f | ||
|
|
9f61ffb153 | ||
|
|
b2f7f86d6a | ||
|
|
4799176c14 | ||
|
|
0a89439c80 | ||
|
|
9c202aa47a | ||
|
|
6b0f942598 | ||
|
|
8db9060a40 | ||
|
|
f94221918f | ||
|
|
cc47f4b488 | ||
|
|
5c027e2649 | ||
|
|
4156f28b93 | ||
|
|
c271d4e74b | ||
|
|
97464ef1d2 | ||
|
|
518b5d91dd | ||
|
|
e25c7d7824 | ||
|
|
29fa9a5a21 | ||
|
|
083df1aae2 | ||
|
|
3a73c98e19 | ||
|
|
80cb2d9ba4 | ||
|
|
317b4e9b5c | ||
|
|
24143f5d20 | ||
|
|
209e1ae8cf | ||
|
|
37836ae992 | ||
|
|
d15b47fc65 | ||
|
|
58d9101ef6 | ||
|
|
ca8bfeab64 | ||
|
|
957b1c2944 | ||
|
|
92fcd0ec32 | ||
|
|
db3079271e | ||
|
|
9d6ad223cb | ||
|
|
3837bd3c26 | ||
|
|
18d5d80fba | ||
|
|
9d2e173f71 | ||
|
|
68c1e572b9 | ||
|
|
806680517b | ||
|
|
53357d20f3 | ||
|
|
a44472e559 | ||
|
|
6b152bcc8c | ||
|
|
30f1cbf710 | ||
|
|
0165d373bd | ||
|
|
6f9a975f7a | ||
|
|
21a07841f6 | ||
|
|
81495ab8a8 | ||
|
|
5ed3cafc4a | ||
|
|
0b95cfdb8f | ||
|
|
e8527ff506 | ||
|
|
ef90d24bdc | ||
|
|
a2b0548c62 | ||
|
|
611660cbc3 | ||
|
|
370d9ef423 | ||
|
|
8d2b454b1c | ||
|
|
28b168e742 | ||
|
|
98c0698097 | ||
|
|
80a5c3a85e | ||
|
|
ca3bc9cd70 | ||
|
|
2c3b5cb5a4 | ||
|
|
5f62047aff | ||
|
|
d0f24afc2e | ||
|
|
1f6b0e900f | ||
|
|
ddb9b6f0b0 | ||
|
|
45c21767d5 | ||
|
|
f01a5cfe40 |
1194 changed files with 90001 additions and 21693 deletions
|
|
@ -149,4 +149,4 @@ These credits can be spent in the 2009Scape Reward Shop. It's important to be cl
|
|||
|
||||
Testers are not the only people who can gain credits - other ways of earning credits can be found on [the 2009Scape website](https://2009scape.org/site/game_guide/credits.html).
|
||||
|
||||
Please be patient! The Credit system is not fully complete yet, so it will take a long time for credits to be awarded.
|
||||
Please be patient! The Credit system is not fully complete yet, so it will take a long time for credits to be awarded.
|
||||
1
Server/.gitignore
vendored
1
Server/.gitignore
vendored
|
|
@ -2,6 +2,7 @@ bin/**
|
|||
out/**
|
||||
data/logs/**
|
||||
data/profile/**
|
||||
data/playerstats/**
|
||||
.idea/**
|
||||
/bin
|
||||
.DS_Store**
|
||||
|
|
|
|||
|
|
@ -25,4 +25,7 @@
|
|||
<ObjectAction mode="add" id="21301" x="2662" y="3162" z="0" direction="e"/>
|
||||
<ObjectAction mode="add" id="4176" x="2629" y="3661" z="2" type="4" direction="e"/>
|
||||
|
||||
<ObjectAction mode="add" id="2489" x="2839" y="3282" z="0" direction="w"/>
|
||||
<ObjectAction mode="add" id="36695" x="2894" y="3510" z="0" direction="w"/>
|
||||
|
||||
</parsing>
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@
|
|||
"What do you think @name?",
|
||||
"How does that sound @name?",
|
||||
"That sounds great @name.",
|
||||
"I’m learning English.",
|
||||
"I'm learning English.",
|
||||
"I don't understand.",
|
||||
"Could you repeat that please @name?",
|
||||
"Could you please talk slower @name?",
|
||||
|
|
@ -301,7 +301,7 @@
|
|||
"Always check announcments",
|
||||
"We thrivin",
|
||||
"Ship @name",
|
||||
"Dont forget to vote 2009Scape!",
|
||||
"Dont forget to vote 2009scape!",
|
||||
"Kermit is too legit 2 quit",
|
||||
"Out here on the range we are having fun",
|
||||
"I am hank steel",
|
||||
|
|
@ -338,7 +338,7 @@
|
|||
"I couldn't agree more @name",
|
||||
"It cost me a fortune @name",
|
||||
"I am dog tired",
|
||||
"Don’t take it personally",
|
||||
"Don't take it personally",
|
||||
"We will be having a good time",
|
||||
"Same as always @name",
|
||||
"No problem",
|
||||
|
|
@ -367,33 +367,16 @@
|
|||
"May Guthix bring you balance.",
|
||||
"May Guthix bring you balance.",
|
||||
"May Guthix bring you balance.",
|
||||
"Thy death was not in vain, for it brought some balance to the world. May Guthix bring you rest.",
|
||||
"May you walk the path, and never fall, for Guthix walks beside thee on thy journey. May Guthix bring you peace.",
|
||||
"All things must end, as all begin; Only Guthix knows the role thou must play. May Guthix bring you balance.",
|
||||
"In life, in death, in joy, in sorrow: May thine experience show thee balance. May Guthix bring you balance.",
|
||||
"Thou must do as thou must, no matter what. Thine actions bring balance to this world. May Guthix bring you balance.",
|
||||
"The river flows, the sun ignites, May you stand with Guthix in thy fights. May Guthix bring you balance.",
|
||||
"A journey of a single step, May take thee over a thousand miles. May Guthix bring you balance.",
|
||||
"Zamorak give me strength!",
|
||||
"Zamorak give me strength!",
|
||||
"Zamorak give me strength!",
|
||||
"May your bloodthirst never be sated, and may all your battles be glorious. Zamorak bring you strength.",
|
||||
"There is no opinion that cannot be proven true...by crushing those who choose to disagree with it. Zamorak give me strength!",
|
||||
"Battles are not lost and won; They simply remove the weak from the equation. Zamorak give me strength!",
|
||||
"Those who fight, then run away, shame Zamorak with their cowardice. Zamorak give me strength!",
|
||||
"Battle is by those who choose to disagree with it. Zamorak give me strength!",
|
||||
"Strike fast, strike hard, strike true: The strength of Zamorak will be with you. Zamorak give me strength!",
|
||||
"The weak deserve to die, so the strong may flourish. This is the creed of Zamorak.",
|
||||
"This is Saradomin's wisdom.",
|
||||
"This is Saradomin's wisdom.",
|
||||
"This is Saradomin's wisdom.",
|
||||
"Go in peace in the name of Saradomin; may his glory shine upon you like the sun.",
|
||||
"Thy cause was false, thy skills did lack; See you in Lumbridge when you get back.",
|
||||
"Protect your self, protect your friends. Mine is the glory that never ends. This is Saradomin's wisdom.",
|
||||
"The darkness in life may be avoided, by the light of wisdom shining. This is Saradomin's wisdom.",
|
||||
"Show love to your friends, and mercy to your enemies, and know that the wisdom of Saradomin will follow. This is Saradomin's wisdom.",
|
||||
"A fight begun, when the cause is just, will prevail over all others. This is Saradomin's wisdom.",
|
||||
"The currency of goodness is honour; It retains its value through scarcity. This is Saradomin's wisdom.",
|
||||
"For Camelot!",
|
||||
"Firmly grasp it!",
|
||||
"My legs!",
|
||||
|
|
@ -496,21 +479,525 @@
|
|||
"Shlisshalpshlaap",
|
||||
"Somebody call for an exterminator?",
|
||||
"Decisive action. Should work.",
|
||||
"R E A D Y T O R A I S E S O M E H E L L",
|
||||
"Darkness overpowering.",
|
||||
"Got any questions about propane? Or propane accessories?",
|
||||
"When someone asks me if I am a god, I say Y E S!!!",
|
||||
"You run out of Marines?",
|
||||
"Goliath Online",
|
||||
"I'm escaping to the one place that hasn't been corrupted by Capitalism. Lunar Isle!",
|
||||
"Selling wildy protection, 100k gp",
|
||||
"Can’t we get you on Mastermind, @name? Next contestant – @name from Lumbridge. Special subject – the bleedin’ obvious.",
|
||||
"Oh, you’re German! I’m sorry, I thought there was something wrong with you.",
|
||||
"Listen, don’t mention the war! I mentioned it once, but I think I got away with it all right.",
|
||||
"Can't we get you on Mastermind, @name?",
|
||||
"Listen, don't mention the war! I mentioned it once, but I think I got away with it all right.",
|
||||
"Cunnilingus and psychiatry brought us to this.",
|
||||
"Oh, poor baby. What do you want, a Brimstail's Sampler?",
|
||||
"There's an old TzHarrian saying, you fuck up once, you lose two teeth.",
|
||||
"The lineup consisted simply of six hydrocoptic marzelvanes so fitted to the ambifacient lunar waneshaft that sidefumbling was prevented."
|
||||
"Ah, the Wilderness... where dreams of riches meet a swift demise.",
|
||||
"Who needs a quest guide? I've got the whole wiki memorized.",
|
||||
"Buying GF 10k coins. Must have at least 70 Agility.",
|
||||
"I swear, the goblins in Goblin Village have it out for me.",
|
||||
"Why do wizards always hang out in towers? Is it a zoning thing?",
|
||||
"I'm training my Construction skill. My house is gonna be lit!",
|
||||
"The GE is like the stock market, but with dragon bones.",
|
||||
"Why do we need a cabbage patch in Draynor? Seriously.",
|
||||
"I've been mining rune essence for hours. My pickaxe hates me.",
|
||||
"@name hit 99 Cooking. Time to open a gourmet restaurant in Varrock.",
|
||||
"I'm convinced the @name is actually a time-traveling wizard.",
|
||||
"Anyone up for a Castle Wars match? I need that decorative armor.",
|
||||
"Accidentally clicked Attack on a guard. Now I'm a wanted criminal.",
|
||||
"Why do we even have a Duel Arena? It's just a fancy boxing ring.",
|
||||
"I've got a stack of burnt lobsters. Anyone want to buy them?",
|
||||
"Greetings, @name! Looking for a quest?",
|
||||
"Just got a rare drop! The RNG gods are smiling upon me!",
|
||||
"Anyone need help with a boss fight? I've got my dragon dagger ready.",
|
||||
"Buying feathers! Will pay top price!",
|
||||
"The Lumbridge cows are my favorite training spot.",
|
||||
"Who needs a teleport? I've got my magic runes stocked.",
|
||||
"@name hit 99 Woodcutting. Time to chop some yews!",
|
||||
"Anyone seen the Wise Old Man lately? I owe him a visit.",
|
||||
"Selling lobsters! Freshly caught from Catherby.",
|
||||
"Swear, the Wilderness is scarier than my nightmares.",
|
||||
"Looking for a clan to join. Any takers?",
|
||||
"I'm an ironman, so no trading for me!",
|
||||
"Anyone up for a Castle Wars match?",
|
||||
"The Grand Exchange prices are crashing. Panic sell!",
|
||||
"Who else remembers the Falador Massacre?",
|
||||
"I'm saving up for a party hat. Wish me luck!",
|
||||
"Barrows runs are my addiction. Those crypts are spooky.",
|
||||
"I'm convinced the Wise Old Man is secretly Zamorak.",
|
||||
"I'm a completionist, so I'm grinding out all the achievements.",
|
||||
"The music in this game is surprisingly epic.",
|
||||
"Tried to trade with a tree... It didn't go well.",
|
||||
"My bank is like a black hole. Items disappear forever.",
|
||||
"I'm convinced the Wise Old Man is just a confused tourist.",
|
||||
"My character's fashion sense? Let's just say it's 'unique.'",
|
||||
"Challenged a cow to a dance-off. It won.",
|
||||
"Why does the Lumbridge Guide always look so lost?",
|
||||
"I'm training Agility, but my real-life agility is zero.",
|
||||
"Tried to fish in the desert. Sandfish are elusive.",
|
||||
"The Grand Exchange is like a chaotic stock market.",
|
||||
"I'm a master at clicking 'Continue' during quests.",
|
||||
"I'm convinced the chickens are plotting world domination.",
|
||||
"I'm a woodcutter, but I've never seen a talking tree.",
|
||||
"I'm a vegetarian, except when it comes to killing dragons.",
|
||||
"Why do wizards wear pointy hats? Is it a fashion statement?",
|
||||
"Challenged a guard to a staring contest. He won.",
|
||||
"I'm collecting cabbage. It's a noble pursuit.",
|
||||
"Accidentally set my cat on fire. It's now a firecat.",
|
||||
"I'm convinced the Wise Old Man is secretly a time traveler.",
|
||||
"I'm a quest completionist, but I still can't find my keys.",
|
||||
"I'm convinced the ducks are spying on us.",
|
||||
"I'm a pro at avoiding the Lumbridge swamp. Too many frogs.",
|
||||
"Hey, can someone lend me 10k? I promise I'll pay it back... eventually.",
|
||||
"Why do I always find the one square where the random event spawns?",
|
||||
"I'm training Prayer by burying bones. It's like a spiritual workout.",
|
||||
"The Wise Old Man's fashion sense is questionable.",
|
||||
"I'm convinced the ducks are secretly plotting world domination.",
|
||||
"Why do wizards wear pointy hats? Is it a dress code?",
|
||||
"I'm collecting cabbage. It's a noble pursuit, really.",
|
||||
"I'm a vegetarian, except when it comes to killing dragons.",
|
||||
"Why does the Lumbridge Guide always look so lost?",
|
||||
"Training Agility, but my real-life agility is zero.",
|
||||
"I'm convinced the Wise Old Man is secretly a time traveler.",
|
||||
"Tried to mine air. It's an untapped resource.",
|
||||
"I'm a quest completionist, but I still can't find my keys.",
|
||||
"Challenged a guard to a staring contest. He won.",
|
||||
"I'm saving up for a party hat. Priorities, you know?",
|
||||
"Why do goblins drop coins? Do they moonlight as accountants?",
|
||||
"I'm convinced the chickens are plotting something.",
|
||||
"Clicked 'Attack' on a chicken. Now I'm a poultry murderer.",
|
||||
"My character's fashion sense? Let's just say it's 'unique.'",
|
||||
"Do you know where I can find the entrance to the Taverley Dungeon?",
|
||||
"Hey, anyone here familiar with the Barrows? I need some tips.",
|
||||
"Is there a bank nearby? My inventory is overflowing with loot",
|
||||
"I'm clueless about clue scrolls",
|
||||
"Where's the best spot to catch sharks? I'm aiming for 99 Fishing.",
|
||||
"Is there a shortcut to the Karamja Volcano?",
|
||||
"Can someone explain the mechanics of the Jad fight in the Fight Caves?",
|
||||
"I'm stuck on the Elemental Workshop quest. Any hints?",
|
||||
"Where can I find a loom to spin flax into bowstrings?",
|
||||
"What's the best gear setup for killing dragons? I want that visage drop!",
|
||||
"I'm trying to unlock the fairy rings",
|
||||
"How do I recharge my amulet of glory?",
|
||||
"Why do goblins drop coins?",
|
||||
"The Grand Exchange is like the stock market",
|
||||
"My real-life agility is more like a lumbering tortoise.",
|
||||
"The Wise Old Man's fashion sense is like Woahs",
|
||||
"I challenged a cow to a dance off, surprisingly smooth mooves.",
|
||||
"Why does the Lumbridge Guide always look lost?",
|
||||
"I'm convinced the ducks in Lumbridge are plotting world domination!",
|
||||
"I accidentally ate my prayer potion I'm blessed with heartburn",
|
||||
"I'm a vegetarian, except when it comes to slaying dragons.",
|
||||
"Why do wizards wear pointy hats? Is it a magical dress code?",
|
||||
"I'm a quest completionist, but I still can't find my keys in real life.",
|
||||
"I challenged a guard to a staring contest. He won.",
|
||||
"I'm saving up for a party hat. Priorities, ya know?",
|
||||
"What's the deal with the Wilderness?",
|
||||
"I'm convinced the chickens are secretly plotting world domination!",
|
||||
"Accidentally clicked 'Attack' on a guard. Now I'm on a watchlist.",
|
||||
"My character's fashion sense? Let's just say it's 'unique'",
|
||||
"Lobsters heal my soul",
|
||||
"Trimmed armor or bust!",
|
||||
"Wilderness: Where friendships go to die",
|
||||
"Buying gf 10k",
|
||||
"Dancing for coins at Lumbridge",
|
||||
"Wearing full rune like a boss",
|
||||
"Teleporting to Camelot for quests",
|
||||
"Fishing for hours at Catherby",
|
||||
"PKing with a rune 2h",
|
||||
"World 1 Falador Park parties",
|
||||
"Staking my bank at the Duel Arena",
|
||||
"Dying to Elvarg's fiery breath sums up my life",
|
||||
"Got the Quest cape finally on my main!",
|
||||
"Wearing a party hat with pride",
|
||||
"Castle Wars: Red vs Blue",
|
||||
"Trading in Varrock Square",
|
||||
"Barrows runs for that sweet loot",
|
||||
"Spending hours in Pest Control is life",
|
||||
"Killing cows for leather armor is a good start",
|
||||
"Farming herbs in Ardougne can be good money",
|
||||
"Clan chat drama LOL",
|
||||
"Mining rune essence endlessly",
|
||||
"Agility courses: A love-hate relationship",
|
||||
"Dueling for honor.... and GP",
|
||||
"Buying runes from Aubury is decent money",
|
||||
"Chasing the Easter Bunny like a scam",
|
||||
"Wearing a skillcape with pride",
|
||||
"Fletching yew longbows for profit",
|
||||
"Going to implings in Puro-Puro",
|
||||
"Castle Wars barricade wars",
|
||||
"Dropping party hats at drop parties like pennies",
|
||||
"Killing lesser demons in Karamja is part of my holy conquest",
|
||||
"@name lures noobs into the Wilderness",
|
||||
"Farming ranarrs for cash",
|
||||
"Getting lost in the Underground Pass",
|
||||
"Selling coal at the Grand Exchange",
|
||||
"Fighting the Kalphite Queen",
|
||||
"Picking flax in Seers' Village",
|
||||
"Begging for free stuff in Lumbridge",
|
||||
"Smithing rune platebodies for profit",
|
||||
"Logging out in Lumbridge Castle",
|
||||
"Hey @name, how do I get to the Grand Exchange?",
|
||||
"Veteran here! @name, what's your favorite quest?",
|
||||
"@name, how do I make money fast?",
|
||||
"Hey @name, what's the best combat style for bossing?",
|
||||
"@name, always carry an emergency teleport!",
|
||||
"New player here! @name, what's the Wilderness like?",
|
||||
"Hey @name, how do I join a clan?",
|
||||
"@name, prioritize Prayer levels!",
|
||||
"@name, what's the best way to train Agility?",
|
||||
"Hey @name, what's your favorite minigame?",
|
||||
"@name, never trust a PKer in Lumbridge!",
|
||||
"@name, how do I get a fire cape?",
|
||||
"Hey @name, what's the fastest way to level up Magic?",
|
||||
"@name, try the Barrows tunnels!",
|
||||
"@name, what's the deal with Pest Control?",
|
||||
"Hey @name, how do I unlock the Fairy Rings?",
|
||||
"@name, remember the old random events?",
|
||||
"@name, should I train Strength or Attack first?",
|
||||
"Hey @name, what's your favorite skillcape?",
|
||||
"@name, can't do the Fight Caves!",
|
||||
"@name, how do I get a pet?",
|
||||
"Hey @name, what's the best food for boss fights?",
|
||||
"@name, Castle Wars or Clan Wars?",
|
||||
"@name, what's a clue scroll?",
|
||||
"Hey @name, how do I defeat Jad?",
|
||||
"@name, use Protect from Melee at KBD!",
|
||||
"@name, should I train Ranged or Magic?",
|
||||
"Hey @name, what's the best way to level up Crafting?",
|
||||
"@name, don't forget your anti-dragon shield!",
|
||||
"@name, what's the Stronghold of Security?",
|
||||
"Hey @name, how do I access the Legends' Guild?",
|
||||
"@name, remember the old PvP worlds?",
|
||||
"@name, how do I get a dragon defender?",
|
||||
"Hey @name, what's the best way to level up Herblore?",
|
||||
"@name, always carry a charged amulet of glory!",
|
||||
"@name, should I train Fishing or Cooking?",
|
||||
"Hey @name, how do I defeat the Chaos Elemental?",
|
||||
"@name, try the TzHaar Fight Pit!",
|
||||
"@name, what's the best way to level up Smithing?",
|
||||
"Hey @name, what's your favorite Slayer master?",
|
||||
"@name, use the Ardougne cloak teleports!",
|
||||
"@name, what's the Legends' Quest about?",
|
||||
"Hey @name, how do I unlock the Ancient Magicks?",
|
||||
"@name, remember the old Pest Control boats?",
|
||||
"@name, what's the best way to level up Construction?",
|
||||
"Hey @name, what's the fastest way to level up Prayer?",
|
||||
"@name, the old Duel Arena stakes!",
|
||||
"@name, what's the Warriors' Guild?",
|
||||
"Hey @name, how do I defeat the Kalphite Queen?",
|
||||
"@name, use the fairy ring code BIP!",
|
||||
"@name, should I train Attack or Defense first?",
|
||||
"Hey @name, what's the best way to level up Thieving?",
|
||||
"@name, don't forget your charged glory amulet!",
|
||||
"@name, what's the Legends' Cape?",
|
||||
"Hey @name, how do I access the Heroes' Guild?",
|
||||
"@name, remember the old Pest Control void gear?",
|
||||
"@name, how do I get a firemaking skillcape?",
|
||||
"Buying gf 10k",
|
||||
"Trimming armor for free!",
|
||||
"Wanna join my clan? We're called The Mighty Cabbages'!",
|
||||
"I'll meet you at the Falador Party Room!",
|
||||
"Dancing for coins in Varrock Square!",
|
||||
"Remember when the Wilderness was dangerous?",
|
||||
"I got a rune scimitar drop from Lesser Demons!",
|
||||
"Lumbridge Swamp is haunted!",
|
||||
"Anyone up for Castle Wars?",
|
||||
"I miss the old random events!",
|
||||
"World 2 is the trading hub!",
|
||||
"I'm going to train my Agility at the Gnome Stronghold!",
|
||||
"I just got 99 Cooking!",
|
||||
"Fishing lobsters at Catherby is life!",
|
||||
"The Legends' Guild is so exclusive!",
|
||||
"Who needs a quest guide? I'll figure it out!",
|
||||
"I'm mining rune essence for hours!",
|
||||
"Barrows armor looks sick!",
|
||||
"I'm stuck in the Underground Pass!",
|
||||
"The Stronghold of Security taught me about account security!",
|
||||
"I'm going to farm herbs in Ardougne!",
|
||||
"I'm getting my fire cape!",
|
||||
"I love the music in RuneScape!",
|
||||
"I'm alching my maple longbows!",
|
||||
"I'm doing the Recipe for Disaster subquests!",
|
||||
"I'm going to train my combat stats at the Rock Crabs!",
|
||||
"I'm going for the Quest Cape!",
|
||||
"I'm going to mine pure essence!",
|
||||
"I'm hunting chinchompas in the Feldip Hills!",
|
||||
"I'm going to train my Woodcutting at Seers' Village!",
|
||||
"I'm going to fish sharks at the Fishing Guild!",
|
||||
"I'm going to train my Thieving at Ardougne Knights!",
|
||||
"I'm going to hunt implings in Puro-Puro!",
|
||||
"I'm going to train my Hunter at the Falconry!",
|
||||
"I'm smithing rune platebodies!",
|
||||
"I'm going to train my Farming at the Tree Gnome Stronghold!",
|
||||
"I'm going to hunt red chinchompas in the Wilderness!",
|
||||
"I'm doing the Underground Pass quest!",
|
||||
"I'm going to fish monkfish in Piscatoris!",
|
||||
"Meet me in Varrock, @name, for an epic trade",
|
||||
"@name, join my clan; we'll conquer the Wilderness together!",
|
||||
"Beware the dragons, @name, they're fiercer than you think",
|
||||
"Crafting runes with @name, the best mage in Gielinor",
|
||||
"Fishing lobsters with @name, the sea's no match for us",
|
||||
"@name, your swordsmanship at Duel Arena is unmatched!",
|
||||
"Questing through dark caves, @name always leads the way",
|
||||
"Share your wisdom, @name, how'd you master those spells?",
|
||||
"Legends speak of @name bravery at the God Wars",
|
||||
"Need more arrows, @name? I've got plenty to spare",
|
||||
"Cooking's a breeze when @name around, no burnt lobsters!",
|
||||
"Mining together, @name and I strike gold every time",
|
||||
"@name, let's barter; your herbs for my potions?",
|
||||
"Training agility with @name, leaping like graceful gazelles",
|
||||
"Heard @name got the best magic beans in town",
|
||||
"Fletching bows with @name, aiming for perfection",
|
||||
"Smithing with @name, our anvils never cool down",
|
||||
"Adventuring with @name, every quest is a thrill",
|
||||
"Battling demons, @name courage inspires us all",
|
||||
"Slaying dragons, @name the hero we need",
|
||||
"Gathering at Falador, @name party room is legendary",
|
||||
"Hunting chinchompas, @name traps are always full",
|
||||
"Farming's fun with @name, our crops never fail",
|
||||
"Brewing potions, @name mixtures are magical",
|
||||
"Casting spells with @name, we're invincible",
|
||||
"Building fires, @name flames warm the coldest nights",
|
||||
"Sailing to Pest Control, @name our fearless captain",
|
||||
"Trading runes, @name deals are the fairest",
|
||||
"Exploring dungeons, @name the light in the darkness",
|
||||
"Charging orbs with @name, our energy knows no bounds",
|
||||
"Dancing in Draynor, @name moves are enchanting",
|
||||
"Playing Gnomeball, @name the star player",
|
||||
"Harvesting willows, @name axe swings true",
|
||||
"Enchanting jewelry, @name touch turns copper to gold",
|
||||
"Summoning familiars, @name spirit wolf leads the pack",
|
||||
"Thieving from stalls, @name hands are lightning-fast",
|
||||
"Crafting runes, @name essence never runs dry",
|
||||
"Fishing at Catherby, @name catch feeds us all",
|
||||
"Cooking feasts, @name dishes delight the gods",
|
||||
"Mining runite, @name pickaxe strikes rich veins",
|
||||
"Bartering at Grand Exchange, @name a trading master",
|
||||
"Training prayer, @name piety moves mountains",
|
||||
"Fighting revenants, @name valor shines bright",
|
||||
"Building homes, @name construction is flawless",
|
||||
"Hunting imps, @name net is always full",
|
||||
"Brewing ale, @name tavern is the town's favorite",
|
||||
"Casting high alchemy, @name turns junk into treasure",
|
||||
"Sailing to Karamja, @name adventures are legendary",
|
||||
"Forging alliances, @name charisma unites clans",
|
||||
"Defeating bosses, @name name echoes in legends",
|
||||
"Are you mewing @name???",
|
||||
"Check out that gyatt @name",
|
||||
"Bruhhhhh @name got that rizz",
|
||||
"@name rizzing up the bots",
|
||||
"Ironman? More like copperboy LOL",
|
||||
"What that gyatt do @name",
|
||||
"He's got the zoomies!",
|
||||
"@name likes pickles and dipped in mayo",
|
||||
"Lmaaooooooo",
|
||||
"Bruh she said she loved me...",
|
||||
"I caught @name rizzing a mewing teacher",
|
||||
"What that mouth do bb",
|
||||
"Ayo tf he say",
|
||||
"Ayo",
|
||||
"Ayo @name a freak lowkey",
|
||||
"Ayo tf",
|
||||
"@name catch me outside howbout that",
|
||||
"Wasssssuuuuppppppp",
|
||||
"Knock knock @name",
|
||||
"Oh boy howdy do i have a surprise for you",
|
||||
"Noooooo",
|
||||
"What do you mean I haven't done anything wtf",
|
||||
"Redrocket redrocket!!!",
|
||||
"I made 20,000 crochet sock puppets for ceikry",
|
||||
"Come on @name",
|
||||
"Are we rading tonight @name?",
|
||||
"Why would he say that",
|
||||
"Penguins are technically reptiles",
|
||||
"Brb smell something burning",
|
||||
"Need pest control partner, you handle the portals, i will afk",
|
||||
"Bruhhhh the skibiddi rizz in my gyatt makes my mewing sesh rough",
|
||||
"@name jajajajaja",
|
||||
"Wait, I can't raid tonight @name",
|
||||
"Brb, pizza's here. Hope they ask why I'm a grown man dressed like an elf",
|
||||
"Sorry, gotta go AFK. My dog just ate my gaming headset.",
|
||||
"Brb, my grandma just fell down the stairs",
|
||||
"Hold on, the baby's crying, aka @name",
|
||||
"Oops, spilled my drink",
|
||||
"Guys, I need to log off, my plants are staging a revolt for not watering them",
|
||||
"AFK a sec, my neighbor's llama is in my backyard again",
|
||||
"My pizza rolls are ready",
|
||||
"Lost track of time, i'm late for my own wedding",
|
||||
"Sorry, can't hear you over the sound of my laundry",
|
||||
"Turn HDR off in windows @name",
|
||||
"Www. no one cares .com",
|
||||
"Hey @name www dot stfu dot com",
|
||||
"Like pitching a tent in a pair of britches",
|
||||
"Mad as a bag of ferrets",
|
||||
"I dont think beavers built the hoover dam",
|
||||
"How do beavers get the concrete for dams?",
|
||||
"@name show me the way",
|
||||
"@name onwards brutha",
|
||||
"@name eats fried rat tails",
|
||||
"@name is a rat",
|
||||
"Why are there so many people farming right now",
|
||||
"@name fuck the police",
|
||||
"@name says the like pickles on their hotdogs",
|
||||
"Fuck the guards, free woah in varrock prison",
|
||||
"Ayo fuck u mean",
|
||||
"Woop woop thats da sound of the beast",
|
||||
"How are you the way that you are",
|
||||
"She sells seashells by the sea shore",
|
||||
"@name certified rat",
|
||||
"@name buys skimmed milk",
|
||||
"Got milk?",
|
||||
"Are you JSON because i want you to get array from me",
|
||||
"@name likes string manipulation",
|
||||
"@name sells legos",
|
||||
"JUST DO IT",
|
||||
"Why are there so many motherfucking options",
|
||||
"Just hit the fucking auto hide thing",
|
||||
"Just play",
|
||||
"Hell no this shit is fuzzy as balls",
|
||||
"@name is fuzzy as balls",
|
||||
"Turn your brightness up @name",
|
||||
"On my pc it runs perfectly",
|
||||
"I know why mine seems a little jumpy",
|
||||
"Stream the window not the monitor",
|
||||
"Discords a bitch",
|
||||
"Why are there so many handsome people at the ge like @name",
|
||||
"I'll make you squeel of fortune",
|
||||
"You will get it in due time @name",
|
||||
"I was one turn away",
|
||||
"It do be pipe time @name",
|
||||
"Sometimes i like to cover myself in vaseline and pretend i'm a slug",
|
||||
"Woah is a greased pig",
|
||||
"Sometimes i dig holes in my backyard and pretend i'm a carrot",
|
||||
"It's pipe time @name",
|
||||
"If i am not pipe timing i am programming",
|
||||
"Yes i have thigh high socks, no you cannot have them",
|
||||
"I scream when i wear my programming socks",
|
||||
"Anyone wanna buy @name's bathwater?",
|
||||
"Anyone wanna buy my used socks?",
|
||||
"@name be getting bags",
|
||||
"What the fuck is this",
|
||||
"Hi i noticed you haven't taken a break in hours @name",
|
||||
"I really am seething rn",
|
||||
"I am so fucking tilted",
|
||||
"Go back to your fucking frogs",
|
||||
"Life is simple as frog farmer",
|
||||
"A q p",
|
||||
"Oooooh that's a first",
|
||||
"Been a minute @name",
|
||||
"Hey @name",
|
||||
"Oh shit it's @name",
|
||||
"Hey @name wyd today?",
|
||||
"Ayo @name",
|
||||
"Wyd @name",
|
||||
"Wbu @name?",
|
||||
"Good fuck em, that's what they get",
|
||||
"Deathknight lookin rat ass mf @name",
|
||||
"@name sucks slugs",
|
||||
"Brb gotta take a shit",
|
||||
"@name will brb went to take a shit",
|
||||
"Tell me when he is coming",
|
||||
"This guy is being incredibly based",
|
||||
"@name is based af",
|
||||
"Taking l's all day today @name",
|
||||
"That sucks massive dongus",
|
||||
"Ah i was about to type that",
|
||||
"Where is stormwind?",
|
||||
"How do i buy gold",
|
||||
"@name sells gold",
|
||||
"@name is a gold digger",
|
||||
"Ayo @name wanna buy some frog legs?",
|
||||
"Brb fucking burnt my pizza rolls",
|
||||
"I swear @name if you need roll again",
|
||||
"@name you are a hunter you don't need plate armor",
|
||||
"Dragonriding is satisfying",
|
||||
"There's an old TzHarrian saying, you fuck up once, you lose two teeth",
|
||||
"FUCK",
|
||||
"@name i am ready when you are",
|
||||
"Anyone selling logs?",
|
||||
"That is hilarious @name",
|
||||
"Alright @name",
|
||||
"I need to go get my quest cape",
|
||||
"500 barrows runs dry",
|
||||
"Back to back to back barrows items, easy game",
|
||||
"@name did you know them?",
|
||||
"@name sucks eggs",
|
||||
"@name eats snails",
|
||||
"Who is that?",
|
||||
"I've gotta go in 20 minutes",
|
||||
"Bonk",
|
||||
"Gtg in 30 minutes",
|
||||
"They left 50 minutes ago",
|
||||
"I think it's just gonna be us",
|
||||
"Who is that?",
|
||||
"Stop following me",
|
||||
"@name stop following me",
|
||||
"I think @name is watching me",
|
||||
"@name wouldn't let me get a hit in at clan wars",
|
||||
"Clan wars and chill?",
|
||||
"Quick mewing sesh",
|
||||
"Don't you stickbug me",
|
||||
"Get stick bugged",
|
||||
"Wtf why are you a dragon",
|
||||
"Fun fact, woah eats eggs whole like a snake",
|
||||
"Ceikys there's a rare over there",
|
||||
"Where is goldshire?",
|
||||
"How long have you played @name?",
|
||||
"Wanna quest?",
|
||||
"TROGDORRRRRR",
|
||||
"Fuck this shit i'm out",
|
||||
"Wait till you get your first 99",
|
||||
"How is that even possible",
|
||||
"That's the max",
|
||||
"@name is trying to max",
|
||||
"Complesionist cape?",
|
||||
"How can you increase your run speed?",
|
||||
"@name where is barrows?",
|
||||
"@name where are rune rocks?",
|
||||
"@name where is yanille?",
|
||||
"@name how long have you played for?",
|
||||
"Yes these quotes were hand typed",
|
||||
"Kermit was here",
|
||||
"World of Warcraft died after Wrath",
|
||||
"Ceikry needs to add talent trees",
|
||||
"How do you get to the wilderness?",
|
||||
"Anyone tryna lure @name?",
|
||||
"@name tried to lure me",
|
||||
"@name bots all the time",
|
||||
"Anyone want chicken tendies",
|
||||
"Brb foods ready",
|
||||
"Brb",
|
||||
"Gotta go get food",
|
||||
"Anyone else from northern alaska?",
|
||||
"Fishing 4 gp",
|
||||
"Looking for gf",
|
||||
"Anyone wanna be my discord kitten?",
|
||||
"Selling discord kittens",
|
||||
"@name is a discord kitten",
|
||||
"Add me on discord",
|
||||
"Are you in the 09discord",
|
||||
"Where are you going @name?",
|
||||
"Idk what i am going to cook today",
|
||||
"What should i eat tonight",
|
||||
"He is in the cave",
|
||||
"Don't forget to save game before logging out",
|
||||
"American horror story died after season 1",
|
||||
"Prequels are better than the sequels",
|
||||
"Disney star wars is the best star wars",
|
||||
"Halo 5 sucked",
|
||||
"Selling xbox live gold and 1600 microsoft points for 50k gp",
|
||||
"Buying gf 25gp and a bucket",
|
||||
"@name i heard evilwaffles bots",
|
||||
"@name hopefully ceikry doesn't find out about evilwaffles",
|
||||
"Honk honk",
|
||||
"Where is the road to mordor?",
|
||||
"Golem lookin ass bitch",
|
||||
"@name rat looking mf",
|
||||
"@name uses sand paper to wipe",
|
||||
"@name said Woah is cute",
|
||||
"You need 25 of 40 to do that",
|
||||
"Over 1000 unique lines of dialogue",
|
||||
"What should i get to eat",
|
||||
"Ge be poppin today",
|
||||
"Where all the woahs at",
|
||||
"Ayo woahscam got that gyatt",
|
||||
"That is one i haven't seen before"
|
||||
],
|
||||
"halloween": [
|
||||
"Trick or treat!!!",
|
||||
|
|
@ -521,9 +1008,9 @@
|
|||
"Costume party at my P O H!! Follow me!",
|
||||
"Trick, then!",
|
||||
"Brrrainssssssss...",
|
||||
"'Cause this is thriller, thriller night, and no one's gonna save you from the beast about to strike!",
|
||||
"This is Hallowe'en, this is Hallowe'en, pumpkins scream in the dead of night!",
|
||||
"This is Hallowe'en, everybody make a scene, Trick or treat till the neighbors gonna die of fright!",
|
||||
"'Cause this is thriller, thriller night!",
|
||||
"This is Hallowe'en, this is Hallowe'en!",
|
||||
"This is Hallowe'en, everybody make a scene!",
|
||||
"In this town we call home, everyone hail to the pumpkin song!",
|
||||
"Watch out for Skeleton Jack!",
|
||||
"The headless-what-man? Horse? Never heard of those.",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
BIN
Server/data/cache/main_file_cache.dat2
(Stored with Git LFS)
vendored
BIN
Server/data/cache/main_file_cache.dat2
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Server/data/cache/main_file_cache.idx255
(Stored with Git LFS)
vendored
BIN
Server/data/cache/main_file_cache.idx255
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
Server/data/cache/main_file_cache.idx5
(Stored with Git LFS)
vendored
BIN
Server/data/cache/main_file_cache.idx5
(Stored with Git LFS)
vendored
Binary file not shown.
|
|
@ -301,7 +301,7 @@
|
|||
},
|
||||
{
|
||||
"id": "2025",
|
||||
"replaceId": "1534",
|
||||
"replaceId": "2026",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -312,7 +312,7 @@
|
|||
"metal": "false"
|
||||
},
|
||||
{
|
||||
"id": "2036",
|
||||
"id": "1530",
|
||||
"replaceId": "1531",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
|
|
@ -925,7 +925,7 @@
|
|||
},
|
||||
{
|
||||
"id": "3747",
|
||||
"replaceId": "1534",
|
||||
"replaceId": "3748",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -943,7 +943,7 @@
|
|||
},
|
||||
{
|
||||
"id": "4148",
|
||||
"replaceId": "4248",
|
||||
"replaceId": "4246",
|
||||
"fence": "false",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -1759,7 +1759,7 @@
|
|||
},
|
||||
{
|
||||
"id": "14245",
|
||||
"replaceId": "14248",
|
||||
"replaceId": "14246",
|
||||
"fence": "true",
|
||||
"metal": "false"
|
||||
},
|
||||
|
|
@ -1984,16 +1984,14 @@
|
|||
"replaceId": "28518",
|
||||
"fence": "false",
|
||||
"metal": "true",
|
||||
"autowalk": "true",
|
||||
"questRequirement": "Icthlarin's Little Helper"
|
||||
"autowalk": "true"
|
||||
},
|
||||
{
|
||||
"id": "28514",
|
||||
"replaceId": "28518",
|
||||
"fence": "false",
|
||||
"metal": "true",
|
||||
"autowalk": "true",
|
||||
"questRequirement": "Icthlarin's Little Helper"
|
||||
"autowalk": "true"
|
||||
},
|
||||
{
|
||||
"id": "21065",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -233,7 +233,7 @@
|
|||
},
|
||||
{
|
||||
"item_id": "946",
|
||||
"loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,3218,9887,0,33}-"
|
||||
"loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,3218,9887,0,33}-{1,2700,3407,0,100}-"
|
||||
},
|
||||
{
|
||||
"item_id": "952",
|
||||
|
|
@ -241,7 +241,7 @@
|
|||
},
|
||||
{
|
||||
"item_id": "954",
|
||||
"loc_data": "{1,2094,3152,0,150}-"
|
||||
"loc_data": "{1,2094,3152,0,150}-{1,2785,3279,0,150}-{1,2786,3287,0,150}-{1,2786,3286,0,150}-"
|
||||
},
|
||||
{
|
||||
"item_id": "960",
|
||||
|
|
@ -339,6 +339,14 @@
|
|||
"item_id": "1422",
|
||||
"loc_data": "{1,3320,3137,0,150}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1467",
|
||||
"loc_data": "{1,2784,3289,0,0}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1469",
|
||||
"loc_data": "{1,2766,3277,0,100}-{1,2766,3289,0,100}-"
|
||||
},
|
||||
{
|
||||
"item_id": "1510",
|
||||
"loc_data": "{1,2576,3334,0,100}-"
|
||||
|
|
@ -619,6 +627,10 @@
|
|||
"item_id": "4707",
|
||||
"loc_data": "{1,3571,3312,0,40}-"
|
||||
},
|
||||
{
|
||||
"item_id": "4838",
|
||||
"loc_data": "{1,2593,3103,1,40}-"
|
||||
},
|
||||
{
|
||||
"item_id": "5008",
|
||||
"loc_data": "{1,3230,9609,0,44}-"
|
||||
|
|
@ -627,6 +639,10 @@
|
|||
"item_id": "5523",
|
||||
"loc_data": "{1,2935,3282,1,90}-"
|
||||
},
|
||||
{
|
||||
"item_id": "5586",
|
||||
"loc_data": "{1,2473,4941,0,90}-"
|
||||
},
|
||||
{
|
||||
"item_id": "6291",
|
||||
"loc_data": "{1,2681,3111,0,30}-{1,2673,3112,0,30}-{1,2674,3094,0,30}-{1,2671,3089,0,30}-"
|
||||
|
|
|
|||
|
|
@ -95,6 +95,30 @@
|
|||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "68",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "69",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "70",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "71",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "74",
|
||||
"interfaceType": "4",
|
||||
|
|
@ -365,6 +389,30 @@
|
|||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "245",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "246",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "247",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "248",
|
||||
"interfaceType": "4",
|
||||
"walkable": "false",
|
||||
"tabIndex": "-1"
|
||||
},
|
||||
{
|
||||
"id": "256",
|
||||
"interfaceType": "8",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2566
Server/data/configs/music_regions.json
Normal file
2566
Server/data/configs/music_regions.json
Normal file
File diff suppressed because it is too large
Load diff
62
Server/data/configs/music_tiles.json
Normal file
62
Server/data/configs/music_tiles.json
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
[
|
||||
{
|
||||
"id": "98",
|
||||
"borders": "{3072,3456,3135,3519,[3076,3456,3085,3458]~,[3082,3459,3085,3460]}"
|
||||
},
|
||||
{
|
||||
"id": "141",
|
||||
"borders": "{3072,3392,3135,3455,[3076,3452,3085,3455]}"
|
||||
},
|
||||
{
|
||||
"id": "228",
|
||||
"borders": "{2896,5446,2919,5462}"
|
||||
},
|
||||
{
|
||||
"id": "229",
|
||||
"borders": "{2921,5456,2937,5479}"
|
||||
},
|
||||
{
|
||||
"id": "230",
|
||||
"borders": "{2904,5481,2927,5497}"
|
||||
},
|
||||
{
|
||||
"id": "231",
|
||||
"borders": "{2886,5464,2902,5487}"
|
||||
},
|
||||
{
|
||||
"id": "386",
|
||||
"borders": "{2820,5312,2849,5369}-{2849,5349,2880,5374}"
|
||||
},
|
||||
{
|
||||
"id": "391",
|
||||
"borders": "{2879,5340,2944,5366}-{2909,5316,2944,5340}"
|
||||
},
|
||||
{
|
||||
"id": "399",
|
||||
"borders": "{2816,5248,2943,5375,[2823,5250,2844,5310]~,[2844,5250,2878,5280]~,[2879,5340,2944,5366]~,[2909,5316,2944,5340]~,[2820,5312,2849,5369]~,[2849,5349,2880,5374]~,[2885,5253,2934,5278]~,[2913,5278,2937,5306]}"
|
||||
},
|
||||
{
|
||||
"id": "404",
|
||||
"borders": "{2823,5250,2844,5310}-{2844,5250,2878,5276}"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"borders": "{2885,5253,2934,5278}-{2913,5278,2937,5306}"
|
||||
},
|
||||
{
|
||||
"id": "459",
|
||||
"borders": "{3137,5442,3192,5564}-{3193,5442,3198,5472}-{3193,5507,3198,5564}"
|
||||
},
|
||||
{
|
||||
"id": "467",
|
||||
"borders": "{3199,5441,3262,5564}-{3193,5482,3198,5497}"
|
||||
},
|
||||
{
|
||||
"id": "488",
|
||||
"borders": "{3263,5441,3327,5566}"
|
||||
},
|
||||
{
|
||||
"id": "492",
|
||||
"borders": "{3076,3452,3085,3460,[3076,3459,3081,3460]}"
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -16324,7 +16324,7 @@
|
|||
"ids": "11629"
|
||||
},
|
||||
{
|
||||
"examine": "South to Falador :: West to Taverley :: East to Varrock.",
|
||||
"examine": "This tells you which way is which.",
|
||||
"ids": "11630,11631,11632,11633"
|
||||
},
|
||||
{
|
||||
|
|
@ -16741,7 +16741,7 @@
|
|||
},
|
||||
{
|
||||
"examine": "Better not eat them!",
|
||||
"ids": "12003"
|
||||
"ids": "12003,12128"
|
||||
},
|
||||
{
|
||||
"examine": "It's going to be a tight squeeze!",
|
||||
|
|
@ -16881,7 +16881,7 @@
|
|||
},
|
||||
{
|
||||
"examine": "A wall jutting out into the path.",
|
||||
"ids": "12127,12128,12129,12130"
|
||||
"ids": "12127,12129,12130"
|
||||
},
|
||||
{
|
||||
"examine": "Spooky.",
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@
|
|||
"general_store": "true",
|
||||
"id": "25",
|
||||
"title": "Lumbridge General Store",
|
||||
"stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}"
|
||||
"stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}-{1939,1000,1}"
|
||||
},
|
||||
{
|
||||
"npcs": "4716",
|
||||
|
|
@ -564,7 +564,7 @@
|
|||
"general_store": "false",
|
||||
"id": "65",
|
||||
"title": "Dodgy Mikes Second-hand Clothing",
|
||||
"stock": "{7114,10,100}"
|
||||
"stock": "{7114,10,100}-{7122,10,100}-{7128,10,100}-{7134,10,100}-{7110,10,100}-{7126,10,100}-{7132,10,100}-{7138,10,100}-{7116,10,100}-{7124,10,100}-{7130,10,100}-{7112,10,100}-{7136,10,100}"
|
||||
},
|
||||
{
|
||||
"npcs": "2161",
|
||||
|
|
@ -1599,7 +1599,7 @@
|
|||
"general_store": "false",
|
||||
"id": "181",
|
||||
"title": "MoonClan Fine Clothes",
|
||||
"stock": "{9068,10,100}-{9069,10,100}-{9070,10,100}-{9071,10,100}-{9072,10,100}-{9073,10,100}-{9074,10,100}-{1733,50,100}-{1734,500,100}"
|
||||
"stock": "{9068,10,100}-{9069,10,100}-{9070,10,100}-{9071,10,100}-{9072,10,100}-{9073,10,100}-{9074,10,100}-{1733,50,100}-{1734,500,100}-{9084,10,100}-{9096,10,100}-{9097,10,100}-{9098,10,100}-{9099,10,100}-{9100,10,100}-{9101,10,100}-{9102,10,100}-{9104,10,100}"
|
||||
},
|
||||
{
|
||||
"npcs": "",
|
||||
|
|
@ -2177,5 +2177,23 @@
|
|||
"id": "255",
|
||||
"title": "Castle Wars Ticket Exchange",
|
||||
"stock": "{4068,1,100}-{4069,1,100}-{4070,1,100}-{4071,1,100}-{4072,1,100}-{4503,1,100}-{4504,1,100}-{4505,1,100}-{4506,1,100}-{4507,1,100}-{4508,1,100}-{4509,1,100}-{4510,1,100}-{4511,1,100}-{4512,1,100}-{4513,1,100}-{4514,1,100}-{4515,1,100}-{4516,1,100}"
|
||||
},
|
||||
{
|
||||
"npcs": "5111",
|
||||
"high_alch": "0",
|
||||
"currency": "995",
|
||||
"general_store": "false",
|
||||
"id": "256",
|
||||
"title": "Leon's Prototype Crossbow",
|
||||
"stock": "{10156,2,100}"
|
||||
},
|
||||
{
|
||||
"npcs": "2039",
|
||||
"high_alch": "0",
|
||||
"currency": "995",
|
||||
"general_store": "false",
|
||||
"id": "256",
|
||||
"title": "Uglug's Stuffsies",
|
||||
"stock": "{4844,100,10}-{10927,0,100}-{2862,100,100}-{1777,10,200}-{2876,0,500}-{2878,10,100}-{4850,0,100}-{946,5,100}-{4773,0,1000}-{4778,0,1000}-{4783,0,1000}-{4788,0,1500}-{4793,0,2000}-{4798,0,3000}-{4803,0,4000}-{4827,0,2000}"
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -2,6 +2,7 @@ package content.data
|
|||
|
||||
import content.global.skill.magic.TeleportMethod
|
||||
import content.global.skill.slayer.SlayerManager.Companion.getInstance
|
||||
import content.global.skill.slayer.SlayerUtils
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.event.TeleportEvent
|
||||
|
|
@ -304,7 +305,7 @@ enum class EnchantedJewellery(
|
|||
return
|
||||
}
|
||||
sendNPCDialogue(player, slayerManager.master!!.npc, "You're currently " +
|
||||
"assigned to kill ${getSlayerTaskName(player).lowercase(Locale.getDefault())}'s; " +
|
||||
"assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player))} " +
|
||||
"only ${getSlayerTaskKillsRemaining(player)} more to go.", core.game.dialogue.FacialExpression.FRIENDLY)
|
||||
// Slayer tracker UI
|
||||
setVarp(player, 2502, slayerManager.flags.taskFlags shr 4)
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public enum GodBook {
|
|||
* @param page the page.
|
||||
*/
|
||||
public void insertPage(Player player, Item book, Item page) {
|
||||
if (!hasRequirement(player, "Horror from the Deep"))
|
||||
if (!hasRequirement(player, Quests.HORROR_FROM_THE_DEEP))
|
||||
return;
|
||||
if (hasPage(player, book, page)) {
|
||||
player.sendMessage("The book already has that page.");
|
||||
|
|
|
|||
158
Server/src/main/content/data/Quests.kt
Normal file
158
Server/src/main/content/data/Quests.kt
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
package content.data
|
||||
|
||||
enum class Quests(val questName: String) {
|
||||
MYTHS_OF_THE_WHITE_LANDS("Myths of the White Lands"),
|
||||
BLACK_KNIGHTS_FORTRESS("Black Knights' Fortress"),
|
||||
COOKS_ASSISTANT("Cook's Assistant"),
|
||||
DEMON_SLAYER("Demon Slayer"),
|
||||
DORICS_QUEST("Doric's Quest"),
|
||||
DRAGON_SLAYER("Dragon Slayer"),
|
||||
ERNEST_THE_CHICKEN("Ernest the Chicken"),
|
||||
GOBLIN_DIPLOMACY("Goblin Diplomacy"),
|
||||
IMP_CATCHER("Imp Catcher"),
|
||||
THE_KNIGHTS_SWORD("The Knight's Sword"),
|
||||
PIRATES_TREASURE("Pirate's Treasure"),
|
||||
PRINCE_ALI_RESCUE("Prince Ali Rescue"),
|
||||
THE_RESTLESS_GHOST("The Restless Ghost"),
|
||||
ROMEO_JULIET("Romeo & Juliet"),
|
||||
RUNE_MYSTERIES("Rune Mysteries"),
|
||||
SHEEP_SHEARER("Sheep Shearer"),
|
||||
SHIELD_OF_ARRAV("Shield of Arrav"),
|
||||
VAMPIRE_SLAYER("Vampire Slayer"),
|
||||
WITCHS_POTION("Witch's Potion"),
|
||||
ANIMAL_MAGNETISM("Animal Magnetism"),
|
||||
BETWEEN_A_ROCK("Between a Rock..."),
|
||||
BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting"),
|
||||
BIOHAZARD("Biohazard"),
|
||||
CABIN_FEVER("Cabin Fever"),
|
||||
CLOCK_TOWER("Clock Tower"),
|
||||
CONTACT("Contact!"),
|
||||
ZOGRE_FLESH_EATERS("Zogre Flesh Eaters"),
|
||||
CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain"),
|
||||
DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale"),
|
||||
DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun"),
|
||||
DEATH_PLATEAU("Death Plateau"),
|
||||
DESERT_TREASURE("Desert Treasure"),
|
||||
DEVIOUS_MINDS("Devious Minds"),
|
||||
THE_DIG_SITE("The Dig Site"),
|
||||
DRUIDIC_RITUAL("Druidic Ritual"),
|
||||
DWARF_CANNON("Dwarf Cannon"),
|
||||
EADGARS_RUSE("Eadgar's Ruse"),
|
||||
EAGLES_PEAK("Eagles' Peak"),
|
||||
ELEMENTAL_WORKSHOP_I("Elemental Workshop I"),
|
||||
ELEMENTAL_WORKSHOP_II("Elemental Workshop II"),
|
||||
ENAKHRAS_LAMENT("Enakhra's Lament"),
|
||||
ENLIGHTENED_JOURNEY("Enlightened Journey"),
|
||||
THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie"),
|
||||
FAIRYTALE_I_GROWING_PAINS("Fairytale I - Growing Pains"),
|
||||
FAIRYTALE_II_CURE_A_QUEEN("Fairytale II - Cure a Queen"),
|
||||
FAMILY_CREST("Family Crest"),
|
||||
THE_FEUD("The Feud"),
|
||||
FIGHT_ARENA("Fight Arena"),
|
||||
FISHING_CONTEST("Fishing Contest"),
|
||||
FORGETTABLE_TALE("Forgettable Tale..."),
|
||||
THE_FREMENNIK_TRIALS("The Fremennik Trials"),
|
||||
WATERFALL_QUEST("Waterfall Quest"),
|
||||
GARDEN_OF_TRANQUILITY("Garden of Tranquility"),
|
||||
GERTRUDES_CAT("Gertrude's Cat"),
|
||||
GHOSTS_AHOY("Ghosts Ahoy"),
|
||||
THE_GIANT_DWARF("The Giant Dwarf"),
|
||||
THE_GOLEM("The Golem"),
|
||||
THE_GRAND_TREE("The Grand Tree"),
|
||||
THE_HAND_IN_THE_SAND("The Hand in the Sand"),
|
||||
HAUNTED_MINE("Haunted Mine"),
|
||||
HAZEEL_CULT("Hazeel Cult"),
|
||||
HEROES_QUEST("Heroes' Quest"),
|
||||
HOLY_GRAIL("Holy Grail"),
|
||||
HORROR_FROM_THE_DEEP("Horror from the Deep"),
|
||||
ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper"),
|
||||
IN_AID_OF_THE_MYREQUE("In Aid of the Myreque"),
|
||||
IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque"),
|
||||
JUNGLE_POTION("Jungle Potion"),
|
||||
LEGENDS_QUEST("Legend's Quest"),
|
||||
LOST_CITY("Lost City"),
|
||||
THE_LOST_TRIBE("The Lost Tribe"),
|
||||
LUNAR_DIPLOMACY("Lunar Diplomacy"),
|
||||
MAKING_HISTORY("Making History"),
|
||||
MERLINS_CRYSTAL("Merlin's Crystal"),
|
||||
MONKEY_MADNESS("Monkey Madness"),
|
||||
MONKS_FRIEND("Monk's Friend"),
|
||||
MOUNTAIN_DAUGHTER("Mountain Daughter"),
|
||||
MOURNINGS_END_PART_I("Mourning's End Part I"),
|
||||
MOURNINGS_END_PART_II("Mourning's End Part II"),
|
||||
MURDER_MYSTERY("Murder Mystery"),
|
||||
MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure"),
|
||||
NATURE_SPIRIT("Nature Spirit"),
|
||||
OBSERVATORY_QUEST("Observatory Quest"),
|
||||
ONE_SMALL_FAVOUR("One Small Favour"),
|
||||
PLAGUE_CITY("Plague City"),
|
||||
PRIEST_IN_PERIL("Priest in Peril"),
|
||||
RAG_AND_BONE_MAN("Rag and Bone Man"),
|
||||
RATCATCHERS("Ratcatchers"),
|
||||
RECIPE_FOR_DISASTER("Recipe for Disaster"),
|
||||
RECRUITMENT_DRIVE("Recruitment Drive"),
|
||||
REGICIDE("Regicide"),
|
||||
ROVING_ELVES("Roving Elves"),
|
||||
ROYAL_TROUBLE("Royal Trouble"),
|
||||
RUM_DEAL("Rum Deal"),
|
||||
SCORPION_CATCHER("Scorpion Catcher"),
|
||||
SEA_SLUG("Sea Slug"),
|
||||
THE_SLUG_MENACE("The Slug Menace"),
|
||||
SHADES_OF_MORTTON("Shades of Mort'ton"),
|
||||
SHADOW_OF_THE_STORM("Shadow of the Storm"),
|
||||
SHEEP_HERDER("Sheep Herder"),
|
||||
SHILO_VILLAGE("Shilo Village"),
|
||||
A_SOULS_BANE("A Soul's Bane"),
|
||||
SPIRITS_OF_THE_ELID("Spirits of the Elid"),
|
||||
SWAN_SONG("Swan Song"),
|
||||
TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio"),
|
||||
A_TAIL_OF_TWO_CATS("A Tail of Two Cats"),
|
||||
TEARS_OF_GUTHIX("Tears of Guthix"),
|
||||
TEMPLE_OF_IKOV("Temple of Ikov"),
|
||||
THRONE_OF_MISCELLANIA("Throne of Miscellania"),
|
||||
THE_TOURIST_TRAP("The Tourist Trap"),
|
||||
WITCHS_HOUSE("Witch's House"),
|
||||
TREE_GNOME_VILLAGE("Tree Gnome Village"),
|
||||
TRIBAL_TOTEM("Tribal Totem"),
|
||||
TROLL_ROMANCE("Troll Romance"),
|
||||
TROLL_STRONGHOLD("Troll Stronghold"),
|
||||
UNDERGROUND_PASS("Underground Pass"),
|
||||
WANTED("Wanted!"),
|
||||
WATCHTOWER("Watchtower"),
|
||||
COLD_WAR("Cold War"),
|
||||
THE_FREMENNIK_ISLES("The Fremennik Isles"),
|
||||
TOWER_OF_LIFE("Tower of Life"),
|
||||
THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery"),
|
||||
WHAT_LIES_BELOW("What Lies Below"),
|
||||
OLAFS_QUEST("Olaf's Quest"),
|
||||
ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M"),
|
||||
DREAM_MENTOR("Dream Mentor"),
|
||||
GRIM_TALES("Grim Tales"),
|
||||
KINGS_RANSOM("King's Ransom"),
|
||||
THE_PATH_OF_GLOUPHRIE("The Path of Glouphrie"),
|
||||
BACK_TO_MY_ROOTS("Back to my Roots"),
|
||||
LAND_OF_THE_GOBLINS("Land of the Goblins"),
|
||||
DEALING_WITH_SCABARAS("Dealing with Scabaras"),
|
||||
WOLF_WHISTLE("Wolf Whistle"),
|
||||
AS_A_FIRST_RESORT("As a First Resort..."),
|
||||
CATAPULT_CONSTRUCTION("Catapult Construction"),
|
||||
KENNITHS_CONCERNS("Kennith's Concerns"),
|
||||
LEGACY_OF_SEERGAZE("Legacy of Seergaze"),
|
||||
PERILS_OF_ICE_MOUNTAIN("Perils of Ice Mountain"),
|
||||
TOKTZ_KET_DILL("TokTz-Ket-Dill"),
|
||||
SMOKING_KILLS("Smoking Kills"),
|
||||
ROCKING_OUT("Rocking Out"),
|
||||
SPIRIT_OF_SUMMER("Spirit of Summer"),
|
||||
MEETING_HISTORY("Meeting History"),
|
||||
ALL_FIRED_UP("All Fired Up"),
|
||||
SUMMERS_END("Summer's End"),
|
||||
DEFENDER_OF_VARROCK("Defender of Varrock"),
|
||||
SWEPT_AWAY("Swept Away"),
|
||||
WHILE_GUTHIX_SLEEPS("While Guthix Sleeps"),
|
||||
IN_PYRE_NEED("In Pyre Need"),
|
||||
TEST_QUEST("Test Quest");
|
||||
|
||||
override fun toString(): String {
|
||||
return questName
|
||||
}
|
||||
}
|
||||
|
|
@ -30,36 +30,36 @@ public enum Consumables {
|
|||
HERRING(new Food(new int[] {347}, new HealingEffect(5))),
|
||||
MACKEREL(new Food(new int[] {355}, new HealingEffect(6))),
|
||||
ROAST_BIRD_MEAT(new Food(new int[] {9980}, new HealingEffect(6))),
|
||||
THIN_SNAIL(new Food(new int[] {3369}, new HealingEffect(5))),
|
||||
THIN_SNAIL(new Food(new int[] {3369}, new RandomHealthEffect(5, 7))),
|
||||
TROUT(new Food(new int[] {333}, new HealingEffect(7))),
|
||||
SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new HealingEffect(7))),
|
||||
SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new RandomHealthEffect(7, 11))),
|
||||
SPIDER_ON_SHAFT(new Food(new int[] {6299}, new HealingEffect(7))),
|
||||
ROAST_RABBIT(new Food(new int[] {7223}, new HealingEffect(7))),
|
||||
LEAN_SNAIL(new Food(new int[] {3371}, new HealingEffect(8))),
|
||||
LEAN_SNAIL(new Food(new int[] {3371}, new RandomHealthEffect(6, 8))),
|
||||
COD(new Food(new int[] {339}, new HealingEffect(7))),
|
||||
PIKE(new Food(new int[] {351}, new HealingEffect(8))),
|
||||
ROAST_BEAST_MEAT(new Food(new int[] {9988}, new HealingEffect(8))),
|
||||
COOKED_CRAB_MEAT(new Food(new int[] {7521, 7523, 7524, 7525, 7526}, new HealingEffect(2))),
|
||||
FAT_SNAIL(new Food(new int[] {3373}, new HealingEffect(9))),
|
||||
FAT_SNAIL(new Food(new int[] {3373}, new RandomHealthEffect(7, 9))),
|
||||
SALMON(new Food(new int[] {329}, new HealingEffect(9))),
|
||||
SLIMY_EEL(new Food(new int[] {3381}, new HealingEffect(6))),
|
||||
SLIMY_EEL(new Food(new int[] {3381}, new RandomHealthEffect(6, 10))),
|
||||
TUNA(new Food(new int[] {361}, new HealingEffect(10))),
|
||||
COOKED_KARAMBWAN(new Food(new int[] {3144}, new HealingEffect(18)), true),
|
||||
COOKED_CHOMPY(new Food(new int[] {2878}, new HealingEffect(10))),
|
||||
RAINBOW_FISH(new Food(new int[] {10136}, new HealingEffect(11))),
|
||||
CAVE_EEL(new Food(new int[] {5003}, new HealingEffect(7))),
|
||||
CAVE_EEL(new Food(new int[] {5003}, new RandomHealthEffect(8, 12))),
|
||||
LOBSTER(new Food(new int[] {379}, new HealingEffect(12))),
|
||||
COOKED_JUBBLY(new Food(new int[] {7568}, new HealingEffect(15))),
|
||||
BASS(new Food(new int[] {365}, new HealingEffect(13))),
|
||||
SWORDFISH(new Food(new int[] {373}, new HealingEffect(14))),
|
||||
LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(14))),
|
||||
LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(11))),
|
||||
MONKFISH(new Food(new int[] {7946}, new HealingEffect(16))),
|
||||
SHARK(new Food(new int[] {385}, new HealingEffect(20))),
|
||||
SEA_TURTLE(new Food(new int[] {397}, new HealingEffect(21))),
|
||||
MANTA_RAY(new Food(new int[] {391}, new HealingEffect(22))),
|
||||
KARAMBWANJI(new Food(new int[] {3151}, new HealingEffect(3))),
|
||||
STUFFED_SNAKE(new Food(new int[] {7579}, new HealingEffect(20), "You eat the stuffed snake-it's quite a meal! It tastes like chicken.")),
|
||||
CRAYFISH(new Food(new int[] {13433}, new HealingEffect(2))),
|
||||
CRAYFISH(new Food(new int[] {13433}, new HealingEffect(1))),
|
||||
GIANT_FROG_LEGS(new Food(new int [] {4517}, new HealingEffect(6))),
|
||||
|
||||
/** Breads */
|
||||
|
|
@ -111,7 +111,7 @@ public enum Consumables {
|
|||
|
||||
/** Vegetables */
|
||||
POTATO(new Food(new int[] {1942}, new HealingEffect(1), "You eat the potato. Yuck!")),
|
||||
BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(2))),
|
||||
BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(4))),
|
||||
SPICY_SAUCE(new Food(new int[] {7072, 1923}, new HealingEffect(2))),
|
||||
CHILLI_CON_CARNE(new Food(new int[] {7062, 1923}, new HealingEffect(5))),
|
||||
SCRAMBLED_EGG(new Food(new int[] {7078, 1923}, new HealingEffect(5))),
|
||||
|
|
@ -128,8 +128,8 @@ public enum Consumables {
|
|||
MUSHROOM_POTATO(new Food(new int[] {7058}, new HealingEffect(20))),
|
||||
TUNA_AND_CORN(new Food(new int[] {7068, 1923}, new HealingEffect(13))),
|
||||
TUNA_POTATO(new Food(new int[] {7060}, new HealingEffect(22))),
|
||||
ONION(new Food(new int[] {1957}, new HealingEffect(2), "It's always sad to see a grown man/woman cry.")),
|
||||
CABBAGE(new Food(new int[] {1965}, new HealingEffect(2), "You eat the cabbage. Yuck!")),
|
||||
ONION(new Food(new int[] {1957}, new HealingEffect(1), "It's always sad to see a grown man/woman cry.")),
|
||||
CABBAGE(new Food(new int[] {1965}, new HealingEffect(1), "You eat the cabbage. Yuck!")),
|
||||
DRAYNOR_CABBAGE(new Food(new int[] {1967}, new DraynorCabbageEffect(), "You eat the cabbage.", "It seems to taste nicer than normal.")),
|
||||
EVIL_TURNIP(new Food(new int[] {12134, 12136, 12138}, new HealingEffect(6))),
|
||||
SPINACH_ROLL(new Food(new int[] {1969}, new HealingEffect(2))),
|
||||
|
|
@ -147,7 +147,7 @@ public enum Consumables {
|
|||
ORANGE(new Food(new int[] {2108}, new HealingEffect(2))),
|
||||
ORANGE_CHUNKS(new Food(new int[] {2110}, new HealingEffect(2))),
|
||||
ORANGE_SLICES(new Food(new int[] {2112}, new HealingEffect(2))),
|
||||
PAPAYA_FRUIT(new Food(new int[] {5972}, new HealingEffect(2))),
|
||||
PAPAYA_FRUIT(new Food(new int[] {5972}, new MultiEffect(new EnergyEffect(5), new HealingEffect(8)))),
|
||||
TENTI_PINEAPPLE(new FakeConsumable(1851, new String[] {"Try using a knife to slice it into pieces."})),
|
||||
PINEAPPLE(new FakeConsumable(2114, new String[] {"Try using a knife to slice it into pieces."})),
|
||||
PINEAPPLE_CHUNKS(new Food(new int[] {2116}, new HealingEffect(2))),
|
||||
|
|
@ -169,8 +169,8 @@ public enum Consumables {
|
|||
STRANGE_FRUIT(new Food(new int[] {464}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(30)))),
|
||||
|
||||
/** Gnome Cooking */
|
||||
TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(12))),
|
||||
PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(12))),
|
||||
TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(8))),
|
||||
PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(8))),
|
||||
SPICY_CRUNCHIES(new Food(new int[] {2213}, new HealingEffect(7))),
|
||||
PREMADE_SY_CRUNCH(new Food(new int[] {2241}, new HealingEffect(7))),
|
||||
WORM_CRUNCHIES(new Food(new int[] {2205}, new HealingEffect(8))),
|
||||
|
|
@ -307,7 +307,7 @@ public enum Consumables {
|
|||
OOMLIE_WRAP(new Food(new int[] {Items.COOKED_OOMLIE_WRAP_2343}, new MultiEffect(new HealingEffect(14), new AchievementEffect(DiaryType.KARAMJA, 2, 2)))),
|
||||
ROE(new Food(new int[]{11324}, new HealingEffect(3))),
|
||||
EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))),
|
||||
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(6))),
|
||||
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))),
|
||||
EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))),
|
||||
FROG_SPAWN(new Food(new int[] {5004}, new RandomHealthEffect(3, 7), "You eat the frogspawn. Yuck.")),
|
||||
|
||||
|
|
@ -319,44 +319,44 @@ public enum Consumables {
|
|||
STRENGTH(new Potion(new int[] {113, 115, 117, 119}, new SkillEffect(Skills.STRENGTH, 3, 0.1))),
|
||||
ATTACK(new Potion(new int[] {2428, 121, 123, 125}, new SkillEffect(Skills.ATTACK, 3, 0.1))),
|
||||
DEFENCE(new Potion(new int[] {2432, 133, 135, 137}, new SkillEffect(Skills.DEFENCE, 3, 0.1))),
|
||||
RANGING(new Potion(new int[] {2444, 169, 171, 173}, new SkillEffect(Skills.RANGE, 3, 0.1))),
|
||||
MAGIC(new Potion(new int[] {3040, 3042, 3044, 3046}, new SkillEffect(Skills.MAGIC, 3, 0.1))),
|
||||
SUPER_STRENGTH(new Potion(new int[] {2440, 157, 159, 161}, new SkillEffect(Skills.STRENGTH, 3, 0.2))),
|
||||
SUPER_ATTACK(new Potion(new int[] {2436, 145, 147, 149}, new SkillEffect(Skills.ATTACK, 3, 0.2))),
|
||||
SUPER_DEFENCE(new Potion(new int[] {2442, 163, 165, 167}, new SkillEffect(Skills.DEFENCE, 3, 0.2))),
|
||||
RANGING(new Potion(new int[] {2444, 169, 171, 173}, new SkillEffect(Skills.RANGE, 4, 0.1))),
|
||||
MAGIC(new Potion(new int[] {3040, 3042, 3044, 3046}, new SkillEffect(Skills.MAGIC, 4, 0))),
|
||||
SUPER_STRENGTH(new Potion(new int[] {2440, 157, 159, 161}, new SkillEffect(Skills.STRENGTH, 5, 0.15))),
|
||||
SUPER_ATTACK(new Potion(new int[] {2436, 145, 147, 149}, new SkillEffect(Skills.ATTACK, 5, 0.15))),
|
||||
SUPER_DEFENCE(new Potion(new int[] {2442, 163, 165, 167}, new SkillEffect(Skills.DEFENCE, 5, 0.15))),
|
||||
ANTIPOISON(new Potion(new int[] {2446, 175, 177, 179}, new AddTimerEffect("poison:immunity", secondsToTicks(90)))),
|
||||
ANTIPOISON_(new Potion(new int[] {5943, 5945, 5947, 5949}, new AddTimerEffect("poison:immunity", minutesToTicks(9)))),
|
||||
ANTIPOISON__(new Potion(new int[] {5952, 5954, 5956, 5958}, new AddTimerEffect("poison:immunity", minutesToTicks(12)))),
|
||||
SUPER_ANTIP(new Potion(new int[] {2448, 181, 183, 185}, new AddTimerEffect("poison:immunity", minutesToTicks(6)))),
|
||||
RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new MultiEffect(new SetAttributeEffect("disease:immunity", 300), new RemoveTimerEffect("disease")))),
|
||||
RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new CureDiseaseEffect())),
|
||||
AGILITY(new Potion(new int[] {3032, 3034, 3036, 3038}, new SkillEffect(Skills.AGILITY, 3, 0))),
|
||||
HUNTER(new Potion(new int[] {9998, 10000, 10002, 10004}, new SkillEffect(Skills.HUNTER, 3, 0))),
|
||||
RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))),
|
||||
SARA_BREW(new Potion(new int[] {6685, 6687, 6689, 6691}, new MultiEffect(new PercentHeal(2, .15), new SkillEffect(Skills.ATTACK, 0, -0.10), new SkillEffect(Skills.STRENGTH, 0, -0.10), new SkillEffect(Skills.MAGIC, 0, -0.10), new SkillEffect(Skills.RANGE, 0, -0.10), new SkillEffect(Skills.DEFENCE, 2, 0.2)))),
|
||||
SARA_BREW(new Potion(new int[] {6685, 6687, 6689, 6691}, new MultiEffect(new PercentHeal(0, .15), new SkillEffect(Skills.ATTACK, 0, -0.10), new SkillEffect(Skills.STRENGTH, 0, -0.10), new SkillEffect(Skills.MAGIC, 0, -0.10), new SkillEffect(Skills.RANGE, 0, -0.10), new SkillEffect(Skills.DEFENCE, 0, 0.25)))),
|
||||
SUMMONING(new Potion(new int[] {12140, 12142, 12144, 12146}, new MultiEffect(new RestoreSummoningSpecial(), new SummoningEffect(7, 0.25)))),
|
||||
COMBAT(new Potion(new int[] {9739, 9741, 9743, 9745}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, .1), new SkillEffect(Skills.ATTACK, 3, .1)))),
|
||||
ENERGY(new Potion(new int[] {3008, 3010, 3012, 3014}, new MultiEffect(new EnergyEffect(10), new HealingEffect(3)))),
|
||||
ENERGY(new Potion(new int[] {3008, 3010, 3012, 3014}, new EnergyEffect(10))),
|
||||
FISHING(new Potion(new int[] {2438, 151, 153, 155}, new SkillEffect(Skills.FISHING, 3, 0))),
|
||||
PRAYER(new Potion(new int[] {2434, 139, 141, 143}, new PrayerEffect(7, 0.25))),
|
||||
SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new MultiEffect(new RestoreEffect(8, 0.25), new PrayerEffect(8, 0.25), new SummoningEffect(8, 0.25)))),
|
||||
ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1), new RandomPrayerEffect(0, 10)))),
|
||||
ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new SetAttributeEffect("fire:immune", 600, true))),
|
||||
SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new RestoreEffect(8, 0.25, true))),
|
||||
ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1)))),
|
||||
ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))),
|
||||
GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))),
|
||||
MAGIC_ESS(new Potion(new int[] {11491, 11489}, new SkillEffect(Skills.MAGIC,3,0))),
|
||||
SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25), new PrayerEffect(8,0.25), new RemoveTimerEffect("poison"), new RemoveTimerEffect("disease")))),
|
||||
SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25, true), new AddTimerEffect("poison:immunity", secondsToTicks(90)), new RemoveTimerEffect("disease")))),
|
||||
SUPER_ENERGY(new Potion(new int[] {3016, 3018, 3020, 3022}, new EnergyEffect(20))),
|
||||
BLAMISH_OIL(new FakeConsumable(1582, new String[] {"You know... I'd really rather not."})),
|
||||
|
||||
/** Barbarian Mixes */
|
||||
PRAYERMIX(new BarbarianMix(new int[] {11465, 11467}, new MultiEffect(new PrayerEffect(7, 0.25), new HealingEffect(6)))),
|
||||
ZAMMY_MIX(new BarbarianMix(new int[] {11521, 11523}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1), new RandomPrayerEffect(0, 10)))),
|
||||
ZAMMY_MIX(new BarbarianMix(new int[] {11521, 11523}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1)))),
|
||||
ATT_MIX(new BarbarianMix(new int[] {11429, 11431}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new HealingEffect(3)))),
|
||||
ANTIP_MIX(new BarbarianMix(new int[] {11433, 11435}, new MultiEffect(new AddTimerEffect("poison:immunity", secondsToTicks(90)), new HealingEffect(3)))),
|
||||
RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new RemoveTimerEffect("disease"), new SetAttributeEffect("disease:immunity", 300), new HealingEffect(3)))),
|
||||
RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new CureDiseaseEffect(), new HealingEffect(3)))),
|
||||
STR_MIX(new BarbarianMix(new int[] {11443, 11441}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0.1), new HealingEffect(3)))),
|
||||
RESTO_MIX(new BarbarianMix(new int[] {11449, 11451}, new MultiEffect(new RestoreEffect(10, 0.3), new HealingEffect(3)))),
|
||||
SUPER_RESTO_MIX(new BarbarianMix(new int [] {11493, 11495}, new MultiEffect(new RestoreEffect(8,0.25), new PrayerEffect(8, 0.25), new SummoningEffect(8, 0.25), new HealingEffect(6)))),
|
||||
ENERGY_MIX(new BarbarianMix(new int[] {11453, 11455}, new MultiEffect(new EnergyEffect(10), new HealingEffect(6)))),
|
||||
ENERGY_MIX(new BarbarianMix(new int[] {11453, 11455}, new MultiEffect(new EnergyEffect(10), new HealingEffect(3)))),
|
||||
DEF_MIX(new BarbarianMix(new int[] {11457, 11459}, new MultiEffect(new SkillEffect(Skills.DEFENCE, 3, 0.1), new HealingEffect(6)))),
|
||||
AGIL_MIX(new BarbarianMix(new int[] {11461, 11463}, new MultiEffect(new SkillEffect(Skills.AGILITY, 3, 0), new HealingEffect(6)))),
|
||||
COMBAT_MIX(new BarbarianMix(new int[] {11445, 11447}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new SkillEffect(Skills.STRENGTH, 3, 0.1), new HealingEffect(6)))),
|
||||
|
|
@ -367,6 +367,7 @@ public enum Consumables {
|
|||
SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))),
|
||||
ANTIDOTE_PLUS_MIX(new BarbarianMix(new int[] {11501, 11503}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(9)), new RandomHealthEffect(3, 7)))),
|
||||
ANTIP_SUPERMIX(new BarbarianMix(new int[] {11473, 11475}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(6)), new RandomHealthEffect(3, 7)))),
|
||||
ANTIFIRE_MIX(new BarbarianMix(new int[] {11505, 11507}, new MultiEffect(new AddTimerEffect("dragonfire:immunity", 600, true), new RandomHealthEffect(3, 7)))),
|
||||
|
||||
/** Stealing creation potions */
|
||||
SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package content.data.consumables.effects
|
||||
|
||||
import core.api.*
|
||||
import core.game.consumable.ConsumableEffect
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.timer.impl.Disease
|
||||
|
||||
class CureDiseaseEffect () : ConsumableEffect() {
|
||||
override fun activate (p: Player) {
|
||||
val existingTimer = getTimer<Disease>(p)
|
||||
if (existingTimer != null) {
|
||||
existingTimer.hitsLeft -= 9
|
||||
if (existingTimer.hitsLeft <= 0) {
|
||||
sendMessage(p, "The disease has been cured.")
|
||||
removeTimer<Disease>(p)
|
||||
}else{
|
||||
sendMessage(p,"You feel slightly better.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,21 +6,37 @@ import core.game.node.entity.skill.Skills;
|
|||
|
||||
public class RestoreEffect extends ConsumableEffect {
|
||||
double base,bonus;
|
||||
boolean all_skills; // Except for hitpoints
|
||||
public RestoreEffect(double base, double bonus){
|
||||
this.base = base;
|
||||
this.bonus = bonus;
|
||||
this.all_skills = false;
|
||||
}
|
||||
|
||||
public RestoreEffect(double base, double bonus, boolean all_skills){
|
||||
this.base = base;
|
||||
this.bonus = bonus;
|
||||
this.all_skills = all_skills;
|
||||
}
|
||||
final int[] SKILLS = new int[] { Skills.DEFENCE, Skills.ATTACK, Skills.STRENGTH, Skills.MAGIC, Skills.RANGE };
|
||||
final int[] ALL_SKILLS = new int[]{
|
||||
Skills.ATTACK,Skills.DEFENCE, Skills.STRENGTH,Skills.RANGE,Skills.PRAYER,Skills.MAGIC, Skills.COOKING,
|
||||
Skills.WOODCUTTING,Skills.FLETCHING,Skills.FISHING,Skills.FIREMAKING,Skills.CRAFTING,Skills.SMITHING,
|
||||
Skills.MINING,Skills.HERBLORE,Skills.AGILITY,Skills.THIEVING,Skills.SLAYER,Skills.FARMING,
|
||||
Skills.RUNECRAFTING,Skills.HUNTER,Skills.CONSTRUCTION,Skills.SUMMONING };
|
||||
@Override
|
||||
public void activate(Player p) {
|
||||
Skills sk = p.getSkills();
|
||||
for(int skill : SKILLS){
|
||||
int[] skills = this.all_skills ? ALL_SKILLS : SKILLS;
|
||||
for(int skill : skills){
|
||||
int statL = sk.getStaticLevel(skill);
|
||||
int boost = (int) (base + (statL * bonus));
|
||||
int curL = sk.getLevel(skill);
|
||||
if(curL < statL){
|
||||
int boost = (int) (base + (statL * bonus));
|
||||
p.getSkills().updateLevel(skill, boost, statL);
|
||||
}
|
||||
if (skill == Skills.PRAYER)
|
||||
p.getSkills().incrementPrayerPoints(boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ class ChampionChallengeListener : InteractionListener, MapArea {
|
|||
)
|
||||
|
||||
private val PORTCULLIS = Scenery.PORTCULLIS_10553
|
||||
private val LADDER = Scenery.LADDER_10554
|
||||
private val CHAMPION_STATUE_CLOSED = Scenery.CHAMPION_STATUE_10556
|
||||
private val CHAMPION_STATUE_OPEN = Scenery.CHAMPION_STATUE_10557
|
||||
private val TRAPDOOR_CLOSED = Scenery.TRAPDOOR_10558
|
||||
|
|
@ -124,6 +123,13 @@ class ChampionChallengeListener : InteractionListener, MapArea {
|
|||
private val ARENA_ZONE = 12696
|
||||
|
||||
override fun defineListeners() {
|
||||
// Champion's Guild Basement Ladder to Main Floor
|
||||
addClimbDest(Location(3190, 9758, 0), Location(3190, 3356, 0))
|
||||
// Champion Statue Ladder to Arena
|
||||
addClimbDest(Location(3184, 9758, 0), Location(3182, 9758, 0))
|
||||
// Arena Ladder to Champion's Guild Basement
|
||||
addClimbDest(Location(3183, 9758, 0), Location(3185, 9758, 0))
|
||||
|
||||
on(LARXUS, IntType.NPC, "talk-to") { player, _ ->
|
||||
openDialogue(player, LarxusDialogue(false))
|
||||
return@on true
|
||||
|
|
@ -134,18 +140,18 @@ class ChampionChallengeListener : InteractionListener, MapArea {
|
|||
return@on true
|
||||
}
|
||||
|
||||
on(TRAPDOOR_CLOSED, IntType.SCENERY, "open") { _, node ->
|
||||
replaceScenery(node.asScenery(), TRAPDOOR_OPEN, 100, node.location)
|
||||
return@on true
|
||||
}
|
||||
|
||||
onUseWith(IntType.NPC, ChampionScrollsDropHandler.SCROLLS, NPCs.LARXUS_3050) { player, _, _ ->
|
||||
openDialogue(player, LarxusDialogue(true))
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
on(TRAPDOOR_CLOSED, IntType.SCENERY, "open") { _, node ->
|
||||
replaceScenery(node.asScenery(), TRAPDOOR_OPEN, 100, node.location)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(TRAPDOOR_OPEN, IntType.SCENERY, "close") { _, node ->
|
||||
replaceScenery(node.asScenery(), TRAPDOOR_CLOSED, 100, node.location)
|
||||
replaceScenery(node.asScenery(), TRAPDOOR_CLOSED, -1, node.location)
|
||||
return@on true
|
||||
}
|
||||
|
||||
|
|
@ -154,15 +160,6 @@ class ChampionChallengeListener : InteractionListener, MapArea {
|
|||
return@on true
|
||||
}
|
||||
|
||||
on(LADDER, IntType.SCENERY, "climb-up") { player, _ ->
|
||||
teleport(player, Location.create(3185, 9758, 0))
|
||||
return@on true
|
||||
}
|
||||
on(CHAMPION_STATUE_OPEN, IntType.SCENERY, "climb-down") { player, _ ->
|
||||
teleport(player, Location.create(3182, 9758, 0))
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(PORTCULLIS, IntType.SCENERY, "open") { player, node ->
|
||||
if (player.getAttribute("championsarena:start", false) == false) {
|
||||
sendNPCDialogue(player, NPCs.LARXUS_3050, "You need to arrange a challenge with me before you enter the arena.")
|
||||
|
|
@ -229,4 +226,4 @@ class ChampionChallengeListener : InteractionListener, MapArea {
|
|||
ZoneRestriction.RANDOM_EVENTS
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,12 +11,13 @@ import core.ServerStore.Companion.getString
|
|||
|
||||
import content.global.bots.ShootingStarBot
|
||||
import core.game.world.repository.Repository
|
||||
import core.tools.RandomFunction
|
||||
|
||||
/**
|
||||
* Represents a shooting star object (Only ever initialized once) (ideally)
|
||||
* @author Ceikry
|
||||
*/
|
||||
class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()){
|
||||
class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()) {
|
||||
val crash_locations = mapOf(
|
||||
"East of Dark Wizards' Tower" to Location.create(2925, 3339, 0), // East of Dark Wizards' Tower
|
||||
"Crafting Guild" to Location.create(2940, 3280, 0), // Crafting Guild Mine
|
||||
|
|
@ -26,12 +27,12 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
"Brimhaven mining site" to Location.create(2743, 3143, 0), // Brimhaven mining site
|
||||
"South Crandor mining site" to Location.create(2822, 3239, 0), // South Crandor mining site (requires Dragon Slayer)
|
||||
"Karamja mining site" to Location.create(2854, 3032, 0), // Karamja mining site
|
||||
"Shilo Village mining site" to Location.create(2826, 2997, 0), // Shilo Village mining site/Gem rocks
|
||||
"Shilo Village mining site" to Location.create(2826, 2997, 0), // Shilo Village mining site/Gem rocks (requires Shilo Village prereqs)
|
||||
"Relleka mining site" to Location.create(2682, 3700, 0), // Rellekka mining site
|
||||
"Jatizso mine" to Location.create(2393, 3815, 0), //Jatiszo mining site (requires Fremennik Trials)
|
||||
//"Lunar Isle mine" to Location.create(2140, 3939, 0), // Lunar Isle mine (requires Lunar Diplomacy?)
|
||||
//"Miscellania coal mine" to Location.create(2529, 3887, 0), // Miscellania coal mine (requires Fremennik Trials)
|
||||
//"Neitiznot runite mine" to Location.create(2376, 3835, 0), // Near the Neitiznot runite mine (requires Fremennik Trials) currently inaccessible as bridge does not work
|
||||
"Jatizso mine" to Location.create(2393, 3815, 0), //Jatiszo mining site (requires Fremennik Isles prereqs)
|
||||
"Lunar Isle mine" to Location.create(2140, 3939, 0), // Lunar Isle mine (requires Lunar Diplomacy prereqs)
|
||||
"Miscellania coal mine" to Location.create(2529, 3887, 0), // Miscellania coal mine (requires The Fremennik Trials)
|
||||
//"Neitiznot runite mine" to Location.create(2376, 3835, 0), // Near the Neitiznot runite mine (requires Fremennik Isles prereqs) currently inaccessible as bridge does not work
|
||||
"Ardougne mining site" to Location.create(2600, 3232, 0), // Ardougne mining site (Monastery)
|
||||
"Ardougne eastern mine" to Location.create(2706, 3334, 0), // Ardougne mining site (Legends Guild)
|
||||
"Kandarin Coal trucks" to Location.create(2589, 3485, 0), // Kandarin Coal trucks
|
||||
|
|
@ -48,11 +49,11 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
"South-west Varrock mine" to Location.create(3176, 3362, 0), // South-west Varrock mine / Champion's Guild mine
|
||||
"Varrock east bank" to Location.create(3259, 3407, 0), // Varrock east bank / Rune shop
|
||||
"Lumbridge Swamp south-east mine" to Location.create(3227, 3150, 0), // Lumbridge Swamp south-east mine
|
||||
//"Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires Quest to enter)
|
||||
//"Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter)
|
||||
"Canifis Bank" to Location.create(3504, 3487, 0), // Canifis bank
|
||||
"Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires Quest to enter but is currently accessible for Slayer)
|
||||
"Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires quest to enter but is currently accessible for Slayer)
|
||||
"Gnome stronghold Bank" to Location.create(2460, 3432, 0), // Gnome stronghold bank
|
||||
"Lletya bank" to Location.create(2329, 3163, 0), // Lletya bank (requires Roving Elves?)
|
||||
"Lletya bank" to Location.create(2329, 3163, 0), // Lletya bank (requires MEP1 prereqs)
|
||||
"Piscatoris mining site" to Location.create(2336, 3636, 0), // Piscatoris mining site
|
||||
"North Edgeville mining site" to Location.create(3101, 3569, 0), // Wilderness Steel mine / Zamorak mage mine
|
||||
"Southern wilderness mine" to Location.create(3025, 3591, 0), // Wilderness skeleton mine
|
||||
|
|
@ -79,22 +80,15 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
* Degrades a ShootingStar (or removes the starObject and spawns a Star Sprite if it's the last star)
|
||||
*/
|
||||
fun degrade() {
|
||||
if(level.ordinal == 0){
|
||||
selfBots.filter { it.isMining() }.forEach { it.sleep() }
|
||||
SceneryBuilder.remove(starObject)
|
||||
isSpawned = false
|
||||
starSprite.location = starObject.location
|
||||
starSprite.init()
|
||||
spriteSpawned = true
|
||||
ShootingStarPlugin.getStoreFile().clear()
|
||||
if(level.ordinal == 0) {
|
||||
spawnSprite()
|
||||
return
|
||||
}
|
||||
level = getNextType()
|
||||
maxDust = level.totalStardust
|
||||
dustLeft = level.totalStardust
|
||||
|
||||
ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered
|
||||
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft
|
||||
|
||||
val newStar = Scenery(level.objectId, starObject.location)
|
||||
SceneryBuilder.replace(starObject, newStar)
|
||||
|
|
@ -110,7 +104,6 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
*/
|
||||
fun fire() {
|
||||
SceneryBuilder.remove(starObject)
|
||||
rebuildVars()
|
||||
clearSprite()
|
||||
SceneryBuilder.add(starObject)
|
||||
if(!isSpawned) {
|
||||
|
|
@ -123,37 +116,54 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
}
|
||||
isSpawned = true
|
||||
Repository.sendNews("A shooting star level ${level.ordinal + 1} just crashed near ${location}!")
|
||||
ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
|
||||
ShootingStarPlugin.getStoreFile()["location"] = location
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered
|
||||
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuilds some of the variables with new information.
|
||||
*/
|
||||
fun rebuildVars(){
|
||||
if(firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()){
|
||||
level = ShootingStarType.values()[ShootingStarPlugin.getStoreFile().getInt("level")]
|
||||
location = ShootingStarPlugin.getStoreFile().getString("location")
|
||||
isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered")
|
||||
} else {
|
||||
level = ShootingStarType.values().random()
|
||||
location = crash_locations.entries.random().key
|
||||
isDiscovered = false
|
||||
// Defaults
|
||||
var levelOrd = RandomFunction.random(9)
|
||||
level = ShootingStarType.values()[levelOrd]
|
||||
location = crash_locations.entries.random().key
|
||||
isDiscovered = false
|
||||
dustLeft = level.totalStardust
|
||||
ticks = 0
|
||||
spriteSpawned = false
|
||||
|
||||
if (firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()) {
|
||||
// Replace default with stored values, if any
|
||||
levelOrd = ShootingStarPlugin.getStoreFile().getInt("level", levelOrd)
|
||||
level = ShootingStarType.values()[levelOrd]
|
||||
location = ShootingStarPlugin.getStoreFile().getString("location", location)
|
||||
isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered", false)
|
||||
dustLeft = ShootingStarPlugin.getStoreFile().getInt("dustLeft", dustLeft)
|
||||
ticks = ShootingStarPlugin.getStoreFile().getInt("ticks", ticks)
|
||||
spriteSpawned = ShootingStarPlugin.getStoreFile().getBoolean("spriteSpawned", false)
|
||||
}
|
||||
|
||||
maxDust = level.totalStardust
|
||||
dustLeft = level.totalStardust
|
||||
starObject = Scenery(level.objectId, crash_locations.get(location))
|
||||
}
|
||||
|
||||
ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
|
||||
ShootingStarPlugin.getStoreFile()["location"] = location
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = false
|
||||
|
||||
ticks = 0
|
||||
firstStar = false
|
||||
fun spawnSprite() {
|
||||
selfBots.filter { it.isMining() }.forEach { it.sleep() }
|
||||
SceneryBuilder.remove(starObject)
|
||||
isSpawned = false
|
||||
starSprite.location = starObject.location
|
||||
starSprite.init()
|
||||
spriteSpawned = true
|
||||
ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned
|
||||
}
|
||||
|
||||
fun clearSprite() {
|
||||
starSprite.clear()
|
||||
spriteSpawned = false
|
||||
ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -161,6 +171,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
|
|||
*/
|
||||
fun decDust() {
|
||||
if(--dustLeft <= 0) degrade()
|
||||
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: Shootin
|
|||
player.sendMessage("You have ${player.skills.experienceMultiplier * player.getAttribute("shooting-star:bonus-xp", 0).toDouble()} bonus xp towards mining stardust.")
|
||||
ShootingStarPlugin.submitScoreBoard(player)
|
||||
star.isDiscovered = true
|
||||
ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered
|
||||
return player.skills.getLevel(Skills.MINING) >= star.miningLevel
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ import core.ServerStore.Companion.getBoolean
|
|||
import core.game.dialogue.DialogueFile
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.tools.SystemLogger
|
||||
import core.game.system.command.Privilege
|
||||
import core.game.world.GameWorld
|
||||
import core.tools.Log
|
||||
import core.tools.secondsToTicks
|
||||
import content.data.Quests
|
||||
|
||||
class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener {
|
||||
override fun login(player: Player) {
|
||||
|
|
@ -27,14 +27,30 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
override fun tick() {
|
||||
++star.ticks
|
||||
|
||||
// Check if the current star sprite should expire
|
||||
val maxDelay = tickDelay + (tickDelay / 3)
|
||||
if(star.ticks > maxDelay && star.spriteSpawned){
|
||||
star.clearSprite()
|
||||
}
|
||||
|
||||
if ((star.ticks >= tickDelay && !star.spriteSpawned) || (!star.isSpawned && !star.spriteSpawned)) {
|
||||
if (star.firstStar && !star.isSpawned && !star.spriteSpawned) {
|
||||
// Apparently, the server has only just booted
|
||||
star.rebuildVars()
|
||||
if (star.spriteSpawned) {
|
||||
star.spawnSprite()
|
||||
} else {
|
||||
star.fire()
|
||||
}
|
||||
star.firstStar = false
|
||||
}
|
||||
|
||||
// Check if it's time to fire a new one
|
||||
if (star.ticks >= tickDelay && !star.spriteSpawned) {
|
||||
star.rebuildVars()
|
||||
star.fire()
|
||||
}
|
||||
|
||||
getStoreFile()["ticks"] = star.ticks
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
|
|
@ -66,35 +82,52 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
return@on true
|
||||
}
|
||||
|
||||
val condition: (Player) -> Boolean = when(star.location.toLowerCase()){
|
||||
"canifis bank" -> { p -> hasRequirement(p, "Priest in Peril") }
|
||||
//"Burgh de Rott bank" -> { p -> p.questRepository.isComplete("Priest in Peril")} // for now, require this as it is in Morytania. remove when appropriate quests added - Crash
|
||||
"crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40) }
|
||||
"lletya bank" -> {p -> hasRequirement(p, "Mourning's End Part I") }
|
||||
"jatizso mine" -> {p -> hasRequirement(player, "Fremennik Trials") }
|
||||
"south crandor mining site" -> {p -> hasRequirement(p, "Dragon Slayer") }
|
||||
"shilo village mining site" -> {p -> hasRequirement(p, "Shilo Village") }
|
||||
"mos le'harmless bank" -> {p -> hasRequirement(p, "Cabin Fever") }
|
||||
else -> {_ -> true}
|
||||
class RingDialogue(val star: ShootingStar) : DialogueFile() {
|
||||
val shouldWarn = when (star.location) {
|
||||
"North Edgeville mining site",
|
||||
"Southern wilderness mine",
|
||||
"Wilderness hobgoblin mine",
|
||||
"Pirates' Hideout mine",
|
||||
"Lava Maze mining site",
|
||||
"Mage Arena bank" -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
fun teleportToStar(player: Player) {
|
||||
val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) {
|
||||
"canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")}
|
||||
//"burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} //disabled: crash
|
||||
"crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)}
|
||||
"lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)}
|
||||
"jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)}
|
||||
"south crandor mining site" -> {p -> hasRequirement(p, Quests.DRAGON_SLAYER)}
|
||||
"shilo village mining site" -> {p -> hasRequirement(p, Quests.SHILO_VILLAGE)}
|
||||
"mos le'harmless bank" -> {p -> hasRequirement(p, Quests.CABIN_FEVER)} //needs to be updated to check for completion when the quest releases; https://runescape.wiki/w/Mos_Le%27Harmless?oldid=913025
|
||||
"lunar isle mine" -> {p -> hasRequirement(p, Quests.LUNAR_DIPLOMACY)}
|
||||
"miscellania coal mine" -> {p -> requireQuest(p, Quests.THE_FREMENNIK_TRIALS, "to access this.")}
|
||||
//"neitiznot runite mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} //disabled: currently not reachable
|
||||
else -> {_ -> true}
|
||||
}
|
||||
if (!condition.invoke(player)) {
|
||||
sendDialogue(player,"Magical forces prevent your teleportation.")
|
||||
} else if (teleport(player, star.crash_locations[star.location]!!.transform(0, -1, 0), TeleportManager.TeleportType.MINIGAME)) {
|
||||
getRingStoreFile()[player.username.toLowerCase()] = true
|
||||
}
|
||||
}
|
||||
when (stage) {
|
||||
0 -> dialogue(if (star.spriteSpawned) "The star sprite has already been freed." else "The star sprite is still trapped.").also { if (shouldWarn) stage++ else stage += 2 }
|
||||
1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ }
|
||||
2 -> player.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ }
|
||||
3 -> when (buttonID) {
|
||||
1 -> end().also { teleportToStar(player) }
|
||||
2 -> end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!condition.invoke(player)){
|
||||
sendDialogue(player, "Magical forces prevent your teleportation.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
val shouldWarn = when(star.location){
|
||||
"North Edgeville mining site",
|
||||
"Southern wilderness mine",
|
||||
"Wilderness hobgoblin mine",
|
||||
"Pirates' Hideout mine",
|
||||
"Lava Maze mining site",
|
||||
"Mage Arena bank" -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
openDialogue(player, RingDialogue(shouldWarn, star))
|
||||
|
||||
openDialogue(player, RingDialogue(star))
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
|
@ -105,6 +138,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
}
|
||||
|
||||
define("submit", Privilege.ADMIN) { _, _ ->
|
||||
star.rebuildVars()
|
||||
star.fire()
|
||||
}
|
||||
|
||||
|
|
@ -119,26 +153,6 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
|
|||
|
||||
private data class ScoreboardEntry(val player: String, val time: Int)
|
||||
|
||||
private class RingDialogue(val shouldWarn: Boolean, val star: ShootingStar) : DialogueFile(){
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (stage) {
|
||||
0 -> dialogue(if (star.spriteSpawned) "The star sprite has already been freed." else "The star sprite is still trapped.").also { if (shouldWarn) stage++ else stage += 2 }
|
||||
1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ }
|
||||
2 -> player!!.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ }
|
||||
3 -> when (buttonID) {
|
||||
1 -> teleport(player!!, star).also { end() }
|
||||
2 -> end()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun teleport(player: Player, star: ShootingStar){
|
||||
if (teleport(player, star.crash_locations[star.location]!!.transform(0, -1, 0), TeleportManager.TeleportType.MINIGAME)) {
|
||||
getRingStoreFile()[player.username.toLowerCase()] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val star = ShootingStar()
|
||||
private val tickDelay = if(GameWorld.settings?.isDevMode == true) 200 else 25000
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ public abstract class ClueScrollPlugin extends MapZone implements Plugin<Object>
|
|||
int hasAmt = 0;
|
||||
for (int i = 0; i < equipment.length; i++) {
|
||||
for (int k = 0; k < equipment[i].length; k++) {
|
||||
if (player.getEquipment().contains(equipment[i][k], 1)) {
|
||||
if (player.getEquipment().contains(equipment[i][k], 1) || player.costumeRoomBank.contains(equipment[i][k], 1)) {
|
||||
hasAmt++;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
28
Server/src/main/content/global/ame/KidnapHelper.kt
Normal file
28
Server/src/main/content/global/ame/KidnapHelper.kt
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package content.global.ame
|
||||
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager.TeleportType
|
||||
import core.game.world.map.Location
|
||||
|
||||
fun kidnapPlayer(player: Player, loc: Location, type: TeleportType) {
|
||||
setAttribute(player, "kidnapped-by-random", true)
|
||||
if (getAttribute(player, "/save:original-loc", null) == null) {
|
||||
setAttribute(player, "/save:original-loc", player.location)
|
||||
}
|
||||
teleport(player, loc, type)
|
||||
}
|
||||
|
||||
fun returnPlayer(player: Player) {
|
||||
// Prevent returning more than once and sending the player back to HOME_LOCATION
|
||||
if (getAttribute<Location?>(player, "kidnapped-by-random", null) == null) {
|
||||
return
|
||||
}
|
||||
|
||||
player.locks.unlockTeleport()
|
||||
val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0))
|
||||
teleport(player, destination)
|
||||
unlock(player)
|
||||
removeAttributes(player, "/save:original-loc", "kidnapped-by-random")
|
||||
}
|
||||
|
|
@ -3,9 +3,15 @@ package content.global.ame
|
|||
import content.global.ame.events.MysteriousOldManNPC
|
||||
import core.api.playGlobalAudio
|
||||
import core.api.poofClear
|
||||
import core.api.sendMessage
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.combat.CombatStyle
|
||||
import core.game.node.entity.impl.PulseType
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.agg.AggressiveBehavior
|
||||
import core.game.node.entity.npc.agg.AggressiveHandler
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
|
|
@ -13,10 +19,11 @@ import core.game.world.map.RegionManager
|
|||
import core.game.world.map.path.Pathfinder
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.integrations.discord.Discord
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.tools.secondsToTicks
|
||||
import core.tools.ticksToCycles
|
||||
import org.rs09.consts.Sounds
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.min
|
||||
import kotlin.random.Random
|
||||
import kotlin.reflect.full.createInstance
|
||||
|
||||
|
|
@ -66,7 +73,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
if (!player.getAttribute("random:pause", false)) {
|
||||
ticksLeft--
|
||||
}
|
||||
|
||||
if (!pulseManager.hasPulseRunning() && !finalized) {
|
||||
follow()
|
||||
}
|
||||
|
|
@ -87,6 +93,11 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
location = spawnLocation
|
||||
player.setAttribute("re-npc", this)
|
||||
super.init()
|
||||
super.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() {
|
||||
override fun canSelectTarget(entity: Entity, target: Entity): Boolean {
|
||||
return target == player
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
open fun onTimeUp() {
|
||||
|
|
@ -118,4 +129,19 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
|
|||
}
|
||||
|
||||
abstract fun talkTo(npc: NPC)
|
||||
}
|
||||
|
||||
override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean {
|
||||
if (entity != player) {
|
||||
if (entity is Player) {
|
||||
sendMessage(entity, "It isn't interested in fighting you.") //TODO authentic message
|
||||
}
|
||||
return false
|
||||
}
|
||||
return super.isAttackable(entity, style, message)
|
||||
}
|
||||
|
||||
fun idForCombatLevel(ids: List<Int>, player: Player): Int {
|
||||
val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1
|
||||
return ids[index]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,18 @@ package content.global.ame
|
|||
import org.rs09.consts.Items
|
||||
import content.global.ame.events.MysteriousOldManNPC
|
||||
import content.global.ame.events.certer.CerterNPC
|
||||
import content.global.ame.events.drilldemon.SeargentDamienNPC
|
||||
import content.global.ame.events.drilldemon.SergeantDamienNPC
|
||||
import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC
|
||||
import content.global.ame.events.evilbob.EvilBobNPC
|
||||
import content.global.ame.events.evilchicken.EvilChickenNPC
|
||||
import content.global.ame.events.freakyforester.FreakyForesterNPC
|
||||
import content.global.ame.events.maze.MazeNPC
|
||||
import content.global.ame.events.genie.GenieNPC
|
||||
import content.global.ame.events.pillory.PilloryNPC
|
||||
import content.global.ame.events.rickturpentine.RickTurpentineNPC
|
||||
import content.global.ame.events.rivertroll.RiverTrollRENPC
|
||||
import content.global.ame.events.rockgolem.RockGolemRENPC
|
||||
import content.global.ame.events.quizmaster.QuizMasterNPC
|
||||
import content.global.ame.events.sandwichlady.SandwichLadyRENPC
|
||||
import content.global.ame.events.shade.ShadeRENPC
|
||||
import content.global.ame.events.strangeplant.StrangePlantNPC
|
||||
|
|
@ -43,7 +46,8 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
|
|||
WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,0.1),
|
||||
WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1)
|
||||
)),
|
||||
DRILL_DEMON(npc = SeargentDamienNPC()),
|
||||
MAZE(npc = MazeNPC()),
|
||||
DRILL_DEMON(npc = SergeantDamienNPC()),
|
||||
EVIL_CHICKEN(npc = EvilChickenNPC()),
|
||||
STRANGE_PLANT(npc = StrangePlantNPC()),
|
||||
SWARM(npc = SwarmNPC()),
|
||||
|
|
@ -52,7 +56,9 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
|
|||
RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot),
|
||||
SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"),
|
||||
FREAKY_FORESTER(npc = FreakyForesterNPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
|
||||
PILLORY(npc = PilloryNPC(), skillIds = intArrayOf(Skills.THIEVING)),
|
||||
TREE_SPIRIT(npc = TreeSpiritRENPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
|
||||
QUIZ_MASTER(npc = QuizMasterNPC()),
|
||||
RIVER_TROLL(RiverTrollRENPC(), skillIds = intArrayOf(Skills.FISHING)),
|
||||
ROCK_GOLEM(RockGolemRENPC(), skillIds = intArrayOf(Skills.MINING)),
|
||||
SHADE(ShadeRENPC(), skillIds = intArrayOf(Skills.PRAYER)),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
package content.global.ame.events
|
||||
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.npc.NPCBehavior
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class HostileRandomEventBehavior : NPCBehavior(
|
||||
NPCs.EVIL_CHICKEN_2463, NPCs.EVIL_CHICKEN_2464, NPCs.EVIL_CHICKEN_2465, NPCs.EVIL_CHICKEN_2466, NPCs.EVIL_CHICKEN_2467, NPCs.EVIL_CHICKEN_2468,
|
||||
NPCs.RIVER_TROLL_391, NPCs.RIVER_TROLL_392, NPCs.RIVER_TROLL_393, NPCs.RIVER_TROLL_394, NPCs.RIVER_TROLL_395, NPCs.RIVER_TROLL_396,
|
||||
NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418,
|
||||
NPCs.SHADE_425, NPCs.SHADE_426, NPCs.SHADE_427, NPCs.SHADE_428, NPCs.SHADE_429, NPCs.SHADE_430, NPCs.SHADE_431,
|
||||
NPCs.TREE_SPIRIT_438, NPCs.TREE_SPIRIT_439, NPCs.TREE_SPIRIT_440, NPCs.TREE_SPIRIT_441, NPCs.TREE_SPIRIT_442, NPCs.TREE_SPIRIT_443,
|
||||
NPCs.ZOMBIE_419, NPCs.ZOMBIE_420, NPCs.ZOMBIE_421, NPCs.ZOMBIE_422, NPCs.ZOMBIE_423, NPCs.ZOMBIE_424
|
||||
) {
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return super.getXpMultiplier(self, attacker) / 16.0
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ class DrillDemonListeners : InteractionListener, MapArea {
|
|||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS)
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
|
|
@ -90,4 +90,4 @@ class DrillDemonListeners : InteractionListener, MapArea {
|
|||
setComponentVisibility(entity.asPlayer(), 746, 12, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
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
|
||||
|
|
@ -11,7 +14,6 @@ import org.rs09.consts.NPCs
|
|||
|
||||
object DrillDemonUtils {
|
||||
val DD_KEY_TASK = "/save:drilldemon:task"
|
||||
val DD_KEY_RETURN_LOC = "/save:original-loc"
|
||||
val DD_SIGN_VARP = 531
|
||||
val DD_SIGN_JOG = 0
|
||||
val DD_SIGN_SITUP = 1
|
||||
|
|
@ -23,8 +25,7 @@ object DrillDemonUtils {
|
|||
val DD_NPC = NPCs.SERGEANT_DAMIEN_2790
|
||||
|
||||
fun teleport(player: Player) {
|
||||
setAttribute(player, DD_KEY_RETURN_LOC, player.location)
|
||||
teleport(player, Location.create(3163, 4819, 0))
|
||||
kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT)
|
||||
player.interfaceManager.closeDefaultTabs()
|
||||
setComponentVisibility(player, 548, 69, true)
|
||||
setComponentVisibility(player, 746, 12, true)
|
||||
|
|
@ -63,13 +64,8 @@ object DrillDemonUtils {
|
|||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
unlock(player)
|
||||
teleport(player, getAttribute(player, DD_KEY_RETURN_LOC, Location.create(3222, 3218, 0)))
|
||||
removeAttribute(player, DD_KEY_RETURN_LOC)
|
||||
removeAttribute(player, DD_KEY_TASK)
|
||||
removeAttribute(player, DD_CORRECT_OFFSET)
|
||||
removeAttribute(player, DD_CORRECT_COUNTER)
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, DD_KEY_TASK, DD_CORRECT_OFFSET, DD_CORRECT_COUNTER)
|
||||
player.interfaceManager.openDefaultTabs()
|
||||
setComponentVisibility(player, 548, 69, false)
|
||||
setComponentVisibility(player, 746, 12, false)
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ import core.game.interaction.QueueStrength
|
|||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.tools.secondsToTicks
|
||||
|
||||
class SeargentDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
|
||||
class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat(player.username.capitalize() + "! Drop and give me 20!")
|
||||
sendChat(player.username+ "! Drop and give me 20!")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.ame.events.evilbob
|
||||
|
||||
import content.global.ame.returnPlayer
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.game.dialogue.FacialExpression
|
||||
|
|
@ -8,8 +9,6 @@ import core.game.interaction.InteractionListener
|
|||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.link.emote.Emotes
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
|
|
@ -121,7 +120,7 @@ class EvilBobListeners : InteractionListener, MapArea {
|
|||
}
|
||||
3 -> {
|
||||
sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.")
|
||||
teleport(player, getAttribute(player, EvilBobUtils.prevLocation, Location.create(3222, 3219, 0)))
|
||||
returnPlayer(player)
|
||||
EvilBobUtils.reward(player)
|
||||
EvilBobUtils.cleanup(player)
|
||||
resetAnimator(player)
|
||||
|
|
@ -139,7 +138,7 @@ class EvilBobListeners : InteractionListener, MapArea {
|
|||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS)
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
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
|
||||
|
|
@ -13,10 +16,8 @@ import org.rs09.consts.NPCs
|
|||
import org.rs09.consts.Scenery
|
||||
|
||||
object EvilBobUtils {
|
||||
const val prevLocation = "/save:original-loc"
|
||||
const val eventComplete = "/save:evilbob:eventcomplete"
|
||||
const val assignedFishingZone = "/save:evilbob:fishingzone"
|
||||
const val fishCaught = "evilbob:fishcaught"
|
||||
const val attentive = "/save:evilbob:attentive"
|
||||
const val servantHelpDialogueSeen = "/save:evilbob:servantdialogeseen"
|
||||
const val attentiveNewSpot = "/save:evilbob:attentivenewspot"
|
||||
|
|
@ -53,14 +54,11 @@ object EvilBobUtils {
|
|||
}
|
||||
|
||||
fun teleport(player: Player) {
|
||||
setAttribute(player, prevLocation, player.location)
|
||||
player.properties.teleportLocation = Location.create(3419, 4776, 0)
|
||||
kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
player.properties.teleportLocation = getAttribute(player, prevLocation, null)
|
||||
removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
|
||||
removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
|
||||
removeAll(player, Items.FISHLIKE_THING_6202)
|
||||
removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK)
|
||||
removeAll(player, Items.FISHLIKE_THING_6206)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ import core.tools.RandomFunction
|
|||
import org.rs09.consts.Items
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import java.lang.Integer.max
|
||||
|
||||
val ids = 2463..2468
|
||||
val ids = (2463..2468).toList()
|
||||
|
||||
class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) {
|
||||
val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!")
|
||||
|
|
@ -19,8 +18,7 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN
|
|||
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, (player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat(phrases.random().replace("@name",player.username.capitalize()))
|
||||
|
|
|
|||
|
|
@ -57,10 +57,10 @@ class FreakListeners : InteractionListener, MapArea {
|
|||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS)
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
entity.locks.lockTeleport(1000000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
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
|
||||
|
||||
object FreakUtils{
|
||||
const val freakNpc = NPCs.FREAKY_FORESTER_2458
|
||||
const val freakPreviousLoc = "/save:original-loc"
|
||||
const val freakTask = "/save:freakyf:task"
|
||||
const val freakComplete = "/save:freakyf:complete"
|
||||
const val pheasantKilled = "freakyf:killed"
|
||||
|
|
@ -27,14 +29,12 @@ object FreakUtils{
|
|||
}
|
||||
|
||||
fun teleport(player: Player) {
|
||||
setAttribute(player, freakPreviousLoc, player.location)
|
||||
teleport(player, Location.create(2599, 4777 ,0))
|
||||
kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player) {
|
||||
player.locks.unlockTeleport()
|
||||
player.properties.teleportLocation = getAttribute(player,freakPreviousLoc,null)
|
||||
removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled)
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, freakTask, freakComplete, pheasantKilled)
|
||||
removeAll(player, Items.RAW_PHEASANT_6178)
|
||||
removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK)
|
||||
removeAll(player, Items.RAW_PHEASANT_6179)
|
||||
|
|
|
|||
277
Server/src/main/content/global/ame/events/maze/MazeInterface.kt
Normal file
277
Server/src/main/content/global/ame/events/maze/MazeInterface.kt
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
package content.global.ame.events.maze
|
||||
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.api.utils.WeightedItem
|
||||
import core.game.event.EventHook
|
||||
import core.game.event.TickEvent
|
||||
import core.game.global.action.DoorActionHandler
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.GameWorld.Pulser
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.*
|
||||
|
||||
class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
|
||||
companion object {
|
||||
const val MAZE_TIMER_INTERFACE = Components.MAZETIMER_209
|
||||
const val MAZE_TIMER_VARP = 531 // Interface 209 child 2 config: [531, 0]
|
||||
const val MAZE_ATTRIBUTE_TICKS_LEFT = "maze:percent-ticks-left"
|
||||
const val MAZE_ATTRIBUTE_CHESTS_OPEN = "/save:maze:chests-opened"
|
||||
|
||||
val STARTING_POINTS = arrayOf(
|
||||
Location(2928, 4553, 0),
|
||||
Location(2917, 4553, 0),
|
||||
Location(2908, 4555, 0),
|
||||
Location(2891, 4589, 0),
|
||||
Location(2891, 4595, 0),
|
||||
Location(2891, 4595, 0),
|
||||
Location(2926, 4597, 0),
|
||||
Location(2931, 4597, 0),
|
||||
// There's 2 more, but there isn't a door for them...
|
||||
)
|
||||
|
||||
val REWARD_ITEM = intArrayOf(
|
||||
Items.COINS_995,
|
||||
Items.FEATHER_314,
|
||||
Items.IRON_ARROW_884,
|
||||
Items.CHAOS_RUNE_562,
|
||||
Items.STEEL_ARROW_886,
|
||||
Items.DEATH_RUNE_560,
|
||||
Items.COAL_454,
|
||||
Items.NATURE_RUNE_561,
|
||||
Items.MITHRIL_ORE_448
|
||||
)
|
||||
|
||||
val ITEM_DIVISOR = arrayOf(
|
||||
1.0,
|
||||
2.0,
|
||||
3.0,
|
||||
9.0,
|
||||
12.0,
|
||||
18.0,
|
||||
45.0,
|
||||
162.0,
|
||||
180.0,
|
||||
)
|
||||
|
||||
val CHEST_REWARDS = WeightBasedTable.create(
|
||||
WeightedItem(Items.AIR_RUNE_556,15,15,1.0),
|
||||
WeightedItem(Items.WATER_RUNE_555,10,10,1.0),
|
||||
WeightedItem(Items.EARTH_RUNE_557,10,10,1.0),
|
||||
WeightedItem(Items.FIRE_RUNE_554,10,10,1.0),
|
||||
WeightedItem(Items.BRONZE_ARROW_882,20,20,1.0),
|
||||
WeightedItem(Items.BRONZE_BOLTS_877,10,10,1.0),
|
||||
WeightedItem(Items.IRON_ARROW_884,15,15,1.0),
|
||||
WeightedItem(Items.ATTACK_POTION2_123,1,1,1.0),
|
||||
WeightedItem(Items.STRENGTH_POTION2_117,1,1,1.0),
|
||||
WeightedItem(Items.DEFENCE_POTION2_135,1,1,1.0),
|
||||
)
|
||||
|
||||
fun initMaze(player: Player) {
|
||||
setAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 300)
|
||||
setVarp(player, MAZE_TIMER_VARP, (getAttribute<Int>(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) / 3),false)
|
||||
openOverlay(player, MAZE_TIMER_INTERFACE)
|
||||
sendMessage(player, "You need to reach the maze center, then you'll be returned to where you were.")
|
||||
sendNPCDialogue(player, NPCs.MYSTERIOUS_OLD_MAN_410, "You need to reach the maze center, then you'll be returned to where you were.")
|
||||
}
|
||||
|
||||
fun calculateLoot(player: Player) {
|
||||
val randomNumber = (0..8).random()
|
||||
val totalLevel = player.getSkills().totalLevel.toDouble()
|
||||
val rewardPotential = getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0).toDouble() / 300.0
|
||||
val itemDivisor = ITEM_DIVISOR[randomNumber]
|
||||
val itemQuantity = (totalLevel * rewardPotential * 3.33) / itemDivisor
|
||||
// sendMessage(player, "Maze reward calculation: $totalLevel * $rewardPotential * 3.33 / $itemDivisor = $itemQuantity")
|
||||
if (itemQuantity.toInt() > 0) {
|
||||
addItemOrDrop(player, REWARD_ITEM[randomNumber], itemQuantity.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chest Location to rotation mapping.
|
||||
* This is needed as it is impossible to obtain the underlying chest scenery for the rotation.
|
||||
* 0: Facing North, 1: Facing East, 2: Facing South, 3: Facing West
|
||||
*/
|
||||
val chestLocationRotationMap = mapOf(
|
||||
Location(2930, 4595, 0).toString() to 2,
|
||||
Location(2924, 4572, 0).toString() to 2,
|
||||
Location(2925, 4573, 0).toString() to 0,
|
||||
Location(2900, 4578, 0).toString() to 2,
|
||||
Location(2901, 4560, 0).toString() to 1,
|
||||
Location(2890, 4599, 0).toString() to 2,
|
||||
Location(2896, 4591, 0).toString() to 2,
|
||||
Location(2895, 4592, 0).toString() to 1,
|
||||
Location(2901, 4560, 0).toString() to 3,
|
||||
Location(2918, 4590, 0).toString() to 1,
|
||||
Location(2917, 4590, 0).toString() to 3,
|
||||
)
|
||||
|
||||
/**
|
||||
* Chest Interaction workaround
|
||||
*
|
||||
* The issue here is that the walls(3626) of the Maze are overlapping some(not all) chest sceneries.
|
||||
*
|
||||
* The types for the wallScenery:
|
||||
* Type 0 - flat panel |
|
||||
* Type 2 - right angle panel with rotation 0:r 1:7 2:> 3:L
|
||||
* Type 3 - corner post . for angle edges of walls
|
||||
*/
|
||||
fun overrideScenery(wallScenery: core.game.node.scenery.Scenery, chestSceneryId: Int): core.game.node.scenery.Scenery {
|
||||
if (wallScenery.id == chestSceneryId) {
|
||||
replaceScenery(wallScenery, Scenery.CHEST_3636, 30)
|
||||
wallScenery.isActive = true
|
||||
return wallScenery // Return the chest scenery as the wallScenery isn't there.
|
||||
}
|
||||
|
||||
addScenery(Scenery.CHEST_3636, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10)
|
||||
addScenery(wallScenery)
|
||||
// replaceScenery(newChestScenery, Scenery.CHEST_3636, 3) // didn't work for an underlying scenery
|
||||
// I did a world pulse since everyone will get to see the chest open.
|
||||
Pulser.submit(object : Pulse(30) {
|
||||
override fun pulse(): Boolean {
|
||||
addScenery(Scenery.CHEST_3635, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10)
|
||||
addScenery(wallScenery)
|
||||
return true
|
||||
}
|
||||
})
|
||||
// Return the chest scenery to replace PacketProcessor so that MISMATCH will not happen.
|
||||
return core.game.node.scenery.Scenery(
|
||||
chestSceneryId,
|
||||
wallScenery.location,
|
||||
chestLocationRotationMap[wallScenery.location.toString()] ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
|
||||
// This somehow doesn't trigger as the scenery.id != objId (3626 != 3635)
|
||||
on(Scenery.CHEST_3635, IntType.SCENERY, "open") { player, node ->
|
||||
if (getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0 && getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0) < 10) {
|
||||
animate(player, 536)
|
||||
// val actualScenery = RegionManager.getObject(node.location.z, node.location.x, node.location.y, 3626)
|
||||
val tableRoll = CHEST_REWARDS.roll()
|
||||
addItemOrBank(player, tableRoll[0].id)
|
||||
when (tableRoll[0].id){
|
||||
Items.AIR_RUNE_556 -> sendItemDialogue(player, Items.AIR_RUNE_556, "You've found some air runes!")
|
||||
Items.WATER_RUNE_555 -> sendItemDialogue(player, Items.WATER_RUNE_555, "You've found some water runes!")
|
||||
Items.EARTH_RUNE_557 -> sendItemDialogue(player, Items.EARTH_RUNE_557, "You've found some earth runes!")
|
||||
Items.FIRE_RUNE_554 -> sendItemDialogue(player, Items.FIRE_RUNE_554, "You've found some fire runes!")
|
||||
Items.BRONZE_ARROW_882 -> sendItemDialogue(player, Items.BRONZE_ARROW_882, "You've found some bronze arrows!")
|
||||
Items.BRONZE_BOLTS_877 -> sendItemDialogue(player, Items.BRONZE_BOLTS_877, "You've found some bronze bolts!")
|
||||
Items.IRON_ARROW_884 -> sendItemDialogue(player, Items.IRON_ARROW_884, "You've found some iron arrows!")
|
||||
Items.ATTACK_POTION2_123 -> sendItemDialogue(player, Items.ATTACK_POTION2_123, "You've found an attack potion!")
|
||||
Items.STRENGTH_POTION2_117 -> sendItemDialogue(player, Items.STRENGTH_POTION2_117, "You've found a strength potion!")
|
||||
Items.DEFENCE_POTION2_135 -> sendItemDialogue(player, Items.DEFENCE_POTION2_135, "You've found a defence potion!")
|
||||
}
|
||||
setAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0))
|
||||
} else {
|
||||
sendMessage(player,"You find nothing of interest.")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.CHEST_3636, SCENERY, "search") { player, node ->
|
||||
sendMessage(player,"You find nothing of interest.")
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.WALL_3626, IntType.SCENERY, "open") { player, node ->
|
||||
sendMessage(player, "That bit doesn't open.") // 0xBrLo9woIY
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.WALL_3628, IntType.SCENERY, "open") { player, node ->
|
||||
// Door opening workaround
|
||||
// Ignore 3629(WALL_3629) and 3630(WALL_3630) in handleAutowalkDoor ignoreSecondDoor
|
||||
DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Scenery.STRANGE_SHRINE_3634, IntType.SCENERY, "touch") { player, node ->
|
||||
player.unhook(this)
|
||||
closeOverlay(player)
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(86, 0, 3), player.location)
|
||||
animate(player,862)
|
||||
return@queueScript delayScript(player, 6)
|
||||
}
|
||||
1 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
2 -> {
|
||||
returnPlayer(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
closeOverlay(player)
|
||||
return@queueScript delayScript(player, 1)
|
||||
}
|
||||
3 -> {
|
||||
calculateLoot(player)
|
||||
removeAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT)
|
||||
removeAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun process(entity: Entity, event: TickEvent) {
|
||||
if (entity is Player) {
|
||||
if (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0) {
|
||||
setAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) - 1)
|
||||
}
|
||||
setVarp(entity, MAZE_TIMER_VARP, (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) / 3), false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(getRegionBorders(11591))
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (entity is Player) {
|
||||
sendMessage(entity, "Head for the center of the maze.")
|
||||
entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12)
|
||||
openOverlay(entity, MAZE_TIMER_INTERFACE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.restoreTabs()
|
||||
closeOverlay(entity)
|
||||
entity.unhook(this)
|
||||
}
|
||||
}
|
||||
override fun entityStep(entity: Entity, location: Location, lastLocation: Location) {
|
||||
if (entity is Player) {
|
||||
entity.hook(Event.Tick, this)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
57
Server/src/main/content/global/ame/events/maze/MazeNPC.kt
Normal file
57
Server/src/main/content/global/ame/events/maze/MazeNPC.kt
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package content.global.ame.events.maze
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import content.global.ame.kidnapPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.build.DynamicRegion
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) {
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("Aha, you'll do ${player.username}!")
|
||||
face(player)
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
MazeInterface.initMaze(player)
|
||||
// Note: This event is NOT instanced:
|
||||
// Sources:
|
||||
// https://youtu.be/2gpzn9oNdy0 (2007)
|
||||
// https://youtu.be/Tni1HURgnxg (2008)
|
||||
// https://youtu.be/igdwDZOv9LU (2008)
|
||||
// https://youtu.be/0oBCkLArUmc (2011 - even with personal Mysterious Old Man) - "Sorry, this is not the old man you are looking for."
|
||||
// https://youtu.be/FMuKZm-Ikgs (2011)
|
||||
// val region = DynamicRegion.create(11591)
|
||||
kidnapPlayer(player, MazeInterface.STARTING_POINTS.random(), TeleportManager.TeleportType.INSTANT) // 10 random spots
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
package content.global.ame.events.pillory
|
||||
|
||||
import content.global.ame.RandomEvents
|
||||
import content.global.ame.returnPlayer
|
||||
import core.api.*
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.interaction.InterfaceListener
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Scenery
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
/**
|
||||
* Pillory Unlocking Interface PILLORY_189
|
||||
*
|
||||
* https://www.youtube.com/watch?v=caWn7pE2mkE
|
||||
* https://www.youtube.com/watch?v=TMVR5cZZwZ0
|
||||
* https://www.youtube.com/watch?v=Ym9LCDP-Q74
|
||||
* https://www.youtube.com/watch?v=_vn0QZTtI6U (Failure)
|
||||
* https://www.youtube.com/watch?v=zmXDikQIua4
|
||||
*
|
||||
* Child IDs
|
||||
* 4 - Rotating Lock Model
|
||||
* 5 6 7 - Swinging Keys Models
|
||||
* 8 9 10 - Buttons for the Swinging Keys Models
|
||||
* 11 12 13 14 15 16 - Padlocks at the Top
|
||||
* 17 18 19 20 21 22 - Padlocks stars? Model 15272, Anim 4135
|
||||
*
|
||||
* Model IDs
|
||||
* Using the amazeballs ::listifmodels
|
||||
* 9749, 9750, 9751, 9752 - Swinging Keys Models
|
||||
* 9753, 9754, 9755, 9756 - Rotating Lock Models
|
||||
* 9757 9758 locked unlock
|
||||
*/
|
||||
class PilloryInterface : InterfaceListener, InteractionListener, MapArea {
|
||||
companion object {
|
||||
const val PILLORY_LOCK_INTERFACE = 189
|
||||
const val PILLORY_ATTRIBUTE_EVENT_KEYS = "pillory:event-keys"
|
||||
const val PILLORY_ATTRIBUTE_EVENT_LOCK = "pillory:event-lock"
|
||||
const val PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct"
|
||||
const val PILLORY_ATTRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct"
|
||||
|
||||
val LOCATIONS = arrayOf(
|
||||
// Varrock Cages
|
||||
Location(3226, 3407, 0),
|
||||
Location(3228, 3407, 0),
|
||||
Location(3230, 3407, 0),
|
||||
// Seers Village Cages
|
||||
Location(2681, 3489, 0),
|
||||
Location(2683, 3489, 0),
|
||||
Location(2685, 3489, 0),
|
||||
// Yannile Cages
|
||||
Location(2604, 3105, 0),
|
||||
Location(2606, 3105, 0),
|
||||
Location(2608, 3105, 0),
|
||||
)
|
||||
|
||||
fun initPillory(player: Player) {
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.")
|
||||
}
|
||||
|
||||
fun randomPillory(player: Player) {
|
||||
// Shuffle all 4 kinds of keys in, pick 3 for the keys, pick 1 from the 3 as the lock.
|
||||
val keys = (0..3).toIntArray().let{ keys -> keys.shuffle(); return@let keys }
|
||||
val lock = intArrayOf(keys[1], keys[2], keys[3]).random() // Last 3 as there are 4 keys. key[0] is fallback.
|
||||
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, keys)
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, lock)
|
||||
|
||||
player.packetDispatch.sendModelOnInterface(9753 + lock, PILLORY_LOCK_INTERFACE, 4, 0)
|
||||
player.packetDispatch.sendModelOnInterface(9749 + keys[1], PILLORY_LOCK_INTERFACE, 5, 0)
|
||||
player.packetDispatch.sendModelOnInterface(9749 + keys[2], PILLORY_LOCK_INTERFACE, 6, 0)
|
||||
player.packetDispatch.sendModelOnInterface(9749 + keys[3], PILLORY_LOCK_INTERFACE, 7, 0)
|
||||
|
||||
val numberToGetCorrect = getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3)
|
||||
val correctCount = getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
|
||||
for (i in 1.. 6) {
|
||||
// Set if lock is red or green.
|
||||
if (i <= correctCount) {
|
||||
player.packetDispatch.sendModelOnInterface(9758, PILLORY_LOCK_INTERFACE, 10 + i, 0)
|
||||
} else {
|
||||
player.packetDispatch.sendModelOnInterface(9757, PILLORY_LOCK_INTERFACE, 10 + i, 0)
|
||||
}
|
||||
// Set if hide or show lock.
|
||||
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 10 + i, i > numberToGetCorrect)
|
||||
}
|
||||
}
|
||||
|
||||
fun selectedKey(player: Player, buttonID: Int) {
|
||||
val keys = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, intArrayOf(0, 0, 0))
|
||||
val lock = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, -1)
|
||||
if (keys[buttonID] == lock) {
|
||||
// CORRECT ANSWER
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + 1)
|
||||
if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, -1)) {
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "You've escaped!")
|
||||
sendMessage(player, "You've escaped!")
|
||||
removeAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT)
|
||||
removeAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER)
|
||||
closeInterface(player)
|
||||
queueScript(player, 0, 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 -> {
|
||||
val loot = RandomEvents.CERTER.loot!!.roll(player)[0]
|
||||
addItemOrDrop(player, loot.id, loot.amount)
|
||||
returnPlayer(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
closeInterface(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
randomPillory(player)
|
||||
player.dialogueInterpreter.sendPlainMessage(
|
||||
true,
|
||||
"",
|
||||
"Correct!",
|
||||
"" + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + " down, " +
|
||||
(getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)) + " to go!")
|
||||
// Animation for the star, but it doesn't work.
|
||||
player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1), false)
|
||||
sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1))
|
||||
} else {
|
||||
// WRONG ANSWER
|
||||
player.dialogueInterpreter.close()
|
||||
player.dialogueInterpreter.sendDialogues(NPCs.TRAMP_2794 , FacialExpression.OLD_ANGRY1, "Bah, that's not right.","Use the key that matches the hole", "in the spinning lock.")
|
||||
if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) {
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1)
|
||||
}
|
||||
setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)
|
||||
closeInterface(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineInterfaceListeners() {
|
||||
on(PILLORY_LOCK_INTERFACE){ player, component, opcode, buttonID, slot, itemID ->
|
||||
when (buttonID) {
|
||||
8 -> selectedKey(player, 1)
|
||||
9 -> selectedKey(player, 2)
|
||||
10 -> selectedKey(player, 3)
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
onOpen(PILLORY_LOCK_INTERFACE){ player, component ->
|
||||
return@onOpen true
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Scenery.CAGE_6836, IntType.SCENERY, "unlock") { player, node ->
|
||||
if (player.location in LOCATIONS) { // When you aren't inside.
|
||||
randomPillory(player)
|
||||
openInterface(player, PILLORY_LOCK_INTERFACE)
|
||||
player.dialogueInterpreter.sendPlainMessage(true, "", "Pick the <col=8A0808>swinging key</col> that matches the", "hole in the <col=8A0808>spinning lock</col>.")
|
||||
} else {
|
||||
sendMessage(player, "You can't unlock the pillory, you'll let all the prisoners out!")
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(
|
||||
// Varrock Cages
|
||||
ZoneBorders(3226, 3407, 3226, 3407),
|
||||
ZoneBorders(3228, 3407, 3228, 3407),
|
||||
ZoneBorders(3230, 3407, 3230, 3407),
|
||||
// Seers Village Cages
|
||||
ZoneBorders(2681, 3489, 2681, 3489),
|
||||
ZoneBorders(2683, 3489, 2683, 3489),
|
||||
ZoneBorders(2685, 3489, 2685, 3489),
|
||||
// Yannile Cages
|
||||
ZoneBorders(2604, 3105, 2604, 3105),
|
||||
ZoneBorders(2606, 3105, 2606, 3105),
|
||||
ZoneBorders(2608, 3105, 2608, 3105),
|
||||
)
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12)
|
||||
}
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.restoreTabs()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package content.global.ame.events.pillory
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import content.global.ame.kidnapPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
//player.dialogueInterpreter.open(FreakyForesterDialogue(),npc)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package content.global.ame.events.quizmaster
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import org.rs09.consts.NPCs
|
||||
|
||||
class QuizMasterBorders : MapArea {
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(getRegionBorders(7754))
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12)
|
||||
face(entity, Location(1952, 4768, 1))
|
||||
animate(entity,2378)
|
||||
openDialogue(entity, QuizMasterDialogueFile(), NPC(NPCs.QUIZ_MASTER_2477))
|
||||
}
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.restoreTabs()
|
||||
//closeOverlay(entity)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
package content.global.ame.events.quizmaster
|
||||
|
||||
import content.global.ame.returnPlayer
|
||||
import core.ServerConstants
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.api.utils.WeightedItem
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.END_DIALOGUE
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
|
||||
class QuizMasterDialogueFile : DialogueFile() {
|
||||
companion object {
|
||||
const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191
|
||||
const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct"
|
||||
const val QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER = "quizmaster:random-answer"
|
||||
|
||||
/*
|
||||
// Golden Models:
|
||||
8828 ADAMANT_BATTLEAXE_1371
|
||||
8829 SALMON_329
|
||||
8830 TROUT_333
|
||||
8831 NECKLACE
|
||||
8832 WOODEN_SHIELD_1171
|
||||
8833 BRONZE_MED_HELM_1139
|
||||
8834 RING
|
||||
8835 SECATEURS_5329
|
||||
8836 BRONZE_SWORD_1277
|
||||
8837 GARDENING_TROWEL_5325
|
||||
*/
|
||||
val sets = arrayOf(
|
||||
intArrayOf(8828, 8829, 8829),
|
||||
intArrayOf(8831, 8837, 8835),
|
||||
intArrayOf(8830, 8832, 8833),
|
||||
intArrayOf(8835, 8834, 8831),
|
||||
intArrayOf(8837, 8836, 8828),
|
||||
)
|
||||
|
||||
fun randomQuestion(player: Player): Int {
|
||||
val randomSet = intArrayOf(*sets.random())
|
||||
val answer = intArrayOf(*randomSet)[0]
|
||||
randomSet.shuffle()
|
||||
val correctButton = randomSet.indexOf(answer) + 2 // buttons are 3,4,5
|
||||
|
||||
player.packetDispatch.sendModelOnInterface(randomSet[0], QUIZMASTER_INTERFACE, 6, 512)
|
||||
player.packetDispatch.sendModelOnInterface(randomSet[1], QUIZMASTER_INTERFACE, 7, 512)
|
||||
player.packetDispatch.sendModelOnInterface(randomSet[2], QUIZMASTER_INTERFACE, 8, 512)
|
||||
player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 6, 512,0,0)
|
||||
player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 7, 512,0,0)
|
||||
player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 8, 512,0,0)
|
||||
|
||||
return correctButton
|
||||
}
|
||||
|
||||
// Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas.
|
||||
val tableRoll = WeightBasedTable.create(
|
||||
WeightedItem(Items.LAMP_2528, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.CABBAGE_1965, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.DIAMOND_1601, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.BUCKET_1925, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.FLIER_956, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.OLD_BOOT_685, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.BODY_RUNE_559, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.ONION_1957, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.MITHRIL_SCIMITAR_1329, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.CASKET_405, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.STEEL_PLATEBODY_1119, 1, 1, 1.0, false),
|
||||
WeightedItem(Items.NATURE_RUNE_561, 20, 20, 1.0, false),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (stage) {
|
||||
0 -> npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "<col=8A0808>O D D</col> <col=8A088A>O N E</col> <col=08088A>O U T</col>").also { stage++ }
|
||||
1 -> player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...").also { stage++ }
|
||||
2 -> npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "<col=FF0000>${player?.username}</col>!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!").also { stage++ }
|
||||
3 -> {
|
||||
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player!!))
|
||||
player!!.interfaceManager.openChatbox(QUIZMASTER_INTERFACE)
|
||||
stage++
|
||||
}
|
||||
4-> {
|
||||
if (buttonID == getAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) {
|
||||
// Correct Answer
|
||||
setAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1)
|
||||
if (getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) {
|
||||
npc(FacialExpression.FRIENDLY,"<col=08088A>CONGRATULATIONS!</col>", "You are a <col=8A0808>WINNER</col>!", "Please choose your <col=08088A>PRIZE</col>!")
|
||||
stage = 5
|
||||
} else {
|
||||
npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!")
|
||||
stage = 3
|
||||
}
|
||||
} else {
|
||||
// Wrong Answer
|
||||
npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!")
|
||||
stage = 3
|
||||
}
|
||||
}
|
||||
// Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas.
|
||||
5 -> options("1000 Coins", "Random Item").also { stage++ }
|
||||
6 -> {
|
||||
resetAnimator(player!!)
|
||||
returnPlayer(player!!)
|
||||
when (buttonID) {
|
||||
1 -> {
|
||||
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
addItemOrDrop(player!!, Items.COINS_995, 1000)
|
||||
return@queueScript stopExecuting(player!!)
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
addItemOrDrop(player!!, tableRoll.roll()[0].id)
|
||||
return@queueScript stopExecuting(player!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAttributes(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER)
|
||||
stage = END_DIALOGUE
|
||||
end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package content.global.ame.events.quizmaster
|
||||
|
||||
import content.global.ame.RandomEventNPC
|
||||
import content.global.ame.kidnapPlayer
|
||||
import core.api.*
|
||||
import core.api.utils.WeightBasedTable
|
||||
import core.game.interaction.QueueStrength
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import org.rs09.consts.NPCs
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
/**
|
||||
* Quiz Master NPC:
|
||||
*
|
||||
* https://www.youtube.com/watch?v=EFAWSiPTfcM
|
||||
* https://www.youtube.com/watch?v=caWn7pE2mkE
|
||||
* https://www.youtube.com/watch?v=Bc1gAov2o4w
|
||||
* https://www.youtube.com/watch?v=oHU8-MUarxE
|
||||
* https://www.youtube.com/watch?v=wvjYiF4v9tI
|
||||
* https://www.youtube.com/watch?v=dC6rlSnXEfw
|
||||
*/
|
||||
class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.QUIZ_MASTER_2477) {
|
||||
override fun init() {
|
||||
super.init()
|
||||
sendChat("Hey ${player.username}! It's your lucky day!")
|
||||
queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
lock(player, 6)
|
||||
sendGraphics(Graphics(1576, 0, 0), player.location)
|
||||
animate(player,8939)
|
||||
playAudio(player, Sounds.TELEPORT_ALL_200)
|
||||
return@queueScript delayScript(player, 3)
|
||||
}
|
||||
1 -> {
|
||||
kidnapPlayer(player, Location(1952, 4764, 1), TeleportManager.TeleportType.INSTANT)
|
||||
setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0)
|
||||
AntiMacro.terminateEventNpc(player)
|
||||
sendGraphics(Graphics(1577, 0, 0), player.location)
|
||||
animate(player,8941)
|
||||
sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.")
|
||||
sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case.
|
||||
return@queueScript delayScript(player, 6)
|
||||
}
|
||||
2 -> {
|
||||
face(player, Location(1952, 4768, 1))
|
||||
animate(player,2378)
|
||||
// This is not needed as when you enter the QuizMasterBorders, it should fire off the dialogue
|
||||
// openDialogue(player, QuizMasterDialogueFile(), this.asNpc())
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun talkTo(npc: NPC) {
|
||||
openDialogue(player, QuizMasterDialogueFile(), this.asNpc())
|
||||
}
|
||||
}
|
||||
|
|
@ -4,17 +4,14 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import java.lang.Integer.max
|
||||
|
||||
|
||||
val ids = 391..396
|
||||
val ids = (391..396).toList()
|
||||
|
||||
class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(391){
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, (player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Fishies be mine, leave dem fishies!")
|
||||
|
|
|
|||
|
|
@ -4,17 +4,14 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.max
|
||||
|
||||
|
||||
val ids = 413..418
|
||||
val ids = (413..418).toList()
|
||||
|
||||
class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(413){
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0,(player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Raarrrgghh! Flee human!")
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.*
|
||||
|
||||
class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){
|
||||
val ids = (425..430).toList()
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1))
|
||||
val id = ids[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Leave this place!")
|
||||
|
|
|
|||
|
|
@ -32,4 +32,8 @@ class StrangePlantBehavior() : NPCBehavior(NPCs.STRANGE_PLANT_408) {
|
|||
override fun onDeathStarted(self: NPC, killer: Entity) {
|
||||
AntiMacro.terminateEventNpc(killer.asPlayer())
|
||||
}
|
||||
}
|
||||
|
||||
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
|
||||
return super.getXpMultiplier(self, attacker) / 16.0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.component.Component
|
||||
import core.game.dialogue.FacialExpression
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package content.global.ame.events
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
import content.global.ame.events.supriseexam.SurpriseExamUtils
|
||||
import content.global.ame.events.surpriseexam.SurpriseExamUtils
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.game.system.timer.impl.AntiMacro
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.dialogue.DialogueFile
|
||||
import core.tools.END_DIALOGUE
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.node.entity.npc.NPC
|
||||
import org.rs09.consts.Components
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
package content.global.ame.events.surpriseexam
|
||||
|
||||
import core.game.component.Component
|
||||
import core.game.node.entity.player.Player
|
||||
|
|
@ -9,20 +9,22 @@ import org.rs09.consts.NPCs
|
|||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import content.global.handlers.iface.ExperienceInterface
|
||||
import core.api.MapArea
|
||||
import core.api.removeItem
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
|
||||
class SupriseExamListeners : InteractionListener {
|
||||
val MORDAUT = NPCs.MR_MORDAUT_6117
|
||||
val BOOK_OF_KNOWLEDGE = Items.BOOK_OF_KNOWLEDGE_11640
|
||||
class SupriseExamListeners : InteractionListener, MapArea {
|
||||
override fun defineListeners() {
|
||||
|
||||
on(MORDAUT, IntType.NPC, "talk-to"){ player, node ->
|
||||
on(NPCs.MR_MORDAUT_6117, IntType.NPC, "talk-to") { player, node ->
|
||||
player.faceLocation(Location.create(1886, 5024, 0))
|
||||
val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3
|
||||
player.dialogueInterpreter.open(MordautDialogue(examComplete),node.asNpc())
|
||||
val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT, 0) == 3
|
||||
player.dialogueInterpreter.open(MordautDialogue(examComplete), node.asNpc())
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open"){ player, node ->
|
||||
on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open") { player, node ->
|
||||
val correctDoor = player.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1)
|
||||
|
||||
if(correctDoor == -1){
|
||||
|
|
@ -39,9 +41,9 @@ class SupriseExamListeners : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
|
||||
on(BOOK_OF_KNOWLEDGE, IntType.ITEM, "read"){ player, _ ->
|
||||
player.setAttribute("caller"){skill: Int,p: Player ->
|
||||
if(p.inventory.remove(Item(BOOK_OF_KNOWLEDGE))) {
|
||||
on(Items.BOOK_OF_KNOWLEDGE_11640, IntType.ITEM, "read") { player, _ ->
|
||||
player.setAttribute("caller") { skill: Int, p: Player ->
|
||||
if (removeItem(p, Items.BOOK_OF_KNOWLEDGE_11640)) {
|
||||
val level = p.skills.getStaticLevel(skill)
|
||||
val experience = level * 15.0
|
||||
p.skills.addExperience(skill, experience)
|
||||
|
|
@ -54,8 +56,16 @@ class SupriseExamListeners : InteractionListener {
|
|||
}
|
||||
|
||||
override fun defineDestinationOverrides() {
|
||||
setDest(IntType.NPC,MORDAUT){ _, _ ->
|
||||
setDest(IntType.NPC, NPCs.MR_MORDAUT_6117) { _, _ ->
|
||||
return@setDest Location.create(1886, 5025, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun defineAreaBorders(): Array<ZoneBorders> {
|
||||
return arrayOf(ZoneBorders.forRegion(7502))
|
||||
}
|
||||
|
||||
override fun getRestrictions(): Array<ZoneRestriction> {
|
||||
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,18 @@
|
|||
package content.global.ame.events.supriseexam
|
||||
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.node.item.GroundItemManager
|
||||
import core.game.node.item.Item
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.map.Location
|
||||
import org.rs09.consts.Components
|
||||
import org.rs09.consts.Items
|
||||
import core.ServerConstants
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
|
||||
object SurpriseExamUtils {
|
||||
|
||||
val SE_KEY_LOC = "/save:original-loc"
|
||||
val SE_KEY_INDEX = "supexam:index"
|
||||
val SE_LOGOUT_KEY = "suprise_exam"
|
||||
val SE_DOOR_KEY = "supexam:door"
|
||||
val INTER_PATTERN_CHILDS = intArrayOf(6,7,8)
|
||||
val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13)
|
||||
|
|
@ -29,28 +26,16 @@ object SurpriseExamUtils {
|
|||
intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311)
|
||||
)
|
||||
|
||||
fun teleport(player: Player){
|
||||
player.setAttribute(SE_KEY_LOC,player.location)
|
||||
|
||||
registerLogoutListener(player, SE_LOGOUT_KEY){p ->
|
||||
p.location = getAttribute(p, SE_KEY_LOC, ServerConstants.HOME_LOCATION)
|
||||
}
|
||||
|
||||
player.properties.teleportLocation = Location.create(1886, 5025, 0)
|
||||
fun teleport(player: Player) {
|
||||
kidnapPlayer(player, Location.create(1886, 5025, 0), TeleportManager.TeleportType.INSTANT)
|
||||
}
|
||||
|
||||
fun cleanup(player: Player){
|
||||
player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC,null)
|
||||
clearLogoutListener(player, SE_LOGOUT_KEY)
|
||||
player.removeAttribute(SE_KEY_LOC)
|
||||
player.removeAttribute(SE_KEY_INDEX)
|
||||
player.removeAttribute(SE_KEY_CORRECT)
|
||||
returnPlayer(player)
|
||||
removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT)
|
||||
player.pulseManager.run(object : Pulse(2){
|
||||
override fun pulse(): Boolean {
|
||||
val reward = Item(Items.BOOK_OF_KNOWLEDGE_11640)
|
||||
if(!player.inventory.add(reward)){
|
||||
GroundItemManager.create(reward,player)
|
||||
}
|
||||
addItemOrDrop(player, Items.BOOK_OF_KNOWLEDGE_11640)
|
||||
return true
|
||||
}
|
||||
}, PulseType.CUSTOM_1)
|
||||
|
|
@ -4,17 +4,14 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.max
|
||||
|
||||
|
||||
val ids = 438..443
|
||||
val ids = (438..443).toList()
|
||||
|
||||
class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(438){
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0,(player.properties.combatLevel / 20) - 1)
|
||||
val id = ids.toList()[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Leave these woods and never return!")
|
||||
|
|
|
|||
|
|
@ -4,15 +4,13 @@ import core.game.node.entity.Entity
|
|||
import core.game.node.entity.npc.NPC
|
||||
import content.global.ame.RandomEventNPC
|
||||
import core.api.utils.WeightBasedTable
|
||||
import kotlin.math.*
|
||||
|
||||
class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){
|
||||
val ids = (419..424).toList()
|
||||
override fun talkTo(npc: NPC) {}
|
||||
override fun init() {
|
||||
super.init()
|
||||
val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1))
|
||||
val id = ids[index]
|
||||
val id = idForCombatLevel(ids, player)
|
||||
this.transform(id)
|
||||
this.attack(player)
|
||||
sendChat("Brainsssss!")
|
||||
|
|
|
|||
|
|
@ -12,15 +12,16 @@ import core.game.world.map.Location
|
|||
import core.game.world.map.RegionManager
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.update.flag.*
|
||||
import core.tools.RandomFunction
|
||||
import org.json.simple.JSONArray
|
||||
import org.json.simple.JSONObject
|
||||
import core.ServerConstants
|
||||
import core.api.log
|
||||
import core.game.bots.AIRepository
|
||||
import core.game.bots.CombatBotAssembler
|
||||
import core.game.bots.Script
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListeners
|
||||
import core.tools.Log
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
import java.time.LocalDateTime
|
||||
|
|
@ -40,21 +41,27 @@ import kotlin.random.Random
|
|||
* @author Ceikry
|
||||
*/
|
||||
|
||||
//Adventure Bots v4.0.0 -Expansion Edition-
|
||||
// Adventure Bots v1.1.0 : Expansion Edition (Previously v4.0.0)
|
||||
// Super Grand Exchange Update
|
||||
class Adventurer(val style: CombatStyle): Script() {
|
||||
|
||||
var city: Location = lumbridge
|
||||
var ticks = 0
|
||||
var freshspawn = true
|
||||
var sold = false
|
||||
private val geloc: Location = if (Random.nextBoolean()){
|
||||
Location.create(3165, 3487, 0)
|
||||
}else{
|
||||
Location.create(3164, 3492, 0)
|
||||
}
|
||||
var poiloc: Location = karamja
|
||||
var geSocialLoc: Location = getRandomGESocialLocation()
|
||||
var geClerkLoc: Location = getRandomGELocation()
|
||||
var geClerksloc: Location = neGEClerk
|
||||
|
||||
var freshspawn: Boolean = true
|
||||
var sold: Boolean = false
|
||||
var poi: Boolean = false
|
||||
|
||||
val chance: Int = if (cityLocationsGE.contains(city)) 3500 else 3000
|
||||
var ticks: Int = 0
|
||||
var counter: Int = 0
|
||||
var random: Int = (5..30).random()
|
||||
val waitTotal: Int = 8
|
||||
var returnToAdventure: Int = 0
|
||||
var geWait: Int = 0
|
||||
var geLongWait: Int = 0
|
||||
|
||||
val type = when(style){
|
||||
CombatStyle.MELEE -> CombatBotAssembler.Type.MELEE
|
||||
|
|
@ -74,23 +81,81 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "${bot.name} is an Adventurer bot at ${bot.location}! State: $state - City: $city"
|
||||
return "${bot.username} is an Adventurer bot " +
|
||||
"at ${bot.location}! " +
|
||||
"State: $state - " +
|
||||
"City: $city - " +
|
||||
"Ticks: $ticks - " +
|
||||
"Freshspawn: $freshspawn - " +
|
||||
"Sold: $sold - " +
|
||||
"Counter: $counter"
|
||||
}
|
||||
|
||||
var state = State.START
|
||||
|
||||
fun getRandomCity(): Location{
|
||||
private fun getRandomCity(): Location{
|
||||
return cities.random()
|
||||
}
|
||||
|
||||
fun getRandomPoi(): Location{
|
||||
private fun getRandomPoi(): Location{
|
||||
return pois.random()
|
||||
}
|
||||
|
||||
private fun getRandomGESocialLocation(): Location{
|
||||
return socialLocationsGE.random()
|
||||
}
|
||||
|
||||
private fun getRandomGELocation(): Location {
|
||||
return cityLocationsGE.random()
|
||||
}
|
||||
|
||||
private fun randomNumberFromOne(maxInt: Int): Int {
|
||||
return Random.nextInt(0, maxInt)
|
||||
}
|
||||
|
||||
private fun otherPlayersNearby(): Boolean {
|
||||
val localPlayers = RegionManager.getLocalPlayers(bot)
|
||||
val otherPlayers = localPlayers.filter { it.name != bot.name }
|
||||
return otherPlayers.isNotEmpty()
|
||||
}
|
||||
|
||||
private fun checkNearBank() {
|
||||
if(bankMap[city] == null){
|
||||
scriptAPI.teleport(getRandomCity().also { city = it })
|
||||
} else {
|
||||
if(bankMap[city]?.insideBorder(bot) == true){
|
||||
state = State.FIND_BANK
|
||||
} else {
|
||||
bankMap[city]?.let { scriptAPI.walkTo(it.randomLoc) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCounter(maxCounter: Int) {
|
||||
if (counter++ >= maxCounter) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
}
|
||||
|
||||
private fun teleportToRandomCity() {
|
||||
city = getRandomCity()
|
||||
when (city) {
|
||||
neGEClerk -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-3,2,0,1,0)) }
|
||||
swGEClerk -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-2,3,-1,0,0)) }
|
||||
nwGEBanker -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-2,0,-3,2,0)) }
|
||||
seGEBanker -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,0,2,-2,3,0)) }
|
||||
else -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-1,1,-1,1,0)) }
|
||||
}
|
||||
}
|
||||
|
||||
val resources = listOf(
|
||||
"Rocks","Tree","Oak","Willow",
|
||||
"Maple tree","Yew","Magic tree",
|
||||
"Teak","Mahogany")
|
||||
|
||||
//TODO: Optimise and adjust how bots handle picking up ground items further.
|
||||
fun immerse() {
|
||||
if (counter++ == 180) {state = State.TELEPORTING
|
||||
}
|
||||
if (counter++ >= Random.nextInt(150,300)) { state = State.TELEPORTING }
|
||||
val items = AIRepository.groundItems[bot]
|
||||
if (Random.nextBoolean()) {
|
||||
if (items.isNullOrEmpty()) {
|
||||
|
|
@ -98,33 +163,13 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
state = State.LOOT_DELAY
|
||||
}
|
||||
if (bot.inventory.isFull) {
|
||||
if(bankMap[city] == null){
|
||||
scriptAPI.teleport(getRandomCity().also { city = it })
|
||||
} else {
|
||||
if(bankMap[city]?.insideBorder(bot) == true){
|
||||
state = State.FIND_BANK
|
||||
} else {
|
||||
scriptAPI.walkTo(bankMap[city]?.randomLoc ?: Location(0, 0, 0))
|
||||
}
|
||||
}
|
||||
checkNearBank()
|
||||
}
|
||||
|
||||
} else {
|
||||
if (bot.inventory.isFull){
|
||||
if(bankMap[city] == null){
|
||||
scriptAPI.teleport(getRandomCity().also { city = it })
|
||||
} else {
|
||||
if(bankMap[city]?.insideBorder(bot) == true){
|
||||
state = State.FIND_BANK
|
||||
} else {
|
||||
scriptAPI.walkTo(bankMap[city]?.randomLoc ?: Location(0, 0, 0))
|
||||
}
|
||||
}
|
||||
checkNearBank()
|
||||
} else {
|
||||
val resources = listOf(
|
||||
"Rocks","Tree","Oak","Willow",
|
||||
"Maple tree","Yew","Magic tree",
|
||||
"Teak","Mahogany")
|
||||
val resource = scriptAPI.getNearestNodeFromList(resources,true)
|
||||
if(resource != null){
|
||||
if(resource.name.contains("ocks")) InteractionListeners.run(resource.id,
|
||||
|
|
@ -137,18 +182,17 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
}
|
||||
|
||||
fun refresh() {
|
||||
// log(this::class.java, Log.WARN, "${bot.username} refreshed from $state at $city with $ticks and $counter counter.")
|
||||
scriptAPI.teleport(lumbridge)
|
||||
freshspawn = true
|
||||
state = State.START
|
||||
}
|
||||
|
||||
var poi = false
|
||||
var poiloc = karamja
|
||||
|
||||
//Adventure Bots Actual Code STARTS HERE!!!
|
||||
// 100 ticks = 60 seconds
|
||||
override fun tick() {
|
||||
ticks++
|
||||
if (ticks++ >= 800) {
|
||||
// Hard refresh
|
||||
if (ticks >= 1000) {
|
||||
ticks = 0
|
||||
refresh()
|
||||
return
|
||||
|
|
@ -186,49 +230,42 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
}
|
||||
return
|
||||
} else {
|
||||
state = State.EXPLORE
|
||||
state = State.ADVENTURE
|
||||
}
|
||||
}
|
||||
|
||||
State.START -> {
|
||||
if (freshspawn) {
|
||||
freshspawn = false
|
||||
scriptAPI.randomWalkTo(lumbridge, 20)
|
||||
scriptAPI.randomWalkTo(lumbridge, randomNumberFromOne(25))
|
||||
} else {
|
||||
city = getRandomCity()
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
}
|
||||
|
||||
State.TELEPORTING -> {
|
||||
if (freshspawn){ freshspawn = false }
|
||||
teleportToRandomCity()
|
||||
poi = false
|
||||
sold = false
|
||||
ticks = 0
|
||||
counter = 0
|
||||
if (bot.location != city) {
|
||||
poi = false
|
||||
scriptAPI.teleport(city)
|
||||
} else {
|
||||
poi = false
|
||||
state = State.EXPLORE
|
||||
}
|
||||
state = State.ADVENTURE
|
||||
return
|
||||
}
|
||||
|
||||
State.EXPLORE -> {
|
||||
if (counter++ == 350) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
|
||||
val chance = if (city == ge || city == ge2) 5000 else 2500
|
||||
if (RandomFunction.random(chance) <= 10) {
|
||||
val nearbyPlayers = RegionManager.getLocalPlayers(bot)
|
||||
if (nearbyPlayers.isNotEmpty()) {
|
||||
State.ADVENTURE -> {
|
||||
checkCounter(800)
|
||||
if (randomNumberFromOne(chance) <= 10) {
|
||||
if (otherPlayersNearby()) {
|
||||
ticks = 0
|
||||
dialogue()
|
||||
}
|
||||
}
|
||||
|
||||
if (RandomFunction.random(1000) <= 150 && !poi) {
|
||||
val roamDistance = if (city != ge && city != ge2) 225 else 7
|
||||
if ((city == ge || city == ge2) && RandomFunction.random(100) < 90) {
|
||||
if (!poi && randomNumberFromOne(1000) <= 75) {
|
||||
val roamDistance = if (!cityLocationsGE.contains(city)) 225 else randomNumberFromOne(5)
|
||||
if (cityLocationsGE.contains(city) && randomNumberFromOne(100) < 90) {
|
||||
if (!bot.bank.isEmpty) {
|
||||
state = State.FIND_GE
|
||||
}
|
||||
|
|
@ -238,33 +275,46 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
return
|
||||
}
|
||||
|
||||
if (RandomFunction.random(1000) <= 50 && poi){
|
||||
if (poi && randomNumberFromOne(1000) <= 100){
|
||||
immerse()
|
||||
return
|
||||
}
|
||||
|
||||
if (poi && randomNumberFromOne(1000) <= 25){
|
||||
dialogue()
|
||||
}
|
||||
|
||||
if (poi && randomNumberFromOne(1000) <= 50){
|
||||
val roamDistancePoi = when(poiloc){
|
||||
teakfarm, crawlinghands -> 5
|
||||
treegnome -> 50
|
||||
isafdar -> 40
|
||||
eaglespeek -> 40
|
||||
keldagrimout -> 30
|
||||
teak1 -> 30
|
||||
miningguild -> 5
|
||||
magics, coal -> 7
|
||||
gemrocks, chaosnpc, chaosnpc2 -> 1
|
||||
magics, coalTrucks -> 7
|
||||
miningguild, teakfarm, crawlinghands -> 5
|
||||
varLumberYard -> 20
|
||||
keldagrimout, teak1 -> 30
|
||||
eaglespeek, isafdar -> 40
|
||||
treegnome -> 50
|
||||
else -> 60
|
||||
}
|
||||
scriptAPI.randomWalkTo(poiloc,roamDistancePoi)
|
||||
return
|
||||
}
|
||||
|
||||
if (RandomFunction.random(1000) <= 75) {
|
||||
if (city != ge && city != ge2) {
|
||||
if (randomNumberFromOne(1000) <= 75) {
|
||||
if (!cityLocationsGE.contains(city)) {
|
||||
ticks = 0
|
||||
immerse()
|
||||
return
|
||||
} else {
|
||||
return
|
||||
} else if (randomNumberFromOne(chance) <= 55 && otherPlayersNearby()) {
|
||||
ticks = 0
|
||||
dialogue()
|
||||
}
|
||||
}
|
||||
|
||||
if (RandomFunction.random(20000) <= 60 && !poi) {
|
||||
if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 50) {
|
||||
state = State.IDLE_GE
|
||||
}
|
||||
|
||||
if (!poi && randomNumberFromOne(1000) <= 5) {
|
||||
poiloc = getRandomPoi()
|
||||
city = teak1
|
||||
poi = true
|
||||
|
|
@ -272,26 +322,24 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
return
|
||||
}
|
||||
|
||||
if ((city == ge || city == ge2) && RandomFunction.random(1000) >= 999) {
|
||||
ticks = 0
|
||||
city = getRandomCity()
|
||||
if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 100) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
|
||||
if (city == ge || city == ge2) {
|
||||
return
|
||||
}
|
||||
|
||||
if (city == teak1 && counter++ >= 240){
|
||||
city = getRandomCity()
|
||||
state = State.TELEPORTING
|
||||
if (cityLocationsGE.contains(city)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (counter++ >= 240 && RandomFunction.random(100) >= 10) {
|
||||
if (poi && randomNumberFromOne(1000) <= 20){
|
||||
state = State.TELEPORTING
|
||||
return
|
||||
}
|
||||
|
||||
if (counter++ >= 750 && randomNumberFromOne(100) <= 50) {
|
||||
// log(this::class.java, Log.FINE, "${bot.username} has moved on to a different city at $ticks ticks and $counter counter.")
|
||||
city = getRandomCity()
|
||||
if (RandomFunction.random(100) % 2 == 0) {
|
||||
counter = 0
|
||||
ticks = 0
|
||||
if (randomNumberFromOne(100) % 2 == 0) {
|
||||
state = State.TELEPORTING
|
||||
} else {
|
||||
if (citygroupA.contains(city)) {
|
||||
|
|
@ -309,122 +357,122 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
return
|
||||
}
|
||||
|
||||
State.GE -> {
|
||||
var ge = false
|
||||
if (counter++ == 180) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
if (!sold) {
|
||||
if (counter++ >= 15) {
|
||||
sold = true
|
||||
ge = true
|
||||
State.IDLE_GE -> {
|
||||
returnToAdventure = Random.nextInt(350, 750)
|
||||
if (counter++ >= returnToAdventure){
|
||||
if (randomNumberFromOne(100) <= 25){
|
||||
ticks = 0
|
||||
counter = 0
|
||||
poiloc = getRandomPoi()
|
||||
city = teak1
|
||||
poi = true
|
||||
scriptAPI.teleport(poiloc)
|
||||
state = State.ADVENTURE
|
||||
return
|
||||
} else {
|
||||
counter = 0
|
||||
ticks = 0
|
||||
scriptAPI.sellAllOnGeAdv()
|
||||
state = State.TELEPORTING
|
||||
return
|
||||
}
|
||||
}
|
||||
if (cityLocationsGE.contains(city)){
|
||||
if (randomNumberFromOne(1000) <= 5) {
|
||||
ticks = 0
|
||||
geSocialLoc = scriptAPI.randomizeLocationInRanges(getRandomGESocialLocation(),-1,1,-1,1,0)
|
||||
} else if (randomNumberFromOne(1000) <= 10) {
|
||||
ticks = 0
|
||||
scriptAPI.randomWalkTo(geSocialLoc, randomNumberFromOne(5))
|
||||
return
|
||||
}
|
||||
if (randomNumberFromOne(1000) <= 5 && otherPlayersNearby()){
|
||||
ticks = 0
|
||||
dialogue()
|
||||
} else if (randomNumberFromOne(1000) <= 250){
|
||||
return
|
||||
}
|
||||
} else if (ge && sold) {
|
||||
ge = false
|
||||
city = getRandomCity()
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
State.FIND_GE -> {
|
||||
if (counter++ == 180) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
sold = false
|
||||
val ge: Scenery? = scriptAPI.getNearestNode("Desk", true) as Scenery?
|
||||
if (ge == null || bot.bank.isEmpty) state = State.EXPLORE
|
||||
if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE
|
||||
class GEPulse : MovementPulse(bot, ge, DestinationFlag.OBJECT) {
|
||||
override fun pulse(): Boolean {
|
||||
bot.faceLocation(ge?.location)
|
||||
state = State.GE
|
||||
return true
|
||||
return true.also { state = State.GE }
|
||||
}
|
||||
}
|
||||
if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE
|
||||
if (ge != null && !bot.bank.isEmpty) {
|
||||
counter = 0
|
||||
scriptAPI.randomWalkTo(geloc, 3)
|
||||
GameWorld.Pulser.submit(GEPulse())
|
||||
if (randomNumberFromOne(1000) <= 25 && otherPlayersNearby()){
|
||||
dialogue()
|
||||
scriptAPI.randomWalkTo(geSocialLoc, randomNumberFromOne(5))
|
||||
} else if (randomNumberFromOne(500) <= 50) {
|
||||
GameWorld.Pulser.submit(GEPulse())
|
||||
}
|
||||
}
|
||||
checkCounter(500)
|
||||
return
|
||||
}
|
||||
|
||||
State.GE -> {
|
||||
geClerksloc = clerkLocationsGe.random()
|
||||
geWait = Random.nextInt(35, 100)
|
||||
geLongWait = Random.nextInt(350, 750)
|
||||
if (!sold) {
|
||||
if (randomNumberFromOne(500) <= 25){ scriptAPI.randomWalkTo(geClerksloc, randomNumberFromOne(4))}
|
||||
if (counter++ >= geWait) {
|
||||
scriptAPI.randomWalkTo(geClerksloc, randomNumberFromOne(1))
|
||||
sold = true
|
||||
counter = 0
|
||||
ticks = 0
|
||||
scriptAPI.sellAllOnGeAdv()
|
||||
state = State.TELEPORTING
|
||||
return
|
||||
}
|
||||
} else if (counter++ >= geLongWait) {
|
||||
state = State.TELEPORTING
|
||||
return
|
||||
}
|
||||
checkCounter(1000)
|
||||
return
|
||||
}
|
||||
|
||||
State.FIND_BANK -> {
|
||||
if (counter++ == 300) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
val bank: Scenery? = scriptAPI.getNearestNode("Bank booth", true) as Scenery?
|
||||
if (badedge.insideBorder(bot) || bot.location == badedge2 || bot.location == badedge3 || bot.location == badedge4) {
|
||||
bot.randomWalk(5, 5)
|
||||
}
|
||||
if (bank == null) state = State.EXPLORE
|
||||
class BankingPulse : MovementPulse(bot, bank, DestinationFlag.OBJECT) {
|
||||
override fun pulse(): Boolean {
|
||||
bot.faceLocation(bank?.location)
|
||||
state = State.IDLE_BANKS
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (bank != null) {
|
||||
bot.pulseManager.run(BankingPulse())
|
||||
if (bank == null) { state = State.TELEPORTING }
|
||||
if (bank != null && randomNumberFromOne(100) <= 5) {
|
||||
scriptAPI.depositAtBank()
|
||||
} else if (bank != null && randomNumberFromOne(100) <= 5){
|
||||
scriptAPI.randomWalkTo(bank.location,3)
|
||||
}
|
||||
checkCounter(500)
|
||||
return
|
||||
}
|
||||
|
||||
State.IDLE_BANKS -> {
|
||||
if (counter++ == 300) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
if (RandomFunction.random(1000) < 100) {
|
||||
for (item in bot.inventory.toArray()) {
|
||||
item ?: continue
|
||||
when (item.id) {
|
||||
1359, 590, 1271, 995 -> continue
|
||||
}
|
||||
bot.bank.add(item)
|
||||
bot.inventory.remove(item)
|
||||
}
|
||||
counter = 0
|
||||
state = State.EXPLORE
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
State.FIND_CITY -> {
|
||||
if (counter++ >= 600 || (city == ge || city == ge2)) {
|
||||
counter = 0
|
||||
if (counter++ >= 500 || cityLocationsGE.contains(city)){
|
||||
scriptAPI.teleport(getRandomCity().also { city = it })
|
||||
state = State.EXPLORE
|
||||
state = State.ADVENTURE
|
||||
}
|
||||
if (bot.location.equals(city)) {
|
||||
state = State.EXPLORE
|
||||
state = State.ADVENTURE
|
||||
} else {
|
||||
scriptAPI.randomWalkTo(city, 5)
|
||||
scriptAPI.randomWalkTo(city, randomNumberFromOne(10))
|
||||
}
|
||||
checkCounter(600)
|
||||
return
|
||||
}
|
||||
|
||||
State.IDLE_CITY -> {
|
||||
if (counter++ == 300) {
|
||||
state = State.TELEPORTING
|
||||
}
|
||||
var random = (120..300).random()
|
||||
if (counter++ == random && RandomFunction.random(1000) % 33 == 0) {
|
||||
counter = 0
|
||||
state = State.EXPLORE
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun dialogue() {
|
||||
val localPlayer = RegionManager.getLocalPlayers(bot).random()
|
||||
val until = 1225 - dateCode
|
||||
val lineStd = dialogue.getLines("standard").rand()
|
||||
var lineAlt = ""
|
||||
|
|
@ -455,20 +503,29 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand()
|
||||
}
|
||||
|
||||
val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd }
|
||||
.replace("@name", localPlayer.username)
|
||||
.replace("@timer", until.toString())
|
||||
|
||||
scriptAPI.sendChat(chat)
|
||||
var localPlayers = RegionManager.getLocalPlayers(bot)
|
||||
if (localPlayers.isNotEmpty()) {
|
||||
val localPlayer = localPlayers
|
||||
.filter { it.name != bot.name }
|
||||
.randomOrNull()
|
||||
if (localPlayer != null) {
|
||||
val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd }
|
||||
.replace("@name", localPlayer.username)
|
||||
.replace("@timer", until.toString())
|
||||
scriptAPI.sendChat(chat)
|
||||
} else {
|
||||
val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd }
|
||||
scriptAPI.sendChat(chat)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class State{
|
||||
START,
|
||||
EXPLORE,
|
||||
ADVENTURE,
|
||||
FIND_BANK,
|
||||
IDLE_BANKS,
|
||||
FIND_CITY,
|
||||
IDLE_CITY,
|
||||
IDLE_GE,
|
||||
GE,
|
||||
TELEPORTING,
|
||||
LOOT,
|
||||
|
|
@ -489,44 +546,94 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
val badedge = ZoneBorders(3094, 3494, 3096, 3497)
|
||||
val badedge2 = Location.create(3094, 3492, 0)
|
||||
val badedge3 = Location.create(3094, 3490, 0)
|
||||
val badedge4 = Location.create(3094, 3494, 0)
|
||||
|
||||
// Start Cities
|
||||
val yanille: Location = Location.create(2615, 3104, 0)
|
||||
val ardougne: Location = Location.create(2662, 3304, 0)
|
||||
val seers: Location = Location.create(2726, 3485, 0)
|
||||
val edgeville: Location = Location.create(3088, 3486, 0)
|
||||
val ge: Location = Location.create(3168, 3487, 0)
|
||||
val ge2: Location = Location.create(3161, 3493, 0)
|
||||
val catherby: Location = Location.create(2809, 3435, 0)
|
||||
val falador: Location = Location.create(2965, 3380, 0)
|
||||
val varrock: Location = Location.create(3213, 3428, 0)
|
||||
val draynor: Location = Location.create(3080, 3250, 0)
|
||||
val rimmington: Location = Location.create(2977, 3239, 0)
|
||||
val lumbridge: Location = Location.create(3222, 3219, 0)
|
||||
val karamja = Location.create(2849, 3033, 0)
|
||||
val alkharid = Location.create(3297, 3219, 0)
|
||||
val feldiphills = Location.create(2535, 2919, 0)
|
||||
val isafdar = Location.create(2241, 3217, 0)
|
||||
val eaglespeek = Location.create(2333, 3579, 0)
|
||||
val canafis = Location.create(3492, 3485, 0)
|
||||
val treegnome = Location.create(2437, 3441, 0)
|
||||
val teak1 = Location.create(2334, 3048, 0)
|
||||
val teakfarm = Location.create(2825, 3085, 0)
|
||||
val keldagrimout = Location.create(2724,3692,0)
|
||||
val miningguild = Location.create(3046,9740,0)
|
||||
val magics = Location.create(2285,3146,0)
|
||||
val coal = Location.create(2581,3481,0)
|
||||
val crawlinghands = Location.create(3422,3548,0)
|
||||
val gemrocks = Location.create(2825,2997,0)
|
||||
val chaosnpc = Location.create(2612,9484,0)
|
||||
val chaosnpc2 = Location.create(2580,9501,0)
|
||||
val taverly = Location.create(2909, 3436, 0)
|
||||
val karamja: Location = Location.create(2849, 3033, 0)
|
||||
val alkharid: Location = Location.create(3297, 3219, 0)
|
||||
|
||||
// Start POI
|
||||
val feldiphills: Location = Location.create(2535, 2919, 0)
|
||||
val isafdar: Location = Location.create(2241, 3217, 0)
|
||||
val eaglespeek: Location = Location.create(2333, 3579, 0)
|
||||
val canafis: Location = Location.create(3492, 3485, 0)
|
||||
val treegnome: Location = Location.create(2437, 3441, 0)
|
||||
val teak1: Location = Location.create(2334, 3048, 0)
|
||||
val teakfarm: Location = Location.create(2825, 3085, 0)
|
||||
val keldagrimout: Location = Location.create(2724,3692, 0)
|
||||
val miningguild: Location = Location.create(3046,9740, 0)
|
||||
val magics: Location = Location.create(2285,3146, 0)
|
||||
val coalTrucks: Location = Location.create(2581,3481, 0)
|
||||
val crawlinghands: Location = Location.create(3422,3548, 0)
|
||||
val gemrocks: Location = Location.create(2825,2997, 0)
|
||||
val chaosnpc: Location = Location.create(2612,9484, 0)
|
||||
val chaosnpc2: Location = Location.create(2586, 9501, 0)
|
||||
val varLumberYard: Location = Location.create(3289, 3482, 0)
|
||||
val taverly: Location = Location.create(2909, 3436, 0)
|
||||
|
||||
val swGEClerk: Location = Location.create(3164, 3487, 0)
|
||||
val neGEClerk: Location = Location.create(3165, 3492, 0)
|
||||
val nwGEBanker: Location = Location.create(3162, 3490, 0)
|
||||
val seGEBanker: Location = Location.create(3167, 3489, 0)
|
||||
|
||||
val badedge = ZoneBorders(3094, 3494, 3096, 3497)
|
||||
val badedge2: Location = Location.create(3094, 3492, 0)
|
||||
val badedge3: Location = Location.create(3094, 3490, 0)
|
||||
val badedge4: Location = Location.create(3094, 3494, 0)
|
||||
|
||||
var citygroupA = listOf(falador, varrock, draynor, rimmington, lumbridge, edgeville)
|
||||
var citygroupB = listOf(yanille, ardougne, seers, catherby)
|
||||
|
||||
val cities = listOf(
|
||||
swGEClerk, neGEClerk, nwGEBanker, seGEBanker,
|
||||
yanille, ardougne, seers, catherby,
|
||||
falador, varrock, draynor, rimmington,
|
||||
lumbridge, edgeville
|
||||
)
|
||||
|
||||
val pois = listOf(
|
||||
karamja, karamja, alkharid,
|
||||
alkharid, feldiphills, feldiphills,
|
||||
isafdar, eaglespeek, eaglespeek,
|
||||
canafis, treegnome, treegnome,
|
||||
teak1, teakfarm, keldagrimout,
|
||||
miningguild, coalTrucks, crawlinghands,
|
||||
magics, gemrocks, chaosnpc, chaosnpc,
|
||||
chaosnpc2, taverly,
|
||||
varLumberYard)
|
||||
|
||||
val cityLocationsGE = listOf(swGEClerk, neGEClerk, nwGEBanker, seGEBanker)
|
||||
|
||||
val socialLocationsGE = listOf(
|
||||
Location.create(3158, 3483, 0),
|
||||
Location.create(3165, 3480, 0),
|
||||
Location.create(3172, 3483, 0),
|
||||
Location.create(3174, 3489, 0),
|
||||
Location.create(3171, 3497, 0),
|
||||
Location.create(3164, 3499, 0),
|
||||
Location.create(3157, 3497, 0),
|
||||
Location.create(3155, 3489, 0),
|
||||
Location.create(3167, 3492, 0),
|
||||
Location.create(3162, 3492, 0),
|
||||
Location.create(3162, 3487, 0),
|
||||
Location.create(3167, 3487, 0)
|
||||
)
|
||||
|
||||
val clerkLocationsGe = listOf(
|
||||
Location.create(3165, 3492, 0),
|
||||
Location.create(3164, 3492, 0),
|
||||
Location.create(3164, 3487, 0),
|
||||
Location.create(3165, 3487, 0)
|
||||
)
|
||||
|
||||
var bankMap = mapOf<Location, ZoneBorders>(
|
||||
falador to ZoneBorders(2950, 3374, 2943, 3368),
|
||||
varrock to ZoneBorders(3182, 3435, 3189, 3446),
|
||||
|
|
@ -538,22 +645,10 @@ class Adventurer(val style: CombatStyle): Script() {
|
|||
catherby to ZoneBorders(2807, 3438, 2811, 3441)
|
||||
)
|
||||
|
||||
val cities = listOf(yanille, ardougne, seers, catherby, falador, varrock,
|
||||
draynor, rimmington, lumbridge, ge, ge2, edgeville)
|
||||
|
||||
val pois = listOf(
|
||||
karamja, karamja, alkharid,
|
||||
alkharid, feldiphills, feldiphills,
|
||||
isafdar, eaglespeek, eaglespeek,
|
||||
canafis, treegnome, treegnome,
|
||||
teak1, teakfarm, keldagrimout,
|
||||
miningguild, coal, crawlinghands,
|
||||
magics, gemrocks, chaosnpc, chaosnpc,
|
||||
chaosnpc2, taverly)
|
||||
|
||||
private val whiteWolfMountainTop = Location(2850, 3496, 0)
|
||||
private val catherbyToTopOfWhiteWolf = arrayOf(Location(2856, 3442, 0), Location(2848, 3455, 0), Location(2848, 3471, 0), Location(2848, 3487, 0))
|
||||
private val tavleryToTopOfWhiteWolf = arrayOf(Location(2872, 3425, 0), Location(2863, 3440, 0), Location(2863, 3459, 0), Location(2854, 3475, 0), Location(2859, 3488, 0))
|
||||
|
||||
val common_stuck_locations = mapOf(
|
||||
// South of Tavlery dungeon
|
||||
ZoneBorders(2878, 3386, 2884, 3395) to { it: Adventurer ->
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import core.api.*
|
|||
import core.game.bots.*
|
||||
import core.game.ge.GrandExchange
|
||||
import core.game.interaction.DestinationFlag
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListeners
|
||||
import core.game.interaction.MovementPulse
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.skill.Skills
|
||||
|
|
@ -16,6 +14,7 @@ import core.game.node.item.Item
|
|||
import core.game.world.map.Location
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import org.rs09.consts.Items
|
||||
import content.data.Quests
|
||||
|
||||
@PlayerCompatible
|
||||
@ScriptName("Falador Cannonball Smelter")
|
||||
|
|
@ -273,6 +272,6 @@ class CannonballSmelter : Script() {
|
|||
skills.put(Skills.HITPOINTS,99)
|
||||
skills.put(Skills.DEFENCE,99)
|
||||
skills.put(Skills.SMITHING,35)
|
||||
quests.add("Dwarf Cannon")
|
||||
quests.add(Quests.DWARF_CANNON)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,18 +45,7 @@ class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin
|
|||
|
||||
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 switch my default bank account.", 7),
|
||||
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),
|
||||
|
|
@ -78,6 +67,53 @@ class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin
|
|||
"Leave your valuables with us if you want to keep them safe."
|
||||
).also { stage = END_DIALOGUE }
|
||||
|
||||
7 -> showTopics(
|
||||
IfTopic(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"I'd like to turn on the Clan bank, please.",
|
||||
8,
|
||||
!(player.getAttribute("clanbank:enabled",false))
|
||||
),
|
||||
IfTopic(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"I'd like to turn off the Clan bank, please.",
|
||||
9,
|
||||
player.getAttribute("clanbank:enabled",false)
|
||||
),
|
||||
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)
|
||||
),
|
||||
)
|
||||
|
||||
8 -> {
|
||||
player.setAttribute("/save:clanbank:enabled", true)
|
||||
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"The Clan bank has been enabled. " +
|
||||
"If the Clan owner is online, you will access their primary bank account instead of your own."
|
||||
).also { stage = 2 }
|
||||
}
|
||||
|
||||
9 -> {
|
||||
player.removeAttribute("clanbank:enabled")
|
||||
|
||||
npcl(
|
||||
core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
"The Clan bank has been disabled. " +
|
||||
"You will now always open your personal bank account."
|
||||
).also { stage = 2 }
|
||||
}
|
||||
|
||||
10 -> {
|
||||
openBankAccount(player)
|
||||
end()
|
||||
|
|
|
|||
|
|
@ -3,160 +3,227 @@ package content.global.dialogue
|
|||
import content.global.skill.farming.FarmerPayOptionDialogue
|
||||
import content.global.skill.farming.Farmers
|
||||
import content.global.skill.farming.FarmingPatch
|
||||
import core.game.node.entity.npc.NPC
|
||||
import content.global.skill.farming.PatchType
|
||||
import core.api.*
|
||||
import core.game.dialogue.FacialExpression
|
||||
import core.game.dialogue.IfTopic
|
||||
import core.game.dialogue.Topic
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.plugin.Initializable
|
||||
import org.rs09.consts.Items
|
||||
import core.tools.END_DIALOGUE
|
||||
import core.tools.START_DIALOGUE
|
||||
|
||||
@Initializable
|
||||
class GardenerDialoguePlugin(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) {
|
||||
override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin {
|
||||
return GardenerDialoguePlugin(player)
|
||||
}
|
||||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
npc = args[0] as NPC
|
||||
options("Would you look after my crops for me?","Can you sell me something?")
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
when(stage){
|
||||
0 -> when(buttonId){
|
||||
1 -> player("Would you look after my crops for me?").also { stage = 10 }
|
||||
2 -> player("Can you sell me something?").also { stage = 30 }
|
||||
val patches = Farmers.forId(npc.id)!!.patches
|
||||
when (stage) {
|
||||
// TODO: Can fruit trees be chopped down by the gardener too?
|
||||
START_DIALOGUE -> {
|
||||
val patch = patches[0].getPatchFor(player)
|
||||
showTopics(
|
||||
IfTopic(
|
||||
FacialExpression.ASKING,
|
||||
"Would you chop my tree down for me?",
|
||||
1000,
|
||||
patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown()
|
||||
),
|
||||
IfTopic(
|
||||
FacialExpression.ASKING,
|
||||
"Would you look after my crops for me?",
|
||||
10,
|
||||
!(patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown())
|
||||
),
|
||||
Topic(FacialExpression.ASKING, "Can you give me any farming advice?", 2000),
|
||||
Topic(FacialExpression.ASKING, "Can you sell me something?", 30),
|
||||
Topic(FacialExpression.NEUTRAL, "That's all, thanks.", END_DIALOGUE)
|
||||
)
|
||||
}
|
||||
|
||||
10 -> npc("I might. Which one were you thinking of?").also { stage++ }
|
||||
11 -> when(npc.id){
|
||||
Farmers.ELSTAN.id, Farmers.LYRA.id -> options("The north-western allotment.","The south-eastern allotment.").also { stage = 15 }
|
||||
Farmers.DANTAERA.id, Farmers.KRAGEN.id -> options("The north allotment.","The south allotment.").also { stage = 15 }
|
||||
else -> player("Uh, that one.").also { stage++ }
|
||||
10 -> {
|
||||
if (patches.size > 1) {
|
||||
npc("I might. Which one were you thinking of?").also { stage = 20 }
|
||||
} else {
|
||||
openPayGardenerDialogue(player, patches[0])
|
||||
}
|
||||
}
|
||||
|
||||
12 -> npc("Oh, right. My bad.").also { stage++ }
|
||||
13 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[0])
|
||||
|
||||
15 -> when(buttonId){
|
||||
1 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[0])
|
||||
2 -> checkPatch(player,Farmers.forId(npc.id)!!.patches[1])
|
||||
20 -> when (npc.id) {
|
||||
Farmers.ELSTAN.id, Farmers.LYRA.id -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "The north-western allotment.", 21),
|
||||
Topic(FacialExpression.NEUTRAL, "The south-eastern allotment.", 22)
|
||||
)
|
||||
Farmers.DANTAERA.id, Farmers.KRAGEN.id -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "The northern allotment.", 21),
|
||||
Topic(FacialExpression.NEUTRAL, "The southern allotment.", 22)
|
||||
)
|
||||
}
|
||||
21 -> openPayGardenerDialogue(player, patches[0])
|
||||
22 -> openPayGardenerDialogue(player, patches[1])
|
||||
|
||||
30 -> npc("That depends on whether I have it to sell.","What is it that you're looking for?").also { stage++ }
|
||||
31 -> options("Some plant cure.","A bucket of compost.","A rake.","(See more items)").also { stage = 32 }
|
||||
32 -> when(buttonId){
|
||||
1 -> player("Some plant cure.").also { stage = 100 }
|
||||
2 -> player("A bucket of compost.").also { stage = 200 }
|
||||
3 -> player("A rake.").also { stage = 300 }
|
||||
4 -> options("A watering can.","A gardening trowel.","A seed dibber.","(See previous items)").also { stage++ }
|
||||
}
|
||||
33 -> when(buttonId){
|
||||
1 -> player("A watering can.").also { stage = 400 }
|
||||
2 -> player("A gardening trowel.").also { stage = 500 }
|
||||
3 -> player("A seed dibber.").also { stage = 600 }
|
||||
4 -> options("Some plant cure.","A bucket of compost.","A rake.","(See more items)").also { stage = 32 }
|
||||
}
|
||||
30 -> npc(FacialExpression.NEUTRAL, "That depends on whether I have it to sell. What is it", "that you're looking for?").also { stage++ }
|
||||
31 -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "Some plant cure.", 100),
|
||||
Topic(FacialExpression.NEUTRAL, "A bucket of compost.", 200),
|
||||
Topic(FacialExpression.NEUTRAL, "A rake.", 300),
|
||||
Topic("(See more items)", 32, true)
|
||||
)
|
||||
32 -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "A watering can.", 400),
|
||||
Topic(FacialExpression.NEUTRAL, "A gardening trowel.", 500),
|
||||
Topic(FacialExpression.NEUTRAL, "A seed dibber.", 600),
|
||||
Topic("(See previous items)", 31, true),
|
||||
Topic(FacialExpression.NEUTRAL, "Forget it.", 40, true)
|
||||
)
|
||||
|
||||
100 -> npc("Plant cure, eh? I might have some put aside for myself.","Tell you what, I'll sell you some plant cure","for 25 gp if you like.").also { stage++ }
|
||||
101 -> options("Yes, that sounds like a fair price.","No thanks, I can get that much cheaper.").also { stage++ }
|
||||
102 -> when(buttonId){
|
||||
40 -> player("Forget it, you don't have anything I need.").also { stage = END_DIALOGUE }
|
||||
|
||||
100 -> npc("Plant cure, eh? I might have some put aside for myself.", "Tell you what. I'll sell you some plant cure for 25 gp if", "you like.").also { stage++ }
|
||||
101 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
102 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,25))){
|
||||
player.inventory.add(Item(Items.PLANT_CURE_6036))
|
||||
player(FacialExpression.HAPPY, "Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if (removeItem(player, Item(Items.COINS_995, 25))) {
|
||||
addItemOrDrop(player, Items.PLANT_CURE_6036)
|
||||
} else {
|
||||
player.sendMessage("You need 25 gp to pay for that.")
|
||||
sendMessage(player, "You need 25 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
200 -> npc("A bucket of compost, eh? I might have one spare...","tell you what, I'll sell it to you for 35 gp if you like.").also { stage++ }
|
||||
201 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
202 -> when(buttonId){
|
||||
200 -> npc("A bucket of compost, eh? I might have one spare...", "tell you what, I'll sell it to you for 35 gp if you like.").also { stage++ }
|
||||
201 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
202 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,35))){
|
||||
player.inventory.add(Item(Items.COMPOST_6032))
|
||||
if (removeItem(player, Item(Items.COINS_995, 35))) {
|
||||
addItemOrDrop(player, Items.COMPOST_6032)
|
||||
} else {
|
||||
player.sendMessage("You need 35 gp to pay for that.")
|
||||
sendMessage(player, "You need 35 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
300 -> npc("A rake, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
301 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
302 -> when(buttonId){
|
||||
300 -> npc("A rake, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
301 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
302 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,15))){
|
||||
player.inventory.add(Item(Items.RAKE_5341))
|
||||
if (removeItem(player, Item(Items.COINS_995, 15))) {
|
||||
addItemOrDrop(player, Items.RAKE_5341)
|
||||
} else {
|
||||
player.sendMessage("You need 15 gp to pay for that.")
|
||||
sendMessage(player, "You need 15 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
400 -> npc("A watering can, eh? I might have one spare...","tell you what, I'll sell it to you for 25 gp if you like.").also { stage++ }
|
||||
401 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
400 -> npc("A watering can, eh? I might have one spare...", "tell you what, I'll sell it to you for 25 gp if you like.").also { stage++ }
|
||||
401 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
402 -> when(buttonId){
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,25))){
|
||||
player.inventory.add(Item(Items.WATERING_CAN8_5340))
|
||||
if (removeItem(player, Item(Items.COINS_995, 25))) {
|
||||
addItemOrDrop(player, Items.WATERING_CAN8_5340)
|
||||
} else {
|
||||
player.sendMessage("You need 25 gp to pay for that.")
|
||||
sendMessage(player, "You need 25 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
500 -> npc("A gardening trowel, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
501 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
502 -> when(buttonId){
|
||||
500 -> npc("A gardening trowel, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
501 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
502 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,15))){
|
||||
player.inventory.add(Item(Items.GARDENING_TROWEL_5325))
|
||||
if (removeItem(player, Item(Items.COINS_995, 15))) {
|
||||
addItemOrDrop(player, Items.GARDENING_TROWEL_5325)
|
||||
} else {
|
||||
player.sendMessage("You need 15 gp to pay for that.")
|
||||
sendMessage(player, "You need 15 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
600 -> npc("A seed dibber, eh? I might have one spare...","tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
601 -> options("Yes, that sounds fair.","No thanks, I can get that cheaper.").also { stage++ }
|
||||
602 -> when(buttonId){
|
||||
600 -> npc("A seed dibber, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ }
|
||||
601 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ }
|
||||
602 -> when (buttonId) {
|
||||
1 -> {
|
||||
player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE }
|
||||
if(player.inventory.remove(Item(995,15))){
|
||||
player.inventory.add(Item(Items.SEED_DIBBER_5343))
|
||||
if (removeItem(player, Item(Items.COINS_995, 15))) {
|
||||
addItemOrDrop(player, Items.SEED_DIBBER_5343)
|
||||
} else {
|
||||
player.sendMessage("You need 15 gp to pay for that.")
|
||||
sendMessage(player, "You need 15 gp to pay for that.")
|
||||
}
|
||||
}
|
||||
2 -> end()
|
||||
2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE }
|
||||
}
|
||||
|
||||
// Note: This dialogue changes slightly in April 2009, and significantly in December 2009
|
||||
1000 -> npc(FacialExpression.THINKING, "Why? You look like you could chop it down yourself!").also { stage++ }
|
||||
1001 -> showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "Yes, you're right - I'll do it myself.", END_DIALOGUE),
|
||||
Topic(FacialExpression.NEUTRAL, "I can't be bothered - I'd rather pay you to do it.", 1020)
|
||||
)
|
||||
|
||||
1020 -> npc(FacialExpression.NEUTRAL, "Well, it's a lot of hard work - if you pay me 200 GP", "I'll chop it down for you.").also { stage++ }
|
||||
1021 -> {
|
||||
if (inInventory(player, Items.COINS_995, 200)) {
|
||||
showTopics(
|
||||
Topic(FacialExpression.NEUTRAL, "Here's 200GP - chop my tree down please.", 1022),
|
||||
Topic(FacialExpression.NEUTRAL, "I don't want to pay that much, sorry.", END_DIALOGUE)
|
||||
)
|
||||
} else {
|
||||
player("I don't have that much money on me.").also { stage = END_DIALOGUE } // not authentic
|
||||
}
|
||||
}
|
||||
1022 -> {
|
||||
end()
|
||||
if (removeItem(player, Item(Items.COINS_995, 200))) {
|
||||
patches[0].getPatchFor(player).clear()
|
||||
}
|
||||
}
|
||||
|
||||
2000 -> {
|
||||
val advice = arrayOf(
|
||||
"There are four main Farming areas - Elstan looks after an area south of Falador, Dantaera has one to the north of Catherby, Kragen has one near Ardougne, and Lyra looks after a place in north Morytania.",
|
||||
"If you want to grow fruit trees you could try a few places: Catherby and Brimhaven have a couple of fruit tree patches, and I hear that the gnomes are big on that sort of thing.",
|
||||
"Bittercap mushrooms can only be grown in a special patch in Morytania, near the Mort Myre swamp. There the ground is especially dank and suited to growing poisonous fungi.",
|
||||
"There is a special patch for growing Belladonna - I believe it's somewhere near Draynor Manor, where the ground is a tad 'unblessed'.",
|
||||
|
||||
"Don't just throw away your weeds after you've raked a patch - put them in a compost bin and make some compost.",
|
||||
"Applying compost to a patch will not only reduce the chance that your crops will get diseased, but you will also grow more crops to harvest.",
|
||||
"Supercompost is far better than normal compost, but more expensive to make. You need to rot the right type of item; show me an item, and I'll tell you if it's super-compostable or not.",
|
||||
|
||||
"Tree seeds must be grown in a plantpot of soil into a sapling, and then transferred to a tree patch to continue growing to adulthood.",
|
||||
"You don't have to buy all your plantpots you know, you can make them yourself on a pottery wheel. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.",
|
||||
"You can fill plantpots with soil from Farming patches, if you have a gardening trowel.",
|
||||
|
||||
"Vegetables, hops and flowers are far more likely to grow healthily if you water them periodically.",
|
||||
"The only way to cure a bush or tree of disease is to prune away the diseased leaves with a pair of secateurs. For all other crops I would just apply some plant-cure.",
|
||||
"If you need to be rid of your fruit trees for any reason, all you have to do is chop them down and then dig up the stump.",
|
||||
|
||||
"You can put up to ten potatoes, cabbages or onions in vegetable sacks, although you can't have a mix in the same sack.",
|
||||
"You can put up to five tomatoes, strawberries, apples, bananas or oranges into a fruit basket, although you can't have a mix in the same basket.",
|
||||
"If you want to make your own sacks and baskets you'll need to use the loom that's near the Farming shop in Falador. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.",
|
||||
"You can buy all the farming tools from farming shops, which can be found close to the allotments.",
|
||||
|
||||
"Hops are good for brewing ales. I believe there's a brewery up in Keldagrim somewhere, and I've heard rumours that a place called Phasmatys used to be good for that type of thing. 'Fore they all died, of course.",
|
||||
)
|
||||
npcl(FacialExpression.NEUTRAL, advice.random()).also { stage = START_DIALOGUE }
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun checkPatch(player: Player,fPatch: FarmingPatch){
|
||||
if(fPatch.getPatchFor(player).isWeedy()){
|
||||
npc("You don't have anything planted in that patch.","Plant something and I might agree to look after it for you.").also { stage = END_DIALOGUE }
|
||||
} else if(fPatch.getPatchFor(player).isGrown()){
|
||||
npc("That patch is already fully grown!","I don't know what you want me to do with it!").also { stage = END_DIALOGUE }
|
||||
} else if(fPatch.getPatchFor(player).protectionPaid) {
|
||||
npc("Are you alright? You've already", "paid me for that.").also { stage = END_DIALOGUE }
|
||||
} else {
|
||||
end()
|
||||
player.dialogueInterpreter.open(FarmerPayOptionDialogue(fPatch.getPatchFor(player)),npc)
|
||||
}
|
||||
fun openPayGardenerDialogue(player: Player, fPatch: FarmingPatch) {
|
||||
end()
|
||||
openDialogue(player, FarmerPayOptionDialogue(fPatch.getPatchFor(player)), npc)
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public class ManDialoguePlugin extends DialoguePlugin {
|
|||
/**
|
||||
* The NPC ids that use this dialogue plugin.
|
||||
*/
|
||||
private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 351, 352, 353, 354, 359, 360, 361, 362, 363, 726, 727, 728, 729, 730, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,};
|
||||
private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,};
|
||||
|
||||
public ManDialoguePlugin() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,17 +36,21 @@ public final class ClanInterfacePlugin extends ComponentPlugin {
|
|||
switch (component.getId()) {
|
||||
case 589:
|
||||
switch (button) {
|
||||
case 9:
|
||||
if (player.getInterfaceManager().getComponent(590) != null) {
|
||||
player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'");
|
||||
case 9:
|
||||
if (player.getInterfaceManager().getComponent(590) != null) {
|
||||
player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'");
|
||||
return true;
|
||||
}
|
||||
ClanRepository.openSettings(player);
|
||||
return true;
|
||||
}
|
||||
ClanRepository.openSettings(player);
|
||||
return true;
|
||||
case 14:
|
||||
player.getDetails().getCommunication().toggleLootshare(player);
|
||||
return true;
|
||||
case 14:
|
||||
if (player.getIronmanManager().checkRestriction()) {
|
||||
return false;
|
||||
}
|
||||
player.getDetails().getCommunication().toggleLootshare(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case 590:
|
||||
final ClanRepository clan = ClanRepository.get(player.getName(), true);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import core.plugin.Initializable
|
|||
import core.plugin.Plugin
|
||||
import core.tools.Log
|
||||
import org.rs09.consts.Sounds
|
||||
import content.data.Quests
|
||||
|
||||
/**
|
||||
* Represents the experience interface.
|
||||
|
|
@ -78,15 +79,15 @@ class ExperienceInterface() : ComponentPlugin() {
|
|||
}
|
||||
|
||||
private fun checkHerblore(player: Player): Boolean{
|
||||
return (player.questRepository.isComplete("Druidic Ritual"))
|
||||
return (player.questRepository.isComplete(Quests.DRUIDIC_RITUAL))
|
||||
}
|
||||
|
||||
private fun checkSummoning(player: Player): Boolean{
|
||||
return player.questRepository.isComplete("Wolf Whistle")
|
||||
return player.questRepository.isComplete(Quests.WOLF_WHISTLE)
|
||||
}
|
||||
|
||||
private fun checkRunecrafting(player: Player): Boolean{
|
||||
return player.questRepository.isComplete("Rune Mysteries")
|
||||
return player.questRepository.isComplete(Quests.RUNE_MYSTERIES)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -2,109 +2,130 @@ package content.global.handlers.iface
|
|||
|
||||
import core.api.*
|
||||
import core.game.event.FairyRingDialEvent
|
||||
import core.game.component.Component
|
||||
import core.game.interaction.InterfaceListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.system.task.Pulse
|
||||
import core.game.world.GameWorld
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionManager
|
||||
import core.tools.RandomFunction
|
||||
import core.game.interaction.InterfaceListener
|
||||
import core.game.world.GameWorld
|
||||
|
||||
val RING_1 = arrayOf('a','d','c','b')
|
||||
val RING_2 = arrayOf('i','l','k','j')
|
||||
val RING_3 = arrayOf('p','s','r','q')
|
||||
import content.data.Quests
|
||||
|
||||
/**
|
||||
* Handles the fairy ring interface
|
||||
* @author Ceikry
|
||||
*/
|
||||
class FairyRingInterface : InterfaceListener {
|
||||
|
||||
val RINGS = 734
|
||||
val TRAVEL_LOG = 735
|
||||
companion object {
|
||||
const val RINGS_IFACE = 734
|
||||
const val LOG_IFACE_ID = 735
|
||||
const val VARP_F_RING = 816
|
||||
const val VB_LOG_SORT_ORDER = 4618
|
||||
const val VB_RING_1 = 2341
|
||||
const val VB_RING_2 = 2342
|
||||
const val VB_RING_3 = 2343
|
||||
val RING_1 = arrayOf('a','d','c','b')
|
||||
val RING_2 = arrayOf('i','l','k','j')
|
||||
val RING_3 = arrayOf('p','s','r','q')
|
||||
}
|
||||
|
||||
override fun defineInterfaceListeners() {
|
||||
|
||||
onOpen(RINGS){player, _ ->
|
||||
player.interfaceManager.openSingleTab(Component(TRAVEL_LOG))
|
||||
player.setAttribute("fr:ring1", 0)
|
||||
player.setAttribute("fr:ring2", 0)
|
||||
player.setAttribute("fr:ring3", 0)
|
||||
FairyRing.drawLog(player)
|
||||
onOpen(RINGS_IFACE){ player, _ ->
|
||||
openSingleTab(player, LOG_IFACE_ID)
|
||||
saveVarp(player, VARP_F_RING)
|
||||
return@onOpen true
|
||||
}
|
||||
|
||||
onClose(RINGS){player, _ ->
|
||||
closeTabInterface(player)
|
||||
player.removeAttribute("fr:ring1")
|
||||
player.removeAttribute("fr:ring2")
|
||||
player.removeAttribute("fr:ring3")
|
||||
setVarp(player, 816, 0)
|
||||
onOpen(LOG_IFACE_ID){ player, _ ->
|
||||
drawLog(player)
|
||||
return@onOpen true
|
||||
}
|
||||
|
||||
onClose(RINGS_IFACE){ player, _ ->
|
||||
closeTabInterface(player)
|
||||
return@onClose true
|
||||
}
|
||||
|
||||
on(RINGS){player, _, _, buttonID, _, _ ->
|
||||
if(player.getAttribute("fr:time",0L) > System.currentTimeMillis()) return@on true
|
||||
var delayIncrementer = 1750L
|
||||
on(RINGS_IFACE){ player, _, _, buttonID, _, _ ->
|
||||
when(buttonID){
|
||||
23 -> delayIncrementer += increment(player,1)
|
||||
25 -> delayIncrementer += increment(player,2)
|
||||
27 -> delayIncrementer += increment(player,3)
|
||||
23 -> increment(player,1)
|
||||
25 -> increment(player,2)
|
||||
27 -> increment(player,3)
|
||||
24 -> decrement(player,1)
|
||||
26 -> decrement(player,2)
|
||||
28 -> decrement(player,3)
|
||||
21 -> confirm(player)
|
||||
}
|
||||
player.setAttribute("fr:time",System.currentTimeMillis() + delayIncrementer)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(TRAVEL_LOG,12){player, _, _, _, _, _ ->
|
||||
on(LOG_IFACE_ID,12){ player, _, _, _, _, _ ->
|
||||
toggleSortOrder(player)
|
||||
return@on true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun toggleSortOrder(player: Player): Long{
|
||||
val ring1index = player.getAttribute("fr:ring1",0)
|
||||
var toSet = player.getAttribute("fr:sortorder",true)
|
||||
toSet = !toSet
|
||||
player.setAttribute("fr:sortorder",toSet)
|
||||
if(toSet) {
|
||||
setVarp(player, 816, ring1index)
|
||||
player.setAttribute("fr:ring2",0)
|
||||
player.setAttribute("fr:ring3",0)
|
||||
/**
|
||||
* Draws the travel log interface
|
||||
* Currently, the visited logs is a bool array in globalData. Someone should migrate this to prefs or something at some point.
|
||||
* On transmit of Varp 816, which all used varbits are part of here, the CS2 is invoked to populate the codes in the log and sort them correctly.
|
||||
* @param player The player to draw the interface for
|
||||
*/
|
||||
private fun drawLog (player: Player)
|
||||
{
|
||||
for (i in FairyRing.values().indices) {
|
||||
/* Snowscape: show all fairy ring destinations, whether they have been there or not.
|
||||
if (!player.savedData.globalData.hasTravelLog(i)) {
|
||||
continue
|
||||
}
|
||||
*/
|
||||
val ring = FairyRing.values()[i]
|
||||
if (ring.childId == -1) {
|
||||
continue
|
||||
}
|
||||
setInterfaceText(player, "<br>${ring.tip}", LOG_IFACE_ID, ring.childId)
|
||||
}
|
||||
return -1750L
|
||||
}
|
||||
|
||||
fun increment(player: Player,ring: Int): Long{
|
||||
val curIndex = player.getAttribute("fr:ring$ring",0)
|
||||
var nextIndex = 0
|
||||
if(curIndex == 3) nextIndex = 0
|
||||
else if(curIndex == 1) nextIndex = 3
|
||||
else if(curIndex == 2) nextIndex = 2
|
||||
else nextIndex = curIndex + 1
|
||||
player.setAttribute("fr:ring$ring",nextIndex)
|
||||
return if (curIndex == 1) 1750L else 0L
|
||||
private fun toggleSortOrder(player: Player) {
|
||||
val curSort = getVarbit(player, VB_LOG_SORT_ORDER) == 0
|
||||
setVarbit(player, VB_LOG_SORT_ORDER, if (curSort) 1 else 0)
|
||||
drawLog(player)
|
||||
}
|
||||
|
||||
fun increment(player: Player,ring: Int) {
|
||||
val vbit = when(ring) {
|
||||
1 -> VB_RING_1
|
||||
2 -> VB_RING_2
|
||||
3 -> VB_RING_3
|
||||
else -> return
|
||||
}
|
||||
val curIndex = getVarbit(player, vbit)
|
||||
val nextIndex: Int = if(curIndex == 3) 0
|
||||
else curIndex + 1
|
||||
setVarbit(player, vbit, nextIndex)
|
||||
}
|
||||
|
||||
fun decrement(player: Player,ring: Int){
|
||||
val curIndex = player.getAttribute("fr:ring$ring",0)
|
||||
var nextIndex = 0
|
||||
if(curIndex == 0) nextIndex = 3
|
||||
else nextIndex = curIndex - 1
|
||||
player.setAttribute("fr:ring$ring",nextIndex)
|
||||
val vbit = when(ring) {
|
||||
1 -> VB_RING_1
|
||||
2 -> VB_RING_2
|
||||
3 -> VB_RING_3
|
||||
else -> return
|
||||
}
|
||||
val curIndex = getVarbit(player, vbit)
|
||||
val nextIndex: Int = if(curIndex == 0) 3
|
||||
else curIndex - 1
|
||||
setVarbit(player, vbit, nextIndex)
|
||||
}
|
||||
|
||||
private fun confirm(player: Player){
|
||||
val ring1index = player.getAttribute("fr:ring1",0)
|
||||
val ring2index = player.getAttribute("fr:ring2",0)
|
||||
val ring3index = player.getAttribute("fr:ring3",0)
|
||||
val ring1index = getVarbit(player, VB_RING_1)
|
||||
val ring2index = getVarbit(player, VB_RING_2)
|
||||
val ring3index = getVarbit(player, VB_RING_3)
|
||||
val code = "${RING_1[ring1index]}${RING_2[ring2index]}${RING_3[ring3index]}"
|
||||
val ring: FairyRing? = try {
|
||||
FairyRing.valueOf(code.uppercase())
|
||||
|
|
@ -160,7 +181,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
AKS(Location.create(2571, 2956, 0), "Feldip Hills: Jungle Hunter area", 25),
|
||||
ALQ(Location.create(3597, 3495, 0), "Morytania: Haunted Woods east of Canifis", 27) {
|
||||
override fun checkAccess(player: Player) : Boolean {
|
||||
return requireQuest(player, "Priest in Peril", "to use this ring.")
|
||||
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.")
|
||||
}
|
||||
},
|
||||
ALS(Location.create(2644, 3495, 0), "Kandarin: McGrubor's Wood", 29),
|
||||
|
|
@ -172,7 +193,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
BKQ(Location.create(3041, 4532, 0), "Other realms: Enchanted Valley", 39),
|
||||
BKR(Location.create(3469, 3431, 0), "Morytania: Mort Myre, south of Canifis", 40) {
|
||||
override fun checkAccess(player: Player) : Boolean {
|
||||
return requireQuest(player, "Priest in Peril", "to use this ring.")
|
||||
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.")
|
||||
}
|
||||
},
|
||||
BLP(Location.create(2437, 5126, 0), "Dungeons: TzHaar area", 42),
|
||||
|
|
@ -180,7 +201,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
BLR(Location.create(2740, 3351, 0), "Kandarin: Legends' Guild", 44),
|
||||
CIP(Location.create(2513, 3884, 0), "Islands: Miscellania", 46) {
|
||||
override fun checkAccess(player: Player): Boolean {
|
||||
return requireQuest(player, "Fremennik Trials", "to use this ring.")
|
||||
return requireQuest(player, Quests.THE_FREMENNIK_TRIALS, "to use this ring.")
|
||||
}
|
||||
},
|
||||
CIQ(Location.create(2528, 3127, 0), "Kandarin: North-west of Yanille", 47),
|
||||
|
|
@ -189,7 +210,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
CKR(Location.create(2801, 3003, 0), "Karamja: South of Tai Bwo Wannai Village", 56),
|
||||
CKS(Location.create(3447, 3470, 0), "Morytania: Canifis", 57) {
|
||||
override fun checkAccess(player: Player) : Boolean {
|
||||
return requireQuest(player, "Priest in Peril", "to use this ring.")
|
||||
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.")
|
||||
}
|
||||
},
|
||||
CLP(Location.create(3082, 3206, 0), "Islands: South of Draynor Village", 58),
|
||||
|
|
@ -208,23 +229,4 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
|
|||
open fun checkAccess(player: Player) : Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Draws the travel log.
|
||||
* @param player the player.
|
||||
*/
|
||||
fun drawLog(player: Player) {
|
||||
for (i in FairyRing.values().indices) {
|
||||
if (!player.savedData.globalData.hasTravelLog(i)) {
|
||||
continue
|
||||
}
|
||||
val ring = FairyRing.values()[i]
|
||||
if (ring.childId == -1) {
|
||||
continue
|
||||
}
|
||||
setInterfaceText(player, "<br>${ring.tip}", 735, ring.childId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,7 @@ public final class JewelleryInterface extends ComponentPlugin {
|
|||
amount = 5;
|
||||
break;
|
||||
case 124:
|
||||
/* No need to calculate the maximum amount here, because the make() function will perform that step
|
||||
if (data.name().contains("GOLD")) {
|
||||
amount = player.getInventory().getAmount(new Item(GOLD_BAR));
|
||||
} else {
|
||||
|
|
@ -178,6 +179,8 @@ public final class JewelleryInterface extends ComponentPlugin {
|
|||
amount = first;
|
||||
}
|
||||
}
|
||||
*/
|
||||
amount = 99;
|
||||
break;
|
||||
case 199:
|
||||
final JewelleryItem d = data;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ import core.game.node.entity.player.link.SpellBookManager.SpellBook;
|
|||
import core.game.world.GameWorld;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
import content.data.Quests;
|
||||
import static core.api.ContentAPIKt.hasRequirement;
|
||||
|
||||
/**
|
||||
* Represents the magic book interface handling of non-combat spells.
|
||||
* @author 'Vexia
|
||||
|
|
@ -42,9 +45,44 @@ public final class MagicBookInterface extends ComponentPlugin {
|
|||
? SpellBook.ANCIENT
|
||||
: SpellBook.LUNAR;
|
||||
|
||||
// Snowscape: Allow switching between unlocked spellbooks with the magic interface sort buttons
|
||||
if (spellBook == SpellBook.MODERN) {
|
||||
if (button == 65 && swapSpellBook(player, SpellBook.ANCIENT)) {
|
||||
return true;
|
||||
} else if (button == 66 && swapSpellBook(player, SpellBook.LUNAR)) {
|
||||
return true;
|
||||
}
|
||||
} else if (spellBook == SpellBook.ANCIENT) {
|
||||
if (button == 29 && swapSpellBook(player, SpellBook.MODERN)) {
|
||||
return true;
|
||||
} else if (button == 31 && swapSpellBook(player, SpellBook.LUNAR)) {
|
||||
return true;
|
||||
}
|
||||
} else if (spellBook == SpellBook.LUNAR) {
|
||||
if (button == 40 && swapSpellBook(player, SpellBook.MODERN)) {
|
||||
return true;
|
||||
} else if (button == 41 && swapSpellBook(player, SpellBook.ANCIENT)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SpellListeners.run(button, SpellListener.NONE, SpellUtils.getBookFromInterface(component.getId()),player,null);
|
||||
boolean result = MagicSpell.castSpell(player, spellBook, button, player);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Snowscape custom function
|
||||
private boolean swapSpellBook(final Player player, SpellBook spellBook) {
|
||||
if (spellBook == SpellBook.ANCIENT && !hasRequirement(player, Quests.DESERT_TREASURE)) {
|
||||
return false;
|
||||
} else if (spellBook == SpellBook.LUNAR && !hasRequirement(player, Quests.LUNAR_DIPLOMACY)) {
|
||||
return false;
|
||||
}
|
||||
player.getSpellBookManager().setSpellBook(spellBook);
|
||||
player.getSpellBookManager().update(player);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import core.plugin.Initializable;
|
|||
import core.plugin.Plugin;
|
||||
|
||||
import static core.api.ContentAPIKt.hasRequirement;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Represents the prayer interface.
|
||||
|
|
@ -27,7 +28,7 @@ public final class PrayerTabInterface extends ComponentPlugin {
|
|||
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
|
||||
final PrayerType type = PrayerType.get(button);
|
||||
if (type == PrayerType.CHIVALRY || type == PrayerType.PIETY)
|
||||
if (!hasRequirement(player, "King's Ransom"))
|
||||
if (!hasRequirement(player, Quests.KINGS_RANSOM))
|
||||
return true;
|
||||
if (type == null) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ import kotlin.math.*
|
|||
import java.util.*
|
||||
|
||||
import org.rs09.consts.*
|
||||
import content.data.Quests
|
||||
|
||||
object QuestTabUtils {
|
||||
@JvmStatic
|
||||
fun showRequirementsInterface (player: Player, button: Int) {
|
||||
val questName = getNameForButton (button)
|
||||
val questReq = QuestRequirements.values().filter { it.questName.equals(questName, true) }.firstOrNull() ?: return
|
||||
fun showRequirementsInterface(player: Player, button: Int) {
|
||||
val questName = getNameForButton(button)
|
||||
val questReq = QuestRequirements.values().filter { it.quest.questName == questName }.firstOrNull() ?: return
|
||||
var (isMet, unmetReqs) = QuestReq(questReq).evaluate(player)
|
||||
|
||||
var messageList = ArrayList<String>()
|
||||
|
|
@ -27,7 +28,7 @@ object QuestTabUtils {
|
|||
closeInterface(player)
|
||||
for (req in unmetReqs) {
|
||||
if (req is QuestReq)
|
||||
questList.add(req.questReq.questName)
|
||||
questList.add(req.questReq.quest.questName)
|
||||
else if (req is SkillReq) {
|
||||
if (statMap[req.skillId] == null || (statMap[req.skillId] != null && statMap[req.skillId]!! < req.level))
|
||||
statMap[req.skillId] = req.level
|
||||
|
|
@ -82,163 +83,163 @@ object QuestTabUtils {
|
|||
openInterface(player, Components.QUESTJOURNAL_SCROLL_275)
|
||||
}
|
||||
|
||||
fun getNameForButton (button: Int) : String {
|
||||
val name = when (button) {
|
||||
10 -> "Myths of the White Lands"
|
||||
11 -> "Myths of the White Lands"
|
||||
private fun getNameForButton(button: Int) : String {
|
||||
val quest = when (button) {
|
||||
10 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName
|
||||
11 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName
|
||||
12 -> "Free Quests"
|
||||
13 -> "Black Knights' Fortress"
|
||||
14 -> "Cook's Assistant"
|
||||
15 -> "Demon Slayer"
|
||||
16 -> "Doric's Quest"
|
||||
17 -> "Dragon Slayer"
|
||||
18 -> "Ernest the Chicken"
|
||||
19 -> "Goblin Diplomacy"
|
||||
20 -> "Imp Catcher"
|
||||
21 -> "The Knight's Sword"
|
||||
22 -> "Pirate's Treasure"
|
||||
23 -> "Prince Ali Rescue"
|
||||
24 -> "The Restless Ghost"
|
||||
25 -> "Romeo & Juliet"
|
||||
26 -> "Rune Mysteries"
|
||||
27 -> "Sheep Shearer"
|
||||
28 -> "Shield of Arrav"
|
||||
29 -> "Vampire Slayer"
|
||||
30 -> "Witch's Potion"
|
||||
13 -> Quests.BLACK_KNIGHTS_FORTRESS.questName
|
||||
14 -> Quests.COOKS_ASSISTANT.questName
|
||||
15 -> Quests.DEMON_SLAYER.questName
|
||||
16 -> Quests.DORICS_QUEST.questName
|
||||
17 -> Quests.DRAGON_SLAYER.questName
|
||||
18 -> Quests.ERNEST_THE_CHICKEN.questName
|
||||
19 -> Quests.GOBLIN_DIPLOMACY.questName
|
||||
20 -> Quests.IMP_CATCHER.questName
|
||||
21 -> Quests.THE_KNIGHTS_SWORD.questName
|
||||
22 -> Quests.PIRATES_TREASURE.questName
|
||||
23 -> Quests.PRINCE_ALI_RESCUE.questName
|
||||
24 -> Quests.THE_RESTLESS_GHOST.questName
|
||||
25 -> Quests.ROMEO_JULIET.questName
|
||||
26 -> Quests.RUNE_MYSTERIES.questName
|
||||
27 -> Quests.SHEEP_SHEARER.questName
|
||||
28 -> Quests.SHIELD_OF_ARRAV.questName
|
||||
29 -> Quests.VAMPIRE_SLAYER.questName
|
||||
30 -> Quests.WITCHS_POTION.questName
|
||||
31 -> "Members' Quests"
|
||||
32 -> "Animal Magnetism"
|
||||
33 -> "Between a Rock..."
|
||||
34 -> "Big Chompy Bird Hunting"
|
||||
35 -> "Biohazard"
|
||||
36 -> "Cabin Fever"
|
||||
37 -> "Clock Tower"
|
||||
38 -> "Contact!"
|
||||
39 -> "Zogre Flesh Eaters"
|
||||
40 -> "Creature of Fenkenstrain"
|
||||
41 -> "Darkness of Hallowvale"
|
||||
42 -> "Death to the Dorgeshuun"
|
||||
43 -> "Death Plateau"
|
||||
44 -> "Desert Treasure"
|
||||
45 -> "Devious Minds"
|
||||
46 -> "The Dig Site"
|
||||
47 -> "Druidic Ritual"
|
||||
48 -> "Dwarf Cannon"
|
||||
49 -> "Eadgar's Ruse"
|
||||
50 -> "Eagles' Peak"
|
||||
51 -> "Elemental Workshop I"
|
||||
52 -> "Elemental Workshop II"
|
||||
53 -> "Enakhra's Lament"
|
||||
54 -> "Enlightened Journey"
|
||||
55 -> "The Eyes of Glouphrie"
|
||||
56 -> "Fairytale I - Growing Pains"
|
||||
57 -> "Fairytale II - Cure a Queen"
|
||||
58 -> "Family Crest"
|
||||
59 -> "The Feud"
|
||||
60 -> "Fight Arena"
|
||||
61 -> "Fishing Contest"
|
||||
62 -> "Forgettable Tale..."
|
||||
63 -> "The Fremennik Trials"
|
||||
64 -> "Waterfall Quest"
|
||||
65 -> "Garden of Tranquillity"
|
||||
66 -> "Gertrude's Cat"
|
||||
67 -> "Ghosts Ahoy"
|
||||
68 -> "The Giant Dwarf"
|
||||
69 -> "The Golem"
|
||||
70 -> "The Grand Tree"
|
||||
71 -> "The Hand in the Sand"
|
||||
72 -> "Haunted Mine"
|
||||
73 -> "Hazeel Cult"
|
||||
74 -> "Heroes' Quest"
|
||||
75 -> "Holy Grail"
|
||||
76 -> "Horror from the Deep"
|
||||
77 -> "Icthlarin's Little Helper"
|
||||
78 -> "In Aid of the Myreque"
|
||||
79 -> "In Search of the Myreque"
|
||||
80 -> "Jungle Potion"
|
||||
81 -> "Legend's Quest"
|
||||
82 -> "Lost City"
|
||||
83 -> "The Lost Tribe"
|
||||
84 -> "Lunar Diplomacy"
|
||||
85 -> "Making History"
|
||||
86 -> "Merlin's Crystal"
|
||||
87 -> "Monkey Madness"
|
||||
88 -> "Monk's Friend"
|
||||
89 -> "Mountain Daughter"
|
||||
90 -> "Mourning's End Part I"
|
||||
91 -> "Mourning's End Part II"
|
||||
92 -> "Murder Mystery"
|
||||
93 -> "My Arm's Big Adventure"
|
||||
94 -> "Nature Spirit"
|
||||
95 -> "Observatory Quest"
|
||||
96 -> "One Small Favour"
|
||||
97 -> "Plague City"
|
||||
98 -> "Priest in Peril"
|
||||
99 -> "Rag and Bone Man"
|
||||
100 -> "Ratcatchers"
|
||||
101 -> "Recipe for Disaster"
|
||||
102 -> "Recruitment Drive"
|
||||
103 -> "Regicide"
|
||||
104 -> "Roving Elves"
|
||||
105 -> "Royal Trouble"
|
||||
106 -> "Rum Deal"
|
||||
107 -> "Scorpion Catcher"
|
||||
108 -> "Sea Slug"
|
||||
109 -> "The Slug Menace"
|
||||
110 -> "Shades of Mort'ton"
|
||||
111 -> "Shadow of the Storm"
|
||||
112 -> "Sheep Herder"
|
||||
113 -> "Shilo Village"
|
||||
114 -> "A Soul's Bane"
|
||||
115 -> "Spirits of the Elid"
|
||||
116 -> "Swan Song"
|
||||
117 -> "Tai Bwo Wannai Trio"
|
||||
118 -> "A Tail of Two Cats"
|
||||
119 -> "Tears of Guthix"
|
||||
120 -> "Temple of Ikov"
|
||||
121 -> "Throne of Miscellania"
|
||||
122 -> "The Tourist Trap"
|
||||
123 -> "Witch's House"
|
||||
124 -> "Tree Gnome Village"
|
||||
125 -> "Tribal Totem"
|
||||
126 -> "Troll Romance"
|
||||
127 -> "Troll Stronghold"
|
||||
128 -> "Underground Pass"
|
||||
129 -> "Wanted!"
|
||||
130 -> "Watchtower"
|
||||
131 -> "Cold War"
|
||||
132 -> "The Fremennik Isles"
|
||||
133 -> "Tower of Life"
|
||||
134 -> "The Great Brain Robbery"
|
||||
135 -> "What Lies Below"
|
||||
136 -> "Olaf's Quest"
|
||||
137 -> "Another Slice of H.A.M"
|
||||
138 -> "Dream Mentor"
|
||||
139 -> "Grim Tales"
|
||||
140 -> "King's Ransom"
|
||||
141 -> "The Path of Glouphrie"
|
||||
142 -> "Back to my Roots"
|
||||
143 -> "Land of the Goblins"
|
||||
144 -> "Dealing with Scabaras"
|
||||
145 -> "Wolf Whistle"
|
||||
146 -> "As a First Resort..."
|
||||
147 -> "Catapult Construction"
|
||||
148 -> "Kennith's Concerns"
|
||||
149 -> "Legacy of Seergaze"
|
||||
150 -> "Perils of Ice Mountain"
|
||||
151 -> "TokTz-Ket-Dill"
|
||||
152 -> "Smoking Kills"
|
||||
153 -> "Rocking Out"
|
||||
154 -> "Spirit of Summer"
|
||||
155 -> "Meeting History"
|
||||
156 -> "All Fired Up"
|
||||
157 -> "Summer's End"
|
||||
158 -> "Defender of Varrock"
|
||||
159 -> "Swept Away"
|
||||
160 -> "While Guthix Sleeps"
|
||||
161 -> "In Pyre Need"
|
||||
162 -> "Myths of the White Lands"
|
||||
32 -> Quests.ANIMAL_MAGNETISM.questName
|
||||
33 -> Quests.BETWEEN_A_ROCK.questName
|
||||
34 -> Quests.BIG_CHOMPY_BIRD_HUNTING.questName
|
||||
35 -> Quests.BIOHAZARD.questName
|
||||
36 -> Quests.CABIN_FEVER.questName
|
||||
37 -> Quests.CLOCK_TOWER.questName
|
||||
38 -> Quests.CONTACT.questName
|
||||
39 -> Quests.ZOGRE_FLESH_EATERS.questName
|
||||
40 -> Quests.CREATURE_OF_FENKENSTRAIN.questName
|
||||
41 -> Quests.DARKNESS_OF_HALLOWVALE.questName
|
||||
42 -> Quests.DEATH_TO_THE_DORGESHUUN.questName
|
||||
43 -> Quests.DEATH_PLATEAU.questName
|
||||
44 -> Quests.DESERT_TREASURE.questName
|
||||
45 -> Quests.DEVIOUS_MINDS.questName
|
||||
46 -> Quests.THE_DIG_SITE.questName
|
||||
47 -> Quests.DRUIDIC_RITUAL.questName
|
||||
48 -> Quests.DWARF_CANNON.questName
|
||||
49 -> Quests.EADGARS_RUSE.questName
|
||||
50 -> Quests.EAGLES_PEAK.questName
|
||||
51 -> Quests.ELEMENTAL_WORKSHOP_I.questName
|
||||
52 -> Quests.ELEMENTAL_WORKSHOP_II.questName
|
||||
53 -> Quests.ENAKHRAS_LAMENT.questName
|
||||
54 -> Quests.ENLIGHTENED_JOURNEY.questName
|
||||
55 -> Quests.THE_EYES_OF_GLOUPHRIE.questName
|
||||
56 -> Quests.FAIRYTALE_I_GROWING_PAINS.questName
|
||||
57 -> Quests.FAIRYTALE_II_CURE_A_QUEEN.questName
|
||||
58 -> Quests.FAMILY_CREST.questName
|
||||
59 -> Quests.THE_FEUD.questName
|
||||
60 -> Quests.FIGHT_ARENA.questName
|
||||
61 -> Quests.FISHING_CONTEST.questName
|
||||
62 -> Quests.FORGETTABLE_TALE.questName
|
||||
63 -> Quests.THE_FREMENNIK_TRIALS.questName
|
||||
64 -> Quests.WATERFALL_QUEST.questName
|
||||
65 -> Quests.GARDEN_OF_TRANQUILITY.questName
|
||||
66 -> Quests.GERTRUDES_CAT.questName
|
||||
67 -> Quests.GHOSTS_AHOY.questName
|
||||
68 -> Quests.THE_GIANT_DWARF.questName
|
||||
69 -> Quests.THE_GOLEM.questName
|
||||
70 -> Quests.THE_GRAND_TREE.questName
|
||||
71 -> Quests.THE_HAND_IN_THE_SAND.questName
|
||||
72 -> Quests.HAUNTED_MINE.questName
|
||||
73 -> Quests.HAZEEL_CULT.questName
|
||||
74 -> Quests.HEROES_QUEST.questName
|
||||
75 -> Quests.HOLY_GRAIL.questName
|
||||
76 -> Quests.HORROR_FROM_THE_DEEP.questName
|
||||
77 -> Quests.ICTHLARINS_LITTLE_HELPER.questName
|
||||
78 -> Quests.IN_AID_OF_THE_MYREQUE.questName
|
||||
79 -> Quests.IN_SEARCH_OF_THE_MYREQUE.questName
|
||||
80 -> Quests.JUNGLE_POTION.questName
|
||||
81 -> Quests.LEGENDS_QUEST.questName
|
||||
82 -> Quests.LOST_CITY.questName
|
||||
83 -> Quests.THE_LOST_TRIBE.questName
|
||||
84 -> Quests.LUNAR_DIPLOMACY.questName
|
||||
85 -> Quests.MAKING_HISTORY.questName
|
||||
86 -> Quests.MERLINS_CRYSTAL.questName
|
||||
87 -> Quests.MONKEY_MADNESS.questName
|
||||
88 -> Quests.MONKS_FRIEND.questName
|
||||
89 -> Quests.MOUNTAIN_DAUGHTER.questName
|
||||
90 -> Quests.MOURNINGS_END_PART_I.questName
|
||||
91 -> Quests.MOURNINGS_END_PART_II.questName
|
||||
92 -> Quests.MURDER_MYSTERY.questName
|
||||
93 -> Quests.MY_ARMS_BIG_ADVENTURE.questName
|
||||
94 -> Quests.NATURE_SPIRIT.questName
|
||||
95 -> Quests.OBSERVATORY_QUEST.questName
|
||||
96 -> Quests.ONE_SMALL_FAVOUR.questName
|
||||
97 -> Quests.PLAGUE_CITY.questName
|
||||
98 -> Quests.PRIEST_IN_PERIL.questName
|
||||
99 -> Quests.RAG_AND_BONE_MAN.questName
|
||||
100 -> Quests.RATCATCHERS.questName
|
||||
101 -> Quests.RECIPE_FOR_DISASTER.questName
|
||||
102 -> Quests.RECRUITMENT_DRIVE.questName
|
||||
103 -> Quests.REGICIDE.questName
|
||||
104 -> Quests.ROVING_ELVES.questName
|
||||
105 -> Quests.ROYAL_TROUBLE.questName
|
||||
106 -> Quests.RUM_DEAL.questName
|
||||
107 -> Quests.SCORPION_CATCHER.questName
|
||||
108 -> Quests.SEA_SLUG.questName
|
||||
109 -> Quests.THE_SLUG_MENACE.questName
|
||||
110 -> Quests.SHADES_OF_MORTTON.questName
|
||||
111 -> Quests.SHADOW_OF_THE_STORM.questName
|
||||
112 -> Quests.SHEEP_HERDER.questName
|
||||
113 -> Quests.SHILO_VILLAGE.questName
|
||||
114 -> Quests.A_SOULS_BANE.questName
|
||||
115 -> Quests.SPIRITS_OF_THE_ELID.questName
|
||||
116 -> Quests.SWAN_SONG.questName
|
||||
117 -> Quests.TAI_BWO_WANNAI_TRIO.questName
|
||||
118 -> Quests.A_TAIL_OF_TWO_CATS.questName
|
||||
119 -> Quests.TEARS_OF_GUTHIX.questName
|
||||
120 -> Quests.TEMPLE_OF_IKOV.questName
|
||||
121 -> Quests.THRONE_OF_MISCELLANIA.questName
|
||||
122 -> Quests.THE_TOURIST_TRAP.questName
|
||||
123 -> Quests.WITCHS_HOUSE.questName
|
||||
124 -> Quests.TREE_GNOME_VILLAGE.questName
|
||||
125 -> Quests.TRIBAL_TOTEM.questName
|
||||
126 -> Quests.TROLL_ROMANCE.questName
|
||||
127 -> Quests.TROLL_STRONGHOLD.questName
|
||||
128 -> Quests.UNDERGROUND_PASS.questName
|
||||
129 -> Quests.WANTED.questName
|
||||
130 -> Quests.WATCHTOWER.questName
|
||||
131 -> Quests.COLD_WAR.questName
|
||||
132 -> Quests.THE_FREMENNIK_ISLES.questName
|
||||
133 -> Quests.TOWER_OF_LIFE.questName
|
||||
134 -> Quests.THE_GREAT_BRAIN_ROBBERY.questName
|
||||
135 -> Quests.WHAT_LIES_BELOW.questName
|
||||
136 -> Quests.OLAFS_QUEST.questName
|
||||
137 -> Quests.ANOTHER_SLICE_OF_HAM.questName
|
||||
138 -> Quests.DREAM_MENTOR.questName
|
||||
139 -> Quests.GRIM_TALES.questName
|
||||
140 -> Quests.KINGS_RANSOM.questName
|
||||
141 -> Quests.THE_PATH_OF_GLOUPHRIE.questName
|
||||
142 -> Quests.BACK_TO_MY_ROOTS.questName
|
||||
143 -> Quests.LAND_OF_THE_GOBLINS.questName
|
||||
144 -> Quests.DEALING_WITH_SCABARAS.questName
|
||||
145 -> Quests.WOLF_WHISTLE.questName
|
||||
146 -> Quests.AS_A_FIRST_RESORT.questName
|
||||
147 -> Quests.CATAPULT_CONSTRUCTION.questName
|
||||
148 -> Quests.KENNITHS_CONCERNS.questName
|
||||
149 -> Quests.LEGACY_OF_SEERGAZE.questName
|
||||
150 -> Quests.PERILS_OF_ICE_MOUNTAIN.questName
|
||||
151 -> Quests.TOKTZ_KET_DILL.questName
|
||||
152 -> Quests.SMOKING_KILLS.questName
|
||||
153 -> Quests.ROCKING_OUT.questName
|
||||
154 -> Quests.SPIRIT_OF_SUMMER.questName
|
||||
155 -> Quests.MEETING_HISTORY.questName
|
||||
156 -> Quests.ALL_FIRED_UP.questName
|
||||
157 -> Quests.SUMMERS_END.questName
|
||||
158 -> Quests.DEFENDER_OF_VARROCK.questName
|
||||
159 -> Quests.SWEPT_AWAY.questName
|
||||
160 -> Quests.WHILE_GUTHIX_SLEEPS.questName
|
||||
161 -> Quests.IN_PYRE_NEED.questName
|
||||
162 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName
|
||||
else -> ""
|
||||
}
|
||||
return name
|
||||
return quest as String
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public class SmeltingInterface extends ComponentPlugin {
|
|||
* @author 'Vexia
|
||||
*/
|
||||
public enum BarButton {
|
||||
BRONZE_1(16, Bar.BRONZE, 1), BRONZE_5(15, Bar.BRONZE, 5), BRONZE_10(14, Bar.BRONZE, 10), BRONZE_X(13, Bar.BRONZE, -1), BLURITE_1(20, Bar.BLURITE, 1), BLURITE_5(19, Bar.BLURITE, 5), BLURITE_10(18, Bar.BLURITE, 10), BLURITE_X(17, Bar.BLURITE, -1), IRON_1(24, Bar.IRON, 1), IRON_5(23, Bar.IRON, 5), IRON_10(22, Bar.IRON, 10), IRON_X(21, Bar.IRON, -1), SILVER_1(28, Bar.SILVER, 1), SILVER_5(27, Bar.SILVER, 5), SILVER_10(26, Bar.SILVER, 10), SILVER_X(25, Bar.SILVER, -1), STEEL_1(32, Bar.STEEL, 1), STEEL_5(31, Bar.STEEL, 5), STEEL_10(30, Bar.STEEL, 10), STEEL_X(29, Bar.STEEL, -1), GOLD_1(36, Bar.GOLD, 1), GOLD_5(35, Bar.GOLD, 5), GOLD_10(34, Bar.GOLD, 10), GOLD_X(33, Bar.GOLD, -1), MITHRIL_1(40, Bar.MITHRIL, 1), MITHRIL_5(39, Bar.MITHRIL, 5), MITHRIL_10(38, Bar.MITHRIL, 10), MITHRIL_X(37, Bar.MITHRIL, -1), ADAMANT_1(44, Bar.ADAMANT, 1), ADAMANT_5(43, Bar.ADAMANT, 5), ADAMANT_10(42, Bar.ADAMANT, 10), ADAMANT_X(41, Bar.ADAMANT, -1), RUNE_1(48, Bar.RUNITE, 1), RUNE_5(47, Bar.RUNITE, 5), RUNE_10(46, Bar.RUNITE, 10), RUNE_X(45, Bar.RUNITE, -1);
|
||||
BRONZE_1(16, Bar.BRONZE, 1), BRONZE_5(15, Bar.BRONZE, 5), BRONZE_10(14, Bar.BRONZE, 30), BRONZE_X(13, Bar.BRONZE, -1), BLURITE_1(20, Bar.BLURITE, 1), BLURITE_5(19, Bar.BLURITE, 5), BLURITE_10(18, Bar.BLURITE, 30), BLURITE_X(17, Bar.BLURITE, -1), IRON_1(24, Bar.IRON, 1), IRON_5(23, Bar.IRON, 5), IRON_10(22, Bar.IRON, 30), IRON_X(21, Bar.IRON, -1), SILVER_1(28, Bar.SILVER, 1), SILVER_5(27, Bar.SILVER, 5), SILVER_10(26, Bar.SILVER, 30), SILVER_X(25, Bar.SILVER, -1), STEEL_1(32, Bar.STEEL, 1), STEEL_5(31, Bar.STEEL, 5), STEEL_10(30, Bar.STEEL, 30), STEEL_X(29, Bar.STEEL, -1), GOLD_1(36, Bar.GOLD, 1), GOLD_5(35, Bar.GOLD, 5), GOLD_10(34, Bar.GOLD, 30), GOLD_X(33, Bar.GOLD, -1), MITHRIL_1(40, Bar.MITHRIL, 1), MITHRIL_5(39, Bar.MITHRIL, 5), MITHRIL_10(38, Bar.MITHRIL, 30), MITHRIL_X(37, Bar.MITHRIL, -1), ADAMANT_1(44, Bar.ADAMANT, 1), ADAMANT_5(43, Bar.ADAMANT, 5), ADAMANT_10(42, Bar.ADAMANT, 30), ADAMANT_X(41, Bar.ADAMANT, -1), RUNE_1(48, Bar.RUNITE, 1), RUNE_5(47, Bar.RUNITE, 5), RUNE_10(46, Bar.RUNITE, 30), RUNE_X(45, Bar.RUNITE, -1);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code BarButton} {@code Object}.
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public class GrandExchangeInterface extends ComponentPlugin {
|
|||
GrandExchangeOffer offer;
|
||||
GrandExchangeRecords records = GrandExchangeRecords.getInstance(player);
|
||||
if (index > -1 && (offer = records.getOffer(records.getOfferRecords()[index])) != null) {
|
||||
StockMarket.withdraw(player, offer, slot >> 1);
|
||||
StockMarket.withdraw(player, offer, slot >> 1, opcode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class StockMarket : InterfaceListener {
|
|||
209,211 -> if (openedOffer == null){
|
||||
SystemLogger.logGE("[WARN] Player tried to withdraw item with null openedOffer!")
|
||||
return@on false
|
||||
} else withdraw(player, openedOffer, (button - 209) shr 1)
|
||||
} else withdraw(player, openedOffer, (button - 209) shr 1, op)
|
||||
190 -> confirmOffer(player, tempOffer, openedIndex).also { return@on true }
|
||||
194 -> player.interfaceManager.openChatbox(Components.OBJDIALOG_389)
|
||||
203 -> abortOffer(player, openedOffer)
|
||||
|
|
@ -342,7 +342,7 @@ class StockMarket : InterfaceListener {
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
fun withdraw(player: Player, offer: GrandExchangeOffer, index: Int)
|
||||
fun withdraw(player: Player, offer: GrandExchangeOffer, index: Int, op: Int)
|
||||
{
|
||||
val item = offer.withdraw[index]
|
||||
if(item == null)
|
||||
|
|
@ -351,20 +351,32 @@ class StockMarket : InterfaceListener {
|
|||
return
|
||||
}
|
||||
|
||||
if(hasSpaceFor(player, item))
|
||||
{
|
||||
addItem(player, item.id, item.amount)
|
||||
}
|
||||
else
|
||||
{
|
||||
val note = item.noteChange
|
||||
if(note == -1 || !hasSpaceFor(player, Item(note, item.amount)))
|
||||
{
|
||||
playAudio(player, Sounds.GE_TRADE_ERROR_4039)
|
||||
sendMessage(player, "You do not have enough room in your inventory.")
|
||||
return
|
||||
when (op) {
|
||||
// withdraw notes
|
||||
155 -> {
|
||||
val note = item.noteChange
|
||||
if (note == -1) {
|
||||
sendMessage(player, "This item cannot be noted")
|
||||
return
|
||||
}
|
||||
if (hasSpaceFor(player, Item(note, item.amount))) {
|
||||
addItem(player, note, item.amount)
|
||||
} else {
|
||||
playAudio(player, Sounds.GE_TRADE_ERROR_4039)
|
||||
sendMessage(player, "You do not have enough room in your inventory.")
|
||||
return
|
||||
}
|
||||
}
|
||||
// withdraw items
|
||||
196 -> {
|
||||
if (hasSpaceFor(player, item)) {
|
||||
addItem(player, item.id, item.amount)
|
||||
} else {
|
||||
playAudio(player, Sounds.GE_TRADE_ERROR_4039)
|
||||
sendMessage(player, "You do not have enough room in your inventory.")
|
||||
return
|
||||
}
|
||||
}
|
||||
else addItem(player, note, item.amount)
|
||||
}
|
||||
|
||||
offer.withdraw[index] = null
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import core.game.world.update.flag.context.Graphics
|
|||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Scenery
|
||||
import org.rs09.consts.Sounds
|
||||
import content.data.Quests
|
||||
|
||||
@Suppress("unused")
|
||||
class EctophialListener : InteractionListener {
|
||||
|
|
@ -37,7 +38,7 @@ class EctophialListener : InteractionListener {
|
|||
}
|
||||
|
||||
on(Items.ECTOPHIAL_4251, IntType.ITEM, "empty") { player, node ->
|
||||
if (!hasRequirement(player, "Ghosts Ahoy"))
|
||||
if (!hasRequirement(player, Quests.GHOSTS_AHOY))
|
||||
return@on true
|
||||
|
||||
if (player.isTeleBlocked) {
|
||||
|
|
@ -45,28 +46,29 @@ class EctophialListener : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
delayEntity(player, 10)
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
sendMessage(player, "You empty the ectoplasm onto the ground around your feet...")
|
||||
playAudio(player, 4580)
|
||||
visualize(player, emptyAnimation, emptyGraphics)
|
||||
replaceSlot(player, node.asItem().slot, Item(Items.ECTOPHIAL_4252), Item(Items.ECTOPHIAL_4251))
|
||||
return@queueScript delayScript(player, emptyAnimation.duration)
|
||||
}
|
||||
1 -> {
|
||||
teleport(player, Location.create(3658, 3517, 0), TeleportType.ECTOPHIAL)
|
||||
sendMessage(player, "...and the world changes around you.")
|
||||
return@queueScript delayScript(player, 9)
|
||||
}
|
||||
2 -> {
|
||||
face(player, Location(3659, 3519, 0))
|
||||
refillEctophial(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
closeAllInterfaces(player)
|
||||
queueScript(player, 0, QueueStrength.SOFT) { stage: Int ->
|
||||
when (stage) {
|
||||
0 -> {
|
||||
sendMessage(player, "You empty the ectoplasm onto the ground around your feet...")
|
||||
playAudio(player, 4580)
|
||||
visualize(player, emptyAnimation, emptyGraphics)
|
||||
replaceSlot(player, node.asItem().slot, Item(Items.ECTOPHIAL_4252), Item(Items.ECTOPHIAL_4251))
|
||||
return@queueScript delayScript(player, emptyAnimation.duration)
|
||||
}
|
||||
1 -> {
|
||||
teleport(player, Location.create(3658, 3517, 0), TeleportType.ECTOPHIAL)
|
||||
sendMessage(player, "...and the world changes around you.")
|
||||
return@queueScript delayScript(player, 9)
|
||||
}
|
||||
2 -> {
|
||||
face(player, Location(3659, 3519, 0))
|
||||
refillEctophial(player)
|
||||
return@queueScript stopExecuting(player)
|
||||
}
|
||||
else -> return@queueScript stopExecuting(player)
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,14 @@ import org.rs09.consts.Sounds
|
|||
class EnchantJewelleryTabListener : InteractionListener {
|
||||
|
||||
private val LVL_1_ENCHANT = mapOf(
|
||||
Items.BLUE_DRAGONHIDE_1751 to Items.PLAIN_SATCHEL_10877,
|
||||
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.GREEN_DRAGONHIDE_1753 to Items.GREEN_SATCHEL_10878,
|
||||
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,
|
||||
|
|
@ -23,6 +25,7 @@ class EnchantJewelleryTabListener : InteractionListener {
|
|||
)
|
||||
|
||||
private val LVL_3_ENCHANT = mapOf(
|
||||
Items.RED_DRAGONHIDE_1749 to Items.RED_SATCHEL_10879,
|
||||
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,
|
||||
|
|
@ -30,6 +33,7 @@ class EnchantJewelleryTabListener : InteractionListener {
|
|||
)
|
||||
|
||||
private val LVL_4_ENCHANT = mapOf(
|
||||
Items.DAGANNOTH_HIDE_6155 to Items.GOLD_SATCHEL_10881,
|
||||
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,
|
||||
|
|
@ -37,6 +41,7 @@ class EnchantJewelleryTabListener : InteractionListener {
|
|||
)
|
||||
|
||||
private val LVL_5_ENCHANT = mapOf(
|
||||
Items.SUQAH_HIDE_9080 to Items.RUNE_SATCHEL_10882,
|
||||
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,
|
||||
|
|
@ -44,6 +49,7 @@ class EnchantJewelleryTabListener : InteractionListener {
|
|||
)
|
||||
|
||||
private val LVL_6_ENCHANT = mapOf(
|
||||
Items.BLACK_DRAGONHIDE_1747 to Items.BLACK_SATCHEL_10880,
|
||||
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,
|
||||
|
|
@ -52,6 +58,7 @@ class EnchantJewelleryTabListener : InteractionListener {
|
|||
|
||||
override fun defineListeners() {
|
||||
on(IntType.ITEM, "break") {player, node ->
|
||||
closeAllInterfaces(player)
|
||||
delayEntity(player, 1)
|
||||
queueScript(player, strength = QueueStrength.SOFT) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package content.global.handlers.item
|
||||
|
||||
import content.global.skill.slayer.SlayerUtils
|
||||
import core.api.*
|
||||
import content.global.skill.slayer.Tasks
|
||||
import org.rs09.consts.Items
|
||||
|
|
@ -41,7 +42,8 @@ class EnchantedGemDialogue() : DialogueFile() {
|
|||
if(getSlayerTask(player!!) == Tasks.JAD) {
|
||||
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill TzTok-Jad!")
|
||||
} else {
|
||||
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${getSlayerTaskName(player!!)}s; only ${getSlayerTaskKillsRemaining(player!!)} more to go.")
|
||||
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${SlayerUtils.pluralise(
|
||||
getSlayerTaskName(player!!))}; only ${getSlayerTaskKillsRemaining(player!!)} more to go.")
|
||||
}
|
||||
setVarp(player!!, 2502, getSlayerTaskFlags(player!!) shr 4)
|
||||
stage = 1
|
||||
|
|
|
|||
|
|
@ -53,17 +53,17 @@ class ExplorersRingPlugin : InteractionListener {
|
|||
sendMessage(player, "You have used up all of your charges for the day.")
|
||||
return@on true
|
||||
}
|
||||
sendDialogue(player, "Choose the item that you wish to convert to coins.")
|
||||
addDialogueAction (player) {_,_ ->
|
||||
sendItemSelect (player, "Choose") { slot, optionIndex ->
|
||||
//sendDialogue(player, "Choose the item that you wish to convert to coins.")
|
||||
//addDialogueAction (player) {_,_ ->
|
||||
sendItemSelect (player, "Cast Low Level Alchemy on:") { slot, optionIndex ->
|
||||
val item = player.inventory[slot]
|
||||
if (item == null)
|
||||
return@sendItemSelect
|
||||
if (!ModernListeners().alchemize(player, item, false))
|
||||
if (!ModernListeners().alchemize(player, item, false, explorersRing = true))
|
||||
return@sendItemSelect
|
||||
getStoreFile()[player.username.lowercase() + ":alchs"] = remaining - 1
|
||||
}
|
||||
}
|
||||
//}
|
||||
return@on true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@ import org.rs09.consts.Items
|
|||
import core.game.dialogue.DialogueFile
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
|
||||
class GodBookListeners : InteractionListener {
|
||||
|
||||
|
|
@ -20,16 +23,42 @@ class GodBookListeners : InteractionListener {
|
|||
openDialogue(player, HOLY_DIALOGUE(BOOK.SARA))
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(GB_ZAMORAK, IntType.ITEM, "preach"){ player, _ ->
|
||||
openDialogue(player, HOLY_DIALOGUE(BOOK.ZAM))
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(GB_GUTHIX, IntType.ITEM, "preach"){ player, _ ->
|
||||
openDialogue(player, HOLY_DIALOGUE(BOOK.GUTHIX))
|
||||
return@on true
|
||||
}
|
||||
|
||||
fun bless(player: Player, node: Node, product: Int) {
|
||||
if (player.skills.getStaticLevel(Skills.PRAYER) < 50) {
|
||||
sendMessage(player, "You need a Prayer level of at least 50 in order to do this.")
|
||||
} else if (player.skills.prayerPoints < 4) {
|
||||
sendMessage(player, "You need at least 4 prayer points in order to do this.")
|
||||
} else {
|
||||
sendMessage(player, "You bless the ${node.asItem().name.lowercase()}.")
|
||||
player.skills.decrementPrayerPoints(4.0)
|
||||
replaceSlot(player, node.asItem().slot, Item(product), node.asItem())
|
||||
}
|
||||
}
|
||||
onUseWith(IntType.ITEM, GB_SARADOMIN, Items.UNBLESSED_SYMBOL_1716) { player, _, symbol ->
|
||||
bless(player, symbol, Items.HOLY_SYMBOL_1718)
|
||||
return@onUseWith true
|
||||
}
|
||||
onUseWith(IntType.ITEM, GB_ZAMORAK, Items.UNPOWERED_SYMBOL_1722) { player, _, symbol ->
|
||||
bless(player, symbol, Items.UNHOLY_SYMBOL_1724)
|
||||
return@onUseWith true
|
||||
}
|
||||
onUseWith(IntType.ITEM, GB_GUTHIX, Items.UNBLESSED_SYMBOL_1716) { player, _, symbol ->
|
||||
bless(player, symbol, Items.HOLY_SYMBOL_1718)
|
||||
return@onUseWith true
|
||||
}
|
||||
onUseWith(IntType.ITEM, GB_GUTHIX, Items.UNPOWERED_SYMBOL_1722) { player, _, symbol ->
|
||||
bless(player, symbol, Items.UNHOLY_SYMBOL_1724)
|
||||
return@onUseWith true
|
||||
}
|
||||
}
|
||||
|
||||
internal enum class BOOK {
|
||||
|
|
@ -129,6 +158,5 @@ class GodBookListeners : InteractionListener {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public class GodBookPlugin extends OptionHandler {
|
|||
for (GodBook book : GodBook.values()) {
|
||||
book.getDamagedBook().getDefinition().getHandlers().put("option:check", this);
|
||||
}
|
||||
ClassScanner.definePlugins(new PageHandler(), new GodBookItem(), new SymbolBlessHandler());
|
||||
ClassScanner.definePlugins(new PageHandler(), new GodBookItem());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -51,77 +51,6 @@ public class GodBookPlugin extends OptionHandler {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the blessing of a symbol with a god book.
|
||||
* @author Vexia
|
||||
*/
|
||||
public class SymbolBlessHandler extends UseWithHandler {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SymbolBlessHandler} {@code Object}
|
||||
*/
|
||||
public SymbolBlessHandler() {
|
||||
super(1716);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
for (GodBook book : GodBook.values()) {
|
||||
addHandler(book.getBook().getId(), ITEM_TYPE, this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(NodeUsageEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
GodBook book = GodBook.forItem(event.getUsedItem(), false);
|
||||
if (book == null) {
|
||||
return false;
|
||||
}
|
||||
final Item symbol = event.getUsedWith().asItem();
|
||||
if (player.getSkills().getLevel(Skills.PRAYER) < 50) {
|
||||
player.sendMessage("You need a Prayer level of at least 50 in order to do this.");
|
||||
return true;
|
||||
}
|
||||
if (player.getSkills().getPrayerPoints() < 4) {
|
||||
player.sendMessage("You need at least 4 prayer points in order to do this.");
|
||||
return true;
|
||||
}
|
||||
if (book == GodBook.BOOK_OF_BALANCE) {
|
||||
player.getDialogueInterpreter().sendOptions("Select an Option", "Unholy symbol", "Holy symbol");
|
||||
player.getDialogueInterpreter().addAction(new DialogueAction() {
|
||||
|
||||
@Override
|
||||
public void handle(Player player, int buttonId) {
|
||||
bless(player, symbol, buttonId == 1 ? GodBook.UNHOLY_BOOK : GodBook.HOLY_BOOK);
|
||||
}
|
||||
|
||||
});
|
||||
return true;
|
||||
}
|
||||
bless(player, symbol, book);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blesses a symbol.
|
||||
* @param player the player.
|
||||
* @param book the book.
|
||||
*/
|
||||
private void bless(Player player, Item symbol, GodBook book) {
|
||||
if (!player.getInventory().containsItem(symbol)) {
|
||||
return;
|
||||
}
|
||||
if (player.getInventory().get(symbol.getSlot()) == null) {
|
||||
return;
|
||||
}
|
||||
player.getInventory().replace(book.getBlessItem()[0], symbol.getSlot());
|
||||
player.getSkills().decrementPrayerPoints(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A god book item.
|
||||
* @author Vexia
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class GrandSeedPodHandler : InteractionListener {
|
|||
}
|
||||
|
||||
if (opt == "squash") {
|
||||
closeAllInterfaces(player)
|
||||
visualize(player, SQUASH_ANIM_BEGIN, SQUASH_GRAPHICS_BEGIN)
|
||||
delayEntity(player, 12)
|
||||
queueScript(player, 3, QueueStrength.SOFT) {stage: Int ->
|
||||
|
|
@ -93,4 +94,4 @@ class GrandSeedPodHandler : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,24 +5,34 @@ import core.game.interaction.IntType
|
|||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.node.item.Item
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.world.repository.Repository
|
||||
|
||||
class HouseTeleTabOptionListener : InteractionListener {
|
||||
override fun defineListeners() {
|
||||
val homeTabID = 8013
|
||||
on(homeTabID, IntType.ITEM, "break") {player, node ->
|
||||
var hasHouse = player.houseManager.location.exitLocation != null
|
||||
if (!hasHouse) {
|
||||
sendMessage( player, "You must have a house to teleport to before attempting that.")
|
||||
return@on false
|
||||
//Snowscape: teleport to the last house you entered, if possible
|
||||
var owner: Player
|
||||
val lastHouseOwner = Repository.getPlayerByName(player.getAttribute("lasthouseentered", null))
|
||||
if (lastHouseOwner != null && !lastHouseOwner.getHouseManager().isLocked()) {
|
||||
owner = lastHouseOwner
|
||||
} else {
|
||||
var hasHouse = player.houseManager.location.exitLocation != null
|
||||
if (!hasHouse) {
|
||||
sendMessage( player, "You must have a house to teleport to before attempting that.")
|
||||
return@on false
|
||||
}
|
||||
owner = player
|
||||
}
|
||||
closeInterface(player)
|
||||
lock(player, 5)
|
||||
if (inInventory(player, node.id)) {
|
||||
player.houseManager.preEnter(player, false)
|
||||
val location = player.houseManager.getEnterLocation()
|
||||
owner.houseManager.preEnter(player, false)
|
||||
val location = owner.houseManager.getEnterLocation()
|
||||
if (teleport(player, location, TeleportManager.TeleportType.TELETABS)) {
|
||||
removeItem(player, Item(node.id, 1))
|
||||
player.houseManager.postEnter(player, false)
|
||||
owner.houseManager.postEnter(player, false)
|
||||
}
|
||||
}
|
||||
return@on true
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import core.api.*
|
|||
import core.game.node.entity.player.link.quest.QuestRepository
|
||||
import org.rs09.consts.Items
|
||||
import core.game.interaction.InteractionListener
|
||||
import content.data.Quests
|
||||
|
||||
class ItemQuestRequirementListener : InteractionListener {
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
|
||||
/*
|
||||
onEquip(fremennikIslesEquipment) { player, _ ->
|
||||
if (!isQuestComplete(player, "Fremennik Isles")) {
|
||||
if (!isQuestComplete(player, Quests.THE_FREMENNIK_ISLES)) {
|
||||
sendMessage(player, "You must have completed The Fremennik Isles to equip this.")
|
||||
return@onEquip false
|
||||
}
|
||||
|
|
@ -114,7 +115,7 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
}
|
||||
|
||||
onEquip(fremennikIslesDuringQuestEquipment){ player, _ ->
|
||||
if (questStage(player, "Fremennik Isles") > 0) {
|
||||
if (questStage(player, Quests.THE_FREMENNIK_ISLES) > 0) {
|
||||
sendMessage(player, "You must have started The Fremennik Isles to equip this.")
|
||||
return@onEquip false
|
||||
}
|
||||
|
|
@ -123,23 +124,23 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
*/
|
||||
|
||||
onEquip(fremennikTrialsEquipment) { player, _ ->
|
||||
return@onEquip hasRequirement(player, "Fremennik Trials")
|
||||
return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)
|
||||
}
|
||||
|
||||
onEquip(fremennikIslesEquipment) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "The Fremennik Isles")
|
||||
return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_ISLES)
|
||||
}
|
||||
|
||||
onEquip(avasBackpacks){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Animal Magnetism")
|
||||
return@onEquip hasRequirement(player, Quests.ANIMAL_MAGNETISM)
|
||||
}
|
||||
|
||||
onEquip(lostCityWeapons){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Lost City")
|
||||
return@onEquip hasRequirement(player, Quests.LOST_CITY)
|
||||
}
|
||||
|
||||
onEquip(Items.CAPE_OF_LEGENDS_1052) { player, _ ->
|
||||
return@onEquip hasRequirement(player, "Legend's Quest")
|
||||
return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST)
|
||||
}
|
||||
|
||||
onEquip(questCapes) { player, _ ->
|
||||
|
|
@ -152,84 +153,84 @@ class ItemQuestRequirementListener : InteractionListener {
|
|||
}
|
||||
|
||||
onEquip(Items.WOLFBANE_2952){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Priest in Peril")
|
||||
return@onEquip hasRequirement(player, Quests.PRIEST_IN_PERIL)
|
||||
}
|
||||
|
||||
onEquip(Items.ANCIENT_MACE_11061){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Another Slice of H.A.M")
|
||||
return@onEquip hasRequirement(player, Quests.ANOTHER_SLICE_OF_HAM)
|
||||
}
|
||||
|
||||
onEquip(Items.ANCIENT_STAFF_4675){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Desert Treasure")
|
||||
return@onEquip hasRequirement(player, Quests.DESERT_TREASURE)
|
||||
}
|
||||
|
||||
onEquip(Items.ELEMENTAL_SHIELD_2890) { player, _ ->
|
||||
return@onEquip hasRequirement(player, "Elemental Workshop I")
|
||||
return@onEquip hasRequirement(player, Quests.ELEMENTAL_WORKSHOP_I)
|
||||
}
|
||||
|
||||
onEquip(crystalEquipment){ player, _ ->
|
||||
return@onEquip hasRequirement(player, "Roving Elves")
|
||||
return@onEquip hasRequirement(player, Quests.ROVING_ELVES)
|
||||
}
|
||||
|
||||
onEquip(dragonSlayerEquipment) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Dragon Slayer")
|
||||
return@onEquip hasRequirement(player, Quests.DRAGON_SLAYER)
|
||||
}
|
||||
|
||||
onEquip(Items.DRAGON_SCIMITAR_4587) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Monkey Madness")
|
||||
return@onEquip hasRequirement(player, Quests.MONKEY_MADNESS)
|
||||
}
|
||||
|
||||
onEquip(Items.GLOVES_7462) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Recipe for Disaster")
|
||||
return@onEquip hasRequirement(player, Quests.RECIPE_FOR_DISASTER)
|
||||
}
|
||||
|
||||
onEquip(Items.SLAYER_HELMET_13263) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Smoking Kills")
|
||||
return@onEquip hasRequirement(player, Quests.SMOKING_KILLS)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_HALBERD_3204) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Regicide")
|
||||
return@onEquip hasRequirement(player, Quests.REGICIDE)
|
||||
}
|
||||
|
||||
onEquip (Items.CLIMBING_BOOTS_3105) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Death Plateau")
|
||||
return@onEquip hasRequirement(player, Quests.DEATH_PLATEAU)
|
||||
}
|
||||
|
||||
onEquip (godBooks) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Horror from the Deep")
|
||||
return@onEquip hasRequirement(player, Quests.HORROR_FROM_THE_DEEP)
|
||||
}
|
||||
|
||||
onEquip (pharaohScepters) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Icthlarin's Little Helper")
|
||||
return@onEquip hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_SQ_SHIELD_1187) {player, _ ->
|
||||
//because I know people won't believe it: https://runescape.wiki/w/Dragon_sq_shield?oldid=899636
|
||||
return@onEquip hasRequirement(player, "Legend's Quest")
|
||||
return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST)
|
||||
}
|
||||
|
||||
onEquip (initiateArmour) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Recruitment Drive")
|
||||
return@onEquip hasRequirement(player, Quests.RECRUITMENT_DRIVE)
|
||||
}
|
||||
|
||||
onEquip (proselyteArmour) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "The Slug Menace")
|
||||
return@onEquip hasRequirement(player, Quests.THE_SLUG_MENACE)
|
||||
}
|
||||
|
||||
onEquip (spiritShields) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Summer's End")
|
||||
return@onEquip hasRequirement(player, Quests.SUMMERS_END)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_MACE_1434) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Heroes' Quest")
|
||||
return@onEquip hasRequirement(player, Quests.HEROES_QUEST)
|
||||
}
|
||||
|
||||
onEquip (Items.DRAGON_BATTLEAXE_1377) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Heroes' Quest")
|
||||
return@onEquip hasRequirement(player, Quests.HEROES_QUEST)
|
||||
}
|
||||
|
||||
onEquip (Items.DARKLIGHT_6746) {player, _ ->
|
||||
return@onEquip hasRequirement(player, "Shadow of the Storm")
|
||||
return@onEquip hasRequirement(player, Quests.SHADOW_OF_THE_STORM)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ import core.plugin.Initializable;
|
|||
import core.plugin.Plugin;
|
||||
import core.plugin.ClassScanner;
|
||||
import core.tools.RandomFunction;
|
||||
import org.rs09.consts.Sounds;
|
||||
|
||||
import static core.api.ContentAPIKt.playAudio;
|
||||
|
||||
/**
|
||||
* Handles a morph item.
|
||||
|
|
@ -65,6 +68,7 @@ public class MorphItemPlugin implements Plugin<Object> {
|
|||
*/
|
||||
private void morph(Player player, Item item) {
|
||||
int morphId = item.getId() == 6583 ? 2626 : EASTER_EGG_IDS[RandomFunction.random(EASTER_EGG_IDS.length)];
|
||||
playAudio(player, 1520);
|
||||
player.getInterfaceManager().close();
|
||||
player.getAppearance().transformNPC(morphId);
|
||||
player.getInterfaceManager().removeTabs(0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import core.game.node.entity.player.Player;
|
|||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import content.region.morytania.quest.naturespirit.NSUtils;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Handles the Silver Sickle (b) to collect Mort Myre Fungus.
|
||||
|
|
@ -28,7 +29,7 @@ public final class SilverSicklePlugin extends OptionHandler {
|
|||
switch (option) {
|
||||
case "operate":
|
||||
case "cast bloom":
|
||||
if(player.getQuestRepository().getQuest("Nature Spirit").getStage(player) >= 75) {
|
||||
if(player.getQuestRepository().getQuest(Quests.NATURE_SPIRIT).getStage(player) >= 75) {
|
||||
player.getPacketDispatch().sendAnimation(9021);
|
||||
NSUtils.castBloom(player);
|
||||
} else {
|
||||
|
|
|
|||
183
Server/src/main/content/global/handlers/item/SnowscapeSatchelListener.kt
Executable file
183
Server/src/main/content/global/handlers/item/SnowscapeSatchelListener.kt
Executable file
|
|
@ -0,0 +1,183 @@
|
|||
package content.global.handlers.item
|
||||
|
||||
import core.api.*
|
||||
import core.game.container.Container
|
||||
import content.global.skill.summoning.familiar.BurdenContainerListener
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
//import core.game.node.entity.player.info.login.PlayerSaver
|
||||
import core.game.node.item.Item
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import org.json.simple.JSONArray
|
||||
import org.json.simple.JSONObject
|
||||
import org.json.simple.parser.JSONParser
|
||||
import org.rs09.consts.Items
|
||||
|
||||
import core.game.component.Component
|
||||
import core.game.component.CloseEvent
|
||||
import core.game.container.access.InterfaceContainer
|
||||
import content.global.handlers.scenery.BankBoothListener
|
||||
import content.global.handlers.npc.BankerNPC
|
||||
|
||||
/**
|
||||
* Listener for satchels from Creature Creation, repurposed for Snowscape
|
||||
* They are repurposed as item pouches, using the summoning familiar inventory interface
|
||||
* @author
|
||||
*/
|
||||
class SnowscapeSatchelListener : InteractionListener {
|
||||
|
||||
companion object {
|
||||
|
||||
val plainSatchelId = 10877
|
||||
val greenSatchelId = 10878
|
||||
val redSatchelId = 10879
|
||||
val blackSatchelId = 10880
|
||||
val goldSatchelId = 10881
|
||||
val runeSatchelId = 10882
|
||||
val satchelIds = intArrayOf(plainSatchelId,greenSatchelId,redSatchelId,blackSatchelId,goldSatchelId,runeSatchelId)
|
||||
|
||||
|
||||
|
||||
|
||||
private fun transferItem(player: Player, satchelId: Int, item: Item, amount: Int, withdraw: Boolean, asNote: Boolean = false) {
|
||||
if (withdraw == false && !isAllowed(player, satchelId, unnote(item).getId())) {
|
||||
player.sendMessage(item.getName() + " cannot be stored in the " + Item(satchelId).getName() + ".")
|
||||
return
|
||||
}
|
||||
if (withdraw == true && asNote == false && satchelId == plainSatchelId) {
|
||||
player.sendMessage("This satchel can only be emptied by a banker. Use it on a bank booth to get the items.")
|
||||
return
|
||||
}
|
||||
val to = if (withdraw) player.getInventory() else getSatchel(player, satchelId)
|
||||
val from = if (withdraw) getSatchel(player, satchelId) else player.getInventory()
|
||||
val maximum = if (asNote) to.getMaximumAdd(note(item)) else to.getMaximumAdd(unnote(item))
|
||||
if (maximum < 1 && withdraw == false) {
|
||||
player.sendMessage("There is not enough space for the " + item.getName() + " in the satchel.")
|
||||
return
|
||||
}
|
||||
val finalAmount = kotlin.comparisons.minOf(amount, from.getAmount(item), maximum)
|
||||
val finalItem = Item(item.getId(), finalAmount)
|
||||
if (finalAmount > 0 && from.remove(finalItem)) {
|
||||
if (asNote) to.add(note(finalItem)) else to.add(unnote(finalItem))
|
||||
}
|
||||
}
|
||||
|
||||
private fun emptySatchel(player: Player, satchelId: Int, asNote: Boolean = false) {
|
||||
if (asNote == false && satchelId == plainSatchelId) {
|
||||
player.sendMessage("This satchel can only be emptied by a banker. Use it on a Bank Booth to get the items.")
|
||||
return
|
||||
}
|
||||
val satchel = getSatchel(player, satchelId)
|
||||
repeat(satchel.capacity()) { index ->
|
||||
var item = satchel.get(index)
|
||||
if (item != null) {
|
||||
transferItem(player, satchelId, item, satchel.getAmount(item), true, asNote)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Function to handle constructing the correct interfaces when the satchel is opened
|
||||
private fun openSatchel(player: Player, node: Node) {
|
||||
val satchelId = node.asItem().getId()
|
||||
val satchel = getSatchel(player, satchelId)
|
||||
if (satchel.getListeners().count() < 1) satchel.register(BurdenContainerListener(player))
|
||||
|
||||
player.getInterfaceManager().open(Component(671)).setCloseEvent(CloseEvent { player, component ->
|
||||
player.getInterfaceManager().closeSingleTab()
|
||||
removeAttribute(player, "openSatchel")
|
||||
return@CloseEvent true
|
||||
}
|
||||
)
|
||||
setAttribute(player, "openSatchel", satchelId)
|
||||
satchel.shift()
|
||||
player.getInterfaceManager().openSingleTab(Component(665))
|
||||
InterfaceContainer.generateItems(player, player.getInventory().toArray(), arrayOf("Store-X","Store-All","Store-10","Store-5","Store-1"),665,0,7,4,93)
|
||||
InterfaceContainer.generateItems(player, satchel.toArray(), arrayOf("Withdraw-X","Withdraw-All","Withdraw-10","Withdraw-5","Withdraw-1"),671,27,5,6,30)
|
||||
}
|
||||
|
||||
// This is called by BurdenInterfacePlugin.java when the player interacts with the familiar interface and the "openSatchel" attribute exists
|
||||
fun satchelInterfaceAction(player: Player, component: Component, opcode: Int, button: Int, slot: Int, itemId: Int) {
|
||||
val satchelId = getAttribute(player, "openSatchel", 0)
|
||||
val withdraw = component.getId() == 671
|
||||
val container = if (withdraw) getSatchel(player, satchelId) else player.getInventory()
|
||||
val item = if (slot >= 0 && slot < container.capacity()) container.get(slot) else null
|
||||
if (item == null && button != 29) return
|
||||
when (opcode) {
|
||||
155 -> if (button == 29) emptySatchel(player, satchelId) else transferItem(player, satchelId, item!!, 1, withdraw)
|
||||
196 -> transferItem(player, satchelId, item!!, 5, withdraw)
|
||||
124 -> transferItem(player, satchelId, item!!, 10, withdraw)
|
||||
199 -> transferItem(player, satchelId, item!!, container.getAmount(item), withdraw)
|
||||
234 -> sendInputDialogue(player, true, "Enter the amount:") { value -> transferItem(player, satchelId, item!!, value as Int, withdraw) }
|
||||
9 -> player.sendMessage(item!!.getDefinition().getExamine())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun getSatchel(player: Player, satchelId: Int): Container {
|
||||
var satchel: Container? = null
|
||||
when (satchelId) {
|
||||
plainSatchelId -> satchel = player.plainSatchel
|
||||
greenSatchelId -> satchel = player.greenSatchel
|
||||
redSatchelId -> satchel = player.redSatchel
|
||||
blackSatchelId -> satchel = player.blackSatchel
|
||||
goldSatchelId -> satchel = player.goldSatchel
|
||||
runeSatchelId -> satchel = player.runeSatchel
|
||||
}
|
||||
return satchel!!
|
||||
}
|
||||
|
||||
// Checks if the item is allowed in the satchel. The NPCDropTables.java function calls this on satchels the player is carrying.
|
||||
fun isAllowed(player: Player, satchelId: Int, itemId: Int): Boolean {
|
||||
when (satchelId) {
|
||||
plainSatchelId -> return itemId !in satchelIds
|
||||
greenSatchelId -> return (Item(itemId).getName().contains(" seed") || Item(itemId).getName().contains("Grimy") || Item(itemId).getName().contains("Clean "))
|
||||
redSatchelId -> return itemId in intArrayOf(*(12158..12168).toList().toIntArray()) || Item(itemId).getName().equals("Clue scroll")
|
||||
blackSatchelId -> return itemId in intArrayOf(995)
|
||||
goldSatchelId -> return itemId in intArrayOf(436,438,440,442,444,446,447,449,451,453,668,2892,2349,2351,2353,2355,2357,2359,2361,2363,2365,1601,1603,1605,1607,1609,1611,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,6571,6573)
|
||||
runeSatchelId -> return itemId in intArrayOf(556,555,557,554,558,559,564,562,9075,561,563,560,565,566,4694,4695,4696,4697,4698,4699)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun defineListeners() {
|
||||
|
||||
onUseAnyWith(IntType.ITEM, *satchelIds) { player, used, with ->
|
||||
val satchelId = with.asItem().getId()
|
||||
transferItem(player, satchelId, used.asItem(), player.getInventory().getAmount(used.asItem()),false)
|
||||
return@onUseAnyWith true
|
||||
}
|
||||
|
||||
on(satchelIds, IntType.ITEM, "inspect","operate") { player, node ->
|
||||
openSatchel(player, node)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(satchelIds, IntType.ITEM, "empty") { player, node ->
|
||||
emptySatchel(player, node.asItem().getId())
|
||||
return@on true
|
||||
}
|
||||
|
||||
// BankBoothListener values are public but BankChestListener values are not, so rather than edit the BankChestListener file I have copied the IDs here. 12309 is the Culinomancer's chest.
|
||||
val bankChests = intArrayOf(3194,4483,10562,14382,16695,16696,21301,27662,27663)
|
||||
val bankUseWiths = intArrayOf(*BankBoothListener.BANK_BOOTHS, 12309, *bankChests)
|
||||
onUseWith(IntType.SCENERY, satchelIds, *bankUseWiths) { player, used, with ->
|
||||
emptySatchel(player, used.asItem().getId(), true)
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
//6362 is the Ourania Altar banker.
|
||||
val bankers = intArrayOf(*BankerNPC.NPC_IDS, *BankerNPC.SPECIAL_NPC_IDS, 6362)
|
||||
|
||||
onUseWith(IntType.NPC, satchelIds, *bankers) { player, used, with ->
|
||||
emptySatchel(player, used.asItem().getId(), true)
|
||||
return@onUseWith true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
146
Server/src/main/content/global/handlers/item/SnowscapeTeleorb.kt
Normal file
146
Server/src/main/content/global/handlers/item/SnowscapeTeleorb.kt
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
package content.global.handlers.item
|
||||
|
||||
import core.api.*
|
||||
import core.game.node.Node
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.skill.Skills
|
||||
import core.game.node.item.Item
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.build.DynamicRegion
|
||||
import core.game.world.map.zone.ZoneRestriction
|
||||
import core.game.world.update.flag.context.Animation
|
||||
import core.game.world.update.flag.context.Graphics
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.dialogue.*
|
||||
import core.tools.START_DIALOGUE
|
||||
import org.rs09.consts.Items
|
||||
import org.rs09.consts.Sounds
|
||||
|
||||
import core.game.component.Component
|
||||
|
||||
/**
|
||||
* Listener for the strange teleorb object. Normally this object is part of the While Guthix Sleeps quest, but it has been repurposed.
|
||||
* The new purpose is a custom teleport artifact, allowing players to save a location and teleport back to it.
|
||||
* @author
|
||||
*/
|
||||
class SnowscapeTeleorb : InteractionListener {
|
||||
|
||||
// The teleorb item id
|
||||
val teleorb = 14534
|
||||
|
||||
// How many law runes are required for one teleport charge
|
||||
val runesPerTeleportNormal = 20
|
||||
val runesPerTeleportBoosted = 2
|
||||
|
||||
override fun defineListeners() {
|
||||
on(teleorb, IntType.ITEM, "inspect") { player, node ->
|
||||
inspect(player, node)
|
||||
return@on true
|
||||
}
|
||||
on(teleorb, IntType.ITEM, "activate") { player, node ->
|
||||
activate(player, node)
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
private fun inspect(player: Player, node: Node) {
|
||||
openDialogue(player,SnowscapeTeleorbDialogue())
|
||||
}
|
||||
|
||||
private fun activate(player: Player, node: Node) {
|
||||
val charges = getAttribute(player, "teleorb:charges",0) as Int
|
||||
var runesPerTeleport = if (getAttribute(player, "snowscape:boostedmode", false)) runesPerTeleportBoosted else runesPerTeleportNormal
|
||||
if (charges >= runesPerTeleport) {
|
||||
val destination = getAttribute(player, "teleorb:location", Location.create(3236,3218,0))
|
||||
player.getTeleporter().send(destination, TeleportManager.TeleportType.ENTRANA_MAGIC_DOOR)
|
||||
setAttribute(player, "/save:teleorb:charges", charges - runesPerTeleport)
|
||||
player.sendMessage("Charges remaining: " + ((getAttribute(player, "teleorb:charges",0) as Int) / runesPerTeleport))
|
||||
rewardXP(player, Skills.MAGIC, 15.0 * runesPerTeleport)
|
||||
} else {
|
||||
player.sendMessage("<col=ff0000>The teleorb is out of charges.</col>")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class SnowscapeTeleorbDialogue : DialogueFile() {
|
||||
|
||||
// How many law runes are required for one teleport charge
|
||||
val runesPerTeleportNormal = 20
|
||||
val runesPerTeleportBoosted = 2
|
||||
|
||||
val teleorb = 14534
|
||||
val lawRune = 563
|
||||
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
when (stage) {
|
||||
START_DIALOGUE -> options("Update Location","Recharge","Show Info").also {stage++}
|
||||
|
||||
1 -> when (buttonID) {
|
||||
1 -> player?.let {
|
||||
end()
|
||||
val region = it.getViewport().getRegion()
|
||||
if (region == null || region is DynamicRegion || it.getZoneMonitor().isRestricted(ZoneRestriction.OFF_MAP)) {
|
||||
it.sendMessage("This location cannot be saved!")
|
||||
} else {
|
||||
setAttribute(it, "/save:teleorb:location", it.getLocation())
|
||||
sendInputDialogue(it, false, "Location saved. Enter a description of this location:",) { value ->
|
||||
setAttribute(it, "/save:teleorb:description", value as String)
|
||||
}
|
||||
it.sendMessage("Location saved.")
|
||||
it.graphics(Graphics(343))
|
||||
it.animate(Animation(1818))
|
||||
playAudio(it, Sounds.TELE_OTHER_CAST_199)
|
||||
}
|
||||
}
|
||||
2 -> options("Recharge with Law Runes","Recharge with additional orbs").also {stage++}
|
||||
3 -> player?.let {
|
||||
end()
|
||||
var runesPerTeleport = if (getAttribute(it, "snowscape:boostedmode", false)) runesPerTeleportBoosted else runesPerTeleportNormal
|
||||
it.sendMessage("Current saved location: " + getAttribute(it, "teleorb:description", "Unknown").replace("_"," "))
|
||||
it.sendMessage("Charges remaining: " + ((getAttribute(it, "teleorb:charges",0) as Int) / runesPerTeleport))
|
||||
}
|
||||
}
|
||||
2 -> when (buttonID) {
|
||||
1 -> player?.let {
|
||||
end()
|
||||
var runesPerTeleport = if (getAttribute(it, "snowscape:boostedmode", false)) runesPerTeleportBoosted else runesPerTeleportNormal
|
||||
sendInputDialogue(it, true, "Each charge requires $runesPerTeleport Law Runes. How many runes would you like to use?",) { value ->
|
||||
var amount = kotlin.math.min(amountInInventory(it,lawRune), value as Int)
|
||||
if (removeItem(it, Item(lawRune, amount))) {
|
||||
it.sendMessage("You charge the teleorb with $amount Law Runes.")
|
||||
amount += (getAttribute(it, "teleorb:charges",0) as Int)
|
||||
setAttribute(it, "/save:teleorb:charges", amount)
|
||||
it.sendMessage("Current charges: " + ((getAttribute(it, "teleorb:charges",0) as Int) / runesPerTeleport))
|
||||
it.graphics(Graphics(141,96))
|
||||
it.animate(Animation(722))
|
||||
playAudio(it, Sounds.LUNAR_EMBUE_RUNES_2888) //Yes, Imbue is mispelled in the sounds list.
|
||||
}
|
||||
}
|
||||
}
|
||||
2 -> player?.let {
|
||||
end()
|
||||
var runesPerTeleport = if (getAttribute(it, "snowscape:boostedmode", false)) runesPerTeleportBoosted else runesPerTeleportNormal
|
||||
sendInputDialogue(it, true, "Each additional orb adds one charge. How many would you like to use?",) { value ->
|
||||
var amount = kotlin.math.min(amountInInventory(it,teleorb) - 1, value as Int)
|
||||
if (amount > 0 && removeItem(it, Item(teleorb, amount))) {
|
||||
it.sendMessage("You destroy $amount teleorbs, fusing their energy into one.")
|
||||
amount = amount * runesPerTeleport
|
||||
amount += (getAttribute(it, "teleorb:charges",0) as Int)
|
||||
setAttribute(it, "/save:teleorb:charges", amount)
|
||||
it.sendMessage("Current charges: " + ((getAttribute(it, "teleorb:charges",0) as Int) / runesPerTeleport))
|
||||
it.graphics(Graphics(141,96))
|
||||
it.animate(Animation(722))
|
||||
playAudio(it, Sounds.LUNAR_EMBUE_RUNES_2888)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +1,55 @@
|
|||
package content.global.handlers.item
|
||||
|
||||
import core.api.inInventory
|
||||
import core.api.removeItem
|
||||
import core.api.teleport
|
||||
import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE
|
||||
import core.api.*
|
||||
import core.game.interaction.IntType
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.entity.player.link.TeleportManager
|
||||
import core.game.node.item.Item
|
||||
import core.game.world.map.Location
|
||||
import core.api.hasRequirement;
|
||||
import content.data.Quests
|
||||
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
|
||||
class TeleTabsListener : InteractionListener {
|
||||
|
||||
enum class TeleTabs(val item: Int, val location: Location, val exp: Double, val requirementCheck: (Player) -> Boolean = { true }) {
|
||||
ADDOUGNE_TELEPORT(8011, Location.create(2662, 3307, 0), 61.0, {
|
||||
player -> hasRequirement(player, "Plague City");
|
||||
player -> getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)
|
||||
}),
|
||||
AIR_ALTAR_TELEPORT(13599, Location.create(2978, 3296, 0), 0.0),
|
||||
ASTRAL_ALTAR_TELEPORT(13611, Location.create(2156, 3862, 0), 0.0),
|
||||
BLOOD_ALTAR_TELEPORT(13610, Location.create(3559, 9778, 0), 0.0),
|
||||
ASTRAL_ALTAR_TELEPORT(13611, Location.create(2156, 3862, 0), 0.0, {
|
||||
player -> hasRequirement(player, Quests.LUNAR_DIPLOMACY);
|
||||
}),
|
||||
BLOOD_ALTAR_TELEPORT(13610, Location.create(3559, 9778, 0), 0.0, {
|
||||
player -> hasRequirement(player, Quests.LEGACY_OF_SEERGAZE);
|
||||
}),
|
||||
BODY_ALTAR_TELEPORT(13604, Location.create(3055, 3443, 0), 0.0),
|
||||
CAMELOT_TELEPORT(8010, Location.create(2757, 3477, 0), 55.5),
|
||||
CHAOS_ALTAR_TELEPORT(13606, Location.create(3058, 3593, 0), 0.0),
|
||||
COSMIC_ALTAR_TELEPORT(13605, Location.create(2411, 4380, 0), 0.0),
|
||||
DEATH_ALTAR_TELEPORT(13609, Location.create(1863, 4639, 0), 0.0),
|
||||
COSMIC_ALTAR_TELEPORT(13605, Location.create(2411, 4380, 0), 0.0, {
|
||||
player -> hasRequirement(player, Quests.LOST_CITY);
|
||||
}),
|
||||
DEATH_ALTAR_TELEPORT(13609, Location.create(1863, 4639, 0), 0.0, {
|
||||
player -> hasRequirement(player, Quests.MOURNINGS_END_PART_II);
|
||||
}),
|
||||
EARTH_ALTAR_TELEPORT(13602, Location.create(3304, 3472, 0), 0.0),
|
||||
FALADOR_TELEPORT(8009, Location.create(2966, 3380, 0), 47.0),
|
||||
FIRE_ALTAR_TELEPORT(13603, Location.create(3311, 3252, 0), 0.0),
|
||||
LAW_ALTAR_TELEPORT(13608, Location.create(2857, 3378, 0), 0.0),
|
||||
LAW_ALTAR_TELEPORT(13608, Location.create(2857, 3378, 0), 0.0, {
|
||||
player -> if (!ItemDefinition.canEnterEntrana(player)) (player.sendMessage("The power of Saradomin prevents you from taking armour or weaponry to Entrana.") !is Unit) else true; // ugly way of doing this, but the sendMessage function returns a Unit type, so by using !is Unit it becomes false.
|
||||
}),
|
||||
LUMBRIDGE_TELEPORT(8008, Location.create(3222, 3218, 0), 41.0),
|
||||
MIND_ALTAR_TELEPORT(13600, Location.create(2979, 3510, 0), 0.0),
|
||||
NATURE_ALTAR_TELEPORT(13607, Location.create(2868, 3013, 0), 0.0),
|
||||
TELEKINETIC_GRAB(8022, Location.create(2836, 3285, 0), 0.0, {
|
||||
player -> hasRequirement(player, Quests.DRAGON_SLAYER);
|
||||
}),
|
||||
VARROCK_TELEPORT(8007, Location.create(3212, 3423, 0), 35.00),
|
||||
WATCH_TOWER_TELEPORT(8012, Location.create(2548, 3114, 0), 68.00),
|
||||
WATCH_TOWER_TELEPORT(8012, Location.create(2548, 3114, 0), 68.00, {
|
||||
player -> hasRequirement(player, Quests.WATCHTOWER);
|
||||
}),
|
||||
WATER_ALTAR_TELEPORT(13601, Location.create(3182, 3162, 0), 0.0);
|
||||
|
||||
companion object {
|
||||
|
|
@ -51,9 +67,17 @@ class TeleTabsListener : InteractionListener {
|
|||
val tabEnum = TeleTabs.forId(tab)
|
||||
if (tabEnum != null && inInventory(player,tab)) {
|
||||
val tabloc = tabEnum.location
|
||||
if (inInventory(player, tab) && tabEnum.requirementCheck(player)) {
|
||||
if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) {
|
||||
removeItem(player, Item(node.id, 1))
|
||||
if (inInventory(player, tab)) {
|
||||
if (tabEnum.requirementCheck(player)){
|
||||
if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) {
|
||||
removeItem(player, Item(node.id, 1))
|
||||
}
|
||||
}
|
||||
else {
|
||||
when (tabEnum){
|
||||
TeleTabs.ADDOUGNE_TELEPORT -> sendMessage(player, "You need to complete Plague City to use this tablet.")
|
||||
else -> sendMessage(player, "You do not have the requirements to use this tablet.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import core.game.world.map.zone.impl.WildernessZone;
|
|||
import core.plugin.Plugin;
|
||||
|
||||
import static core.api.ContentAPIKt.hasRequirement;
|
||||
import content.data.Quests;
|
||||
|
||||
/**
|
||||
* Represents the rotten potato plugin.
|
||||
|
|
@ -34,7 +35,7 @@ public final class TeleportCrystalPlugin extends OptionHandler {
|
|||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
if (!hasRequirement(player, "Mourning's End Part I"))
|
||||
if (!hasRequirement(player, Quests.MOURNINGS_END_PART_I))
|
||||
return true;
|
||||
if (!WildernessZone.checkTeleport(player, 20)) {
|
||||
player.getPacketDispatch().sendMessage("The crystal is unresponsive.");
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@ import core.game.world.update.flag.context.Graphics
|
|||
import org.rs09.consts.Items
|
||||
import core.game.interaction.InteractionListener
|
||||
import core.game.interaction.IntType
|
||||
import kotlinx.coroutines.delay
|
||||
import org.rs09.consts.Sounds
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
|
||||
|
||||
class ToyListeners : InteractionListener {
|
||||
companion object {
|
||||
|
|
@ -14,10 +21,12 @@ class ToyListeners : InteractionListener {
|
|||
private val MARIONETTE_WALK = Animation(3004)
|
||||
private val MARIONETTE_BOW = Animation(3005)
|
||||
private val MARIONETTE_DANCE = Animation(3006)
|
||||
private val MARIONETTE_GFX = arrayOf(intArrayOf(507, 508, 509, 510), intArrayOf(511, 512, 513, 514), intArrayOf(515, 516, 517, 518))
|
||||
private val MARIONETTE_GFX =
|
||||
arrayOf(intArrayOf(507, 508, 509, 510), intArrayOf(511, 512, 513, 514), intArrayOf(515, 516, 517, 518))
|
||||
private val SNOWGLOBE_SHAKE = Animation(7535) //Initial Shake
|
||||
private val SNOWGLOBE_HOLDFACE = Animation(7536) //Immediately after shake, player holds the snow globe to face
|
||||
private val SNOWGLOBE_INTERFACE = 659 //After HOLDFACE this interface is displayed, player either clicks 'continue' for inv of snowballs, or 'close' for no snowballs
|
||||
private val SNOWGLOBE_INTERFACE =
|
||||
659 //After HOLDFACE this interface is displayed, player either clicks 'continue' for inv of snowballs, or 'close' for no snowballs
|
||||
private val SNOWGLOBE_DOWNFAST = Animation(7537) //Used when player hit 'close' on the interface
|
||||
private val SNOWGLOBE_DOWNSLOW = Animation(7538) //Used when the player hit 'continue' on the interface
|
||||
private val SNOWGLOBE_STOMP = Animation(7528) //When player hits continue this animation plays
|
||||
|
|
@ -34,7 +43,7 @@ class ToyListeners : InteractionListener {
|
|||
}
|
||||
|
||||
override fun defineListeners() {
|
||||
on(Items.CHOCATRICE_CAPE_12634, IntType.ITEM, "operate"){ player, _ ->
|
||||
on(Items.CHOCATRICE_CAPE_12645, IntType.ITEM, "operate") { player, _ ->
|
||||
lockInteractions(player, 2)
|
||||
visualize(player, 8903, 1566)
|
||||
return@on true
|
||||
|
|
@ -44,18 +53,18 @@ class ToyListeners : InteractionListener {
|
|||
val index = MARIONETTES.indexOf(marionette.id)
|
||||
|
||||
lockInteractions(player, 2)
|
||||
when(getUsedOption(player)) {
|
||||
when (getUsedOption(player)) {
|
||||
"jump" -> visualize(player, MARIONETTE_JUMP, MARIONETTE_GFX[index][0])
|
||||
"walk" -> visualize(player, MARIONETTE_WALK, MARIONETTE_GFX[index][1])
|
||||
"bow" -> visualize(player, MARIONETTE_BOW, MARIONETTE_GFX[index][2])
|
||||
"bow" -> visualize(player, MARIONETTE_BOW, MARIONETTE_GFX[index][2])
|
||||
"dance" -> visualize(player, MARIONETTE_DANCE, MARIONETTE_GFX[index][3])
|
||||
}
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Items.REINDEER_HAT_10507, IntType.ITEM, "operate"){ player, _ ->
|
||||
on(Items.REINDEER_HAT_10507, IntType.ITEM, "operate") { player, _ ->
|
||||
lockInteractions(player, 2)
|
||||
animate(player, 5059)
|
||||
visualize(player, 5059, 859)
|
||||
return@on true
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +73,7 @@ class ToyListeners : InteractionListener {
|
|||
animate(player, SNOWGLOBE_SHAKE)
|
||||
runTask(player, 3) {
|
||||
animate(player, SNOWGLOBE_HOLDFACE)
|
||||
runTask(player){
|
||||
runTask(player) {
|
||||
openInterface(player, SNOWGLOBE_INTERFACE)
|
||||
}
|
||||
}
|
||||
|
|
@ -80,17 +89,17 @@ class ToyListeners : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
|
||||
on(Items.TOY_KITE_12844, IntType.ITEM, "fly"){ player, _ ->
|
||||
on(Items.TOY_KITE_12844, IntType.ITEM, "fly","operate") { player, _ ->
|
||||
lockInteractions(player, 2)
|
||||
animate(player, TOY_KITE_FLY)
|
||||
return@on true
|
||||
}
|
||||
|
||||
on(Items.YO_YO_4079, IntType.ITEM, "play", "loop", "walk", "crazy"){ player, _ ->
|
||||
on(Items.YO_YO_4079, IntType.ITEM, "play", "loop", "walk", "crazy") { player, _ ->
|
||||
val option = getUsedOption(player)
|
||||
|
||||
lockInteractions(player, 2)
|
||||
when(option) {
|
||||
when (option) {
|
||||
"play" -> animate(player, YOYO_PLAY)
|
||||
"loop" -> animate(player, YOYO_LOOP)
|
||||
"walk" -> animate(player, YOYO_WALK)
|
||||
|
|
@ -99,11 +108,11 @@ class ToyListeners : InteractionListener {
|
|||
return@on true
|
||||
}
|
||||
|
||||
on(Items.ZOMBIE_HEAD_6722, IntType.ITEM, "talk-at", "display", "question"){ player, _ ->
|
||||
on(Items.ZOMBIE_HEAD_6722, IntType.ITEM, "talk-at", "display", "question") { player, _ ->
|
||||
val option = getUsedOption(player)
|
||||
|
||||
lockInteractions(player, 2)
|
||||
when(option) {
|
||||
when (option) {
|
||||
"talk-at" -> {
|
||||
animate(player, ZOMBIE_HEAD_TALK_AT)
|
||||
sendChat(player, "Alas!")
|
||||
|
|
@ -116,5 +125,12 @@ class ToyListeners : InteractionListener {
|
|||
}
|
||||
return@on true
|
||||
}
|
||||
on(Items.RUBBER_CHICKEN_4566, IntType.ITEM, "operate", "Dance") { player, _ ->
|
||||
lockInteractions(player, 2)
|
||||
visualize(player, 1835, -1)
|
||||
playJingle(player, 99);
|
||||
playAudio(player, 355, 100);
|
||||
return@on true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ class CrystalEquipmentRegister : StartupListener {
|
|||
val shield: Array<Int> = arrayOf(Items.NEW_CRYSTAL_SHIELD_4224, Items.CRYSTAL_SHIELD_FULL_4225, Items.CRYSTAL_SHIELD_9_10_4226, Items.CRYSTAL_SHIELD_8_10_4227, Items.CRYSTAL_SHIELD_7_10_4228, Items.CRYSTAL_SHIELD_6_10_4229, Items.CRYSTAL_SHIELD_5_10_4230, Items.CRYSTAL_SHIELD_4_10_4231, Items.CRYSTAL_SHIELD_3_10_4232, Items.CRYSTAL_SHIELD_2_10_4233, Items.CRYSTAL_SHIELD_1_10_4234, Items.CRYSTAL_SEED_4207)
|
||||
val bow: Array<Int> = arrayOf(Items.NEW_CRYSTAL_BOW_4212, Items.CRYSTAL_BOW_FULL_4214, Items.CRYSTAL_BOW_9_10_4215, Items.CRYSTAL_BOW_8_10_4216, Items.CRYSTAL_BOW_7_10_4217, Items.CRYSTAL_BOW_6_10_4218, Items.CRYSTAL_BOW_5_10_4219, Items.CRYSTAL_BOW_4_10_4220, Items.CRYSTAL_BOW_3_10_4221, Items.CRYSTAL_BOW_2_10_4222, Items.CRYSTAL_BOW_1_10_4223, Items.CRYSTAL_SEED_4207)
|
||||
override fun startup() {
|
||||
EquipmentDegrader.registerSet(250, shield)
|
||||
EquipmentDegrader.registerSet(250, bow)
|
||||
EquipmentDegrader.registerSet(1200, shield)
|
||||
EquipmentDegrader.registerSet(1200, bow)
|
||||
}
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ public final class AncientMaceSpecialHandler extends MeleeSwingHandler implement
|
|||
state.setStyle(CombatStyle.MELEE);
|
||||
int hit = 0;
|
||||
if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.1, 0.98)) {
|
||||
hit = RandomFunction.random(calculateHit(entity, victim, 1));
|
||||
hit = RandomFunction.random(calculateHit(entity, victim, 1) + 1);
|
||||
if (entity.getSkills().getPrayerPoints() < entity.getSkills().getStaticLevel(5)) {
|
||||
entity.getSkills().setPrayerPoints(entity.getSkills().getPrayerPoints() + hit);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,13 +59,10 @@ public final class BackstabSpecialHandler extends MeleeSwingHandler implements P
|
|||
}
|
||||
state.setStyle(CombatStyle.MELEE);
|
||||
int hit = 0;
|
||||
double accuracy = 1.0;
|
||||
if (!victim.getProperties().getCombatPulse().isAttacking()) {
|
||||
accuracy = 1.75;
|
||||
}
|
||||
if (isAccurateImpact(entity, victim, CombatStyle.MELEE, accuracy, 0.98)) {
|
||||
hit = RandomFunction.random(calculateHit(entity, victim, 1.0));
|
||||
victim.getSkills().updateLevel(Skills.DEFENCE, -hit / 10, 0);
|
||||
if (!victim.getProperties().getCombatPulse().isAttacking() || isAccurateImpact(entity, victim, CombatStyle.MELEE)) {
|
||||
hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1);
|
||||
if (victim.getSkills().getStaticLevel(Skills.DEFENCE) >= victim.getSkills().getDynamicLevels()[Skills.DEFENCE])
|
||||
victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0);
|
||||
}
|
||||
state.setEstimatedHit(hit);
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
package content.global.handlers.item.equipment.special;
|
||||
|
||||
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.DeathTask;
|
||||
import core.game.node.entity.combat.*;
|
||||
import core.game.node.entity.combat.ImpactHandler.HitsplatType;
|
||||
import core.game.node.entity.impl.Animator.Priority;
|
||||
import core.game.node.entity.impl.Projectile;
|
||||
|
|
@ -17,7 +15,6 @@ import core.game.world.update.flag.context.Graphics;
|
|||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
import core.tools.RandomFunction;
|
||||
import core.game.node.entity.combat.RangeSwingHandler;
|
||||
import core.game.world.GameWorld;
|
||||
import core.game.world.repository.Repository;
|
||||
import org.rs09.consts.Sounds;
|
||||
|
|
@ -34,6 +31,13 @@ import static core.api.ContentAPIKt.playGlobalAudio;
|
|||
@Initializable
|
||||
public final class ChainhitSpecialHandler extends RangeSwingHandler implements Plugin<Object> {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ChainhitSpecialHandler} {@code Object}.
|
||||
*/
|
||||
public ChainhitSpecialHandler() {
|
||||
super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* The sp::ecial energy required.
|
||||
*/
|
||||
|
|
@ -159,7 +163,7 @@ public final class ChainhitSpecialHandler extends RangeSwingHandler implements P
|
|||
public boolean pulse() {
|
||||
BattleState bs = new BattleState(entity, e);
|
||||
bs.setMaximumHit(calculateHit(player, e, 1.0));
|
||||
bs.setEstimatedHit(RandomFunction.RANDOM.nextInt(bs.getMaximumHit()));
|
||||
bs.setEstimatedHit(RandomFunction.random(bs.getMaximumHit() + 1));
|
||||
handleHit(victim, e, player, bs);
|
||||
ChainhitSpecialHandler.super.visualizeImpact(player, e, bs);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -31,13 +31,6 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler {
|
|||
*/
|
||||
private static final Graphics END_GRAPHIC = new Graphics(157, 96);
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ChinchompaSwingHandler} {@code Object}.
|
||||
*/
|
||||
public ChinchompaSwingHandler() {
|
||||
super(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int swing(Entity entity, Entity victim, BattleState state) {
|
||||
boolean multi = entity.getProperties().isMultiZone() && victim.getProperties().isMultiZone();
|
||||
|
|
@ -72,7 +65,7 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler {
|
|||
s.setStyle(CombatStyle.RANGE);
|
||||
int hit = 0;
|
||||
if (isAccurateImpact(entity, e, CombatStyle.RANGE)) {
|
||||
hit = RandomFunction.random(calculateHit(entity, e, 1.0));
|
||||
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
|
||||
}
|
||||
s.setEstimatedHit(hit);
|
||||
}
|
||||
|
|
|
|||
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