Compare commits

..

No commits in common. "master" and "Oct-07-2024" have entirely different histories.

1002 changed files with 12361 additions and 76359 deletions

1
Server/.gitignore vendored
View file

@ -2,7 +2,6 @@ bin/**
out/** out/**
data/logs/** data/logs/**
data/profile/** data/profile/**
data/playerstats/**
.idea/** .idea/**
/bin /bin
.DS_Store** .DS_Store**

View file

@ -25,7 +25,4 @@
<ObjectAction mode="add" id="21301" x="2662" y="3162" z="0" direction="e"/> <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="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> </parsing>

View file

@ -301,7 +301,7 @@
"Always check announcments", "Always check announcments",
"We thrivin", "We thrivin",
"Ship @name", "Ship @name",
"Dont forget to vote 2009scape!", "Dont forget to vote 2009Scape!",
"Kermit is too legit 2 quit", "Kermit is too legit 2 quit",
"Out here on the range we are having fun", "Out here on the range we are having fun",
"I am hank steel", "I am hank steel",
@ -367,16 +367,33 @@
"May Guthix bring you balance.", "May Guthix bring you balance.",
"May Guthix bring you balance.", "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.", "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!", "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.", "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.", "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.", "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.", "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!", "For Camelot!",
"Firmly grasp it!", "Firmly grasp it!",
"My legs!", "My legs!",
@ -479,525 +496,21 @@
"Shlisshalpshlaap", "Shlisshalpshlaap",
"Somebody call for an exterminator?", "Somebody call for an exterminator?",
"Decisive action. Should work.", "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.", "Darkness overpowering.",
"Got any questions about propane? Or propane accessories?", "Got any questions about propane? Or propane accessories?",
"When someone asks me if I am a god, I say Y E S!!!", "When someone asks me if I am a god, I say Y E S!!!",
"You run out of Marines?", "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", "Selling wildy protection, 100k gp",
"Can't we get you on Mastermind, @name?", "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.", "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.", "Cunnilingus and psychiatry brought us to this.",
"Ah, the Wilderness... where dreams of riches meet a swift demise.", "Oh, poor baby. What do you want, a Brimstail's Sampler?",
"Who needs a quest guide? I've got the whole wiki memorized.", "There's an old TzHarrian saying, you fuck up once, you lose two teeth.",
"Buying GF 10k coins. Must have at least 70 Agility.", "The lineup consisted simply of six hydrocoptic marzelvanes so fitted to the ambifacient lunar waneshaft that sidefumbling was prevented."
"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": [ "halloween": [
"Trick or treat!!!", "Trick or treat!!!",
@ -1008,9 +521,9 @@
"Costume party at my P O H!! Follow me!", "Costume party at my P O H!! Follow me!",
"Trick, then!", "Trick, then!",
"Brrrainssssssss...", "Brrrainssssssss...",
"'Cause this is thriller, thriller night!", "'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!", "This is Hallowe'en, this is Hallowe'en, pumpkins scream in the dead of night!",
"This is Hallowe'en, everybody make a scene!", "This is Hallowe'en, everybody make a scene, Trick or treat till the neighbors gonna die of fright!",
"In this town we call home, everyone hail to the pumpkin song!", "In this town we call home, everyone hail to the pumpkin song!",
"Watch out for Skeleton Jack!", "Watch out for Skeleton Jack!",
"The headless-what-man? Horse? Never heard of those.", "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

Binary file not shown.

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

Binary file not shown.

View file

@ -301,7 +301,7 @@
}, },
{ {
"id": "2025", "id": "2025",
"replaceId": "2026", "replaceId": "1534",
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
}, },
@ -312,7 +312,7 @@
"metal": "false" "metal": "false"
}, },
{ {
"id": "1530", "id": "2036",
"replaceId": "1531", "replaceId": "1531",
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
@ -925,7 +925,7 @@
}, },
{ {
"id": "3747", "id": "3747",
"replaceId": "3748", "replaceId": "1534",
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
}, },
@ -943,7 +943,7 @@
}, },
{ {
"id": "4148", "id": "4148",
"replaceId": "4246", "replaceId": "4248",
"fence": "false", "fence": "false",
"metal": "false" "metal": "false"
}, },
@ -1759,7 +1759,7 @@
}, },
{ {
"id": "14245", "id": "14245",
"replaceId": "14246", "replaceId": "14248",
"fence": "true", "fence": "true",
"metal": "false" "metal": "false"
}, },
@ -1984,14 +1984,16 @@
"replaceId": "28518", "replaceId": "28518",
"fence": "false", "fence": "false",
"metal": "true", "metal": "true",
"autowalk": "true" "autowalk": "true",
"questRequirement": "Icthlarin's Little Helper"
}, },
{ {
"id": "28514", "id": "28514",
"replaceId": "28518", "replaceId": "28518",
"fence": "false", "fence": "false",
"metal": "true", "metal": "true",
"autowalk": "true" "autowalk": "true",
"questRequirement": "Icthlarin's Little Helper"
}, },
{ {
"id": "21065", "id": "21065",

View file

@ -3262,7 +3262,7 @@
} }
], ],
"charm": [], "charm": [],
"ids": "73,74,75,419,420,421,422,423,424,2714,2863,2866,2869,2878,3622,4392,4393,4394,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5375,5376,5377,5378,5379,5380,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,6099,6100,6131", "ids": "73,74,75,419,420,421,422,423,424,1826,2714,2863,2866,2869,2878,3622,4392,4393,4394,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5375,5376,5377,5378,5379,5380,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,6099,6100,6131",
"description": "", "description": "",
"main": [ "main": [
{ {
@ -5858,28 +5858,32 @@
"charm": [ "charm": [
{ {
"minAmount": "1", "minAmount": "1",
"weight": "1000.0", "weight": "100.0",
"id": "0", "id": "12158",
"maxAmount": "1"
}
],
"tertiary": [
{
"minAmount": "1",
"weight": "4986.5",
"id": "0",
"maxAmount": "1" "maxAmount": "1"
}, },
{ {
"minAmount": "1", "minAmount": "1",
"weight": "12.5", "weight": "100.0",
"id": "10976", "id": "12159",
"maxAmount": "1" "maxAmount": "1"
}, },
{ {
"minAmount": "1", "minAmount": "1",
"weight": "1.0", "weight": "100.0",
"id": "10977", "id": "12160",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "12163",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5600.0",
"id": "0",
"maxAmount": "1" "maxAmount": "1"
} }
], ],
@ -5888,135 +5892,171 @@
"main": [ "main": [
{ {
"minAmount": "1", "minAmount": "1",
"weight": "39.0625", "weight": "50.0",
"id": "7844",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "10977",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "10976",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5323",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5298",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5281",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5301",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5280",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5294",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5297",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5104",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5100",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5106",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "12176",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5293",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5296",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5311",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5105",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "5292",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5295",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5303",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5302",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5321",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "5299",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "5.0",
"id": "31",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "0",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "3.0",
"id": "6666", "id": "6666",
"maxAmount": "1" "maxAmount": "1"
}, },
{ {
"minAmount": "1", "minAmount": "1",
"weight": "78.125", "weight": "3.0",
"id": "6665", "id": "6665",
"maxAmount": "1" "maxAmount": "1"
},
{
"minAmount": "1",
"weight": "13.0",
"id": "14422",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "13.0",
"id": "14430",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "345",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "327",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "371",
"maxAmount": "1"
},
{
"minAmount": "2",
"weight": "156.25",
"id": "372",
"maxAmount": "5"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "359",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "360",
"maxAmount": "3"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "383",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "349",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "331",
"maxAmount": "1"
},
{
"minAmount": "5",
"weight": "156.25",
"id": "313",
"maxAmount": "15"
},
{
"minAmount": "1",
"weight": "156.25",
"id": "1511",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "1383",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "78.125",
"id": "407",
"maxAmount": "1"
},
{
"minAmount": "4",
"weight": "78.125",
"id": "402",
"maxAmount": "8"
},
{
"minAmount": "5",
"weight": "4.0",
"id": "555",
"maxAmount": "18"
},
{
"minAmount": "3",
"weight": "78.125",
"id": "6664",
"maxAmount": "6"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "401",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "39.0625",
"id": "6667",
"maxAmount": "1"
} }
] ]
}, },
@ -11386,11 +11426,47 @@
"weight": "100.0", "weight": "100.0",
"id": "526", "id": "526",
"maxAmount": "1" "maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "1506",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "6065",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "6067",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "6069",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "6068",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "100.0",
"id": "6070",
"maxAmount": "1"
} }
], ],
"charm": [], "charm": [],
"ids": "370,357,348,369,347,371", "ids": "347,348,357,369,370,371,372,717,718,719,2349,2350,2351,2373,2374,2784,3216",
"description": "all combat mourners", "description": "",
"main": [] "main": []
}, },
{ {
@ -18085,7 +18161,7 @@
"maxAmount": "1" "maxAmount": "1"
} }
], ],
"ids": "1183,1184,1201,2359,2360,2361,2362,2373,7438,7439,7440,7441", "ids": "1183,1184,1201,2359,2360,2361,2362,7438,7439,7440,7441",
"description": "", "description": "",
"main": [ "main": [
{ {
@ -28469,10 +28545,60 @@
"maxAmount": "1" "maxAmount": "1"
} }
], ],
"charm": [], "charm": [
"ids": "2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057", {
"minAmount": "1",
"weight": "85.8093",
"id": "0",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "10.9113",
"id": "12158",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "1.6775",
"id": "12159",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "1.6019",
"id": "12160",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "0.0",
"id": "12163",
"maxAmount": "1"
}
],
"ids": "2044,2045,2046,2047,2048,2049,2051,2052,2053,2054,2055",
"description": "", "description": "",
"main": [] "main": [
{
"minAmount": "1",
"weight": "1.0",
"id": "1",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "124.0",
"id": "0",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "3.0",
"id": "7848",
"maxAmount": "1"
}
]
}, },
{ {
"default": [ "default": [
@ -29406,18 +29532,6 @@
"id": "1438", "id": "1438",
"maxAmount": "1" "maxAmount": "1"
}, },
{
"minAmount": "1",
"weight": "25.0",
"id": "1456",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "1450",
"maxAmount": "1"
},
{ {
"minAmount": "1", "minAmount": "1",
"weight": "25.0", "weight": "25.0",
@ -29590,18 +29704,6 @@
"id": "1438", "id": "1438",
"maxAmount": "1" "maxAmount": "1"
}, },
{
"minAmount": "1",
"weight": "25.0",
"id": "1456",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "1450",
"maxAmount": "1"
},
{ {
"minAmount": "1", "minAmount": "1",
"weight": "25.0", "weight": "25.0",
@ -29774,18 +29876,6 @@
"id": "1438", "id": "1438",
"maxAmount": "1" "maxAmount": "1"
}, },
{
"minAmount": "1",
"weight": "25.0",
"id": "1456",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "25.0",
"id": "1450",
"maxAmount": "1"
},
{ {
"minAmount": "1", "minAmount": "1",
"weight": "25.0", "weight": "25.0",
@ -39803,20 +39893,7 @@
] ]
}, },
{ {
"default": [ "default": [],
{
"minAmount": "1",
"weight": "1.0",
"id": "532",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "1.0",
"id": "9080",
"maxAmount": "1"
}
],
"charm": [ "charm": [
{ {
"minAmount": "1", "minAmount": "1",
@ -58788,26 +58865,6 @@
"description": "Ram", "description": "Ram",
"main": [] "main": []
}, },
{
"default": [
{
"minAmount": "1",
"weight": "1.0",
"id": "526",
"maxAmount": "1"
},
{
"minAmount": "1",
"weight": "1.0",
"id": "1583",
"maxAmount": "1"
}
],
"charm": [],
"ids": "6108",
"description": "",
"main": []
},
{ {
"default": [], "default": [],
"charm": [], "charm": [],
@ -58821,19 +58878,5 @@
"maxAmount": "1" "maxAmount": "1"
} }
] ]
},
{
"default": [
{
"minAmount": "1",
"weight": "1.0",
"id": "592",
"maxAmount": "1"
}
],
"charm": [],
"ids": "8127",
"description": "Dark energy core",
"main": []
} }
] ]

View file

@ -233,7 +233,7 @@
}, },
{ {
"item_id": "946", "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}-{1,2700,3407,0,100}-" "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}-"
}, },
{ {
"item_id": "952", "item_id": "952",
@ -241,7 +241,7 @@
}, },
{ {
"item_id": "954", "item_id": "954",
"loc_data": "{1,2094,3152,0,150}-{1,2785,3279,0,150}-{1,2786,3287,0,150}-{1,2786,3286,0,150}-" "loc_data": "{1,2094,3152,0,150}-"
}, },
{ {
"item_id": "960", "item_id": "960",
@ -339,14 +339,6 @@
"item_id": "1422", "item_id": "1422",
"loc_data": "{1,3320,3137,0,150}-" "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", "item_id": "1510",
"loc_data": "{1,2576,3334,0,100}-" "loc_data": "{1,2576,3334,0,100}-"
@ -627,10 +619,6 @@
"item_id": "4707", "item_id": "4707",
"loc_data": "{1,3571,3312,0,40}-" "loc_data": "{1,3571,3312,0,40}-"
}, },
{
"item_id": "4838",
"loc_data": "{1,2593,3103,1,40}-"
},
{ {
"item_id": "5008", "item_id": "5008",
"loc_data": "{1,3230,9609,0,44}-" "loc_data": "{1,3230,9609,0,44}-"

View file

@ -95,30 +95,6 @@
"walkable": "false", "walkable": "false",
"tabIndex": "-1" "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", "id": "74",
"interfaceType": "4", "interfaceType": "4",
@ -389,30 +365,6 @@
"walkable": "false", "walkable": "false",
"tabIndex": "-1" "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", "id": "256",
"interfaceType": "8", "interfaceType": "8",

View file

@ -5719,7 +5719,7 @@
}, },
{ {
"shop_price": "35", "shop_price": "35",
"examine": "Allows you to rest in the luxurious Paramayer Inn.", "examine": "Allows you to rest in the luxurious Paramayer&#91;sic&#93; Inn.",
"durability": null, "durability": null,
"name": "Paramaya ticket", "name": "Paramaya ticket",
"archery_ticket_price": "0", "archery_ticket_price": "0",
@ -5727,7 +5727,7 @@
}, },
{ {
"shop_price": "35", "shop_price": "35",
"examine": "Allows you to rest in the luxurious Paramayer Inn.", "examine": "Allows you to rest in the luxurious Paramayer&#91;sic&#93; Inn.",
"durability": null, "durability": null,
"name": "Paramaya ticket", "name": "Paramaya ticket",
"archery_ticket_price": "0", "archery_ticket_price": "0",
@ -16309,7 +16309,6 @@
"examine": "Maybe I should read this...", "examine": "Maybe I should read this...",
"durability": null, "durability": null,
"name": "A magic scroll", "name": "A magic scroll",
"tradeable": "false",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "1505" "id": "1505"
}, },
@ -16325,7 +16324,7 @@
"equipment_slot": "0" "equipment_slot": "0"
}, },
{ {
"examine": "Quite a small key.", "examine": "Quite a small key (Plague City).",
"durability": null, "durability": null,
"name": "A small key", "name": "A small key",
"archery_ticket_price": "0", "archery_ticket_price": "0",
@ -16870,7 +16869,7 @@
"id": "1583" "id": "1583"
}, },
{ {
"examine": "Apparently my name is Hartigen.", "examine": "Apparently my name is Hartigan",
"durability": null, "durability": null,
"name": "Id papers", "name": "Id papers",
"tradeable": "false", "tradeable": "false",
@ -20560,7 +20559,7 @@
}, },
{ {
"ge_buy_limit": "1000", "ge_buy_limit": "1000",
"examine": "Yuck, I don't like cabbage.", "examine": "On ground: Cabbage... yuck!In inventory: Yuck, I don't like cabbage.",
"grand_exchange_price": "41", "grand_exchange_price": "41",
"durability": null, "durability": null,
"name": "Cabbage", "name": "Cabbage",
@ -20579,7 +20578,7 @@
"id": "1966" "id": "1966"
}, },
{ {
"examine": "Yuck, a cabbage from Draynor Manor. I don't like cabbage.", "examine": "On ground: Cabbage... yuck!In inventory: Yuck, I don't like cabbage.",
"grand_exchange_price": "55", "grand_exchange_price": "55",
"durability": null, "durability": null,
"name": "Cabbage", "name": "Cabbage",
@ -33983,7 +33982,7 @@
{ {
"requirements": "{1,40}", "requirements": "{1,40}",
"ge_buy_limit": "2", "ge_buy_limit": "2",
"examine": "Rune platebody with complete gold trim & plating.", "examine": "Rune platebody with complete gold trim &amp; plating.",
"durability": null, "durability": null,
"weight": "10", "weight": "10",
"absorb": "3,0,6", "absorb": "3,0,6",
@ -38818,7 +38817,7 @@
"name": "Crystal bow 9/10", "name": "Crystal bow 9/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4215", "id": "4215",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,96,0,0,0,0,0,0,0,0,0,68"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38839,7 +38838,7 @@
"name": "Crystal bow 8/10", "name": "Crystal bow 8/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4216", "id": "4216",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,92,0,0,0,0,0,0,0,0,0,66"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38860,7 +38859,7 @@
"name": "Crystal bow 7/10", "name": "Crystal bow 7/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4217", "id": "4217",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,88,0,0,0,0,0,0,0,0,0,64"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38881,7 +38880,7 @@
"name": "Crystal bow 6/10", "name": "Crystal bow 6/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4218", "id": "4218",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,62"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38902,7 +38901,7 @@
"name": "Crystal bow 5/10", "name": "Crystal bow 5/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4219", "id": "4219",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,80,0,0,0,0,0,0,0,0,0,60"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38923,7 +38922,7 @@
"name": "Crystal bow 4/10", "name": "Crystal bow 4/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4220", "id": "4220",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,76,0,0,0,0,0,0,0,0,0,58"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38944,7 +38943,7 @@
"name": "Crystal bow 3/10", "name": "Crystal bow 3/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4221", "id": "4221",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,72,0,0,0,0,0,0,0,0,0,56"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38965,7 +38964,7 @@
"name": "Crystal bow 2/10", "name": "Crystal bow 2/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4222", "id": "4222",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,68,0,0,0,0,0,0,0,0,0,54"
}, },
{ {
"requirements": "{4,70}-{16,50}", "requirements": "{4,70}-{16,50}",
@ -38986,7 +38985,7 @@
"name": "Crystal bow 1/10", "name": "Crystal bow 1/10",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4223", "id": "4223",
"bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" "bonuses": "0,0,0,0,64,0,0,0,0,0,0,0,0,0,52"
}, },
{ {
"requirements": "{1,70}-{16,50}", "requirements": "{1,70}-{16,50}",
@ -39029,7 +39028,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4226", "id": "4226",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,49,52,51,0,78,68,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39043,7 +39042,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4227", "id": "4227",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,47,50,49,0,76,66,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39057,7 +39056,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4228", "id": "4228",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,45,48,47,0,74,65,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39071,7 +39070,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4229", "id": "4229",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,43,46,45,0,72,63,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39085,7 +39084,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4230", "id": "4230",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,41,44,43,0,70,61,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39099,7 +39098,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4231", "id": "4231",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,39,42,41,0,68,59,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39113,7 +39112,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4232", "id": "4232",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,37,40,39,0,66,58,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39127,7 +39126,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4233", "id": "4233",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,35,38,37,0,64,56,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -39141,7 +39140,7 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4234", "id": "4234",
"absorb": "6,0,12", "absorb": "6,0,12",
"bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", "bonuses": "0,0,0,-10,-10,33,36,35,0,62,54,0,0,0,0",
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
@ -42661,7 +42660,7 @@
"id": "4619" "id": "4619"
}, },
{ {
"examine": "It looks horrible.", "examine": "It looks horrible.On ground: Not good for eating.",
"durability": null, "durability": null,
"name": "Black mushroom", "name": "Black mushroom",
"weight": "1", "weight": "1",
@ -42750,7 +42749,7 @@
"equipment_slot": "12" "equipment_slot": "12"
}, },
{ {
"examine": "A silver pot made by Ruantun.", "examine": "Frank's shiny silver coated pot.",
"durability": null, "durability": null,
"name": "Silver pot", "name": "Silver pot",
"tradeable": "false", "tradeable": "false",
@ -42767,7 +42766,7 @@
"id": "4659" "id": "4659"
}, },
{ {
"examine": "A silver pot made by Ruantun filled with your blood.", "examine": "Frank's shiny silver coated pot.",
"durability": null, "durability": null,
"name": "Silver pot", "name": "Silver pot",
"tradeable": "false", "tradeable": "false",
@ -42776,7 +42775,7 @@
"id": "4660" "id": "4660"
}, },
{ {
"examine": "A blessed silver pot made by Ruantun filled with your blood.", "examine": "A silver pot made by Ruantun and blessed on Entrana.",
"durability": null, "durability": null,
"name": "Blessed pot", "name": "Blessed pot",
"weight": "2", "weight": "2",
@ -42784,7 +42783,7 @@
"id": "4661" "id": "4661"
}, },
{ {
"examine": "A silver pot made by Ruantun filled with blood and garlic.", "examine": "Frank's shiny silver coated pot.",
"durability": null, "durability": null,
"name": "Silver pot", "name": "Silver pot",
"tradeable": "false", "tradeable": "false",
@ -42793,7 +42792,7 @@
"id": "4662" "id": "4662"
}, },
{ {
"examine": "A blessed silver pot filled with blood and garlic.", "examine": "A silver pot made by Ruantun and blessed on Entrana.",
"durability": null, "durability": null,
"name": "Blessed pot", "name": "Blessed pot",
"weight": "2", "weight": "2",
@ -42801,7 +42800,7 @@
"id": "4663" "id": "4663"
}, },
{ {
"examine": "A silver pot made by Ruantun filled with blood and spices.", "examine": "Frank's shiny silver coated pot.",
"durability": null, "durability": null,
"name": "Silver pot", "name": "Silver pot",
"tradeable": "false", "tradeable": "false",
@ -42810,7 +42809,7 @@
"id": "4664" "id": "4664"
}, },
{ {
"examine": "A blessed silver pot filled with blood and spices.", "examine": "A silver pot made by Ruantun and blessed on Entrana.",
"durability": null, "durability": null,
"name": "Blessed pot", "name": "Blessed pot",
"weight": "2", "weight": "2",
@ -42818,7 +42817,7 @@
"id": "4665" "id": "4665"
}, },
{ {
"examine": "A silver pot made by Ruantun filled with blood, garlic and spices.", "examine": "Frank's shiny silver coated pot.",
"durability": null, "durability": null,
"name": "Silver pot", "name": "Silver pot",
"tradeable": "false", "tradeable": "false",
@ -42827,7 +42826,7 @@
"id": "4666" "id": "4666"
}, },
{ {
"examine": "A blessed silver pot filled with blood, garlic and spices.", "examine": "A silver pot made by Ruantun and blessed on Entrana.",
"durability": null, "durability": null,
"name": "Blessed pot", "name": "Blessed pot",
"weight": "2", "weight": "2",
@ -43127,13 +43126,13 @@
"id": "4702" "id": "4702"
}, },
{ {
"shop_price": "1", "shop_price": "975000",
"examine": "Doesn't look very special.", "examine": "A magic stone to make high-level furniture.",
"grand_exchange_price": "0", "grand_exchange_price": "977755",
"durability": null, "durability": null,
"name": "Magic stone", "name": "Magic stone",
"tradeable": "false", "tradeable": "true",
"weight": "2.267", "weight": "1",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "4703" "id": "4703"
}, },
@ -48988,7 +48987,7 @@
"id": "5419" "id": "5419"
}, },
{ {
"examine": "There is one potato in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(1)", "name": "Potatoes(1)",
@ -49005,7 +49004,7 @@
"id": "5421" "id": "5421"
}, },
{ {
"examine": "There are two potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(2)", "name": "Potatoes(2)",
@ -49022,7 +49021,7 @@
"id": "5423" "id": "5423"
}, },
{ {
"examine": "There are three potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(3)", "name": "Potatoes(3)",
@ -49039,7 +49038,7 @@
"id": "5425" "id": "5425"
}, },
{ {
"examine": "There are four potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(4)", "name": "Potatoes(4)",
@ -49056,7 +49055,7 @@
"id": "5427" "id": "5427"
}, },
{ {
"examine": "There are five potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(5)", "name": "Potatoes(5)",
@ -49073,7 +49072,7 @@
"id": "5429" "id": "5429"
}, },
{ {
"examine": "There are six potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(6)", "name": "Potatoes(6)",
@ -49090,7 +49089,7 @@
"id": "5431" "id": "5431"
}, },
{ {
"examine": "There are seven potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(7)", "name": "Potatoes(7)",
@ -49107,7 +49106,7 @@
"id": "5433" "id": "5433"
}, },
{ {
"examine": "There are eight potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(8)", "name": "Potatoes(8)",
@ -49124,7 +49123,7 @@
"id": "5435" "id": "5435"
}, },
{ {
"examine": "There are nine potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1276", "grand_exchange_price": "1276",
"durability": null, "durability": null,
"name": "Potatoes(9)", "name": "Potatoes(9)",
@ -49142,7 +49141,7 @@
}, },
{ {
"ge_buy_limit": "1000", "ge_buy_limit": "1000",
"examine": "There are ten potatoes in this sack.", "examine": "There are &lt;number of potatoes&gt; in this sack.",
"grand_exchange_price": "1052", "grand_exchange_price": "1052",
"durability": null, "durability": null,
"name": "Potatoes(10)", "name": "Potatoes(10)",
@ -49334,7 +49333,7 @@
"id": "5459" "id": "5459"
}, },
{ {
"examine": "There is one cabbage in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(1)", "name": "Cabbages(1)",
@ -49350,7 +49349,7 @@
"id": "5461" "id": "5461"
}, },
{ {
"examine": "There are two cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(2)", "name": "Cabbages(2)",
@ -49366,7 +49365,7 @@
"id": "5463" "id": "5463"
}, },
{ {
"examine": "There are three cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(3)", "name": "Cabbages(3)",
@ -49382,7 +49381,7 @@
"id": "5465" "id": "5465"
}, },
{ {
"examine": "There are four cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(4)", "name": "Cabbages(4)",
@ -49398,7 +49397,7 @@
"id": "5467" "id": "5467"
}, },
{ {
"examine": "There are five cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(5)", "name": "Cabbages(5)",
@ -49414,7 +49413,7 @@
"id": "5469" "id": "5469"
}, },
{ {
"examine": "There are six cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(6)", "name": "Cabbages(6)",
@ -49430,7 +49429,7 @@
"id": "5471" "id": "5471"
}, },
{ {
"examine": "There are seven cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(7)", "name": "Cabbages(7)",
@ -49446,7 +49445,7 @@
"id": "5473" "id": "5473"
}, },
{ {
"examine": "There are eight cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(8)", "name": "Cabbages(8)",
@ -49462,7 +49461,7 @@
"id": "5475" "id": "5475"
}, },
{ {
"examine": "There are nine cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "1304", "grand_exchange_price": "1304",
"durability": null, "durability": null,
"name": "Cabbages(9)", "name": "Cabbages(9)",
@ -49479,7 +49478,7 @@
}, },
{ {
"ge_buy_limit": "1000", "ge_buy_limit": "1000",
"examine": "There are ten cabbages in this sack.", "examine": "There are &lt;number of cabbages&gt; in this sack.",
"grand_exchange_price": "917", "grand_exchange_price": "917",
"durability": null, "durability": null,
"name": "Cabbages(10)", "name": "Cabbages(10)",
@ -55739,7 +55738,7 @@
"equipment_slot": "4" "equipment_slot": "4"
}, },
{ {
"examine": "These are in need of a good tailor.", "examine": "Damaged: These are in need of a good tailor.Repaired: A pair of mourner trousers.",
"durability": null, "durability": null,
"name": "Mourner trousers", "name": "Mourner trousers",
"weight": "2.25", "weight": "2.25",
@ -55747,7 +55746,7 @@
"id": "6066" "id": "6066"
}, },
{ {
"examine": "A pair of mourner trousers.", "examine": "Damaged: These are in need of a good tailor.Repaired: A pair of mourner trousers.",
"durability": null, "durability": null,
"name": "Mourner trousers", "name": "Mourner trousers",
"weight": "2.25", "weight": "2.25",
@ -58310,7 +58309,7 @@
{ {
"shop_price": "150", "shop_price": "150",
"ge_buy_limit": "100", "ge_buy_limit": "100",
"examine": "A brown armband, as worn by the Tai Bwo Wannai locals.", "examine": "A &lt;colour&gt; armband, as worn by the Tai Bwo Wannai locals.",
"grand_exchange_price": "734", "grand_exchange_price": "734",
"durability": null, "durability": null,
"name": "Villager armband", "name": "Villager armband",
@ -58443,7 +58442,7 @@
{ {
"shop_price": "150", "shop_price": "150",
"ge_buy_limit": "100", "ge_buy_limit": "100",
"examine": "A blue armband, as worn by the Tai Bwo Wannai locals.", "examine": "A &lt;colour&gt; armband, as worn by the Tai Bwo Wannai locals.",
"grand_exchange_price": "672", "grand_exchange_price": "672",
"durability": null, "durability": null,
"name": "Villager armband", "name": "Villager armband",
@ -58554,7 +58553,7 @@
{ {
"shop_price": "150", "shop_price": "150",
"ge_buy_limit": "100", "ge_buy_limit": "100",
"examine": "A yellow armband, as worn by the Tai Bwo Wannai locals.", "examine": "A &lt;colour&gt; armband, as worn by the Tai Bwo Wannai locals.",
"grand_exchange_price": "823", "grand_exchange_price": "823",
"durability": null, "durability": null,
"name": "Villager armband", "name": "Villager armband",
@ -58665,7 +58664,7 @@
{ {
"shop_price": "150", "shop_price": "150",
"ge_buy_limit": "100", "ge_buy_limit": "100",
"examine": "A pink armband, as worn by the Tai Bwo Wannai locals.", "examine": "A &lt;colour&gt; armband, as worn by the Tai Bwo Wannai locals.",
"grand_exchange_price": "1697", "grand_exchange_price": "1697",
"durability": null, "durability": null,
"name": "Villager armband", "name": "Villager armband",
@ -59765,7 +59764,7 @@
}, },
{ {
"destroy_message": "You will not get a replacement for the present. Open it for your reward.", "destroy_message": "You will not get a replacement for the present. Open it for your reward.",
"examine": "Thanks for all your help! Love, Bob & Neite.", "examine": "Thanks for all your help! Love, Bob &amp; Neite.",
"durability": null, "durability": null,
"name": "Present", "name": "Present",
"tradeable": "false", "tradeable": "false",
@ -59959,7 +59958,6 @@
"attack_speed": "5", "attack_speed": "5",
"turn180_anim": "1206", "turn180_anim": "1206",
"equipment_slot": "3", "equipment_slot": "3",
"attack_anims": "419,419,419,419",
"grand_exchange_price": "423100", "grand_exchange_price": "423100",
"stand_anim": "813", "stand_anim": "813",
"tradeable": "true", "tradeable": "true",
@ -70694,7 +70692,7 @@
}, },
{ {
"ge_buy_limit": "100", "ge_buy_limit": "100",
"examine": "Nice bit of crafting!", "examine": "In inventory: Nice bit of crafting! When released: Nice bit of crafting that...",
"grand_exchange_price": "3236", "grand_exchange_price": "3236",
"durability": null, "durability": null,
"name": "Toy doll", "name": "Toy doll",
@ -70712,7 +70710,7 @@
"id": "7764" "id": "7764"
}, },
{ {
"examine": "Nice bit of crafting!", "examine": "In inventory: Nice bit of crafting! When released: Nice bit of crafting that...",
"grand_exchange_price": "3289", "grand_exchange_price": "3289",
"durability": null, "durability": null,
"name": "Toy doll (wound)", "name": "Toy doll (wound)",
@ -93160,7 +93158,7 @@
}, },
{ {
"requirements": "{1,40}", "requirements": "{1,40}",
"examine": "Rune platebody with complete gold trim & plating.", "examine": "Rune platebody with complete gold trim &amp; plating.",
"durability": null, "durability": null,
"weight": "10", "weight": "10",
"absorb": "3,0,6", "absorb": "3,0,6",
@ -93782,9 +93780,6 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "10858", "id": "10858",
"stand_turn_anim": "7040", "stand_turn_anim": "7040",
"defence_anim": "7050",
"attack_anims": "7041,7041,7048,7049",
"attack_audios": "2503,0,2504,0",
"bonuses": "-4,27,21,4,0,0,0,0,4,-1,0,26,0,0,0" "bonuses": "-4,27,21,4,0,0,0,0,4,-1,0,26,0,0,0"
}, },
{ {
@ -93927,7 +93922,7 @@
}, },
{ {
"shop_price": "128", "shop_price": "128",
"examine": "I can keep my items in here, but I'll need a banker to get them out.", "examine": "I can keep my grub in here.",
"durability": null, "durability": null,
"name": "Plain satchel", "name": "Plain satchel",
"weight": "0.1", "weight": "0.1",
@ -93936,7 +93931,7 @@
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
"examine": "I can keep my seeds and herbs in here.", "examine": "I can keep my grub in here.",
"durability": null, "durability": null,
"name": "Green satchel", "name": "Green satchel",
"weight": "0.1", "weight": "0.1",
@ -93946,7 +93941,7 @@
}, },
{ {
"shop_price": "128", "shop_price": "128",
"examine": "I can keep my summoning charms in here.", "examine": "I can keep my grub in here.",
"durability": null, "durability": null,
"name": "Red satchel", "name": "Red satchel",
"weight": "0.1", "weight": "0.1",
@ -93964,7 +93959,7 @@
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
"examine": "I can keep my ores in here.", "examine": "I can keep my grub in here.",
"durability": null, "durability": null,
"name": "Gold satchel", "name": "Gold satchel",
"weight": "0.1", "weight": "0.1",
@ -93973,7 +93968,7 @@
"equipment_slot": "5" "equipment_slot": "5"
}, },
{ {
"examine": "I can keep my runes in here.", "examine": "I can keep my grub in here.",
"durability": null, "durability": null,
"name": "Rune satchel", "name": "Rune satchel",
"weight": "0.1", "weight": "0.1",
@ -105250,28 +105245,28 @@
"id": "12196" "id": "12196"
}, },
{ {
"examine": "A hatchling green dragon.", "examine": "(hatchling) A hatchling &lt;dragon colour&gt; dragon.(baby) A bigger baby &lt;colour&gt; dragon.",
"durability": null, "durability": null,
"name": "Dragon hatchling", "name": "Dragon hatchling",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12197" "id": "12197"
}, },
{ {
"examine": "Little Nipper.", "examine": "Baby: Little NipperAdult: Bigger Nipper.",
"durability": null, "durability": null,
"name": "Baby giant crab", "name": "Baby giant crab",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12198" "id": "12198"
}, },
{ {
"examine": "A stripy little baby raccoon.", "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.",
"durability": null, "durability": null,
"name": "Baby raccoon", "name": "Baby raccoon",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12199" "id": "12199"
}, },
{ {
"examine": "An experienced nut-thief.", "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.",
"durability": null, "durability": null,
"name": "Squirrel", "name": "Squirrel",
"archery_ticket_price": "0", "archery_ticket_price": "0",
@ -106504,28 +106499,28 @@
"id": "12468" "id": "12468"
}, },
{ {
"examine": "A hatchling red dragon.", "examine": "(hatchling) A hatchling &lt;dragon colour&gt; dragon.(baby) A bigger baby &lt;colour&gt; dragon.",
"durability": null, "durability": null,
"name": "Dragon hatchling", "name": "Hatchling dragon",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12469" "id": "12469"
}, },
{ {
"examine": "A hatchling blue dragon.", "examine": "(hatchling) A hatchling &lt;dragon colour&gt; dragon.(baby) A bigger baby &lt;colour&gt; dragon.",
"durability": null, "durability": null,
"name": "Hatchling dragon", "name": "Hatchling dragon",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12471" "id": "12471"
}, },
{ {
"examine": "A hatchling green dragon.", "examine": "(hatchling) A hatchling &lt;dragon colour&gt; dragon.(baby) A bigger baby &lt;colour&gt; dragon.",
"durability": null, "durability": null,
"name": "Hatchling dragon", "name": "Hatchling dragon",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12473" "id": "12473"
}, },
{ {
"examine": "A hatchling black dragon.", "examine": "(hatchling) A hatchling &lt;dragon colour&gt; dragon.(baby) A bigger baby &lt;colour&gt; dragon.",
"durability": null, "durability": null,
"name": "Hatchling dragon", "name": "Hatchling dragon",
"archery_ticket_price": "0", "archery_ticket_price": "0",
@ -106572,17 +106567,16 @@
"id": "12480" "id": "12480"
}, },
{ {
"examine": "Can't fly and can barely walk, but adorable nonetheless.", "examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.",
"durability": null, "durability": null,
"name": "Baby penguin", "name": "Baby penguin",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12481" "id": "12481"
}, },
{ {
"examine": "I can hatch this in an incubator.", "examine": "I can hatch this in an Incubator.",
"durability": null, "durability": null,
"name": "Penguin egg", "name": "Penguin egg",
"tradeable": "false",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12483" "id": "12483"
}, },
@ -108978,14 +108972,14 @@
"id": "12761" "id": "12761"
}, },
{ {
"examine": "Can't fly and can barely walk, but adorable nonetheless.", "examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.",
"durability": null, "durability": null,
"name": "Baby penguin", "name": "Baby penguin",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "12763" "id": "12763"
}, },
{ {
"examine": "Can't fly and can barely walk, but adorable nonetheless.", "examine": "(Baby) Can't fly and can barely walk, but adorable nonetheless. (adult) Emperor of all he surveys.",
"durability": null, "durability": null,
"name": "Baby penguin", "name": "Baby penguin",
"archery_ticket_price": "0", "archery_ticket_price": "0",
@ -119761,18 +119755,18 @@
}, },
{ {
"requirements": "{11,79}", "requirements": "{11,79}",
"destroy_message": "To get another pair of Flame Gloves, you need to keep ten beacons alight simultaneously and then talk to King Roald.",
"shop_price": "200", "shop_price": "200",
"examine": "The hottest gloves in town.", "examine": "The hottest gloves in town.",
"durability": null, "durability": null,
"destroy": "true",
"attack_speed": "4",
"absorb": "0,0,0",
"equipment_slot": "9",
"destroy_message": "To get another pair of Flame Gloves, you need to keep ten beacons alight simultaneously and then talk to King Roald.",
"name": "Flame gloves", "name": "Flame gloves",
"destroy": "true",
"archery_ticket_price": "0", "archery_ticket_price": "0",
"attack_speed": "4",
"id": "13660", "id": "13660",
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" "absorb": "0,0,0",
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
"equipment_slot": "9"
}, },
{ {
"requirements": "{11,92}", "requirements": "{11,92}",
@ -122130,7 +122124,7 @@
{ {
"lendable": "true", "lendable": "true",
"destroy_message": "Drop", "destroy_message": "Drop",
"examine": "Rune platebody with complete gold trim & plating.", "examine": "Rune platebody with complete gold trim &amp; plating.",
"grand_exchange_price": "2034838", "grand_exchange_price": "2034838",
"durability": null, "durability": null,
"name": "Gilded platebody", "name": "Gilded platebody",
@ -130892,7 +130886,7 @@
"bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
}, },
{ {
"destroy_message": "You can make another by casting the Charge Air Orb spell on the Abyssal Rift in the center of the Abyss.", "destroy_message": "You gained this orb from Dark Squall's base. You can probably get another one from visiting the same place.",
"examine": "This orb can used to teleport people...somehow.", "examine": "This orb can used to teleport people...somehow.",
"durability": null, "durability": null,
"name": "Strange teleorb", "name": "Strange teleorb",
@ -132101,20 +132095,5 @@
"archery_ticket_price": "0", "archery_ticket_price": "0",
"id": "14658", "id": "14658",
"equipment_slot": "0" "equipment_slot": "0"
},
{
"examine": "Emperor of all he surveys.",
"name": "Penguin",
"id": "12482"
},
{
"examine": "Emperor of all he surveys.",
"name": "Penguin",
"id": "12762"
},
{
"examine": "Emperor of all he surveys.",
"name": "Penguin",
"id": "12764"
} }
] ]

View file

@ -2079,18 +2079,6 @@
"region": "12880", "region": "12880",
"id": "441" "id": "441"
}, },
{
"region": "12888",
"id": "445"
},
{
"region": "12889",
"id": "445"
},
{
"region": "12890",
"id": "445"
},
{ {
"region": "12944", "region": "12944",
"id": "606" "id": "606"
@ -2211,18 +2199,6 @@
"region": "13142", "region": "13142",
"id": "459" "id": "459"
}, },
{
"region": "13144",
"id": "445"
},
{
"region": "13145",
"id": "445"
},
{
"region": "13146",
"id": "445"
},
{ {
"region": "13199", "region": "13199",
"id": "388" "id": "388"
@ -2295,18 +2271,6 @@
"region": "13373", "region": "13373",
"id": "586" "id": "586"
}, },
{
"region": "13400",
"id": "445"
},
{
"region": "13401",
"id": "445"
},
{
"region": "13402",
"id": "445"
},
{ {
"region": "13456", "region": "13456",
"id": "452" "id": "452"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -16324,7 +16324,7 @@
"ids": "11629" "ids": "11629"
}, },
{ {
"examine": "This tells you which way is which.", "examine": "South to Falador :: West to Taverley :: East to Varrock.",
"ids": "11630,11631,11632,11633" "ids": "11630,11631,11632,11633"
}, },
{ {

View file

@ -213,7 +213,7 @@
"general_store": "true", "general_store": "true",
"id": "25", "id": "25",
"title": "Lumbridge General Store", "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}-{1939,1000,1}" "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}"
}, },
{ {
"npcs": "4716", "npcs": "4716",
@ -564,7 +564,7 @@
"general_store": "false", "general_store": "false",
"id": "65", "id": "65",
"title": "Dodgy Mikes Second-hand Clothing", "title": "Dodgy Mikes Second-hand Clothing",
"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}" "stock": "{7114,10,100}"
}, },
{ {
"npcs": "2161", "npcs": "2161",
@ -1599,7 +1599,7 @@
"general_store": "false", "general_store": "false",
"id": "181", "id": "181",
"title": "MoonClan Fine Clothes", "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}-{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}" "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}"
}, },
{ {
"npcs": "", "npcs": "",
@ -2177,23 +2177,5 @@
"id": "255", "id": "255",
"title": "Castle Wars Ticket Exchange", "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}" "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

View file

@ -2,7 +2,6 @@ package content.data
import content.global.skill.magic.TeleportMethod import content.global.skill.magic.TeleportMethod
import content.global.skill.slayer.SlayerManager.Companion.getInstance import content.global.skill.slayer.SlayerManager.Companion.getInstance
import content.global.skill.slayer.SlayerUtils
import core.ServerConstants import core.ServerConstants
import core.api.* import core.api.*
import core.game.event.TeleportEvent import core.game.event.TeleportEvent
@ -305,7 +304,7 @@ enum class EnchantedJewellery(
return return
} }
sendNPCDialogue(player, slayerManager.master!!.npc, "You're currently " + sendNPCDialogue(player, slayerManager.master!!.npc, "You're currently " +
"assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player))} " + "assigned to kill ${getSlayerTaskName(player).lowercase(Locale.getDefault())}'s; " +
"only ${getSlayerTaskKillsRemaining(player)} more to go.", core.game.dialogue.FacialExpression.FRIENDLY) "only ${getSlayerTaskKillsRemaining(player)} more to go.", core.game.dialogue.FacialExpression.FRIENDLY)
// Slayer tracker UI // Slayer tracker UI
setVarp(player, 2502, slayerManager.flags.taskFlags shr 4) setVarp(player, 2502, slayerManager.flags.taskFlags shr 4)

View file

@ -100,7 +100,7 @@ public enum GodBook {
* @param page the page. * @param page the page.
*/ */
public void insertPage(Player player, Item book, Item page) { public void insertPage(Player player, Item book, Item page) {
if (!hasRequirement(player, Quests.HORROR_FROM_THE_DEEP)) if (!hasRequirement(player, "Horror from the Deep"))
return; return;
if (hasPage(player, book, page)) { if (hasPage(player, book, page)) {
player.sendMessage("The book already has that page."); player.sendMessage("The book already has that page.");

View file

@ -1,158 +0,0 @@
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
}
}

View file

@ -30,36 +30,36 @@ public enum Consumables {
HERRING(new Food(new int[] {347}, new HealingEffect(5))), HERRING(new Food(new int[] {347}, new HealingEffect(5))),
MACKEREL(new Food(new int[] {355}, new HealingEffect(6))), MACKEREL(new Food(new int[] {355}, new HealingEffect(6))),
ROAST_BIRD_MEAT(new Food(new int[] {9980}, new HealingEffect(6))), ROAST_BIRD_MEAT(new Food(new int[] {9980}, new HealingEffect(6))),
THIN_SNAIL(new Food(new int[] {3369}, new RandomHealthEffect(5, 7))), THIN_SNAIL(new Food(new int[] {3369}, new HealingEffect(5))),
TROUT(new Food(new int[] {333}, new HealingEffect(7))), TROUT(new Food(new int[] {333}, new HealingEffect(7))),
SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new RandomHealthEffect(7, 11))), SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new HealingEffect(7))),
SPIDER_ON_SHAFT(new Food(new int[] {6299}, new HealingEffect(7))), SPIDER_ON_SHAFT(new Food(new int[] {6299}, new HealingEffect(7))),
ROAST_RABBIT(new Food(new int[] {7223}, new HealingEffect(7))), ROAST_RABBIT(new Food(new int[] {7223}, new HealingEffect(7))),
LEAN_SNAIL(new Food(new int[] {3371}, new RandomHealthEffect(6, 8))), LEAN_SNAIL(new Food(new int[] {3371}, new HealingEffect(8))),
COD(new Food(new int[] {339}, new HealingEffect(7))), COD(new Food(new int[] {339}, new HealingEffect(7))),
PIKE(new Food(new int[] {351}, new HealingEffect(8))), PIKE(new Food(new int[] {351}, new HealingEffect(8))),
ROAST_BEAST_MEAT(new Food(new int[] {9988}, 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))), COOKED_CRAB_MEAT(new Food(new int[] {7521, 7523, 7524, 7525, 7526}, new HealingEffect(2))),
FAT_SNAIL(new Food(new int[] {3373}, new RandomHealthEffect(7, 9))), FAT_SNAIL(new Food(new int[] {3373}, new HealingEffect(9))),
SALMON(new Food(new int[] {329}, new HealingEffect(9))), SALMON(new Food(new int[] {329}, new HealingEffect(9))),
SLIMY_EEL(new Food(new int[] {3381}, new RandomHealthEffect(6, 10))), SLIMY_EEL(new Food(new int[] {3381}, new HealingEffect(6))),
TUNA(new Food(new int[] {361}, new HealingEffect(10))), TUNA(new Food(new int[] {361}, new HealingEffect(10))),
COOKED_KARAMBWAN(new Food(new int[] {3144}, new HealingEffect(18)), true), COOKED_KARAMBWAN(new Food(new int[] {3144}, new HealingEffect(18)), true),
COOKED_CHOMPY(new Food(new int[] {2878}, new HealingEffect(10))), COOKED_CHOMPY(new Food(new int[] {2878}, new HealingEffect(10))),
RAINBOW_FISH(new Food(new int[] {10136}, new HealingEffect(11))), RAINBOW_FISH(new Food(new int[] {10136}, new HealingEffect(11))),
CAVE_EEL(new Food(new int[] {5003}, new RandomHealthEffect(8, 12))), CAVE_EEL(new Food(new int[] {5003}, new HealingEffect(7))),
LOBSTER(new Food(new int[] {379}, new HealingEffect(12))), LOBSTER(new Food(new int[] {379}, new HealingEffect(12))),
COOKED_JUBBLY(new Food(new int[] {7568}, new HealingEffect(15))), COOKED_JUBBLY(new Food(new int[] {7568}, new HealingEffect(15))),
BASS(new Food(new int[] {365}, new HealingEffect(13))), BASS(new Food(new int[] {365}, new HealingEffect(13))),
SWORDFISH(new Food(new int[] {373}, new HealingEffect(14))), SWORDFISH(new Food(new int[] {373}, new HealingEffect(14))),
LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(11))), LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(14))),
MONKFISH(new Food(new int[] {7946}, new HealingEffect(16))), MONKFISH(new Food(new int[] {7946}, new HealingEffect(16))),
SHARK(new Food(new int[] {385}, new HealingEffect(20))), SHARK(new Food(new int[] {385}, new HealingEffect(20))),
SEA_TURTLE(new Food(new int[] {397}, new HealingEffect(21))), SEA_TURTLE(new Food(new int[] {397}, new HealingEffect(21))),
MANTA_RAY(new Food(new int[] {391}, new HealingEffect(22))), MANTA_RAY(new Food(new int[] {391}, new HealingEffect(22))),
KARAMBWANJI(new Food(new int[] {3151}, new HealingEffect(3))), 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.")), 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(1))), CRAYFISH(new Food(new int[] {13433}, new HealingEffect(2))),
GIANT_FROG_LEGS(new Food(new int [] {4517}, new HealingEffect(6))), GIANT_FROG_LEGS(new Food(new int [] {4517}, new HealingEffect(6))),
/** Breads */ /** Breads */
@ -111,7 +111,7 @@ public enum Consumables {
/** Vegetables */ /** Vegetables */
POTATO(new Food(new int[] {1942}, new HealingEffect(1), "You eat the potato. Yuck!")), POTATO(new Food(new int[] {1942}, new HealingEffect(1), "You eat the potato. Yuck!")),
BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(4))), BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(2))),
SPICY_SAUCE(new Food(new int[] {7072, 1923}, new HealingEffect(2))), SPICY_SAUCE(new Food(new int[] {7072, 1923}, new HealingEffect(2))),
CHILLI_CON_CARNE(new Food(new int[] {7062, 1923}, new HealingEffect(5))), CHILLI_CON_CARNE(new Food(new int[] {7062, 1923}, new HealingEffect(5))),
SCRAMBLED_EGG(new Food(new int[] {7078, 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))), MUSHROOM_POTATO(new Food(new int[] {7058}, new HealingEffect(20))),
TUNA_AND_CORN(new Food(new int[] {7068, 1923}, new HealingEffect(13))), TUNA_AND_CORN(new Food(new int[] {7068, 1923}, new HealingEffect(13))),
TUNA_POTATO(new Food(new int[] {7060}, new HealingEffect(22))), TUNA_POTATO(new Food(new int[] {7060}, new HealingEffect(22))),
ONION(new Food(new int[] {1957}, new HealingEffect(1), "It's always sad to see a grown man/woman cry.")), 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(1), "You eat the cabbage. Yuck!")), CABBAGE(new Food(new int[] {1965}, new HealingEffect(2), "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.")), 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))), EVIL_TURNIP(new Food(new int[] {12134, 12136, 12138}, new HealingEffect(6))),
SPINACH_ROLL(new Food(new int[] {1969}, new HealingEffect(2))), 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(new Food(new int[] {2108}, new HealingEffect(2))),
ORANGE_CHUNKS(new Food(new int[] {2110}, new HealingEffect(2))), ORANGE_CHUNKS(new Food(new int[] {2110}, new HealingEffect(2))),
ORANGE_SLICES(new Food(new int[] {2112}, new HealingEffect(2))), ORANGE_SLICES(new Food(new int[] {2112}, new HealingEffect(2))),
PAPAYA_FRUIT(new Food(new int[] {5972}, new MultiEffect(new EnergyEffect(5), new HealingEffect(8)))), PAPAYA_FRUIT(new Food(new int[] {5972}, new HealingEffect(2))),
TENTI_PINEAPPLE(new FakeConsumable(1851, new String[] {"Try using a knife to slice it into pieces."})), 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(new FakeConsumable(2114, new String[] {"Try using a knife to slice it into pieces."})),
PINEAPPLE_CHUNKS(new Food(new int[] {2116}, new HealingEffect(2))), 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)))), STRANGE_FRUIT(new Food(new int[] {464}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(30)))),
/** Gnome Cooking */ /** Gnome Cooking */
TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(8))), TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(12))),
PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(8))), PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(12))),
SPICY_CRUNCHIES(new Food(new int[] {2213}, new HealingEffect(7))), SPICY_CRUNCHIES(new Food(new int[] {2213}, new HealingEffect(7))),
PREMADE_SY_CRUNCH(new Food(new int[] {2241}, new HealingEffect(7))), PREMADE_SY_CRUNCH(new Food(new int[] {2241}, new HealingEffect(7))),
WORM_CRUNCHIES(new Food(new int[] {2205}, new HealingEffect(8))), 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)))), OOMLIE_WRAP(new Food(new int[] {Items.COOKED_OOMLIE_WRAP_2343}, new MultiEffect(new HealingEffect(14), new AchievementEffect(DiaryType.KARAMJA, 2, 2)))),
ROE(new Food(new int[]{11324}, new HealingEffect(3))), ROE(new Food(new int[]{11324}, new HealingEffect(3))),
EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))), EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))),
CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))), CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(6))),
EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))), 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.")), FROG_SPAWN(new Food(new int[] {5004}, new RandomHealthEffect(3, 7), "You eat the frogspawn. Yuck.")),
@ -328,7 +328,7 @@ public enum Consumables {
ANTIPOISON_(new Potion(new int[] {5943, 5945, 5947, 5949}, new AddTimerEffect("poison:immunity", minutesToTicks(9)))), ANTIPOISON_(new Potion(new int[] {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)))), 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)))), 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 CureDiseaseEffect())), RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new MultiEffect(new SetAttributeEffect("disease:immunity", 300), new RemoveTimerEffect("disease")))),
AGILITY(new Potion(new int[] {3032, 3034, 3036, 3038}, new SkillEffect(Skills.AGILITY, 3, 0))), AGILITY(new Potion(new int[] {3032, 3034, 3036, 3038}, new SkillEffect(Skills.AGILITY, 3, 0))),
HUNTER(new Potion(new int[] {9998, 10000, 10002, 10004}, new SkillEffect(Skills.HUNTER, 3, 0))), HUNTER(new Potion(new int[] {9998, 10000, 10002, 10004}, new SkillEffect(Skills.HUNTER, 3, 0))),
RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))), RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))),
@ -339,8 +339,8 @@ public enum Consumables {
FISHING(new Potion(new int[] {2438, 151, 153, 155}, new SkillEffect(Skills.FISHING, 3, 0))), FISHING(new Potion(new int[] {2438, 151, 153, 155}, new SkillEffect(Skills.FISHING, 3, 0))),
PRAYER(new Potion(new int[] {2434, 139, 141, 143}, new PrayerEffect(7, 0.25))), PRAYER(new Potion(new int[] {2434, 139, 141, 143}, new PrayerEffect(7, 0.25))),
SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new RestoreEffect(8, 0.25, true))), SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new RestoreEffect(8, 0.25, true))),
ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1)))), ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1), new RandomPrayerEffect(0, 10)))),
ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))), ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new SetAttributeEffect("fire:immune", 600, true))),
GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))), GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))),
MAGIC_ESS(new Potion(new int[] {11491, 11489}, new SkillEffect(Skills.MAGIC,3,0))), MAGIC_ESS(new Potion(new int[] {11491, 11489}, new SkillEffect(Skills.MAGIC,3,0))),
SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25, true), new AddTimerEffect("poison:immunity", secondsToTicks(90)), new RemoveTimerEffect("disease")))), SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25, true), new AddTimerEffect("poison:immunity", secondsToTicks(90)), new RemoveTimerEffect("disease")))),
@ -349,10 +349,10 @@ public enum Consumables {
/** Barbarian Mixes */ /** Barbarian Mixes */
PRAYERMIX(new BarbarianMix(new int[] {11465, 11467}, new MultiEffect(new PrayerEffect(7, 0.25), new HealingEffect(6)))), PRAYERMIX(new BarbarianMix(new int[] {11465, 11467}, new MultiEffect(new PrayerEffect(7, 0.25), new HealingEffect(6)))),
ZAMMY_MIX(new BarbarianMix(new int[] {11521, 11523}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1)))), 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)))),
ATT_MIX(new BarbarianMix(new int[] {11429, 11431}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new HealingEffect(3)))), ATT_MIX(new BarbarianMix(new int[] {11429, 11431}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new HealingEffect(3)))),
ANTIP_MIX(new BarbarianMix(new int[] {11433, 11435}, new MultiEffect(new AddTimerEffect("poison:immunity", secondsToTicks(90)), new HealingEffect(3)))), ANTIP_MIX(new BarbarianMix(new int[] {11433, 11435}, new MultiEffect(new AddTimerEffect("poison:immunity", secondsToTicks(90)), new HealingEffect(3)))),
RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new CureDiseaseEffect(), new HealingEffect(3)))), RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new RemoveTimerEffect("disease"), new SetAttributeEffect("disease:immunity", 300), new HealingEffect(3)))),
STR_MIX(new BarbarianMix(new int[] {11443, 11441}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0.1), 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)))), 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)))), SUPER_RESTO_MIX(new BarbarianMix(new int [] {11493, 11495}, new MultiEffect(new RestoreEffect(8,0.25), new PrayerEffect(8, 0.25), new SummoningEffect(8, 0.25), new HealingEffect(6)))),
@ -367,7 +367,6 @@ public enum Consumables {
SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))), 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)))), 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)))), 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 */ /** Stealing creation potions */
SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))), SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))),

View file

@ -1,21 +0,0 @@
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.")
}
}
}
}

View file

@ -30,13 +30,11 @@ public class RestoreEffect extends ConsumableEffect {
int[] skills = this.all_skills ? ALL_SKILLS : SKILLS; int[] skills = this.all_skills ? ALL_SKILLS : SKILLS;
for(int skill : skills){ for(int skill : skills){
int statL = sk.getStaticLevel(skill); int statL = sk.getStaticLevel(skill);
int boost = (int) (base + (statL * bonus));
int curL = sk.getLevel(skill); int curL = sk.getLevel(skill);
if(curL < statL){ if(curL < statL){
int boost = (int) (base + (statL * bonus));
p.getSkills().updateLevel(skill, boost, statL); p.getSkills().updateLevel(skill, boost, statL);
} }
if (skill == Skills.PRAYER)
p.getSkills().incrementPrayerPoints(boost);
} }
} }
} }

View file

@ -11,13 +11,12 @@ import core.ServerStore.Companion.getString
import content.global.bots.ShootingStarBot import content.global.bots.ShootingStarBot
import core.game.world.repository.Repository import core.game.world.repository.Repository
import core.tools.RandomFunction
/** /**
* Represents a shooting star object (Only ever initialized once) (ideally) * Represents a shooting star object (Only ever initialized once) (ideally)
* @author Ceikry * @author Ceikry
*/ */
class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()) { class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()){
val crash_locations = mapOf( val crash_locations = mapOf(
"East of Dark Wizards' Tower" to Location.create(2925, 3339, 0), // East of Dark Wizards' Tower "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 "Crafting Guild" to Location.create(2940, 3280, 0), // Crafting Guild Mine
@ -31,7 +30,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
"Relleka mining site" to Location.create(2682, 3700, 0), // Rellekka mining site "Relleka mining site" to Location.create(2682, 3700, 0), // Rellekka mining site
"Jatizso mine" to Location.create(2393, 3815, 0), //Jatiszo mining site (requires Fremennik Isles prereqs) "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) "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) "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 Isles prereqs) currently inaccessible as bridge does not work //"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 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) "Ardougne eastern mine" to Location.create(2706, 3334, 0), // Ardougne mining site (Legends Guild)
@ -80,15 +79,22 @@ 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) * Degrades a ShootingStar (or removes the starObject and spawns a Star Sprite if it's the last star)
*/ */
fun degrade() { fun degrade() {
if(level.ordinal == 0) { if(level.ordinal == 0){
spawnSprite() selfBots.filter { it.isMining() }.forEach { it.sleep() }
SceneryBuilder.remove(starObject)
isSpawned = false
starSprite.location = starObject.location
starSprite.init()
spriteSpawned = true
ShootingStarPlugin.getStoreFile().clear()
return return
} }
level = getNextType() level = getNextType()
maxDust = level.totalStardust maxDust = level.totalStardust
dustLeft = level.totalStardust dustLeft = level.totalStardust
ShootingStarPlugin.getStoreFile()["level"] = level.ordinal ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered
val newStar = Scenery(level.objectId, starObject.location) val newStar = Scenery(level.objectId, starObject.location)
SceneryBuilder.replace(starObject, newStar) SceneryBuilder.replace(starObject, newStar)
@ -104,6 +110,7 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
*/ */
fun fire() { fun fire() {
SceneryBuilder.remove(starObject) SceneryBuilder.remove(starObject)
rebuildVars()
clearSprite() clearSprite()
SceneryBuilder.add(starObject) SceneryBuilder.add(starObject)
if(!isSpawned) { if(!isSpawned) {
@ -116,54 +123,37 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
} }
isSpawned = true isSpawned = true
Repository.sendNews("A shooting star level ${level.ordinal + 1} just crashed near ${location}!") 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. * Rebuilds some of the variables with new information.
*/ */
fun rebuildVars(){ fun rebuildVars(){
// Defaults if(firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()){
var levelOrd = RandomFunction.random(9) level = ShootingStarType.values()[ShootingStarPlugin.getStoreFile().getInt("level")]
level = ShootingStarType.values()[levelOrd] location = ShootingStarPlugin.getStoreFile().getString("location")
location = crash_locations.entries.random().key isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered")
isDiscovered = false } else {
dustLeft = level.totalStardust level = ShootingStarType.values().random()
ticks = 0 location = crash_locations.entries.random().key
spriteSpawned = false isDiscovered = 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 maxDust = level.totalStardust
dustLeft = level.totalStardust
starObject = Scenery(level.objectId, crash_locations.get(location)) starObject = Scenery(level.objectId, crash_locations.get(location))
}
fun spawnSprite() { ShootingStarPlugin.getStoreFile()["level"] = level.ordinal
selfBots.filter { it.isMining() }.forEach { it.sleep() } ShootingStarPlugin.getStoreFile()["location"] = location
SceneryBuilder.remove(starObject) ShootingStarPlugin.getStoreFile()["isDiscovered"] = false
isSpawned = false
starSprite.location = starObject.location ticks = 0
starSprite.init() firstStar = false
spriteSpawned = true
ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned
} }
fun clearSprite() { fun clearSprite() {
starSprite.clear() starSprite.clear()
spriteSpawned = false spriteSpawned = false
ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned
} }
/** /**
@ -171,7 +161,6 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
*/ */
fun decDust() { fun decDust() {
if(--dustLeft <= 0) degrade() if(--dustLeft <= 0) degrade()
ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft
} }
/** /**

View file

@ -51,7 +51,6 @@ 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.") player.sendMessage("You have ${player.skills.experienceMultiplier * player.getAttribute("shooting-star:bonus-xp", 0).toDouble()} bonus xp towards mining stardust.")
ShootingStarPlugin.submitScoreBoard(player) ShootingStarPlugin.submitScoreBoard(player)
star.isDiscovered = true star.isDiscovered = true
ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered
return player.skills.getLevel(Skills.MINING) >= star.miningLevel return player.skills.getLevel(Skills.MINING) >= star.miningLevel
} }

View file

@ -12,11 +12,11 @@ import core.ServerStore.Companion.getBoolean
import core.game.dialogue.DialogueFile import core.game.dialogue.DialogueFile
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.interaction.IntType import core.game.interaction.IntType
import core.tools.SystemLogger
import core.game.system.command.Privilege import core.game.system.command.Privilege
import core.game.world.GameWorld import core.game.world.GameWorld
import core.tools.Log import core.tools.Log
import core.tools.secondsToTicks import core.tools.secondsToTicks
import content.data.Quests
class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener { class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener {
override fun login(player: Player) { override fun login(player: Player) {
@ -27,30 +27,14 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
override fun tick() { override fun tick() {
++star.ticks ++star.ticks
// Check if the current star sprite should expire
val maxDelay = tickDelay + (tickDelay / 3) val maxDelay = tickDelay + (tickDelay / 3)
if(star.ticks > maxDelay && star.spriteSpawned){ if(star.ticks > maxDelay && star.spriteSpawned){
star.clearSprite() star.clearSprite()
} }
if (star.firstStar && !star.isSpawned && !star.spriteSpawned) { if ((star.ticks >= tickDelay && !star.spriteSpawned) || (!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() star.fire()
} }
getStoreFile()["ticks"] = star.ticks
} }
override fun defineListeners() { override fun defineListeners() {
@ -96,17 +80,17 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
override fun handle(componentID: Int, buttonID: Int) { override fun handle(componentID: Int, buttonID: Int) {
fun teleportToStar(player: Player) { fun teleportToStar(player: Player) {
val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) { val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) {
"canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")} "canifis bank" -> {p -> requireQuest(p, "Priest in Peril", "to access this.") }
//"burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} //disabled: crash //"burgh de rott bank" -> {p -> hasRequirement(p, "In Aid of the Myreque") } //disabled: crash
"crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)} "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40) }
"lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)} "lletya bank" -> {p -> hasRequirement(p, "Mourning's End Part I") }
"jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} "jatizso mine" -> {p -> hasRequirement(p, "The Fremennik Isles") }
"south crandor mining site" -> {p -> hasRequirement(p, Quests.DRAGON_SLAYER)} "south crandor mining site" -> {p -> hasRequirement(p, "Dragon Slayer") }
"shilo village mining site" -> {p -> hasRequirement(p, Quests.SHILO_VILLAGE)} "shilo village mining site" -> {p -> hasRequirement(p, "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 "mos le'harmless bank" -> {p -> hasRequirement(p, "Cabin Fever") } //needs to be updated to check for completion when the quest releases; https://runescape.wiki/w/Mos_Le%27Harmless?oldid=913025
"lunar isle mine" -> {p -> hasRequirement(p, Quests.LUNAR_DIPLOMACY)} "lunar isle mine" -> {p -> hasRequirement(p, "Lunar Diplomacy") }
"miscellania coal mine" -> {p -> requireQuest(p, Quests.THE_FREMENNIK_TRIALS, "to access this.")} "miscellania coal mine" -> {p -> requireQuest(p, "The Fremennik Trials", "to access this.") }
//"neitiznot runite mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} //disabled: currently not reachable //"neitiznot runite mine" -> {p -> hasRequirement(p, "The Fremennik Isles") } //disabled: currently not reachable
else -> {_ -> true} else -> {_ -> true}
} }
if (!condition.invoke(player)) { if (!condition.invoke(player)) {
@ -138,7 +122,6 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
} }
define("submit", Privilege.ADMIN) { _, _ -> define("submit", Privilege.ADMIN) { _, _ ->
star.rebuildVars()
star.fire() star.fire()
} }

View file

@ -192,7 +192,7 @@ public abstract class ClueScrollPlugin extends MapZone implements Plugin<Object>
int hasAmt = 0; int hasAmt = 0;
for (int i = 0; i < equipment.length; i++) { for (int i = 0; i < equipment.length; i++) {
for (int k = 0; k < equipment[i].length; k++) { for (int k = 0; k < equipment[i].length; k++) {
if (player.getEquipment().contains(equipment[i][k], 1) || player.costumeRoomBank.contains(equipment[i][k], 1)) { if (player.getEquipment().contains(equipment[i][k], 1)) {
hasAmt++; hasAmt++;
break; break;
} }

View file

@ -1,28 +0,0 @@
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")
}

View file

@ -3,15 +3,9 @@ package content.global.ame
import content.global.ame.events.MysteriousOldManNPC import content.global.ame.events.MysteriousOldManNPC
import core.api.playGlobalAudio import core.api.playGlobalAudio
import core.api.poofClear import core.api.poofClear
import core.api.sendMessage
import core.api.utils.WeightBasedTable
import core.game.interaction.MovementPulse 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.impl.PulseType
import core.game.node.entity.npc.NPC 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.entity.player.Player
import core.game.node.item.Item import core.game.node.item.Item
import core.game.world.map.Location import core.game.world.map.Location
@ -19,11 +13,10 @@ import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Graphics import core.game.world.update.flag.context.Graphics
import core.integrations.discord.Discord import core.integrations.discord.Discord
import core.api.utils.WeightBasedTable
import core.tools.secondsToTicks import core.tools.secondsToTicks
import core.tools.ticksToCycles import core.tools.ticksToCycles
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
import kotlin.math.ceil
import kotlin.math.min
import kotlin.random.Random import kotlin.random.Random
import kotlin.reflect.full.createInstance import kotlin.reflect.full.createInstance
@ -73,6 +66,7 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
if (!player.getAttribute("random:pause", false)) { if (!player.getAttribute("random:pause", false)) {
ticksLeft-- ticksLeft--
} }
if (!pulseManager.hasPulseRunning() && !finalized) { if (!pulseManager.hasPulseRunning() && !finalized) {
follow() follow()
} }
@ -93,11 +87,6 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
location = spawnLocation location = spawnLocation
player.setAttribute("re-npc", this) player.setAttribute("re-npc", this)
super.init() super.init()
super.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() {
override fun canSelectTarget(entity: Entity, target: Entity): Boolean {
return target == player
}
})
} }
open fun onTimeUp() { open fun onTimeUp() {
@ -129,19 +118,4 @@ abstract class RandomEventNPC(id: Int) : NPC(id) {
} }
abstract fun talkTo(npc: NPC) 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]
}
} }

View file

@ -3,18 +3,15 @@ package content.global.ame
import org.rs09.consts.Items import org.rs09.consts.Items
import content.global.ame.events.MysteriousOldManNPC import content.global.ame.events.MysteriousOldManNPC
import content.global.ame.events.certer.CerterNPC import content.global.ame.events.certer.CerterNPC
import content.global.ame.events.drilldemon.SergeantDamienNPC import content.global.ame.events.drilldemon.SeargentDamienNPC
import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC
import content.global.ame.events.evilbob.EvilBobNPC import content.global.ame.events.evilbob.EvilBobNPC
import content.global.ame.events.evilchicken.EvilChickenNPC import content.global.ame.events.evilchicken.EvilChickenNPC
import content.global.ame.events.freakyforester.FreakyForesterNPC 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.genie.GenieNPC
import content.global.ame.events.pillory.PilloryNPC
import content.global.ame.events.rickturpentine.RickTurpentineNPC import content.global.ame.events.rickturpentine.RickTurpentineNPC
import content.global.ame.events.rivertroll.RiverTrollRENPC import content.global.ame.events.rivertroll.RiverTrollRENPC
import content.global.ame.events.rockgolem.RockGolemRENPC 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.sandwichlady.SandwichLadyRENPC
import content.global.ame.events.shade.ShadeRENPC import content.global.ame.events.shade.ShadeRENPC
import content.global.ame.events.strangeplant.StrangePlantNPC import content.global.ame.events.strangeplant.StrangePlantNPC
@ -46,8 +43,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,0.1), WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,0.1),
WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1) WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1)
)), )),
MAZE(npc = MazeNPC()), DRILL_DEMON(npc = SeargentDamienNPC()),
DRILL_DEMON(npc = SergeantDamienNPC()),
EVIL_CHICKEN(npc = EvilChickenNPC()), EVIL_CHICKEN(npc = EvilChickenNPC()),
STRANGE_PLANT(npc = StrangePlantNPC()), STRANGE_PLANT(npc = StrangePlantNPC()),
SWARM(npc = SwarmNPC()), SWARM(npc = SwarmNPC()),
@ -56,9 +52,7 @@ enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = n
RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot), RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot),
SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"), SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"),
FREAKY_FORESTER(npc = FreakyForesterNPC(), skillIds = intArrayOf(Skills.WOODCUTTING)), FREAKY_FORESTER(npc = FreakyForesterNPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
PILLORY(npc = PilloryNPC(), skillIds = intArrayOf(Skills.THIEVING)),
TREE_SPIRIT(npc = TreeSpiritRENPC(), skillIds = intArrayOf(Skills.WOODCUTTING)), TREE_SPIRIT(npc = TreeSpiritRENPC(), skillIds = intArrayOf(Skills.WOODCUTTING)),
QUIZ_MASTER(npc = QuizMasterNPC()),
RIVER_TROLL(RiverTrollRENPC(), skillIds = intArrayOf(Skills.FISHING)), RIVER_TROLL(RiverTrollRENPC(), skillIds = intArrayOf(Skills.FISHING)),
ROCK_GOLEM(RockGolemRENPC(), skillIds = intArrayOf(Skills.MINING)), ROCK_GOLEM(RockGolemRENPC(), skillIds = intArrayOf(Skills.MINING)),
SHADE(ShadeRENPC(), skillIds = intArrayOf(Skills.PRAYER)), SHADE(ShadeRENPC(), skillIds = intArrayOf(Skills.PRAYER)),

View file

@ -1,19 +0,0 @@
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
}
}

View file

@ -1,7 +1,7 @@
package content.global.ame.events package content.global.ame.events
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import content.global.ame.events.surpriseexam.SurpriseExamUtils import content.global.ame.events.supriseexam.SurpriseExamUtils
import core.game.dialogue.DialogueFile import core.game.dialogue.DialogueFile
import core.game.system.timer.impl.AntiMacro import core.game.system.timer.impl.AntiMacro

View file

@ -79,7 +79,7 @@ class DrillDemonListeners : InteractionListener, MapArea {
} }
override fun getRestrictions(): Array<ZoneRestriction> { override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS)
} }
override fun areaEnter(entity: Entity) { override fun areaEnter(entity: Entity) {

View file

@ -1,11 +1,8 @@
package content.global.ame.events.drilldemon package content.global.ame.events.drilldemon
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.* import core.api.*
import core.game.interaction.QueueStrength import core.game.interaction.QueueStrength
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
@ -14,6 +11,7 @@ import org.rs09.consts.NPCs
object DrillDemonUtils { object DrillDemonUtils {
val DD_KEY_TASK = "/save:drilldemon:task" val DD_KEY_TASK = "/save:drilldemon:task"
val DD_KEY_RETURN_LOC = "/save:original-loc"
val DD_SIGN_VARP = 531 val DD_SIGN_VARP = 531
val DD_SIGN_JOG = 0 val DD_SIGN_JOG = 0
val DD_SIGN_SITUP = 1 val DD_SIGN_SITUP = 1
@ -25,7 +23,10 @@ object DrillDemonUtils {
val DD_NPC = NPCs.SERGEANT_DAMIEN_2790 val DD_NPC = NPCs.SERGEANT_DAMIEN_2790
fun teleport(player: Player) { fun teleport(player: Player) {
kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT) if (getAttribute(player, DD_KEY_RETURN_LOC, null) == null) {
setAttribute(player, DD_KEY_RETURN_LOC, player.location)
}
teleport(player, Location.create(3163, 4819, 0))
player.interfaceManager.closeDefaultTabs() player.interfaceManager.closeDefaultTabs()
setComponentVisibility(player, 548, 69, true) setComponentVisibility(player, 548, 69, true)
setComponentVisibility(player, 746, 12, true) setComponentVisibility(player, 746, 12, true)
@ -64,8 +65,13 @@ object DrillDemonUtils {
} }
fun cleanup(player: Player) { fun cleanup(player: Player) {
returnPlayer(player) player.locks.unlockTeleport()
removeAttributes(player, DD_KEY_TASK, DD_CORRECT_OFFSET, DD_CORRECT_COUNTER) 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)
player.interfaceManager.openDefaultTabs() player.interfaceManager.openDefaultTabs()
setComponentVisibility(player, 548, 69, false) setComponentVisibility(player, 548, 69, false)
setComponentVisibility(player, 746, 12, false) setComponentVisibility(player, 746, 12, false)

View file

@ -10,11 +10,11 @@ import core.game.interaction.QueueStrength
import core.game.system.timer.impl.AntiMacro import core.game.system.timer.impl.AntiMacro
import core.tools.secondsToTicks import core.tools.secondsToTicks
class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) { class SeargentDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) {
override fun init() { override fun init() {
super.init() super.init()
sendChat(player.username+ "! Drop and give me 20!") sendChat(player.username.capitalize() + "! Drop and give me 20!")
queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> queueScript(player, 4, QueueStrength.SOFT) { stage: Int ->
when (stage) { when (stage) {
0 -> { 0 -> {

View file

@ -1,6 +1,5 @@
package content.global.ame.events.evilbob package content.global.ame.events.evilbob
import content.global.ame.returnPlayer
import core.ServerConstants import core.ServerConstants
import core.api.* import core.api.*
import core.game.dialogue.FacialExpression import core.game.dialogue.FacialExpression
@ -9,6 +8,8 @@ import core.game.interaction.InteractionListener
import core.game.interaction.QueueStrength import core.game.interaction.QueueStrength
import core.game.node.entity.Entity import core.game.node.entity.Entity
import core.game.node.entity.player.link.emote.Emotes 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.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction import core.game.world.map.zone.ZoneRestriction
@ -120,7 +121,7 @@ class EvilBobListeners : InteractionListener, MapArea {
} }
3 -> { 3 -> {
sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.") sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.")
returnPlayer(player) teleport(player, getAttribute(player, EvilBobUtils.prevLocation, Location.create(3222, 3219, 0)))
EvilBobUtils.reward(player) EvilBobUtils.reward(player)
EvilBobUtils.cleanup(player) EvilBobUtils.cleanup(player)
resetAnimator(player) resetAnimator(player)
@ -138,7 +139,7 @@ class EvilBobListeners : InteractionListener, MapArea {
} }
override fun getRestrictions(): Array<ZoneRestriction> { override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS)
} }
override fun areaEnter(entity: Entity) { override fun areaEnter(entity: Entity) {

View file

@ -1,10 +1,7 @@
package content.global.ame.events.evilbob package content.global.ame.events.evilbob
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.* import core.api.*
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
@ -16,6 +13,7 @@ import org.rs09.consts.NPCs
import org.rs09.consts.Scenery import org.rs09.consts.Scenery
object EvilBobUtils { object EvilBobUtils {
const val prevLocation = "/save:original-loc"
const val eventComplete = "/save:evilbob:eventcomplete" const val eventComplete = "/save:evilbob:eventcomplete"
const val assignedFishingZone = "/save:evilbob:fishingzone" const val assignedFishingZone = "/save:evilbob:fishingzone"
const val attentive = "/save:evilbob:attentive" const val attentive = "/save:evilbob:attentive"
@ -54,11 +52,16 @@ object EvilBobUtils {
} }
fun teleport(player: Player) { fun teleport(player: Player) {
kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT) if (getAttribute(player, prevLocation, null) == null) {
setAttribute(player, prevLocation, player.location)
}
player.properties.teleportLocation = Location.create(3419, 4776, 0)
} }
fun cleanup(player: Player) { fun cleanup(player: Player) {
removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen) player.locks.unlockTeleport()
player.properties.teleportLocation = getAttribute(player, prevLocation, null)
removeAttributes(player, assignedFishingZone, eventComplete, prevLocation, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen)
removeAll(player, Items.FISHLIKE_THING_6202) removeAll(player, Items.FISHLIKE_THING_6202)
removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK) removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK)
removeAll(player, Items.FISHLIKE_THING_6206) removeAll(player, Items.FISHLIKE_THING_6206)

View file

@ -9,8 +9,9 @@ import core.tools.RandomFunction
import org.rs09.consts.Items import org.rs09.consts.Items
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import java.lang.Integer.max
val ids = (2463..2468).toList() val ids = 2463..2468
class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) { class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) {
val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!") val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!")
@ -18,7 +19,8 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN
override fun init() { override fun init() {
super.init() super.init()
val id = idForCombatLevel(ids, player) val index = max(0, (player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id) this.transform(id)
this.attack(player) this.attack(player)
sendChat(phrases.random().replace("@name",player.username.capitalize())) sendChat(phrases.random().replace("@name",player.username.capitalize()))

View file

@ -57,7 +57,7 @@ class FreakListeners : InteractionListener, MapArea {
} }
override fun getRestrictions(): Array<ZoneRestriction> { override fun getRestrictions(): Array<ZoneRestriction> {
return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS)
} }
override fun areaEnter(entity: Entity) { override fun areaEnter(entity: Entity) {

View file

@ -1,18 +1,16 @@
package content.global.ame.events.freakyforester package content.global.ame.events.freakyforester
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.* import core.api.*
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import core.tools.RandomFunction import core.tools.RandomFunction
object FreakUtils{ object FreakUtils{
const val freakNpc = NPCs.FREAKY_FORESTER_2458 const val freakNpc = NPCs.FREAKY_FORESTER_2458
const val freakPreviousLoc = "/save:original-loc"
const val freakTask = "/save:freakyf:task" const val freakTask = "/save:freakyf:task"
const val freakComplete = "/save:freakyf:complete" const val freakComplete = "/save:freakyf:complete"
const val pheasantKilled = "freakyf:killed" const val pheasantKilled = "freakyf:killed"
@ -29,12 +27,16 @@ object FreakUtils{
} }
fun teleport(player: Player) { fun teleport(player: Player) {
kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT) if (getAttribute(player, freakPreviousLoc,null) == null) {
setAttribute(player, freakPreviousLoc, player.location)
}
teleport(player, Location.create(2599, 4777 ,0))
} }
fun cleanup(player: Player) { fun cleanup(player: Player) {
returnPlayer(player) player.locks.unlockTeleport()
removeAttributes(player, freakTask, freakComplete, pheasantKilled) player.properties.teleportLocation = getAttribute(player,freakPreviousLoc,null)
removeAttributes(player, freakPreviousLoc, freakTask, freakComplete, pheasantKilled)
removeAll(player, Items.RAW_PHEASANT_6178) removeAll(player, Items.RAW_PHEASANT_6178)
removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK) removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK)
removeAll(player, Items.RAW_PHEASANT_6179) removeAll(player, Items.RAW_PHEASANT_6179)

View file

@ -1,277 +0,0 @@
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)
}
}
}

View file

@ -1,57 +0,0 @@
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.
}
}

View file

@ -1,219 +0,0 @@
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()
}
}
}

View file

@ -1,50 +0,0 @@
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)
}
}

View file

@ -1,37 +0,0 @@
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)
}
}
}

View file

@ -1,129 +0,0 @@
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()
}
}
}
}

View file

@ -1,65 +0,0 @@
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())
}
}

View file

@ -4,14 +4,17 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import java.lang.Integer.max
val ids = (391..396).toList()
val ids = 391..396
class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(391){ class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(391){
override fun talkTo(npc: NPC) {} override fun talkTo(npc: NPC) {}
override fun init() { override fun init() {
super.init() super.init()
val id = idForCombatLevel(ids, player) val index = max(0, (player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id) this.transform(id)
this.attack(player) this.attack(player)
sendChat("Fishies be mine, leave dem fishies!") sendChat("Fishies be mine, leave dem fishies!")

View file

@ -4,14 +4,17 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import kotlin.math.max
val ids = (413..418).toList()
val ids = 413..418
class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(413){ class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(413){
override fun talkTo(npc: NPC) {} override fun talkTo(npc: NPC) {}
override fun init() { override fun init() {
super.init() super.init()
val id = idForCombatLevel(ids, player) val index = max(0,(player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id) this.transform(id)
this.attack(player) this.attack(player)
sendChat("Raarrrgghh! Flee human!") sendChat("Raarrrgghh! Flee human!")

View file

@ -4,13 +4,15 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import kotlin.math.*
class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){ class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){
val ids = (425..430).toList() val ids = (425..430).toList()
override fun talkTo(npc: NPC) {} override fun talkTo(npc: NPC) {}
override fun init() { override fun init() {
super.init() super.init()
val id = idForCombatLevel(ids, player) val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1))
val id = ids[index]
this.transform(id) this.transform(id)
this.attack(player) this.attack(player)
sendChat("Leave this place!") sendChat("Leave this place!")

View file

@ -32,8 +32,4 @@ class StrangePlantBehavior() : NPCBehavior(NPCs.STRANGE_PLANT_408) {
override fun onDeathStarted(self: NPC, killer: Entity) { override fun onDeathStarted(self: NPC, killer: Entity) {
AntiMacro.terminateEventNpc(killer.asPlayer()) AntiMacro.terminateEventNpc(killer.asPlayer())
} }
override fun getXpMultiplier(self: NPC, attacker: Entity): Double {
return super.getXpMultiplier(self, attacker) / 16.0
}
} }

View file

@ -1,4 +1,4 @@
package content.global.ame.events.surpriseexam package content.global.ame.events.supriseexam
import core.game.component.Component import core.game.component.Component
import core.game.dialogue.FacialExpression import core.game.dialogue.FacialExpression

View file

@ -1,4 +1,4 @@
package content.global.ame.events.surpriseexam package content.global.ame.events.supriseexam
import core.game.dialogue.DialogueFile import core.game.dialogue.DialogueFile
import core.tools.END_DIALOGUE import core.tools.END_DIALOGUE

View file

@ -1,4 +1,4 @@
package content.global.ame.events.surpriseexam package content.global.ame.events.supriseexam
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import org.rs09.consts.Components import org.rs09.consts.Components

View file

@ -1,4 +1,4 @@
package content.global.ame.events.surpriseexam package content.global.ame.events.supriseexam
import core.game.component.Component import core.game.component.Component
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
@ -9,22 +9,20 @@ import org.rs09.consts.NPCs
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.interaction.IntType import core.game.interaction.IntType
import content.global.handlers.iface.ExperienceInterface 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, MapArea { class SupriseExamListeners : InteractionListener {
val MORDAUT = NPCs.MR_MORDAUT_6117
val BOOK_OF_KNOWLEDGE = Items.BOOK_OF_KNOWLEDGE_11640
override fun defineListeners() { override fun defineListeners() {
on(NPCs.MR_MORDAUT_6117, IntType.NPC, "talk-to") { player, node -> on(MORDAUT, IntType.NPC, "talk-to"){ player, node ->
player.faceLocation(Location.create(1886, 5024, 0)) player.faceLocation(Location.create(1886, 5024, 0))
val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT, 0) == 3 val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3
player.dialogueInterpreter.open(MordautDialogue(examComplete), node.asNpc()) player.dialogueInterpreter.open(MordautDialogue(examComplete),node.asNpc())
return@on true 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) val correctDoor = player.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1)
if(correctDoor == -1){ if(correctDoor == -1){
@ -41,9 +39,9 @@ class SupriseExamListeners : InteractionListener, MapArea {
return@on true return@on true
} }
on(Items.BOOK_OF_KNOWLEDGE_11640, IntType.ITEM, "read") { player, _ -> on(BOOK_OF_KNOWLEDGE, IntType.ITEM, "read"){ player, _ ->
player.setAttribute("caller") { skill: Int, p: Player -> player.setAttribute("caller"){skill: Int,p: Player ->
if (removeItem(p, Items.BOOK_OF_KNOWLEDGE_11640)) { if(p.inventory.remove(Item(BOOK_OF_KNOWLEDGE))) {
val level = p.skills.getStaticLevel(skill) val level = p.skills.getStaticLevel(skill)
val experience = level * 15.0 val experience = level * 15.0
p.skills.addExperience(skill, experience) p.skills.addExperience(skill, experience)
@ -56,16 +54,8 @@ class SupriseExamListeners : InteractionListener, MapArea {
} }
override fun defineDestinationOverrides() { override fun defineDestinationOverrides() {
setDest(IntType.NPC, NPCs.MR_MORDAUT_6117) { _, _ -> setDest(IntType.NPC,MORDAUT){ _, _ ->
return@setDest Location.create(1886, 5025, 0) 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)
}
} }

View file

@ -1,18 +1,21 @@
package content.global.ame.events.surpriseexam package content.global.ame.events.supriseexam
import content.global.ame.kidnapPlayer
import content.global.ame.returnPlayer
import core.api.* import core.api.*
import core.game.node.entity.impl.PulseType import core.game.node.entity.impl.PulseType
import core.game.node.entity.player.Player 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.system.task.Pulse
import core.game.world.map.Location import core.game.world.map.Location
import org.rs09.consts.Components import org.rs09.consts.Components
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.node.entity.player.link.TeleportManager import core.ServerConstants
object SurpriseExamUtils { object SurpriseExamUtils {
val SE_KEY_LOC = "/save:original-loc"
val SE_KEY_INDEX = "supexam:index" val SE_KEY_INDEX = "supexam:index"
val SE_LOGOUT_KEY = "suprise_exam"
val SE_DOOR_KEY = "supexam:door" val SE_DOOR_KEY = "supexam:door"
val INTER_PATTERN_CHILDS = intArrayOf(6,7,8) val INTER_PATTERN_CHILDS = intArrayOf(6,7,8)
val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13) val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13)
@ -26,16 +29,28 @@ object SurpriseExamUtils {
intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311) intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311)
) )
fun teleport(player: Player) { fun teleport(player: Player){
kidnapPlayer(player, Location.create(1886, 5025, 0), TeleportManager.TeleportType.INSTANT) if (getAttribute(player, SE_KEY_LOC, null) == null) {
player.setAttribute(SE_KEY_LOC, player.location)
}
registerLogoutListener(player, SE_LOGOUT_KEY){p ->
p.location = getAttribute(p, SE_KEY_LOC, ServerConstants.HOME_LOCATION)
}
player.properties.teleportLocation = Location.create(1886, 5025, 0)
} }
fun cleanup(player: Player){ fun cleanup(player: Player){
returnPlayer(player) player.properties.teleportLocation = player.getAttribute(SE_KEY_LOC,null)
removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT) clearLogoutListener(player, SE_LOGOUT_KEY)
player.removeAttribute(SE_KEY_LOC)
player.removeAttribute(SE_KEY_INDEX)
player.removeAttribute(SE_KEY_CORRECT)
player.pulseManager.run(object : Pulse(2){ player.pulseManager.run(object : Pulse(2){
override fun pulse(): Boolean { override fun pulse(): Boolean {
addItemOrDrop(player, Items.BOOK_OF_KNOWLEDGE_11640) val reward = Item(Items.BOOK_OF_KNOWLEDGE_11640)
if(!player.inventory.add(reward)){
GroundItemManager.create(reward,player)
}
return true return true
} }
}, PulseType.CUSTOM_1) }, PulseType.CUSTOM_1)

View file

@ -4,14 +4,17 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import kotlin.math.max
val ids = (438..443).toList()
val ids = 438..443
class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(438){ class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(438){
override fun talkTo(npc: NPC) {} override fun talkTo(npc: NPC) {}
override fun init() { override fun init() {
super.init() super.init()
val id = idForCombatLevel(ids, player) val index = max(0,(player.properties.combatLevel / 20) - 1)
val id = ids.toList()[index]
this.transform(id) this.transform(id)
this.attack(player) this.attack(player)
sendChat("Leave these woods and never return!") sendChat("Leave these woods and never return!")

View file

@ -4,13 +4,15 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable import core.api.utils.WeightBasedTable
import kotlin.math.*
class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){ class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){
val ids = (419..424).toList() val ids = (419..424).toList()
override fun talkTo(npc: NPC) {} override fun talkTo(npc: NPC) {}
override fun init() { override fun init() {
super.init() super.init()
val id = idForCombatLevel(ids, player) val index = max(0, min(ids.size, (player.properties.combatLevel / 20) - 1))
val id = ids[index]
this.transform(id) this.transform(id)
this.attack(player) this.attack(player)
sendChat("Brainsssss!") sendChat("Brainsssss!")

View file

@ -12,16 +12,15 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager import core.game.world.map.RegionManager
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.* import core.game.world.update.flag.*
import core.tools.RandomFunction
import org.json.simple.JSONArray import org.json.simple.JSONArray
import org.json.simple.JSONObject import org.json.simple.JSONObject
import core.ServerConstants import core.ServerConstants
import core.api.log
import core.game.bots.AIRepository import core.game.bots.AIRepository
import core.game.bots.CombatBotAssembler import core.game.bots.CombatBotAssembler
import core.game.bots.Script import core.game.bots.Script
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.interaction.InteractionListeners import core.game.interaction.InteractionListeners
import core.tools.Log
import java.io.File import java.io.File
import java.io.FileReader import java.io.FileReader
import java.time.LocalDateTime import java.time.LocalDateTime
@ -41,27 +40,21 @@ import kotlin.random.Random
* @author Ceikry * @author Ceikry
*/ */
// Adventure Bots v1.1.0 : Expansion Edition (Previously v4.0.0) //Adventure Bots v4.0.0 -Expansion Edition-
// Super Grand Exchange Update
class Adventurer(val style: CombatStyle): Script() { class Adventurer(val style: CombatStyle): Script() {
var city: Location = lumbridge var city: Location = lumbridge
var poiloc: Location = karamja var ticks = 0
var geSocialLoc: Location = getRandomGESocialLocation() var freshspawn = true
var geClerkLoc: Location = getRandomGELocation() var sold = false
var geClerksloc: Location = neGEClerk private val geloc: Location = if (Random.nextBoolean()){
Location.create(3165, 3487, 0)
}else{
Location.create(3164, 3492, 0)
}
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 counter: Int = 0
val waitTotal: Int = 8 var random: Int = (5..30).random()
var returnToAdventure: Int = 0
var geWait: Int = 0
var geLongWait: Int = 0
val type = when(style){ val type = when(style){
CombatStyle.MELEE -> CombatBotAssembler.Type.MELEE CombatStyle.MELEE -> CombatBotAssembler.Type.MELEE
@ -81,81 +74,23 @@ class Adventurer(val style: CombatStyle): Script() {
} }
override fun toString(): String { override fun toString(): String {
return "${bot.username} is an Adventurer bot " + return "${bot.name} is an Adventurer bot at ${bot.location}! State: $state - City: $city"
"at ${bot.location}! " +
"State: $state - " +
"City: $city - " +
"Ticks: $ticks - " +
"Freshspawn: $freshspawn - " +
"Sold: $sold - " +
"Counter: $counter"
} }
var state = State.START var state = State.START
private fun getRandomCity(): Location{ fun getRandomCity(): Location{
return cities.random() return cities.random()
} }
private fun getRandomPoi(): Location{ fun getRandomPoi(): Location{
return pois.random() 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. //TODO: Optimise and adjust how bots handle picking up ground items further.
fun immerse() { fun immerse() {
if (counter++ >= Random.nextInt(150,300)) { state = State.TELEPORTING } if (counter++ == 180) {state = State.TELEPORTING
}
val items = AIRepository.groundItems[bot] val items = AIRepository.groundItems[bot]
if (Random.nextBoolean()) { if (Random.nextBoolean()) {
if (items.isNullOrEmpty()) { if (items.isNullOrEmpty()) {
@ -163,13 +98,33 @@ class Adventurer(val style: CombatStyle): Script() {
state = State.LOOT_DELAY state = State.LOOT_DELAY
} }
if (bot.inventory.isFull) { if (bot.inventory.isFull) {
checkNearBank() 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))
}
}
} }
} else { } else {
if (bot.inventory.isFull){ if (bot.inventory.isFull){
checkNearBank() 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))
}
}
} else { } else {
val resources = listOf(
"Rocks","Tree","Oak","Willow",
"Maple tree","Yew","Magic tree",
"Teak","Mahogany")
val resource = scriptAPI.getNearestNodeFromList(resources,true) val resource = scriptAPI.getNearestNodeFromList(resources,true)
if(resource != null){ if(resource != null){
if(resource.name.contains("ocks")) InteractionListeners.run(resource.id, if(resource.name.contains("ocks")) InteractionListeners.run(resource.id,
@ -182,17 +137,18 @@ class Adventurer(val style: CombatStyle): Script() {
} }
fun refresh() { fun refresh() {
// log(this::class.java, Log.WARN, "${bot.username} refreshed from $state at $city with $ticks and $counter counter.")
scriptAPI.teleport(lumbridge) scriptAPI.teleport(lumbridge)
freshspawn = true
state = State.START state = State.START
} }
var poi = false
var poiloc = karamja
//Adventure Bots Actual Code STARTS HERE!!! //Adventure Bots Actual Code STARTS HERE!!!
// 100 ticks = 60 seconds
override fun tick() { override fun tick() {
ticks++ ticks++
// Hard refresh if (ticks++ >= 800) {
if (ticks >= 1000) {
ticks = 0 ticks = 0
refresh() refresh()
return return
@ -230,42 +186,49 @@ class Adventurer(val style: CombatStyle): Script() {
} }
return return
} else { } else {
state = State.ADVENTURE state = State.EXPLORE
} }
} }
State.START -> { State.START -> {
if (freshspawn) { if (freshspawn) {
freshspawn = false freshspawn = false
scriptAPI.randomWalkTo(lumbridge, randomNumberFromOne(25)) scriptAPI.randomWalkTo(lumbridge, 20)
} else { } else {
city = getRandomCity()
state = State.TELEPORTING state = State.TELEPORTING
} }
} }
State.TELEPORTING -> { State.TELEPORTING -> {
if (freshspawn){ freshspawn = false }
teleportToRandomCity()
poi = false
sold = false
ticks = 0 ticks = 0
counter = 0 counter = 0
state = State.ADVENTURE if (bot.location != city) {
return poi = false
scriptAPI.teleport(city)
} else {
poi = false
state = State.EXPLORE
}
} }
State.ADVENTURE -> { State.EXPLORE -> {
checkCounter(800) if (counter++ == 350) {
if (randomNumberFromOne(chance) <= 10) { state = State.TELEPORTING
if (otherPlayersNearby()) { }
val chance = if (city == ge || city == ge2) 5000 else 2500
if (RandomFunction.random(chance) <= 10) {
val nearbyPlayers = RegionManager.getLocalPlayers(bot)
if (nearbyPlayers.isNotEmpty()) {
ticks = 0 ticks = 0
dialogue() dialogue()
} }
} }
if (!poi && randomNumberFromOne(1000) <= 75) { if (RandomFunction.random(1000) <= 150 && !poi) {
val roamDistance = if (!cityLocationsGE.contains(city)) 225 else randomNumberFromOne(5) val roamDistance = if (city != ge && city != ge2) 225 else 7
if (cityLocationsGE.contains(city) && randomNumberFromOne(100) < 90) { if ((city == ge || city == ge2) && RandomFunction.random(100) < 90) {
if (!bot.bank.isEmpty) { if (!bot.bank.isEmpty) {
state = State.FIND_GE state = State.FIND_GE
} }
@ -275,46 +238,33 @@ class Adventurer(val style: CombatStyle): Script() {
return return
} }
if (poi && randomNumberFromOne(1000) <= 100){ if (RandomFunction.random(1000) <= 50 && poi){
immerse()
return
}
if (poi && randomNumberFromOne(1000) <= 25){
dialogue()
}
if (poi && randomNumberFromOne(1000) <= 50){
val roamDistancePoi = when(poiloc){ val roamDistancePoi = when(poiloc){
gemrocks, chaosnpc, chaosnpc2 -> 1 teakfarm, crawlinghands -> 5
magics, coalTrucks -> 7
miningguild, teakfarm, crawlinghands -> 5
varLumberYard -> 20
keldagrimout, teak1 -> 30
eaglespeek, isafdar -> 40
treegnome -> 50 treegnome -> 50
isafdar -> 40
eaglespeek -> 40
keldagrimout -> 30
teak1 -> 30
miningguild -> 5
magics, coal -> 7
gemrocks, chaosnpc, chaosnpc2 -> 1
else -> 60 else -> 60
} }
scriptAPI.randomWalkTo(poiloc,roamDistancePoi) scriptAPI.randomWalkTo(poiloc,roamDistancePoi)
return return
} }
if (randomNumberFromOne(1000) <= 75) { if (RandomFunction.random(1000) <= 75) {
if (!cityLocationsGE.contains(city)) { if (city != ge && city != ge2) {
ticks = 0
immerse() immerse()
return return
} else if (randomNumberFromOne(chance) <= 55 && otherPlayersNearby()) { } else {
ticks = 0 return
dialogue()
} }
} }
if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 50) { if (RandomFunction.random(20000) <= 60 && !poi) {
state = State.IDLE_GE
}
if (!poi && randomNumberFromOne(1000) <= 5) {
poiloc = getRandomPoi() poiloc = getRandomPoi()
city = teak1 city = teak1
poi = true poi = true
@ -322,24 +272,26 @@ class Adventurer(val style: CombatStyle): Script() {
return return
} }
if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 100) { if ((city == ge || city == ge2) && RandomFunction.random(1000) >= 999) {
state = State.TELEPORTING ticks = 0
return
}
if (cityLocationsGE.contains(city)) {
return
}
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() city = getRandomCity()
if (randomNumberFromOne(100) % 2 == 0) { state = State.TELEPORTING
}
if (city == ge || city == ge2) {
return
}
if (city == teak1 && counter++ >= 240){
city = getRandomCity()
state = State.TELEPORTING
}
if (counter++ >= 240 && RandomFunction.random(100) >= 10) {
city = getRandomCity()
if (RandomFunction.random(100) % 2 == 0) {
counter = 0
ticks = 0
state = State.TELEPORTING state = State.TELEPORTING
} else { } else {
if (citygroupA.contains(city)) { if (citygroupA.contains(city)) {
@ -357,122 +309,122 @@ class Adventurer(val style: CombatStyle): Script() {
return return
} }
State.IDLE_GE -> { State.GE -> {
returnToAdventure = Random.nextInt(350, 750) var ge = false
if (counter++ >= returnToAdventure){ if (counter++ == 180) {
if (randomNumberFromOne(100) <= 25){ state = State.TELEPORTING
ticks = 0
counter = 0
poiloc = getRandomPoi()
city = teak1
poi = true
scriptAPI.teleport(poiloc)
state = State.ADVENTURE
return
} else {
counter = 0
ticks = 0
state = State.TELEPORTING
return
}
} }
if (cityLocationsGE.contains(city)){ if (!sold) {
if (randomNumberFromOne(1000) <= 5) { if (counter++ >= 15) {
sold = true
ge = true
counter = 0
ticks = 0 ticks = 0
geSocialLoc = scriptAPI.randomizeLocationInRanges(getRandomGESocialLocation(),-1,1,-1,1,0) scriptAPI.sellAllOnGeAdv()
} 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 return
} }
} else if (ge && sold) {
ge = false
city = getRandomCity()
state = State.TELEPORTING
} }
return return
} }
State.FIND_GE -> { State.FIND_GE -> {
if (counter++ == 180) {
state = State.TELEPORTING
}
sold = false sold = false
val ge: Scenery? = scriptAPI.getNearestNode("Desk", true) as Scenery? val ge: Scenery? = scriptAPI.getNearestNode("Desk", true) as Scenery?
if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE if (ge == null || bot.bank.isEmpty) state = State.EXPLORE
class GEPulse : MovementPulse(bot, ge, DestinationFlag.OBJECT) { class GEPulse : MovementPulse(bot, ge, DestinationFlag.OBJECT) {
override fun pulse(): Boolean { override fun pulse(): Boolean {
bot.faceLocation(ge?.location) bot.faceLocation(ge?.location)
return true.also { state = State.GE } state = State.GE
return true
} }
} }
if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE
if (ge != null && !bot.bank.isEmpty) { if (ge != null && !bot.bank.isEmpty) {
if (randomNumberFromOne(1000) <= 25 && otherPlayersNearby()){ counter = 0
dialogue() scriptAPI.randomWalkTo(geloc, 3)
scriptAPI.randomWalkTo(geSocialLoc, randomNumberFromOne(5)) GameWorld.Pulser.submit(GEPulse())
} 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 return
} }
State.FIND_BANK -> { State.FIND_BANK -> {
val bank: Scenery? = scriptAPI.getNearestNode("Bank booth", true) as Scenery? if (counter++ == 300) {
if (bank == null) { state = State.TELEPORTING } state = State.TELEPORTING
if (bank != null && randomNumberFromOne(100) <= 5) { }
scriptAPI.depositAtBank() val bank: Scenery? = scriptAPI.getNearestNode("Bank booth", true) as Scenery?
} else if (bank != null && randomNumberFromOne(100) <= 5){ if (badedge.insideBorder(bot) || bot.location == badedge2 || bot.location == badedge3 || bot.location == badedge4) {
scriptAPI.randomWalkTo(bank.location,3) 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())
} }
checkCounter(500)
return 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 -> { State.FIND_CITY -> {
if (counter++ >= 500 || cityLocationsGE.contains(city)){ if (counter++ >= 600 || (city == ge || city == ge2)) {
counter = 0
scriptAPI.teleport(getRandomCity().also { city = it }) scriptAPI.teleport(getRandomCity().also { city = it })
state = State.ADVENTURE state = State.EXPLORE
} }
if (bot.location.equals(city)) { if (bot.location.equals(city)) {
state = State.ADVENTURE state = State.EXPLORE
} else { } else {
scriptAPI.randomWalkTo(city, randomNumberFromOne(10)) scriptAPI.randomWalkTo(city, 5)
} }
checkCounter(600)
return 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() { fun dialogue() {
val localPlayer = RegionManager.getLocalPlayers(bot).random()
val until = 1225 - dateCode val until = 1225 - dateCode
val lineStd = dialogue.getLines("standard").rand() val lineStd = dialogue.getLines("standard").rand()
var lineAlt = "" var lineAlt = ""
@ -503,29 +455,20 @@ class Adventurer(val style: CombatStyle): Script() {
dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand() dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand()
} }
var localPlayers = RegionManager.getLocalPlayers(bot) val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd }
if (localPlayers.isNotEmpty()) { .replace("@name", localPlayer.username)
val localPlayer = localPlayers .replace("@timer", until.toString())
.filter { it.name != bot.name }
.randomOrNull() scriptAPI.sendChat(chat)
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{ enum class State{
START, START,
ADVENTURE, EXPLORE,
FIND_BANK, FIND_BANK,
IDLE_BANKS,
FIND_CITY, FIND_CITY,
IDLE_GE, IDLE_CITY,
GE, GE,
TELEPORTING, TELEPORTING,
LOOT, LOOT,
@ -546,94 +489,44 @@ class Adventurer(val style: CombatStyle): Script() {
} }
companion object { companion object {
// Start Cities 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)
val yanille: Location = Location.create(2615, 3104, 0) val yanille: Location = Location.create(2615, 3104, 0)
val ardougne: Location = Location.create(2662, 3304, 0) val ardougne: Location = Location.create(2662, 3304, 0)
val seers: Location = Location.create(2726, 3485, 0) val seers: Location = Location.create(2726, 3485, 0)
val edgeville: Location = Location.create(3088, 3486, 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 catherby: Location = Location.create(2809, 3435, 0)
val falador: Location = Location.create(2965, 3380, 0) val falador: Location = Location.create(2965, 3380, 0)
val varrock: Location = Location.create(3213, 3428, 0) val varrock: Location = Location.create(3213, 3428, 0)
val draynor: Location = Location.create(3080, 3250, 0) val draynor: Location = Location.create(3080, 3250, 0)
val rimmington: Location = Location.create(2977, 3239, 0) val rimmington: Location = Location.create(2977, 3239, 0)
val lumbridge: Location = Location.create(3222, 3219, 0) val lumbridge: Location = Location.create(3222, 3219, 0)
val karamja: Location = Location.create(2849, 3033, 0) val karamja = Location.create(2849, 3033, 0)
val alkharid: Location = Location.create(3297, 3219, 0) val alkharid = Location.create(3297, 3219, 0)
val feldiphills = Location.create(2535, 2919, 0)
// Start POI val isafdar = Location.create(2241, 3217, 0)
val feldiphills: Location = Location.create(2535, 2919, 0) val eaglespeek = Location.create(2333, 3579, 0)
val isafdar: Location = Location.create(2241, 3217, 0) val canafis = Location.create(3492, 3485, 0)
val eaglespeek: Location = Location.create(2333, 3579, 0) val treegnome = Location.create(2437, 3441, 0)
val canafis: Location = Location.create(3492, 3485, 0) val teak1 = Location.create(2334, 3048, 0)
val treegnome: Location = Location.create(2437, 3441, 0) val teakfarm = Location.create(2825, 3085, 0)
val teak1: Location = Location.create(2334, 3048, 0) val keldagrimout = Location.create(2724,3692,0)
val teakfarm: Location = Location.create(2825, 3085, 0) val miningguild = Location.create(3046,9740,0)
val keldagrimout: Location = Location.create(2724,3692, 0) val magics = Location.create(2285,3146,0)
val miningguild: Location = Location.create(3046,9740, 0) val coal = Location.create(2581,3481,0)
val magics: Location = Location.create(2285,3146, 0) val crawlinghands = Location.create(3422,3548,0)
val coalTrucks: Location = Location.create(2581,3481, 0) val gemrocks = Location.create(2825,2997,0)
val crawlinghands: Location = Location.create(3422,3548, 0) val chaosnpc = Location.create(2612,9484,0)
val gemrocks: Location = Location.create(2825,2997, 0) val chaosnpc2 = Location.create(2580,9501,0)
val chaosnpc: Location = Location.create(2612,9484, 0) val taverly = Location.create(2909, 3436, 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 citygroupA = listOf(falador, varrock, draynor, rimmington, lumbridge, edgeville)
var citygroupB = listOf(yanille, ardougne, seers, catherby) 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>( var bankMap = mapOf<Location, ZoneBorders>(
falador to ZoneBorders(2950, 3374, 2943, 3368), falador to ZoneBorders(2950, 3374, 2943, 3368),
varrock to ZoneBorders(3182, 3435, 3189, 3446), varrock to ZoneBorders(3182, 3435, 3189, 3446),
@ -645,10 +538,22 @@ class Adventurer(val style: CombatStyle): Script() {
catherby to ZoneBorders(2807, 3438, 2811, 3441) 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 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 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)) 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( val common_stuck_locations = mapOf(
// South of Tavlery dungeon // South of Tavlery dungeon
ZoneBorders(2878, 3386, 2884, 3395) to { it: Adventurer -> ZoneBorders(2878, 3386, 2884, 3395) to { it: Adventurer ->

View file

@ -7,6 +7,8 @@ import core.api.*
import core.game.bots.* import core.game.bots.*
import core.game.ge.GrandExchange import core.game.ge.GrandExchange
import core.game.interaction.DestinationFlag import core.game.interaction.DestinationFlag
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
import core.game.interaction.MovementPulse import core.game.interaction.MovementPulse
import core.game.node.Node import core.game.node.Node
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
@ -14,7 +16,6 @@ import core.game.node.item.Item
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items import org.rs09.consts.Items
import content.data.Quests
@PlayerCompatible @PlayerCompatible
@ScriptName("Falador Cannonball Smelter") @ScriptName("Falador Cannonball Smelter")
@ -272,6 +273,6 @@ class CannonballSmelter : Script() {
skills.put(Skills.HITPOINTS,99) skills.put(Skills.HITPOINTS,99)
skills.put(Skills.DEFENCE,99) skills.put(Skills.DEFENCE,99)
skills.put(Skills.SMITHING,35) skills.put(Skills.SMITHING,35)
quests.add(Quests.DWARF_CANNON) quests.add("Dwarf Cannon")
} }
} }

View file

@ -45,7 +45,18 @@ class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin
2 -> showTopics( 2 -> showTopics(
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to access my bank account, please.", 10), Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to access my bank account, please.", 10),
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to switch my default bank account.", 7), IfTopic(
core.game.dialogue.FacialExpression.FRIENDLY,
"I'd like to switch to my ${getBankAccountName(player, true)} bank account.",
13,
hasActivatedSecondaryBankAccount(player)
),
IfTopic(
core.game.dialogue.FacialExpression.FRIENDLY,
"I'd like to open a secondary bank account.",
20,
!hasActivatedSecondaryBankAccount(player)
),
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to check my PIN settings.", 11), Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to check my PIN settings.", 11),
Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to collect items.", 12), Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to collect items.", 12),
Topic(core.game.dialogue.FacialExpression.ASKING, "What is this place?", 3), Topic(core.game.dialogue.FacialExpression.ASKING, "What is this place?", 3),
@ -67,53 +78,6 @@ class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin
"Leave your valuables with us if you want to keep them safe." "Leave your valuables with us if you want to keep them safe."
).also { stage = END_DIALOGUE } ).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 -> { 10 -> {
openBankAccount(player) openBankAccount(player)
end() end()

View file

@ -22,7 +22,7 @@ public class ManDialoguePlugin extends DialoguePlugin {
/** /**
* The NPC ids that use this dialogue plugin. * The NPC ids that use this dialogue plugin.
*/ */
private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,}; 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,};
public ManDialoguePlugin() { public ManDialoguePlugin() {
} }

View file

@ -36,21 +36,17 @@ public final class ClanInterfacePlugin extends ComponentPlugin {
switch (component.getId()) { switch (component.getId()) {
case 589: case 589:
switch (button) { switch (button) {
case 9: case 9:
if (player.getInterfaceManager().getComponent(590) != null) { if (player.getInterfaceManager().getComponent(590) != null) {
player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'"); player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'");
return true;
}
ClanRepository.openSettings(player);
return true; return true;
case 14: }
if (player.getIronmanManager().checkRestriction()) { ClanRepository.openSettings(player);
return false; return true;
} case 14:
player.getDetails().getCommunication().toggleLootshare(player); player.getDetails().getCommunication().toggleLootshare(player);
return true; return true;
} }
break; break;
case 590: case 590:
final ClanRepository clan = ClanRepository.get(player.getName(), true); final ClanRepository clan = ClanRepository.get(player.getName(), true);

View file

@ -10,7 +10,6 @@ import core.plugin.Initializable
import core.plugin.Plugin import core.plugin.Plugin
import core.tools.Log import core.tools.Log
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
import content.data.Quests
/** /**
* Represents the experience interface. * Represents the experience interface.
@ -79,15 +78,15 @@ class ExperienceInterface() : ComponentPlugin() {
} }
private fun checkHerblore(player: Player): Boolean{ private fun checkHerblore(player: Player): Boolean{
return (player.questRepository.isComplete(Quests.DRUIDIC_RITUAL)) return (player.questRepository.isComplete("Druidic Ritual"))
} }
private fun checkSummoning(player: Player): Boolean{ private fun checkSummoning(player: Player): Boolean{
return player.questRepository.isComplete(Quests.WOLF_WHISTLE) return player.questRepository.isComplete("Wolf Whistle")
} }
private fun checkRunecrafting(player: Player): Boolean{ private fun checkRunecrafting(player: Player): Boolean{
return player.questRepository.isComplete(Quests.RUNE_MYSTERIES) return player.questRepository.isComplete("Rune Mysteries")
} }
companion object { companion object {

View file

@ -10,7 +10,7 @@ import core.game.world.GameWorld
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.RegionManager import core.game.world.map.RegionManager
import core.tools.RandomFunction import core.tools.RandomFunction
import content.data.Quests
/** /**
* Handles the fairy ring interface * Handles the fairy ring interface
@ -77,11 +77,9 @@ class FairyRingInterface : InterfaceListener {
private fun drawLog (player: Player) private fun drawLog (player: Player)
{ {
for (i in FairyRing.values().indices) { 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)) { if (!player.savedData.globalData.hasTravelLog(i)) {
continue continue
} }
*/
val ring = FairyRing.values()[i] val ring = FairyRing.values()[i]
if (ring.childId == -1) { if (ring.childId == -1) {
continue continue
@ -181,7 +179,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
AKS(Location.create(2571, 2956, 0), "Feldip Hills: Jungle Hunter area", 25), 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) { ALQ(Location.create(3597, 3495, 0), "Morytania: Haunted Woods east of Canifis", 27) {
override fun checkAccess(player: Player) : Boolean { override fun checkAccess(player: Player) : Boolean {
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") return requireQuest(player, "Priest in Peril", "to use this ring.")
} }
}, },
ALS(Location.create(2644, 3495, 0), "Kandarin: McGrubor's Wood", 29), ALS(Location.create(2644, 3495, 0), "Kandarin: McGrubor's Wood", 29),
@ -193,7 +191,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
BKQ(Location.create(3041, 4532, 0), "Other realms: Enchanted Valley", 39), BKQ(Location.create(3041, 4532, 0), "Other realms: Enchanted Valley", 39),
BKR(Location.create(3469, 3431, 0), "Morytania: Mort Myre, south of Canifis", 40) { BKR(Location.create(3469, 3431, 0), "Morytania: Mort Myre, south of Canifis", 40) {
override fun checkAccess(player: Player) : Boolean { override fun checkAccess(player: Player) : Boolean {
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") return requireQuest(player, "Priest in Peril", "to use this ring.")
} }
}, },
BLP(Location.create(2437, 5126, 0), "Dungeons: TzHaar area", 42), BLP(Location.create(2437, 5126, 0), "Dungeons: TzHaar area", 42),
@ -201,7 +199,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
BLR(Location.create(2740, 3351, 0), "Kandarin: Legends' Guild", 44), BLR(Location.create(2740, 3351, 0), "Kandarin: Legends' Guild", 44),
CIP(Location.create(2513, 3884, 0), "Islands: Miscellania", 46) { CIP(Location.create(2513, 3884, 0), "Islands: Miscellania", 46) {
override fun checkAccess(player: Player): Boolean { override fun checkAccess(player: Player): Boolean {
return requireQuest(player, Quests.THE_FREMENNIK_TRIALS, "to use this ring.") return requireQuest(player, "Fremennik Trials", "to use this ring.")
} }
}, },
CIQ(Location.create(2528, 3127, 0), "Kandarin: North-west of Yanille", 47), CIQ(Location.create(2528, 3127, 0), "Kandarin: North-west of Yanille", 47),
@ -210,7 +208,7 @@ enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int
CKR(Location.create(2801, 3003, 0), "Karamja: South of Tai Bwo Wannai Village", 56), CKR(Location.create(2801, 3003, 0), "Karamja: South of Tai Bwo Wannai Village", 56),
CKS(Location.create(3447, 3470, 0), "Morytania: Canifis", 57) { CKS(Location.create(3447, 3470, 0), "Morytania: Canifis", 57) {
override fun checkAccess(player: Player) : Boolean { override fun checkAccess(player: Player) : Boolean {
return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") return requireQuest(player, "Priest in Peril", "to use this ring.")
} }
}, },
CLP(Location.create(3082, 3206, 0), "Islands: South of Draynor Village", 58), CLP(Location.create(3082, 3206, 0), "Islands: South of Draynor Village", 58),

View file

@ -165,7 +165,6 @@ public final class JewelleryInterface extends ComponentPlugin {
amount = 5; amount = 5;
break; break;
case 124: case 124:
/* No need to calculate the maximum amount here, because the make() function will perform that step
if (data.name().contains("GOLD")) { if (data.name().contains("GOLD")) {
amount = player.getInventory().getAmount(new Item(GOLD_BAR)); amount = player.getInventory().getAmount(new Item(GOLD_BAR));
} else { } else {
@ -179,8 +178,6 @@ public final class JewelleryInterface extends ComponentPlugin {
amount = first; amount = first;
} }
} }
*/
amount = 99;
break; break;
case 199: case 199:
final JewelleryItem d = data; final JewelleryItem d = data;

View file

@ -14,9 +14,6 @@ import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.world.GameWorld; import core.game.world.GameWorld;
import core.plugin.Plugin; import core.plugin.Plugin;
import content.data.Quests;
import static core.api.ContentAPIKt.hasRequirement;
/** /**
* Represents the magic book interface handling of non-combat spells. * Represents the magic book interface handling of non-combat spells.
* @author 'Vexia * @author 'Vexia
@ -45,44 +42,9 @@ public final class MagicBookInterface extends ComponentPlugin {
? SpellBook.ANCIENT ? SpellBook.ANCIENT
: SpellBook.LUNAR; : 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); SpellListeners.run(button, SpellListener.NONE, SpellUtils.getBookFromInterface(component.getId()),player,null);
boolean result = MagicSpell.castSpell(player, spellBook, button, player); boolean result = MagicSpell.castSpell(player, spellBook, button, player);
return result; 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;
}
} }

View file

@ -9,7 +9,6 @@ import core.plugin.Initializable;
import core.plugin.Plugin; import core.plugin.Plugin;
import static core.api.ContentAPIKt.hasRequirement; import static core.api.ContentAPIKt.hasRequirement;
import content.data.Quests;
/** /**
* Represents the prayer interface. * Represents the prayer interface.
@ -28,7 +27,7 @@ public final class PrayerTabInterface extends ComponentPlugin {
public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) {
final PrayerType type = PrayerType.get(button); final PrayerType type = PrayerType.get(button);
if (type == PrayerType.CHIVALRY || type == PrayerType.PIETY) if (type == PrayerType.CHIVALRY || type == PrayerType.PIETY)
if (!hasRequirement(player, Quests.KINGS_RANSOM)) if (!hasRequirement(player, "King's Ransom"))
return true; return true;
if (type == null) { if (type == null) {
return true; return true;

View file

@ -10,13 +10,12 @@ import kotlin.math.*
import java.util.* import java.util.*
import org.rs09.consts.* import org.rs09.consts.*
import content.data.Quests
object QuestTabUtils { object QuestTabUtils {
@JvmStatic @JvmStatic
fun showRequirementsInterface(player: Player, button: Int) { fun showRequirementsInterface (player: Player, button: Int) {
val questName = getNameForButton(button) val questName = getNameForButton (button)
val questReq = QuestRequirements.values().filter { it.quest.questName == questName }.firstOrNull() ?: return val questReq = QuestRequirements.values().filter { it.questName.equals(questName, true) }.firstOrNull() ?: return
var (isMet, unmetReqs) = QuestReq(questReq).evaluate(player) var (isMet, unmetReqs) = QuestReq(questReq).evaluate(player)
var messageList = ArrayList<String>() var messageList = ArrayList<String>()
@ -28,7 +27,7 @@ object QuestTabUtils {
closeInterface(player) closeInterface(player)
for (req in unmetReqs) { for (req in unmetReqs) {
if (req is QuestReq) if (req is QuestReq)
questList.add(req.questReq.quest.questName) questList.add(req.questReq.questName)
else if (req is SkillReq) { else if (req is SkillReq) {
if (statMap[req.skillId] == null || (statMap[req.skillId] != null && statMap[req.skillId]!! < req.level)) if (statMap[req.skillId] == null || (statMap[req.skillId] != null && statMap[req.skillId]!! < req.level))
statMap[req.skillId] = req.level statMap[req.skillId] = req.level
@ -83,163 +82,163 @@ object QuestTabUtils {
openInterface(player, Components.QUESTJOURNAL_SCROLL_275) openInterface(player, Components.QUESTJOURNAL_SCROLL_275)
} }
private fun getNameForButton(button: Int) : String { fun getNameForButton (button: Int) : String {
val quest = when (button) { val name = when (button) {
10 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName 10 -> "Myths of the White Lands"
11 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName 11 -> "Myths of the White Lands"
12 -> "Free Quests" 12 -> "Free Quests"
13 -> Quests.BLACK_KNIGHTS_FORTRESS.questName 13 -> "Black Knights' Fortress"
14 -> Quests.COOKS_ASSISTANT.questName 14 -> "Cook's Assistant"
15 -> Quests.DEMON_SLAYER.questName 15 -> "Demon Slayer"
16 -> Quests.DORICS_QUEST.questName 16 -> "Doric's Quest"
17 -> Quests.DRAGON_SLAYER.questName 17 -> "Dragon Slayer"
18 -> Quests.ERNEST_THE_CHICKEN.questName 18 -> "Ernest the Chicken"
19 -> Quests.GOBLIN_DIPLOMACY.questName 19 -> "Goblin Diplomacy"
20 -> Quests.IMP_CATCHER.questName 20 -> "Imp Catcher"
21 -> Quests.THE_KNIGHTS_SWORD.questName 21 -> "The Knight's Sword"
22 -> Quests.PIRATES_TREASURE.questName 22 -> "Pirate's Treasure"
23 -> Quests.PRINCE_ALI_RESCUE.questName 23 -> "Prince Ali Rescue"
24 -> Quests.THE_RESTLESS_GHOST.questName 24 -> "The Restless Ghost"
25 -> Quests.ROMEO_JULIET.questName 25 -> "Romeo & Juliet"
26 -> Quests.RUNE_MYSTERIES.questName 26 -> "Rune Mysteries"
27 -> Quests.SHEEP_SHEARER.questName 27 -> "Sheep Shearer"
28 -> Quests.SHIELD_OF_ARRAV.questName 28 -> "Shield of Arrav"
29 -> Quests.VAMPIRE_SLAYER.questName 29 -> "Vampire Slayer"
30 -> Quests.WITCHS_POTION.questName 30 -> "Witch's Potion"
31 -> "Members' Quests" 31 -> "Members' Quests"
32 -> Quests.ANIMAL_MAGNETISM.questName 32 -> "Animal Magnetism"
33 -> Quests.BETWEEN_A_ROCK.questName 33 -> "Between a Rock..."
34 -> Quests.BIG_CHOMPY_BIRD_HUNTING.questName 34 -> "Big Chompy Bird Hunting"
35 -> Quests.BIOHAZARD.questName 35 -> "Biohazard"
36 -> Quests.CABIN_FEVER.questName 36 -> "Cabin Fever"
37 -> Quests.CLOCK_TOWER.questName 37 -> "Clock Tower"
38 -> Quests.CONTACT.questName 38 -> "Contact!"
39 -> Quests.ZOGRE_FLESH_EATERS.questName 39 -> "Zogre Flesh Eaters"
40 -> Quests.CREATURE_OF_FENKENSTRAIN.questName 40 -> "Creature of Fenkenstrain"
41 -> Quests.DARKNESS_OF_HALLOWVALE.questName 41 -> "Darkness of Hallowvale"
42 -> Quests.DEATH_TO_THE_DORGESHUUN.questName 42 -> "Death to the Dorgeshuun"
43 -> Quests.DEATH_PLATEAU.questName 43 -> "Death Plateau"
44 -> Quests.DESERT_TREASURE.questName 44 -> "Desert Treasure"
45 -> Quests.DEVIOUS_MINDS.questName 45 -> "Devious Minds"
46 -> Quests.THE_DIG_SITE.questName 46 -> "The Dig Site"
47 -> Quests.DRUIDIC_RITUAL.questName 47 -> "Druidic Ritual"
48 -> Quests.DWARF_CANNON.questName 48 -> "Dwarf Cannon"
49 -> Quests.EADGARS_RUSE.questName 49 -> "Eadgar's Ruse"
50 -> Quests.EAGLES_PEAK.questName 50 -> "Eagles' Peak"
51 -> Quests.ELEMENTAL_WORKSHOP_I.questName 51 -> "Elemental Workshop I"
52 -> Quests.ELEMENTAL_WORKSHOP_II.questName 52 -> "Elemental Workshop II"
53 -> Quests.ENAKHRAS_LAMENT.questName 53 -> "Enakhra's Lament"
54 -> Quests.ENLIGHTENED_JOURNEY.questName 54 -> "Enlightened Journey"
55 -> Quests.THE_EYES_OF_GLOUPHRIE.questName 55 -> "The Eyes of Glouphrie"
56 -> Quests.FAIRYTALE_I_GROWING_PAINS.questName 56 -> "Fairytale I - Growing Pains"
57 -> Quests.FAIRYTALE_II_CURE_A_QUEEN.questName 57 -> "Fairytale II - Cure a Queen"
58 -> Quests.FAMILY_CREST.questName 58 -> "Family Crest"
59 -> Quests.THE_FEUD.questName 59 -> "The Feud"
60 -> Quests.FIGHT_ARENA.questName 60 -> "Fight Arena"
61 -> Quests.FISHING_CONTEST.questName 61 -> "Fishing Contest"
62 -> Quests.FORGETTABLE_TALE.questName 62 -> "Forgettable Tale..."
63 -> Quests.THE_FREMENNIK_TRIALS.questName 63 -> "The Fremennik Trials"
64 -> Quests.WATERFALL_QUEST.questName 64 -> "Waterfall Quest"
65 -> Quests.GARDEN_OF_TRANQUILITY.questName 65 -> "Garden of Tranquillity"
66 -> Quests.GERTRUDES_CAT.questName 66 -> "Gertrude's Cat"
67 -> Quests.GHOSTS_AHOY.questName 67 -> "Ghosts Ahoy"
68 -> Quests.THE_GIANT_DWARF.questName 68 -> "The Giant Dwarf"
69 -> Quests.THE_GOLEM.questName 69 -> "The Golem"
70 -> Quests.THE_GRAND_TREE.questName 70 -> "The Grand Tree"
71 -> Quests.THE_HAND_IN_THE_SAND.questName 71 -> "The Hand in the Sand"
72 -> Quests.HAUNTED_MINE.questName 72 -> "Haunted Mine"
73 -> Quests.HAZEEL_CULT.questName 73 -> "Hazeel Cult"
74 -> Quests.HEROES_QUEST.questName 74 -> "Heroes' Quest"
75 -> Quests.HOLY_GRAIL.questName 75 -> "Holy Grail"
76 -> Quests.HORROR_FROM_THE_DEEP.questName 76 -> "Horror from the Deep"
77 -> Quests.ICTHLARINS_LITTLE_HELPER.questName 77 -> "Icthlarin's Little Helper"
78 -> Quests.IN_AID_OF_THE_MYREQUE.questName 78 -> "In Aid of the Myreque"
79 -> Quests.IN_SEARCH_OF_THE_MYREQUE.questName 79 -> "In Search of the Myreque"
80 -> Quests.JUNGLE_POTION.questName 80 -> "Jungle Potion"
81 -> Quests.LEGENDS_QUEST.questName 81 -> "Legend's Quest"
82 -> Quests.LOST_CITY.questName 82 -> "Lost City"
83 -> Quests.THE_LOST_TRIBE.questName 83 -> "The Lost Tribe"
84 -> Quests.LUNAR_DIPLOMACY.questName 84 -> "Lunar Diplomacy"
85 -> Quests.MAKING_HISTORY.questName 85 -> "Making History"
86 -> Quests.MERLINS_CRYSTAL.questName 86 -> "Merlin's Crystal"
87 -> Quests.MONKEY_MADNESS.questName 87 -> "Monkey Madness"
88 -> Quests.MONKS_FRIEND.questName 88 -> "Monk's Friend"
89 -> Quests.MOUNTAIN_DAUGHTER.questName 89 -> "Mountain Daughter"
90 -> Quests.MOURNINGS_END_PART_I.questName 90 -> "Mourning's End Part I"
91 -> Quests.MOURNINGS_END_PART_II.questName 91 -> "Mourning's End Part II"
92 -> Quests.MURDER_MYSTERY.questName 92 -> "Murder Mystery"
93 -> Quests.MY_ARMS_BIG_ADVENTURE.questName 93 -> "My Arm's Big Adventure"
94 -> Quests.NATURE_SPIRIT.questName 94 -> "Nature Spirit"
95 -> Quests.OBSERVATORY_QUEST.questName 95 -> "Observatory Quest"
96 -> Quests.ONE_SMALL_FAVOUR.questName 96 -> "One Small Favour"
97 -> Quests.PLAGUE_CITY.questName 97 -> "Plague City"
98 -> Quests.PRIEST_IN_PERIL.questName 98 -> "Priest in Peril"
99 -> Quests.RAG_AND_BONE_MAN.questName 99 -> "Rag and Bone Man"
100 -> Quests.RATCATCHERS.questName 100 -> "Ratcatchers"
101 -> Quests.RECIPE_FOR_DISASTER.questName 101 -> "Recipe for Disaster"
102 -> Quests.RECRUITMENT_DRIVE.questName 102 -> "Recruitment Drive"
103 -> Quests.REGICIDE.questName 103 -> "Regicide"
104 -> Quests.ROVING_ELVES.questName 104 -> "Roving Elves"
105 -> Quests.ROYAL_TROUBLE.questName 105 -> "Royal Trouble"
106 -> Quests.RUM_DEAL.questName 106 -> "Rum Deal"
107 -> Quests.SCORPION_CATCHER.questName 107 -> "Scorpion Catcher"
108 -> Quests.SEA_SLUG.questName 108 -> "Sea Slug"
109 -> Quests.THE_SLUG_MENACE.questName 109 -> "The Slug Menace"
110 -> Quests.SHADES_OF_MORTTON.questName 110 -> "Shades of Mort'ton"
111 -> Quests.SHADOW_OF_THE_STORM.questName 111 -> "Shadow of the Storm"
112 -> Quests.SHEEP_HERDER.questName 112 -> "Sheep Herder"
113 -> Quests.SHILO_VILLAGE.questName 113 -> "Shilo Village"
114 -> Quests.A_SOULS_BANE.questName 114 -> "A Soul's Bane"
115 -> Quests.SPIRITS_OF_THE_ELID.questName 115 -> "Spirits of the Elid"
116 -> Quests.SWAN_SONG.questName 116 -> "Swan Song"
117 -> Quests.TAI_BWO_WANNAI_TRIO.questName 117 -> "Tai Bwo Wannai Trio"
118 -> Quests.A_TAIL_OF_TWO_CATS.questName 118 -> "A Tail of Two Cats"
119 -> Quests.TEARS_OF_GUTHIX.questName 119 -> "Tears of Guthix"
120 -> Quests.TEMPLE_OF_IKOV.questName 120 -> "Temple of Ikov"
121 -> Quests.THRONE_OF_MISCELLANIA.questName 121 -> "Throne of Miscellania"
122 -> Quests.THE_TOURIST_TRAP.questName 122 -> "The Tourist Trap"
123 -> Quests.WITCHS_HOUSE.questName 123 -> "Witch's House"
124 -> Quests.TREE_GNOME_VILLAGE.questName 124 -> "Tree Gnome Village"
125 -> Quests.TRIBAL_TOTEM.questName 125 -> "Tribal Totem"
126 -> Quests.TROLL_ROMANCE.questName 126 -> "Troll Romance"
127 -> Quests.TROLL_STRONGHOLD.questName 127 -> "Troll Stronghold"
128 -> Quests.UNDERGROUND_PASS.questName 128 -> "Underground Pass"
129 -> Quests.WANTED.questName 129 -> "Wanted!"
130 -> Quests.WATCHTOWER.questName 130 -> "Watchtower"
131 -> Quests.COLD_WAR.questName 131 -> "Cold War"
132 -> Quests.THE_FREMENNIK_ISLES.questName 132 -> "The Fremennik Isles"
133 -> Quests.TOWER_OF_LIFE.questName 133 -> "Tower of Life"
134 -> Quests.THE_GREAT_BRAIN_ROBBERY.questName 134 -> "The Great Brain Robbery"
135 -> Quests.WHAT_LIES_BELOW.questName 135 -> "What Lies Below"
136 -> Quests.OLAFS_QUEST.questName 136 -> "Olaf's Quest"
137 -> Quests.ANOTHER_SLICE_OF_HAM.questName 137 -> "Another Slice of H.A.M"
138 -> Quests.DREAM_MENTOR.questName 138 -> "Dream Mentor"
139 -> Quests.GRIM_TALES.questName 139 -> "Grim Tales"
140 -> Quests.KINGS_RANSOM.questName 140 -> "King's Ransom"
141 -> Quests.THE_PATH_OF_GLOUPHRIE.questName 141 -> "The Path of Glouphrie"
142 -> Quests.BACK_TO_MY_ROOTS.questName 142 -> "Back to my Roots"
143 -> Quests.LAND_OF_THE_GOBLINS.questName 143 -> "Land of the Goblins"
144 -> Quests.DEALING_WITH_SCABARAS.questName 144 -> "Dealing with Scabaras"
145 -> Quests.WOLF_WHISTLE.questName 145 -> "Wolf Whistle"
146 -> Quests.AS_A_FIRST_RESORT.questName 146 -> "As a First Resort..."
147 -> Quests.CATAPULT_CONSTRUCTION.questName 147 -> "Catapult Construction"
148 -> Quests.KENNITHS_CONCERNS.questName 148 -> "Kennith's Concerns"
149 -> Quests.LEGACY_OF_SEERGAZE.questName 149 -> "Legacy of Seergaze"
150 -> Quests.PERILS_OF_ICE_MOUNTAIN.questName 150 -> "Perils of Ice Mountain"
151 -> Quests.TOKTZ_KET_DILL.questName 151 -> "TokTz-Ket-Dill"
152 -> Quests.SMOKING_KILLS.questName 152 -> "Smoking Kills"
153 -> Quests.ROCKING_OUT.questName 153 -> "Rocking Out"
154 -> Quests.SPIRIT_OF_SUMMER.questName 154 -> "Spirit of Summer"
155 -> Quests.MEETING_HISTORY.questName 155 -> "Meeting History"
156 -> Quests.ALL_FIRED_UP.questName 156 -> "All Fired Up"
157 -> Quests.SUMMERS_END.questName 157 -> "Summer's End"
158 -> Quests.DEFENDER_OF_VARROCK.questName 158 -> "Defender of Varrock"
159 -> Quests.SWEPT_AWAY.questName 159 -> "Swept Away"
160 -> Quests.WHILE_GUTHIX_SLEEPS.questName 160 -> "While Guthix Sleeps"
161 -> Quests.IN_PYRE_NEED.questName 161 -> "In Pyre Need"
162 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName 162 -> "Myths of the White Lands"
else -> "" else -> ""
} }
return quest as String return name
} }
} }

View file

@ -49,7 +49,7 @@ public class SmeltingInterface extends ComponentPlugin {
* @author 'Vexia * @author 'Vexia
*/ */
public enum BarButton { public enum BarButton {
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); 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);
/** /**
* Constructs a new {@code BarButton} {@code Object}. * Constructs a new {@code BarButton} {@code Object}.

View file

@ -13,7 +13,6 @@ import core.game.world.update.flag.context.Graphics
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.Scenery import org.rs09.consts.Scenery
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
import content.data.Quests
@Suppress("unused") @Suppress("unused")
class EctophialListener : InteractionListener { class EctophialListener : InteractionListener {
@ -38,7 +37,7 @@ class EctophialListener : InteractionListener {
} }
on(Items.ECTOPHIAL_4251, IntType.ITEM, "empty") { player, node -> on(Items.ECTOPHIAL_4251, IntType.ITEM, "empty") { player, node ->
if (!hasRequirement(player, Quests.GHOSTS_AHOY)) if (!hasRequirement(player, "Ghosts Ahoy"))
return@on true return@on true
if (player.isTeleBlocked) { if (player.isTeleBlocked) {

View file

@ -10,14 +10,12 @@ import org.rs09.consts.Sounds
class EnchantJewelleryTabListener : InteractionListener { class EnchantJewelleryTabListener : InteractionListener {
private val LVL_1_ENCHANT = mapOf( 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_RING_1637 to Items.RING_OF_RECOIL_2550,
Items.SAPPHIRE_NECKLACE_1656 to Items.GAMES_NECKLACE8_3853, Items.SAPPHIRE_NECKLACE_1656 to Items.GAMES_NECKLACE8_3853,
Items.SAPPHIRE_AMULET_1694 to Items.AMULET_OF_MAGIC_1727, Items.SAPPHIRE_AMULET_1694 to Items.AMULET_OF_MAGIC_1727,
Items.SAPPHIRE_BRACELET_11072 to Items.BRACELET_OF_CLAY_11074 Items.SAPPHIRE_BRACELET_11072 to Items.BRACELET_OF_CLAY_11074
) )
private val LVL_2_ENCHANT = mapOf( 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_RING_1639 to Items.RING_OF_DUELLING8_2552,
Items.EMERALD_NECKLACE_1658 to Items.BINDING_NECKLACE_5521, Items.EMERALD_NECKLACE_1658 to Items.BINDING_NECKLACE_5521,
Items.EMERALD_AMULET_1696 to Items.AMULET_OF_DEFENCE_1729, Items.EMERALD_AMULET_1696 to Items.AMULET_OF_DEFENCE_1729,
@ -25,7 +23,6 @@ class EnchantJewelleryTabListener : InteractionListener {
) )
private val LVL_3_ENCHANT = mapOf( 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_RING_1641 to Items.RING_OF_FORGING_2568,
Items.RUBY_NECKLACE_1660 to Items.DIGSITE_PENDANT_5_11194, Items.RUBY_NECKLACE_1660 to Items.DIGSITE_PENDANT_5_11194,
Items.RUBY_AMULET_1698 to Items.AMULET_OF_STRENGTH_1725, Items.RUBY_AMULET_1698 to Items.AMULET_OF_STRENGTH_1725,
@ -33,7 +30,6 @@ class EnchantJewelleryTabListener : InteractionListener {
) )
private val LVL_4_ENCHANT = mapOf( 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_RING_1643 to Items.RING_OF_LIFE_2570,
Items.DIAMOND_NECKLACE_1662 to Items.PHOENIX_NECKLACE_11090, Items.DIAMOND_NECKLACE_1662 to Items.PHOENIX_NECKLACE_11090,
Items.DIAMOND_AMULET_1700 to Items.AMULET_OF_POWER_1731, Items.DIAMOND_AMULET_1700 to Items.AMULET_OF_POWER_1731,
@ -41,7 +37,6 @@ class EnchantJewelleryTabListener : InteractionListener {
) )
private val LVL_5_ENCHANT = mapOf( 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.DRAGONSTONE_RING_1645 to Items.RING_OF_WEALTH4_14646,
Items.DRAGON_NECKLACE_1664 to Items.SKILLS_NECKLACE4_11105, Items.DRAGON_NECKLACE_1664 to Items.SKILLS_NECKLACE4_11105,
Items.DRAGONSTONE_AMMY_1702 to Items.AMULET_OF_GLORY4_1712, Items.DRAGONSTONE_AMMY_1702 to Items.AMULET_OF_GLORY4_1712,
@ -49,7 +44,6 @@ class EnchantJewelleryTabListener : InteractionListener {
) )
private val LVL_6_ENCHANT = mapOf( 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_RING_6575 to Items.RING_OF_STONE_6583,
Items.ONYX_NECKLACE_6577 to Items.BERSERKER_NECKLACE_11128, Items.ONYX_NECKLACE_6577 to Items.BERSERKER_NECKLACE_11128,
Items.ONYX_AMULET_6581 to Items.AMULET_OF_FURY_6585, Items.ONYX_AMULET_6581 to Items.AMULET_OF_FURY_6585,

View file

@ -1,6 +1,5 @@
package content.global.handlers.item package content.global.handlers.item
import content.global.skill.slayer.SlayerUtils
import core.api.* import core.api.*
import content.global.skill.slayer.Tasks import content.global.skill.slayer.Tasks
import org.rs09.consts.Items import org.rs09.consts.Items
@ -42,8 +41,7 @@ class EnchantedGemDialogue() : DialogueFile() {
if(getSlayerTask(player!!) == Tasks.JAD) { if(getSlayerTask(player!!) == Tasks.JAD) {
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill TzTok-Jad!") npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill TzTok-Jad!")
} else { } else {
npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${SlayerUtils.pluralise( npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${getSlayerTaskName(player!!)}s; only ${getSlayerTaskKillsRemaining(player!!)} more to go.")
getSlayerTaskName(player!!))}; only ${getSlayerTaskKillsRemaining(player!!)} more to go.")
} }
setVarp(player!!, 2502, getSlayerTaskFlags(player!!) shr 4) setVarp(player!!, 2502, getSlayerTaskFlags(player!!) shr 4)
stage = 1 stage = 1

View file

@ -53,9 +53,9 @@ class ExplorersRingPlugin : InteractionListener {
sendMessage(player, "You have used up all of your charges for the day.") sendMessage(player, "You have used up all of your charges for the day.")
return@on true return@on true
} }
//sendDialogue(player, "Choose the item that you wish to convert to coins.") sendDialogue(player, "Choose the item that you wish to convert to coins.")
//addDialogueAction (player) {_,_ -> addDialogueAction (player) {_,_ ->
sendItemSelect (player, "Cast Low Level Alchemy on:") { slot, optionIndex -> sendItemSelect (player, "Choose") { slot, optionIndex ->
val item = player.inventory[slot] val item = player.inventory[slot]
if (item == null) if (item == null)
return@sendItemSelect return@sendItemSelect
@ -63,7 +63,7 @@ class ExplorersRingPlugin : InteractionListener {
return@sendItemSelect return@sendItemSelect
getStoreFile()[player.username.lowercase() + ":alchs"] = remaining - 1 getStoreFile()[player.username.lowercase() + ":alchs"] = remaining - 1
} }
//} }
return@on true return@on true
} }

View file

@ -5,34 +5,24 @@ import core.game.interaction.IntType
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.node.entity.player.link.TeleportManager import core.game.node.entity.player.link.TeleportManager
import core.game.node.item.Item import core.game.node.item.Item
import core.game.node.entity.player.Player
import core.game.world.repository.Repository
class HouseTeleTabOptionListener : InteractionListener { class HouseTeleTabOptionListener : InteractionListener {
override fun defineListeners() { override fun defineListeners() {
val homeTabID = 8013 val homeTabID = 8013
on(homeTabID, IntType.ITEM, "break") {player, node -> on(homeTabID, IntType.ITEM, "break") {player, node ->
//Snowscape: teleport to the last house you entered, if possible var hasHouse = player.houseManager.location.exitLocation != null
var owner: Player if (!hasHouse) {
val lastHouseOwner = Repository.getPlayerByName(player.getAttribute("lasthouseentered", null)) sendMessage( player, "You must have a house to teleport to before attempting that.")
if (lastHouseOwner != null && !lastHouseOwner.getHouseManager().isLocked()) { return@on false
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) closeInterface(player)
lock(player, 5) lock(player, 5)
if (inInventory(player, node.id)) { if (inInventory(player, node.id)) {
owner.houseManager.preEnter(player, false) player.houseManager.preEnter(player, false)
val location = owner.houseManager.getEnterLocation() val location = player.houseManager.getEnterLocation()
if (teleport(player, location, TeleportManager.TeleportType.TELETABS)) { if (teleport(player, location, TeleportManager.TeleportType.TELETABS)) {
removeItem(player, Item(node.id, 1)) removeItem(player, Item(node.id, 1))
owner.houseManager.postEnter(player, false) player.houseManager.postEnter(player, false)
} }
} }
return@on true return@on true

View file

@ -4,7 +4,6 @@ import core.api.*
import core.game.node.entity.player.link.quest.QuestRepository import core.game.node.entity.player.link.quest.QuestRepository
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import content.data.Quests
class ItemQuestRequirementListener : InteractionListener { class ItemQuestRequirementListener : InteractionListener {
@ -107,7 +106,7 @@ class ItemQuestRequirementListener : InteractionListener {
/* /*
onEquip(fremennikIslesEquipment) { player, _ -> onEquip(fremennikIslesEquipment) { player, _ ->
if (!isQuestComplete(player, Quests.THE_FREMENNIK_ISLES)) { if (!isQuestComplete(player, "Fremennik Isles")) {
sendMessage(player, "You must have completed The Fremennik Isles to equip this.") sendMessage(player, "You must have completed The Fremennik Isles to equip this.")
return@onEquip false return@onEquip false
} }
@ -115,7 +114,7 @@ class ItemQuestRequirementListener : InteractionListener {
} }
onEquip(fremennikIslesDuringQuestEquipment){ player, _ -> onEquip(fremennikIslesDuringQuestEquipment){ player, _ ->
if (questStage(player, Quests.THE_FREMENNIK_ISLES) > 0) { if (questStage(player, "Fremennik Isles") > 0) {
sendMessage(player, "You must have started The Fremennik Isles to equip this.") sendMessage(player, "You must have started The Fremennik Isles to equip this.")
return@onEquip false return@onEquip false
} }
@ -124,23 +123,23 @@ class ItemQuestRequirementListener : InteractionListener {
*/ */
onEquip(fremennikTrialsEquipment) { player, _ -> onEquip(fremennikTrialsEquipment) { player, _ ->
return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_TRIALS) return@onEquip hasRequirement(player, "Fremennik Trials")
} }
onEquip(fremennikIslesEquipment) {player, _ -> onEquip(fremennikIslesEquipment) {player, _ ->
return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_ISLES) return@onEquip hasRequirement(player, "The Fremennik Isles")
} }
onEquip(avasBackpacks){ player, _ -> onEquip(avasBackpacks){ player, _ ->
return@onEquip hasRequirement(player, Quests.ANIMAL_MAGNETISM) return@onEquip hasRequirement(player, "Animal Magnetism")
} }
onEquip(lostCityWeapons){ player, _ -> onEquip(lostCityWeapons){ player, _ ->
return@onEquip hasRequirement(player, Quests.LOST_CITY) return@onEquip hasRequirement(player, "Lost City")
} }
onEquip(Items.CAPE_OF_LEGENDS_1052) { player, _ -> onEquip(Items.CAPE_OF_LEGENDS_1052) { player, _ ->
return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST) return@onEquip hasRequirement(player, "Legend's Quest")
} }
onEquip(questCapes) { player, _ -> onEquip(questCapes) { player, _ ->
@ -153,84 +152,84 @@ class ItemQuestRequirementListener : InteractionListener {
} }
onEquip(Items.WOLFBANE_2952){ player, _ -> onEquip(Items.WOLFBANE_2952){ player, _ ->
return@onEquip hasRequirement(player, Quests.PRIEST_IN_PERIL) return@onEquip hasRequirement(player, "Priest in Peril")
} }
onEquip(Items.ANCIENT_MACE_11061){ player, _ -> onEquip(Items.ANCIENT_MACE_11061){ player, _ ->
return@onEquip hasRequirement(player, Quests.ANOTHER_SLICE_OF_HAM) return@onEquip hasRequirement(player, "Another Slice of H.A.M")
} }
onEquip(Items.ANCIENT_STAFF_4675){ player, _ -> onEquip(Items.ANCIENT_STAFF_4675){ player, _ ->
return@onEquip hasRequirement(player, Quests.DESERT_TREASURE) return@onEquip hasRequirement(player, "Desert Treasure")
} }
onEquip(Items.ELEMENTAL_SHIELD_2890) { player, _ -> onEquip(Items.ELEMENTAL_SHIELD_2890) { player, _ ->
return@onEquip hasRequirement(player, Quests.ELEMENTAL_WORKSHOP_I) return@onEquip hasRequirement(player, "Elemental Workshop I")
} }
onEquip(crystalEquipment){ player, _ -> onEquip(crystalEquipment){ player, _ ->
return@onEquip hasRequirement(player, Quests.ROVING_ELVES) return@onEquip hasRequirement(player, "Roving Elves")
} }
onEquip(dragonSlayerEquipment) {player, _ -> onEquip(dragonSlayerEquipment) {player, _ ->
return@onEquip hasRequirement(player, Quests.DRAGON_SLAYER) return@onEquip hasRequirement(player, "Dragon Slayer")
} }
onEquip(Items.DRAGON_SCIMITAR_4587) {player, _ -> onEquip(Items.DRAGON_SCIMITAR_4587) {player, _ ->
return@onEquip hasRequirement(player, Quests.MONKEY_MADNESS) return@onEquip hasRequirement(player, "Monkey Madness")
} }
onEquip(Items.GLOVES_7462) {player, _ -> onEquip(Items.GLOVES_7462) {player, _ ->
return@onEquip hasRequirement(player, Quests.RECIPE_FOR_DISASTER) return@onEquip hasRequirement(player, "Recipe for Disaster")
} }
onEquip(Items.SLAYER_HELMET_13263) {player, _ -> onEquip(Items.SLAYER_HELMET_13263) {player, _ ->
return@onEquip hasRequirement(player, Quests.SMOKING_KILLS) return@onEquip hasRequirement(player, "Smoking Kills")
} }
onEquip (Items.DRAGON_HALBERD_3204) {player, _ -> onEquip (Items.DRAGON_HALBERD_3204) {player, _ ->
return@onEquip hasRequirement(player, Quests.REGICIDE) return@onEquip hasRequirement(player, "Regicide")
} }
onEquip (Items.CLIMBING_BOOTS_3105) {player, _ -> onEquip (Items.CLIMBING_BOOTS_3105) {player, _ ->
return@onEquip hasRequirement(player, Quests.DEATH_PLATEAU) return@onEquip hasRequirement(player, "Death Plateau")
} }
onEquip (godBooks) {player, _ -> onEquip (godBooks) {player, _ ->
return@onEquip hasRequirement(player, Quests.HORROR_FROM_THE_DEEP) return@onEquip hasRequirement(player, "Horror from the Deep")
} }
onEquip (pharaohScepters) {player, _ -> onEquip (pharaohScepters) {player, _ ->
return@onEquip hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER) return@onEquip hasRequirement(player, "Icthlarin's Little Helper")
} }
onEquip (Items.DRAGON_SQ_SHIELD_1187) {player, _ -> onEquip (Items.DRAGON_SQ_SHIELD_1187) {player, _ ->
//because I know people won't believe it: https://runescape.wiki/w/Dragon_sq_shield?oldid=899636 //because I know people won't believe it: https://runescape.wiki/w/Dragon_sq_shield?oldid=899636
return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST) return@onEquip hasRequirement(player, "Legend's Quest")
} }
onEquip (initiateArmour) {player, _ -> onEquip (initiateArmour) {player, _ ->
return@onEquip hasRequirement(player, Quests.RECRUITMENT_DRIVE) return@onEquip hasRequirement(player, "Recruitment Drive")
} }
onEquip (proselyteArmour) {player, _ -> onEquip (proselyteArmour) {player, _ ->
return@onEquip hasRequirement(player, Quests.THE_SLUG_MENACE) return@onEquip hasRequirement(player, "The Slug Menace")
} }
onEquip (spiritShields) {player, _ -> onEquip (spiritShields) {player, _ ->
return@onEquip hasRequirement(player, Quests.SUMMERS_END) return@onEquip hasRequirement(player, "Summer's End")
} }
onEquip (Items.DRAGON_MACE_1434) {player, _ -> onEquip (Items.DRAGON_MACE_1434) {player, _ ->
return@onEquip hasRequirement(player, Quests.HEROES_QUEST) return@onEquip hasRequirement(player, "Heroes' Quest")
} }
onEquip (Items.DRAGON_BATTLEAXE_1377) {player, _ -> onEquip (Items.DRAGON_BATTLEAXE_1377) {player, _ ->
return@onEquip hasRequirement(player, Quests.HEROES_QUEST) return@onEquip hasRequirement(player, "Heroes' Quest")
} }
onEquip (Items.DARKLIGHT_6746) {player, _ -> onEquip (Items.DARKLIGHT_6746) {player, _ ->
return@onEquip hasRequirement(player, Quests.SHADOW_OF_THE_STORM) return@onEquip hasRequirement(player, "Shadow of the Storm")
} }
} }
} }

View file

@ -8,7 +8,6 @@ import core.game.node.entity.player.Player;
import core.plugin.Initializable; import core.plugin.Initializable;
import core.plugin.Plugin; import core.plugin.Plugin;
import content.region.morytania.quest.naturespirit.NSUtils; import content.region.morytania.quest.naturespirit.NSUtils;
import content.data.Quests;
/** /**
* Handles the Silver Sickle (b) to collect Mort Myre Fungus. * Handles the Silver Sickle (b) to collect Mort Myre Fungus.
@ -29,7 +28,7 @@ public final class SilverSicklePlugin extends OptionHandler {
switch (option) { switch (option) {
case "operate": case "operate":
case "cast bloom": case "cast bloom":
if(player.getQuestRepository().getQuest(Quests.NATURE_SPIRIT).getStage(player) >= 75) { if(player.getQuestRepository().getQuest("Nature Spirit").getStage(player) >= 75) {
player.getPacketDispatch().sendAnimation(9021); player.getPacketDispatch().sendAnimation(9021);
NSUtils.castBloom(player); NSUtils.castBloom(player);
} else { } else {

View file

@ -1,183 +0,0 @@
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
}
}
}

View file

@ -1,146 +0,0 @@
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)
}
}
}
}
}
}
}

View file

@ -1,55 +1,39 @@
package content.global.handlers.item package content.global.handlers.item
import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE import core.api.inInventory
import core.api.* import core.api.removeItem
import core.api.teleport
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.player.link.TeleportManager import core.game.node.entity.player.link.TeleportManager
import core.game.node.item.Item import core.game.node.item.Item
import core.game.world.map.Location import core.game.world.map.Location
import content.data.Quests import core.api.hasRequirement;
import core.cache.def.impl.ItemDefinition;
class TeleTabsListener : InteractionListener { class TeleTabsListener : InteractionListener {
enum class TeleTabs(val item: Int, val location: Location, val exp: Double, val requirementCheck: (Player) -> Boolean = { true }) { 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, { ADDOUGNE_TELEPORT(8011, Location.create(2662, 3307, 0), 61.0, {
player -> getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false) player -> hasRequirement(player, "Plague City");
}), }),
AIR_ALTAR_TELEPORT(13599, Location.create(2978, 3296, 0), 0.0), AIR_ALTAR_TELEPORT(13599, Location.create(2978, 3296, 0), 0.0),
ASTRAL_ALTAR_TELEPORT(13611, Location.create(2156, 3862, 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),
}),
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), BODY_ALTAR_TELEPORT(13604, Location.create(3055, 3443, 0), 0.0),
CAMELOT_TELEPORT(8010, Location.create(2757, 3477, 0), 55.5), CAMELOT_TELEPORT(8010, Location.create(2757, 3477, 0), 55.5),
CHAOS_ALTAR_TELEPORT(13606, Location.create(3058, 3593, 0), 0.0), CHAOS_ALTAR_TELEPORT(13606, Location.create(3058, 3593, 0), 0.0),
COSMIC_ALTAR_TELEPORT(13605, Location.create(2411, 4380, 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),
}),
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), EARTH_ALTAR_TELEPORT(13602, Location.create(3304, 3472, 0), 0.0),
FALADOR_TELEPORT(8009, Location.create(2966, 3380, 0), 47.0), FALADOR_TELEPORT(8009, Location.create(2966, 3380, 0), 47.0),
FIRE_ALTAR_TELEPORT(13603, Location.create(3311, 3252, 0), 0.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), LUMBRIDGE_TELEPORT(8008, Location.create(3222, 3218, 0), 41.0),
MIND_ALTAR_TELEPORT(13600, Location.create(2979, 3510, 0), 0.0), MIND_ALTAR_TELEPORT(13600, Location.create(2979, 3510, 0), 0.0),
NATURE_ALTAR_TELEPORT(13607, Location.create(2868, 3013, 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), 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); WATER_ALTAR_TELEPORT(13601, Location.create(3182, 3162, 0), 0.0);
companion object { companion object {
@ -67,17 +51,9 @@ class TeleTabsListener : InteractionListener {
val tabEnum = TeleTabs.forId(tab) val tabEnum = TeleTabs.forId(tab)
if (tabEnum != null && inInventory(player,tab)) { if (tabEnum != null && inInventory(player,tab)) {
val tabloc = tabEnum.location val tabloc = tabEnum.location
if (inInventory(player, tab)) { if (inInventory(player, tab) && tabEnum.requirementCheck(player)) {
if (tabEnum.requirementCheck(player)){ if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) {
if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) { removeItem(player, Item(node.id, 1))
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.")
}
} }
} }
} }

View file

@ -14,7 +14,6 @@ import core.game.world.map.zone.impl.WildernessZone;
import core.plugin.Plugin; import core.plugin.Plugin;
import static core.api.ContentAPIKt.hasRequirement; import static core.api.ContentAPIKt.hasRequirement;
import content.data.Quests;
/** /**
* Represents the rotten potato plugin. * Represents the rotten potato plugin.
@ -35,7 +34,7 @@ public final class TeleportCrystalPlugin extends OptionHandler {
@Override @Override
public boolean handle(Player player, Node node, String option) { public boolean handle(Player player, Node node, String option) {
if (!hasRequirement(player, Quests.MOURNINGS_END_PART_I)) if (!hasRequirement(player, "Mourning's End Part I"))
return true; return true;
if (!WildernessZone.checkTeleport(player, 20)) { if (!WildernessZone.checkTeleport(player, 20)) {
player.getPacketDispatch().sendMessage("The crystal is unresponsive."); player.getPacketDispatch().sendMessage("The crystal is unresponsive.");

View file

@ -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 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) 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() { override fun startup() {
EquipmentDegrader.registerSet(1200, shield) EquipmentDegrader.registerSet(250, shield)
EquipmentDegrader.registerSet(1200, bow) EquipmentDegrader.registerSet(250, bow)
} }
} }

View file

@ -0,0 +1,56 @@
package content.global.handlers.item.withnpc
import core.api.Container
import core.api.*
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import core.game.interaction.InteractionListener
import core.game.interaction.IntType
class CatOnArdougneCivilian: InteractionListener {
private val civilians = intArrayOf(
NPCs.CIVILIAN_785,
NPCs.CIVILIAN_786,
NPCs.CIVILIAN_787
)
private val cats = intArrayOf(
Items.PET_CAT_1561,
Items.PET_CAT_1562,
Items.PET_CAT_1563,
Items.PET_CAT_1564,
Items.PET_CAT_1565,
Items.PET_CAT_1566,
Items.OVERGROWN_CAT_1567,
Items.OVERGROWN_CAT_1568,
Items.OVERGROWN_CAT_1569,
Items.OVERGROWN_CAT_1570,
Items.OVERGROWN_CAT_1571,
Items.OVERGROWN_CAT_1572,
Items.LAZY_CAT_6551,
Items.LAZY_CAT_6552,
Items.LAZY_CAT_6553,
Items.LAZY_CAT_6554,
Items.WILY_CAT_6555,
Items.WILY_CAT_6556,
Items.WILY_CAT_6557,
Items.WILY_CAT_6558,
Items.WILY_CAT_6559,
Items.WILY_CAT_6560,
Items.HELL_CAT_7582,
Items.OVERGROWN_HELLCAT_7581,
Items.LAZY_HELL_CAT_7584,
Items.WILY_HELLCAT_7585,
)
override fun defineListeners() {
onUseWith(IntType.NPC,cats,*civilians){ player, used, _ ->
sendItemDialogue(player,Items.DEATH_RUNE_560,"You hand over the cat.<br>You are given 100 Death Runes.")
player.familiarManager.removeDetails(used.id)
removeItem(player,used,Container.INVENTORY)
addItem(player,Items.DEATH_RUNE_560,100)
return@onUseWith true
}
}
}

View file

@ -10,27 +10,27 @@ import org.rs09.consts.NPCs
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.world.GameWorld.Pulser import core.game.world.GameWorld.Pulser
import content.data.Quests
class GCItemOnCat : InteractionListener { class GCItemOnCat : InteractionListener {
override fun defineListeners() { override fun defineListeners() {
val GERTCAT = "Gertrude's Cat"
val BEND_DOWN = 827 val BEND_DOWN = 827
onUseWith(IntType.NPC, Items.BUCKET_OF_MILK_1927, NPCs.GERTRUDES_CAT_2997) { player, used, with -> onUseWith(IntType.NPC, Items.BUCKET_OF_MILK_1927, NPCs.GERTRUDES_CAT_2997) { player, used, with ->
if(getQuestStage(player, Quests.GERTRUDES_CAT) == 20 && removeItem(player, used.asItem())){ if(getQuestStage(player, GERTCAT) == 20 && removeItem(player, used.asItem())){
addItem(player, Items.BUCKET_1925) addItem(player, Items.BUCKET_1925)
animate(player, BEND_DOWN) //bend down animate(player, BEND_DOWN) //bend down
sendChat(with.asNpc(), "Mew!") sendChat(with.asNpc(), "Mew!")
setQuestStage(player, Quests.GERTRUDES_CAT, 30) setQuestStage(player, GERTCAT, 30)
} }
return@onUseWith true return@onUseWith true
} }
onUseWith(IntType.NPC, Items.DOOGLE_SARDINE_1552, NPCs.GERTRUDES_CAT_2997){ player, used, with -> onUseWith(IntType.NPC, Items.DOOGLE_SARDINE_1552, NPCs.GERTRUDES_CAT_2997){ player, used, with ->
if(getQuestStage(player, Quests.GERTRUDES_CAT) == 30 && removeItem(player, used.asItem())){ if(getQuestStage(player, GERTCAT) == 30 && removeItem(player, used.asItem())){
animate(player, BEND_DOWN) animate(player, BEND_DOWN)
sendChat(with.asNpc(), "Mew!") sendChat(with.asNpc(), "Mew!")
setQuestStage(player, Quests.GERTRUDES_CAT, 40) setQuestStage(player, GERTCAT, 40)
} }
return@onUseWith true return@onUseWith true
} }
@ -42,7 +42,7 @@ class GCItemOnCat : InteractionListener {
onUseWith(IntType.NPC, Items.THREE_LITTLE_KITTENS_13236, NPCs.GERTRUDES_CAT_2997){ player, used, with -> onUseWith(IntType.NPC, Items.THREE_LITTLE_KITTENS_13236, NPCs.GERTRUDES_CAT_2997){ player, used, with ->
if(removeItem(player, used.asItem())){ if(removeItem(player, used.asItem())){
setQuestStage(player, Quests.GERTRUDES_CAT, 60) setQuestStage(player, GERTCAT, 60)
//below copied verbatim from original, I don't like it. //below copied verbatim from original, I don't like it.
Pulser.submit(object : Pulse(1) { Pulser.submit(object : Pulse(1) {
var count = 0 var count = 0

View file

@ -14,7 +14,6 @@ import core.game.world.map.path.Pathfinder;
import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Animation;
import core.plugin.Initializable; import core.plugin.Initializable;
import core.plugin.Plugin; import core.plugin.Plugin;
import content.data.Quests;
/** /**
* Represents the plugin used to handle the use with interactions. * Represents the plugin used to handle the use with interactions.
@ -51,7 +50,7 @@ public final class GertrudeCatUsePlugin extends UseWithHandler {
public boolean handle(NodeUsageEvent event) { public boolean handle(NodeUsageEvent event) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
final NPC npc = ((NPC) event.getUsedWith()); final NPC npc = ((NPC) event.getUsedWith());
final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); final Quest quest = player.getQuestRepository().getQuest("Gertrude's Cat");
if (event.getUsedItem().getId() == 1927 && quest.getStage(player) == 20) { if (event.getUsedItem().getId() == 1927 && quest.getStage(player) == 20) {
if (player.getInventory().remove(event.getUsedItem())) { if (player.getInventory().remove(event.getUsedItem())) {
player.getInventory().add(EMPTY_BUCKET); player.getInventory().add(EMPTY_BUCKET);

View file

@ -5,19 +5,20 @@ import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.interaction.IntType import core.game.interaction.IntType
import content.data.Quests
class RopeOnLadyKeli : InteractionListener { class RopeOnLadyKeli : InteractionListener {
override fun defineListeners() { override fun defineListeners() {
val PAR = "Prince Ali Rescue"
onUseWith(IntType.NPC, Items.ROPE_954, NPCs.LADY_KELI_919) { player, used, with -> onUseWith(IntType.NPC, Items.ROPE_954, NPCs.LADY_KELI_919) { player, used, with ->
if(getQuestStage(player, Quests.PRINCE_ALI_RESCUE) in 40..50 && getAttribute(player, "guard-drunk", false)){ if(getQuestStage(player, PAR) in 40..50 && getAttribute(player, "guard-drunk", false)){
if(removeItem(player, used.asItem())){ if(removeItem(player, used.asItem())){
sendDialogue(player, "You overpower Keli, tie her up, and put her in a cupboard.") sendDialogue(player, "You overpower Keli, tie her up, and put her in a cupboard.")
setQuestStage(player, Quests.PRINCE_ALI_RESCUE, 50) setQuestStage(player, PAR, 50)
setAttribute(player, "keli-gone", getWorldTicks() + 350) setAttribute(player, "keli-gone", getWorldTicks() + 350)
} }
} else { } else {
if (getQuestStage(player, Quests.PRINCE_ALI_RESCUE) == 40){ if (getQuestStage(player, PAR) == 40){
sendMessage(player, "You need to do something about the guard first.") sendMessage(player, "You need to do something about the guard first.")
} }
} }

View file

@ -1,7 +1,7 @@
package content.global.handlers.item.withobject package content.global.handlers.item.withobject
import content.data.Quests
import core.api.* import core.api.*
import content.region.kandarin.quest.dwarfcannon.DwarfCannon
import core.game.node.Node import core.game.node.Node
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
@ -19,8 +19,8 @@ class AmmoMouldOnFurnace : InteractionListener {
private fun cannonBallOnUseWithHandler(player: Player, used: Node, with: Node): Boolean { private fun cannonBallOnUseWithHandler(player: Player, used: Node, with: Node): Boolean {
face(player, with.centerLocation) face(player, with.centerLocation)
if(!isQuestComplete(player, Quests.DWARF_CANNON)) { if(!isQuestComplete(player, DwarfCannon.NAME)) {
sendDialogue(player, "You need to complete the ${Quests.DWARF_CANNON} quest in order to do this.") sendDialogue(player, "You need to complete the ${DwarfCannon.NAME} quest in order to do this.")
return true return true
} }
if (getDynLevel(player, Skills.SMITHING) < levelRequirement) { if (getDynLevel(player, Skills.SMITHING) < levelRequirement) {

View file

@ -15,7 +15,6 @@ import core.game.node.scenery.Scenery;
import core.plugin.Plugin; import core.plugin.Plugin;
import core.plugin.Initializable; import core.plugin.Initializable;
import core.plugin.ClassScanner; import core.plugin.ClassScanner;
import content.data.Quests;
/** /**
* Represents the option handler used for smithing. * Represents the option handler used for smithing.
@ -69,7 +68,7 @@ public final class SmithingPlugin extends UseWithHandler {
@Override @Override
public boolean handle(NodeUsageEvent event) { public boolean handle(NodeUsageEvent event) {
final Player player = event.getPlayer(); final Player player = event.getPlayer();
if (((Scenery) event.getUsedWith()).getId() == 2782 && !player.getQuestRepository().isComplete(Quests.DORICS_QUEST)) { if (((Scenery) event.getUsedWith()).getId() == 2782 && !player.getQuestRepository().isComplete("Doric's Quest")) {
player.getDialogueInterpreter().sendDialogue("Property of Doric the Dwarf."); player.getDialogueInterpreter().sendDialogue("Property of Doric the Dwarf.");
return true; return true;
} }

View file

@ -7,7 +7,6 @@ import core.game.node.item.GroundItemManager;
import core.game.node.item.Item; import core.game.node.item.Item;
import core.plugin.Initializable; import core.plugin.Initializable;
import core.game.world.map.Location; import core.game.world.map.Location;
import content.data.Quests;
/** /**
* Represents a rat npc. * Represents a rat npc.
@ -52,7 +51,7 @@ public class RatNPC extends AbstractNPC {
super.finalizeDeath(killer); super.finalizeDeath(killer);
if (killer instanceof Player) { if (killer instanceof Player) {
final Player p = ((Player) killer); final Player p = ((Player) killer);
if (p.getQuestRepository().getQuest(Quests.WITCHS_POTION).isStarted(p)) { if (p.getQuestRepository().getQuest("Witch's Potion").isStarted(p)) {
GroundItemManager.create(RAT_TAIL, getLocation(), p); GroundItemManager.create(RAT_TAIL, getLocation(), p);
} }
} }

View file

@ -17,7 +17,6 @@ import org.rs09.consts.NPCs
import org.rs09.consts.Sounds import org.rs09.consts.Sounds
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.Direction import core.game.world.map.Direction
import content.data.Quests
private val sheepIds = intArrayOf( private val sheepIds = intArrayOf(
NPCs.SHEEP_42, NPCs.SHEEP_42,
@ -75,7 +74,7 @@ class SheepBehavior : NPCBehavior(*sheepIds), InteractionListener {
val sheep = node as NPC val sheep = node as NPC
sheep.faceTemporary(player, 1) sheep.faceTemporary(player, 1)
if (sheep.id == NPCs.SHEEP_3579) { if (sheep.id == NPCs.SHEEP_3579) {
if (player.questRepository.getQuest(Quests.SHEEP_SHEARER).isStarted(player)) { if (player.questRepository.getQuest("Sheep Shearer").isStarted(player)) {
setAttribute(player, ATTR_IS_PENGUIN_SHEEP_SHEARED, true) setAttribute(player, ATTR_IS_PENGUIN_SHEEP_SHEARED, true)
} }
animate(player, Animation(893)) animate(player, Animation(893))

View file

@ -72,7 +72,7 @@ public final class FieldPickingPlugin extends OptionHandler {
player.dispatch(new ResourceProducedEvent(reward.getId(), reward.getAmount(), node, -1)); player.dispatch(new ResourceProducedEvent(reward.getId(), reward.getAmount(), node, -1));
if (plant.name().startsWith("NETTLES") && (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) == null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null && !player.getEquipment().get(EquipmentContainer.SLOT_HANDS).getName().contains("glove"))) { if (plant.name().startsWith("NETTLES") && (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) == null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null && !player.getEquipment().get(EquipmentContainer.SLOT_HANDS).getName().contains("glove"))) {
player.getPacketDispatch().sendMessage("You have been stung by the nettles!"); player.getPacketDispatch().sendMessage("You have been stung by the nettles!");
player.getImpactHandler().manualHit(player, 6, HitsplatType.POISON); player.getImpactHandler().manualHit(player, 2, HitsplatType.POISON);
return true; return true;
} }
if (plant.respawn != -1 && plant != PickingPlant.FLAX) { if (plant.respawn != -1 && plant != PickingPlant.FLAX) {

View file

@ -7,9 +7,6 @@ import core.game.node.entity.player.Player;
import core.game.node.item.Item; import core.game.node.item.Item;
import core.plugin.Initializable; import core.plugin.Initializable;
import core.plugin.Plugin; import core.plugin.Plugin;
import content.data.Quests;
import static core.api.ContentAPIKt.*;
/** /**
* Handles the search option. * Handles the search option.
@ -83,10 +80,6 @@ public class SearchOptionPlugin extends OptionHandler {
player.getInventory().add(new Item(946)); player.getInventory().add(new Item(946));
return true; return true;
} }
if (node.getId() == 12799 && hasRequirement(player, Quests.IN_AID_OF_THE_MYREQUE)) {
openBankAccount(player);
return true;
}
player.getPacketDispatch().sendMessage("You search the " + node.getName().toLowerCase() + " but find nothing."); player.getPacketDispatch().sendMessage("You search the " + node.getName().toLowerCase() + " but find nothing.");
return true; return true;
} }

View file

@ -11,21 +11,18 @@ class SignpostListener : InteractionListener {
override fun defineListeners() { override fun defineListeners() {
on(Scenery.SIGNPOST_18493, IntType.SCENERY, "read") { player, node -> on(Scenery.SIGNPOST_18493, IntType.SCENERY, "read") { player, node ->
if (node.asScenery().location.equals(Location(3235, 3228))) { if (node.asScenery().location.equals(Location(3235, 3228))) {
// Authentic
setInterfaceText(player, "Head north towards Fred's farm, and the windmill.", 135, 3) // North setInterfaceText(player, "Head north towards Fred's farm, and the windmill.", 135, 3) // North
setInterfaceText(player, "South to the swamps of Lumbridge.", 135, 9) // South setInterfaceText(player, "South to the swamps of Lumbridge.", 135, 9) // South
setInterfaceText(player, "Cross the bridge and head east to Al Kharid or north to Varrock.", 135, 8) // East setInterfaceText(player, "Cross the bridge and head east to Al Kharid or north to Varrock.", 135, 8) // East
setInterfaceText(player, "West to the Lumbridge Castle and Draynor Village. Beware the goblins!", 135, 12) // West setInterfaceText(player, "West to the Lumbridge Castle and Draynor Village. Beware the goblins!", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135) openInterface(player, Components.AIDE_COMPASS_135)
} else if (node.asScenery().location.equals(Location(3261, 3230))) { } else if (node.asScenery().location.equals(Location(3261, 3230))) {
// Authentic
setInterfaceText(player, "North to farms and Varrock.", 135, 3) // North setInterfaceText(player, "North to farms and Varrock.", 135, 3) // North
setInterfaceText(player, "The River Lum lies to the south.", 135, 9) // South setInterfaceText(player, "The River Lum lies to the south.", 135, 9) // South
setInterfaceText(player, "East to Al Kharid - toll gate; bring some money.", 135, 8) // East setInterfaceText(player, "East to Al Kharid - toll gate; bring some money.", 135, 8) // East
setInterfaceText(player, "West to Lumbridge.", 135, 12) // West setInterfaceText(player, "West to Lumbridge.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135) openInterface(player, Components.AIDE_COMPASS_135)
} else if (node.asScenery().location.equals(Location(2983, 3278))) { } else if (node.asScenery().location.equals(Location(2983, 3278))) {
// Authentic
setInterfaceText(player, "North to the glorious White Knights' city of Falador.", 135, 3) // North setInterfaceText(player, "North to the glorious White Knights' city of Falador.", 135, 3) // North
setInterfaceText(player, "South to Rimmington.", 135, 9) // South setInterfaceText(player, "South to Rimmington.", 135, 9) // South
setInterfaceText(player, "East to Port Sarim and Draynor Village.", 135, 8) // East setInterfaceText(player, "East to Port Sarim and Draynor Village.", 135, 8) // East
@ -48,14 +45,12 @@ class SignpostListener : InteractionListener {
} }
on(Scenery.SIGNPOST_24263, IntType.SCENERY, "read") { player, node -> on(Scenery.SIGNPOST_24263, IntType.SCENERY, "read") { player, node ->
if (node.asScenery().location.equals(Location(3268, 3332))) { if (node.asScenery().location.equals(Location(3268, 3332))) {
// Authentic
setInterfaceText(player, "Sheep lay this way.", 135, 3) // North setInterfaceText(player, "Sheep lay this way.", 135, 3) // North
setInterfaceText(player, "South through farms to Al Kharid and Lumbridge.", 135, 9) // South setInterfaceText(player, "South through farms to Al Kharid and Lumbridge.", 135, 9) // South
setInterfaceText(player, "East to Al Kharid mine and follow the path north to Varrock east gate.", 135, 8) // East setInterfaceText(player, "East to Al Kharid mine and follow the path north to Varrock east gate.", 135, 8) // East
setInterfaceText(player, "West to Champion's Guild and Varrock south gate.", 135, 12) // West setInterfaceText(player, "West to Champion's Guild and Varrock south gate.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135) openInterface(player, Components.AIDE_COMPASS_135)
} else if (node.asScenery().location.equals(Location(3283, 3333))) { } else if (node.asScenery().location.equals(Location(3283, 3333))) {
// Authentic
setInterfaceText(player, "North to Varrock mine and Varrock east gate.", 135, 3) // North setInterfaceText(player, "North to Varrock mine and Varrock east gate.", 135, 3) // North
setInterfaceText(player, "South to large Mining area and Al Kharid.", 135, 9) // South setInterfaceText(player, "South to large Mining area and Al Kharid.", 135, 9) // South
setInterfaceText(player, "Follow the path east to the Dig Site.", 135, 8) // East setInterfaceText(player, "Follow the path east to the Dig Site.", 135, 8) // East
@ -71,13 +66,7 @@ class SignpostListener : InteractionListener {
return@on true return@on true
} }
on(Scenery.SIGNPOST_4132, IntType.SCENERY, "read") { player, node -> on(Scenery.SIGNPOST_4132, IntType.SCENERY, "read") { player, node ->
if (node.asScenery().location.equals(Location(3223, 3427))) { if (node.asScenery().location.equals(Location(3166, 3286))) {
setInterfaceText(player, "North to Varrock Palace.", 135, 3) // North
setInterfaceText(player, "South to the Champion's Guild.", 135, 9) // South
setInterfaceText(player, "East to the Dig Site.", 135, 8) // East
setInterfaceText(player, "West to Barbarian Village and Falador.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135)
} else if (node.asScenery().location.equals(Location(3166, 3286))) {
setInterfaceText(player, "North to the windmill.", 135, 3) // North setInterfaceText(player, "North to the windmill.", 135, 3) // North
setInterfaceText(player, "South to a fishing pond next to Fred's farm.", 135, 9) // South setInterfaceText(player, "South to a fishing pond next to Fred's farm.", 135, 9) // South
setInterfaceText(player, "East to Lumbridge.", 135, 8) // East setInterfaceText(player, "East to Lumbridge.", 135, 8) // East
@ -144,56 +133,6 @@ class SignpostListener : InteractionListener {
} }
return@on true return@on true
} }
on(Scenery.SIGNPOST_4135, IntType.SCENERY, "read") { player, node ->
if (node.asScenery().location.equals(Location(3448, 3486))) {
setInterfaceText(player, "North to the Slayer Tower.", 135, 3) // North
setInterfaceText(player, "South to Mort Myre Swamp.", 135, 9) // South
setInterfaceText(player, "East to Canifis.", 135, 8) // East
setInterfaceText(player, "West to Varrock.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135)
} else {
setInterfaceText(player, "North to unknown.", 135, 3) // North
setInterfaceText(player, "South to unknown.", 135, 9) // South
setInterfaceText(player, "East to unknown.", 135, 8) // East
setInterfaceText(player, "West to unknown.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135)
}
return@on true
}
on(Scenery.SIGNPOST_31296, IntType.SCENERY, "read") { player, node ->
if (node.asScenery().location.equals(Location(3304, 3109))) {
// Authentic
setInterfaceText(player, "North to Al Kharid.", 135, 3) // North
setInterfaceText(player, "South to the Desert Mining Camp and Pollnivneach.", 135, 9) // South
setInterfaceText(player, "East and across the river to the Ruins of Uzer.", 135, 8) // East
setInterfaceText(player, "West to the Kalphite Lair.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135)
} else {
setInterfaceText(player, "North to unknown.", 135, 3) // North
setInterfaceText(player, "South to unknown.", 135, 9) // South
setInterfaceText(player, "East to unknown.", 135, 8) // East
setInterfaceText(player, "West to unknown.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135)
}
return@on true
}
on(Scenery.STONE_SIGNPOST_11630, IntType.SCENERY, "read") { player, node ->
// Authentic // https://youtu.be/vvHXKTOh_g4
if (node.asScenery().location.equals(Location(2967, 3412))) {
setInterfaceText(player, "North to Goblin Village.", 135, 3) // North
setInterfaceText(player, "South to Falador.", 135, 9) // South
setInterfaceText(player, "East to Varrock.", 135, 8) // East
setInterfaceText(player, "West to Taverley.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135)
} else {
setInterfaceText(player, "North to unknown.", 135, 3) // North
setInterfaceText(player, "South to unknown.", 135, 9) // South
setInterfaceText(player, "East to unknown.", 135, 8) // East
setInterfaceText(player, "West to unknown.", 135, 12) // West
openInterface(player, Components.AIDE_COMPASS_135)
}
return@on true
}
} }
/** /**
* Old handlers of Signpost. Not all should be opening the AIDE_COMPASS. * Old handlers of Signpost. Not all should be opening the AIDE_COMPASS.

View file

@ -81,33 +81,24 @@ public class ThievingGuidePlugin extends OptionHandler {
player.getDialogueInterpreter().sendDialogues(2266, null, "And where do you think you're going? A little too eager", "I think. Come and talk to me before you go wandering", "around in there."); player.getDialogueInterpreter().sendDialogues(2266, null, "And where do you think you're going? A little too eager", "I think. Come and talk to me before you go wandering", "around in there.");
break; break;
case "crack": case "crack":
if (player.getSkills().getLevel(Skills.THIEVING) < 50) {
player.getPacketDispatch().sendMessage("You need to be level " + level + " thief to crack this safe.");
return true;
}
if (player.getInventory().freeSlots() == 0) {
player.getPacketDispatch().sendMessage("Not enough inventory space.");
return true;
}
final boolean success = success(player, Skills.THIEVING);
player.lock(4);
player.getPacketDispatch().sendMessage("You start cracking the safe.");
player.animate(animations[success ? 1 : 0]);
GameWorld.getPulser().submit(new Pulse(3, player) { GameWorld.getPulser().submit(new Pulse(3, player) {
@Override @Override
public boolean pulse() { public boolean pulse() {
if (player.getSkills().getLevel(Skills.THIEVING) < 50) {
player.getPacketDispatch().sendMessage("You need to be level " + level + " thief to crack this safe.");
return true;
}
if (player.getInventory().freeSlots() == 0) {
player.getPacketDispatch().sendMessage("Not enough inventory space.");
return true;
}
if (player.getSkills().getLifepoints() <= 6) {
player.getPacketDispatch().sendMessage("You're too injured to be dealing with traps right now.");
return true;
}
if (player.getLocation().getDistance(node.getLocation()) >= 1) {
return true;
}
final boolean success = success(player, Skills.THIEVING);
//player.lock(4);
player.getPacketDispatch().sendMessage("You start cracking the safe.");
player.animate(animations[success ? 1 : 0]);
if (success) { if (success) {
handleSuccess(player, (Scenery) node); handleSuccess(player, (Scenery) node);
return false; return true;
} }
final boolean trapped = RandomFunction.random(3) == 1; final boolean trapped = RandomFunction.random(3) == 1;
if (trapped) { if (trapped) {
@ -118,12 +109,11 @@ public class ThievingGuidePlugin extends OptionHandler {
@Override @Override
public boolean pulse() { public boolean pulse() {
player.animate(new Animation(-1, Priority.HIGH)); player.animate(new Animation(-1, Priority.HIGH));
return false; return true;
} }
}); });
} }
return true;
return false;
} }
}); });
break; break;

View file

@ -116,19 +116,25 @@ class WildernessCourse
when (counter++) { when (counter++) {
0 -> { 0 -> {
AgilityHandler.forceWalk(player, -1, Location.create(x, 3937, 0), Location.create(x, 3940, 0), Animation.create(10580), 15, 0.0, null, 1) //10 AgilityHandler.forceWalk(player, -1, Location.create(x, 3937, 0), Location.create(x, 3940, 0), Animation.create(10580), 15, 0.0, null, 1) //10
println("1")
player.teleporter.send(Location.create(3004, 3947, 0), TeleportManager.TeleportType.INSTANT, TeleportManager.WILDY_TELEPORT) player.teleporter.send(Location.create(3004, 3947, 0), TeleportManager.TeleportType.INSTANT, TeleportManager.WILDY_TELEPORT)
println("tele")
counter++ counter++
AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5) //20 AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5) //20
println("3")
return true return true
} }
2 -> { 2 -> {
player.teleporter.send(Location.create(3004, 3947, 0), TeleportManager.TeleportType.INSTANT, TeleportManager.WILDY_TELEPORT) player.teleporter.send(Location.create(3004, 3947, 0), TeleportManager.TeleportType.INSTANT, TeleportManager.WILDY_TELEPORT)
println("tele")
counter++ counter++
AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5) AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5)
println("3")
return true return true
} }
3 -> { 3 -> {
AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5) AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5)
println("3")
return true return true
} }
} }

View file

@ -9,7 +9,6 @@ import core.game.world.map.Location;
import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Animation;
import core.plugin.Initializable; import core.plugin.Initializable;
import core.plugin.Plugin; import core.plugin.Plugin;
import content.data.Quests;
/** /**
* Handles the bar squeezing shortcut. * Handles the bar squeezing shortcut.
@ -62,7 +61,7 @@ public class BarSqueezeShortcut extends AgilityShortcut {
@Override @Override
public boolean checkRequirements(Player player) { public boolean checkRequirements(Player player) {
if (!player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL) && !(player.getLocation().getY() >= 3159 && player.getLocation().getY() <= 3161)) { if (!player.getQuestRepository().isComplete("Priest in Peril") && !(player.getLocation().getY() >= 3159 && player.getLocation().getY() <= 3161)) {
player.getDialogueInterpreter().sendDialogue("You need to have completed Priest in Peril in order to do this."); player.getDialogueInterpreter().sendDialogue("You need to have completed Priest in Peril in order to do this.");
return false; return false;
} }

View file

@ -15,7 +15,6 @@ import core.plugin.Initializable;
import core.plugin.Plugin; import core.plugin.Plugin;
import static core.api.ContentAPIKt.hasRequirement; import static core.api.ContentAPIKt.hasRequirement;
import content.data.Quests;
/** /**
* Handles a tunnel shortcut. * Handles a tunnel shortcut.
@ -74,7 +73,7 @@ public class TunnelShortcut extends AgilityShortcut {
@Override @Override
public void run(final Player player, Scenery object, String option, boolean failed) { public void run(final Player player, Scenery object, String option, boolean failed) {
if (object.getId() == 14922) { if (object.getId() == 14922) {
if (!hasRequirement(player, Quests.SWAN_SONG)) if (!hasRequirement(player, "Swan Song"))
return; return;
} }
player.lock(6); player.lock(6);

View file

@ -59,7 +59,7 @@ public enum BuildHotspot {
DINING_BENCH_1(15300, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY, Decoration.BENCH_GILDED), DINING_BENCH_1(15300, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY, Decoration.BENCH_GILDED),
DINING_BENCH_2(15299, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY,Decoration.BENCH_GILDED), DINING_BENCH_2(15299, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY,Decoration.BENCH_GILDED),
ROPE_BELL_PULL(15304, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ROPE_PULL, Decoration.BELL_PULL, Decoration.FANCY_BELL_PULL), ROPE_BELL_PULL(15304, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ROPE_PULL, Decoration.BELL_PULL, Decoration.FANCY_BELL_PULL),
WALL_DECORATION(15303, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION), WALL_DECORATION(15303, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION),
/** /**
* Low-level Work shop hotspots. * Low-level Work shop hotspots.
@ -67,11 +67,11 @@ public enum BuildHotspot {
REPAIR(15448, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.REPAIR_BENCH, Decoration.WHETSTONE, Decoration.ARMOUR_STAND), REPAIR(15448, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.REPAIR_BENCH, Decoration.WHETSTONE, Decoration.ARMOUR_STAND),
WORKBENCH(15439, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE,Decoration.WORKBENCH_WITH_LATHE), WORKBENCH(15439, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE,Decoration.WORKBENCH_WITH_LATHE),
CRAFTING(15441, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRAFTING_TABLE_1, Decoration.CRAFTING_TABLE_2,Decoration.CRAFTING_TABLE_3, Decoration.CRAFTING_TABLE_4), CRAFTING(15441, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRAFTING_TABLE_1, Decoration.CRAFTING_TABLE_2,Decoration.CRAFTING_TABLE_3, Decoration.CRAFTING_TABLE_4),
TOOL1(15443, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5), TOOL1(15443, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5),
TOOL2(15444, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), TOOL2(15444, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
TOOL3(15445, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), TOOL3(15445, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
TOOL4(15446, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), TOOL4(15446, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
TOOL5(15447, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), TOOL5(15447, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5),
HERALDRY(15450, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PLUMING_STAND, Decoration.SHIELD_EASEL,Decoration.BANNER_EASEL), HERALDRY(15450, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PLUMING_STAND, Decoration.SHIELD_EASEL,Decoration.BANNER_EASEL),
/** /**
@ -188,10 +188,20 @@ public enum BuildHotspot {
MAP(15396, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SMALL_MAP, Decoration.MEDIUM_MAP, Decoration.LARGE_MAP), MAP(15396, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SMALL_MAP, Decoration.MEDIUM_MAP, Decoration.LARGE_MAP),
BOOKCASE2(15397, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), BOOKCASE2(15397, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE),
/**
* Manegerie Hotspots
*/
OBELISK(44911, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.MINI_OBELISK),
PET_FEEDER(44910, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_PET_FEEDER, Decoration.TEAK_PET_FEEDER, Decoration.MAHOGANY_PET_FEEDER),
PET_HOUSE(44909, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_PET_HOUSE, Decoration.TEAK_PET_HOUSE, Decoration.MAHOGANY_PET_HOUSE, Decoration.CONSECRATED_PET_HOUSE, Decoration.DESECRATED_PET_HOUSE, Decoration.NATURAL_PET_HOUSE),
HABITAT_1(44907, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.GARDEN_HABITAT, Decoration.JUNGLE_HABITAT, Decoration.DESERT_HABITAT, Decoration.POLAR_HABITAT, Decoration.VOLCANIC_HABITAT),
HABITAT_2(44908, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.GARDEN_HABITAT, Decoration.JUNGLE_HABITAT, Decoration.DESERT_HABITAT, Decoration.POLAR_HABITAT, Decoration.VOLCANIC_HABITAT),
/** /**
* Combat room hotspots. * Combat room hotspots.
*/ */
WALL_DECORATION2(15297, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION), WALL_DECORATION2(15297, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION),
STORAGE_SPACE(15296, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.GLOVE_RACK, Decoration.WEAPONS_RACK, Decoration.EXTRA_WEAPONS_RACK), STORAGE_SPACE(15296, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.GLOVE_RACK, Decoration.WEAPONS_RACK, Decoration.EXTRA_WEAPONS_RACK),
CR_RING(15277, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), CR_RING(15277, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2),
CR_CORNER(15278, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), CR_CORNER(15278, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2),
@ -228,7 +238,7 @@ public enum BuildHotspot {
LECTERN(15420, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_LECTERN, Decoration.EAGLE_LECTERN, Decoration.DEMON_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), LECTERN(15420, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_LECTERN, Decoration.EAGLE_LECTERN, Decoration.DEMON_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN),
CRYSTAL_BALL(15422, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRYSTAL_BALL, Decoration.ELEMENTAL_SPHERE, Decoration.CRYSTAL_OF_POWER), CRYSTAL_BALL(15422, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRYSTAL_BALL, Decoration.ELEMENTAL_SPHERE, Decoration.CRYSTAL_OF_POWER),
BOOKCASE3(15425, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), BOOKCASE3(15425, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE),
WALL_CHART(15423, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ALCHEMICAL_CHART, Decoration.ASTRONOMICAL_CHART, Decoration.INFERNAL_CHART), WALL_CHART(15423, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ALCHEMICAL_CHART, Decoration.ASTRONOMICAL_CHART, Decoration.INFERNAL_CHART),
TELESCOPE(15424, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TELESCOPE1, Decoration.TELESCOPE2, Decoration.TELESCOPE3), TELESCOPE(15424, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TELESCOPE1, Decoration.TELESCOPE2, Decoration.TELESCOPE3),
/** /**
@ -384,6 +394,7 @@ public enum BuildHotspot {
linkedHotspots.add(new BuildHotspot[] { PRISON, PRISON_DOOR }); linkedHotspots.add(new BuildHotspot[] { PRISON, PRISON_DOOR });
linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT, DUNGEON_DOOR_RIGHT }); linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT, DUNGEON_DOOR_RIGHT });
linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT2, DUNGEON_DOOR_RIGHT2 }); linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT2, DUNGEON_DOOR_RIGHT2 });
linkedHotspots.add(new BuildHotspot[] { HABITAT_1, HABITAT_2 });
linkedHotspots.add(new BuildHotspot[] { SMALL_PLANT_1, SMALL_PLANT1 }); linkedHotspots.add(new BuildHotspot[] { SMALL_PLANT_1, SMALL_PLANT1 });
linkedHotspots.add(new BuildHotspot[] { SHELVES, SHELVES_2 }); linkedHotspots.add(new BuildHotspot[] { SHELVES, SHELVES_2 });
} }

Some files were not shown because too many files have changed in this diff Show more